UmbExtensionElementAndApiSlotElementBase+ refactors

This commit is contained in:
Niels Lyngsø
2024-03-02 11:56:31 +01:00
parent ba5bc7d9e6
commit bae4ec073a
8 changed files with 98 additions and 113 deletions

View File

@@ -1,5 +1,6 @@
import { createExtensionApi } from '../functions/create-extension-api.function.js';
import { createExtensionElement } from '../functions/create-extension-element.function.js';
import { createExtensionApi, type UmbApi } from '../index.js';
import type { UmbApi } from '../models/api.interface.js';
import type { UmbExtensionRegistry } from '../registry/extension.registry.js';
import type { ManifestElementAndApi, ManifestCondition, ManifestWithDynamicConditions } from '../types/index.js';
import { UmbBaseExtensionInitializer } from './base-extension-initializer.controller.js';

View File

@@ -6,3 +6,5 @@ export * from './extension-element-initializer.controller.js';
export * from './extensions-element-initializer.controller.js';
export * from './extension-manifest-initializer.controller.js';
export * from './extensions-manifest-initializer.controller.js';
export * from './extension-element-and-api-initializer.controller.js';
export * from './extensions-element-and-api-initializer.controller.js';

View File

@@ -0,0 +1,65 @@
import { umbExtensionsRegistry } from './registry.js';
import { html, property, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { ManifestElementAndApi } from '@umbraco-cms/backoffice/extension-api';
import { UmbExtensionElementAndApiInitializer } from '@umbraco-cms/backoffice/extension-api';
// TODO: Eslint: allow abstract element class to end with "ElementBase" instead of "Element"
// eslint-disable-next-line local-rules/enforce-element-suffix-on-element-class-name
export abstract class UmbExtensionElementAndApiSlotElementBase<
ManifestType extends ManifestElementAndApi,
> extends UmbLitElement {
_alias?: string;
@property({ type: String, reflect: true })
get alias() {
return this._alias;
}
set alias(newVal) {
this._alias = newVal;
this.#observeManifest();
}
@property({ type: Object, attribute: false })
set props(newVal: Record<string, unknown> | undefined) {
// TODO, compare changes since last time. only reset the ones that changed. This might be better done by the controller is self:
this.#props = newVal;
if (this.#extensionController) {
this.#extensionController.properties = newVal;
}
}
get props() {
return this.#props;
}
#props?: Record<string, unknown> = {};
#extensionController?: UmbExtensionElementAndApiInitializer<ManifestType>;
@state()
_element: ManifestType['ELEMENT_TYPE'] | undefined;
abstract getExtensionType(): string;
abstract getDefaultElementName(): string;
#observeManifest() {
if (!this._alias) return;
new UmbExtensionElementAndApiInitializer<ManifestType>(
this,
umbExtensionsRegistry,
this._alias,
[this],
this.#extensionChanged,
this.getDefaultElementName(),
);
}
#extensionChanged = (isPermitted: boolean, controller: UmbExtensionElementAndApiInitializer<ManifestType>) => {
this._element = isPermitted ? controller.component : undefined;
this.requestUpdate('_element');
};
render() {
return html`${this._element}`;
}
}

View File

