diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-container-structure-helper.class.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-container-structure-helper.class.ts index c3afe98927..2688c49331 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-container-structure-helper.class.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-container-structure-helper.class.ts @@ -240,6 +240,11 @@ export class UmbContentTypeContainerStructureHelper x.id === containerId); } + getContentTypeOfContainer(containerId?: string) { + if (!this.#structure || !containerId) return; + return this.#structure.getContentTypeOfContainer(containerId); + } + containersByNameAndType(name: string, type: UmbPropertyContainerTypes) { return this.#childContainers.asObservablePart((cons) => cons.filter((x) => x.name === name && x.type === type)); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-structure-manager.class.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-structure-manager.class.ts index 26d96f45a8..e0a0601348 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-structure-manager.class.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-structure-manager.class.ts @@ -704,6 +704,12 @@ export class UmbContentTypeStructureManager< }); } + getContentTypeOfContainer(containerId: string) { + return this.#contentTypes + .getValue() + .find((contentType) => contentType.containers.some((c) => c.id === containerId)); + } + contentTypeOfProperty(propertyId: UmbPropertyTypeId) { return this.#contentTypes.asObservablePart((contentTypes) => contentTypes.find((contentType) => contentType.properties.some((p) => p.id === propertyId)), diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-group.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-group.element.ts index 540d32257f..db90c71576 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-group.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-group.element.ts @@ -1,6 +1,6 @@ import type { UUIInputEvent } from '@umbraco-cms/backoffice/external/uui'; import { UmbLitElement, umbFocus } from '@umbraco-cms/backoffice/lit-element'; -import { css, html, customElement, property, state, nothing } from '@umbraco-cms/backoffice/external/lit'; +import { css, html, customElement, property, state, nothing, repeat } from '@umbraco-cms/backoffice/external/lit'; import type { UmbContentTypeContainerStructureHelper, UmbContentTypeModel, @@ -8,6 +8,7 @@ import type { } from '@umbraco-cms/backoffice/content-type'; import './content-type-design-editor-properties.element.js'; +import { umbConfirmModal } from '@umbraco-cms/backoffice/modal'; @customElement('umb-content-type-design-editor-group') export class UmbContentTypeWorkspaceViewEditGroupElement extends UmbLitElement { @@ -37,6 +38,9 @@ export class UmbContentTypeWorkspaceViewEditGroupElement extends UmbLitElement { @property({ type: Boolean, attribute: 'sort-mode-active', reflect: true }) sortModeActive = false; + @property({ attribute: false }) + editContentTypePath?: string; + @state() _groupId?: string; @@ -46,6 +50,9 @@ export class UmbContentTypeWorkspaceViewEditGroupElement extends UmbLitElement { @state() _inherited?: boolean; + @state() + _inheritedFrom?: Array; + #checkInherited() { if (this.groupStructureHelper && this.group) { // Check is this container matches with any other group. If so it is inherited aka. merged with others. [NL] @@ -54,18 +61,22 @@ export class UmbContentTypeWorkspaceViewEditGroupElement extends UmbLitElement { this.observe( this.groupStructureHelper.containersByNameAndType(this.group.name, 'Group'), (containers) => { - const hasAOwnerContainer = containers.some((con) => - this.groupStructureHelper!.isOwnerChildContainer(con.id), - ); + const ownerContainer = containers.find((con) => this.groupStructureHelper!.isOwnerChildContainer(con.id)); + const hasAOwnerContainer = !!ownerContainer; const pureOwnerContainer = hasAOwnerContainer && containers.length === 1; - // TODO: Check if requstUpdate is needed here, I do not think it is when i added it, but I just wanted to be safe when debugging [NL] + // TODO: Check if requestUpdate is needed here, I do not think it is when i added it, but I just wanted to be safe when debugging [NL] const oldHasOwnerContainer = this._hasOwnerContainer; const oldInherited = this._inherited; + const oldInheritedFrom = this._inheritedFrom; this._hasOwnerContainer = hasAOwnerContainer; this._inherited = !pureOwnerContainer; + this._inheritedFrom = containers + .filter((con) => con.id !== this.group!.id) + .map((con) => this.groupStructureHelper!.getContentTypeOfContainer(con.id)); this.requestUpdate('_hasOwnerContainer', oldHasOwnerContainer); this.requestUpdate('_inherited', oldInherited); + this.requestUpdate('_inheritedFrom', oldInheritedFrom); }, 'observeGroupContainers', ); @@ -112,6 +123,27 @@ export class UmbContentTypeWorkspaceViewEditGroupElement extends UmbLitElement { } } + async #requestRemove(e: Event) { + e.preventDefault(); + e.stopImmediatePropagation(); + if (!this.groupStructureHelper || !this._group) return; + + // TODO: Do proper localization here: [NL] + await umbConfirmModal(this, { + headline: `${this.localize.term('actions_delete')} property`, + content: html` + Are you sure you want to delete the group ${this._group.name ?? this._group.id} + + `, + confirmLabel: this.localize.term('actions_delete'), + color: 'danger', + }); + + this.groupStructureHelper.removeContainer(this._group.id); + } + render() { return this._inherited !== undefined && this._groupId ? html` @@ -124,10 +156,9 @@ export class UmbContentTypeWorkspaceViewEditGroupElement extends UmbLitElement { : ''; } + // TODO: impl UMB_EDIT_DOCUMENT_TYPE_PATH_PATTERN #renderContainerHeader() { return html`
-
- + ${this._inherited && this._inheritedFrom + ? html` + + ${this.localize.term('contentTypeEditor_inheritedFrom')} + ${repeat( + this._inheritedFrom, + (inherited) => inherited.unique, + (inherited) => html` + ${inherited.name} + `, + )} + + ` + : null}
- ${this.sortModeActive - ? html` - this._singleValueUpdate('sortOrder', parseInt(e.target.value as string) || 0)} - .value=${this.group!.sortOrder ?? 0} - ?disabled=${!this._hasOwnerContainer}>` - : ''} -
`; +
+ ${this._inherited + ? null + : html` + + `} + ${this.sortModeActive + ? html` + this._singleValueUpdate('sortOrder', parseInt(e.target.value as string) || 0)} + .value=${this.group!.sortOrder ?? 0} + ?disabled=${!this._hasOwnerContainer}>` + : ''} +
`; } static styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-properties.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-properties.element.ts index 06e96bfb28..4f433510d9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-properties.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-properties.element.ts @@ -104,6 +104,9 @@ export class UmbContentTypeDesignEditorPropertiesElement extends UmbLitElement { #propertyStructureHelper = new UmbContentTypePropertyStructureHelper(this); + @property({ attribute: false }) + editContentTypePath?: string; + @state() private _propertyStructure: Array = []; @@ -113,9 +116,6 @@ export class UmbContentTypeDesignEditorPropertiesElement extends UmbLitElement { @state() private _modalRouteBuilderNewProperty?: UmbModalRouteBuilder; - @state() - private _editContentTypePath?: string; - @state() private _sortModeActive?: boolean; @@ -142,18 +142,6 @@ export class UmbContentTypeDesignEditorPropertiesElement extends UmbLitElement { this.consumeContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT, async (workspaceContext) => { this.#propertyStructureHelper.setStructureManager(workspaceContext.structure); - const entityType = workspaceContext.getEntityType(); - - this.#workspaceModal?.destroy(); - this.#workspaceModal = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) - .addAdditionalPath(entityType) - .onSetup(async () => { - return { data: { entityType: entityType, preset: {} } }; - }) - .observeRouteBuilder((routeBuilder) => { - this._editContentTypePath = routeBuilder({}); - }); - this.observe( workspaceContext.structure.ownerContentType, (contentType) => { @@ -208,7 +196,7 @@ export class UmbContentTypeDesignEditorPropertiesElement extends UmbLitElement { return html` diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.element.ts index 4a2a857964..df53221a18 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.element.ts @@ -258,6 +258,7 @@ export class UmbContentTypeDesignEditorPropertyElement extends UmbLitElement { ${this.renderPropertyTags()} @@ -415,7 +416,6 @@ export class UmbContentTypeDesignEditorPropertyElement extends UmbLitElement { #editor { position: relative; - background-color: var(--uui-color-background); } #alias-input, #label-input, diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-tab.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-tab.element.ts index d11766797a..58d32eb3a2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-tab.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-tab.element.ts @@ -12,6 +12,7 @@ import { import './content-type-design-editor-properties.element.js'; import './content-type-design-editor-group.element.js'; import { type UmbSorterConfig, UmbSorterController } from '@umbraco-cms/backoffice/sorter'; +import { UMB_WORKSPACE_MODAL, UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/modal'; const SORTER_CONFIG: UmbSorterConfig = { getUniqueOfElement: (element) => element.group?.id, @@ -71,16 +72,17 @@ export class UmbContentTypeDesignEditorTabElement extends UmbLitElement { }, }); - private _containerId?: string | null; + #workspaceModal?: UmbModalRouteRegistrationController; + #containerId?: string | null; @property({ type: String }) public get containerId(): string | null | undefined { - return this._containerId; + return this.#containerId; } public set containerId(value: string | null | undefined) { - const oldValue = this._containerId; - if (value === this._containerId) return; - this._containerId = value; + const oldValue = this.#containerId; + if (value === this.#containerId) return; + this.#containerId = value; this.#groupStructureHelper.setContainerId(value); this.requestUpdate('containerId', oldValue); } @@ -94,6 +96,9 @@ export class UmbContentTypeDesignEditorTabElement extends UmbLitElement { @state() _sortModeActive?: boolean; + @state() + _editContentTypePath?: string; + #groupStructureHelper = new UmbContentTypeContainerStructureHelper(this); constructor() { @@ -101,6 +106,18 @@ export class UmbContentTypeDesignEditorTabElement extends UmbLitElement { this.consumeContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT, (context) => { this.#groupStructureHelper.setStructureManager(context.structure); + + const entityType = context.getEntityType(); + + this.#workspaceModal?.destroy(); + this.#workspaceModal = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + .addAdditionalPath(entityType) + .onSetup(async () => { + return { data: { entityType: entityType, preset: {} } }; + }) + .observeRouteBuilder((routeBuilder) => { + this._editContentTypePath = routeBuilder({}); + }); }); this.consumeContext(UMB_CONTENT_TYPE_DESIGN_EDITOR_CONTEXT, (context) => { this.observe( @@ -138,19 +155,11 @@ export class UmbContentTypeDesignEditorTabElement extends UmbLitElement { // Idea, maybe we can gather the sortOrder from the last group rendered and add 1 to it? const len = this._groups.length; const sortOrder = len === 0 ? 0 : this._groups[len - 1].sortOrder + 1; - this.#groupStructureHelper.addContainer(this._containerId, sortOrder); + this.#groupStructureHelper.addContainer(this.#containerId, sortOrder); }; render() { return html` - ${ - this._sortModeActive - ? html`` - : '' - } ${ this._hasProperties ? html` @@ -169,6 +178,7 @@ export class UmbContentTypeDesignEditorTabElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor.element.ts index 0431c3e3c3..720c6c6b34 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor.element.ts @@ -276,7 +276,6 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements if (tab) { const path = this._routerPath + '/tab/' + encodeFolderName(tab.name && tab.name !== '' ? tab.name : '-'); window.history.replaceState(null, '', path); - console.log('new tab', path); this.#focusInput(); } } @@ -525,14 +524,6 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements static styles = [ UmbTextStyles, css` - #buttons-wrapper { - flex: 1; - display: flex; - align-items: center; - justify-content: space-between; - align-items: stretch; - } - :host { position: relative; display: flex; @@ -541,6 +532,14 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements --uui-tab-background: var(--uui-color-surface); } + #buttons-wrapper { + flex: 1; + display: flex; + align-items: center; + justify-content: space-between; + align-items: stretch; + } + [drag-placeholder] { opacity: 0.5; } @@ -553,6 +552,7 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements #header { width: 100%; + min-height: var(--uui-size-15); display: flex; align-items: center; justify-content: space-between;