Compare commits

..

No commits in common. "ed90250876467795865d6ee95eaf1c023d843b83" and "70aa8adbbae3247062d5602b9599932421a0ffe8" have entirely different histories.

9 changed files with 202 additions and 13488 deletions

View File

@ -1,12 +0,0 @@
{
"mcpServers": {
"kendoai": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@progress/kendo-angular-mcp@latest"],
"env": {
"TELERIK_LICENSE_PATH":"C:/Users/Chris/AppData/Roaming/Telerik/telerik-license.txt"
}
}
}
}

View File

@ -38,7 +38,6 @@
"node_modules/nebular-icons/scss/nebular-icons.scss",
"node_modules/pace-js/templates/pace-theme-flash.tmpl.css",
"node_modules/leaflet/dist/leaflet.css",
"node_modules/@progress/kendo-theme-default/dist/all.css",
"src/app/@theme/styles/styles.scss",
"src/assets/styles/site.scss"
],

13397
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,7 @@
"e2e": "ng e2e",
"docs": "compodoc -p src/tsconfig.app.json -d docs",
"docs:serve": "compodoc -p src/tsconfig.app.json -d docs -s",
"prepush": "echo 'Pre-push hook disabled - style linting skipped'",
"prepush": "npm run lint:ci",
"release:changelog": "npm run conventional-changelog -- -p angular -i CHANGELOG.md -s"
},
"dependencies": {
@ -45,13 +45,6 @@
"@nebular/eva-icons": "13.0.0",
"@nebular/security": "13.0.0",
"@nebular/theme": "13.0.0",
"@progress/kendo-angular-buttons": "^20.1.1",
"@progress/kendo-angular-dialog": "^20.1.1",
"@progress/kendo-angular-editor": "^20.1.1",
"@progress/kendo-angular-toolbar": "^20.1.1",
"@progress/kendo-licensing": "^1.7.1",
"@progress/kendo-svg-icons": "^4.5.0",
"@progress/kendo-theme-default": "^12.2.0",
"@tinymce/tinymce-angular": "^7.0.0",
"angular2-chartjs": "0.4.1",
"angular2-qrcode": "^2.0.3",

View File

@ -35,10 +35,6 @@ import { MobStandInfoComponent } from './massive-darkness2/mobs/mob-stand-info/m
import { HtmlEditorModule } from '../ui/html-editor/html-editor.module';
import { EditorModule } from '@tinymce/tinymce-angular';
import { MD2HtmlEditorComponent } from './massive-darkness2/md2-html-editor/md2-html-editor.component';
import { MD2IconPickerDlgComponent } from './massive-darkness2/md2-html-editor/md2-icon-picker-dlg.component';
import { EditorModule as KendoEditorModule } from '@progress/kendo-angular-editor';
import { ToolBarModule } from '@progress/kendo-angular-toolbar';
import { ButtonsModule } from '@progress/kendo-angular-buttons';
@NgModule({
@ -67,8 +63,7 @@ import { ButtonsModule } from '@progress/kendo-angular-buttons';
MobDefInfoComponent,
MobCombatInfoComponent,
MobStandInfoComponent,
MD2HtmlEditorComponent,
MD2IconPickerDlgComponent
MD2HtmlEditorComponent
],
imports: [
CommonModule,
@ -100,10 +95,7 @@ import { ButtonsModule } from '@progress/kendo-angular-buttons';
AlertDlgModule,
DropDownListModule,
HtmlEditorModule,
EditorModule,
KendoEditorModule,
ToolBarModule,
ButtonsModule
EditorModule
]
})
export class GamesModule { }

View File

@ -1,20 +1 @@
<kendo-editor [value]="value" (valueChange)="onChange($event)" (blur)="onTouched()" [disabled]="disabled"
[iframeCss]="{ content: customCssClass }">
<kendo-toolbar>
<!-- Standard editing tools -->
<kendo-toolbar-button kendoEditorBold></kendo-toolbar-button>
<kendo-toolbar-button kendoEditorItalic></kendo-toolbar-button>
<kendo-toolbar-button kendoEditorUnderline></kendo-toolbar-button>
<kendo-toolbar-separator></kendo-toolbar-separator>
<kendo-toolbar-button kendoEditorUnorderedList></kendo-toolbar-button>
<kendo-toolbar-button kendoEditorOrderedList></kendo-toolbar-button>
<kendo-toolbar-separator></kendo-toolbar-separator>
<kendo-toolbar-button kendoEditorUndo></kendo-toolbar-button>
<kendo-toolbar-button kendoEditorRedo></kendo-toolbar-button>
<kendo-toolbar-separator></kendo-toolbar-separator>
<!-- Custom MD2 Icon button -->
<kendo-toolbar-button (click)="showInsertMD2Icon()">
Insert Icon
</kendo-toolbar-button>
</kendo-toolbar>
</kendo-editor>
<!-- <editor [init]="htmlEditorSetting"></editor> -->

