Skip to content

Commit

Permalink
Feat(Edit Contentlet): Add TinyMCE V6 WYSIWFY field to the form (#27961)
Browse files Browse the repository at this point in the history
* feat: add WYSIWYG field

* chore: code cleanup

* chore: cover tests

* chore: code cleanup

* chore: run yarn
  • Loading branch information
rjvelazco authored Mar 14, 2024
1 parent fcfbbe9 commit 6e0fce1
Show file tree
Hide file tree
Showing 12 changed files with 152 additions and 3 deletions.
5 changes: 5 additions & 0 deletions core-web/apps/dotcms-ui/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
"assets": [
"apps/dotcms-ui/src/favicon.ico",
"apps/dotcms-ui/src/assets",
{
"glob": "**/*",
"input": "node_modules/tinymce",
"output": "/tinymce/"
},
{
"glob": "**/*",
"input": "node_modules/monaco-editor",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@
*ngSwitchCase="fieldTypes.KEY_VALUE"
[formControlName]="field.variable"
[attr.data-testId]="'field-' + field.variable" />

<dot-wysiwyg-field
*ngSwitchCase="fieldTypes.WYSIWYG"
[field]="field"
[attr.data-testId]="'field-' + field.variable" />
</ng-container>

<small *ngIf="field.hint" [attr.data-testId]="'hint-' + field.variable">{{ field.hint }}</small>
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { describe } from '@jest/globals';
import { byTestId, createComponentFactory, mockProvider, Spectator } from '@ngneat/spectator/jest';
import { EditorComponent } from '@tinymce/tinymce-angular';
import { MockComponent } from 'ng-mocks';
import { of } from 'rxjs';

Expand Down Expand Up @@ -30,6 +31,7 @@ import { DotEditContentSelectFieldComponent } from '../../fields/dot-edit-conten
import { DotEditContentTagFieldComponent } from '../../fields/dot-edit-content-tag-field/dot-edit-content-tag-field.component';
import { DotEditContentTextAreaComponent } from '../../fields/dot-edit-content-text-area/dot-edit-content-text-area.component';
import { DotEditContentTextFieldComponent } from '../../fields/dot-edit-content-text-field/dot-edit-content-text-field.component';
import { DotWYSIWYGFieldComponent } from '../../fields/dot-wysiwyg-field/dot-wysiwyg-field.component';
import { FIELD_TYPES } from '../../models/dot-edit-content-field.enum';
import { DotEditContentService } from '../../services/dot-edit-content.service';
import {
Expand Down Expand Up @@ -122,6 +124,10 @@ const FIELD_TYPES_COMPONENTS: Record<FIELD_TYPES, Type<unknown> | DotEditFieldTe
component: DotEditContentKeyValueComponent,
declarations: [MockComponent(DotKeyValueComponent)],
providers: [mockProvider(DotMessageDisplayService)]
},
[FIELD_TYPES.WYSIWYG]: {
component: DotWYSIWYGFieldComponent,
declarations: [MockComponent(EditorComponent)]
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { DotFieldRequiredDirective } from '@dotcms/ui';
import { DotEditContentBinaryFieldComponent } from '../../fields/dot-edit-content-binary-field/dot-edit-content-binary-field.component';
import { DotEditContentFieldsModule } from '../../fields/dot-edit-content-fields.module';
import { DotEditContentKeyValueComponent } from '../../fields/dot-edit-content-key-value/dot-edit-content-key-value.component';
import { DotWYSIWYGFieldComponent } from '../../fields/dot-wysiwyg-field/dot-wysiwyg-field.component';
import { CALENDAR_FIELD_TYPES } from '../../models/dot-edit-content-field.constant';
import { FIELD_TYPES } from '../../models/dot-edit-content-field.enum';

Expand All @@ -33,7 +34,8 @@ import { FIELD_TYPES } from '../../models/dot-edit-content-field.enum';
DotFieldRequiredDirective,
BlockEditorModule,
DotEditContentBinaryFieldComponent,
DotEditContentKeyValueComponent
DotEditContentKeyValueComponent,
DotWYSIWYGFieldComponent
]
})
export class DotEditContentFieldComponent {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<editor [formControlName]="field.variable" [plugins]="plugins()" [toolbar]="toolbar()"> </editor>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
:host::ng-deep {
// Hide the promotion button
// This button redirect to the tinyMCE premium page
.tox-promotion {
display: none;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Spectator, createComponentFactory } from '@ngneat/spectator';
import { EditorComponent, EditorModule } from '@tinymce/tinymce-angular';
import { MockComponent } from 'ng-mocks';

import {
ControlContainer,
FormGroupDirective,
FormsModule,
ReactiveFormsModule
} from '@angular/forms';

import { DotWYSIWYGFieldComponent } from './dot-wysiwyg-field.component';

import { WYSIWYG_MOCK, createFormGroupDirectiveMock } from '../../utils/mocks';

const ALL_PLUGINS =
'advlist autolink lists link image charmap preview anchor pagebreak searchreplace wordcount visualblocks visualchars code fullscreen insertdatetime media nonbreaking save table directionality emoticons template';
const ALL_TOOLBAR_ITEMS =
'paste print textpattern | insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image hr | preview | validation media | forecolor dotimageclipboard backcolor emoticons';

describe('DotWYSIWYGFieldComponent', () => {
let spectator: Spectator<DotWYSIWYGFieldComponent>;
const createComponent = createComponentFactory({
component: DotWYSIWYGFieldComponent,
imports: [EditorModule, FormsModule, ReactiveFormsModule],
declarations: [MockComponent(EditorComponent)],
componentViewProviders: [
{
provide: ControlContainer,
useValue: createFormGroupDirectiveMock()
}
],
providers: [FormGroupDirective]
});

beforeEach(() => {
spectator = createComponent({
props: {
field: WYSIWYG_MOCK
}
});
});

it('should instance WYSIWYG editor and set the correct plugins and toolbar items', () => {
const editor = spectator.query(EditorComponent);
expect(editor).toBeTruthy();
expect(editor.plugins).toEqual(ALL_PLUGINS);
expect(editor.toolbar).toEqual(ALL_TOOLBAR_ITEMS);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { EditorModule, TINYMCE_SCRIPT_SRC } from '@tinymce/tinymce-angular';

import { ChangeDetectionStrategy, Component, Input, inject, signal } from '@angular/core';
import { ControlContainer, FormsModule, ReactiveFormsModule } from '@angular/forms';

import { DotCMSContentTypeField } from '@dotcms/dotcms-models';

@Component({
selector: 'dot-wysiwyg-field',
standalone: true,
imports: [EditorModule, FormsModule, ReactiveFormsModule],
templateUrl: './dot-wysiwyg-field.component.html',
styleUrl: './dot-wysiwyg-field.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [{ provide: TINYMCE_SCRIPT_SRC, useValue: 'tinymce/tinymce.min.js' }],
viewProviders: [
{
provide: ControlContainer,
useFactory: () => inject(ControlContainer, { skipSelf: true })
}
]
})
export class DotWYSIWYGFieldComponent {
@Input() field!: DotCMSContentTypeField;

protected readonly plugins = signal(
'advlist autolink lists link image charmap preview anchor pagebreak searchreplace wordcount visualblocks visualchars code fullscreen insertdatetime media nonbreaking save table directionality emoticons template'
);
protected readonly toolbar = signal(
'paste print textpattern | insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image hr | preview | validation media | forecolor dotimageclipboard backcolor emoticons'
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ export enum FIELD_TYPES {
BINARY = 'Binary',
CUSTOM_FIELD = 'Custom-Field',
JSON = 'JSON-Field',
KEY_VALUE = 'Key-Value'
KEY_VALUE = 'Key-Value',
WYSIWYG = 'WYSIWYG'
}
27 changes: 26 additions & 1 deletion core-web/libs/edit-content/src/lib/utils/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,30 @@ export const KEY_VALUE_MOCK: DotCMSContentTypeField = {
variable: 'KeyValue'
};

export const WYSIWYG_MOCK: DotCMSContentTypeField = {
clazz: 'com.dotcms.contenttype.model.field.ImmutableWYSIWYGField',
contentTypeId: '93ebaff75f3e3887bea73ecd04588dc9',
dataType: 'TEXT',
fieldType: 'WYSIWYG',
fieldTypeLabel: 'WYSIWYG',
fieldVariables: [],
fixed: false,
hint: 'A hint text',
iDate: 1698291913000,
id: '96909fa20a00497cd3b766b52edac0ec',
indexed: false,
listed: false,
modDate: 1698291913000,
name: 'WYSIWYG',
readOnly: false,
required: false,
searchable: false,
sortOrder: 1,
unique: false,
values: '<p>HELLO</p>',
variable: 'WYSIWYG'
};

export const FIELDS_MOCK: DotCMSContentTypeField[] = [
TEXT_FIELD_MOCK,
TEXT_AREA_FIELD_MOCK,
Expand All @@ -560,7 +584,8 @@ export const FIELDS_MOCK: DotCMSContentTypeField[] = [
BINARY_FIELD_MOCK,
CUSTOM_FIELD_MOCK,
JSON_FIELD_MOCK,
KEY_VALUE_MOCK
KEY_VALUE_MOCK,
WYSIWYG_MOCK
];

export const FIELD_MOCK: DotCMSContentTypeField = TEXT_FIELD_MOCK;
Expand Down
2 changes: 2 additions & 0 deletions core-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"@nx/angular": "18.0.4",
"@swc/helpers": "~0.5.2",
"@tarekraafat/autocomplete.js": "^10.2.6",
"@tinymce/tinymce-angular": "^7.0.0",
"@tiptap/core": "^2.0.0-beta.218",
"@tiptap/extension-bubble-menu": "^2.0.0-beta.218",
"@tiptap/extension-character-count": "^2.0.0-beta.218",
Expand Down Expand Up @@ -126,6 +127,7 @@
"superstruct": "^1.0.3",
"terser": "^5.28.1",
"test": "^0.6.0",
"tinymce": "^6.8.3",
"tslib": "^2.3.0",
"uuid": "^9.0.0",
"zone.js": "0.14.2"
Expand Down
13 changes: 13 additions & 0 deletions core-web/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6122,6 +6122,14 @@
resolved "https://registry.npmjs.org/@thednp/shorty/-/shorty-2.0.0.tgz#e05e6754032c091f599ac0c4ed7efde6558bdedb"
integrity sha512-kwtLivCxYIoFfGIVU4NlZtfdA/zxZ6X8UcWaJrb7XqU3WQ4Q1p5IaZlLBfOVAO06WH5oWE87QUdK/dS56Wnfjg==

"@tinymce/tinymce-angular@^7.0.0":
version "7.0.0"
resolved "https://registry.npmjs.org/@tinymce/tinymce-angular/-/tinymce-angular-7.0.0.tgz#010de497d5774a8bdc5d5936bf4fb976adf05f56"
integrity sha512-IKNaG/ihlxE1XCfq6lzULbnsqZO9KNJtlpu5jo6JDJDL9zcFzj/N2A16Kk7rTj1yfmDoB1IXAk/BpMOvgDY8cg==
dependencies:
tinymce "^6.0.0 || ^5.5.0"
tslib "^2.3.0"

"@tiptap/core@^2.0.0-beta.218", "@tiptap/core@^2.2.2":
version "2.2.2"
resolved "https://registry.npmjs.org/@tiptap/core/-/core-2.2.2.tgz#7664197dafee890a5f42ba03b50c202bdf1da761"
Expand Down Expand Up @@ -21994,6 +22002,11 @@ tiny-relative-date@^1.3.0:
resolved "https://registry.npmjs.org/tiny-relative-date/-/tiny-relative-date-1.3.0.tgz#fa08aad501ed730f31cc043181d995c39a935e07"
integrity sha512-MOQHpzllWxDCHHaDno30hhLfbouoYlOI8YlMNtvKe1zXbjEVhbcEovQxvZrPvtiYW630GQDoMMarCnjfyfHA+A==

"tinymce@^6.0.0 || ^5.5.0", tinymce@^6.8.3:
version "6.8.3"
resolved "https://registry.npmjs.org/tinymce/-/tinymce-6.8.3.tgz#0025a4aaa4c24dc2a3e32e83dfda705d196fd802"
integrity sha512-3fCHKAeqT+xNwBVESf6iDbDV0VNwZNmfrkx9c/6Gz5iB8piMfaO6s7FvoiTrj1hf1gVbfyLTnz1DooI6DhgINQ==

tippy.js@^6.3.7:
version "6.3.7"
resolved "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz#8ccfb651d642010ed9a32ff29b0e9e19c5b8c61c"
Expand Down

0 comments on commit 6e0fce1

Please sign in to comment.