load extension function
This commit is contained in:
@@ -3,11 +3,15 @@ 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;
|
||||
name: string;
|
||||
js?: string | (() => Promise<unknown>);
|
||||
js?: string | (() => Promise<UmbExtensionManifestJSModel>);
|
||||
elementName?: string;
|
||||
//meta: undefined;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { UmbExtensionManifest, UmbExtensionManifestJSModel } from './extension.registry';
|
||||
|
||||
export function loadExtension(manifest: UmbExtensionManifest): Promise<UmbExtensionManifestJSModel> | Promise<null> | null {
|
||||
|
||||
|
||||
if (typeof manifest.js === 'function') {
|
||||
return manifest.js() as Promise<UmbExtensionManifestJSModel>;
|
||||
}
|
||||
|
||||
// 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>;
|
||||
}
|
||||
|
||||
console.log('-- Extension does not have any referenced JS')
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
@@ -94,6 +94,17 @@ const registerInternalManifests = async () => {
|
||||
group: 'common',
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'propertyEditorUI',
|
||||
alias: 'External.PropertyEditorUI.Test',
|
||||
name: 'Text',
|
||||
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: 'Umb.PropertyEditorUI.Textarea',
|
||||
|
||||
@@ -6,6 +6,7 @@ import { UmbDataTypeStore } from '../core/stores/data-type.store';
|
||||
import { mergeMap, 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';
|
||||
|
||||
@customElement('umb-node-property-data-type')
|
||||
class UmbNodePropertyDataType extends UmbContextConsumerMixin(LitElement) {
|
||||
@@ -96,28 +97,30 @@ class UmbNodePropertyDataType extends UmbContextConsumerMixin(LitElement) {
|
||||
|
||||
const oldValue = this._element;
|
||||
|
||||
if (typeof _propertyEditorUI.js === 'function') {
|
||||
this._element = _propertyEditorUI.js();
|
||||
// TODO: Niels: I guess this is not the element returned but a Promise of loading the JS, which hopefully exports the Class or maybe an ElementName prop?
|
||||
}
|
||||
if (typeof _propertyEditorUI.js === 'string') {
|
||||
// const loadJsPromise = (() => import(_propertyEditorUI.js as string))();
|
||||
// TODO: show a loader until JS is loaded?
|
||||
}
|
||||
loadExtension(_propertyEditorUI)?.then(js => {
|
||||
|
||||
if (_propertyEditorUI.elementName) {
|
||||
this._element = document.createElement(_propertyEditorUI.elementName);
|
||||
}
|
||||
// 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;
|
||||
|
||||
// TODO: Set/Parse Data-Type-UI-configuration
|
||||
if (elementName) {
|
||||
this._element = document.createElement(elementName);
|
||||
}
|
||||
|
||||
// TODO: Set/Parse Data-Type-UI-configuration
|
||||
|
||||
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.)
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private _onPropertyEditorChange = ( e:CustomEvent) => {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
class ExternalPropertyEditorTest extends HTMLElement {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.attachShadow({mode: 'open'}); // sets and returns 'this.shadowRoot'
|
||||
const wrapper = document.createElement('span');
|
||||
wrapper.textContent = 'hello world';
|
||||
this.shadowRoot.append(wrapper);
|
||||
}
|
||||
}
|
||||
customElements.define('external-property-editor-test', ExternalPropertyEditorTest);
|
||||
@@ -26,6 +26,8 @@ class UmbPropertyEditorText extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
export const elementName = 'umb-property-editor-text';
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-property-editor-text': UmbPropertyEditorText;
|
||||
|
||||
Reference in New Issue
Block a user