From 2ff34b334391258176c20c12ff65672baff9f7d5 Mon Sep 17 00:00:00 2001 From: Lone Iversen <108085781+loivsen@users.noreply.github.com> Date: Wed, 10 Apr 2024 14:26:45 +0200 Subject: [PATCH 1/2] fix workspace setup --- ...lueprint-property-dataset-context.token.ts | 13 ++ ...ment-blueprint-property-dataset-context.ts | 121 ++++++++++++++++++ ...cument-blueprint-root-workspace.element.ts | 3 +- ...-blueprint-workspace-split-view.element.ts | 6 +- .../document-blueprint-workspace.context.ts | 22 +++- .../document-blueprints/workspace/index.ts | 1 + 6 files changed, 156 insertions(+), 10 deletions(-) create mode 100644 src/packages/documents/document-blueprints/property-dataset-context/document-blueprint-property-dataset-context.token.ts create mode 100644 src/packages/documents/document-blueprints/property-dataset-context/document-blueprint-property-dataset-context.ts diff --git a/src/packages/documents/document-blueprints/property-dataset-context/document-blueprint-property-dataset-context.token.ts b/src/packages/documents/document-blueprints/property-dataset-context/document-blueprint-property-dataset-context.token.ts new file mode 100644 index 0000000000..3c28da9db2 --- /dev/null +++ b/src/packages/documents/document-blueprints/property-dataset-context/document-blueprint-property-dataset-context.token.ts @@ -0,0 +1,13 @@ +import { UMB_DOCUMENT_BLUEPRINT_ENTITY_TYPE } from '../entity.js'; +import type { UmbDocumentBlueprintPropertyDataContext } from './document-blueprint-property-dataset-context.js'; +import type { UmbPropertyDatasetContext } from '@umbraco-cms/backoffice/property'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; + +export const IsDocumentBlueprintPropertyDatasetContext = ( + context: UmbPropertyDatasetContext, +): context is UmbDocumentBlueprintPropertyDataContext => context.getEntityType() === UMB_DOCUMENT_BLUEPRINT_ENTITY_TYPE; + +export const UMB_DOCUMENT_BLUEPRINT_PROPERTY_DATASET_CONTEXT = new UmbContextToken< + UmbPropertyDatasetContext, + UmbDocumentBlueprintPropertyDataContext +>('UmbVariantContext', undefined, IsDocumentBlueprintPropertyDatasetContext); diff --git a/src/packages/documents/document-blueprints/property-dataset-context/document-blueprint-property-dataset-context.ts b/src/packages/documents/document-blueprints/property-dataset-context/document-blueprint-property-dataset-context.ts new file mode 100644 index 0000000000..1b67f782e3 --- /dev/null +++ b/src/packages/documents/document-blueprints/property-dataset-context/document-blueprint-property-dataset-context.ts @@ -0,0 +1,121 @@ +import type { UmbDocumentBlueprintWorkspaceContext } from '../workspace/index.js'; +import type { UmbNameablePropertyDatasetContext, UmbPropertyDatasetContext } from '@umbraco-cms/backoffice/property'; +import { UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; +import { type Observable, map } from '@umbraco-cms/backoffice/external/rxjs'; +import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; +import type { UmbVariantModel } from '@umbraco-cms/backoffice/variant'; +import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; +import type { UmbPropertyTypeModel } from '@umbraco-cms/backoffice/content-type'; + +// TODO: This code can be split into a UmbContentTypePropertyDatasetContext, leaving just the publishing state and methods to this class. +export class UmbDocumentBlueprintPropertyDataContext + extends UmbContextBase + implements UmbPropertyDatasetContext, UmbNameablePropertyDatasetContext +{ + #workspace: UmbDocumentBlueprintWorkspaceContext; + #variantId: UmbVariantId; + public getVariantId() { + return this.#variantId; + } + + #currentVariant = new UmbObjectState(undefined); + currentVariant = this.#currentVariant.asObservable(); + + name = this.#currentVariant.asObservablePart((x) => x?.name); + culture = this.#currentVariant.asObservablePart((x) => x?.culture); + segment = this.#currentVariant.asObservablePart((x) => x?.segment); + + // TODO: Refactor: Make a properties observable. (with such I think i mean a property value object array.. array with object with properties, alias, value, culture and segment) + // TO make such happen I think we need to maintain all properties and their value of this object. + // This will actually make it simpler if multiple are watching the same property. + // But it will also mean that we wil watch all properties and their structure, for variantID, all the time for all of the properties. + + getEntityType(): string { + return this.#workspace.getEntityType(); + } + getUnique(): string | undefined { + return this.#workspace.getUnique(); + } + getName(): string | undefined { + return this.#workspace.getName(this.#variantId); + } + setName(name: string) { + this.#workspace.setName(name, this.#variantId); + } + getVariantInfo() { + return this.#workspace.getVariant(this.#variantId); + } + + constructor(host: UmbControllerHost, workspace: UmbDocumentBlueprintWorkspaceContext, variantId?: UmbVariantId) { + // The controller alias, is a very generic name cause we want only one of these for this controller host. + super(host, UMB_PROPERTY_DATASET_CONTEXT); + this.#workspace = workspace; + this.#variantId = variantId ?? UmbVariantId.CreateInvariant(); + + this.observe( + this.#workspace.variantById(this.#variantId), + async (variantInfo) => { + if (!variantInfo) return; + this.#currentVariant.setValue(variantInfo); + }, + '_observeActiveVariant', + ); + } + + #createPropertyVariantId(property: UmbPropertyTypeModel) { + return UmbVariantId.Create({ + culture: property.variesByCulture ? this.#variantId.culture : null, + segment: property.variesBySegment ? this.#variantId.segment : null, + }); + } + + /** + * TODO: Write proper JSDocs here. + * Ideally do not use these methods, its better to communicate directly with the workspace, but if you do not know the property variant id, then this will figure it out for you. So good for externals to set or get values of a property. + */ + async propertyVariantId(propertyAlias: string) { + return (await this.#workspace.structure.propertyStructureByAlias(propertyAlias)).pipe( + map((property) => (property ? this.#createPropertyVariantId(property) : undefined)), + ); + } + + /** + * TODO: Write proper JSDocs here. + * Ideally do not use this method, its better to communicate directly with the workspace, but if you do not know the property variant id, then this will figure it out for you. So good for externals to set or get values of a property. + */ + async propertyValueByAlias( + propertyAlias: string, + ): Promise | undefined> { + await this.#workspace.isLoaded(); + const structure = await this.#workspace.structure.getPropertyStructureByAlias(propertyAlias); + if (structure) { + return this.#workspace.propertyValueByAlias(propertyAlias, this.#createPropertyVariantId(structure)); + } + return; + } + + // TODO: Refactor: Not used currently, but should investigate if we can implement this, to spare some energy. + async propertyValueByAliasAndCulture( + propertyAlias: string, + propertyVariantId: UmbVariantId, + ): Promise | undefined> { + return this.#workspace.propertyValueByAlias(propertyAlias, propertyVariantId); + } + + /** + * TODO: Write proper JSDocs here. + * Ideally do not use these methods, its better to communicate directly with the workspace, but if you do not know the property variant id, then this will figure it out for you. So good for externals to set or get values of a property. + */ + async setPropertyValue(propertyAlias: string, value: unknown) { + // This is not reacting to if the property variant settings changes while running. + const property = await this.#workspace.structure.getPropertyStructureByAlias(propertyAlias); + if (property) { + const variantId = this.#createPropertyVariantId(property); + + // This is not reacting to if the property variant settings changes while running. + this.#workspace.setPropertyValue(propertyAlias, value, variantId); + } + } +} diff --git a/src/packages/documents/document-blueprints/workspace/document-blueprint-root-workspace.element.ts b/src/packages/documents/document-blueprints/workspace/document-blueprint-root-workspace.element.ts index a2595863dd..876fb1d3e4 100644 --- a/src/packages/documents/document-blueprints/workspace/document-blueprint-root-workspace.element.ts +++ b/src/packages/documents/document-blueprints/workspace/document-blueprint-root-workspace.element.ts @@ -1,10 +1,11 @@ +import { UMB_DOCUMENT_BLUEPRINT_WORKSPACE_ALIAS } from './manifests.js'; import { html, customElement, css } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; @customElement('umb-document-blueprint-root-workspace') export class UmbDocumentBlueprintRootWorkspaceElement extends UmbLitElement { render() { - return html` + return html`

diff --git a/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace-split-view.element.ts b/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace-split-view.element.ts index 77cc3b90b3..5f8842615b 100644 --- a/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace-split-view.element.ts +++ b/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace-split-view.element.ts @@ -1,3 +1,4 @@ +import { UMB_DOCUMENT_BLUEPRINT_WORKSPACE_ALIAS } from './manifests.js'; import { UMB_DOCUMENT_BLUEPRINT_WORKSPACE_CONTEXT } from './document-blueprint-workspace.context-token.js'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { css, html, nothing, customElement, state, repeat } from '@umbraco-cms/backoffice/external/lit'; @@ -14,6 +15,7 @@ export class UmbDocumentBlueprintWorkspaceSplitViewElement extends UmbLitElement constructor() { super(); + console.log('split view'); // TODO: Refactor: use a split view workspace context token: this.consumeContext(UMB_DOCUMENT_BLUEPRINT_WORKSPACE_CONTEXT, (context) => { @@ -42,14 +44,14 @@ export class UmbDocumentBlueprintWorkspaceSplitViewElement extends UmbLitElement view.index + '_' + (view.culture ?? '') + '_' + (view.segment ?? '') + '_' + this._variants!.length, (view) => html` `, )}

- ` + ` : nothing; } diff --git a/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts b/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts index 49024a6b9a..c1b7161e4e 100644 --- a/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts +++ b/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts @@ -1,3 +1,4 @@ +import { UmbDocumentBlueprintPropertyDataContext } from '../property-dataset-context/document-blueprint-property-dataset-context.js'; import { UMB_DOCUMENT_BLUEPRINT_ENTITY_TYPE } from '../entity.js'; import { UmbDocumentBlueprintDetailRepository } from '../repository/index.js'; import type { @@ -5,7 +6,7 @@ import type { UmbDocumentBlueprintVariantModel, UmbDocumentBlueprintVariantOptionModel, } from '../types.js'; -import { UmbDocumentPropertyDataContext } from '../../documents/property-dataset-context/document-property-dataset-context.js'; +import { UMB_DOCUMENT_BLUEPRINT_WORKSPACE_ALIAS } from './manifests.js'; import { appendToFrozenArray, mergeObservables, @@ -28,7 +29,6 @@ import { UMB_INVARIANT_CULTURE, UmbVariantId } from '@umbraco-cms/backoffice/var import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbLanguageDetailModel } from '@umbraco-cms/backoffice/language'; import type { UmbRoutableWorkspaceContext } from '@umbraco-cms/backoffice/workspace'; -import { UmbDocumentWorkspaceContext } from '@umbraco-cms/backoffice/document'; type EntityType = UmbDocumentBlueprintDetailModel; @@ -47,12 +47,16 @@ export class UmbDocumentBlueprintWorkspaceContext #persistedData = new UmbObjectState(undefined); #currentData = new UmbObjectState(undefined); - - // TODo: Optimize this so it uses either a App Language Context? [NL] + #getDataPromise?: Promise; + // TODO: Optimize this so it uses either a App Language Context? [NL] #languageRepository = new UmbLanguageCollectionRepository(this); #languages = new UmbArrayState([], (x) => x.unique); public readonly languages = this.#languages.asObservable(); + public isLoaded() { + return this.#getDataPromise; + } + readonly unique = this.#currentData.asObservablePart((data) => data?.unique); readonly contentTypeUnique = this.#currentData.asObservablePart((data) => data?.documentType.unique); @@ -105,7 +109,7 @@ export class UmbDocumentBlueprintWorkspaceContext ); constructor(host: UmbControllerHost) { - super(host, 'Umb.Workspace.DocumentBlueprint'); + super(host, UMB_DOCUMENT_BLUEPRINT_WORKSPACE_ALIAS); this.observe(this.contentTypeUnique, (unique) => this.structure.loadType(unique)); this.observe(this.varies, (varies) => (this.#varies = varies)); @@ -159,7 +163,7 @@ export class UmbDocumentBlueprintWorkspaceContext async load(unique: string) { this.resetState(); - + this.#getDataPromise = this.repository.requestByUnique(unique); const { data, asObservable } = await this.repository.requestByUnique(unique); if (data) { @@ -429,10 +433,14 @@ export class UmbDocumentBlueprintWorkspaceContext } */ - public createPropertyDatasetContext(host: UmbControllerHost, variantId: UmbVariantId) { + /*public createPropertyDatasetContext(host: UmbControllerHost, variantId: UmbVariantId) { // TODO: [LK] Temporary workaround/hack to get the workspace to load. const docCxt = new UmbDocumentWorkspaceContext(host); return new UmbDocumentPropertyDataContext(host, docCxt, variantId); + }*/ + + public createPropertyDatasetContext(host: UmbControllerHost, variantId: UmbVariantId) { + return new UmbDocumentBlueprintPropertyDataContext(host, this, variantId); } public destroy(): void { diff --git a/src/packages/documents/document-blueprints/workspace/index.ts b/src/packages/documents/document-blueprints/workspace/index.ts index 22a5c8eeab..0848864a8d 100644 --- a/src/packages/documents/document-blueprints/workspace/index.ts +++ b/src/packages/documents/document-blueprints/workspace/index.ts @@ -1 +1,2 @@ export * from './document-blueprint-workspace.context-token.js'; +export * from './document-blueprint-workspace.context.js'; From 33d07141bc87a0b7d1918b3ceffa401c44e609bb Mon Sep 17 00:00:00 2001 From: Lone Iversen <108085781+loivsen@users.noreply.github.com> Date: Wed, 10 Apr 2024 15:47:49 +0200 Subject: [PATCH 2/2] view --- ...ment-blueprint-property-dataset-context.ts | 1 + .../workspace/manifests.ts | 29 ++- ...-workspace-view-edit-properties.element.ts | 71 ++++++++ ...ueprint-workspace-view-edit-tab.element.ts | 88 +++++++++ ...t-blueprint-workspace-view-edit.element.ts | 169 ++++++++++++++++++ 5 files changed, 356 insertions(+), 2 deletions(-) create mode 100644 src/packages/documents/document-blueprints/workspace/views/edit/document-blueprint-workspace-view-edit-properties.element.ts create mode 100644 src/packages/documents/document-blueprints/workspace/views/edit/document-blueprint-workspace-view-edit-tab.element.ts create mode 100644 src/packages/documents/document-blueprints/workspace/views/edit/document-blueprint-workspace-view-edit.element.ts diff --git a/src/packages/documents/document-blueprints/property-dataset-context/document-blueprint-property-dataset-context.ts b/src/packages/documents/document-blueprints/property-dataset-context/document-blueprint-property-dataset-context.ts index 1b67f782e3..2d3836ae46 100644 --- a/src/packages/documents/document-blueprints/property-dataset-context/document-blueprint-property-dataset-context.ts +++ b/src/packages/documents/document-blueprints/property-dataset-context/document-blueprint-property-dataset-context.ts @@ -50,6 +50,7 @@ export class UmbDocumentBlueprintPropertyDataContext constructor(host: UmbControllerHost, workspace: UmbDocumentBlueprintWorkspaceContext, variantId?: UmbVariantId) { // The controller alias, is a very generic name cause we want only one of these for this controller host. + super(host, UMB_PROPERTY_DATASET_CONTEXT); this.#workspace = workspace; this.#variantId = variantId ?? UmbVariantId.CreateInvariant(); diff --git a/src/packages/documents/document-blueprints/workspace/manifests.ts b/src/packages/documents/document-blueprints/workspace/manifests.ts index 9427a1084f..b0061305da 100644 --- a/src/packages/documents/document-blueprints/workspace/manifests.ts +++ b/src/packages/documents/document-blueprints/workspace/manifests.ts @@ -1,6 +1,10 @@ import { UMB_DOCUMENT_BLUEPRINT_ENTITY_TYPE } from '../entity.js'; import { UmbSaveWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; -import type { ManifestWorkspace, ManifestWorkspaceActions } from '@umbraco-cms/backoffice/extension-registry'; +import type { + ManifestWorkspace, + ManifestWorkspaceActions, + ManifestWorkspaceView, +} from '@umbraco-cms/backoffice/extension-registry'; export const UMB_DOCUMENT_BLUEPRINT_WORKSPACE_ALIAS = 'Umb.Workspace.DocumentBlueprint'; @@ -15,6 +19,27 @@ const workspace: ManifestWorkspace = { }, }; +const workspaceViews: Array = [ + { + type: 'workspaceView', + alias: 'Umb.WorkspaceView.DocumentBlueprint.Edit', + name: 'Document Blueprint Workspace Edit View', + element: () => import('./views/edit/document-blueprint-workspace-view-edit.element.js'), + weight: 200, + meta: { + label: '#general_content', + pathname: 'content', + icon: 'document', + }, + conditions: [ + { + alias: 'Umb.Condition.WorkspaceAlias', + match: workspace.alias, + }, + ], + }, +]; + const workspaceActions: Array = [ { type: 'workspaceAction', @@ -37,4 +62,4 @@ const workspaceActions: Array = [ }, ]; -export const manifests = [workspace, ...workspaceActions]; +export const manifests = [workspace, ...workspaceViews, ...workspaceActions]; diff --git a/src/packages/documents/document-blueprints/workspace/views/edit/document-blueprint-workspace-view-edit-properties.element.ts b/src/packages/documents/document-blueprints/workspace/views/edit/document-blueprint-workspace-view-edit-properties.element.ts new file mode 100644 index 0000000000..ebabfa0fe7 --- /dev/null +++ b/src/packages/documents/document-blueprints/workspace/views/edit/document-blueprint-workspace-view-edit-properties.element.ts @@ -0,0 +1,71 @@ +import { UMB_DOCUMENT_BLUEPRINT_WORKSPACE_CONTEXT } from '../../document-blueprint-workspace.context-token.js'; +import { css, html, customElement, property, state, repeat } from '@umbraco-cms/backoffice/external/lit'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import type { UmbPropertyTypeModel } from '@umbraco-cms/backoffice/content-type'; +import { UmbContentTypePropertyStructureHelper } from '@umbraco-cms/backoffice/content-type'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import type { UmbDocumentTypeDetailModel } from '@umbraco-cms/backoffice/document-type'; + +@customElement('umb-document-blueprint-workspace-view-edit-properties') +export class UmbDocumentBlueprintWorkspaceViewEditPropertiesElement extends UmbLitElement { + @property({ type: String, attribute: 'container-id', reflect: false }) + public get containerId(): string | null | undefined { + return this.#propertyStructureHelper.getContainerId(); + } + public set containerId(value: string | null | undefined) { + this.#propertyStructureHelper.setContainerId(value); + } + + #propertyStructureHelper = new UmbContentTypePropertyStructureHelper(this); + + @state() + _propertyStructure?: Array; + + constructor() { + super(); + + this.consumeContext(UMB_DOCUMENT_BLUEPRINT_WORKSPACE_CONTEXT, (workspaceContext) => { + this.#propertyStructureHelper.setStructureManager(workspaceContext.structure); + }); + this.observe( + this.#propertyStructureHelper.propertyStructure, + (propertyStructure) => { + this._propertyStructure = propertyStructure; + }, + null, + ); + } + + render() { + return this._propertyStructure + ? repeat( + this._propertyStructure, + (property) => property.alias, + (property) => + html` `, + ) + : ''; + } + + static styles = [ + UmbTextStyles, + css` + .property { + border-bottom: 1px solid var(--uui-color-divider); + } + .property:last-child { + border-bottom: 0; + } + `, + ]; +} + +export default UmbDocumentBlueprintWorkspaceViewEditPropertiesElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-blueprint-workspace-view-edit-properties': UmbDocumentBlueprintWorkspaceViewEditPropertiesElement; + } +} diff --git a/src/packages/documents/document-blueprints/workspace/views/edit/document-blueprint-workspace-view-edit-tab.element.ts b/src/packages/documents/document-blueprints/workspace/views/edit/document-blueprint-workspace-view-edit-tab.element.ts new file mode 100644 index 0000000000..ed60a266fc --- /dev/null +++ b/src/packages/documents/document-blueprints/workspace/views/edit/document-blueprint-workspace-view-edit-tab.element.ts @@ -0,0 +1,88 @@ +import { UMB_DOCUMENT_BLUEPRINT_WORKSPACE_CONTEXT } from '../../document-blueprint-workspace.context-token.js'; +import { css, html, customElement, property, state, repeat } from '@umbraco-cms/backoffice/external/lit'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import type { UmbPropertyTypeContainerModel } from '@umbraco-cms/backoffice/content-type'; +import { UmbContentTypeContainerStructureHelper } from '@umbraco-cms/backoffice/content-type'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; + +import './document-blueprint-workspace-view-edit-properties.element.js'; + +@customElement('umb-document-blueprint-workspace-view-edit-tab') +export class UmbDocumentBlueprintWorkspaceViewEditTabElement extends UmbLitElement { + @property({ type: String }) + public get containerId(): string | null | undefined { + return this._containerId; + } + public set containerId(value: string | null | undefined) { + this._containerId = value; + this.#groupStructureHelper.setContainerId(value); + } + @state() + private _containerId?: string | null; + + #groupStructureHelper = new UmbContentTypeContainerStructureHelper(this); + + @state() + _groups: Array = []; + + @state() + _hasProperties = false; + + constructor() { + super(); + + this.consumeContext(UMB_DOCUMENT_BLUEPRINT_WORKSPACE_CONTEXT, (workspaceContext) => { + this.#groupStructureHelper.setStructureManager(workspaceContext.structure); + }); + this.observe(this.#groupStructureHelper.mergedContainers, (groups) => { + this._groups = groups; + }); + this.observe(this.#groupStructureHelper.hasProperties, (hasProperties) => { + this._hasProperties = hasProperties; + }); + } + + render() { + return html` + ${this._hasProperties + ? html` + + + + ` + : ''} + ${repeat( + this._groups, + (group) => group.id, + (group) => + html` + + `, + )} + `; + } + + static styles = [ + UmbTextStyles, + css` + uui-box { + --uui-box-default-padding: 0 var(--uui-size-space-5); + } + uui-box:not(:first-child) { + margin-top: var(--uui-size-layout-1); + } + `, + ]; +} + +export default UmbDocumentBlueprintWorkspaceViewEditTabElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-blueprint-workspace-view-edit-tab': UmbDocumentBlueprintWorkspaceViewEditTabElement; + } +} diff --git a/src/packages/documents/document-blueprints/workspace/views/edit/document-blueprint-workspace-view-edit.element.ts b/src/packages/documents/document-blueprints/workspace/views/edit/document-blueprint-workspace-view-edit.element.ts new file mode 100644 index 0000000000..9f897c0e3b --- /dev/null +++ b/src/packages/documents/document-blueprints/workspace/views/edit/document-blueprint-workspace-view-edit.element.ts @@ -0,0 +1,169 @@ +import { UMB_DOCUMENT_BLUEPRINT_WORKSPACE_CONTEXT } from '../../document-blueprint-workspace.context-token.js'; +import type { UmbDocumentBlueprintWorkspaceViewEditTabElement } from './document-blueprint-workspace-view-edit-tab.element.js'; +import { css, html, customElement, state, repeat } from '@umbraco-cms/backoffice/external/lit'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import type { UmbPropertyTypeContainerModel } from '@umbraco-cms/backoffice/content-type'; +import { UmbContentTypeContainerStructureHelper } from '@umbraco-cms/backoffice/content-type'; +import type { UmbRoute, UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router'; +import { encodeFolderName } from '@umbraco-cms/backoffice/router'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import type { UmbWorkspaceViewElement } from '@umbraco-cms/backoffice/extension-registry'; + +@customElement('umb-document-blueprint-workspace-view-edit') +export class UmbDocumentBlueprintWorkspaceViewEditElement extends UmbLitElement implements UmbWorkspaceViewElement { + //@state() + //private _hasRootProperties = false; + + @state() + private _hasRootGroups = false; + + @state() + private _routes: UmbRoute[] = []; + + @state() + private _tabs?: Array; + + @state() + private _routerPath?: string; + + @state() + private _activePath = ''; + + private _workspaceContext?: typeof UMB_DOCUMENT_BLUEPRINT_WORKSPACE_CONTEXT.TYPE; + + private _tabsStructureHelper = new UmbContentTypeContainerStructureHelper(this); + + constructor() { + super(); + + this._tabsStructureHelper.setIsRoot(true); + this._tabsStructureHelper.setContainerChildType('Tab'); + this.observe( + this._tabsStructureHelper.mergedContainers, + (tabs) => { + this._tabs = tabs; + this._createRoutes(); + }, + null, + ); + + // _hasRootProperties can be gotten via _tabsStructureHelper.hasProperties. But we do not support root properties currently. + + this.consumeContext(UMB_DOCUMENT_BLUEPRINT_WORKSPACE_CONTEXT, (workspaceContext) => { + this._workspaceContext = workspaceContext; + this._tabsStructureHelper.setStructureManager(workspaceContext.structure); + this._observeRootGroups(); + }); + } + + private _observeRootGroups() { + if (!this._workspaceContext) return; + + this.observe( + this._workspaceContext.structure.hasRootContainers('Group'), + (hasRootGroups) => { + this._hasRootGroups = hasRootGroups; + this._createRoutes(); + }, + '_observeGroups', + ); + } + + private _createRoutes() { + if (!this._tabs || !this._workspaceContext) return; + const routes: UmbRoute[] = []; + + if (this._tabs.length > 0) { + this._tabs?.forEach((tab) => { + const tabName = tab.name ?? ''; + routes.push({ + path: `tab/${encodeFolderName(tabName).toString()}`, + component: () => import('./document-blueprint-workspace-view-edit-tab.element.js'), + setup: (component) => { + (component as UmbDocumentBlueprintWorkspaceViewEditTabElement).containerId = tab.id; + }, + }); + }); + } + + if (this._hasRootGroups) { + routes.push({ + path: '', + component: () => import('./document-blueprint-workspace-view-edit-tab.element.js'), + setup: (component) => { + (component as UmbDocumentBlueprintWorkspaceViewEditTabElement).containerId = null; + }, + }); + } + + if (routes.length !== 0) { + routes.push({ + path: '', + redirectTo: routes[0]?.path, + }); + } + + this._routes = routes; + } + + render() { + if (!this._routes || !this._tabs) return; + return html` + + ${this._routerPath && (this._tabs.length > 1 || (this._tabs.length === 1 && this._hasRootGroups)) + ? html` + ${this._hasRootGroups && this._tabs.length > 0 + ? html` + Content + ` + : ''} + ${repeat( + this._tabs, + (tab) => tab.name, + (tab) => { + const path = this._routerPath + '/tab/' + encodeFolderName(tab.name || ''); + return html`${tab.name}`; + }, + )} + ` + : ''} + + { + this._routerPath = event.target.absoluteRouterPath; + }} + @change=${(event: UmbRouterSlotChangeEvent) => { + this._activePath = event.target.absoluteActiveViewPath || ''; + }}> + + + `; + } + + static styles = [ + UmbTextStyles, + css` + :host { + display: block; + height: 100%; + --uui-tab-background: var(--uui-color-surface); + } + `, + ]; +} + +export default UmbDocumentBlueprintWorkspaceViewEditElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-blueprint-workspace-view-edit': UmbDocumentBlueprintWorkspaceViewEditElement; + } +}