@@ -1,92 +0,0 @@
//import { umbExtensionsRegistry } from './registry.js';
import { html, property, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { ManifestWithDynamicConditions } from '@umbraco-cms/backoffice/extension-api';
//import { UmbExtensionElementInitializer, createExtensionApi } from '@umbraco-cms/backoffice/extension-api';
// TODO: Eslint: allow abstract element class to end with "ElementBase" instead of "Element"
// eslint-disable-next-line local-rules/enforce-element-suffix-on-element-class-name
export abstract class UmbExtensionInitializerElementBase<
ManifestType extends ManifestWithDynamicConditions,
> extends UmbLitElement {
_alias?: string;
@property({ type: String, reflect: true })
get alias() {
return this._alias;
}
set alias(newVal) {
this._alias = newVal;
//this.#observeManifest();
}
@property({ type: Object, attribute: false })
get props() {
//return this.#props;
return {};
}
set props(newVal: Record<string, unknown> | undefined) {
// TODO, compare changes since last time. only reset the ones that changed. This might be better done by the controller is self:
/*this.#props = newVal;
if (this.#extensionElementController) {
this.#extensionElementController.properties = newVal;
}*/
}
/*
#props?: Record<string, unknown> = {};
#extensionElementController?: UmbExtensionElementInitializer<ManifestType>;
@state()
_element: HTMLElement | undefined;
abstract getExtensionType(): string;
abstract getDefaultElementName(): string;
#observeManifest() {
if (!this._alias) return;
this.observe(
umbExtensionsRegistry.byTypeAndAlias(this.getExtensionType(), this._alias),
async (m) => {
if (!m) return;
const manifest = m as unknown as ManifestType;
this.createApi(manifest);
this.createElement(manifest);
},
'umbObserveTreeManifest',
);
}
protected async createApi(manifest?: ManifestType) {
if (!manifest) throw new Error('No manifest');
const api = (await createExtensionApi(manifest, [this])) as unknown as any;
if (!api) throw new Error('No api');
api.setManifest(manifest);
}
protected async createElement(manifest?: ManifestType) {
if (!manifest) throw new Error('No manifest');
const extController = new UmbExtensionElementInitializer<ManifestType>(
this,
umbExtensionsRegistry,
manifest.alias,
this.#extensionChanged,
this.getDefaultElementName(),
);
extController.properties = this.#props;
this.#extensionElementController = extController;
}
#extensionChanged = (isPermitted: boolean, controller: UmbExtensionElementInitializer<ManifestType>) => {
this._element = isPermitted ? controller.component : undefined;
this.requestUpdate('_element');
};
render() {
return html`${this._element}`;
}
*/
}

View File

@@ -3,4 +3,4 @@ export * from './interfaces/index.js';
export * from './models/index.js';
export * from './registry.js';
export { UmbExtensionInitializerElementBase } from './extension-initializer-element-base.js';
export { UmbExtensionElementAndApiSlotElementBase } from './extension-element-and-api-slot-element-base.js';

View File

@@ -65,19 +65,23 @@ export class UmbDefaultTreeContext<TreeItemType extends UmbTreeItemModelBase>
/**
* Sets the manifest
* @param {ManifestCollection} manifest
* @memberof UmbCollectionContext
* @param {ManifestTree} manifest
* @memberof UmbDefaultTreeContext
*/
public setManifest(manifest: ManifestTree | undefined) {
public set manifest(manifest: ManifestTree | undefined) {
if (this.#manifest === manifest) return;
this.#manifest = manifest;
this.#observeRepository(this.#manifest?.meta.repositoryAlias);
}
public get manifest() {
return this.#manifest;
}
// TODO: getManifest, could be refactored to use the getter method [NL]
/**
* Returns the manifest.
* @return {ManifestCollection}
* @memberof UmbCollectionContext
* @return {ManifestTree}
* @memberof UmbDefaultTreeContext
*/
public getManifest() {
return this.#manifest;

View File

@@ -1,9 +1,13 @@
import { customElement, property } from '@umbraco-cms/backoffice/external/lit';
import type { ManifestTreeItem } from '@umbraco-cms/backoffice/extension-registry';
import { UmbExtensionInitializerElementBase, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
import {
UmbExtensionElementAndApiSlotElementBase,
umbExtensionsRegistry,
} from '@umbraco-cms/backoffice/extension-registry';
import { createObservablePart } from '@umbraco-cms/backoffice/observable-api';
@customElement('umb-tree-item')
export class UmbTreeItemElement extends UmbExtensionInitializerElementBase<ManifestTreeItem> {
export class UmbTreeItemElement extends UmbExtensionElementAndApiSlotElementBase<ManifestTreeItem> {
_entityType?: string;
@property({ type: String, reflect: true })
get entityType() {
@@ -11,10 +15,10 @@ export class UmbTreeItemElement extends UmbExtensionInitializerElementBase<Manif
}
set entityType(newVal) {
this._entityType = newVal;
this.#observeManifest();
this.#observeEntityType();
}
#observeManifest() {
#observeEntityType() {
if (!this._entityType) return;
const filterByEntityType = (manifest: ManifestTreeItem) => {
@@ -23,15 +27,16 @@ export class UmbTreeItemElement extends UmbExtensionInitializerElementBase<Manif
};
this.observe(
umbExtensionsRegistry.byTypeAndFilter(this.getExtensionType(), filterByEntityType),
(manifests) => {
if (!manifests) return;
// TODO: what should we do if there are multiple tree items for an entity type?
const manifest = manifests[0];
//this.createApi(manifest);
//this.createElement(manifest);
// TODO: what should we do if there are multiple tree items for an entity type?
// This method gets all extensions based on a type, then filters them based on the entity type. and then we get the alias of the first one [NL]
createObservablePart(
umbExtensionsRegistry.byTypeAndFilter(this.getExtensionType(), filterByEntityType),
(x) => x[0].alias,
),
(alias) => {
this.alias = alias;
},
'umbObserveTreeManifest',
'umbObserveAlias',
);
}

View File

@@ -1,9 +1,9 @@
import { customElement } from '@umbraco-cms/backoffice/external/lit';
import type { ManifestTree } from '@umbraco-cms/backoffice/extension-registry';
import { UmbExtensionInitializerElementBase } from '@umbraco-cms/backoffice/extension-registry';
import { UmbExtensionElementAndApiSlotElementBase } from '@umbraco-cms/backoffice/extension-registry';
@customElement('umb-tree')
export class UmbTreeElement extends UmbExtensionInitializerElementBase<ManifestTree> {
export class UmbTreeElement extends UmbExtensionElementAndApiSlotElementBase<ManifestTree> {
getExtensionType() {
return 'tree';
}