create extension element

This commit is contained in:
Niels Lyngsø
2022-06-01 14:35:02 +02:00
parent 00b29f0173
commit c704a364b2
9 changed files with 84 additions and 32 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

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

View File

@@ -1,17 +1,19 @@
import { UmbExtensionManifest, UmbExtensionManifestJSModel } from './extension.registry';
import { UmbExtensionManifest } from './extension.registry';
export function loadExtension(manifest: UmbExtensionManifest): Promise<UmbExtensionManifestJSModel> | Promise<null> | null {
export function loadExtension(manifest: UmbExtensionManifest): Promise<object|HTMLElement> | Promise<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 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<UmbExtens
};
document.body.appendChild(script);
}) as Promise<null>;
*/
}
console.log('-- Extension does not have any referenced JS')

View File

@@ -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'
}
])
}

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

@@ -50,6 +50,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,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.)

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;