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; }