From cbae64927f9dd0246bad1bb3315b9bf68ac5125c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Ostafin?= Date: Thu, 19 Oct 2023 09:34:27 +0200 Subject: [PATCH] IBX-6315: Edit/Preview embedded items (#123) --- .../content-inline/embed-inline-command.js | 4 +- .../content-inline/embed-inline-editing.js | 57 +++++++++++++++-- .../embed/content-inline/embed-inline-ui.js | 11 +++- .../CKEditor/embed/content/embed-command.js | 4 +- .../CKEditor/embed/content/embed-editing.js | 61 ++++++++++++++++--- .../js/CKEditor/embed/content/embed-ui.js | 11 +++- 6 files changed, 127 insertions(+), 21 deletions(-) diff --git a/src/bundle/Resources/public/js/CKEditor/embed/content-inline/embed-inline-command.js b/src/bundle/Resources/public/js/CKEditor/embed/content-inline/embed-inline-command.js index fa9cd40a..9cc52e7b 100644 --- a/src/bundle/Resources/public/js/CKEditor/embed/content-inline/embed-inline-command.js +++ b/src/bundle/Resources/public/js/CKEditor/embed/content-inline/embed-inline-command.js @@ -7,8 +7,8 @@ class IbexaEmbedContentInlineCommand extends Command { }); } - createEmbed(writer, { contentId, contentName }) { - return writer.createElement('embedInline', { contentId, contentName }); + createEmbed(writer, { contentId, contentName, locationId, languageCodes }) { + return writer.createElement('embedInline', { contentId, contentName, locationId, languageCodes }); } } diff --git a/src/bundle/Resources/public/js/CKEditor/embed/content-inline/embed-inline-editing.js b/src/bundle/Resources/public/js/CKEditor/embed/content-inline/embed-inline-editing.js index f59c98f3..262acb19 100644 --- a/src/bundle/Resources/public/js/CKEditor/embed/content-inline/embed-inline-editing.js +++ b/src/bundle/Resources/public/js/CKEditor/embed/content-inline/embed-inline-editing.js @@ -6,11 +6,27 @@ import IbexaEmbedContentInlineCommand from './embed-inline-command'; import { findContent } from '../../services/content-service'; -const renderPreview = (title) => { +const renderPreview = (title, contentId) => { return ` - - - ${title}`; + + + + ${title} + + + + `; }; class IbexaEmbedContentInlineEditing extends Plugin { @@ -25,7 +41,7 @@ class IbexaEmbedContentInlineEditing extends Plugin { isObject: true, isInline: true, allowWhere: '$text', - allowAttributes: ['contentId', 'contentName'], + allowAttributes: ['contentId', 'contentName', 'locationId', 'languageCodes'], }); } @@ -57,13 +73,35 @@ class IbexaEmbedContentInlineEditing extends Plugin { }) .add((dispatcher) => dispatcher.on('attribute:contentName', (event, data, conversionApi) => { + const { editor } = this; const downcastWriter = conversionApi.writer; const modelElement = data.item; const viewElement = conversionApi.mapper.toViewElement(modelElement); const preview = downcastWriter.createUIElement('span', { class: 'ibexa-embed-content' }, function (domDocument) { + const contentId = modelElement.getAttribute('contentId'); + const contentName = modelElement.getAttribute('contentName'); + const locationId = modelElement.getAttribute('locationId'); + const languageCodes = modelElement.getAttribute('languageCodes'); const domElement = this.toDomElement(domDocument); - domElement.innerHTML = renderPreview(modelElement.getAttribute('contentName')); + domElement.innerHTML = renderPreview(contentName, contentId); + + const itemActionsTriggerElement = domElement.querySelector('.ibexa-embedded-item__actions-menu-trigger-btn'); + const itemActionsMenuContainer = editor.sourceElement.parentNode.querySelector( + '.ibexa-embedded-item-actions .ibexa-multilevel-popup-menu', + ); + + domDocument.body.dispatchEvent( + new CustomEvent('ibexa-embedded-item:create-dynamic-menu', { + detail: { + contentId, + locationId, + languageCodes, + menuTriggerElement: itemActionsTriggerElement, + menuContainer: itemActionsMenuContainer, + }, + }), + ); return domElement; }); @@ -106,9 +144,16 @@ class IbexaEmbedContentInlineEditing extends Plugin { findContent({ token, siteaccess, contentId }, (contents) => { const contentName = contents[0].TranslatedName; + const locationId = contents[0].MainLocation._href.split('/').pop(); + const languageCodes = contents[0].CurrentVersion.Version.VersionInfo.VersionTranslationInfo.Language.map( + (language) => language.languageCode, + ); this.editor.model.change((writer) => { writer.setAttribute('contentName', contentName, modelElement); + writer.setAttribute('contentId', contentId, modelElement); + writer.setAttribute('locationId', locationId, modelElement); + writer.setAttribute('languageCodes', languageCodes, modelElement); }); }); diff --git a/src/bundle/Resources/public/js/CKEditor/embed/content-inline/embed-inline-ui.js b/src/bundle/Resources/public/js/CKEditor/embed/content-inline/embed-inline-ui.js index 5ea9c66b..df5901f3 100644 --- a/src/bundle/Resources/public/js/CKEditor/embed/content-inline/embed-inline-ui.js +++ b/src/bundle/Resources/public/js/CKEditor/embed/content-inline/embed-inline-ui.js @@ -14,9 +14,16 @@ class IbexaEmbedContentInlineUI extends IbexaEmbedBaseUI { } getCommandOptions(items) { + const location = items[0]; + const content = location.ContentInfo.Content; + return { - contentId: items[0].ContentInfo.Content._id, - contentName: items[0].ContentInfo.Content.TranslatedName, + contentId: content._id, + contentName: content.TranslatedName, + locationId: location.id, + languageCodes: content.CurrentVersion.Version.VersionInfo.VersionTranslationInfo.Language.map( + (language) => language.languageCode, + ), }; } } diff --git a/src/bundle/Resources/public/js/CKEditor/embed/content/embed-command.js b/src/bundle/Resources/public/js/CKEditor/embed/content/embed-command.js index 663459a9..896b294e 100644 --- a/src/bundle/Resources/public/js/CKEditor/embed/content/embed-command.js +++ b/src/bundle/Resources/public/js/CKEditor/embed/content/embed-command.js @@ -9,8 +9,8 @@ class IbexaEmbedContentCommand extends Command { }); } - createEmbed(writer, { contentId, contentName }) { - return writer.createElement('embed', { contentId, contentName }); + createEmbed(writer, { contentId, contentName, locationId, languageCodes }) { + return writer.createElement('embed', { contentId, contentName, locationId, languageCodes }); } } diff --git a/src/bundle/Resources/public/js/CKEditor/embed/content/embed-editing.js b/src/bundle/Resources/public/js/CKEditor/embed/content/embed-editing.js index 9e8be02e..c001c8b0 100644 --- a/src/bundle/Resources/public/js/CKEditor/embed/content/embed-editing.js +++ b/src/bundle/Resources/public/js/CKEditor/embed/content/embed-editing.js @@ -6,11 +6,27 @@ import IbexaEmbedContentCommand from './embed-command'; import { findContent } from '../../services/content-service'; -const renderPreview = (title) => { +const renderPreview = (title, contentId) => { return ` - - - ${title}`; + + + + ${title} + + + + `; }; class IbexaEmbedContentEditing extends Plugin { @@ -24,7 +40,7 @@ class IbexaEmbedContentEditing extends Plugin { schema.register('embed', { isObject: true, allowWhere: '$block', - allowAttributes: ['contentId', 'contentName'], + allowAttributes: ['contentId', 'contentName', 'locationId', 'languageCodes'], }); } @@ -43,9 +59,11 @@ class IbexaEmbedContentEditing extends Plugin { class: 'ibexa-embed', }); const preview = downcastWriter.createUIElement('p', { class: 'ibexa-embed-content' }, function (domDocument) { + const contentId = modelElement.getAttribute('contentId'); + const contentName = modelElement.getAttribute('contentName'); const domElement = this.toDomElement(domDocument); - domElement.innerHTML = renderPreview(modelElement.getAttribute('contentName')); + domElement.innerHTML = renderPreview(contentName, contentId); return domElement; }); @@ -57,13 +75,35 @@ class IbexaEmbedContentEditing extends Plugin { }) .add((dispatcher) => dispatcher.on('attribute:contentName', (event, data, conversionApi) => { + const { editor } = this; const downcastWriter = conversionApi.writer; const modelElement = data.item; const viewElement = conversionApi.mapper.toViewElement(modelElement); const preview = downcastWriter.createUIElement('p', { class: 'ibexa-embed-content' }, function (domDocument) { + const contentId = modelElement.getAttribute('contentId'); + const contentName = modelElement.getAttribute('contentName'); + const locationId = modelElement.getAttribute('locationId'); + const languageCodes = modelElement.getAttribute('languageCodes'); const domElement = this.toDomElement(domDocument); - domElement.innerHTML = renderPreview(modelElement.getAttribute('contentName')); + domElement.innerHTML = renderPreview(contentName); + + const itemActionsTriggerElement = domElement.querySelector('.ibexa-embedded-item-actions__menu-trigger-btn'); + const itemActionsMenuContainer = editor.sourceElement.parentNode.querySelector( + '.ibexa-embedded-item-actions .ibexa-multilevel-popup-menu', + ); + + domDocument.body.dispatchEvent( + new CustomEvent('ibexa-embedded-item:create-dynamic-menu', { + detail: { + contentId, + locationId, + languageCodes, + menuTriggerElement: itemActionsTriggerElement, + menuContainer: itemActionsMenuContainer, + }, + }), + ); return domElement; }); @@ -106,9 +146,16 @@ class IbexaEmbedContentEditing extends Plugin { findContent({ token, siteaccess, contentId }, (contents) => { const contentName = contents[0].TranslatedName; + const locationId = contents[0].MainLocation._href.split('/').pop(); + const languageCodes = contents[0].CurrentVersion.Version.VersionInfo.VersionTranslationInfo.Language.map( + (language) => language.languageCode, + ); this.editor.model.change((writer) => { writer.setAttribute('contentName', contentName, modelElement); + writer.setAttribute('contentId', contentId, modelElement); + writer.setAttribute('locationId', locationId, modelElement); + writer.setAttribute('languageCodes', languageCodes, modelElement); }); }); diff --git a/src/bundle/Resources/public/js/CKEditor/embed/content/embed-ui.js b/src/bundle/Resources/public/js/CKEditor/embed/content/embed-ui.js index 46062b93..31a46bfc 100644 --- a/src/bundle/Resources/public/js/CKEditor/embed/content/embed-ui.js +++ b/src/bundle/Resources/public/js/CKEditor/embed/content/embed-ui.js @@ -14,9 +14,16 @@ class IbexaEmbedContentUI extends IbexaEmbedBaseUI { } getCommandOptions(items) { + const location = items[0]; + const content = location.ContentInfo.Content; + return { - contentId: items[0].ContentInfo.Content._id, - contentName: items[0].ContentInfo.Content.TranslatedName, + contentId: content._id, + contentName: content.TranslatedName, + locationId: location.id, + languageCodes: content.CurrentVersion.Version.VersionInfo.VersionTranslationInfo.Language.map( + (language) => language.languageCode, + ), }; } }