WIP
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<kendo-editor [value]="value" (valueChange)="onChange($event)" (blur)="onTouched()" [disabled]="disabled"
|
||||
[schema]="messageTemplateSchema" [iframe]="false">
|
||||
[schema]="messageTemplateSchema" [iframe]="false" class="h-100">
|
||||
<kendo-toolbar>
|
||||
<!-- Standard editing tools -->
|
||||
<kendo-toolbar-buttongroup>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component, ElementRef, EventEmitter, Inject, Input, NgZone, Output, PLATFORM_ID, Renderer2, ViewChild, AfterViewInit } from '@angular/core';
|
||||
import { ControlValueAccessor, Validator, AbstractControl, ValidationErrors } from '@angular/forms';
|
||||
import { Component, ElementRef, EventEmitter, Inject, Input, NgZone, Output, PLATFORM_ID, Renderer2, ViewChild, AfterViewInit, forwardRef, ChangeDetectorRef } from '@angular/core';
|
||||
import { ControlValueAccessor, Validator, AbstractControl, ValidationErrors, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { EditorComponent, NodeSpec, schema, Schema, FontSizeItem } from '@progress/kendo-angular-editor';
|
||||
|
||||
import { MsgBoxService } from '../../../services/msg-box.service';
|
||||
@@ -10,10 +10,18 @@ import { MD2StateService } from '../../../services/MD2/md2-state.service';
|
||||
import { MD2IconPickerDlgComponent } from './md2-icon-picker-dlg.component';
|
||||
import { NbDialogService } from '@nebular/theme';
|
||||
import { DOMParser as ProseMirrorDOMParser } from 'prosemirror-model';
|
||||
import { DialogService } from '@progress/kendo-angular-dialog';
|
||||
@Component({
|
||||
selector: 'md2-html-editor',
|
||||
templateUrl: './md2-html-editor.component.html',
|
||||
styleUrl: './md2-html-editor.component.scss'
|
||||
styleUrl: './md2-html-editor.component.scss',
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: forwardRef(() => MD2HtmlEditorComponent),
|
||||
multi: true
|
||||
}
|
||||
]
|
||||
})
|
||||
export class MD2HtmlEditorComponent implements ControlValueAccessor, AfterViewInit {
|
||||
@ViewChild(EditorComponent) editor: EditorComponent;
|
||||
@@ -52,7 +60,8 @@ export class MD2HtmlEditorComponent implements ControlValueAccessor, AfterViewIn
|
||||
constructor(
|
||||
private msgBoxService: MsgBoxService,
|
||||
private md2StateService: MD2StateService,
|
||||
private dialogService: NbDialogService,
|
||||
private dialogService: DialogService,
|
||||
private cdr: ChangeDetectorRef,
|
||||
elementRef: ElementRef, ngZone: NgZone, @Inject(PLATFORM_ID) platformId: Object) {
|
||||
|
||||
}
|
||||
@@ -71,12 +80,38 @@ export class MD2HtmlEditorComponent implements ControlValueAccessor, AfterViewIn
|
||||
this.fontSizeDropdown.defaultItem = this.defaultFontSize;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the editor value is set if writeValue was called before view init
|
||||
if (this.editor && this.value && this.editor.value !== this.value) {
|
||||
this.editor.value = this.value;
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
// ControlValueAccessor implementation
|
||||
writeValue(value: string): void {
|
||||
this.value = value || '';
|
||||
writeValue(value: string | null | undefined): void {
|
||||
const newValue = value || '';
|
||||
|
||||
// Only update if the value actually changed to avoid unnecessary updates
|
||||
if (this.value !== newValue) {
|
||||
this.value = newValue;
|
||||
|
||||
// Angular's [value] binding will handle updating the editor
|
||||
// But if editor is already initialized and value is out of sync, ensure sync
|
||||
if (this.editor && this.editor.value !== this.value) {
|
||||
// Use setTimeout to avoid ExpressionChangedAfterItHasBeenCheckedError
|
||||
setTimeout(() => {
|
||||
if (this.editor && this.editor.value !== this.value) {
|
||||
this.editor.value = this.value;
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
// Trigger change detection to ensure the binding updates
|
||||
if (!this.cdr['destroyed']) {
|
||||
this.cdr.markForCheck();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registerOnChange(fn: (value: string) => void): void {
|
||||
@@ -92,8 +127,11 @@ export class MD2HtmlEditorComponent implements ControlValueAccessor, AfterViewIn
|
||||
}
|
||||
|
||||
onChange(value: string): void {
|
||||
this.value = value;
|
||||
this.onChangeFn(value);
|
||||
// Only update if value actually changed to prevent infinite loops
|
||||
if (this.value !== value) {
|
||||
this.value = value || '';
|
||||
this.onChangeFn(this.value);
|
||||
}
|
||||
}
|
||||
|
||||
onTouched(): void {
|
||||
@@ -101,10 +139,12 @@ export class MD2HtmlEditorComponent implements ControlValueAccessor, AfterViewIn
|
||||
}
|
||||
|
||||
showInsertMD2Icon() {
|
||||
this.dialogService.open(MD2IconPickerDlgComponent, {
|
||||
closeOnBackdropClick: true,
|
||||
closeOnEsc: true
|
||||
}).onClose.pipe(first()).subscribe((html: string) => {
|
||||
this.dialogService.open({
|
||||
title: 'Insert MD2 Icon',
|
||||
content: MD2IconPickerDlgComponent,
|
||||
width: '800px',
|
||||
height: 600
|
||||
}).result.subscribe((html: string) => {
|
||||
if (html && this.editor) {
|
||||
this.insertAfterSelection(html, true);
|
||||
return;
|
||||
|
||||
@@ -2,16 +2,11 @@ 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';
|
||||
import { DialogRef } from '@progress/kendo-angular-dialog';
|
||||
|
||||
@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="md2-icon-grid">
|
||||
template: ` <div class="md2-icon-grid">
|
||||
<div
|
||||
*ngFor="let iconData of iconList"
|
||||
(click)="selectIcon(iconData)"
|
||||
@@ -19,13 +14,23 @@ import { MD2StateService } from '../../../services/MD2/md2-state.service';
|
||||
[innerHTML]="iconData.html">
|
||||
</div>
|
||||
</div>
|
||||
<!-- <nb-card>
|
||||
<nb-card-header>
|
||||
<h5>Insert MD2 Icon</h5>
|
||||
</nb-card-header>
|
||||
<nb-card-body>
|
||||
|
||||
</nb-card-body>
|
||||
<nb-card-footer>
|
||||
<button nbButton status="primary" (click)="cancel()">Cancel</button>
|
||||
</nb-card-footer>
|
||||
</nb-card>
|
||||
</nb-card> -->
|
||||
`,
|
||||
styles: [`
|
||||
nb-card{
|
||||
max-width: 800px;
|
||||
z-index: 1050;
|
||||
}
|
||||
.md2-icon-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(60px, 1fr));
|
||||
@@ -57,7 +62,7 @@ export class MD2IconPickerDlgComponent implements OnInit {
|
||||
iconList: Array<{ icon: MD2Icon, name: string, html: string }> = [];
|
||||
|
||||
constructor(
|
||||
private dlgRef: NbDialogRef<MD2IconPickerDlgComponent>,
|
||||
private dlgRef: DialogRef,
|
||||
private md2StateService: MD2StateService
|
||||
) { }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user