From 90aabd0cd5c3298b450d3aa26b1fbcde2fa82e72 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 14 Dec 2022 20:11:24 +0100 Subject: [PATCH] add support for single item trees --- .../sections/shared/section.element.ts | 28 ++++++++++--------- .../src/backoffice/trees/manifests.ts | 2 ++ .../trees/shared/tree-item.element.ts | 7 +++-- .../trees/shared/tree-navigator.element.ts | 27 +++++++++++++++++- .../core/extensions-registry/tree.models.ts | 1 + 5 files changed, 48 insertions(+), 17 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/sections/shared/section.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/sections/shared/section.element.ts index 4c6f372374..d6331a6fe2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/sections/shared/section.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/sections/shared/section.element.ts @@ -78,24 +78,26 @@ export class UmbSectionElement extends UmbContextConsumerMixin(UmbObserverMixin( } private _createTreeRoutes() { - const treeRoutes = - this._trees?.map(() => { - return { - path: `:entityType/:key`, - component: () => import('../../editors/shared/editor-entity/editor-entity.element'), - setup: (component: UmbEditorEntityElement, info: any) => { - component.entityKey = info.match.params.key; - component.entityType = info.match.params.entityType; - }, - }; - }) ?? []; - this._routes = [ { path: 'dashboard', component: () => import('./section-dashboards/section-dashboards.element'), }, - ...treeRoutes, + { + path: `:entityType/:key`, + component: () => import('../../editors/shared/editor-entity/editor-entity.element'), + setup: (component: UmbEditorEntityElement, info: any) => { + component.entityKey = info.match.params.key; + component.entityType = info.match.params.entityType; + }, + }, + { + path: `:entityType`, + component: () => import('../../editors/shared/editor-entity/editor-entity.element'), + setup: (component: UmbEditorEntityElement, info: any) => { + component.entityType = info.match.params.entityType; + }, + }, { path: '**', redirectTo: 'dashboard', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/trees/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/trees/manifests.ts index b8c810e378..446d73812f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/trees/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/trees/manifests.ts @@ -1,5 +1,6 @@ import type { ManifestTree } from '@umbraco-cms/models'; + export const manifests: Array = [ { type: 'tree', @@ -11,6 +12,7 @@ export const manifests: Array = [ label: 'Extensions', icon: 'umb:favorite', sections: ['Umb.Section.Settings'], + rootNodeEntityType: 'extensions-list', // TODO: how do we want to handle 'single node trees'. Trees without any children but still needs to open an editor? Currently an editor is chosen based on the entity type. The tree root node doesn't have one, so we need to tell which editor to use. }, }, { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/trees/shared/tree-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/trees/shared/tree-item.element.ts index 64e556f1aa..045a57cb34 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/trees/shared/tree-item.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/trees/shared/tree-item.element.ts @@ -1,6 +1,7 @@ import { css, html, LitElement } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property, state } from 'lit/decorators.js'; +import { ifDefined } from 'lit-html/directives/if-defined.js'; import { UUIMenuItemEvent } from '@umbraco-ui/uui'; import { map } from 'rxjs'; import { repeat } from 'lit/directives/repeat.js'; @@ -23,7 +24,7 @@ export class UmbTreeItem extends UmbContextConsumerMixin(UmbObserverMixin(LitEle private _childItems: Entity[] = []; @state() - private _href = ''; + private _href? = ''; @state() private _loading = false; @@ -120,7 +121,7 @@ export class UmbTreeItem extends UmbContextConsumerMixin(UmbObserverMixin(LitEle // TODO: how do we handle this? private _constructPath(sectionPathname: string, type: string, key: string) { - return `section/${sectionPathname}/${type}/${key}`; + return type ? `section/${sectionPathname}/${type}/${key}` : undefined; } private _onShowChildren(event: UUIMenuItemEvent) { @@ -168,7 +169,7 @@ export class UmbTreeItem extends UmbContextConsumerMixin(UmbObserverMixin(LitEle .loading=${this._loading} .hasChildren=${this.treeItem.hasChildren} label="${this.treeItem.name}" - href="${this._href}" + href="${ifDefined(this._href)}" ?active=${this._isActive}> ${this._renderChildItems()} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/trees/shared/tree-navigator.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/trees/shared/tree-navigator.element.ts index 5727254663..3da760a192 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/trees/shared/tree-navigator.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/trees/shared/tree-navigator.element.ts @@ -3,13 +3,15 @@ import { repeat } from 'lit/directives/repeat.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, state } from 'lit/decorators.js'; import { ifDefined } from 'lit-html/directives/if-defined.js'; +import { UmbSectionContext } from '../../sections/section.context'; import { UmbTreeContext } from '../tree.context'; import { UmbObserverMixin } from '@umbraco-cms/observable-api'; import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; -import type { Entity, ManifestTree } from '@umbraco-cms/models'; +import type { Entity, ManifestSection, ManifestTree } from '@umbraco-cms/models'; import { UmbDataStore } from 'src/core/stores/store'; import './tree-item.element'; +import { UmbDocumentTypeStore } from '@umbraco-cms/stores/document-type/document-type.store'; @customElement('umb-tree-navigator') export class UmbTreeNavigator extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) { @@ -24,7 +26,11 @@ export class UmbTreeNavigator extends UmbContextConsumerMixin(UmbObserverMixin(L @state() private _tree?: ManifestTree; + @state() + private _href?: string; + private _treeStore?: UmbDataStore; + private _sectionContext?: UmbSectionContext; constructor() { super(); @@ -36,6 +42,11 @@ export class UmbTreeNavigator extends UmbContextConsumerMixin(UmbObserverMixin(L this.consumeContext('umbTreeContext', (treeContext: UmbTreeContext) => { this._tree = treeContext.tree; }); + + this.consumeContext('umbSectionContext', (sectionContext: UmbSectionContext) => { + this._sectionContext = sectionContext; + this._observeSection(); + }); } private _onShowRoot() { @@ -54,11 +65,25 @@ export class UmbTreeNavigator extends UmbContextConsumerMixin(UmbObserverMixin(L }); } + private _observeSection() { + if (!this._sectionContext) return; + + this.observe(this._sectionContext?.data, (section) => { + this._href = this._constructPath(section.meta.pathname, this._tree?.meta.rootNodeEntityType); + }); + } + + // TODO: how do we handle this? + private _constructPath(sectionPathname: string, type: string | undefined) { + return type ? `section/${sectionPathname}/${type}` : undefined; + } + render() { // TODO: how do we know if a tree has children? return html` ${this._renderRootItems()} diff --git a/src/Umbraco.Web.UI.Client/src/core/extensions-registry/tree.models.ts b/src/Umbraco.Web.UI.Client/src/core/extensions-registry/tree.models.ts index ccb1543be6..5795dcd3ff 100644 --- a/src/Umbraco.Web.UI.Client/src/core/extensions-registry/tree.models.ts +++ b/src/Umbraco.Web.UI.Client/src/core/extensions-registry/tree.models.ts @@ -9,4 +9,5 @@ export interface MetaTree { label: string; icon: string; sections: Array; + rootNodeEntityType?: string; }