use extension initializer for tree item
This commit is contained in:
@@ -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<TreeItemType extends UmbTreeItemMod
|
||||
public unique?: string | null;
|
||||
public entityType?: string;
|
||||
|
||||
#manifest?: ManifestTreeItem;
|
||||
|
||||
#treeItem = new UmbDeepState<TreeItemType | undefined>(undefined);
|
||||
treeItem = this.#treeItem.asObservable();
|
||||
|
||||
@@ -64,6 +67,25 @@ export abstract class UmbTreeItemContextBase<TreeItemType extends UmbTreeItemMod
|
||||
this.#consumeContexts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the manifest
|
||||
* @param {ManifestCollection} manifest
|
||||
* @memberof UmbCollectionContext
|
||||
*/
|
||||
public setManifest(manifest: ManifestTreeItem | undefined) {
|
||||
if (this.#manifest === manifest) return;
|
||||
this.#manifest = manifest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the manifest.
|
||||
* @return {ManifestCollection}
|
||||
* @memberof UmbCollectionContext
|
||||
*/
|
||||
public getManifest() {
|
||||
return this.#manifest;
|
||||
}
|
||||
|
||||
public setTreeItem(treeItem: TreeItemType | undefined) {
|
||||
if (!treeItem) {
|
||||
this.#treeItem.setValue(undefined);
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import type { UmbTreeItemContext } from '../tree-item/index.js';
|
||||
import type { UmbTreeItemModelBase } from '../types.js';
|
||||
import { UMB_TREE_ITEM_CONTEXT } from './tree-item-context-base.js';
|
||||
import { html, nothing, state, ifDefined, repeat } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { html, nothing, state, ifDefined, repeat, property } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
|
||||
// eslint-disable-next-line local-rules/enforce-element-suffix-on-element-class-name
|
||||
export abstract class UmbTreeItemElementBase extends UmbLitElement {
|
||||
@state()
|
||||
private _item?: UmbTreeItemModelBase;
|
||||
export abstract class UmbTreeItemElementBase<TreeItemModelType extends UmbTreeItemModelBase> 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<UmbTreeItemModelBase>;
|
||||
#treeItemContext?: UmbTreeItemContext<TreeItemModelType>;
|
||||
|
||||
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
|
||||
<uui-menu-item
|
||||
@show-children=${this._onShowChildren}
|
||||
@selected=${this._handleSelectedItem}
|
||||
@@ -97,7 +102,7 @@ export abstract class UmbTreeItemElementBase extends UmbLitElement {
|
||||
.hasChildren=${this._hasChildren}
|
||||
label="${ifDefined(this._item?.name)}"
|
||||
href="${ifDefined(this._isSelectableContext ? undefined : this._href)}">
|
||||
${this.#renderIconContainer()} ${this.#renderLabel()} ${this.#renderActions()} ${this.#renderChildItems()}
|
||||
${this.#renderIconContainer()} ${this.renderLabel()} ${this.#renderActions()} ${this.#renderChildItems()}
|
||||
<slot></slot>
|
||||
</uui-menu-item>
|
||||
`;
|
||||
@@ -134,7 +139,7 @@ export abstract class UmbTreeItemElementBase extends UmbLitElement {
|
||||
return html`<uui-icon slot="icon" name="icon-circle-dotted"></uui-icon>`;
|
||||
}
|
||||
|
||||
#renderLabel() {
|
||||
renderLabel() {
|
||||
return html`<slot name="label" slot="label"></slot>`;
|
||||
}
|
||||
|
||||
@@ -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`<umb-tree-item-default .item=${item}></umb-tree-item-default>`,
|
||||
(item, index) => item.name + '___' + index,
|
||||
(item) => html`<umb-tree-item .entityType=${item.entityType} .props=${{ item }}></umb-tree-item>`,
|
||||
)
|
||||
: ''}
|
||||
`;
|
||||
|
||||
@@ -9,3 +9,5 @@ export class UmbDefaultTreeItemContext<
|
||||
super(host, (x: UmbUniqueTreeItemModel) => x.unique);
|
||||
}
|
||||
}
|
||||
|
||||
export default UmbDefaultTreeItemContext;
|
||||
|
||||
@@ -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<UmbUniqueTreeItemModel> {}
|
||||
|
||||
export default UmbDefaultTreeItemElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from './tree-item.context.interface.js';
|
||||
export * from './tree-item-context.interface.js';
|
||||
export * from './tree-item.element.js';
|
||||
|
||||
@@ -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`<umb-extension-slot
|
||||
type="treeItem"
|
||||
.filter=${(manifests: ManifestTreeItem) => manifests.meta.entityTypes.includes(this.item!.entityType)}
|
||||
.props=${{
|
||||
item: this.item,
|
||||
}}></umb-extension-slot>`;
|
||||
export class UmbTreeItemElement extends UmbExtensionInitializerElementBase<ManifestTreeItem> {
|
||||
_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 {
|
||||
|
||||
@@ -121,7 +121,9 @@ export class UmbTreeElement extends UmbLitElement {
|
||||
|
||||
#renderTreeRoot() {
|
||||
if (this.hideTreeRoot || this._treeRoot === undefined) return nothing;
|
||||
return html` <umb-tree-item .item=${this._treeRoot}></umb-tree-item> `;
|
||||
return html`
|
||||
<umb-tree-item .entityType=${this._treeRoot.entityType} .props=${{ item: this._treeRoot }}></umb-tree-item>
|
||||
`;
|
||||
}
|
||||
|
||||
#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`<umb-tree-item .item=${item}></umb-tree-item>`,
|
||||
(item) => html`<umb-tree-item .entityType=${this._treeRoot.entityType} .props=${item}></umb-tree-item>`,
|
||||
)}
|
||||
`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user