add abstract class for variant tree structure + implement for document

This commit is contained in:
Mads Rasmussen
2024-03-19 13:22:06 +01:00
parent 3d205120b0
commit f2fd096e71
13 changed files with 118 additions and 132 deletions

View File

@@ -3,4 +3,5 @@ export * from './menu-item-layout/index.js';
export * from './menu.element.js';
export * from './menu.context.js';
export * from './menu-tree-structure-workspace-context-base.js';
export * from './menu-variant-tree-structure-workspace-context-base.js';
export * from './types.js';

View File

@@ -0,0 +1,61 @@
import type { UmbVariantStructureItemModel } from './types.js';
import type { UmbTreeRepository } from '@umbraco-cms/backoffice/tree';
import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry';
import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
import { UMB_VARIANT_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace';
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
interface UmbMenuVariantTreeStructureWorkspaceContextBaseArgs {
treeRepositoryAlias: string;
}
export abstract class UmbMenuVariantTreeStructureWorkspaceContextBase extends UmbContextBase<unknown> {
#workspaceContext?: typeof UMB_VARIANT_WORKSPACE_CONTEXT.TYPE;
#args: UmbMenuVariantTreeStructureWorkspaceContextBaseArgs;
#structure = new UmbArrayState<UmbVariantStructureItemModel>([], (x) => x.unique);
public readonly structure = this.#structure.asObservable();
constructor(host: UmbControllerHost, args: UmbMenuVariantTreeStructureWorkspaceContextBaseArgs) {
super(host, 'UmbMenuStructureWorkspaceContext');
this.#args = args;
this.consumeContext(UMB_VARIANT_WORKSPACE_CONTEXT, (instance) => {
this.#workspaceContext = instance;
this.#requestStructure();
});
}
async #requestStructure() {
const isNew = this.#workspaceContext?.getIsNew();
const uniqueObservable = isNew ? this.#workspaceContext?.parentUnique : this.#workspaceContext?.unique;
const unique = (await this.observe(uniqueObservable, () => {})?.asPromise()) as string;
if (!unique) throw new Error('Unique is not available');
const treeRepository = await createExtensionApiByAlias<UmbTreeRepository<any>>(
this,
this.#args.treeRepositoryAlias,
);
const { data } = await treeRepository.requestTreeItemAncestors({ descendantUnique: unique });
if (data) {
const structureItems = data.map((structureItem) => {
return {
unique: structureItem.unique,
entityType: structureItem.entityType,
variants: structureItem.variants.map((variant: any) => {
return {
name: variant.name,
culture: variant.culture,
segment: variant.segment,
};
}),
};
});
this.#structure.setValue(structureItems);
}
}
}

View File

