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/load-extension.function.ts b/src/Umbraco.Web.UI.Client/src/core/extension/load-extension.function.ts index 246333658b..39cd523f42 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,30 +1,32 @@ -import { UmbExtensionManifest, UmbExtensionManifestJSModel } from './extension.registry'; +import { UmbExtensionManifest } from './extension.registry'; + +export function loadExtension(manifest: UmbExtensionManifest): Promise | Promise { -export function loadExtension( - manifest: UmbExtensionManifest -): Promise | Promise | null { 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 new Promise((resolve, reject) => { - const script = document.createElement('script'); - script.type = 'text/javascript'; - //script.charset = 'utf-8'; - script.async = true; - script.src = manifest.js as string; - script.onload = function () { - resolve(null); - }; - script.onerror = function () { - reject(new Error(`Script load error for ${manifest.js}`)); - }; - document.body.appendChild(script); - }) as Promise; + return import(/* @vite-ignore */manifest.js); + /* + return new Promise((resolve, reject) => { + const script = document.createElement('script'); + script.type = 'text/javascript'; + //script.charset = 'utf-8'; + script.async = true; + script.src = manifest.js as string; + script.onload = function () { + resolve(null); + }; + script.onerror = function () { + reject(new Error(`Script load error for ${manifest.js}`)) + }; + document.body.appendChild(script); + }) as Promise; + */ } - console.log('-- Extension does not have any referenced JS'); + console.log('-- Extension does not have any referenced JS') return Promise.resolve(null); } 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 7311e4574f..6d9967a467 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 @@ -17,9 +17,15 @@ export class UmbDataTypeStore { id: 1244, key: 'dt-2', name: 'Textarea (DataType)', - propertyEditorUIAlias: 'Umb.PropertyEditorUI.Textarea', + propertyEditorUIAlias: 'Umb.PropertyEditorUI.Textarea' }, - ]); + { + id: 1246, + key: 'dt-3', + name: 'External Test (DataType)', + propertyEditorUIAlias: 'External.PropertyEditorUI.Test' + } + ]) } getById(id: number): Observable { diff --git a/src/Umbraco.Web.UI.Client/src/index.ts b/src/Umbraco.Web.UI.Client/src/index.ts index c4c9733ab0..c643fdc223 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 a55664c96b..50e3ccf5ba 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 @@ -48,6 +48,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 c0e26ed985..00cc499b96 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,14 +27,14 @@ 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(); } // TODO: make interface for UMBPropertyEditorElement @state() - private _element?: any; + private _element?: {value?:string} & HTMLElement;// TODO: invent interface for propertyEditorUI. @property() value?: string; @@ -93,32 +93,27 @@ class UmbNodePropertyDataType extends UmbContextConsumerMixin(LitElement) { return; } - const oldValue = this._element; - loadExtension(_propertyEditorUI) - ?.then((js) => { - // 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; + createExtensionElement(_propertyEditorUI).then(el => { - 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 as any as EventListener); + } - // TODO: Set/Parse Data-Type-UI-configuration + 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.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.) + }); - if (oldValue) { - oldValue.removeEventListener('property-editor-change', this._onPropertyEditorChange); - } - 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.) - }); } private _onPropertyEditorChange = (e: CustomEvent) => { 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;