From c704a364b216e5e740d2d97dbacfa1ee1e2898be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 1 Jun 2022 14:35:02 +0200 Subject: [PATCH] create extension element --- .../create-extension-element.function.ts | 34 +++++++++++++++++++ .../src/core/extension/extension.registry.ts | 4 --- .../core/extension/load-extension.function.ts | 11 +++--- .../src/core/stores/data-type.store.ts | 6 ++++ src/Umbraco.Web.UI.Client/src/index.ts | 17 ++++++++-- .../src/mocks/data/content.data.ts | 7 ++++ .../node-property-data-type.element.ts | 31 +++++++---------- .../external-property-editor-test.js | 2 +- .../property-editor-text.element.ts | 4 +-- 9 files changed, 84 insertions(+), 32 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/core/extension/create-extension-element.function.ts diff --git a/src/Umbraco.Web.UI.Client/src/core/extension/create-extension-element.function.ts b/src/Umbraco.Web.UI.Client/src/core/extension/create-extension-element.function.ts new file mode 100644 index 0000000000..0db61a8b6e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/extension/create-extension-element.function.ts @@ -0,0 +1,34 @@ +import { UmbExtensionManifest } from './extension.registry'; +import { loadExtension } from './load-extension.function'; + +export function createExtensionElement(manifest: UmbExtensionManifest): Promise | Promise { + + //TODO: Write tests for these extension options: + return loadExtension(manifest).then((js) => { + + if (manifest.elementName) { + console.log('-- created by elementName', manifest.elementName); + return document.createElement(manifest.elementName as any); + } + + console.log(js) + + if (js) { + if (js instanceof HTMLElement) { + console.log('-- created by manifest method providing HTMLElement', js); + return js; + } + if ((js as any).elementName) { + console.log('-- created by export elementName', (js as any).elementName); + return document.createElement((js as any).elementName); + } + if ((js as any).default) { + console.log('-- created by default class', (js as any).default); + return new ((js as any).default) as HTMLElement; + } + } + + console.error('-- Extension did not succeed creating an element'); + return Promise.resolve(undefined); + }); +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/core/extension/extension.registry.ts b/src/Umbraco.Web.UI.Client/src/core/extension/extension.registry.ts index 1717a63032..0c75c70637 100644 --- a/src/Umbraco.Web.UI.Client/src/core/extension/extension.registry.ts +++ b/src/Umbraco.Web.UI.Client/src/core/extension/extension.registry.ts @@ -3,10 +3,6 @@ import { BehaviorSubject, map, Observable } from 'rxjs'; // TODO: how do we want to type extensions? export type UmbExtensionType = 'startUp' | 'section' | 'propertyEditorUI' | 'dashboard'; -export type UmbExtensionManifestJSModel = { - elementName?: string; -} - export type UmbExtensionManifestBase = { //type: string; alias: string; diff --git a/src/Umbraco.Web.UI.Client/src/core/extension/load-extension.function.ts b/src/Umbraco.Web.UI.Client/src/core/extension/load-extension.function.ts index 38bbc9c1f9..6840926fe4 100644 --- a/src/Umbraco.Web.UI.Client/src/core/extension/load-extension.function.ts +++ b/src/Umbraco.Web.UI.Client/src/core/extension/load-extension.function.ts @@ -1,17 +1,19 @@ -import { UmbExtensionManifest, UmbExtensionManifestJSModel } from './extension.registry'; +import { UmbExtensionManifest } from './extension.registry'; -export function loadExtension(manifest: UmbExtensionManifest): Promise | Promise | null { +export function loadExtension(manifest: UmbExtensionManifest): Promise | Promise { if (typeof manifest.js === 'function') { - return manifest.js() as Promise; + return manifest.js() as Promise; } // TODO: verify if this is acceptable solution. if (typeof manifest.js === 'string') { + return import(/* @vite-ignore */manifest.js); + /* return new Promise((resolve, reject) => { const script = document.createElement('script'); - script .type = 'text/javascript'; + script.type = 'text/javascript'; //script.charset = 'utf-8'; script.async = true; script.src = manifest.js as string; @@ -23,6 +25,7 @@ export function loadExtension(manifest: UmbExtensionManifest): Promise; + */ } console.log('-- Extension does not have any referenced JS') diff --git a/src/Umbraco.Web.UI.Client/src/core/stores/data-type.store.ts b/src/Umbraco.Web.UI.Client/src/core/stores/data-type.store.ts index 2b2175d821..2de7b883d2 100644 --- a/src/Umbraco.Web.UI.Client/src/core/stores/data-type.store.ts +++ b/src/Umbraco.Web.UI.Client/src/core/stores/data-type.store.ts @@ -19,6 +19,12 @@ export class UmbDataTypeStore { key: 'dt-2', name: 'Textarea (DataType)', propertyEditorUIAlias: 'Umb.PropertyEditorUI.Textarea' + }, + { + id: 1246, + key: 'dt-3', + name: 'External Test (DataType)', + propertyEditorUIAlias: 'External.PropertyEditorUI.Test' } ]) } diff --git a/src/Umbraco.Web.UI.Client/src/index.ts b/src/Umbraco.Web.UI.Client/src/index.ts index e94a42637f..fd80f7f5a7 100644 --- a/src/Umbraco.Web.UI.Client/src/index.ts +++ b/src/Umbraco.Web.UI.Client/src/index.ts @@ -87,7 +87,7 @@ const registerInternalManifests = async () => { type: 'propertyEditorUI', alias: 'Umb.PropertyEditorUI.Text', name: 'Text', - elementName: 'umb-property-editor-text', + //elementName: 'umb-property-editor-text', js: () => import('./property-editors/property-editor-text.element'), meta: { icon: 'document', @@ -98,13 +98,26 @@ const registerInternalManifests = async () => { type: 'propertyEditorUI', alias: 'External.PropertyEditorUI.Test', name: 'Text', - elementName: 'external-property-editor-test', //Gets the element name from JS file. + //elementName: 'external-property-editor-test', //Gets the element name from JS file. js: '/src/property-editors/external-property-editor-test.js', meta: { icon: 'document', group: 'common', } }, + /* + { + type: 'propertyEditorUI', + alias: 'External.PropertyEditorUI.Test', + name: 'Text', + elementName: 'external-property-editor-test', //Gets the element name from JS file. + js: () => Promise.resolve(document.createElement('hr')), + meta: { + icon: 'document', + group: 'common', + } + }, + */ { type: 'propertyEditorUI', alias: 'Umb.PropertyEditorUI.Textarea', diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/content.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/content.data.ts index 0d436fc663..7f145485e1 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/content.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/content.data.ts @@ -50,6 +50,13 @@ export const data: Array = [ dataTypeKey: 'dt-2', tempValue: 'Tex areaaaa 1' }, + { + alias: 'myExternalEditor', + label: 'External label 1', + description: 'This is the a external property', + dataTypeKey: 'dt-3', + tempValue: 'Tex lkasdfkljdfsa 1' + }, ], /* // Concept for stored values, better approach for variants, separating data from structure/configuration diff --git a/src/Umbraco.Web.UI.Client/src/node-editor/node-property-data-type.element.ts b/src/Umbraco.Web.UI.Client/src/node-editor/node-property-data-type.element.ts index f4139aefc3..168025f990 100644 --- a/src/Umbraco.Web.UI.Client/src/node-editor/node-property-data-type.element.ts +++ b/src/Umbraco.Web.UI.Client/src/node-editor/node-property-data-type.element.ts @@ -3,10 +3,10 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property, state } from 'lit/decorators.js'; import { UmbContextConsumerMixin } from '../core/context'; import { UmbDataTypeStore } from '../core/stores/data-type.store'; -import { mergeMap, Subscription, map, switchMap } from 'rxjs'; +import { Subscription, map, switchMap } from 'rxjs'; import { DataTypeEntity } from '../mocks/data/content.data'; import { UmbExtensionManifest, UmbExtensionRegistry } from '../core/extension'; -import { loadExtension } from '../core/extension/load-extension.function'; +import { createExtensionElement } from '../core/extension/create-extension-element.function'; @customElement('umb-node-property-data-type') class UmbNodePropertyDataType extends UmbContextConsumerMixin(LitElement) { @@ -27,7 +27,7 @@ class UmbNodePropertyDataType extends UmbContextConsumerMixin(LitElement) { return this._dataTypeKey; } public set dataTypeKey(key: string | undefined) { - const oldValue = this._dataTypeKey + //const oldValue = this._dataTypeKey; this._dataTypeKey = key; this._useDataType(); } @@ -35,7 +35,7 @@ class UmbNodePropertyDataType extends UmbContextConsumerMixin(LitElement) { // TODO: make interface for UMBPropertyEditorElement @state() - private _element?:any; + private _element?: {value?:string} & HTMLElement;// TODO: invent interface for propertyEditorUI. @property() value?:string; @@ -95,27 +95,22 @@ class UmbNodePropertyDataType extends UmbContextConsumerMixin(LitElement) { return; } - const oldValue = this._element; - loadExtension(_propertyEditorUI)?.then(js => { + createExtensionElement(_propertyEditorUI).then(el => { - // TODO: something with JS - console.log('ext js', js); - // IF we got a JS file loaded, we can use its elementName prop. - const elementName = _propertyEditorUI.elementName || js?.elementName; - - if (elementName) { - this._element = document.createElement(elementName); - } + const oldValue = this._element; + this._element = el; // TODO: Set/Parse Data-Type-UI-configuration if(oldValue) { - oldValue.removeEventListener('property-editor-change', this._onPropertyEditorChange); + oldValue.removeEventListener('property-editor-change', this._onPropertyEditorChange as any as EventListener); + } + + if(this._element) { + this._element.addEventListener('property-editor-change', this._onPropertyEditorChange as any as EventListener); + this._element.value = this.value;// Be aware its duplicated code } - this._element.addEventListener('property-editor-change', this._onPropertyEditorChange); - - this._element.value = this.value;// Be aware its duplicated code this.requestUpdate('element', oldValue); }).catch(() => { // TODO: loading JS failed so we should do some nice UI. (This does only happen if extension has a js prop, otherwise we concluded that no source was needed resolved the load.) diff --git a/src/Umbraco.Web.UI.Client/src/property-editors/external-property-editor-test.js b/src/Umbraco.Web.UI.Client/src/property-editors/external-property-editor-test.js index 943239e765..ee0df111f5 100644 --- a/src/Umbraco.Web.UI.Client/src/property-editors/external-property-editor-test.js +++ b/src/Umbraco.Web.UI.Client/src/property-editors/external-property-editor-test.js @@ -1,4 +1,4 @@ -class ExternalPropertyEditorTest extends HTMLElement { +export default class ExternalPropertyEditorTest extends HTMLElement { constructor() { super(); diff --git a/src/Umbraco.Web.UI.Client/src/property-editors/property-editor-text.element.ts b/src/Umbraco.Web.UI.Client/src/property-editors/property-editor-text.element.ts index 8b8e8702d1..dced3c3927 100644 --- a/src/Umbraco.Web.UI.Client/src/property-editors/property-editor-text.element.ts +++ b/src/Umbraco.Web.UI.Client/src/property-editors/property-editor-text.element.ts @@ -3,7 +3,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property } from 'lit/decorators.js'; @customElement('umb-property-editor-text') -class UmbPropertyEditorText extends LitElement { +export default class UmbPropertyEditorText extends LitElement { static styles = [ UUITextStyles, css` @@ -26,8 +26,6 @@ class UmbPropertyEditorText extends LitElement { } } -export const elementName = 'umb-property-editor-text'; - declare global { interface HTMLElementTagNameMap { 'umb-property-editor-text': UmbPropertyEditorText;