15.3: Hotfix: Content type discard changes (#18490)

* wrap in entity detail workspace element

* use element on media type and member type

* add developer console warning

* sync current data with owner content type

* Update content-type-workspace-context-base.ts

* fix lint error
This commit is contained in:
Mads Rasmussen
2025-02-28 13:38:54 +01:00
committed by GitHub
parent 2bdeefec16
commit 9dfa110cb8
4 changed files with 42 additions and 19 deletions

View File

@@ -10,7 +10,7 @@ import {
type UmbRoutableWorkspaceContext,
} from '@umbraco-cms/backoffice/workspace';
import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models';
import { jsonStringComparison, type Observable } from '@umbraco-cms/backoffice/observable-api';
import type { Observable } from '@umbraco-cms/backoffice/observable-api';
import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action';
import {
UmbRequestReloadChildrenOfEntityEvent,
@@ -21,6 +21,8 @@ import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity';
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface UmbContentTypeWorkspaceContextArgs extends UmbEntityDetailWorkspaceContextArgs {}
const LOADING_STATE_UNIQUE = 'umbLoadingContentTypeDetail';
export abstract class UmbContentTypeWorkspaceContextBase<
DetailModelType extends UmbContentTypeDetailModel = UmbContentTypeDetailModel,
DetailRepositoryType extends UmbDetailRepository<DetailModelType> = UmbDetailRepository<DetailModelType>,
@@ -61,6 +63,9 @@ export abstract class UmbContentTypeWorkspaceContextBase<
this.allowedContentTypes = this.structure.ownerContentTypeObservablePart((data) => data?.allowedContentTypes);
this.compositions = this.structure.ownerContentTypeObservablePart((data) => data?.compositions);
this.collection = this.structure.ownerContentTypeObservablePart((data) => data?.collection);
// Keep current data in sync with the owner content type - This is used for the discard changes feature
this.observe(this.structure.ownerContentType, (data) => this._data.setCurrent(data));
}
/**
@@ -72,21 +77,27 @@ export abstract class UmbContentTypeWorkspaceContextBase<
args: UmbEntityDetailWorkspaceContextCreateArgs<DetailModelType>,
): Promise<DetailModelType | undefined> {
this.resetState();
this.loading.addState({ unique: LOADING_STATE_UNIQUE, message: `Creating ${this.getEntityType()} scaffold` });
this.setParent(args.parent);
const request = this.structure.createScaffold(args.preset);
this._getDataPromise = request;
let { data } = await request;
if (!data) return undefined;
this.setUnique(data.unique);
if (data) {
data = await this._scaffoldProcessData(data);
if (this.modalContext) {
data = { ...data, ...this.modalContext.data.preset };
if (this.modalContext) {
// Notice if the preset comes with values, they will overwrite the scaffolded values... [NL]
data = { ...data, ...this.modalContext.data.preset };
}
this.setUnique(data.unique);
this.setIsNew(true);
this._data.setPersisted(data);
}
this.setIsNew(true);
this._data.setPersisted(data);
this.loading.removeState(LOADING_STATE_UNIQUE);
return data;
}
@@ -97,8 +108,13 @@ export abstract class UmbContentTypeWorkspaceContextBase<
* @returns { Promise<DetailModelType> } The loaded data
*/
override async load(unique: string) {
if (unique === this.getUnique() && this._getDataPromise) {
return (await this._getDataPromise) as any;
}
this.resetState();
this.setUnique(unique);
this.loading.addState({ unique: LOADING_STATE_UNIQUE, message: `Loading ${this.getEntityType()} Details` });
this._getDataPromise = this.structure.loadType(unique);
const response = await this._getDataPromise;
const data = response.data;
@@ -106,11 +122,24 @@ export abstract class UmbContentTypeWorkspaceContextBase<
if (data) {
this._data.setPersisted(data);
this.setIsNew(false);
this.observe(
response.asObservable(),
(entity: any) => this.#onDetailStoreChange(entity),
'umbContentTypeDetailStoreObserver',
);
}
this.loading.removeState(LOADING_STATE_UNIQUE);
return response;
}
#onDetailStoreChange(entity: DetailModelType | undefined) {
if (!entity) {
this._data.clear();
}
}
/**
* Creates the Content Type
* @param { DetailModelType } currentData The current data
@@ -232,12 +261,6 @@ export abstract class UmbContentTypeWorkspaceContextBase<
return this.structure.getOwnerContentType();
}
protected override _getHasUnpersistedChanges(): boolean {
const currentData = this.structure.getOwnerContentType();
const persistedData = this._data.getPersisted();
return jsonStringComparison(persistedData, currentData) === false;
}
public override destroy(): void {
this.structure.destroy();
super.destroy();

View File

@@ -78,7 +78,7 @@ export class UmbDocumentTypeWorkspaceEditorElement extends UmbLitElement {
override render() {
return html`
<umb-workspace-editor>
<umb-entity-detail-workspace-editor>
<div id="header" slot="header">
<uui-button id="icon" compact label="icon" look="outline" @click=${this._handleIconClick}>
<umb-icon name=${ifDefined(this._icon)}></umb-icon>
@@ -105,7 +105,7 @@ export class UmbDocumentTypeWorkspaceEditorElement extends UmbLitElement {
@input=${this.#onDescriptionChange}></uui-input>
</div>
</div>
</umb-workspace-editor>
</umb-entity-detail-workspace-editor>
`;
}

View File

@@ -82,7 +82,7 @@ export class UmbMediaTypeWorkspaceEditorElement extends UmbLitElement {
override render() {
return html`
<umb-workspace-editor>
<umb-entity-detail-workspace-editor>
<div id="header" slot="header">
<uui-button id="icon" compact label="icon" look="outline" @click=${this._handleIconClick}>
<umb-icon name=${ifDefined(this._icon)}></umb-icon>
@@ -107,7 +107,7 @@ export class UmbMediaTypeWorkspaceEditorElement extends UmbLitElement {
@input=${this.#onDescriptionChange}></uui-input>
</div>
</div>
</umb-workspace-editor>
</umb-entity-detail-workspace-editor>
`;
}

View File

@@ -77,7 +77,7 @@ export class UmbMemberTypeWorkspaceEditorElement extends UmbLitElement {
override render() {
return html`
<umb-workspace-editor>
<umb-entity-detail-workspace-editor>
<div id="header" slot="header">
<uui-button id="icon" compact label="icon" look="outline" @click=${this._handleIconClick}>
<umb-icon name=${ifDefined(this._icon)}></umb-icon>
@@ -102,7 +102,7 @@ export class UmbMemberTypeWorkspaceEditorElement extends UmbLitElement {
@input=${this.#onDescriptionChange}></uui-input>
</div>
</div>
</umb-workspace-editor>
</umb-entity-detail-workspace-editor>
`;
}