View File

@ -1,6 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MD2HtmlEditorComponent } from './md2-html-editor.component';
import { GamesModule } from '../../games.module';
describe('MD2HtmlEditorComponent', () => {
let component: MD2HtmlEditorComponent;
@ -8,7 +8,7 @@ describe('MD2HtmlEditorComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [GamesModule]
imports: [MD2HtmlEditorComponent]
})
.compileComponents();

View File

@ -1,112 +1,97 @@
import { Component, ElementRef, EventEmitter, Inject, Input, NgZone, Output, PLATFORM_ID, Renderer2, ViewChild } from '@angular/core';
import { Component, ElementRef, EventEmitter, Inject, Input, NgZone, Output, PLATFORM_ID, Renderer2 } from '@angular/core';
import { ControlValueAccessor, Validator, AbstractControl, ValidationErrors } from '@angular/forms';
import { EditorComponent } from '@progress/kendo-angular-editor';
import { MsgBoxService } from '../../../services/msg-box.service';
import { DropDownOption } from '../../../entity/dropDownOption';
import { MD2Icon } from '../massive-darkness2.model';
import { first } from 'rxjs/operators';
import { MD2StateService } from '../../../services/MD2/md2-state.service';
import { MD2IconPickerDlgComponent } from './md2-icon-picker-dlg.component';
import { NbDialogService } from '@nebular/theme';
import { HtmlEditorSettings } from '../../../ui/html-editor/html-editor.model';
import { EditorComponent } from '@tinymce/tinymce-angular';
import { Editor } from 'tinymce';
@Component({
selector: 'md2-html-editor',
templateUrl: './md2-html-editor.component.html',
styleUrl: './md2-html-editor.component.scss'
})
export class MD2HtmlEditorComponent implements ControlValueAccessor {
@ViewChild(EditorComponent) editor: EditorComponent;
value: string = '';
disabled: boolean = false;
customCssClass = '.MD2Icon{font-family: "Massive Darkness 2", sans-serif !important; font-size: 40px; margin-left:5px} body{font-size: 30px; }';
// ControlValueAccessor interface
private onChangeFn = (value: string) => { };
private onTouchedFn = () => { };
export class MD2HtmlEditorComponent extends EditorComponent implements ControlValueAccessor {
htmlEditorSetting: HtmlEditorSettings = {};
constructor(
private msgBoxService: MsgBoxService,
private md2StateService: MD2StateService,
private dialogService: NbDialogService,
elementRef: ElementRef, ngZone: NgZone, @Inject(PLATFORM_ID) platformId: Object) {
super(elementRef, ngZone, platformId);
// this.elementRef is private. Need a duplicate
this._elementRef2 = elementRef;
this.htmlEditorSetting.base_url = '/tinymce';
this.htmlEditorSetting.suffix = '.min';
this.htmlEditorSetting['parentComponent'] = this;
this.htmlEditorSetting.plugins = [
'noneditable', 'lists', 'link', 'image', 'table', 'code'];
this.htmlEditorSetting.toolbar = ['undo redo | blocks | bold italic | alignleft aligncentre alignright alignjustify | indent outdent | bullist numlist | code customInsertButton'];
this.htmlEditorSetting.content_style = '.MD2Icon{font-family: "Massive Darkness 2", sans-serif !important; font-size: 40px; margin-left:5px} body{font-size: 30px; }';
this.htmlEditorSetting.noneditable_noneditable_class = 'MD2Icon';
//this.htmlEditorSetting.o = this.htmlEditorSetup;
this.htmlEditorSetting.setup = (editor) => this.htmlEditorSetup(editor)
}
htmlEditorSetup(editor: Editor) {
if (editor) {
let component = this.htmlEditorSetting['parentComponent'] as MD2HtmlEditorComponent;
editor.ui.registry.addButton('customInsertButton', {
icon: 'code-sample',
text: 'MD2 Icon',
onAction: (_) => component.showInsertMD2Icon(this.editor as any)
});
}
}
showInsertMD2Icon(editor: Editor) {
var iconKeys = Object.keys(MD2Icon);
iconKeys = iconKeys.slice(iconKeys.length / 2, iconKeys.length - 1);
this.ngZone.run(_ => {
this.msgBoxService.showInputbox('Insert MD2 Icon', '', { inputType: 'dropdown', dropDownOptions: iconKeys.map((k, i) => new DropDownOption(i, k)) })
.pipe(first()).subscribe(result => {
editor.insertContent(`<span class="MD2Icon mceNonEditable">${String.fromCharCode(65 + result)}</span>`);
this.writeValue(editor.getContent());
});
});
}
// ControlValueAccessor implementation
writeValue(value: string): void {
this.value = value || '';
private _elementRef2: ElementRef;
writeValue(value: string | null): void {
super.writeValue(value);
}
registerOnChange(fn: (value: string) => void): void {
this.onChangeFn = fn;
super.registerOnChange(fn);
}
registerOnTouched(fn: () => void): void {
this.onTouchedFn = fn;
registerOnTouched(fn: any): void {
super.registerOnTouched(fn);
}
setDisabledState(isDisabled: boolean): void {
this.disabled = isDisabled;
super.setDisabledState(isDisabled);
}
checkDomAttachment(): boolean {
// check if component has been attached to DOM yet
return document.body.contains(this._elementRef2.nativeElement);
}
ngAfterViewInit() {
this.init = this.htmlEditorSetting;
//this.htmlEditorSetup();
super.ngAfterViewInit();
}
onChange(value: string): void {
this.value = value;
this.onChangeFn(value);
}
onTouched(): void {
this.onTouchedFn();
}
showInsertMD2Icon() {
this.dialogService.open(MD2IconPickerDlgComponent, {
closeOnBackdropClick: true,
closeOnEsc: true
}).onClose.pipe(first()).subscribe((html: string) => {
if (html && this.editor) {
// Insert the HTML content at the current cursor position
// Use ProseMirror's dispatch method to insert content at cursor
const view = this.editor.view;
if (view && view.state) {
try {
// Parse the HTML content
const dom = document.createElement('div');
dom.innerHTML = html;
// Use ProseMirror's DOMParser to parse HTML
// Access it from the view's state
const pmState = view.state;
// Use the editor's exec method or manual dispatch
if ((this.editor as any).exec) {
// Try using exec with 'insertHTML' command if available
try {
(this.editor as any).exec('insertHTML', html);
} catch (e) {
throw new Error('insertHTML not supported');
}
} else {
throw new Error('exec method not available');
}
} catch (e) {
console.error('Error inserting HTML:', e);
// Fallback: append to the end
const currentValue = this.editor.value || '';
const newValue = currentValue + ' ' + html;
this.value = newValue;
this.onChange(newValue);
}
} else {
// Fallback: append to the end
const currentValue = this.editor.value || '';
const newValue = currentValue + ' ' + html;
this.value = newValue;
this.onChange(newValue);
}
}
});
private InitializeEditor() {
this.init = new HtmlEditorSettings({});
//super.initialise();
}
}

View File

@ -1,81 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { NbDialogRef } from '@nebular/theme';
import { MD2Icon } from '../massive-darkness2.model';
import { MD2StateService } from '../../../services/MD2/md2-state.service';
@Component({
selector: 'md2-icon-picker-dlg',
template: `
<nb-card style="max-width: 800px;">
<nb-card-header>
<h5>Insert MD2 Icon</h5>
</nb-card-header>
<nb-card-body>
<div class="icon-grid">
<div
*ngFor="let iconData of iconList"
(click)="selectIcon(iconData)"
class="icon-item"
[innerHTML]="iconData.html">
</div>
</div>
</nb-card-body>
<nb-card-footer>
<button nbButton status="primary" (click)="cancel()">Cancel</button>
</nb-card-footer>
</nb-card>
`,
styles: [`
.icon-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(60px, 1fr));
gap: 10px;
max-height: 400px;
overflow-y: auto;
}
.icon-item {
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
transition: all 0.2s;
}
.icon-item:hover {
background-color: #f0f0f0;
border-color: #007bff;
transform: scale(1.1);
}
`]
})
export class MD2IconPickerDlgComponent implements OnInit {
iconList: Array<{ icon: MD2Icon, name: string, html: string }> = [];
constructor(
private dlgRef: NbDialogRef<MD2IconPickerDlgComponent>,
private md2StateService: MD2StateService
) { }
ngOnInit(): void {
// Get all icons
for (let icon of Object.values(MD2Icon).filter(val => typeof val === 'number') as MD2Icon[]) {
this.iconList.push({
icon: icon,
name: MD2Icon[icon],
html: this.md2StateService.iconHtml(icon)
});
}
}
selectIcon(iconData: { icon: MD2Icon, name: string, html: string }) {
this.dlgRef.close(iconData.html);
}
cancel() {
this.dlgRef.close(null);
}
}