Merge remote-tracking branch 'origin/feature/create-extension-element'

This commit is contained in:
Niels Lyngsø
2022-06-01 14:39:09 +02:00
8 changed files with 109 additions and 54 deletions

View File

@@ -0,0 +1,34 @@
import { UmbExtensionManifest } from './extension.registry';
import { loadExtension } from './load-extension.function';
export function createExtensionElement(manifest: UmbExtensionManifest): Promise<HTMLElement> | Promise<undefined> {
//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);
});
}

View File

@@ -1,30 +1,32 @@
import { UmbExtensionManifest, UmbExtensionManifestJSModel } from './extension.registry';
import { UmbExtensionManifest } from './extension.registry';
export function loadExtension(manifest: UmbExtensionManifest): Promise<object|HTMLElement> | Promise<null> {
export function loadExtension(
manifest: UmbExtensionManifest
): Promise<UmbExtensionManifestJSModel> | Promise<null> | null {
if (typeof manifest.js === 'function') {
return manifest.js() as Promise<UmbExtensionManifestJSModel>;
return manifest.js() as Promise<object|HTMLElement>;
}
// 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<null>;
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<null>;
*/
}
console.log('-- Extension does not have any referenced JS');
console.log('-- Extension does not have any referenced JS')
return Promise.resolve(null);
}

View File

@@ -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<DataTypeEntity | null> {

View File

@@ -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',

View File

@@ -48,6 +48,13 @@ export const data: Array<DocumentNode> = [
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

View File

@@ -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) => {

View File

@@ -1,4 +1,4 @@
class ExternalPropertyEditorTest extends HTMLElement {
export default class ExternalPropertyEditorTest extends HTMLElement {
constructor() {
super();

View File

@@ -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;