add entity tree item kind
This commit is contained in:
@@ -14,9 +14,9 @@ const tree: ManifestTree = {
|
||||
|
||||
const treeItem: ManifestTreeItem = {
|
||||
type: 'treeItem',
|
||||
kind: 'entity',
|
||||
alias: 'Umb.TreeItem.Document',
|
||||
name: 'Document Tree Item',
|
||||
loader: () => import('./tree-item/document-tree-item.element'),
|
||||
conditions: {
|
||||
entityType: 'document',
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbMediaRepository } from '../repository/media.repository';
|
||||
import type { ManifestTree } from '@umbraco-cms/backoffice/extensions-registry';
|
||||
import type { ManifestTree, ManifestTreeItem } from '@umbraco-cms/backoffice/extensions-registry';
|
||||
|
||||
const treeAlias = 'Umb.Tree.Media';
|
||||
|
||||
@@ -12,4 +12,14 @@ const tree: ManifestTree = {
|
||||
},
|
||||
};
|
||||
|
||||
export const manifests = [tree];
|
||||
const treeItem: ManifestTreeItem = {
|
||||
type: 'treeItem',
|
||||
kind: 'entity',
|
||||
alias: 'Umb.TreeItem.Media',
|
||||
name: 'Media Tree Item',
|
||||
conditions: {
|
||||
entityType: 'media',
|
||||
},
|
||||
};
|
||||
|
||||
export const manifests = [tree, treeItem];
|
||||
|
||||
@@ -34,6 +34,7 @@ import './section/section-sidebar/section-sidebar.element';
|
||||
import './section/section.element';
|
||||
import './table/table.element';
|
||||
import './tree/tree.element';
|
||||
import './tree/entity-tree-item/entity-tree-item.element';
|
||||
import './tree/tree-menu-item/tree-menu-item.element';
|
||||
import './variantable-property/variantable-property.element';
|
||||
import './workspace/workspace-action-menu/workspace-action-menu.element';
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { UmbTreeItemContextBase } from '../tree-item-base/tree-item-base.context';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/backoffice/controller';
|
||||
import { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
|
||||
// TODO get unique method from an entity repository static method
|
||||
export class UmbEntityTreeItemContext extends UmbTreeItemContextBase<EntityTreeItemResponseModel> {
|
||||
constructor(host: UmbControllerHostInterface, treeItem: EntityTreeItemResponseModel) {
|
||||
super(host, treeItem, (x: EntityTreeItemResponseModel) => x.key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { css, html, nothing } from 'lit';
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { UmbEntityTreeItemContext } from './entity-tree-item.context';
|
||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||
import { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
import { ManifestKind } from '@umbraco-cms/backoffice/extensions-registry';
|
||||
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api';
|
||||
|
||||
// TODO: Move to separate file:
|
||||
const manifest: ManifestKind = {
|
||||
type: 'kind',
|
||||
alias: 'Umb.Kind.EntityTreeItem',
|
||||
matchKind: 'entity',
|
||||
matchType: 'treeItem',
|
||||
manifest: {
|
||||
type: 'treeItem',
|
||||
elementName: 'umb-entity-tree-item',
|
||||
},
|
||||
};
|
||||
umbExtensionsRegistry.register(manifest);
|
||||
|
||||
@customElement('umb-entity-tree-item')
|
||||
export class UmbEntityTreeItemElement extends UmbLitElement {
|
||||
static styles = [UUITextStyles, css``];
|
||||
|
||||
@property({ type: Object, attribute: false })
|
||||
item?: EntityTreeItemResponseModel;
|
||||
|
||||
render() {
|
||||
if (!this.item) return nothing;
|
||||
new UmbEntityTreeItemContext(this, this.item);
|
||||
return html`<umb-tree-item-base .item=${this.item}></umb-tree-item-base>`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-entity-tree-item': UmbEntityTreeItemElement;
|
||||
}
|
||||
}
|
||||
@@ -15,12 +15,18 @@ import {
|
||||
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api';
|
||||
import type { TreeItemPresentationModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
|
||||
// add type for unique function
|
||||
export type UmbTreeItemUniqueFunction<T extends TreeItemPresentationModel> = (x: T) => string | null | undefined;
|
||||
|
||||
export class UmbTreeItemContextBase<T extends TreeItemPresentationModel = TreeItemPresentationModel> {
|
||||
public host: UmbControllerHostInterface;
|
||||
public treeItem: T;
|
||||
public unique: string;
|
||||
public type: string;
|
||||
|
||||
#hasChildren = new BooleanState(false);
|
||||
hasChildren = this.#hasChildren.asObservable();
|
||||
|
||||
#isLoading = new BooleanState(false);
|
||||
isLoading = this.#isLoading.asObservable();
|
||||
|
||||
@@ -43,36 +49,22 @@ export class UmbTreeItemContextBase<T extends TreeItemPresentationModel = TreeIt
|
||||
#sectionContext?: UmbSectionContext;
|
||||
#sectionSidebarContext?: UmbSectionSidebarContext;
|
||||
|
||||
constructor(host: UmbControllerHostInterface, treeItem: T, getUnique: (x: T) => string | null | undefined) {
|
||||
constructor(host: UmbControllerHostInterface, treeItem: T, getUniqueFunction: UmbTreeItemUniqueFunction<T>) {
|
||||
this.host = host;
|
||||
this.treeItem = treeItem;
|
||||
|
||||
const unique = getUnique(this.treeItem);
|
||||
const unique = getUniqueFunction(this.treeItem);
|
||||
if (!unique) throw new Error('Could not create tree item context, unique key is missing');
|
||||
this.unique = unique;
|
||||
|
||||
if (!this.treeItem.type) throw new Error('Could not create tree item context, tree item type is missing');
|
||||
|
||||
this.type = this.treeItem.type;
|
||||
|
||||
new UmbContextConsumerController(host, UMB_SECTION_CONTEXT_TOKEN, (instance) => {
|
||||
this.#sectionContext = instance;
|
||||
this.#observeSectionPath();
|
||||
});
|
||||
|
||||
new UmbContextConsumerController(host, UMB_SECTION_SIDEBAR_CONTEXT_TOKEN, (instance) => {
|
||||
this.#sectionSidebarContext = instance;
|
||||
});
|
||||
|
||||
new UmbContextConsumerController(host, 'umbTreeContext', (treeContext: UmbTreeContextBase) => {
|
||||
this.treeContext = treeContext;
|
||||
this.#observeIsSelectable();
|
||||
this.#observeIsSelected();
|
||||
});
|
||||
|
||||
new UmbContextProviderController(host, UMB_TREE_ITEM_CONTEXT_TOKEN, this);
|
||||
|
||||
this.#observeTreeItemActions();
|
||||
this.#hasChildren.next(this.treeItem.hasChildren || false);
|
||||
|
||||
this.#consumeContexts();
|
||||
new UmbContextProviderController(host, UMB_TREE_ITEM_CONTEXT_TOKEN, this);
|
||||
}
|
||||
|
||||
public async requestChildren() {
|
||||
@@ -95,6 +87,23 @@ export class UmbTreeItemContextBase<T extends TreeItemPresentationModel = TreeIt
|
||||
this.treeContext?.deselect(this.unique);
|
||||
}
|
||||
|
||||
#consumeContexts() {
|
||||
new UmbContextConsumerController(this.host, UMB_SECTION_CONTEXT_TOKEN, (instance) => {
|
||||
this.#sectionContext = instance;
|
||||
this.#observeSectionPath();
|
||||
});
|
||||
|
||||
new UmbContextConsumerController(this.host, UMB_SECTION_SIDEBAR_CONTEXT_TOKEN, (instance) => {
|
||||
this.#sectionSidebarContext = instance;
|
||||
});
|
||||
|
||||
new UmbContextConsumerController(this.host, 'umbTreeContext', (treeContext: UmbTreeContextBase) => {
|
||||
this.treeContext = treeContext;
|
||||
this.#observeIsSelectable();
|
||||
this.#observeIsSelected();
|
||||
});
|
||||
}
|
||||
|
||||
#observeIsSelectable() {
|
||||
if (!this.treeContext) return;
|
||||
new UmbObserverController(this.host, this.treeContext.selectable, (value) => this.#isSelectable.next(value));
|
||||
|
||||
@@ -22,9 +22,6 @@ export class UmbTreeItemBaseElement extends UmbLitElement {
|
||||
this.requestUpdate('item', oldVal);
|
||||
}
|
||||
|
||||
@property({ type: Boolean, attribute: 'has-children' })
|
||||
hasChildren = false;
|
||||
|
||||
@state()
|
||||
private _childItems?: EntityTreeItemResponseModel[];
|
||||
|
||||
@@ -52,6 +49,7 @@ export class UmbTreeItemBaseElement extends UmbLitElement {
|
||||
this.#treeItemContext = instance;
|
||||
if (!this.#treeItemContext) return;
|
||||
// TODO: investigate if we can make an observe decorator
|
||||
this.observe(this.#treeItemContext.hasChildren, (value) => (this.hasChildren = value));
|
||||
this.observe(this.#treeItemContext.isLoading, (value) => (this._isLoading = value));
|
||||
this.observe(this.#treeItemContext.isSelectable, (value) => (this._isSelectable = value));
|
||||
this.observe(this.#treeItemContext.isSelected, (value) => (this._isSelected = value));
|
||||
|
||||
Reference in New Issue
Block a user