diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.context.ts index 1c466b8a0d..855260a7d8 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.context.ts @@ -6,6 +6,7 @@ import type { DocumentModel, DocumentTypeModel, DocumentTypePropertyTypeContainerModel, + DocumentTypePropertyTypeModel, } from '@umbraco-cms/backend-api'; import { partialUpdateFrozenArray, @@ -182,13 +183,30 @@ export class UmbDocumentWorkspaceContext ); } - propertyStructuresOf(containerKey: string | null) { - return this.#documentTypes.getObservablePart((data) => - // TODO: some merging of properties across document types here: - data[0]?.properties?.filter((p) => containerKey === p.containerKey || null) + propertyValueOfAlias(propertyAlias: string, culture: string | null, segment: string | null) { + return this.#data.getObservablePart((data) => + data?.properties?.find( + (p) => propertyAlias === p.alias && (culture === p.culture || null) && (segment === p.segment || null) + ) ); } + propertyStructuresOf(containerKey: string) { + return this.#documentTypes.getObservablePart((docTypes) => { + const props: DocumentTypePropertyTypeModel[] = []; + docTypes.forEach((docType) => { + docType.properties?.forEach((property) => { + if (property.containerKey === containerKey) { + props.push(property); + } + }); + }); + return props; + }); + } + + // TODO: Check what of these methods I ended actually using: + rootContainers(containerType: 'Group' | 'Tab') { return this.#containers.getObservablePart((data) => { return data.filter((x) => x.parentKey === null && x.type === containerType); @@ -200,7 +218,6 @@ export class UmbDocumentWorkspaceContext containerType: 'Group' | 'Tab' ) { return this.#containers.getObservablePart((data) => { - console.log(data, parentKey, containerType); return data.filter((x) => x.parentKey === parentKey && x.type === containerType); }); } @@ -210,13 +227,6 @@ export class UmbDocumentWorkspaceContext return data.filter((x) => x.name === name && x.type === containerType); }); } - - containerByKey(key: DocumentTypePropertyTypeContainerModel['key']) { - return this.#containers.getObservablePart((data) => { - return data.filter((x) => x.key === key); - }); - } - setPropertyValue(alias: string, value: unknown) { const entry = { alias: alias, value: value }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit-properties.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit-properties.element.ts new file mode 100644 index 0000000000..54eb8ee85b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit-properties.element.ts @@ -0,0 +1,137 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, property, state } from 'lit/decorators.js'; +import { repeat } from 'lit/directives/repeat.js'; +import { UmbDocumentWorkspaceContext } from '../document-workspace.context'; +import { UmbLitElement } from '@umbraco-cms/element'; +import { + DocumentPropertyModel, + DocumentTypePropertyTypeModel, + PropertyTypeContainerViewModelBaseModel, +} from '@umbraco-cms/backend-api'; + +@customElement('umb-document-workspace-view-edit-properties') +export class UmbDocumentWorkspaceViewEditPropertiesElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + :host { + display: block; + margin: var(--uui-size-layout-1); + } + `, + ]; + + private _containerName?: string | undefined; + + @property({ type: String }) + public get containerName(): string | undefined { + return this._containerName; + } + public set containerName(value: string | undefined) { + if (this._containerName === value) return; + this._containerName = value; + this._observeGroupContainers(); + } + + @state() + _groupContainers: Array = []; + + @state() + _propertyStructure: Array = []; + + @state() + _propertyValueMap: Map = new Map(); + + private _workspaceContext?: UmbDocumentWorkspaceContext; + + constructor() { + super(); + + // TODO: Figure out how to get the magic string for the workspace context. + this.consumeContext('umbWorkspaceContext', (workspaceContext) => { + this._workspaceContext = workspaceContext; + this._observeGroupContainers(); + }); + } + + private _observeGroupContainers() { + if (!this._workspaceContext || !this.containerName) return; + + // TODO: Should be no need to update this observable if its already there. + this.observe( + this._workspaceContext!.containersByNameAndType(this.containerName, 'Group'), + (groupContainers) => { + this._groupContainers = groupContainers || []; + groupContainers.forEach((group) => { + if (group.key) { + // Gather property aliases of this group, by group key. + this._observePropertyStructureOfGroup(group); + } + }); + }, + '_observeGroupContainers' + ); + } + + private _observePropertyStructureOfGroup(group: PropertyTypeContainerViewModelBaseModel) { + if (!this._workspaceContext || !group.key) return; + + console.log('_observePropertyStructureOfGroup', group); + + // TODO: Should be no need to update this observable if its already there. + this.observe( + this._workspaceContext.propertyStructuresOf(group.key), + (properties) => { + // If this need to be able to remove properties, we need to clean out the ones of this group.key before inserting them: + //this._propertyStructure = this._propertyStructure.filter((x) => x.containerKey !== group.key); + + properties?.forEach((property) => { + if (!this._propertyStructure.find((x) => x.alias === property.alias)) { + this._propertyStructure.push(property); + this._observePropertyValueOfAlias(property.alias!); + } + }); + }, + '_observePropertyStructureOfGroup' + group.key + ); + + // cache observable + } + + private _observePropertyValueOfAlias(propertyAlias: string) { + if (!this._workspaceContext || !propertyAlias) return; + + // TODO: Should be no need to update this observable if its already there. + this.observe( + this._workspaceContext.propertyValueOfAlias(propertyAlias, null, null), + (propertyValue) => { + if (propertyValue) { + this._propertyValueMap.set(propertyAlias, propertyValue); + } else { + this._propertyValueMap.delete(propertyAlias); + } + }, + '_observePropertyValueOfAlias' + propertyAlias + ); + } + + render() { + return repeat( + this._propertyStructure, + (property) => property.alias, + (property) => + html` ` + ); + } +} + +export default UmbDocumentWorkspaceViewEditPropertiesElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-workspace-view-edit-properties': UmbDocumentWorkspaceViewEditPropertiesElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit-tab.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit-tab.element.ts index 920dd112e6..eb1022b4e9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit-tab.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit-tab.element.ts @@ -5,6 +5,7 @@ import { repeat } from 'lit/directives/repeat.js'; import { UmbDocumentWorkspaceContext } from '../document-workspace.context'; import { UmbLitElement } from '@umbraco-cms/element'; import { DocumentPropertyModel, PropertyTypeContainerViewModelBaseModel } from '@umbraco-cms/backend-api'; +import './document-workspace-view-edit-properties.element'; @customElement('umb-document-workspace-view-edit-tab') export class UmbDocumentWorkspaceViewEditTabElement extends UmbLitElement { @@ -40,7 +41,7 @@ export class UmbDocumentWorkspaceViewEditTabElement extends UmbLitElement { _propertyStructure: DocumentPropertyModel[] = []; @state() - _propertyValue: DocumentPropertyModel[] = []; + _propertyValues: DocumentPropertyModel[] = []; //_propertiesObservables: Map = new Map(); @@ -86,8 +87,6 @@ export class UmbDocumentWorkspaceViewEditTabElement extends UmbLitElement { groups = this._groupContainersMap.get(group.name)!; } groups.push(group); - // Gather property aliases of this group, by group key. - this._observePropertyStructureOfGroup(group); } }); }, @@ -96,37 +95,20 @@ export class UmbDocumentWorkspaceViewEditTabElement extends UmbLitElement { }); } - private _observePropertyStructureOfGroup(group: PropertyTypeContainerViewModelBaseModel) { - if (!this._workspaceContext || !group.key) return undefined; - - this.observe( - this._workspaceContext.propertyStructuresOf(group.key), - (properties) => { - this._propertyStructure = properties || []; - }, - '_observePropertyStructureOfGroup' + group.key - ); - - // cache observable - } - render() { - return repeat( - this._groupContainersMap, - (mapEntry) => mapEntry[0], - (mapEntry) => html` ${mapEntry[0]} ` - ); - - /* - ${repeat( - this._propertyStructure.filter((property) => property.groupKey === group.key, - (property) => property.alias, - (property) => - html` x.alias === property.alias)?.value}> ` - )} - */ + return html` + +
+ ${repeat( + this._groupContainersMap, + (mapEntry) => mapEntry[0], + (mapEntry) => html` + + ` + )} + `; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit.element.ts index d5b112bafa..7499c34722 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit.element.ts @@ -51,7 +51,7 @@ export class UmbDocumentWorkspaceViewEditElement extends UmbLitElement { if (!this._workspaceContext) return; this.observe( - this._workspaceContext.containersOfParentKey(null, 'Tab'), + this._workspaceContext.rootContainers('Tab'), (tabs) => { tabs.forEach((tab) => { // Only add each tab name once, as our containers merge on name: