Content Type Designer: Fix moving a group to an inherited tab (#20138)
move group to inherited tab
This commit is contained in:
@@ -39,7 +39,7 @@ export class UmbContentTypeContainerStructureHelper<T extends UmbContentTypeMode
|
||||
return this.#legacyMergedChildContainers.asObservable();
|
||||
}
|
||||
|
||||
#childContainersMerged = new UmbArrayState<UmbPropertyTypeContainerMergedModel>([], (x) => x.path);
|
||||
#childContainersMerged = new UmbArrayState<UmbPropertyTypeContainerMergedModel>([], (x) => x.key);
|
||||
public readonly childContainers = this.#childContainersMerged.asObservable();
|
||||
|
||||
// Owner containers are containers owned by the owner Content Type (The specific one up for editing)
|
||||
|
||||
@@ -198,6 +198,8 @@ export class UmbContentTypeStructureManager<
|
||||
this.#ownerContentTypeUnique = unique;
|
||||
if (!unique) {
|
||||
this.#initRejection?.(`Content Type structure manager could not load: ${unique}`);
|
||||
this.#initResolver = undefined;
|
||||
this.#initRejection = undefined;
|
||||
return Promise.reject(
|
||||
new Error('The unique identifier is missing. A valid unique identifier is required to load the content type.'),
|
||||
);
|
||||
@@ -207,6 +209,8 @@ export class UmbContentTypeStructureManager<
|
||||
const result = await this.observe(observable).asPromise();
|
||||
if (!result) {
|
||||
this.#initRejection?.(`Content Type structure manager could not load: ${unique}`);
|
||||
this.#initResolver = undefined;
|
||||
this.#initRejection = undefined;
|
||||
return {
|
||||
error: new UmbError(`Content Type structure manager could not load: ${unique}`),
|
||||
asObservable: () => observable,
|
||||
@@ -219,10 +223,14 @@ export class UmbContentTypeStructureManager<
|
||||
}).catch(() => {
|
||||
const msg = `Content Type structure manager could not load: ${unique}. Not all Content Types loaded successfully.`;
|
||||
this.#initRejection?.(msg);
|
||||
this.#initResolver = undefined;
|
||||
this.#initRejection = undefined;
|
||||
return Promise.reject(new UmbError(msg));
|
||||
});
|
||||
|
||||
this.#initResolver?.(result);
|
||||
this.#initResolver = undefined;
|
||||
this.#initRejection = undefined;
|
||||
return { data: result, asObservable: () => this.ownerContentType };
|
||||
}
|
||||
|
||||
@@ -234,6 +242,8 @@ export class UmbContentTypeStructureManager<
|
||||
const { data } = repsonse;
|
||||
if (!data) {
|
||||
this.#initRejection?.(`Content Type structure manager could not create scaffold`);
|
||||
this.#initResolver = undefined;
|
||||
this.#initRejection = undefined;
|
||||
return { error: repsonse.error };
|
||||
}
|
||||
|
||||
@@ -244,6 +254,8 @@ export class UmbContentTypeStructureManager<
|
||||
// Make a entry in the repo manager:
|
||||
this.#repoManager!.addEntry(data);
|
||||
this.#initResolver?.(data);
|
||||
this.#initResolver = undefined;
|
||||
this.#initRejection = undefined;
|
||||
return repsonse;
|
||||
}
|
||||
|
||||
@@ -997,16 +1009,21 @@ export class UmbContentTypeStructureManager<
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* Find merged containers that match the provided container ids.
|
||||
* Notice if you can provide one or more ids matching the same container and it will still only return return the matching container once.
|
||||
* @param containerIds - An array of container ids to find merged containers for.
|
||||
* @param id
|
||||
* Find a merged container that match the provided container id.
|
||||
* @param {string} id - The id to find the merged container of.
|
||||
* @returns {UmbPropertyTypeContainerMergedModel | undefined} - The merged containers that match the provided container ids.
|
||||
*/
|
||||
getMergedContainerById(id: string): UmbPropertyTypeContainerMergedModel | undefined {
|
||||
return this.#mergedContainers.find((x) => x.ids.includes(id));
|
||||
}
|
||||
/**
|
||||
* Find a merged container that match the provided merged-container key.
|
||||
* @param {string} key - The key to find the merged container of.
|
||||
* @returns {UmbPropertyTypeContainerMergedModel | undefined} - The merged containers that match the provided merged-container key.
|
||||
*/
|
||||
getMergedContainerByKey(key: string): UmbPropertyTypeContainerMergedModel | undefined {
|
||||
return this.#mergedContainers.find((x) => x.key === key);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
@@ -42,7 +42,7 @@ export class UmbContentTypeWorkspaceViewEditGroupElement extends UmbLitElement {
|
||||
@state()
|
||||
private _groupId?: string;
|
||||
|
||||
@state()
|
||||
@property({ type: Boolean, reflect: true, attribute: 'has-owner-container' })
|
||||
private _hasOwnerContainer?: boolean;
|
||||
|
||||
// attrbute is used by Sorter Controller in parent scope.
|
||||
@@ -273,12 +273,11 @@ export class UmbContentTypeWorkspaceViewEditGroupElement extends UmbLitElement {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
cursor: grab;
|
||||
padding: var(--uui-size-space-4) var(--uui-size-space-5);
|
||||
}
|
||||
|
||||
:host([inherited]) div[slot='header'] {
|
||||
cursor: default;
|
||||
:host([has-owner-container]) div[slot='header'] {
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
div[slot='header'] > div {
|
||||
|
||||
@@ -5,10 +5,10 @@ import type {
|
||||
UmbPropertyTypeContainerModel,
|
||||
} from '../../../types.js';
|
||||
import { UmbContentTypeContainerStructureHelper } from '../../../structure/index.js';
|
||||
import { UMB_CONTENT_TYPE_DESIGN_EDITOR_CONTEXT } from './content-type-design-editor.context-token.js';
|
||||
import type { UmbContentTypeWorkspaceViewEditGroupElement } from './content-type-design-editor-group.element.js';
|
||||
import { css, customElement, html, nothing, property, repeat, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { UMB_CONTENT_TYPE_DESIGN_EDITOR_CONTEXT } from './content-type-design-editor.context-token.js';
|
||||
import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router';
|
||||
import { UmbSorterController } from '@umbraco-cms/backoffice/sorter';
|
||||
import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace';
|
||||
@@ -19,13 +19,13 @@ import './content-type-design-editor-group.element.js';
|
||||
|
||||
const SORTER_CONFIG: UmbSorterConfig<UmbPropertyTypeContainerMergedModel, UmbContentTypeWorkspaceViewEditGroupElement> =
|
||||
{
|
||||
getUniqueOfElement: (element) => element.group?.key,
|
||||
getUniqueOfModel: (modelEntry) => modelEntry.key,
|
||||
getUniqueOfElement: (element) => element.group?.ownerId ?? element.group?.ids[0],
|
||||
getUniqueOfModel: (modelEntry) => modelEntry.ownerId ?? modelEntry.ids[0],
|
||||
// TODO: Make specific to the current owner document. [NL]
|
||||
identifier: 'content-type-container-sorter',
|
||||
itemSelector: 'umb-content-type-design-editor-group',
|
||||
handleSelector: '.drag-handle',
|
||||
disabledItemSelector: '[inherited]', // Inherited attribute is set by the umb-content-type-design-editor-group.
|
||||
disabledItemSelector: ':not([has-owner-container])', // Inherited attribute is set by the umb-content-type-design-editor-group.
|
||||
containerSelector: '.container-list',
|
||||
};
|
||||
|
||||
@@ -38,18 +38,34 @@ export class UmbContentTypeDesignEditorTabElement extends UmbLitElement {
|
||||
onChange: ({ model }) => {
|
||||
this._groups = model;
|
||||
},
|
||||
onContainerChange: ({ item }) => {
|
||||
if (this.#containerId === undefined) {
|
||||
throw new Error('ContainerId is not set');
|
||||
}
|
||||
if (item.ownerId === undefined) {
|
||||
// This may be possible later, but for now this is not possible. [NL]
|
||||
throw new Error(
|
||||
'OwnerId is not set for the given container, we cannot move containers that are not owned by the current Document.',
|
||||
);
|
||||
}
|
||||
this.#groupStructureHelper.partialUpdateContainer(item.ownerId, {
|
||||
parent: this.#containerId ? { id: this.#containerId } : null,
|
||||
});
|
||||
},
|
||||
onEnd: ({ item }) => {
|
||||
/*if (this._inherited === undefined) {
|
||||
throw new Error('OwnerTabId is not set, we have not made a local duplicated of this container.');
|
||||
return;
|
||||
}*/
|
||||
if (item.ownerId === undefined) {
|
||||
// This may be possible later, but for now this is not possible. [NL]
|
||||
throw new Error(
|
||||
'OwnerId is not set for the given container, we cannot move containers that are not owned by the current Document.',
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Explanation: If the item is the first in list, we compare it to the item behind it to set a sortOrder.
|
||||
* If it's not the first in list, we will compare to the item in before it, and check the following item to see if it caused overlapping sortOrder, then update
|
||||
* the overlap if true, which may cause another overlap, so we loop through them till no more overlaps...
|
||||
*/
|
||||
const model = this._groups;
|
||||
const newIndex = model.findIndex((entry) => entry.key === item.key);
|
||||
const newIndex = model.findIndex((entry) => entry.ownerId === item.ownerId);
|
||||
|
||||
// Doesn't exist in model
|
||||
if (newIndex === -1) return;
|
||||
@@ -87,20 +103,22 @@ export class UmbContentTypeDesignEditorTabElement extends UmbLitElement {
|
||||
this.#groupStructureHelper.partialUpdateContainer(entry.ownerId, {
|
||||
sortOrder: ++prevSortOrder,
|
||||
});
|
||||
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
},
|
||||
onRequestDrop: async ({ unique }) => {
|
||||
const context = await this.getContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT);
|
||||
const context = this.#contentTypeWorkspaceContext;
|
||||
if (!context) {
|
||||
throw new Error('Could not get Workspace Context');
|
||||
}
|
||||
return context.structure.getMergedContainerById(unique) as UmbPropertyTypeContainerMergedModel | undefined;
|
||||
const result = context.structure.getMergedContainerById(unique) as
|
||||
| UmbPropertyTypeContainerMergedModel
|
||||
| undefined;
|
||||
return result;
|
||||
},
|
||||
requestExternalRemove: async ({ item }) => {
|
||||
const context = await this.getContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT);
|
||||
const context = this.#contentTypeWorkspaceContext;
|
||||
if (!context) {
|
||||
throw new Error('Could not get Workspace Context');
|
||||
}
|
||||
@@ -110,7 +128,7 @@ export class UmbContentTypeDesignEditorTabElement extends UmbLitElement {
|
||||
);
|
||||
},
|
||||
requestExternalInsert: async ({ item }) => {
|
||||
const context = await this.getContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT);
|
||||
const context = this.#contentTypeWorkspaceContext;
|
||||
if (!context) {
|
||||
throw new Error('Could not get Workspace Context');
|
||||
}
|
||||
@@ -165,11 +183,13 @@ export class UmbContentTypeDesignEditorTabElement extends UmbLitElement {
|
||||
private _editContentTypePath?: string;
|
||||
|
||||
#groupStructureHelper = new UmbContentTypeContainerStructureHelper<UmbContentTypeModel>(this);
|
||||
#contentTypeWorkspaceContext?: typeof UMB_CONTENT_TYPE_WORKSPACE_CONTEXT.TYPE;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.consumeContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT, (context) => {
|
||||
this.#contentTypeWorkspaceContext = context;
|
||||
this.#groupStructureHelper.setStructureManager(context?.structure);
|
||||
|
||||
const entityType = context?.getEntityType();
|
||||
@@ -190,11 +210,6 @@ export class UmbContentTypeDesignEditorTabElement extends UmbLitElement {
|
||||
context?.isSorting,
|
||||
(isSorting) => {
|
||||
this._sortModeActive = isSorting;
|
||||
if (isSorting) {
|
||||
this.#sorter.enable();
|
||||
} else {
|
||||
this.#sorter.disable();
|
||||
}
|
||||
},
|
||||
'_observeIsSorting',
|
||||
);
|
||||
@@ -294,10 +309,20 @@ export class UmbContentTypeDesignEditorTabElement extends UmbLitElement {
|
||||
align-content: start;
|
||||
}
|
||||
|
||||
/* Ensure the container-list has some height when its empty so groups can be dropped into it.*/
|
||||
.container-list {
|
||||
margin-top: calc(var(--uui-size-layout-1) * -1);
|
||||
padding-top: var(--uui-size-layout-1);
|
||||
}
|
||||
|
||||
.container-list #convert-to-tab {
|
||||
margin-bottom: var(--uui-size-layout-1);
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.container-list[sort-mode-active] {
|
||||
min-height: 100px;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -753,7 +753,7 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements
|
||||
transition: opacity 100ms;
|
||||
}
|
||||
|
||||
uui-tab:not(:hover, :focus) .trash {
|
||||
uui-tab:not(:hover, :focus, :focus-within) .trash {
|
||||
opacity: 0;
|
||||
transition: opacity 100ms;
|
||||
}
|
||||
|
||||
@@ -103,8 +103,12 @@ export class UmbModalRouteRegistrationController<
|
||||
|
||||
this.#init = this.consumeContext(UMB_ROUTE_CONTEXT, (_routeContext) => {
|
||||
this.#routeContext = _routeContext;
|
||||
this.#registerModal().catch(() => undefined);
|
||||
}).asPromise({ preventTimeout: true });
|
||||
if (this.#routeContext) {
|
||||
this.#registerModal().catch(() => undefined);
|
||||
}
|
||||
})
|
||||
.asPromise({ preventTimeout: true })
|
||||
.catch(() => undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,7 +180,7 @@ export class UmbModalRouteRegistrationController<
|
||||
if (oldValue === value) return;
|
||||
|
||||
this.#uniquePaths.set(identifier, value);
|
||||
this.#registerModal().catch(() => undefined);
|
||||
this.#registerModal();
|
||||
}
|
||||
getUniquePathValue(identifier: string): string | undefined {
|
||||
return this.#uniquePaths.get(identifier);
|
||||
@@ -234,7 +238,7 @@ export class UmbModalRouteRegistrationController<
|
||||
override hostConnected() {
|
||||
super.hostConnected();
|
||||
if (!this.#modalRegistrationContext) {
|
||||
this.#registerModal().catch(() => undefined);
|
||||
this.#registerModal();
|
||||
}
|
||||
}
|
||||
override hostDisconnected(): void {
|
||||
|
||||
@@ -247,7 +247,6 @@ export type UmbSorterConfig<T, ElementType extends HTMLElement = HTMLElement> =
|
||||
Partial<Pick<INTERNAL_UmbSorterConfig<T, ElementType>, 'ignorerSelector' | 'containerSelector' | 'identifier'>>;
|
||||
|
||||
/**
|
||||
|
||||
* @class UmbSorterController
|
||||
* @implements {UmbControllerInterface}
|
||||
* @description This controller can make user able to sort items.
|
||||
|
||||
Reference in New Issue
Block a user