From 94b1c7c6699d122b8e0faeb183e8cd2f461d06ea Mon Sep 17 00:00:00 2001 From: JesmoDev <26099018+JesmoDev@users.noreply.github.com> Date: Fri, 27 Sep 2024 14:22:56 +0200 Subject: [PATCH] extensions config --- .../rte/tiptap/property-editors/manifests.ts | 11 + ...tiptap-extensions-configuration.element.ts | 190 ++++++++++++++++++ .../property-editors/tiptap/manifests.ts | 7 + 3 files changed, 208 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/property-editors/property-editor-ui-tiptap-extensions-configuration.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/property-editors/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/property-editors/manifests.ts index 71f28f1a7c..2d8c3c7d66 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/property-editors/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/property-editors/manifests.ts @@ -15,4 +15,15 @@ export const manifests: Array = [ group: 'common', }, }, + { + type: 'propertyEditorUi', + alias: 'Umb.PropertyEditorUi.Tiptap.ExtensionsConfiguration', + name: 'Tiptap Extensions Property Editor UI', + js: () => import('./property-editor-ui-tiptap-extensions-configuration.element.js'), + meta: { + label: 'Tiptap Extensions Configuration', + icon: 'icon-autofill', + group: 'common', + }, + }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/property-editors/property-editor-ui-tiptap-extensions-configuration.element.ts b/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/property-editors/property-editor-ui-tiptap-extensions-configuration.element.ts new file mode 100644 index 0000000000..16d24d3a63 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/property-editors/property-editor-ui-tiptap-extensions-configuration.element.ts @@ -0,0 +1,190 @@ +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import type { PropertyValueMap } from '@umbraco-cms/backoffice/external/lit'; +import { customElement, css, html, property, state, repeat } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { umbExtensionsRegistry, type UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry'; +import { + UmbPropertyValueChangeEvent, + type UmbPropertyEditorConfigCollection, +} from '@umbraco-cms/backoffice/property-editor'; + +type ExtensionConfig = { + alias: string; + label: string; + icon?: string; + category: string; +}; + +type ExtensionCategoryItem = { + alias: string; + label: string; + icon?: string; + selected: boolean; +}; + +type ExtensionCategory = { + category: string; + extensions: ExtensionCategoryItem[]; +}; + +@customElement('umb-property-editor-ui-tiptap-extensions-configuration') +export class UmbPropertyEditorUiTiptapExtensionsConfigurationElement + extends UmbLitElement + implements UmbPropertyEditorUiElement +{ + @property({ attribute: false }) + set value(value: string[]) { + if (!value) value = []; + this.#value = value; + } + get value(): string[] { + return this.#value; + } + + #value: string[] = []; + + @property({ attribute: false }) + config?: UmbPropertyEditorConfigCollection; + + @state() + private _extensionCategories: ExtensionCategory[] = []; + + @state() + private _extensionConfigs: ExtensionConfig[] = []; + + protected override async firstUpdated(_changedProperties: PropertyValueMap) { + super.firstUpdated(_changedProperties); + + this.observe(umbExtensionsRegistry.byType('tiptapExtension'), (extensions) => { + this._extensionConfigs = extensions.map((ext) => { + return { + alias: ext.alias, + label: ext.meta.label, + icon: ext.meta.icon, + category: '', + }; + }); + this.#setupExtensionCategories(); + }); + } + + #setupExtensionCategories() { + const withSelectedProperty = this._extensionConfigs.map((extensionConfig) => { + return { + ...extensionConfig, + selected: this.value.includes(extensionConfig.alias), + }; + }); + + const grouped = withSelectedProperty.reduce((acc: any, item) => { + const group = item.category || 'Uncategorized'; // Assign to "Uncategorized" if no group + if (!acc[group]) { + acc[group] = []; + } + acc[group].push(item); + return acc; + }, {}); + this._extensionCategories = Object.keys(grouped).map((group) => ({ + category: group.charAt(0).toUpperCase() + group.slice(1).replace(/-/g, ' '), + extensions: grouped[group], + })); + } + + #onExtensionClick(item: ExtensionCategoryItem) { + item.selected = !item.selected; + + if (item.selected) { + this.#value = [...this.value, item.alias]; + } else { + this.#value = this.value.filter((alias) => alias !== item.alias); + } + + this.requestUpdate('_extensionCategories'); + this.dispatchEvent(new UmbPropertyValueChangeEvent()); + } + + override render() { + return html` +
+ ${repeat( + this._extensionCategories, + (category) => html` +
+

${category.category}

+ ${repeat( + category.extensions, + (item) => + html`
+ this.#onExtensionClick(item)} + > + ${item.label} +
`, + )} +
+ `, + )} +
+ + `; + } + + static override readonly styles = [ + UmbTextStyles, + css` + uui-icon { + width: unset; + height: unset; + display: flex; + vertical-align: unset; + } + uui-button.selected { + --uui-button-border-color: var(--uui-color-selected); + --uui-button-border-width: 2px; + } + .extensions { + display: flex; + flex-wrap: wrap; + gap: 16px; + margin-top: 16px; + } + .extension-item { + display: grid; + grid-template-columns: 36px 1fr; + grid-template-rows: 1fr; + align-items: center; + gap: 9px; + } + .category { + flex: 1; + background-color: var(--uui-color-surface-alt); + padding: 12px; + border-radius: 6px; + display: flex; + flex-direction: column; + gap: 6px; + border: 1px solid var(--uui-color-border); + } + .category-name { + grid-column: 1 / -1; + margin: 0; + font-weight: bold; + display: flex; + } + `, + ]; +} + +export default UmbPropertyEditorUiTiptapExtensionsConfigurationElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-property-editor-ui-tiptap-extensions-configuration': UmbPropertyEditorUiTiptapExtensionsConfigurationElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/property-editors/tiptap/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/property-editors/tiptap/manifests.ts index 5de70b8af0..3569959f82 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/property-editors/tiptap/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/property-editors/tiptap/manifests.ts @@ -13,6 +13,13 @@ export const manifests: Array = [ group: 'richContent', settings: { properties: [ + { + alias: 'extensions', + label: 'Extensions', + description: 'Extensions to enable', + propertyEditorUiAlias: 'Umb.PropertyEditorUi.Tiptap.ExtensionsConfiguration', + weight: 5, + }, { alias: 'toolbar', label: 'Toolbar',