replaced angular editor with ngx-editor
This commit is contained in:
parent
cea2911e8b
commit
60d46c1da0
|
@ -38,6 +38,7 @@
|
|||
"ngx-cookie-service": "^18.0.0",
|
||||
"ngx-cookieconsent": "^6.0.0",
|
||||
"ngx-dropzone": "^3.0.0",
|
||||
"ngx-editor": "^17.5.4",
|
||||
"ngx-guided-tour": "^2.0.1",
|
||||
"ngx-matomo-client": "^6.2.0",
|
||||
"rxjs": "^7.4.0",
|
||||
|
@ -3112,6 +3113,28 @@
|
|||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/core": {
|
||||
"version": "1.6.4",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.4.tgz",
|
||||
"integrity": "sha512-a4IowK4QkXl4SCWTGUR0INAfEOX3wtsYw3rKK5InQEHMGObkR8Xk44qYQD9P4r6HHw0iIfK6GUKECmY8sTkqRA==",
|
||||
"dependencies": {
|
||||
"@floating-ui/utils": "^0.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/dom": {
|
||||
"version": "1.6.7",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.7.tgz",
|
||||
"integrity": "sha512-wmVfPG5o2xnKDU4jx/m4w5qva9FWHcnZ8BvzEe90D/RpwsJaTAVYPEPdQ8sbr/N8zZTAHlZUTQdqg8ZUbzHmng==",
|
||||
"dependencies": {
|
||||
"@floating-ui/core": "^1.6.0",
|
||||
"@floating-ui/utils": "^0.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/utils": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.4.tgz",
|
||||
"integrity": "sha512-dWO2pw8hhi+WrXq1YJy2yCuWoL20PddgGaqTgVe4cOS9Q6qklXCiA1tJEqX6BEwRNSCP84/afac9hd4MS+zEUA=="
|
||||
},
|
||||
"node_modules/@inquirer/figures": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.3.tgz",
|
||||
|
@ -5218,6 +5241,11 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/trusted-types": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
|
||||
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "8.5.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz",
|
||||
|
@ -9813,6 +9841,32 @@
|
|||
"tslib": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ngx-editor": {
|
||||
"version": "17.5.4",
|
||||
"resolved": "https://registry.npmjs.org/ngx-editor/-/ngx-editor-17.5.4.tgz",
|
||||
"integrity": "sha512-1uezbJnMFyELY3h+bNovZCIjrgqXOuIiEA1ZcBb9KIaCoRf6RtBqeRxz/nZVE4lvadHyCH/F4iLqhC8bVDEf2w==",
|
||||
"dependencies": {
|
||||
"@floating-ui/core": "^1.6.0",
|
||||
"@floating-ui/dom": "^1.6.0",
|
||||
"@types/trusted-types": "~2.0.7",
|
||||
"prosemirror-commands": "^1.5.2",
|
||||
"prosemirror-history": "^1.4.0",
|
||||
"prosemirror-inputrules": "^1.4.0",
|
||||
"prosemirror-keymap": "^1.2.2",
|
||||
"prosemirror-model": "^1.21.0",
|
||||
"prosemirror-schema-list": "^1.3.0",
|
||||
"prosemirror-state": "^1.4.3",
|
||||
"prosemirror-view": "^1.33.6",
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": ">=17.1.0",
|
||||
"@angular/core": ">=17.1.0",
|
||||
"@angular/forms": ">=17.1.0",
|
||||
"@angular/platform-browser": ">=17.1.0",
|
||||
"rxjs": ">=7.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ngx-guided-tour": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ngx-guided-tour/-/ngx-guided-tour-2.0.1.tgz",
|
||||
|
@ -10328,6 +10382,11 @@
|
|||
"integrity": "sha512-5VyHfHY3cd0iza71JepYG50My+YUbrFtGoUz2ooEydPyPM7Aai/JW098juLr+RG6+rDJuzNNTsEQu2DZa1A41A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/orderedmap": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz",
|
||||
"integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g=="
|
||||
},
|
||||
"node_modules/os-tmpdir": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
|
||||
|
@ -10914,6 +10973,91 @@
|
|||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-commands": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.5.2.tgz",
|
||||
"integrity": "sha512-hgLcPaakxH8tu6YvVAaILV2tXYsW3rAdDR8WNkeKGcgeMVQg3/TMhPdVoh7iAmfgVjZGtcOSjKiQaoeKjzd2mQ==",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.0.0",
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-history": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.4.1.tgz",
|
||||
"integrity": "sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==",
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.2.2",
|
||||
"prosemirror-transform": "^1.0.0",
|
||||
"prosemirror-view": "^1.31.0",
|
||||
"rope-sequence": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-inputrules": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.4.0.tgz",
|
||||
"integrity": "sha512-6ygpPRuTJ2lcOXs9JkefieMst63wVJBgHZGl5QOytN7oSZs3Co/BYbc3Yx9zm9H37Bxw8kVzCnDsihsVsL4yEg==",
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-keymap": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.2.tgz",
|
||||
"integrity": "sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ==",
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"w3c-keyname": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-model": {
|
||||
"version": "1.21.3",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.21.3.tgz",
|
||||
"integrity": "sha512-nt2Xs/RNGepD9hrrkzXvtCm1mpGJoQfFSPktGa0BF/aav6XsnmVGZ9sTXNWRLupAz5SCLa3EyKlFeK7zJWROKg==",
|
||||
"dependencies": {
|
||||
"orderedmap": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-schema-list": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.4.0.tgz",
|
||||
"integrity": "sha512-nZOIq/AkBSzCENxUyLm5ltWE53e2PLk65ghMN8qLQptOmDVixZlPqtMeQdiNw0odL9vNpalEjl3upgRkuJ/Jyw==",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.0.0",
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-state": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz",
|
||||
"integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.0.0",
|
||||
"prosemirror-transform": "^1.0.0",
|
||||
"prosemirror-view": "^1.27.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-transform": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.9.0.tgz",
|
||||
"integrity": "sha512-5UXkr1LIRx3jmpXXNKDhv8OyAOeLTGuXNwdVfg8x27uASna/wQkr9p6fD3eupGOi4PLJfbezxTyi/7fSJypXHg==",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-view": {
|
||||
"version": "1.33.8",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.33.8.tgz",
|
||||
"integrity": "sha512-4PhMr/ufz2cdvFgpUAnZfs+0xij3RsFysreeG9V/utpwX7AJtYCDVyuRxzWoMJIEf4C7wVihuBNMPpFLPCiLQw==",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.20.0",
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
|
@ -11358,6 +11502,11 @@
|
|||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/rope-sequence": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz",
|
||||
"integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ=="
|
||||
},
|
||||
"node_modules/run-applescript": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz",
|
||||
|
@ -13280,6 +13429,11 @@
|
|||
"@esbuild/win32-x64": "0.20.2"
|
||||
}
|
||||
},
|
||||
"node_modules/w3c-keyname": {
|
||||
"version": "2.2.8",
|
||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
|
||||
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="
|
||||
},
|
||||
"node_modules/watchpack": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz",
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
"ngx-cookie-service": "^18.0.0",
|
||||
"ngx-cookieconsent": "^6.0.0",
|
||||
"ngx-dropzone": "^3.0.0",
|
||||
"ngx-editor": "^17.5.4",
|
||||
"ngx-guided-tour": "^2.0.1",
|
||||
"ngx-matomo-client": "^6.2.0",
|
||||
"rxjs": "^7.4.0",
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
<div *ngIf="internalControl" [id]="id" class="NgxEditor__Wrapper" [class]="wrapperClasses" [ngClass]="{'error': form.hasError('required')}">
|
||||
<ngx-editor-menu
|
||||
[editor]="editor"
|
||||
[disabled]="!editable"
|
||||
[toolbar]="toolbar"
|
||||
></ngx-editor-menu>
|
||||
<ngx-editor
|
||||
[editor]="editor"
|
||||
[formControl]="internalControl"
|
||||
[placeholder]="placeholder"
|
||||
(ngModelChange)="onChange($event)"
|
||||
></ngx-editor>
|
||||
</div>
|
||||
|
||||
<mat-error *ngIf="form.hasError('required')">has error</mat-error>
|
||||
<!--
|
||||
<br>
|
||||
<div>
|
||||
value: {{ form?.value }}, {{form?.disabled}}
|
||||
</div>
|
||||
<br> -->
|
|
@ -0,0 +1,7 @@
|
|||
.NgxEditor__Wrapper {
|
||||
min-height: 150px;
|
||||
|
||||
.error {
|
||||
border: 1px solid #f44336 !important;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from "@angular/core";
|
||||
import { FormBuilder, FormControl, Validators } from "@angular/forms";
|
||||
import { Editor, Toolbar, toHTML, toDoc } from "ngx-editor";
|
||||
|
||||
@Component({
|
||||
selector: 'rich-text-editor-component',
|
||||
// selector: 'app-rich-text-editor',
|
||||
templateUrl: './ngx-rich-text-editor.component.html',
|
||||
styleUrls: ['./ngx-rich-text-editor.component.scss'],
|
||||
})
|
||||
export class NgxRichTextEditorComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
@Input() form: FormControl;
|
||||
@Input() id: string = "editor1";
|
||||
@Input() placeholder: string = "Enter text";
|
||||
@Input() required: boolean = false;
|
||||
@Input() wrapperClasses: string = "";
|
||||
@Input() editable: boolean = true;
|
||||
|
||||
editor: Editor;
|
||||
internalControl!: FormControl;
|
||||
|
||||
toolbar: Toolbar = [
|
||||
['undo', 'redo'],
|
||||
['bold', 'italic', 'underline', 'strike', 'superscript', 'subscript'],
|
||||
['align_left', 'align_center', 'align_right', 'align_justify'],
|
||||
['bullet_list', 'ordered_list'],
|
||||
['text_color'],
|
||||
[{ heading: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] }],
|
||||
['link', 'horizontal_rule'],
|
||||
[ 'format_clear'],
|
||||
];
|
||||
|
||||
constructor(private formBuilder: FormBuilder) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
if (this.required) this.placeholder = this.placeholder + '*';
|
||||
|
||||
const isEmpty = this.form?.value == null || this._isEmpty(toDoc(this.form?.value));
|
||||
|
||||
if (isEmpty) {
|
||||
this.form?.setValue(null);
|
||||
this.internalControl = this.formBuilder.control(null, Validators.required);
|
||||
} else {
|
||||
this.internalControl = this.formBuilder.control(toDoc(this.form?.value), Validators.required);
|
||||
}
|
||||
|
||||
this.editor = new Editor({ content: isEmpty ? null : toDoc(this.form?.value) });
|
||||
|
||||
if (!this.editable) this.internalControl?.disable();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.editor.destroy();
|
||||
}
|
||||
|
||||
onChange(event: any): void {
|
||||
// console.log(event);
|
||||
|
||||
if (this._isEmpty(event)) this.form.setValue(null);
|
||||
else this.form.setValue(toHTML(event));
|
||||
}
|
||||
|
||||
private _isEmpty(richTextContent: any): boolean {
|
||||
const content = richTextContent.content;
|
||||
|
||||
if (!Array.isArray(content)) return true;
|
||||
|
||||
const isEmpty = content?.every(c => {
|
||||
|
||||
if (c.content == null) return true;
|
||||
|
||||
let text = c.content;
|
||||
if (Array.isArray(text)) {
|
||||
if (text?.some(t => t.text != null && t.text?.trim() != '')) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
return isEmpty;
|
||||
}
|
||||
}
|
|
@ -4,7 +4,8 @@ import { AngularEditorConfig } from "@kolkov/angular-editor";
|
|||
import { Subscription } from "rxjs";
|
||||
|
||||
@Component({
|
||||
selector: 'rich-text-editor-component',
|
||||
selector: 'old-rich-text-editor-component',
|
||||
// selector: 'rich-text-editor-component',
|
||||
template: `
|
||||
<div class="editor-wrapper" [class]="wrapperClasses">
|
||||
<angular-editor class="full-width editor" [ngClass]="editable ? '': 'disabled'" [id]="id"
|
||||
|
@ -104,7 +105,7 @@ export class RichTextEditorComponent implements OnInit, OnChanges, OnDestroy {
|
|||
this.editorConfig.editable = this.editable;
|
||||
}
|
||||
|
||||
pasteWithoutFormatting($event) {
|
||||
pasteWithoutFormatting($event) { // TODO: check for the other editor
|
||||
$event.preventDefault();
|
||||
const text = $event.clipboardData.getData("text/plain");
|
||||
window.document.execCommand("insertText", false, text);
|
||||
|
|
|
@ -3,17 +3,22 @@ import {CommonUiModule} from "@common/ui/common-ui.module";
|
|||
import {CommonFormsModule} from "@common/forms/common-forms.module";
|
||||
import {AngularEditorModule} from "@kolkov/angular-editor";
|
||||
import {RichTextEditorComponent} from "@app/library/rich-text-editor/rich-text-editor.component";
|
||||
import { NgxRichTextEditorComponent } from "./ngx-rich-text-editor.component";
|
||||
import { NgxEditorModule } from "ngx-editor";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonUiModule,
|
||||
CommonFormsModule,
|
||||
AngularEditorModule
|
||||
AngularEditorModule,
|
||||
NgxEditorModule,
|
||||
],
|
||||
declarations: [
|
||||
NgxRichTextEditorComponent,
|
||||
RichTextEditorComponent
|
||||
],
|
||||
exports: [
|
||||
NgxRichTextEditorComponent,
|
||||
RichTextEditorComponent
|
||||
]
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue