From 33ee1447cc31c55f73295657410f417da32b7ac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 25 Feb 2025 09:44:31 +0100 Subject: [PATCH] Fix #18431 (#18445) * Keep order from persisted data * refactor to also cover updateCurrent --- .../content/manager/content-data-manager.ts | 29 +++++++++++++++---- .../content/manager/element-data-manager.ts | 29 +++++++++++++++++-- .../src/packages/core/variant/index.ts | 1 + .../src/packages/core/variant/types.ts | 5 ++++ .../packages/core/variant/variant-id.class.ts | 6 +--- .../variant-object-compare.function.ts | 5 ++++ .../entity/entity-workspace-data-manager.ts | 20 +++++++++++++ 7 files changed, 83 insertions(+), 12 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/variant/variant-object-compare.function.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/manager/content-data-manager.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/manager/content-data-manager.ts index d8d375eb4c..85b6ae51e8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content/manager/content-data-manager.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/manager/content-data-manager.ts @@ -2,7 +2,7 @@ import type { UmbContentDetailModel } from '../types.js'; import { UmbElementWorkspaceDataManager } from './element-data-manager.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { appendToFrozenArray, jsonStringComparison } from '@umbraco-cms/backoffice/observable-api'; -import { UmbVariantId, type UmbEntityVariantModel } from '@umbraco-cms/backoffice/variant'; +import { UmbVariantId, umbVariantObjectCompare, type UmbEntityVariantModel } from '@umbraco-cms/backoffice/variant'; export class UmbContentWorkspaceDataManager< ModelType extends UmbContentDetailModel, @@ -19,6 +19,27 @@ export class UmbContentWorkspaceDataManager< this.#variantScaffold = variantScaffold; } + protected override _sortCurrentData = Partial>( + persistedData: Partial, + currentData: GivenType, + ): GivenType { + currentData = super._sortCurrentData(persistedData, currentData); + // Sort the variants in the same order as the persisted data: + const persistedVariants = persistedData.variants; + if (persistedVariants && currentData.variants) { + return { + ...currentData, + variants: [...currentData.variants].sort(function (a, b) { + return ( + persistedVariants.findIndex((x) => umbVariantObjectCompare(x, a)) - + persistedVariants.findIndex((x) => umbVariantObjectCompare(x, b)) + ); + }), + }; + } + return currentData; + } + /** * Sets the variant scaffold data * @param {ModelVariantType} variantScaffold The variant scaffold data @@ -50,8 +71,7 @@ export class UmbContentWorkspaceDataManager< } as ModelVariantType, (x) => variantId.compare(x), ) as Array; - // TODO: I have some trouble with TypeScript here, I does not look like me, but i had to give up. [NL] - this._current.update({ variants: newVariants } as any); + this.updateCurrent({ variants: newVariants } as unknown as ModelType); } else if (this._varies === false) { // TODO: Beware about segments, in this case we need to also consider segments, if its allowed to vary by segments. const invariantVariantId = UmbVariantId.CreateInvariant(); @@ -65,8 +85,7 @@ export class UmbContentWorkspaceDataManager< ...update, } as ModelVariantType, ]; - // TODO: I have some trouble with TypeScript here, I does not look like me, but i had to give up. [NL] - this._current.update({ variants: newVariants } as any); + this.updateCurrent({ variants: newVariants } as unknown as ModelType); } else { throw new Error('Varies by culture is missing'); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/manager/element-data-manager.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/manager/element-data-manager.ts index dfac318c5d..623f99a2c4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content/manager/element-data-manager.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/manager/element-data-manager.ts @@ -1,8 +1,12 @@ import { UmbMergeContentVariantDataController } from '../controller/merge-content-variant-data.controller.js'; import type { UmbElementDetailModel } from '../types.js'; -import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; +import { UmbVariantId, umbVariantObjectCompare } from '@umbraco-cms/backoffice/variant'; import { UmbEntityWorkspaceDataManager, type UmbWorkspaceDataManager } from '@umbraco-cms/backoffice/workspace'; +function valueObjectCompare(a: any, b: any) { + return a.alias === b.alias && umbVariantObjectCompare(a, b); +} + export class UmbElementWorkspaceDataManager extends UmbEntityWorkspaceDataManager implements UmbWorkspaceDataManager @@ -11,6 +15,27 @@ export class UmbElementWorkspaceDataManager = Partial>( + persistedData: Partial, + currentData: GivenType, + ): GivenType { + currentData = super._sortCurrentData(persistedData, currentData); + // Sort the values in the same order as the persisted data: + const persistedValues = persistedData.values; + if (persistedValues && currentData.values) { + return { + ...currentData, + values: [...currentData.values].sort(function (a, b) { + return ( + persistedValues.findIndex((x) => valueObjectCompare(x, a)) - + persistedValues.findIndex((x) => valueObjectCompare(x, b)) + ); + }), + }; + } + return currentData; + } + #updateLock = 0; initiatePropertyValueChange() { this.#updateLock++; @@ -54,7 +79,7 @@ export class UmbElementWorkspaceDataManager */ public readonly current = this._current.asObservable(); + protected _sortCurrentData = Partial>( + persistedData: Partial, + currentData: GivenType, + ): GivenType { + // do nothing. + return currentData; + } + /** * Gets persisted data * @returns {(ModelType | undefined)} @@ -81,6 +89,12 @@ export class UmbEntityWorkspaceDataManager * @memberof UmbSubmittableWorkspaceDataManager */ setCurrent(data: ModelType | undefined) { + if (data) { + const persistedData = this._persisted.getValue(); + if (persistedData) { + data = this._sortCurrentData(persistedData, data); + } + } this._current.setValue(data); } @@ -90,6 +104,12 @@ export class UmbEntityWorkspaceDataManager * @memberof UmbSubmittableWorkspaceDataManager */ updateCurrent(partialData: Partial) { + if (partialData) { + const persistedData = this._persisted.getValue(); + if (persistedData) { + partialData = this._sortCurrentData(persistedData, partialData); + } + } this._current.update(partialData); }