@@ -1,4 +1,3 @@
import { UMB_DOCUMENT_NAVIGATION_STRUCTURE_CONTEXT } from '../../../../../documents/documents/navigation/structure/document-navigation-structure.context-token.js';
import { html, customElement, state, ifDefined } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
@@ -53,7 +52,7 @@ export class UmbVariantWorkspaceBreadcrumbElement extends UmbLitElement {
this.#observeWorkspaceActiveVariant();
});
this.consumeContext(UMB_DOCUMENT_NAVIGATION_STRUCTURE_CONTEXT, (instance) => {
this.consumeContext('UmbMenuStructureWorkspaceContext', (instance) => {
if (!instance) return;
this.#structureContext = instance;
this.#observeAncestors();

View File

@@ -12,7 +12,7 @@ export * from './modals/index.js';
export * from './global-contexts/index.js';
export * from './tree/index.js';
export { UMB_CONTENT_MENU_ALIAS } from './navigation/manifests.js';
export { UMB_CONTENT_MENU_ALIAS } from './menu/manifests.js';
export { UMB_DOCUMENT_COLLECTION_ALIAS } from './collection/index.js';
export type * from './types.js';

View File

@@ -2,7 +2,7 @@ import { manifests as collectionManifests } from './collection/manifests.js';
import { manifests as entityActionManifests } from './entity-actions/manifests.js';
import { manifests as entityBulkActionManifests } from './entity-bulk-actions/manifests.js';
import { manifests as modalManifests } from './modals/manifests.js';
import { manifests as navigationManifests } from './navigation/manifests.js';
import { manifests as menuManifests } from './menu/manifests.js';
import { manifests as propertyEditorManifests } from './property-editors/manifests.js';
import { manifests as recycleBinManifests } from './recycle-bin/manifests.js';
import { manifests as repositoryManifests } from './repository/manifests.js';
@@ -17,7 +17,7 @@ export const manifests = [
...entityActionManifests,
...entityBulkActionManifests,
...modalManifests,
...navigationManifests,
...menuManifests,
...propertyEditorManifests,
...recycleBinManifests,
...repositoryManifests,

View File

@@ -0,0 +1,11 @@
import { UMB_DOCUMENT_TREE_REPOSITORY_ALIAS } from '../tree/index.js';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbMenuVariantTreeStructureWorkspaceContextBase } from '@umbraco-cms/backoffice/menu';
export class UmbDocumentMenuStructureContext extends UmbMenuVariantTreeStructureWorkspaceContextBase {
constructor(host: UmbControllerHost) {
super(host, { treeRepositoryAlias: UMB_DOCUMENT_TREE_REPOSITORY_ALIAS });
}
}
export default UmbDocumentMenuStructureContext;

View File

@@ -0,0 +1,39 @@
import { UMB_DOCUMENT_TREE_ALIAS } from '../tree/index.js';
export const UMB_CONTENT_MENU_ALIAS = 'Umb.Menu.Content';
export const manifests = [
{
type: 'menu',
alias: UMB_CONTENT_MENU_ALIAS,
name: 'Content Menu',
meta: {
label: 'Content',
},
},
{
type: 'menuItem',
kind: 'tree',
alias: 'Umb.MenuItem.Document',
name: 'Document Menu Item',
weight: 200,
meta: {
label: 'Documents',
menus: [UMB_CONTENT_MENU_ALIAS],
treeAlias: UMB_DOCUMENT_TREE_ALIAS,
hideTreeRoot: true,
},
},
{
type: 'workspaceContext',
name: 'Document Structure Context',
alias: 'Umb.Context.Document.Structure',
api: () => import('./document-menu-structure.context.js'),
conditions: [
{
alias: 'Umb.Condition.WorkspaceAlias',
match: 'Umb.Workspace.Document',
},
],
},
];

View File

@@ -1,30 +0,0 @@
import { UMB_DOCUMENT_TREE_ALIAS } from '../tree/index.js';
import { manifests as structureManifests } from './structure/manifests.js';
import type { ManifestMenuItemTreeKind, ManifestMenu } from '@umbraco-cms/backoffice/extension-registry';
export const UMB_CONTENT_MENU_ALIAS = 'Umb.Menu.Content';
const menu: ManifestMenu = {
type: 'menu',
alias: UMB_CONTENT_MENU_ALIAS,
name: 'Content Menu',
meta: {
label: 'Content',
},
};
const menuItem: ManifestMenuItemTreeKind = {
type: 'menuItem',
kind: 'tree',
alias: 'Umb.MenuItem.Document',
name: 'Document Menu Item',
weight: 200,
meta: {
label: 'Documents',
menus: [UMB_CONTENT_MENU_ALIAS],
treeAlias: UMB_DOCUMENT_TREE_ALIAS,
hideTreeRoot: true,
},
};
export const manifests = [menu, menuItem, ...structureManifests];

View File

@@ -1,6 +0,0 @@
import type { UmbDocumentNavigationStructureContext } from './document-navigation-structure.context.js';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
export const UMB_DOCUMENT_NAVIGATION_STRUCTURE_CONTEXT = new UmbContextToken<UmbDocumentNavigationStructureContext>(
'UmbDocumentNavigationStructureContext',
);

View File

@@ -1,75 +0,0 @@
import { UmbDocumentTreeRepository } from '../../tree/document-tree.repository.js';
import type { UmbDocumentTreeItemModel } from '../../tree/types.js';
import { UMB_DOCUMENT_NAVIGATION_STRUCTURE_CONTEXT } from './document-navigation-structure.context-token.js';
import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbVariantableWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace';
import { UMB_VARIANT_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace';
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { UmbVariantModel } from '@umbraco-cms/backoffice/variant';
interface UmbVariantStructureModel {
unique: string | null;
entityType: string;
variants: [
{
name: string;
culture: string | null;
segment: string | null;
},
];
}
export class UmbDocumentNavigationStructureContext extends UmbContextBase<UmbDocumentNavigationStructureContext> {
#workspaceContext?: UmbVariantableWorkspaceContextInterface<UmbVariantModel>;
#treeRepository = new UmbDocumentTreeRepository(this);
#structure = new UmbArrayState<UmbVariantStructureModel>([], (x) => x.unique);
public readonly structure = this.#structure.asObservable();
constructor(host: UmbControllerHost) {
super(host, UMB_DOCUMENT_NAVIGATION_STRUCTURE_CONTEXT);
this.consumeContext(UMB_VARIANT_WORKSPACE_CONTEXT, (instance) => {
this.#workspaceContext = instance;
this.#requestAncestors();
});
}
async #requestAncestors() {
const { data: treeRootData } = await this.#treeRepository.requestTreeRoot();
/* TODO: implement breadcrumb for new items
We currently miss the parent item name for new items. We need to align with backend
how to solve it */
const isNew = this.#workspaceContext?.getIsNew();
if (isNew === true) return;
this.observe(this.#workspaceContext?.unique, async (unique) => {
if (!unique) return;
const { data } = await this.#treeRepository.requestTreeItemAncestors({ descendantUnique: unique });
if (data) {
const structureItems = data.map((item: UmbDocumentTreeItemModel) => {
return {
unique: item.unique,
entityType: item.entityType,
variants: item.variants.map((variant) => {
return {
name: variant.name,
culture: variant.culture,
segment: variant.segment,
};
}),
};
});
this.#structure.setValue(structureItems);
console.log(this.#structure.getValue());
}
});
}
}
export default UmbDocumentNavigationStructureContext;

View File

@@ -1,14 +0,0 @@
export const manifests = [
{
type: 'workspaceContext',
name: 'Document Structure Context',
alias: 'Umb.Context.Document.Structure',
api: () => import('./document-navigation-structure.context.js'),
conditions: [
{
alias: 'Umb.Condition.WorkspaceAlias',
match: 'Umb.Workspace.Document',
},
],
},
];

View File

@@ -1,4 +1,4 @@
import { UMB_CONTENT_MENU_ALIAS } from '../../navigation/manifests.js';
import { UMB_CONTENT_MENU_ALIAS } from '../../menu/manifests.js';
import type { ManifestMenuItemTreeKind } from '@umbraco-cms/backoffice/extension-registry';
const menuItem: ManifestMenuItemTreeKind = {

View File

@@ -1,6 +1,6 @@
import { manifests as dashboardManifests } from './dashboards/manifests.js';
import { manifests as contentSectionManifests } from './section.manifests.js';
import { manifests as contentMenuManifest } from './documents/navigation/manifests.js';
import { manifests as contentMenuManifest } from './documents/menu/manifests.js';
import { manifests as documentBlueprintManifests } from './document-blueprints/manifests.js';
import { manifests as documentTypeManifests } from './document-types/manifests.js';
import { manifests as documentManifests } from './documents/manifests.js';