Skip to content

Commit 5b985dd

Browse files
committed
feat(editor): add tippy.js for enhanced tooltip functionality and integrate ConfirmationService in various components for improved user interactions
1 parent 90d47f6 commit 5b985dd

12 files changed

Lines changed: 110 additions & 44 deletions

File tree

core-web/libs/edit-content/src/lib/components/dot-create-content-dialog/dot-create-content-dialog.component.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { provideHttpClientTesting } from '@angular/common/http/testing';
66
import { NO_ERRORS_SCHEMA } from '@angular/core';
77
import { ActivatedRoute } from '@angular/router';
88

9-
import { MessageService } from 'primeng/api';
9+
import { ConfirmationService, MessageService } from 'primeng/api';
1010
import { DynamicDialogRef, DynamicDialogConfig, DialogService } from 'primeng/dynamicdialog';
1111

1212
import {
@@ -63,6 +63,7 @@ describe('DotEditContentDialogComponent', () => {
6363
}),
6464
mockProvider(DotWorkflowActionsFireService),
6565
mockProvider(MessageService),
66+
ConfirmationService,
6667
mockProvider(DotMessageService, {
6768
get: jest.fn(() => 'Test Message'),
6869
init: jest.fn(() => of({}))

core-web/libs/edit-content/src/lib/components/dot-edit-content-field/dot-edit-content-field.component.spec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ import {
1616
ReactiveFormsModule
1717
} from '@angular/forms';
1818

19+
import { ConfirmationService } from 'primeng/api';
1920
import { DialogService } from 'primeng/dynamicdialog';
2021

2122
import { BlockEditorModule } from '@dotcms/block-editor';
2223
import {
24+
DotContentTypeService,
2325
DotHttpErrorManagerService,
2426
DotLicenseService,
2527
DotMessageDisplayService,
@@ -28,6 +30,7 @@ import {
2830
DotWorkflowActionsFireService
2931
} from '@dotcms/data-access';
3032
import { DotCMSBaseTypesContentTypes, DotCMSContentType } from '@dotcms/dotcms-models';
33+
import { DotCMSEditorComponent } from '@dotcms/new-block-editor';
3134
import { GlobalStore } from '@dotcms/store';
3235
import { DotKeyValueComponent, DotLanguageVariableSelectorComponent } from '@dotcms/ui';
3336
import { monacoMock } from '@dotcms/utils-testing';
@@ -70,6 +73,8 @@ interface DotEditFieldTestBed {
7073
imports?: Type<unknown>[];
7174
providers?: Provider[];
7275
declarations?: Type<unknown>[];
76+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
77+
overrideComponents?: any[];
7378
props?: { [key: string]: unknown }[]; // ContentField Props, that we need to pass to the component inside
7479
outsideFormControl?: boolean; //If the component have [formControlName] hardcoded inside this ContentField component
7580
}
@@ -150,6 +155,15 @@ const FIELD_TYPES_COMPONENTS: Record<FIELD_TYPES, Type<unknown> | DotEditFieldTe
150155
}
151156
}
152157
],
158+
overrideComponents: [
159+
[
160+
DotEditContentBlockEditorComponent,
161+
{
162+
remove: { imports: [DotCMSEditorComponent] },
163+
add: { imports: [MockComponent(DotCMSEditorComponent)] }
164+
}
165+
]
166+
],
153167
outsideFormControl: true
154168
},
155169
[FIELD_TYPES.CUSTOM_FIELD]: {
@@ -262,11 +276,14 @@ describe.each([...FIELDS_TO_BE_RENDER])('DotEditContentFieldComponent all fields
262276
imports: [DotEditContentFieldComponent, ...(fieldTestBed?.imports || [])],
263277
declarations: [...(fieldTestBed?.declarations || [])],
264278
component: DotEditContentFieldComponent,
279+
overrideComponents: fieldTestBed?.overrideComponents ?? [],
265280
providers: [
266281
FormGroupDirective,
267282
provideHttpClient(),
268283
provideHttpClientTesting(),
269284
...(fieldTestBed?.providers || []),
285+
ConfirmationService,
286+
mockProvider(DotContentTypeService),
270287
mockProvider(GlobalStore, {
271288
systemConfig: signal({
272289
systemTimezone: {

core-web/libs/edit-content/src/lib/components/dot-edit-content-form/dot-edit-content-form.component.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { fakeAsync, flush, tick } from '@angular/core/testing';
1515
import { Validators } from '@angular/forms';
1616
import { ActivatedRoute, Router } from '@angular/router';
1717

18-
import { MessageService } from 'primeng/api';
18+
import { ConfirmationService, MessageService } from 'primeng/api';
1919
import { DialogService } from 'primeng/dynamicdialog';
2020
import { Tab, Tabs } from 'primeng/tabs';
2121
import { ToggleSwitch, ToggleSwitchChangeEvent } from 'primeng/toggleswitch';
@@ -93,6 +93,7 @@ describe('DotFormComponent', () => {
9393
mockProvider(DotWorkflowService),
9494
mockProvider(DotContentletService),
9595
mockProvider(MessageService),
96+
ConfirmationService,
9697
mockProvider(DialogService),
9798
mockProvider(DotWorkflowEventHandlerService),
9899
mockProvider(DotWizardService, {

core-web/libs/edit-content/src/lib/components/dot-edit-content-layout/dot-edit-content.layout.component.spec.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { provideHttpClientTesting } from '@angular/common/http/testing';
1313
import { fakeAsync, tick } from '@angular/core/testing';
1414
import { ActivatedRoute, Router } from '@angular/router';
1515

16-
import { MessageService } from 'primeng/api';
16+
import { ConfirmationService, MessageService } from 'primeng/api';
1717
import { ButtonModule } from 'primeng/button';
1818
import { ConfirmDialog } from 'primeng/confirmdialog';
1919
import { DialogService } from 'primeng/dynamicdialog';
@@ -86,7 +86,8 @@ describe('EditContentLayoutComponent', () => {
8686
mockProvider(DotContentTypeService),
8787
mockProvider(DotWorkflowService),
8888
mockProvider(DotContentletService),
89-
mockProvider(DotVersionableService)
89+
mockProvider(DotVersionableService),
90+
ConfirmationService
9091
],
9192
providers: [
9293
mockProvider(DotHttpErrorManagerService),

core-web/libs/edit-content/src/lib/fields/dot-edit-content-block-editor/dot-edit-content-block-editor.component.spec.ts

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import { SpectatorHost, createHostFactory } from '@ngneat/spectator';
1+
import { SpectatorHost, createHostFactory } from '@ngneat/spectator/jest';
2+
import { MockComponent } from 'ng-mocks';
23

34
import { Component, signal } from '@angular/core';
45
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
56
import { By } from '@angular/platform-browser';
67

7-
import { BlockEditorModule, DotBlockEditorComponent } from '@dotcms/block-editor';
88
import { DotCMSContentlet, DotCMSContentTypeField } from '@dotcms/dotcms-models';
9+
import { DotCMSEditorComponent } from '@dotcms/new-block-editor';
910
import { createFakeContentlet } from '@dotcms/utils-testing';
1011

1112
import { DotEditContentBlockEditorComponent } from './dot-edit-content-block-editor.component';
@@ -54,7 +55,16 @@ describe('DotEditContentBlockEditorComponent', () => {
5455
const createHost = createHostFactory({
5556
component: DotEditContentBlockEditorComponent,
5657
host: MockFormComponent,
57-
imports: [ReactiveFormsModule, BlockEditorModule],
58+
imports: [ReactiveFormsModule],
59+
overrideComponents: [
60+
[
61+
DotEditContentBlockEditorComponent,
62+
{
63+
remove: { imports: [DotCMSEditorComponent] },
64+
add: { imports: [MockComponent(DotCMSEditorComponent)] }
65+
}
66+
]
67+
],
5868
providers: [
5969
{
6070
provide: DotEditContentStore,
@@ -101,38 +111,47 @@ describe('DotEditContentBlockEditorComponent', () => {
101111

102112
// Access the component instance to verify the languageId property
103113
const blockEditorDebugElement = spectator.debugElement.query(By.css('dot-block-editor'));
104-
const blockEditorComponent =
105-
blockEditorDebugElement?.componentInstance as DotBlockEditorComponent;
114+
const blockEditorComponent = blockEditorDebugElement?.componentInstance as Record<
115+
string,
116+
unknown
117+
>;
106118
expect(blockEditorComponent.languageId).toBe(2);
107119
});
108120

109121
it('should pass the correct field to dot-block-editor', () => {
110122
spectator.detectChanges();
111123

112124
const blockEditorDebugElement = spectator.debugElement.query(By.css('dot-block-editor'));
113-
const blockEditorComponent =
114-
blockEditorDebugElement?.componentInstance as DotBlockEditorComponent;
125+
const blockEditorComponent = blockEditorDebugElement?.componentInstance as Record<
126+
string,
127+
unknown
128+
>;
115129
expect(blockEditorComponent.field).toEqual(BLOCK_EDITOR_FIELD_MOCK);
116130
});
117131

118132
it('should pass the correct contentlet to dot-block-editor', () => {
119133
spectator.detectChanges();
120134

121135
const blockEditorDebugElement = spectator.debugElement.query(By.css('dot-block-editor'));
122-
const blockEditorComponent =
123-
blockEditorDebugElement?.componentInstance as DotBlockEditorComponent;
124-
expect(blockEditorComponent.contentlet).toBeTruthy();
125-
expect(blockEditorComponent.contentlet[BLOCK_EDITOR_FIELD_MOCK.variable]).toBe('');
136+
const blockEditorComponent = blockEditorDebugElement?.componentInstance as Record<
137+
string,
138+
unknown
139+
>;
140+
const contentlet = blockEditorComponent.contentlet as DotCMSContentlet;
141+
expect(contentlet).toBeTruthy();
142+
expect(contentlet[BLOCK_EDITOR_FIELD_MOCK.variable]).toBe('');
126143
});
127144

128145
it('should pass hasFieldError to dot-block-editor', () => {
129146
spectator.detectChanges();
130147

131148
const blockEditorDebugElement = spectator.debugElement.query(By.css('dot-block-editor'));
132-
const blockEditorComponent =
133-
blockEditorDebugElement?.componentInstance as DotBlockEditorComponent;
149+
const blockEditorComponent = blockEditorDebugElement?.componentInstance as Record<
150+
string,
151+
unknown
152+
>;
134153
// Initially should be false (no errors)
135-
expect(blockEditorComponent.hasFieldError).toBe(false);
154+
expect(blockEditorComponent.hasError).toBe(false);
136155
});
137156

138157
it('should use formControlName from field variable', () => {

core-web/libs/portlets/edit-ema/portlet/src/lib/components/dot-block-editor-sidebar/dot-block-editor-sidebar.component.spec.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
import { byTestId, mockProvider, Spectator } from '@ngneat/spectator';
2-
import { createComponentFactory } from '@ngneat/spectator/jest';
1+
import { byTestId, createComponentFactory, mockProvider, Spectator } from '@ngneat/spectator/jest';
32
import { MockComponent } from 'ng-mocks';
43
import { of, throwError } from 'rxjs';
54

5+
import { ConfirmationService } from 'primeng/api';
66
import { Drawer } from 'primeng/drawer';
77

8-
import { BlockEditorModule, DotBlockEditorComponent } from '@dotcms/block-editor';
98
import {
109
DotAlertConfirmService,
1110
DotContentTypeService,
1211
DotMessageService,
1312
DotWorkflowActionsFireService
1413
} from '@dotcms/data-access';
1514
import { DotCMSContentType, DotCMSContentTypeField } from '@dotcms/dotcms-models';
15+
import { DotCMSEditorComponent } from '@dotcms/new-block-editor';
1616
import {
1717
dotcmsContentTypeBasicMock,
1818
MockDotMessageService,
@@ -95,10 +95,18 @@ describe('DotBlockEditorSidebarComponent', () => {
9595

9696
const createComponent = createComponentFactory({
9797
component: DotBlockEditorSidebarComponent,
98-
imports: [BlockEditorModule],
99-
declarations: [MockComponent(DotBlockEditorComponent)],
98+
overrideComponents: [
99+
[
100+
DotBlockEditorSidebarComponent,
101+
{
102+
remove: { imports: [DotCMSEditorComponent] },
103+
add: { imports: [MockComponent(DotCMSEditorComponent)] }
104+
}
105+
]
106+
],
100107
providers: [
101108
DotAlertConfirmService,
109+
ConfirmationService,
102110
{ provide: DotMessageService, useValue: messageServiceMock },
103111
{
104112
provide: DotWorkflowActionsFireService,
@@ -132,7 +140,7 @@ describe('DotBlockEditorSidebarComponent', () => {
132140
});
133141

134142
it('should set inputs to the block editor', () => {
135-
const blockEditor = spectator.query(DotBlockEditorComponent);
143+
const blockEditor = spectator.query(DotCMSEditorComponent);
136144

137145
expect(blockEditor.field).toEqual(BLOCK_EDITOR_FIELD);
138146
expect(blockEditor.languageId).toBe(EVENT_DATA.language);
@@ -144,7 +152,7 @@ describe('DotBlockEditorSidebarComponent', () => {
144152
const spyWorkflowService = jest
145153
.spyOn(dotWorkflowActionsFireService, 'saveContentlet')
146154
.mockReturnValue(of({}));
147-
const blockEditor = spectator.query(DotBlockEditorComponent);
155+
const blockEditor = spectator.query(DotCMSEditorComponent);
148156

149157
const newValue = { data: 'test value 1' };
150158
blockEditor.valueChange.emit(newValue);
@@ -169,7 +177,7 @@ describe('DotBlockEditorSidebarComponent', () => {
169177
const spyWorkflowService = jest
170178
.spyOn(dotWorkflowActionsFireService, 'saveContentlet')
171179
.mockReturnValue(of({}));
172-
const blockEditor = spectator.query(DotBlockEditorComponent);
180+
const blockEditor = spectator.query(DotCMSEditorComponent);
173181

174182
spectator.setInput('variantName', 'my-experiment-variant');
175183

@@ -206,7 +214,7 @@ describe('DotBlockEditorSidebarComponent', () => {
206214
.spyOn(dotWorkflowActionsFireService, 'saveContentlet')
207215
.mockReturnValue(throwError(() => error404));
208216

209-
const blockEditor = spectator.query(DotBlockEditorComponent);
217+
const blockEditor = spectator.query(DotCMSEditorComponent);
210218
const newValue = { data: 'test value 1' };
211219
blockEditor.valueChange.emit(newValue);
212220

core-web/libs/portlets/edit-ema/portlet/src/lib/dot-ema-shell/dot-ema-shell.component.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { DialogService } from 'primeng/dynamicdialog';
2424
import {
2525
DotAnalyticsTrackerService,
2626
DotContentletLockerService,
27+
DotContentTypeService,
2728
DotCurrentUserService,
2829
DotExperimentsService,
2930
DotLanguagesService,
@@ -254,6 +255,7 @@ describe('DotEmaShellComponent', () => {
254255
MessageService,
255256
UVEStore,
256257
ConfirmationService,
258+
mockProvider(DotContentTypeService),
257259
DotActionUrlService,
258260
DotMessageService,
259261
DialogService,

core-web/libs/portlets/edit-ema/ui/src/lib/dot-content-compare/components/dot-content-compare-block-editor/block-editor-mock/block-editor-mock.component.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import {
44
EventEmitter,
55
Input,
66
OnInit,
7-
Output
7+
Output,
8+
signal
89
} from '@angular/core';
910

1011
import { Editor, JSONContent } from '@tiptap/core';
@@ -18,26 +19,27 @@ import StarterKit from '@tiptap/starter-kit';
1819
})
1920
export class BlockEditorMockComponent implements OnInit {
2021
@Input() value: JSONContent;
21-
editor: Editor;
22+
readonly editor = signal<Editor | null>(null);
2223
@Output() valueChange = new EventEmitter<JSONContent>();
2324

2425
ngOnInit() {
25-
this.editor = new Editor({
26+
const editor = new Editor({
2627
extensions: [StarterKit]
2728
});
2829

29-
this.editor.on('create', () => {
30+
editor.on('create', () => {
3031
if (this.value) {
31-
this.editor.commands.setContent(this.value, false);
32-
// Emit valueChange after setting content
32+
editor.commands.setContent(this.value, { emitUpdate: false });
3333
setTimeout(() => {
34-
this.valueChange.emit(this.editor.getJSON());
34+
this.valueChange.emit(editor.getJSON());
3535
}, 0);
3636
}
3737
});
3838

39-
this.editor.on('update', () => {
40-
this.valueChange.emit(this.editor.getJSON());
39+
editor.on('update', () => {
40+
this.valueChange.emit(editor.getJSON());
4141
});
42+
43+
this.editor.set(editor);
4244
}
4345
}

core-web/libs/portlets/edit-ema/ui/src/lib/dot-content-compare/components/dot-content-compare-block-editor/dot-content-compare-block-editor.component.spec.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -342,12 +342,12 @@ describe('DotContentCompareBlockEditorComponent', () => {
342342
const blockEditor = spectator.component
343343
.blockEditor as unknown as BlockEditorMockComponent;
344344
expect(blockEditor).toBeDefined();
345-
expect(blockEditor.editor).toBeDefined();
345+
expect(blockEditor.editor()).toBeDefined();
346346

347347
const workingEl = spectator.query(byTestId('div-working'));
348348
expect(workingEl).toBeTruthy();
349349
const workingField = workingEl?.innerHTML;
350-
const editorHTML = blockEditor.editor.getHTML();
350+
const editorHTML = blockEditor.editor()?.getHTML();
351351

352352
expect(workingField).toEqual(editorHTML);
353353
});
@@ -371,14 +371,14 @@ describe('DotContentCompareBlockEditorComponent', () => {
371371
.blockEditorCompare as unknown as BlockEditorMockComponent;
372372

373373
expect(blockEditor).toBeDefined();
374-
expect(blockEditor.editor).toBeDefined();
374+
expect(blockEditor.editor()).toBeDefined();
375375
expect(blockEditorCompare).toBeDefined();
376-
expect(blockEditorCompare.editor).toBeDefined();
376+
expect(blockEditorCompare.editor()).toBeDefined();
377377

378378
const pipe = new DotDiffPipe();
379379
const diff = pipe.transform(
380-
blockEditor.editor.getHTML(),
381-
blockEditorCompare.editor.getHTML()
380+
blockEditor.editor()?.getHTML() ?? '',
381+
blockEditorCompare.editor()?.getHTML() ?? ''
382382
);
383383

384384
const compareEl = spectator.query(byTestId('div-compare'));
@@ -404,12 +404,12 @@ describe('DotContentCompareBlockEditorComponent', () => {
404404
.blockEditorCompare as unknown as BlockEditorMockComponent;
405405

406406
expect(blockEditorCompare).toBeDefined();
407-
expect(blockEditorCompare.editor).toBeDefined();
407+
expect(blockEditorCompare.editor()).toBeDefined();
408408

409409
const compareEl = spectator.query(byTestId('div-compare'));
410410
expect(compareEl).toBeTruthy();
411411
const compareField = compareEl?.innerHTML;
412-
const editorHTML = blockEditorCompare.editor.getHTML();
412+
const editorHTML = blockEditorCompare.editor()?.getHTML();
413413

414414
expect(compareField).toEqual(editorHTML);
415415
});

0 commit comments

Comments
 (0)