From 9dfa110cb8fbdcca86bbe96befeac15bbaa9fdab Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 28 Feb 2025 13:38:54 +0100 Subject: [PATCH] 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 --- .../content-type-workspace-context-base.ts | 49 ++++++++++++++----- .../document-type-workspace-editor.element.ts | 4 +- .../media-type-workspace-editor.element.ts | 4 +- .../member-type-workspace-editor.element.ts | 4 +- 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/content-type-workspace-context-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/content-type-workspace-context-base.ts index a37960f622..74c3f510d1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/content-type-workspace-context-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/content-type-workspace-context-base.ts @@ -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 = UmbDetailRepository, @@ -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, ): Promise { 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 } 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(); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type/document-type-workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type/document-type-workspace-editor.element.ts index 6fe2558d9d..be615b0227 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type/document-type-workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type/document-type-workspace-editor.element.ts @@ -78,7 +78,7 @@ export class UmbDocumentTypeWorkspaceEditorElement extends UmbLitElement { override render() { return html` - + - + `; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/workspace/media-type-workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/workspace/media-type-workspace-editor.element.ts index 4c7fd19afb..10c68fbe84 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/workspace/media-type-workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/workspace/media-type-workspace-editor.element.ts @@ -82,7 +82,7 @@ export class UmbMediaTypeWorkspaceEditorElement extends UmbLitElement { override render() { return html` - + - + `; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/workspace/member-type-workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/workspace/member-type-workspace-editor.element.ts index c9d8a5f545..521a3a54c5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/workspace/member-type-workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/workspace/member-type-workspace-editor.element.ts @@ -77,7 +77,7 @@ export class UmbMemberTypeWorkspaceEditorElement extends UmbLitElement { override render() { return html` - + - + `; }