From 4d01fa5e4f76818ffdf705965d112c2cf0b9570b Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 27 Feb 2024 13:47:15 +0100 Subject: [PATCH] use extension initializer for tree item --- .../tree-item-base/tree-item-context-base.ts | 22 +++++++ .../tree-item-base/tree-item-element-base.ts | 28 +++++---- .../tree-item-default.context.ts | 2 + .../tree-item-default.element.ts | 5 +- .../src/packages/core/tree/tree-item/index.ts | 2 +- ...face.ts => tree-item-context.interface.ts} | 0 .../core/tree/tree-item/tree-item.element.ts | 59 +++++++++++-------- .../src/packages/core/tree/tree.element.ts | 7 ++- 8 files changed, 84 insertions(+), 41 deletions(-) rename src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/{tree-item.context.interface.ts => tree-item-context.interface.ts} (100%) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item-base/tree-item-context-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item-base/tree-item-context-base.ts index 3eb1afe20f..ddc998ffc0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item-base/tree-item-context-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item-base/tree-item-context-base.ts @@ -5,6 +5,7 @@ import { UmbReloadTreeItemChildrenRequestEntityActionEvent } from '../reload-tre import { map } from '@umbraco-cms/backoffice/external/rxjs'; import { UMB_SECTION_CONTEXT, UMB_SECTION_SIDEBAR_CONTEXT } from '@umbraco-cms/backoffice/section'; import type { UmbSectionContext, UmbSectionSidebarContext } from '@umbraco-cms/backoffice/section'; +import type { ManifestTreeItem } from '@umbraco-cms/backoffice/extension-registry'; import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import { UmbBooleanState, UmbDeepState, UmbStringState } from '@umbraco-cms/backoffice/observable-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; @@ -24,6 +25,8 @@ export abstract class UmbTreeItemContextBase(undefined); treeItem = this.#treeItem.asObservable(); @@ -64,6 +67,25 @@ export abstract class UmbTreeItemContextBase extends UmbLitElement { + @property({ type: Object, attribute: false }) + item?: TreeItemModelType; @state() - private _childItems?: UmbTreeItemModelBase[]; + private _item?: TreeItemModelType; + + @state() + private _childItems?: TreeItemModelType[]; @state() private _href?: string; @@ -33,7 +36,7 @@ export abstract class UmbTreeItemElementBase extends UmbLitElement { @state() private _iconSlotHasChildren = false; - #treeItemContext?: UmbTreeItemContext; + #treeItemContext?: UmbTreeItemContext; constructor() { super(); @@ -41,6 +44,9 @@ export abstract class UmbTreeItemElementBase extends UmbLitElement { this.consumeContext(UMB_TREE_ITEM_CONTEXT, (instance) => { this.#treeItemContext = instance; if (!this.#treeItemContext) return; + + this.#treeItemContext.setTreeItem(this.item); + // TODO: investigate if we can make an observe decorator this.observe(this.#treeItemContext.treeItem, (value) => (this._item = value)); this.observe(this.#treeItemContext.hasChildren, (value) => (this._hasChildren = value)); @@ -85,7 +91,6 @@ export abstract class UmbTreeItemElementBase extends UmbLitElement { // If we like to be able to open items in selectable context, then we might want to make it as a menu item action, so you have to click ... and chose an action called 'Edit' render() { return html` - HELLO HELLO - ${this.#renderIconContainer()} ${this.#renderLabel()} ${this.#renderActions()} ${this.#renderChildItems()} + ${this.#renderIconContainer()} ${this.renderLabel()} ${this.#renderActions()} ${this.#renderChildItems()} `; @@ -134,7 +139,7 @@ export abstract class UmbTreeItemElementBase extends UmbLitElement { return html``; } - #renderLabel() { + renderLabel() { return html``; } @@ -154,9 +159,8 @@ export abstract class UmbTreeItemElementBase extends UmbLitElement { ${this._childItems ? repeat( this._childItems, - // TODO: get unique here instead of name. we might be able to get it from the context - (item) => item.name, - (item) => html``, + (item, index) => item.name + '___' + index, + (item) => html``, ) : ''} `; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item-default/tree-item-default.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item-default/tree-item-default.context.ts index 3b9efeeeef..a06a30e266 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item-default/tree-item-default.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item-default/tree-item-default.context.ts @@ -9,3 +9,5 @@ export class UmbDefaultTreeItemContext< super(host, (x: UmbUniqueTreeItemModel) => x.unique); } } + +export default UmbDefaultTreeItemContext; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item-default/tree-item-default.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item-default/tree-item-default.element.ts index ca815de068..2f35cd9feb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item-default/tree-item-default.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item-default/tree-item-default.element.ts @@ -1,8 +1,11 @@ import { UmbTreeItemElementBase } from '../tree-item-base/index.js'; +import type { UmbUniqueTreeItemModel } from '../types.js'; import { customElement } from '@umbraco-cms/backoffice/external/lit'; @customElement('umb-default-tree-item') -export class UmbDefaultTreeItemElement extends UmbTreeItemElementBase {} +export class UmbDefaultTreeItemElement extends UmbTreeItemElementBase {} + +export default UmbDefaultTreeItemElement; declare global { interface HTMLElementTagNameMap { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/index.ts index 1ee7965541..1fa0f99af3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/index.ts @@ -1,2 +1,2 @@ -export * from './tree-item.context.interface.js'; +export * from './tree-item-context.interface.js'; export * from './tree-item.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/tree-item.context.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/tree-item-context.interface.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/tree-item.context.interface.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/tree-item-context.interface.ts 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 124f7bce08..e2fa41eb8c 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,32 +1,43 @@ -import type { UmbTreeItemModelBase } from '../types.js'; -import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { css, html, nothing, customElement, property } from '@umbraco-cms/backoffice/external/lit'; +import { customElement, property } from '@umbraco-cms/backoffice/external/lit'; import type { ManifestTreeItem } from '@umbraco-cms/backoffice/extension-registry'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbExtensionInitializerElementBase, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; @customElement('umb-tree-item') -export class UmbTreeItemElement extends UmbLitElement { - @property({ type: Object, attribute: false }) - item?: UmbTreeItemModelBase; - - render() { - if (!this.item) return nothing; - return html` manifests.meta.entityTypes.includes(this.item!.entityType)} - .props=${{ - item: this.item, - }}>`; +export class UmbTreeItemElement extends UmbExtensionInitializerElementBase { + _entityType?: string; + @property({ type: String, reflect: true }) + get entityType() { + return this._entityType; + } + set entityType(newVal) { + this._entityType = newVal; + this.#observeManifest(); } - static styles = [ - UmbTextStyles, - css` - :host { - display: block; - } - `, - ]; + #observeManifest() { + if (!this._entityType) return; + this.observe( + umbExtensionsRegistry.byTypeAndFilter(this.getExtensionType(), (manifest: ManifestTreeItem) => + manifest.meta.entityTypes.includes(this._entityType), + ), + async (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); + }, + 'umbObserveTreeManifest', + ); + } + + getExtensionType() { + return 'treeItem'; + } + + getDefaultElementName() { + return 'umb-default-tree-item'; + } } declare global { 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 ef57d11f20..0b7dd1c38f 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 @@ -121,7 +121,9 @@ export class UmbTreeElement extends UmbLitElement { #renderTreeRoot() { if (this.hideTreeRoot || this._treeRoot === undefined) return nothing; - return html` `; + return html` + + `; } #renderRootItems() { @@ -129,9 +131,8 @@ export class UmbTreeElement extends UmbLitElement { return html` ${repeat( this._items, - // TODO: use unique here: (item, index) => item.name + '___' + index, - (item) => html``, + (item) => html``, )} `; }