Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(UVE): Bring back inline editing for block editor fields in Headless #30638

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<dot-block-editor
[field]="contentlet.field"
[value]="contentlet.content"
[languageId]="contentlet.languageId"
[languageId]="contentlet.language"
(valueChange)="value.set($event)"
data-testId="dot-block-editor" />
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,12 @@ const messageServiceMock = new MockDotMessageService({
const EVENT_DATA = {
fieldName: 'testName',
contentType: 'Blog',
language: '2',
language: 2,
inode: 'testInode',
blockEditorContent: '{"field":"field value"}'
content: {
conent: [],
type: 'doc'
}
};

const contentTypeMock: DotCMSContentType = {
Expand Down Expand Up @@ -135,8 +138,8 @@ describe('DotBlockEditorSidebarComponent', () => {
const blockEditor = spectator.query(DotBlockEditorComponent);

expect(blockEditor.field).toEqual(BLOCK_EDITOR_FIELD);
expect(blockEditor.languageId).toBe(parseInt(EVENT_DATA.language));
expect(blockEditor.value).toEqual(JSON.parse(EVENT_DATA.blockEditorContent));
expect(blockEditor.languageId).toBe(EVENT_DATA.language);
expect(blockEditor.value).toEqual(EVENT_DATA.content);
expect(dotContentTypeService.getContentType).toHaveBeenCalledWith('Blog');
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { map, take } from 'rxjs/operators';
import { JSONContent } from '@tiptap/core';

import { BlockEditorModule } from '@dotcms/block-editor';
import { InlineEditorData } from '@dotcms/client';
import {
DotAlertConfirmService,
DotContentTypeService,
Expand All @@ -24,19 +25,11 @@ import { DotCMSContentTypeField } from '@dotcms/dotcms-models';
import { DotMessagePipe } from '@dotcms/ui';

export interface BlockEditorData {
content: { [key: string]: string };
field: DotCMSContentTypeField;
fieldName: string;
inode: string;
languageId: number;
}

export interface BlockEditorPayload {
fieldName: string;
contentType: string;
inode: string;
language: string;
blockEditorContent: string;
language: number;
content: JSONContent;
field: DotCMSContentTypeField;
}

export const INLINE_EDIT_BLOCK_EDITOR_EVENT = 'edit-block-editor';
Expand Down Expand Up @@ -83,24 +76,18 @@ export class DotBlockEditorSidebarComponent {
/**
* Open the sidebar with the block editor content
*
* @param {BlockEditorPayload} { fieldName, contentType, inode, language, blockEditorContent }
* @param {InlineEditorData} { fieldName, contentType, inode, language, blockEditorContent }
* @memberof DotBlockEditorSidebarComponent
*/
open({
fieldName,
contentType,
inode,
language,
blockEditorContent
}: BlockEditorPayload): void {
open({ inode, content, language, fieldName, contentType }: InlineEditorData): void {
this.#getEditorField({ fieldName, contentType }).subscribe({
next: (field) =>
this.contentlet.set({
inode,
field,
fieldName,
languageId: parseInt(language),
content: this.#getJsonContent(blockEditorContent)
content,
language,
fieldName
}),
error: (err) => console.error('Error getting contentlet ', err)
});
Expand Down Expand Up @@ -173,21 +160,4 @@ export class DotBlockEditorSidebarComponent {
.getContentType(contentType)
.pipe(map(({ fields }) => fields.find(({ variable }) => variable === fieldName)));
}

/**
* Parse the content to JSON
*
* @param {string} content
* @return {*} {JSONContent}
* @memberof DotBlockEditorSidebarComponent
*/
#getJsonContent(content: string): JSONContent {
try {
return JSON.parse(content);
} catch (e) {
console.error('Error parsing JSON content ', e);

return {};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -670,8 +670,11 @@ describe('EditEmaEditorComponent', () => {
new MessageEvent('message', {
origin: HOST,
data: {
action: CLIENT_ACTIONS.INIT_BLOCK_EDITOR_INLINE_EDITING,
payload: {}
action: CLIENT_ACTIONS.INIT_INLINE_EDITING,
payload: {
type: 'BLOCK_EDITOR',
data: {}
}
}
})
);
Expand Down Expand Up @@ -701,7 +704,7 @@ describe('EditEmaEditorComponent', () => {
new MessageEvent('message', {
origin: HOST,
data: {
action: CLIENT_ACTIONS.INIT_BLOCK_EDITOR_INLINE_EDITING,
action: CLIENT_ACTIONS.INIT_INLINE_EDITING,
payload: {}
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ import { ProgressBarModule } from 'primeng/progressbar';

import { takeUntil, catchError, filter, map, switchMap, tap, take } from 'rxjs/operators';

import { CLIENT_ACTIONS, NOTIFY_CLIENT } from '@dotcms/client';
import {
CLIENT_ACTIONS,
NOTIFY_CLIENT,
INLINE_EDITING_EVENT_KEY,
InlineEditEventData
} from '@dotcms/client';
import {
DotMessageService,
DotCopyContentService,
Expand Down Expand Up @@ -863,12 +868,6 @@ export class EditEmaEditorComponent implements OnInit, OnDestroy {
[CLIENT_ACTIONS.IFRAME_SCROLL_END]: () => {
this.uveStore.updateEditorOnScrollEnd();
},
[CLIENT_ACTIONS.INIT_INLINE_EDITING]: () => {
// The iframe says that the editor is ready to start inline editing
// The dataset of the inline-editing contentlet is ready inside the service.
this.inlineEditingService.initEditor();
this.uveStore.setEditorState(EDITOR_STATE.INLINE_EDITING);
},
[CLIENT_ACTIONS.COPY_CONTENTLET_INLINE_EDITING]: (payload: {
dataset: InlineEditingContentletDataset;
}) => {
Expand Down Expand Up @@ -1001,22 +1000,10 @@ export class EditEmaEditorComponent implements OnInit, OnDestroy {
this.dotMessageService.get('editpage.content.contentlet.menu.reorder.title')
);
},
[CLIENT_ACTIONS.INIT_INLINE_EDITING]: (payload) =>
this.#handleInlineEditingEvent(payload),
[CLIENT_ACTIONS.NOOP]: () => {
/* Do Nothing because is not the origin we are expecting */
},
[CLIENT_ACTIONS.INIT_BLOCK_EDITOR_INLINE_EDITING]: (payload) => {
if (!this.uveStore.isEnterprise()) {
this.#dotAlertConfirmService.alert({
header: this.dotMessageService.get(
'dot.common.license.enterprise.only.error'
),
message: this.dotMessageService.get('editpage.not.lincese.error')
});

return;
}

this.blockSidebar?.open(payload);
}
};
const actionToExecute = CLIENT_ACTIONS_FUNC_MAP[action];
Expand Down Expand Up @@ -1365,4 +1352,44 @@ export class EditEmaEditorComponent implements OnInit, OnDestroy {
this.placeItem(payload, dragItem);
});
}

/**
* Handle the inline editing event
*
* @param {*} { type, data }
* @return {*}
* @memberof EditEmaEditorComponent
*/
#handleInlineEditingEvent({
type,
data
}: {
type: INLINE_EDITING_EVENT_KEY;
data?: InlineEditEventData;
}) {
if (!this.uveStore.isEnterprise()) {
this.#dotAlertConfirmService.alert({
header: this.dotMessageService.get('dot.common.license.enterprise.only.error'),
message: this.dotMessageService.get('editpage.not.lincese.error')
});

return;
}

switch (type) {
case 'BLOCK_EDITOR':
this.blockSidebar?.open(data);
break;

case 'WYSIWYG':
this.inlineEditingService.initEditor();
this.uveStore.setEditorState(EDITOR_STATE.INLINE_EDITING);
break;

default:
console.warn('Unknown block editor type', type);

break;
}
rjvelazco marked this conversation as resolved.
Show resolved Hide resolved
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ElementRef, Injectable, signal } from '@angular/core';

import { CLIENT_ACTIONS } from '@dotcms/client';

import { InlineEditingContentletDataset } from '../../edit-ema-editor/components/ema-page-dropzone/types';

declare global {
Expand Down Expand Up @@ -137,8 +139,10 @@ export class InlineEditService {

window.parent.postMessage(
{
action: 'init-inline-editing',
payload: {}
action: CLIENT_ACTIONS.INIT_INLINE_EDITING,
payload: {
type: 'WYSIWYG'
}
},
'*'
);
Expand Down
14 changes: 12 additions & 2 deletions core-web/libs/sdk/client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,19 @@ import {
DotCMSPageEditorConfig,
EditorConfig
} from './lib/editor/models/editor.model';
import {
InlineEditorData,
INLINE_EDITING_EVENT_KEY,
InlineEditEventData
} from './lib/editor/models/inline-event.model';
import { NOTIFY_CLIENT } from './lib/editor/models/listeners.model';
import {
destroyEditor,
editContentlet,
initEditor,
isInsideEditor,
updateNavigation
updateNavigation,
initInlineEditing
} from './lib/editor/sdk-editor';
import { getPageRequestParams, graphqlToPageEntity } from './lib/utils';

Expand All @@ -30,5 +36,9 @@ export {
initEditor,
updateNavigation,
destroyEditor,
ClientConfig
ClientConfig,
initInlineEditing,
InlineEditEventData,
InlineEditorData,
INLINE_EDITING_EVENT_KEY
rjvelazco marked this conversation as resolved.
Show resolved Hide resolved
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { editContentlet } from '../sdk-editor';
import { editContentlet, initInlineEditing } from '../sdk-editor';
declare global {
interface Window {
dotUVE: DotUVE;
Expand All @@ -7,6 +7,7 @@ declare global {

export const INITIAL_DOT_UVE: DotUVE = {
editContentlet,
initInlineEditing,
lastScrollYPosition: 0
};

Expand Down Expand Up @@ -70,10 +71,6 @@ export enum CLIENT_ACTIONS {
* Tell the editor to edit a contentlet
*/
EDIT_CONTENTLET = 'edit-contentlet',
/**
* Tell the editor to open the block editor sidebar
*/
INIT_BLOCK_EDITOR_INLINE_EDITING = 'init-editor-inline-editing',
/**
* Tell the editor to do nothing
*/
Expand Down Expand Up @@ -105,5 +102,6 @@ export function postMessageToEditor<T = unknown>(message: PostMessageProps<T>) {

export interface DotUVE {
editContentlet: typeof editContentlet;
initInlineEditing: typeof initInlineEditing;
lastScrollYPosition: number;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export type INLINE_EDITING_EVENT_KEY = 'BLOCK_EDITOR' | 'WYSIWYG';

export interface InlineEditorData {
inode: string;
language: number;
contentType: string;
fieldName: string;
content: Record<string, unknown>;
}

export type InlineEditEventData = InlineEditorData;
38 changes: 38 additions & 0 deletions core-web/libs/sdk/client/src/lib/editor/sdk-editor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { postMessageToEditor, CLIENT_ACTIONS } from './models/client.model';
import {
addClassToEmptyContentlets,
initEditor,
initInlineEditing,
isInsideEditor,
updateNavigation
} from './sdk-editor';
Expand Down Expand Up @@ -124,4 +125,41 @@ describe('DotCMSPageEditor', () => {
expect(contentlet.classList.contains('empty-contentlet')).toBe(false);
});
});

describe('initInlineEditing', () => {
it('should send the correct message to the editor to edit `block-editor`', () => {
const type = 'BLOCK_EDITOR';
const data = {
inode: '123',
language: 1,
contentType: 'text',
fieldName: 'body',
content: {}
};

initInlineEditing(type, data);

expect(postMessageToEditor).toHaveBeenCalledWith({
action: CLIENT_ACTIONS.INIT_INLINE_EDITING,
payload: {
type,
data
}
});
});

it('should send the correct message to the editor to edit `WYSIWYG`', () => {
const type = 'WYSIWYG';

initInlineEditing(type);

expect(postMessageToEditor).toHaveBeenCalledWith({
action: CLIENT_ACTIONS.INIT_INLINE_EDITING,
payload: {
type,
data: undefined
}
});
});
});
});
Loading