From bae4ec073a06654595196bfe62bce389cdaf30c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Sat, 2 Mar 2024 11:56:31 +0100 Subject: [PATCH] UmbExtensionElementAndApiSlotElementBase+ refactors --- ...-element-and-api-initializer.controller.ts | 3 +- .../libs/extension-api/controller/index.ts | 2 + ...nsion-element-and-api-slot-element-base.ts | 65 +++++++++++++ .../extension-initializer-element-base.ts | 92 ------------------- .../packages/core/extension-registry/index.ts | 2 +- .../core/tree/default/default-tree.context.ts | 14 ++- .../core/tree/tree-item/tree-item.element.ts | 29 +++--- .../src/packages/core/tree/tree.element.ts | 4 +- 8 files changed, 98 insertions(+), 113 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/extension-element-and-api-slot-element-base.ts delete mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/extension-initializer-element-base.ts diff --git a/src/Umbraco.Web.UI.Client/src/libs/extension-api/controller/extension-element-and-api-initializer.controller.ts b/src/Umbraco.Web.UI.Client/src/libs/extension-api/controller/extension-element-and-api-initializer.controller.ts index 26467462a7..9ac994a5f1 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/extension-api/controller/extension-element-and-api-initializer.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/extension-api/controller/extension-element-and-api-initializer.controller.ts @@ -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'; diff --git a/src/Umbraco.Web.UI.Client/src/libs/extension-api/controller/index.ts b/src/Umbraco.Web.UI.Client/src/libs/extension-api/controller/index.ts index db717874aa..a49d53fb99 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/extension-api/controller/index.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/extension-api/controller/index.ts @@ -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'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/extension-element-and-api-slot-element-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/extension-element-and-api-slot-element-base.ts new file mode 100644 index 0000000000..6f1a3001d6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/extension-element-and-api-slot-element-base.ts @@ -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 | 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 = {}; + + #extensionController?: UmbExtensionElementAndApiInitializer; + + @state() + _element: ManifestType['ELEMENT_TYPE'] | undefined; + + abstract getExtensionType(): string; + abstract getDefaultElementName(): string; + + #observeManifest() { + if (!this._alias) return; + + new UmbExtensionElementAndApiInitializer( + this, + umbExtensionsRegistry, + this._alias, + [this], + this.#extensionChanged, + this.getDefaultElementName(), + ); + } + + #extensionChanged = (isPermitted: boolean, controller: UmbExtensionElementAndApiInitializer) => { + this._element = isPermitted ? controller.component : undefined; + this.requestUpdate('_element'); + }; + + render() { + return html`${this._element}`; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/extension-initializer-element-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/extension-initializer-element-base.ts deleted file mode 100644 index fe3994d1d0..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/extension-initializer-element-base.ts +++ /dev/null @@ -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 | 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 = {}; - - #extensionElementController?: UmbExtensionElementInitializer; - - @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( - this, - umbExtensionsRegistry, - manifest.alias, - this.#extensionChanged, - this.getDefaultElementName(), - ); - - extController.properties = this.#props; - - this.#extensionElementController = extController; - } - - #extensionChanged = (isPermitted: boolean, controller: UmbExtensionElementInitializer) => { - this._element = isPermitted ? controller.component : undefined; - this.requestUpdate('_element'); - }; - - render() { - return html`${this._element}`; - } - */ -} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/index.ts index 964c344673..e890b7fe55 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/index.ts @@ -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'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/default/default-tree.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/default/default-tree.context.ts index cd276f59d4..1d5eafa6e0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/default/default-tree.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/default/default-tree.context.ts @@ -65,19 +65,23 @@ export class UmbDefaultTreeContext /** * 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; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/tree-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/tree-item.element.ts index cb059ed4f0..43ffdd96f4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/tree-item.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/tree-item.element.ts @@ -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 { +export class UmbTreeItemElement extends UmbExtensionElementAndApiSlotElementBase { _entityType?: string; @property({ type: String, reflect: true }) get entityType() { @@ -11,10 +15,10 @@ export class UmbTreeItemElement extends UmbExtensionInitializerElementBase { @@ -23,15 +27,16 @@ export class UmbTreeItemElement extends UmbExtensionInitializerElementBase { - 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', ); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree.element.ts index a009817be2..6eb0e6ee57 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree.element.ts @@ -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 { +export class UmbTreeElement extends UmbExtensionElementAndApiSlotElementBase { getExtensionType() { return 'tree'; }