From 2da455069b76c66c3f9af69de7c63a0a7718256e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 20 Feb 2025 17:13:12 +0100 Subject: [PATCH 01/57] property value preset type --- .../property-value-preset.extension.ts | 13 +++++++++++++ .../core/property/property-value-preset/types.ts | 14 ++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset.extension.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset.extension.ts new file mode 100644 index 000000000000..416683f7b0d1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset.extension.ts @@ -0,0 +1,13 @@ +import type { UmbPropertyValueResolver } from './types.js'; +import type { ManifestApi } from '@umbraco-cms/backoffice/extension-api'; + +export interface ManifestPropertyValuePreset extends ManifestApi> { + type: 'propertyValuePreset'; + forEditorAlias: string; +} + +declare global { + interface UmbExtensionManifestMap { + ManifestPropertyValuePreset: ManifestPropertyValuePreset; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts new file mode 100644 index 000000000000..95cc2e2979fe --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts @@ -0,0 +1,14 @@ +import type { UmbPropertyValueData } from '../types/index.js'; +import type { UmbVariantDataModel } from '@umbraco-cms/backoffice/variant'; +import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; + +export type * from './property-value-preset.extension.js'; + +export interface UmbPropertyValueResolver + extends UmbApi { + processValue?: UmbPropertyValueResolverValuesProcessor; +} + +export type UmbPropertyValueResolverValuesProcessor< + PropertyValueType extends UmbPropertyValueData = UmbPropertyValueData, +> = (value: PropertyValueType) => PromiseLike; From 95882f2ba8e25d7fc6376bde658808ba919d8f3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 20 Feb 2025 17:13:22 +0100 Subject: [PATCH 02/57] add version to comment --- .../property-value-resolver.extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-resolver/property-value-resolver.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-resolver/property-value-resolver.extension.ts index 9499e2dde022..bb15c27b6a93 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-resolver/property-value-resolver.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-resolver/property-value-resolver.extension.ts @@ -9,7 +9,7 @@ export interface ManifestPropertyValueResolver extends ManifestApi Date: Thu, 20 Feb 2025 17:14:03 +0100 Subject: [PATCH 03/57] move clone controller --- src/Umbraco.Web.UI.Client/src/packages/core/property/index.ts | 2 +- .../property-value-clone.controller.test.ts | 0 .../property-value-clone.controller.ts | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename src/Umbraco.Web.UI.Client/src/packages/core/property/{controllers => property-value-cloner}/property-value-clone.controller.test.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/core/property/{controllers => property-value-cloner}/property-value-clone.controller.ts (100%) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/index.ts index 3e9e25957511..3d179b636c80 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/index.ts @@ -1,5 +1,5 @@ export * from './components/index.js'; export * from './conditions/index.js'; -export * from './controllers/property-value-clone.controller.js'; +export * from './property-value-cloner/property-value-clone.controller.js'; export * from './property-dataset/index.js'; export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/controllers/property-value-clone.controller.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-cloner/property-value-clone.controller.test.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/core/property/controllers/property-value-clone.controller.test.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-cloner/property-value-clone.controller.test.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/controllers/property-value-clone.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-cloner/property-value-clone.controller.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/core/property/controllers/property-value-clone.controller.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-cloner/property-value-clone.controller.ts From 16ca317b9040baaa6a5c4b6cb7f6cacfe56436f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 20 Feb 2025 21:28:28 +0100 Subject: [PATCH 04/57] add JSDocs --- .../functions/create-extension-api.function.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/libs/extension-api/functions/create-extension-api.function.ts b/src/Umbraco.Web.UI.Client/src/libs/extension-api/functions/create-extension-api.function.ts index a168758d3ab6..82006ce8f461 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/extension-api/functions/create-extension-api.function.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/extension-api/functions/create-extension-api.function.ts @@ -5,10 +5,10 @@ import type { UmbApiConstructorArgumentsMethodType } from './types.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; /** - * - * @param host - * @param manifest - * @param constructorArgs + * @param {UmbControllerHost} host - The controller host for this controller to be appended to + * @param {ManifestApi} manifest - The manifest of the extension + * @param {Array | UmbApiConstructorArgumentsMethodType} constructorArgs - The constructor arguments to pass to the API class + * @returns {Promise} - The API class instance */ export async function createExtensionApi( host: UmbControllerHost, From 1f0cc67393d6e045472f6db49c2b4e53a85afe7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 20 Feb 2025 21:28:39 +0100 Subject: [PATCH 05/57] sort getByTypeAndFilter --- .../src/libs/extension-api/registry/extension.registry.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/libs/extension-api/registry/extension.registry.ts b/src/Umbraco.Web.UI.Client/src/libs/extension-api/registry/extension.registry.ts index 037f2e7f5b2b..15d828a62415 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/extension-api/registry/extension.registry.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/extension-api/registry/extension.registry.ts @@ -467,7 +467,9 @@ export class UmbExtensionRegistry< return []; } const kinds = this._kinds.getValue(); - return exts.map((ext) => (ext?.kind ? (this.#mergeExtensionWithKinds([ext, kinds]) ?? ext) : ext)); + return exts + .map((ext) => (ext?.kind ? (this.#mergeExtensionWithKinds([ext, kinds]) ?? ext) : ext)) + .sort(sortExtensions); } /** From 19529c1e02f291a81d7383d92408d25f7f0272bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 20 Feb 2025 21:29:29 +0100 Subject: [PATCH 06/57] builder --- ...roperty-value-preset-builder.controller.ts | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts new file mode 100644 index 000000000000..961425deba45 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts @@ -0,0 +1,79 @@ +import type { UmbPropertyValueData, UmbPropertyValueDataPotentiallyWithEditorAlias } from '../index.js'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import { createExtensionApi } from '@umbraco-cms/backoffice/extension-api'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; +import type { + UmbPropertyTypePresetModel, + UmbPropertyTypePresetWithSchemaAliasModel, + UmbPropertyValuePresetApi, +} from './types.js'; + +//type PropertyTypesType = UmbPropertyTypePresetModel | UmbPropertyTypePresetWithSchemaAliasModel; + +export class UmbPropertyValuePresetBuilderController extends UmbControllerBase { + /** + * Clones the property data. + * @param {UmbPropertyValueDataPotentiallyWithEditorAlias} property - The property data. + * @returns {Promise} - A promise that resolves to the cloned property data. + */ + async create< + GivenPropertyTypesType extends UmbPropertyTypePresetModel | UmbPropertyTypePresetWithSchemaAliasModel, + ReturnType = GivenPropertyTypesType extends UmbPropertyTypePresetWithSchemaAliasModel + ? UmbPropertyValueDataPotentiallyWithEditorAlias + : UmbPropertyValueData, + >(propertyTypes: Array): Promise> { + const result = await Promise.all(propertyTypes.map(this.#createPropertyPreset)); + + this.destroy(); + + return result; + } + + #createPropertyPreset = async ( + propertyType: UmbPropertyTypePresetModel | UmbPropertyTypePresetWithSchemaAliasModel, + ): Promise => { + const editorAlias: string | undefined = (propertyType as UmbPropertyTypePresetWithSchemaAliasModel) + .propertyEditorSchemaAlias; + + const editorUiAlias = propertyType.propertyEditorUiAlias; + + const alias = propertyType.alias; + if (!alias) { + throw new Error(`alias not defined in ${propertyType}`); + } + + // Find a preset for this editor alias: + const manifests = umbExtensionsRegistry.getByTypeAndFilter( + 'propertyValuePreset', + (x) => x.forPropertyEditorSchemaAlias === editorAlias || x.forPropertyEditorUiAlias === editorUiAlias, + ); + + const apis = (await Promise.all(manifests.map((x) => createExtensionApi(this, x)))).filter( + (x) => x !== undefined, + ) as Array; + + let value: unknown = undefined; + // Important to use a inline for loop, to secure that each entry is processed(asynchronously) in order + for (const api of apis) { + if (!api.processValue) { + throw new Error( + `processValue method is not defined in one of the apis of these extensions: ${manifests.map((x) => x.alias).join(', ')}`, + ); + } + value = await api.processValue(value, propertyType.config); + } + + if (editorAlias) { + return { + editorAlias, + alias, + value, + } satisfies UmbPropertyValueDataPotentiallyWithEditorAlias as ReturnType; + } else { + return { + alias, + value, + } satisfies UmbPropertyValueData as ReturnType; + } + }; +} From 64c7ec3ecd633e96e5dbf2fb2fdc0e015150a0cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 20 Feb 2025 21:30:11 +0100 Subject: [PATCH 07/57] updates for extension type --- .../core/property-editor/config/index.ts | 1 - ...property-editor-config-collection.class.ts | 2 +- .../core/property-editor/config/types.ts | 1 + .../extensions/property-editor.extension.ts | 1 + .../packages/core/property-editor/index.ts | 2 +- .../packages/core/property-editor/types.ts | 2 ++ .../property-value-preset.extension.ts | 7 +++-- .../property/property-value-preset/types.ts | 28 +++++++++++++------ 8 files changed, 30 insertions(+), 14 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/property-editor/config/types.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/property-editor/types.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/config/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/config/index.ts index be254977addb..40cba6de6ff1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/config/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/config/index.ts @@ -1,2 +1 @@ -export type * from './property-editor-config.type.js'; export * from './property-editor-config-collection.class.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/config/property-editor-config-collection.class.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/config/property-editor-config-collection.class.ts index af5c4448a63f..bda33b19f9ef 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/config/property-editor-config-collection.class.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/config/property-editor-config-collection.class.ts @@ -1,4 +1,4 @@ -import type { UmbPropertyEditorConfigProperty, UmbPropertyEditorConfig } from '../index.js'; +import type { UmbPropertyEditorConfigProperty, UmbPropertyEditorConfig } from '../types.js'; import type { DataTypePropertyPresentationModel } from '@umbraco-cms/backoffice/external/backend-api'; /** diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/config/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/config/types.ts new file mode 100644 index 000000000000..516b77df2455 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/config/types.ts @@ -0,0 +1 @@ +export type * from './property-editor-config.type.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/extensions/property-editor.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/extensions/property-editor.extension.ts index c9f0f82d5e70..2ef67d3fa90c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/extensions/property-editor.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/extensions/property-editor.extension.ts @@ -42,6 +42,7 @@ export interface MetaPropertyEditorSchema { export interface PropertyEditorSettings { properties: PropertyEditorSettingsProperty[]; // default data is kept separate from the properties, to give the ability for Property Editor UI to overwrite default values for the property editor settings. + // TODO: Deprecate defaultData in the future and rename to preset. [NL] defaultData?: PropertyEditorSettingsDefaultData[]; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/index.ts index 116b486efdc8..6f36bd603767 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/index.ts @@ -3,4 +3,4 @@ export * from './config/index.js'; export * from './constants.js'; export * from './events/index.js'; export * from './ui-picker-modal/index.js'; -export type * from './extensions/types.js'; +export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/types.ts new file mode 100644 index 000000000000..17fbe12e7a43 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/types.ts @@ -0,0 +1,2 @@ +export type * from './config/types.js'; +export type * from './extensions/types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset.extension.ts index 416683f7b0d1..ad0341524fa3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset.extension.ts @@ -1,9 +1,10 @@ -import type { UmbPropertyValueResolver } from './types.js'; +import type { UmbPropertyValuePresetApi } from './types.js'; import type { ManifestApi } from '@umbraco-cms/backoffice/extension-api'; -export interface ManifestPropertyValuePreset extends ManifestApi> { +export interface ManifestPropertyValuePreset extends ManifestApi> { type: 'propertyValuePreset'; - forEditorAlias: string; + forPropertyEditorSchemaAlias?: string; + forPropertyEditorUiAlias?: string; } declare global { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts index 95cc2e2979fe..cea326faa404 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts @@ -1,14 +1,26 @@ -import type { UmbPropertyValueData } from '../types/index.js'; -import type { UmbVariantDataModel } from '@umbraco-cms/backoffice/variant'; +import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; export type * from './property-value-preset.extension.js'; -export interface UmbPropertyValueResolver - extends UmbApi { - processValue?: UmbPropertyValueResolverValuesProcessor; +export interface UmbPropertyValuePresetApi< + ValueType = unknown, + ConfigType extends UmbPropertyEditorConfig = UmbPropertyEditorConfig, +> extends UmbApi { + processValue: UmbPropertyValuePresetApiValuesProcessor; } -export type UmbPropertyValueResolverValuesProcessor< - PropertyValueType extends UmbPropertyValueData = UmbPropertyValueData, -> = (value: PropertyValueType) => PromiseLike; +export type UmbPropertyValuePresetApiValuesProcessor< + ValueType = unknown, + ConfigType extends UmbPropertyEditorConfig = UmbPropertyEditorConfig, +> = (value: ValueType, config: ConfigType) => PromiseLike; + +export interface UmbPropertyTypePresetModel { + alias: string; + propertyEditorUiAlias: string; + config: UmbPropertyEditorConfig; +} + +export interface UmbPropertyTypePresetWithSchemaAliasModel extends UmbPropertyTypePresetModel { + propertyEditorSchemaAlias: string; +} From c04d0e50efd1be88131ba4bf8e4a8cf32bcf1ad3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 20 Feb 2025 21:36:38 +0100 Subject: [PATCH 08/57] unit test --- ...ty-value-preset-builder.controller.test.ts | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts new file mode 100644 index 000000000000..db30e8af8d15 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts @@ -0,0 +1,113 @@ +import { expect } from '@open-wc/testing'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; +import { customElement } from '@umbraco-cms/backoffice/external/lit'; +import { UmbControllerHostElementMixin } from '@umbraco-cms/backoffice/controller-api'; +import type { + ManifestPropertyValuePreset, + UmbPropertyTypePresetModel, + UmbPropertyTypePresetWithSchemaAliasModel, + UmbPropertyValuePresetApi, +} from './types.js'; +import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; +import { UmbPropertyValuePresetBuilderController } from './property-value-preset-builder.controller.js'; + +@customElement('umb-test-controller-host') +export class UmbTestControllerHostElement extends UmbControllerHostElementMixin(HTMLElement) {} + +export class TestPropertyValuePresetFirstApi implements UmbPropertyValuePresetApi { + async processValue(value: string, config: UmbPropertyEditorConfig) { + return value ? value + '_first' : 'first'; + } + + destroy(): void {} +} + +export class TestPropertyValuePresetSecondApi implements UmbPropertyValuePresetApi { + async processValue(value: string, config: UmbPropertyEditorConfig) { + return value ? value + '_second' : 'second'; + } + + destroy(): void {} +} + +describe('UmbPropertyValuePresetBuilderController', () => { + describe('Create with a single preset', () => { + beforeEach(async () => { + const manifestFirstPreset: ManifestPropertyValuePreset = { + type: 'propertyValuePreset', + name: 'test-preset-1', + alias: 'Umb.Test.Preset.1', + api: TestPropertyValuePresetFirstApi, + forPropertyEditorUiAlias: 'test-editor', + }; + + umbExtensionsRegistry.register(manifestFirstPreset); + }); + afterEach(async () => { + umbExtensionsRegistry.unregister('Umb.Test.Preset.1'); + }); + + it('creates value', async () => { + const ctrlHost = new UmbTestControllerHostElement(); + const ctrl = new UmbPropertyValuePresetBuilderController(ctrlHost); + + const propertyTypes: Array = [ + { + alias: 'test', + propertyEditorUiAlias: 'test-editor', + config: [], + }, + ]; + + const result = await ctrl.create(propertyTypes); + + expect(result.length).to.be.equal(1); + expect(result[0]?.value).to.be.equal('first'); + }); + }); + + describe('Create with a two presets', () => { + beforeEach(async () => { + const manifestFirstPreset: ManifestPropertyValuePreset = { + type: 'propertyValuePreset', + name: 'test-preset-1', + alias: 'Umb.Test.Preset.1', + api: TestPropertyValuePresetFirstApi, + forPropertyEditorUiAlias: 'test-editor', + }; + + const manifestSecondPreset: ManifestPropertyValuePreset = { + type: 'propertyValuePreset', + name: 'test-preset-2', + alias: 'Umb.Test.Preset.2', + api: TestPropertyValuePresetSecondApi, + forPropertyEditorUiAlias: 'test-editor', + }; + + umbExtensionsRegistry.register(manifestFirstPreset); + umbExtensionsRegistry.register(manifestSecondPreset); + }); + afterEach(async () => { + umbExtensionsRegistry.unregister('Umb.Test.Preset.1'); + umbExtensionsRegistry.unregister('Umb.Test.Preset.2'); + }); + + it('creates a combined value', async () => { + const ctrlHost = new UmbTestControllerHostElement(); + const ctrl = new UmbPropertyValuePresetBuilderController(ctrlHost); + + const propertyTypes: Array = [ + { + alias: 'test', + propertyEditorUiAlias: 'test-editor', + config: [], + }, + ]; + + const result = await ctrl.create(propertyTypes); + + expect(result.length).to.be.equal(1); + expect(result[0]?.value).to.be.equal('first_second'); + }); + }); +}); From 7073f4d794354f56486aa5b78b0d10344284ff9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 20 Feb 2025 21:59:48 +0100 Subject: [PATCH 09/57] test weight --- ...ty-value-preset-builder.controller.test.ts | 54 ++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts index db30e8af8d15..174601216a77 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts @@ -14,6 +14,9 @@ import { UmbPropertyValuePresetBuilderController } from './property-value-preset @customElement('umb-test-controller-host') export class UmbTestControllerHostElement extends UmbControllerHostElementMixin(HTMLElement) {} +// TODO: Write test with config, investigate oppertunity to retrieve Config Object, for an simpler DX. [NL] + +// Test with async APIs, espcially where the first one is slower than the last one. export class TestPropertyValuePresetFirstApi implements UmbPropertyValuePresetApi { async processValue(value: string, config: UmbPropertyEditorConfig) { return value ? value + '_first' : 'first'; @@ -72,6 +75,7 @@ describe('UmbPropertyValuePresetBuilderController', () => { type: 'propertyValuePreset', name: 'test-preset-1', alias: 'Umb.Test.Preset.1', + weight: 20, api: TestPropertyValuePresetFirstApi, forPropertyEditorUiAlias: 'test-editor', }; @@ -80,12 +84,13 @@ describe('UmbPropertyValuePresetBuilderController', () => { type: 'propertyValuePreset', name: 'test-preset-2', alias: 'Umb.Test.Preset.2', + weight: 10, api: TestPropertyValuePresetSecondApi, forPropertyEditorUiAlias: 'test-editor', }; - umbExtensionsRegistry.register(manifestFirstPreset); umbExtensionsRegistry.register(manifestSecondPreset); + umbExtensionsRegistry.register(manifestFirstPreset); }); afterEach(async () => { umbExtensionsRegistry.unregister('Umb.Test.Preset.1'); @@ -110,4 +115,51 @@ describe('UmbPropertyValuePresetBuilderController', () => { expect(result[0]?.value).to.be.equal('first_second'); }); }); + + describe('Different weight gets a different execution order', () => { + beforeEach(async () => { + const manifestFirstPreset: ManifestPropertyValuePreset = { + type: 'propertyValuePreset', + name: 'test-preset-1', + alias: 'Umb.Test.Preset.1', + weight: 20, + api: TestPropertyValuePresetFirstApi, + forPropertyEditorUiAlias: 'test-editor', + }; + + const manifestSecondPreset: ManifestPropertyValuePreset = { + type: 'propertyValuePreset', + name: 'test-preset-2', + alias: 'Umb.Test.Preset.2', + weight: 3000, + api: TestPropertyValuePresetSecondApi, + forPropertyEditorUiAlias: 'test-editor', + }; + + umbExtensionsRegistry.register(manifestSecondPreset); + umbExtensionsRegistry.register(manifestFirstPreset); + }); + afterEach(async () => { + umbExtensionsRegistry.unregister('Umb.Test.Preset.1'); + umbExtensionsRegistry.unregister('Umb.Test.Preset.2'); + }); + + it('creates a combined value', async () => { + const ctrlHost = new UmbTestControllerHostElement(); + const ctrl = new UmbPropertyValuePresetBuilderController(ctrlHost); + + const propertyTypes: Array = [ + { + alias: 'test', + propertyEditorUiAlias: 'test-editor', + config: [], + }, + ]; + + const result = await ctrl.create(propertyTypes); + + expect(result.length).to.be.equal(1); + expect(result[0]?.value).to.be.equal('second_first'); + }); + }); }); From d3669143ecb33655d7a7b715b7a86199a76817e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 21 Feb 2025 09:32:27 +0100 Subject: [PATCH 10/57] dynamic filter depending on situation --- .../property-value-preset-builder.controller.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts index 961425deba45..3e5456365801 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts @@ -3,6 +3,7 @@ import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import { createExtensionApi } from '@umbraco-cms/backoffice/extension-api'; import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import type { + ManifestPropertyValuePreset, UmbPropertyTypePresetModel, UmbPropertyTypePresetWithSchemaAliasModel, UmbPropertyValuePresetApi, @@ -36,17 +37,24 @@ export class UmbPropertyValuePresetBuilderController extends UmbControllerBase { .propertyEditorSchemaAlias; const editorUiAlias = propertyType.propertyEditorUiAlias; + if (!editorUiAlias) { + throw new Error(`propertyEditorUiAlias was not defined in ${propertyType}`); + } const alias = propertyType.alias; if (!alias) { throw new Error(`alias not defined in ${propertyType}`); } + let filter: (x: ManifestPropertyValuePreset) => boolean; + if (editorAlias && editorUiAlias) { + filter = (x) => x.forPropertyEditorSchemaAlias === editorAlias || x.forPropertyEditorUiAlias === editorUiAlias; + } else { + filter = (x) => x.forPropertyEditorUiAlias === editorUiAlias; + } + // Find a preset for this editor alias: - const manifests = umbExtensionsRegistry.getByTypeAndFilter( - 'propertyValuePreset', - (x) => x.forPropertyEditorSchemaAlias === editorAlias || x.forPropertyEditorUiAlias === editorUiAlias, - ); + const manifests = umbExtensionsRegistry.getByTypeAndFilter('propertyValuePreset', filter); const apis = (await Promise.all(manifests.map((x) => createExtensionApi(this, x)))).filter( (x) => x !== undefined, From 347bd916521d40055ff9ba27d20fc3fd0c660f57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 21 Feb 2025 09:53:49 +0100 Subject: [PATCH 11/57] async test --- ...ty-value-preset-builder.controller.test.ts | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts index 174601216a77..e53a3a3da512 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts @@ -33,6 +33,15 @@ export class TestPropertyValuePresetSecondApi implements UmbPropertyValuePresetA destroy(): void {} } +export class TestPropertyValuePresetAsyncApi implements UmbPropertyValuePresetApi { + async processValue(value: string, config: UmbPropertyEditorConfig) { + await new Promise((resolve) => setTimeout(resolve, 10)); + return value ? value + '_async' : 'async'; + } + + destroy(): void {} +} + describe('UmbPropertyValuePresetBuilderController', () => { describe('Create with a single preset', () => { beforeEach(async () => { @@ -162,4 +171,62 @@ describe('UmbPropertyValuePresetBuilderController', () => { expect(result[0]?.value).to.be.equal('second_first'); }); }); + + describe('weigthed async presets keeps the right order', () => { + beforeEach(async () => { + const manifestFirstPreset: ManifestPropertyValuePreset = { + type: 'propertyValuePreset', + name: 'test-preset-1', + alias: 'Umb.Test.Preset.1', + weight: 3, + api: TestPropertyValuePresetFirstApi, + forPropertyEditorUiAlias: 'test-editor', + }; + + const manifestAsyncPreset: ManifestPropertyValuePreset = { + type: 'propertyValuePreset', + name: 'test-preset-3', + alias: 'Umb.Test.Preset.3', + weight: 2, + api: TestPropertyValuePresetAsyncApi, + forPropertyEditorUiAlias: 'test-editor', + }; + + const manifestSecondPreset: ManifestPropertyValuePreset = { + type: 'propertyValuePreset', + name: 'test-preset-2', + alias: 'Umb.Test.Preset.2', + weight: 1, + api: TestPropertyValuePresetSecondApi, + forPropertyEditorUiAlias: 'test-editor', + }; + + umbExtensionsRegistry.register(manifestSecondPreset); + umbExtensionsRegistry.register(manifestAsyncPreset); + umbExtensionsRegistry.register(manifestFirstPreset); + }); + afterEach(async () => { + umbExtensionsRegistry.unregister('Umb.Test.Preset.1'); + umbExtensionsRegistry.unregister('Umb.Test.Preset.2'); + umbExtensionsRegistry.unregister('Umb.Test.Preset.3'); + }); + + it('creates a combined value', async () => { + const ctrlHost = new UmbTestControllerHostElement(); + const ctrl = new UmbPropertyValuePresetBuilderController(ctrlHost); + + const propertyTypes: Array = [ + { + alias: 'test', + propertyEditorUiAlias: 'test-editor', + config: [], + }, + ]; + + const result = await ctrl.create(propertyTypes); + + expect(result.length).to.be.equal(1); + expect(result[0]?.value).to.be.equal('first_async_second'); + }); + }); }); From 136c679e1df9b9af1c6ede729aaac0cdca8aba13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 21 Feb 2025 09:59:01 +0100 Subject: [PATCH 12/57] combine ui and schema test --- ...ty-value-preset-builder.controller.test.ts | 111 ++++++++++++++++-- 1 file changed, 98 insertions(+), 13 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts index e53a3a3da512..dadce378f8f7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts @@ -50,7 +50,7 @@ describe('UmbPropertyValuePresetBuilderController', () => { name: 'test-preset-1', alias: 'Umb.Test.Preset.1', api: TestPropertyValuePresetFirstApi, - forPropertyEditorUiAlias: 'test-editor', + forPropertyEditorUiAlias: 'test-editor-ui', }; umbExtensionsRegistry.register(manifestFirstPreset); @@ -66,7 +66,7 @@ describe('UmbPropertyValuePresetBuilderController', () => { const propertyTypes: Array = [ { alias: 'test', - propertyEditorUiAlias: 'test-editor', + propertyEditorUiAlias: 'test-editor-ui', config: [], }, ]; @@ -86,7 +86,7 @@ describe('UmbPropertyValuePresetBuilderController', () => { alias: 'Umb.Test.Preset.1', weight: 20, api: TestPropertyValuePresetFirstApi, - forPropertyEditorUiAlias: 'test-editor', + forPropertyEditorUiAlias: 'test-editor-ui', }; const manifestSecondPreset: ManifestPropertyValuePreset = { @@ -95,7 +95,7 @@ describe('UmbPropertyValuePresetBuilderController', () => { alias: 'Umb.Test.Preset.2', weight: 10, api: TestPropertyValuePresetSecondApi, - forPropertyEditorUiAlias: 'test-editor', + forPropertyEditorUiAlias: 'test-editor-ui', }; umbExtensionsRegistry.register(manifestSecondPreset); @@ -113,7 +113,7 @@ describe('UmbPropertyValuePresetBuilderController', () => { const propertyTypes: Array = [ { alias: 'test', - propertyEditorUiAlias: 'test-editor', + propertyEditorUiAlias: 'test-editor-ui', config: [], }, ]; @@ -133,7 +133,7 @@ describe('UmbPropertyValuePresetBuilderController', () => { alias: 'Umb.Test.Preset.1', weight: 20, api: TestPropertyValuePresetFirstApi, - forPropertyEditorUiAlias: 'test-editor', + forPropertyEditorUiAlias: 'test-editor-ui', }; const manifestSecondPreset: ManifestPropertyValuePreset = { @@ -142,7 +142,7 @@ describe('UmbPropertyValuePresetBuilderController', () => { alias: 'Umb.Test.Preset.2', weight: 3000, api: TestPropertyValuePresetSecondApi, - forPropertyEditorUiAlias: 'test-editor', + forPropertyEditorUiAlias: 'test-editor-ui', }; umbExtensionsRegistry.register(manifestSecondPreset); @@ -160,7 +160,7 @@ describe('UmbPropertyValuePresetBuilderController', () => { const propertyTypes: Array = [ { alias: 'test', - propertyEditorUiAlias: 'test-editor', + propertyEditorUiAlias: 'test-editor-ui', config: [], }, ]; @@ -180,7 +180,7 @@ describe('UmbPropertyValuePresetBuilderController', () => { alias: 'Umb.Test.Preset.1', weight: 3, api: TestPropertyValuePresetFirstApi, - forPropertyEditorUiAlias: 'test-editor', + forPropertyEditorUiAlias: 'test-editor-ui', }; const manifestAsyncPreset: ManifestPropertyValuePreset = { @@ -189,7 +189,7 @@ describe('UmbPropertyValuePresetBuilderController', () => { alias: 'Umb.Test.Preset.3', weight: 2, api: TestPropertyValuePresetAsyncApi, - forPropertyEditorUiAlias: 'test-editor', + forPropertyEditorUiAlias: 'test-editor-ui', }; const manifestSecondPreset: ManifestPropertyValuePreset = { @@ -198,7 +198,7 @@ describe('UmbPropertyValuePresetBuilderController', () => { alias: 'Umb.Test.Preset.2', weight: 1, api: TestPropertyValuePresetSecondApi, - forPropertyEditorUiAlias: 'test-editor', + forPropertyEditorUiAlias: 'test-editor-ui', }; umbExtensionsRegistry.register(manifestSecondPreset); @@ -218,15 +218,100 @@ describe('UmbPropertyValuePresetBuilderController', () => { const propertyTypes: Array = [ { alias: 'test', - propertyEditorUiAlias: 'test-editor', + propertyEditorUiAlias: 'test-editor-ui', + config: [], + }, + { + alias: 'test2', + propertyEditorUiAlias: 'test-editor-ui', config: [], }, ]; const result = await ctrl.create(propertyTypes); - expect(result.length).to.be.equal(1); + expect(result.length).to.be.equal(2); + expect(result[0]?.alias).to.be.equal('test'); expect(result[0]?.value).to.be.equal('first_async_second'); + expect(result[1]?.alias).to.be.equal('test2'); + expect(result[1]?.value).to.be.equal('first_async_second'); + }); + }); + + describe('combine use of UI and Schema Presets', () => { + beforeEach(async () => { + const manifestFirstPreset: ManifestPropertyValuePreset = { + type: 'propertyValuePreset', + name: 'test-preset-1', + alias: 'Umb.Test.Preset.1', + weight: 3, + api: TestPropertyValuePresetFirstApi, + forPropertyEditorSchemaAlias: 'test-editor-schema', + }; + + const manifestAsyncPreset: ManifestPropertyValuePreset = { + type: 'propertyValuePreset', + name: 'test-preset-3', + alias: 'Umb.Test.Preset.3', + weight: 2, + api: TestPropertyValuePresetAsyncApi, + forPropertyEditorUiAlias: 'test-editor-ui', + forPropertyEditorSchemaAlias: 'test-editor-schema', + }; + + const manifestSecondPreset: ManifestPropertyValuePreset = { + type: 'propertyValuePreset', + name: 'test-preset-2', + alias: 'Umb.Test.Preset.2', + weight: 1, + api: TestPropertyValuePresetSecondApi, + forPropertyEditorUiAlias: 'test-editor-ui', + }; + + umbExtensionsRegistry.register(manifestSecondPreset); + umbExtensionsRegistry.register(manifestAsyncPreset); + umbExtensionsRegistry.register(manifestFirstPreset); + }); + afterEach(async () => { + umbExtensionsRegistry.unregister('Umb.Test.Preset.1'); + umbExtensionsRegistry.unregister('Umb.Test.Preset.2'); + umbExtensionsRegistry.unregister('Umb.Test.Preset.3'); + }); + + it('creates only presets that fits the configuration', async () => { + const ctrlHost = new UmbTestControllerHostElement(); + const ctrl = new UmbPropertyValuePresetBuilderController(ctrlHost); + + const propertyTypes: Array = [ + { + alias: 'test', + propertyEditorUiAlias: 'test-editor-ui', + config: [], + }, + { + alias: 'test2', + propertyEditorUiAlias: 'test-editor-ui', + propertyEditorSchemaAlias: 'test-editor-schema', + config: [], + }, + { + alias: 'test3', + propertyEditorUiAlias: 'some-other-ui', + propertyEditorSchemaAlias: 'test-editor-schema', + config: [], + }, + ]; + + const result = await ctrl.create(propertyTypes); + + // Test that only the right presets are used: + expect(result.length).to.be.equal(3); + expect(result[0]?.alias).to.be.equal('test'); + expect(result[0]?.value).to.be.equal('async_second'); + expect(result[1]?.alias).to.be.equal('test2'); + expect(result[1]?.value).to.be.equal('first_async_second'); + expect(result[2]?.alias).to.be.equal('test3'); + expect(result[2]?.value).to.be.equal('first_async'); }); }); }); From 065c93705f9f1271343b38b2ab6e37c3269d61b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 21 Feb 2025 10:07:53 +0100 Subject: [PATCH 13/57] make block creation async --- .../block/block-grid/context/block-grid-entries.context.ts | 2 +- .../block/block-grid/context/block-grid-manager.context.ts | 4 ++-- .../block/block-list/context/block-list-entries.context.ts | 2 +- .../block/block-list/context/block-list-manager.context.ts | 4 ++-- .../block/block-rte/context/block-rte-entries.context.ts | 2 +- .../block/block-rte/context/block-rte-manager.context.ts | 4 ++-- .../src/packages/block/block/context/block-entry.context.ts | 4 ++-- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entries.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entries.context.ts index 3c1d1fee5fb4..7256b02f52a1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entries.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entries.context.ts @@ -436,7 +436,7 @@ export class UmbBlockGridEntriesContext originData?: UmbBlockGridWorkspaceOriginData, ) { await this._retrieveManager; - return this._manager?.create(contentElementTypeKey, partialLayoutEntry, originData); + return await this._manager?.create(contentElementTypeKey, partialLayoutEntry, originData); } // insert Block? diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-manager.context.ts index ed58c645e75f..32885a0695ff 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-manager.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-manager.context.ts @@ -92,14 +92,14 @@ export class UmbBlockGridManagerContext< }); } - create( + async create( contentElementTypeKey: string, partialLayoutEntry?: Omit, // This property is used by some implementations, but not used in this. // eslint-disable-next-line @typescript-eslint/no-unused-vars originData?: UmbBlockGridWorkspaceOriginData, ) { - return super._createBlockData(contentElementTypeKey, partialLayoutEntry); + return await super._createBlockData(contentElementTypeKey, partialLayoutEntry); } /** diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entries.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entries.context.ts index 9cc4369ecd5d..88814b0dc49e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entries.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entries.context.ts @@ -168,7 +168,7 @@ export class UmbBlockListEntriesContext extends UmbBlockEntriesContext< originData?: UmbBlockListWorkspaceOriginData, ) { await this._retrieveManager; - return this._manager?.create(contentElementTypeKey, partialLayoutEntry, originData); + return await this._manager?.create(contentElementTypeKey, partialLayoutEntry, originData); } // insert Block? diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-manager.context.ts index ccc98f903ac7..24622e8e859c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-manager.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-manager.context.ts @@ -21,14 +21,14 @@ export class UmbBlockListManagerContext< return this.#inlineEditingMode.getValue(); } - create( + async create( contentElementTypeKey: string, partialLayoutEntry?: Omit, // This property is used by some implementations, but not used in this. Do not remove. [NL] // eslint-disable-next-line @typescript-eslint/no-unused-vars _originData?: UmbBlockListWorkspaceOriginData, ) { - return super._createBlockData(contentElementTypeKey, partialLayoutEntry); + return await super._createBlockData(contentElementTypeKey, partialLayoutEntry); } insert( diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-entries.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-entries.context.ts index 492ab213fa65..8f78012ac4dc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-entries.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-entries.context.ts @@ -111,7 +111,7 @@ export class UmbBlockRteEntriesContext extends UmbBlockEntriesContext< originData?: UmbBlockRteWorkspaceOriginData, ) { await this._retrieveManager; - return this._manager?.create(contentElementTypeKey, partialLayoutEntry, originData); + return await this._manager?.create(contentElementTypeKey, partialLayoutEntry, originData); } // insert Block? diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-manager.context.ts index c56cfeebd5f1..177621a2f742 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-manager.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-manager.context.ts @@ -18,14 +18,14 @@ export class UmbBlockRteManagerContext< this._layouts.remove(contentKeys); } - create( + async create( contentElementTypeKey: string, partialLayoutEntry?: Omit, // This property is used by some implementations, but not used in this, do not remove. [NL] // eslint-disable-next-line @typescript-eslint/no-unused-vars _originData?: UmbBlockRteWorkspaceOriginData, ) { - const data = super._createBlockData(contentElementTypeKey, partialLayoutEntry); + const data = await super._createBlockData(contentElementTypeKey, partialLayoutEntry); // Find block type. const blockType = this.getBlockTypes().find((x) => x.contentElementTypeKey === contentElementTypeKey); diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entry.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entry.context.ts index 7fd3f5248933..7bea42e67b3e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entry.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entry.context.ts @@ -398,11 +398,11 @@ export abstract class UmbBlockEntryContext< this.observe( observeMultiple([this.settingsKey, this.blockType]), - ([settingsKey, blockType]) => { + async ([settingsKey, blockType]) => { if (!this.#contentKey || settingsKey === undefined || !blockType) return; if (settingsKey == null && blockType.settingsElementTypeKey) { // We have a settings ElementType in config but not in data, so lets create the scaffold for that: [NL] - const settingsData = this._manager!.createBlockSettingsData(blockType.contentElementTypeKey); // Yes its on purpose we use the contentElementTypeKey here, as this is our identifier for a BlockType. [NL] + const settingsData = await this._manager!.createBlockSettingsData(blockType.contentElementTypeKey); // Yes its on purpose we use the contentElementTypeKey here, as this is our identifier for a BlockType. [NL] this._manager?.setOneSettings(settingsData); this._layout.update({ settingsKey: settingsData.key } as Partial); } else if (settingsKey && blockType.settingsElementTypeKey === undefined) { From 19026fbd26b349770bb821b0383ec3a504312b01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 21 Feb 2025 10:10:43 +0100 Subject: [PATCH 14/57] commit todos --- .../block/block/context/block-manager.context.ts | 14 +++++++++++--- .../entity-detail/entity-detail-workspace-base.ts | 1 + 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts index a679c1cd815c..1c1d2a79c089 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts @@ -321,9 +321,9 @@ export abstract class UmbBlockManagerContext< contentElementTypeKey: string, partialLayoutEntry?: Omit, originData?: BlockOriginDataType, - ): UmbBlockDataObjectModel | undefined; + ): Promise | undefined>; - public createBlockSettingsData(contentElementTypeKey: string) { + public async createBlockSettingsData(contentElementTypeKey: string) { const blockType = this.#blockTypes.value.find((x) => x.contentElementTypeKey === contentElementTypeKey); if (!blockType) { throw new Error(`Cannot create block settings, missing block type for ${contentElementTypeKey}`); @@ -332,6 +332,8 @@ export abstract class UmbBlockManagerContext< throw new Error(`Cannot create block settings, missing settings element type for ${contentElementTypeKey}`); } + // TODO: Handle presets here [NL] + return { key: UmbId.new(), contentTypeKey: blockType.settingsElementTypeKey, @@ -340,6 +342,9 @@ export abstract class UmbBlockManagerContext< } protected _createBlockElementData(key: string, elementTypeKey: string) { + // + // TODO: Handle presets here [NL] + return { key: key, contentTypeKey: elementTypeKey, @@ -347,7 +352,10 @@ export abstract class UmbBlockManagerContext< }; } - protected _createBlockData(contentElementTypeKey: string, partialLayoutEntry?: Omit) { + protected async _createBlockData( + contentElementTypeKey: string, + partialLayoutEntry?: Omit, + ) { // Find block type. const blockType = this.#blockTypes.value.find((x) => x.contentElementTypeKey === contentElementTypeKey); if (!blockType) { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts index 88321ebd6f20..3b2e0d805ddd 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts @@ -231,6 +231,7 @@ export abstract class UmbEntityDetailWorkspaceContextBase< await this.#init; this.setParent(args.parent); + // TODO: Handle presets here [NL] const request = this._detailRepository!.createScaffold(args.preset); this._getDataPromise = request; let { data } = await request; From 888e19e98c4713e3dbe114a65812b5a960bc8ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 21 Feb 2025 11:38:57 +0100 Subject: [PATCH 15/57] proper deprecation --- .../context/block-grid-entries.context.ts | 2 +- .../context/block-grid-manager.context.ts | 17 +++++++++++++++-- .../context/block-list-entries.context.ts | 2 +- .../context/block-list-manager.context.ts | 17 +++++++++++++++-- .../context/block-rte-entries.context.ts | 2 +- .../context/block-rte-manager.context.ts | 17 +++++++++++++++-- .../block/context/block-manager.context.ts | 12 ++++++++++++ 7 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entries.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entries.context.ts index 7256b02f52a1..bb1fe4cc3702 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entries.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entries.context.ts @@ -436,7 +436,7 @@ export class UmbBlockGridEntriesContext originData?: UmbBlockGridWorkspaceOriginData, ) { await this._retrieveManager; - return await this._manager?.create(contentElementTypeKey, partialLayoutEntry, originData); + return await this._manager?.createWithPresets(contentElementTypeKey, partialLayoutEntry, originData); } // insert Block? diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-manager.context.ts index 32885a0695ff..d32b1c185c68 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-manager.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-manager.context.ts @@ -10,7 +10,7 @@ import { import { transformServerPathToClientPath } from '@umbraco-cms/backoffice/utils'; import { UmbBlockManagerContext } from '@umbraco-cms/backoffice/block'; import { UMB_APP_CONTEXT } from '@umbraco-cms/backoffice/app'; -import type { UmbBlockDataModel } from '@umbraco-cms/backoffice/block'; +import type { UmbBlockDataModel, UmbBlockDataObjectModel } from '@umbraco-cms/backoffice/block'; import type { UmbBlockTypeGroup } from '@umbraco-cms/backoffice/block-type'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbNumberRangeValueType } from '@umbraco-cms/backoffice/models'; @@ -91,8 +91,21 @@ export class UmbBlockGridManagerContext< this.#serverUrl = appContext.getServerUrl(); }); } + /** + * @deprecated Use createWithPresets instead. Will be removed in v.17. + */ + create( + contentElementTypeKey: string, + partialLayoutEntry?: Omit, + // This property is used by some implementations, but not used in this. Do not remove. [NL] + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _originData?: UmbBlockGridWorkspaceOriginData, + ) { + throw new Error('Method deparecated use createWithPresets'); + return {} as UmbBlockDataObjectModel; + } - async create( + async createWithPresets( contentElementTypeKey: string, partialLayoutEntry?: Omit, // This property is used by some implementations, but not used in this. diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entries.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entries.context.ts index 88814b0dc49e..e625f4d29899 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entries.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entries.context.ts @@ -168,7 +168,7 @@ export class UmbBlockListEntriesContext extends UmbBlockEntriesContext< originData?: UmbBlockListWorkspaceOriginData, ) { await this._retrieveManager; - return await this._manager?.create(contentElementTypeKey, partialLayoutEntry, originData); + return await this._manager?.createWithPresets(contentElementTypeKey, partialLayoutEntry, originData); } // insert Block? diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-manager.context.ts index 24622e8e859c..9b30b9bf1180 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-manager.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-manager.context.ts @@ -2,7 +2,7 @@ import type { UmbBlockListLayoutModel, UmbBlockListTypeModel } from '../types.js import type { UmbBlockListWorkspaceOriginData } from '../index.js'; import type { UmbBlockDataModel } from '../../block/types.js'; import { UmbBooleanState } from '@umbraco-cms/backoffice/observable-api'; -import { UmbBlockManagerContext } from '@umbraco-cms/backoffice/block'; +import { UmbBlockManagerContext, type UmbBlockDataObjectModel } from '@umbraco-cms/backoffice/block'; /** * A implementation of the Block Manager specifically for the Block List Editor. @@ -21,7 +21,20 @@ export class UmbBlockListManagerContext< return this.#inlineEditingMode.getValue(); } - async create( + /** + * @deprecated Use createWithPresets instead. Will be removed in v.17. + */ + create( + contentElementTypeKey: string, + partialLayoutEntry?: Omit, + // This property is used by some implementations, but not used in this. Do not remove. [NL] + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _originData?: UmbBlockListWorkspaceOriginData, + ) { + throw new Error('Method deparecated use createWithPresets'); + return {} as UmbBlockDataObjectModel; + } + async createWithPresets( contentElementTypeKey: string, partialLayoutEntry?: Omit, // This property is used by some implementations, but not used in this. Do not remove. [NL] diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-entries.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-entries.context.ts index 8f78012ac4dc..1724dd6b1ebe 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-entries.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-entries.context.ts @@ -111,7 +111,7 @@ export class UmbBlockRteEntriesContext extends UmbBlockEntriesContext< originData?: UmbBlockRteWorkspaceOriginData, ) { await this._retrieveManager; - return await this._manager?.create(contentElementTypeKey, partialLayoutEntry, originData); + return await this._manager?.createWithPresets(contentElementTypeKey, partialLayoutEntry, originData); } // insert Block? diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-manager.context.ts index 177621a2f742..504e109fa34f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-manager.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-manager.context.ts @@ -1,7 +1,7 @@ import type { UmbBlockRteWorkspaceOriginData } from '../workspace/block-rte-workspace.modal-token.js'; import type { UmbBlockRteLayoutModel, UmbBlockRteTypeModel } from '../types.js'; import type { UmbBlockDataModel } from '../../block/types.js'; -import { UmbBlockManagerContext } from '@umbraco-cms/backoffice/block'; +import { UmbBlockManagerContext, type UmbBlockDataObjectModel } from '@umbraco-cms/backoffice/block'; import '../components/block-rte-entry/index.js'; @@ -18,7 +18,20 @@ export class UmbBlockRteManagerContext< this._layouts.remove(contentKeys); } - async create( + /** + * @deprecated Use createWithPresets instead. Will be removed in v.17. + */ + create( + contentElementTypeKey: string, + partialLayoutEntry?: Omit, + // This property is used by some implementations, but not used in this. Do not remove. [NL] + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _originData?: UmbBlockRteWorkspaceOriginData, + ) { + throw new Error('Method deparecated use createWithPresets'); + return {} as UmbBlockDataObjectModel; + } + async createWithPresets( contentElementTypeKey: string, partialLayoutEntry?: Omit, // This property is used by some implementations, but not used in this, do not remove. [NL] diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts index 1c1d2a79c089..8817dd2a9345 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts @@ -317,10 +317,22 @@ export abstract class UmbBlockManagerContext< ); } + /** + * @deprecated Use `createWithPresets` instead. Which is Async. Will be removed in v.17 + * @param contentElementTypeKey + * @param partialLayoutEntry + * @param originData + */ abstract create( contentElementTypeKey: string, partialLayoutEntry?: Omit, originData?: BlockOriginDataType, + ): UmbBlockDataObjectModel | undefined; + + abstract createWithPresets( + contentElementTypeKey: string, + partialLayoutEntry?: Omit, + originData?: BlockOriginDataType, ): Promise | undefined>; public async createBlockSettingsData(contentElementTypeKey: string) { From 841f25610039e6d8a657282ab8b80877d7e07e63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 21 Feb 2025 13:38:46 +0100 Subject: [PATCH 16/57] value can be undefined --- .../src/packages/core/property/index.ts | 3 ++- .../packages/core/property/property-value-preset/index.ts | 3 +++ .../property-value-preset-builder.controller.test.ts | 6 +++--- .../packages/core/property/property-value-preset/types.ts | 2 +- .../src/packages/core/property/types.ts | 3 ++- 5 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/index.ts index 3d179b636c80..e5d236cee9be 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/index.ts @@ -1,5 +1,6 @@ export * from './components/index.js'; export * from './conditions/index.js'; -export * from './property-value-cloner/property-value-clone.controller.js'; export * from './property-dataset/index.js'; +export * from './property-value-cloner/property-value-clone.controller.js'; +export * from './property-value-preset/index.js'; export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/index.ts new file mode 100644 index 000000000000..071ddb2bfd96 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/index.ts @@ -0,0 +1,3 @@ +export * from './property-value-preset.extension.js'; +export * from './property-value-preset-builder.controller.js'; +export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts index dadce378f8f7..6d7ec7c6ed62 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts @@ -18,7 +18,7 @@ export class UmbTestControllerHostElement extends UmbControllerHostElementMixin( // Test with async APIs, espcially where the first one is slower than the last one. export class TestPropertyValuePresetFirstApi implements UmbPropertyValuePresetApi { - async processValue(value: string, config: UmbPropertyEditorConfig) { + async processValue(value: undefined | string, config: UmbPropertyEditorConfig) { return value ? value + '_first' : 'first'; } @@ -26,7 +26,7 @@ export class TestPropertyValuePresetFirstApi implements UmbPropertyValuePresetAp } export class TestPropertyValuePresetSecondApi implements UmbPropertyValuePresetApi { - async processValue(value: string, config: UmbPropertyEditorConfig) { + async processValue(value: undefined | string, config: UmbPropertyEditorConfig) { return value ? value + '_second' : 'second'; } @@ -34,7 +34,7 @@ export class TestPropertyValuePresetSecondApi implements UmbPropertyValuePresetA } export class TestPropertyValuePresetAsyncApi implements UmbPropertyValuePresetApi { - async processValue(value: string, config: UmbPropertyEditorConfig) { + async processValue(value: undefined | string, config: UmbPropertyEditorConfig) { await new Promise((resolve) => setTimeout(resolve, 10)); return value ? value + '_async' : 'async'; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts index cea326faa404..7fa62f9e7867 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts @@ -13,7 +13,7 @@ export interface UmbPropertyValuePresetApi< export type UmbPropertyValuePresetApiValuesProcessor< ValueType = unknown, ConfigType extends UmbPropertyEditorConfig = UmbPropertyEditorConfig, -> = (value: ValueType, config: ConfigType) => PromiseLike; +> = (value: undefined | ValueType, config: ConfigType) => PromiseLike; export interface UmbPropertyTypePresetModel { alias: string; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/types.ts index d474dcd917e6..28efb1b6df70 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/types.ts @@ -1,5 +1,6 @@ export type * from './conditions/types.js'; +export type * from './extensions/types.js'; export type * from './property-value-cloner/types.js'; +export type * from './property-value-preset/types.js'; export type * from './property-value-resolver/types.js'; export type * from './types/index.js'; -export type * from './extensions/types.js'; From 542b684cb3da636d1b79227b79fde4e8c00103b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 21 Feb 2025 13:39:05 +0100 Subject: [PATCH 17/57] toggle preset api --- .../src/packages/property-editors/index.ts | 1 + .../property-editors/toggle/manifests.ts | 25 +++++++++++-------- .../property-editor-ui-toggle.element.ts | 3 ++- .../toggle/property-value-preset.TrueFalse.ts | 16 ++++++++++++ .../packages/property-editors/toggle/types.ts | 1 + .../src/packages/property-editors/types.ts | 1 + 6 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/property-editors/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/types.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/property-editors/types.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/index.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/index.ts new file mode 100644 index 000000000000..06c33f562f4e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/index.ts @@ -0,0 +1 @@ +export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/manifests.ts index ee3c9d5a5afe..f71eaa878007 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/manifests.ts @@ -1,6 +1,13 @@ import { manifest as trueFalseSchemaManifest } from './Umbraco.TrueFalse.js'; export const manifests: Array = [ + { + type: 'propertyValuePreset', + forPropertyEditorSchemaAlias: 'Umbraco.TrueFalse', + alias: 'Umb.PropertyValuePreset.TrueFalse', + name: 'Property Editor Schema True/False Preset for Initial State', + api: () => import('./property-value-preset.TrueFalse.js'), + }, { type: 'propertyEditorUi', alias: 'Umb.PropertyEditorUi.Toggle', @@ -19,24 +26,22 @@ export const manifests: Array = [ label: 'Preset value', propertyEditorUiAlias: 'Umb.PropertyEditorUi.Toggle', config: [ - { - alias: "ariaLabel", - value: 'toggle for the initial state of this data type' - } - ] + alias: 'ariaLabel', + value: 'toggle for the initial state of this data type', + }, + ], }, { alias: 'showLabels', label: 'Show on/off labels', propertyEditorUiAlias: 'Umb.PropertyEditorUi.Toggle', config: [ - { - alias: "ariaLabel", - value: 'toggle for weather if label should be displayed' - } - ] + alias: 'ariaLabel', + value: 'toggle for weather if label should be displayed', + }, + ], }, { alias: 'labelOn', diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts index 4160cfc53b09..1c8377bb3a77 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts @@ -7,10 +7,11 @@ import type { UmbPropertyEditorUiElement, } from '@umbraco-cms/backoffice/property-editor'; import { UMB_VALIDATION_FALSE_LOCALIZATION_KEY, UmbFormControlMixin } from '@umbraco-cms/backoffice/validation'; +import type { UmbPropertyEditorUIToggleValue } from './types'; @customElement('umb-property-editor-ui-toggle') export class UmbPropertyEditorUIToggleElement - extends UmbFormControlMixin(UmbLitElement) + extends UmbFormControlMixin(UmbLitElement) implements UmbPropertyEditorUiElement { @property({ type: String }) diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts new file mode 100644 index 000000000000..dbd0e97734c5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts @@ -0,0 +1,16 @@ +import type { UmbPropertyValuePresetApi } from '@umbraco-cms/backoffice/property'; +import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; +import type { UmbPropertyEditorUIToggleValue } from './types.js'; + +export class UmbPropertyValuePresetTrueFalseApi + implements UmbPropertyValuePresetApi +{ + async processValue(value: undefined | UmbPropertyEditorUIToggleValue, config: UmbPropertyEditorConfig) { + const initialState = (config.find((x) => x.alias === 'initialState')?.value as boolean | undefined) ?? false; + return value !== undefined ? value : initialState; + } + + destroy(): void {} +} + +export { UmbPropertyValuePresetTrueFalseApi as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/types.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/types.ts new file mode 100644 index 000000000000..69a021a31068 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/types.ts @@ -0,0 +1 @@ +export type UmbPropertyEditorUIToggleValue = boolean; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/types.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/types.ts new file mode 100644 index 000000000000..7333c40dc669 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/types.ts @@ -0,0 +1 @@ +export type * from './toggle/types.js'; From 8d9650a66674f88e18d24d7e8e1152a4c1126709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 21 Feb 2025 13:55:14 +0100 Subject: [PATCH 18/57] ability to observe and get all languages --- .../global-contexts/app-language.context.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/language/global-contexts/app-language.context.ts b/src/Umbraco.Web.UI.Client/src/packages/language/global-contexts/app-language.context.ts index 2f0a6e354dc9..36b12682c9da 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/language/global-contexts/app-language.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/language/global-contexts/app-language.context.ts @@ -13,12 +13,10 @@ import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user'; // TODO: Implement default language end-point, in progress at backend team, so we can avoid getting all languages. export class UmbAppLanguageContext extends UmbContextBase implements UmbApi { #languages = new UmbArrayState([], (x) => x.unique); - - #appLanguage = new UmbObjectState(undefined); - public readonly appLanguage = this.#appLanguage.asObservable(); - public readonly appLanguageCulture = this.#appLanguage.asObservablePart((x) => x?.unique); - - public readonly appLanguageReadOnlyState = new UmbReadOnlyStateManager(this); + public readonly languages = this.#languages.asObservable(); + async getLanguages() { + return await this.observe(this.languages).asPromise(); + } public readonly appDefaultLanguage = this.#languages.asObservablePart((languages) => languages.find((language) => language.isDefault), @@ -26,6 +24,12 @@ export class UmbAppLanguageContext extends UmbContextBase public readonly moreThanOneLanguage = this.#languages.asObservablePart((x) => x.length > 1); + #appLanguage = new UmbObjectState(undefined); + public readonly appLanguage = this.#appLanguage.asObservable(); + public readonly appLanguageCulture = this.#appLanguage.asObservablePart((x) => x?.unique); + + public readonly appLanguageReadOnlyState = new UmbReadOnlyStateManager(this); + #languageCollectionRepository = new UmbLanguageCollectionRepository(this); #currentUserAllowedLanguages: Array = []; #currentUserHasAccessToAllLanguages = false; From 8d5625673bdc4cb0773175b32faa3bb9eda858e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 21 Feb 2025 13:55:26 +0100 Subject: [PATCH 19/57] default config field --- .../property-editors/toggle/property-value-preset.TrueFalse.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts index dbd0e97734c5..1dd35919f4ce 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts @@ -6,7 +6,7 @@ export class UmbPropertyValuePresetTrueFalseApi implements UmbPropertyValuePresetApi { async processValue(value: undefined | UmbPropertyEditorUIToggleValue, config: UmbPropertyEditorConfig) { - const initialState = (config.find((x) => x.alias === 'initialState')?.value as boolean | undefined) ?? false; + const initialState = (config.find((x) => x.alias === 'default')?.value as boolean | undefined) ?? false; return value !== undefined ? value : initialState; } From 14bc83089be40c09c4c2afdb9442a977d79fc83a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 21 Feb 2025 13:57:32 +0100 Subject: [PATCH 20/57] change only to expose all Cultures --- .../language/global-contexts/app-language.context.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/language/global-contexts/app-language.context.ts b/src/Umbraco.Web.UI.Client/src/packages/language/global-contexts/app-language.context.ts index 36b12682c9da..acf0b9f19109 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/language/global-contexts/app-language.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/language/global-contexts/app-language.context.ts @@ -14,8 +14,9 @@ import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user'; export class UmbAppLanguageContext extends UmbContextBase implements UmbApi { #languages = new UmbArrayState([], (x) => x.unique); public readonly languages = this.#languages.asObservable(); - async getLanguages() { - return await this.observe(this.languages).asPromise(); + public readonly cultures = this.#languages.asObservablePart((x) => x.map((y) => y.unique)); + async getCultures() { + return (await this.observe(this.languages).asPromise()).map((x) => x.unique); } public readonly appDefaultLanguage = this.#languages.asObservablePart((languages) => From d770877f17beb82c03c9d397a1c2e8343f0bfb81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Sat, 22 Feb 2025 11:01:32 +0100 Subject: [PATCH 21/57] Variant Presets --- .../property/property-value-preset/index.ts | 1 + ...roperty-value-preset-builder.controller.ts | 72 ++++--- ...-preset-variant-builder.controller.test.ts | 183 ++++++++++++++++++ ...value-preset-variant-builder.controller.ts | 74 +++++++ .../property/property-value-preset/types.ts | 18 +- 5 files changed, 320 insertions(+), 28 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.test.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/index.ts index 071ddb2bfd96..9fc6259f578b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/index.ts @@ -1,3 +1,4 @@ export * from './property-value-preset.extension.js'; export * from './property-value-preset-builder.controller.js'; +export * from './property-value-preset-variant-builder.controller.js'; export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts index 3e5456365801..883aa1aca9ad 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts @@ -7,32 +7,35 @@ import type { UmbPropertyTypePresetModel, UmbPropertyTypePresetWithSchemaAliasModel, UmbPropertyValuePresetApi, + UmbPropertyValuePresetApiCallArgs, } from './types.js'; -//type PropertyTypesType = UmbPropertyTypePresetModel | UmbPropertyTypePresetWithSchemaAliasModel; +const EMPTY_CALL_ARGS = Object.freeze({}); -export class UmbPropertyValuePresetBuilderController extends UmbControllerBase { +export class UmbPropertyValuePresetBuilderController< + ReturnType = UmbPropertyValueData | UmbPropertyValueDataPotentiallyWithEditorAlias, +> extends UmbControllerBase { /** * Clones the property data. - * @param {UmbPropertyValueDataPotentiallyWithEditorAlias} property - The property data. + * @param {UmbPropertyValueDataPotentiallyWithEditorAlias} propertyTypes - Data about the properties to make a preset for. * @returns {Promise} - A promise that resolves to the cloned property data. */ - async create< - GivenPropertyTypesType extends UmbPropertyTypePresetModel | UmbPropertyTypePresetWithSchemaAliasModel, - ReturnType = GivenPropertyTypesType extends UmbPropertyTypePresetWithSchemaAliasModel - ? UmbPropertyValueDataPotentiallyWithEditorAlias - : UmbPropertyValueData, - >(propertyTypes: Array): Promise> { - const result = await Promise.all(propertyTypes.map(this.#createPropertyPreset)); + async create( + propertyTypes: Array, + ): Promise> { + const result = await Promise.all(propertyTypes.map(this.#createPropertyPreset)); + + //Merge all the values into a single array: + const values = result.flatMap((x) => x); this.destroy(); - return result; + return values; } - #createPropertyPreset = async ( + #createPropertyPreset = async ( propertyType: UmbPropertyTypePresetModel | UmbPropertyTypePresetWithSchemaAliasModel, - ): Promise => { + ): Promise> => { const editorAlias: string | undefined = (propertyType as UmbPropertyTypePresetWithSchemaAliasModel) .propertyEditorSchemaAlias; @@ -41,11 +44,6 @@ export class UmbPropertyValuePresetBuilderController extends UmbControllerBase { throw new Error(`propertyEditorUiAlias was not defined in ${propertyType}`); } - const alias = propertyType.alias; - if (!alias) { - throw new Error(`alias not defined in ${propertyType}`); - } - let filter: (x: ManifestPropertyValuePreset) => boolean; if (editorAlias && editorUiAlias) { filter = (x) => x.forPropertyEditorSchemaAlias === editorAlias || x.forPropertyEditorUiAlias === editorUiAlias; @@ -60,28 +58,48 @@ export class UmbPropertyValuePresetBuilderController extends UmbControllerBase { (x) => x !== undefined, ) as Array; + const result = await this._generatePropertyValues(apis, propertyType); + + for (const api of apis) { + api.destroy(); + } + + return result; + }; + + protected async _generatePropertyValues( + apis: Array, + propertyType: UmbPropertyTypePresetModel | UmbPropertyTypePresetWithSchemaAliasModel, + ): Promise> { + return [await this._generatePropertyValue(apis, propertyType, EMPTY_CALL_ARGS)]; + } + + protected async _generatePropertyValue( + apis: Array, + propertyType: UmbPropertyTypePresetModel | UmbPropertyTypePresetWithSchemaAliasModel, + callArgs: UmbPropertyValuePresetApiCallArgs, + ): Promise { let value: unknown = undefined; // Important to use a inline for loop, to secure that each entry is processed(asynchronously) in order for (const api of apis) { if (!api.processValue) { - throw new Error( - `processValue method is not defined in one of the apis of these extensions: ${manifests.map((x) => x.alias).join(', ')}`, - ); + throw new Error(`'processValue()' method is not defined in the api: ${api.constructor.name}`); } - value = await api.processValue(value, propertyType.config); + + value = await api.processValue(value, propertyType.config, propertyType.typeArgs, callArgs); } - if (editorAlias) { + if ((propertyType as UmbPropertyTypePresetWithSchemaAliasModel).propertyEditorSchemaAlias) { return { - editorAlias, - alias, + editorAlias: (propertyType as UmbPropertyTypePresetWithSchemaAliasModel).propertyEditorSchemaAlias, + alias: propertyType.alias, value, } satisfies UmbPropertyValueDataPotentiallyWithEditorAlias as ReturnType; } else { return { - alias, + alias: propertyType.alias, value, } satisfies UmbPropertyValueData as ReturnType; } - }; + } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.test.ts new file mode 100644 index 000000000000..ddab1128e9e8 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.test.ts @@ -0,0 +1,183 @@ +import { expect } from '@open-wc/testing'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; +import { customElement } from '@umbraco-cms/backoffice/external/lit'; +import { UmbControllerHostElementMixin } from '@umbraco-cms/backoffice/controller-api'; +import type { + ManifestPropertyValuePreset, + UmbPropertyTypePresetModel, + UmbPropertyTypePresetModelTypeModel, + UmbPropertyTypePresetWithSchemaAliasModel, + UmbPropertyValuePresetApi, + UmbPropertyValuePresetApiCallArgs, +} from './types.js'; +import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; +import { UmbPropertyValuePresetVariantBuilderController } from './property-value-preset-variant-builder.controller.js'; + +@customElement('umb-test-controller-host') +export class UmbTestControllerHostElement extends UmbControllerHostElementMixin(HTMLElement) {} + +// Test with async APIs, espcially where the first one is slower than the last one. +export class TestPropertyValuePresetFirstApi implements UmbPropertyValuePresetApi { + async processValue( + value: undefined | string, + config: UmbPropertyEditorConfig, + typeArgs: UmbPropertyTypePresetModelTypeModel, + callArgs: UmbPropertyValuePresetApiCallArgs, + ): Promise { + return value + ? value + '_' + 'value for variant ' + callArgs.variantId!.toString() + : 'value for culture ' + callArgs.variantId?.toString(); + } + + destroy(): void {} +} + +describe('UmbPropertyValuePresetVariantBuilderController', () => { + describe('Create with a variant preset', () => { + beforeEach(async () => { + const manifestFirstPreset: ManifestPropertyValuePreset = { + type: 'propertyValuePreset', + name: 'test-preset-1', + alias: 'Umb.Test.Preset.1', + api: TestPropertyValuePresetFirstApi, + forPropertyEditorUiAlias: 'test-editor-ui', + }; + + umbExtensionsRegistry.register(manifestFirstPreset); + }); + afterEach(async () => { + umbExtensionsRegistry.unregister('Umb.Test.Preset.1'); + }); + + it('creates culture variant values', async () => { + const ctrlHost = new UmbTestControllerHostElement(); + const ctrl = new UmbPropertyValuePresetVariantBuilderController(ctrlHost); + ctrl.setCultures(['cultureA', 'cultureB']); + + const propertyTypes: Array = [ + { + alias: 'test', + propertyEditorUiAlias: 'test-editor-ui', + config: [], + typeArgs: { varyByCulture: true }, + }, + ]; + + const result = await ctrl.create(propertyTypes); + + expect(result.length).to.be.equal(2); + expect(result[0]?.value).to.be.equal('value for culture cultureA'); + expect(result[0]?.culture).to.be.equal('cultureA'); + expect(result[1]?.value).to.be.equal('value for culture cultureB'); + expect(result[1]?.culture).to.be.equal('cultureB'); + }); + + it('creates culture variant values when no cultures available should fail', async () => { + const ctrlHost = new UmbTestControllerHostElement(); + const ctrl = new UmbPropertyValuePresetVariantBuilderController(ctrlHost); + + const propertyTypes: Array = [ + { + alias: 'test', + propertyEditorUiAlias: 'test-editor-ui', + config: [], + typeArgs: { varyByCulture: true }, + }, + ]; + + try { + await ctrl.create(propertyTypes); + expect.fail('Expected to fail'); + } catch (e) {} + }); + + it('creates segmented values', async () => { + const ctrlHost = new UmbTestControllerHostElement(); + const ctrl = new UmbPropertyValuePresetVariantBuilderController(ctrlHost); + ctrl.setSegments(['segmentA', 'segmentB']); + + const propertyTypes: Array = [ + { + alias: 'test', + propertyEditorUiAlias: 'test-editor-ui', + config: [], + typeArgs: { varyBySegment: true }, + }, + ]; + + const result = await ctrl.create(propertyTypes); + + expect(result.length).to.be.equal(3); + expect(result[0]?.value).to.be.equal('value for culture invariant'); + expect(result[0]?.culture).to.be.null; + expect(result[0]?.segment).to.be.null; + expect(result[1]?.value).to.be.equal('value for culture invariant_segmentA'); + expect(result[1]?.culture).to.be.null; + expect(result[1]?.segment).to.be.equal('segmentA'); + expect(result[2]?.value).to.be.equal('value for culture invariant_segmentB'); + expect(result[2]?.segment).to.be.equal('segmentB'); + expect(result[2]?.culture).to.be.null; + }); + + it('creates segmented values when no segments available', async () => { + const ctrlHost = new UmbTestControllerHostElement(); + const ctrl = new UmbPropertyValuePresetVariantBuilderController(ctrlHost); + + const propertyTypes: Array = [ + { + alias: 'test', + propertyEditorUiAlias: 'test-editor-ui', + config: [], + typeArgs: { varyBySegment: true }, + }, + ]; + + const result = await ctrl.create(propertyTypes); + + expect(result.length).to.be.equal(1); + expect(result[0]?.value).to.be.equal('value for culture invariant'); + expect(result[0]?.culture).to.be.null; + expect(result[0]?.segment).to.be.null; + }); + + it('creates culture variant and segmented values', async () => { + const ctrlHost = new UmbTestControllerHostElement(); + const ctrl = new UmbPropertyValuePresetVariantBuilderController(ctrlHost); + ctrl.setCultures(['cultureA', 'cultureB']); + ctrl.setSegments(['segmentA', 'segmentB']); + + const propertyTypes: Array = [ + { + alias: 'test', + propertyEditorUiAlias: 'test-editor-ui', + config: [], + typeArgs: { varyByCulture: true, varyBySegment: true }, + }, + ]; + + const result = await ctrl.create(propertyTypes); + + expect(result.length).to.be.equal(6); + + expect(result[0]?.value).to.be.equal('value for culture cultureA'); + expect(result[0]?.culture).to.be.equal('cultureA'); + expect(result[0]?.segment).to.be.null; + expect(result[1]?.value).to.be.equal('value for culture cultureA_segmentA'); + expect(result[1]?.culture).to.be.equal('cultureA'); + expect(result[1]?.segment).to.be.equal('segmentA'); + expect(result[2]?.value).to.be.equal('value for culture cultureA_segmentB'); + expect(result[2]?.culture).to.be.equal('cultureA'); + expect(result[2]?.segment).to.be.equal('segmentB'); + + expect(result[3]?.value).to.be.equal('value for culture cultureB'); + expect(result[3]?.culture).to.be.equal('cultureB'); + expect(result[3]?.segment).to.be.null; + expect(result[4]?.value).to.be.equal('value for culture cultureB_segmentA'); + expect(result[4]?.culture).to.be.equal('cultureB'); + expect(result[4]?.segment).to.be.equal('segmentA'); + expect(result[5]?.value).to.be.equal('value for culture cultureB_segmentB'); + expect(result[5]?.culture).to.be.equal('cultureB'); + expect(result[5]?.segment).to.be.equal('segmentB'); + }); + }); +}); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts new file mode 100644 index 000000000000..a1438f6eab75 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts @@ -0,0 +1,74 @@ +import type { UmbElementValueModel } from '@umbraco-cms/backoffice/content'; +import { UmbPropertyValuePresetBuilderController } from './property-value-preset-builder.controller.js'; +import type { + UmbPropertyTypePresetModel, + UmbPropertyTypePresetWithSchemaAliasModel, + UmbPropertyValuePresetApi, +} from './types.js'; +import { UmbVariantId } from '../../variant/variant-id.class.js'; + +type ReturnType = UmbElementValueModel; + +export class UmbPropertyValuePresetVariantBuilderController extends UmbPropertyValuePresetBuilderController { + #cultures: Array = []; + // Always declare the default segment (null) + #segments: Array = [null]; + + setCultures(cultures: Array): void { + this.#cultures = cultures; + } + setSegments(segments: Array): void { + // No matter how many segments are present, always include the default segment (null) + this.#segments = [null, ...segments]; + } + + protected override async _generatePropertyValues( + apis: Array, + propertyType: UmbPropertyTypePresetModel | UmbPropertyTypePresetWithSchemaAliasModel, + ): Promise> { + let values = []; + + if (propertyType.typeArgs.varyBySegment && propertyType.typeArgs.varyByCulture) { + if (this.#cultures.length === 0) { + throw new Error('Cultures must be set when varying by culture.'); + } + + for (const culture of this.#cultures) { + for (const segment of this.#segments) { + const value = await this._generatePropertyValue(apis, propertyType, { + variantId: new UmbVariantId(culture, segment), + }); + value.culture = culture; + value.segment = segment; + values.push(value); + } + } + } else if (propertyType.typeArgs.varyByCulture) { + if (this.#cultures.length === 0) { + throw new Error('Cultures must be set when varying by culture.'); + } + + for (const culture of this.#cultures) { + const value = await super._generatePropertyValue(apis, propertyType, { + variantId: new UmbVariantId(culture), + }); + value.culture = culture; + value.segment = null; + values.push(value); + } + } else if (propertyType.typeArgs.varyBySegment) { + for (const segment of this.#segments) { + const value = await super._generatePropertyValue(apis, propertyType, { + variantId: new UmbVariantId(null, segment), + }); + // Be aware this maybe should have been the default culture? + value.culture = null; + value.segment = segment; + values.push(value); + } + } else { + values.push(await this._generatePropertyValue(apis, propertyType, {})); + } + return values; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts index 7fa62f9e7867..67e1b3f71495 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts @@ -1,5 +1,6 @@ import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; +import type { UmbVariantId } from '../../variant/variant-id.class.js'; export type * from './property-value-preset.extension.js'; @@ -13,12 +14,27 @@ export interface UmbPropertyValuePresetApi< export type UmbPropertyValuePresetApiValuesProcessor< ValueType = unknown, ConfigType extends UmbPropertyEditorConfig = UmbPropertyEditorConfig, -> = (value: undefined | ValueType, config: ConfigType) => PromiseLike; +> = ( + value: undefined | ValueType, + config: ConfigType, + typeArgs: UmbPropertyTypePresetModelTypeModel, + callArgs: UmbPropertyValuePresetApiCallArgs, +) => PromiseLike; export interface UmbPropertyTypePresetModel { alias: string; propertyEditorUiAlias: string; config: UmbPropertyEditorConfig; + typeArgs: UmbPropertyTypePresetModelTypeModel; +} + +export interface UmbPropertyTypePresetModelTypeModel { + isMandatory?: boolean; + varyByCulture?: boolean; + varyBySegment?: boolean; +} +export interface UmbPropertyValuePresetApiCallArgs { + variantId?: UmbVariantId; } export interface UmbPropertyTypePresetWithSchemaAliasModel extends UmbPropertyTypePresetModel { From 5c585464f0df83667bd0308fa67f9e78232cdfd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Sat, 22 Feb 2025 11:02:48 +0100 Subject: [PATCH 22/57] fix test --- .../property-value-preset-builder.controller.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts index 6d7ec7c6ed62..dfbbbb47e0bb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts @@ -68,6 +68,7 @@ describe('UmbPropertyValuePresetBuilderController', () => { alias: 'test', propertyEditorUiAlias: 'test-editor-ui', config: [], + typeArgs: {}, }, ]; @@ -115,6 +116,7 @@ describe('UmbPropertyValuePresetBuilderController', () => { alias: 'test', propertyEditorUiAlias: 'test-editor-ui', config: [], + typeArgs: {}, }, ]; @@ -162,6 +164,7 @@ describe('UmbPropertyValuePresetBuilderController', () => { alias: 'test', propertyEditorUiAlias: 'test-editor-ui', config: [], + typeArgs: {}, }, ]; @@ -220,11 +223,13 @@ describe('UmbPropertyValuePresetBuilderController', () => { alias: 'test', propertyEditorUiAlias: 'test-editor-ui', config: [], + typeArgs: {}, }, { alias: 'test2', propertyEditorUiAlias: 'test-editor-ui', config: [], + typeArgs: {}, }, ]; @@ -287,18 +292,21 @@ describe('UmbPropertyValuePresetBuilderController', () => { alias: 'test', propertyEditorUiAlias: 'test-editor-ui', config: [], + typeArgs: {}, }, { alias: 'test2', propertyEditorUiAlias: 'test-editor-ui', propertyEditorSchemaAlias: 'test-editor-schema', config: [], + typeArgs: {}, }, { alias: 'test3', propertyEditorUiAlias: 'some-other-ui', propertyEditorSchemaAlias: 'test-editor-schema', config: [], + typeArgs: {}, }, ]; From 10ebeecf46b66bc896a90a915b523cbfded1df27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Sat, 22 Feb 2025 11:14:21 +0100 Subject: [PATCH 23/57] implementation for blocks --- .../block/context/block-manager.context.ts | 70 +++++++++++++++++-- .../block/workspace/block-element-manager.ts | 6 +- .../content-type-structure-manager.class.ts | 11 +++ .../property-editor-ui-toggle.element.ts | 5 +- 4 files changed, 78 insertions(+), 14 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts index 8817dd2a9345..5222255151ee 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts @@ -18,6 +18,13 @@ import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/ import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; import type { UmbBlockTypeBaseModel } from '@umbraco-cms/backoffice/block-type'; import { UmbReadOnlyVariantStateManager } from '@umbraco-cms/backoffice/utils'; +import { + UmbPropertyValuePresetVariantBuilderController, + type UmbPropertyTypePresetModel, + type UmbPropertyTypePresetModelTypeModel, +} from '@umbraco-cms/backoffice/property'; +import { UMB_APP_LANGUAGE_CONTEXT } from '@umbraco-cms/backoffice/language'; +import { UmbDataTypeDetailRepository } from '@umbraco-cms/backoffice/data-type'; export type UmbBlockDataObjectModel = { layout: LayoutEntryType; @@ -353,14 +360,63 @@ export abstract class UmbBlockManagerContext< }; } - protected _createBlockElementData(key: string, elementTypeKey: string) { + protected async _createBlockElementData(key: string, contentTypeKey: string) { // - // TODO: Handle presets here [NL] + const appLanguage = await this.getContext(UMB_APP_LANGUAGE_CONTEXT); + + const contentStructure = this.getStructure(contentTypeKey); + if (!contentStructure) { + throw new Error(`Cannot create Preset for Block, missing content structure for ${contentTypeKey}`); + } + + // Set culture and segment for all values: + const cutlures = contentStructure.variesByCulture ? await appLanguage.getCultures() : []; + if (cutlures.length === 0) { + throw new Error('Could not retrieve app cultures.'); + } + // TODO: Receive the segments from somewhere. [NL] + const segments: Array | undefined = contentStructure.variesBySegment ? [] : undefined; + + const propertyTypes = await contentStructure.getContentTypeProperties(); + const valueDefinitions = await Promise.all( + propertyTypes.map(async (property) => { + // the getItemByUnique is a async method that first resolves once the item is loaded. + const repo = new UmbDataTypeDetailRepository(this); + const dataType = (await repo.requestByUnique(property.dataType.unique)).data; + // This means if its not loaded this will never resolve and the error below will never happen. + if (!dataType) { + throw new Error(`DataType of "${property.dataType.unique}" not found.`); + } + if (!dataType.editorUiAlias) { + throw new Error(`DataType of "${property.dataType.unique}" did not have a editorUiAlias.`); + } + + return { + alias: property.alias, + propertyEditorUiAlias: dataType.editorUiAlias, + propertyEditorSchemaAlias: dataType.editorAlias, + config: dataType.values, + typeArgs: { + variesByCulture: property.variesByCulture, + variesBySegment: property.variesBySegment, + } as UmbPropertyTypePresetModelTypeModel, + } as UmbPropertyTypePresetModel; + }), + ); + + const controller = new UmbPropertyValuePresetVariantBuilderController(this); + controller.setCultures(cutlures); + if (segments) { + controller.setSegments(segments); + } + let values = await controller.create(valueDefinitions); + + // Set culture and segment for all values: return { - key: key, - contentTypeKey: elementTypeKey, - values: [], + key, + contentTypeKey, + values, }; } @@ -380,12 +436,12 @@ export abstract class UmbBlockManagerContext< ...(partialLayoutEntry as Partial), } as BlockLayoutType; - const content = this._createBlockElementData(layout.contentKey, contentElementTypeKey); + const content = await this._createBlockElementData(layout.contentKey, contentElementTypeKey); let settings: UmbBlockDataModel | undefined = undefined; if (blockType.settingsElementTypeKey) { layout.settingsKey = UmbId.new(); - settings = this._createBlockElementData(layout.settingsKey, blockType.settingsElementTypeKey); + settings = await this._createBlockElementData(layout.settingsKey, blockType.settingsElementTypeKey); } return { diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/block-element-manager.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/block-element-manager.ts index bac6c7d5bd8b..4a5c0ab0c205 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/block-element-manager.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/block-element-manager.ts @@ -133,10 +133,7 @@ export class UmbBlockElementManager(); @@ -68,6 +76,9 @@ export class UmbContentTypeStructureManager< // Notice this may need to use getValue to avoid resetting it self. [NL] return contentTypes.flatMap((x) => x.properties ?? []); }); + async getContentTypeProperties() { + return await this.observe(this.contentTypeProperties).asPromise(); + } readonly contentTypeDataTypeUniques = this.#contentTypes.asObservablePart((contentTypes) => { // Notice this may need to use getValue to avoid resetting it self. [NL] return contentTypes diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts index 1c8377bb3a77..9bc790b20fec 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts @@ -48,8 +48,6 @@ export class UmbPropertyEditorUIToggleElement public set config(config: UmbPropertyEditorConfigCollection | undefined) { if (!config) return; - // TODO: Do not set value here, but use future feature of Value Presets. [NL] - this.value ??= config.getValueByAlias('default') ?? false; this._labelOff = config.getValueByAlias('labelOff'); this._labelOn = config.getValueByAlias('labelOn'); this._showLabels = Boolean(config.getValueByAlias('showLabels')); @@ -61,7 +59,8 @@ export class UmbPropertyEditorUIToggleElement } #onChange(event: CustomEvent & { target: UmbInputToggleElement }) { - this.value = event.target.checked; + const checked = event.target.checked; + this.value = this.mandatory ? (checked ?? null) : checked; this.dispatchEvent(new UmbPropertyValueChangeEvent()); } From 79c6d873f1d3698001830c1dc2cf74b6687eef43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Sat, 22 Feb 2025 19:04:43 +0100 Subject: [PATCH 24/57] TODO --- .../controller/base-extensions-initializer.controller.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/libs/extension-api/controller/base-extensions-initializer.controller.ts b/src/Umbraco.Web.UI.Client/src/libs/extension-api/controller/base-extensions-initializer.controller.ts index e7492a6a8dd7..57258cf300a5 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/extension-api/controller/base-extensions-initializer.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/extension-api/controller/base-extensions-initializer.controller.ts @@ -177,6 +177,7 @@ export abstract class UmbBaseExtensionsInitializer< this.#exposedPermittedExts = approvedExtensions; + // TODO: Option to first resolve once all have responded are completed. [NL] if (this.#exposedPermittedExts.length > 0) { this.#promiseResolvers.forEach((x) => x()); this.#promiseResolvers = []; From 32e100a5a23e5fa4396e5f6617b74e4abe804404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Sat, 22 Feb 2025 21:33:32 +0100 Subject: [PATCH 25/57] improve comment --- .../packages/block/block/context/block-manager.context.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts index 5222255151ee..b48641c87866 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts @@ -377,11 +377,12 @@ export abstract class UmbBlockManagerContext< // TODO: Receive the segments from somewhere. [NL] const segments: Array | undefined = contentStructure.variesBySegment ? [] : undefined; + const repo = new UmbDataTypeDetailRepository(this); + const propertyTypes = await contentStructure.getContentTypeProperties(); const valueDefinitions = await Promise.all( propertyTypes.map(async (property) => { - // the getItemByUnique is a async method that first resolves once the item is loaded. - const repo = new UmbDataTypeDetailRepository(this); + // TODO: Implement caching for data-type requests. [NL] const dataType = (await repo.requestByUnique(property.dataType.unique)).data; // This means if its not loaded this will never resolve and the error below will never happen. if (!dataType) { From cf3490fb7f43214fe00f0eaef5aca82b4b1e6700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Sat, 22 Feb 2025 21:41:13 +0100 Subject: [PATCH 26/57] implement for ContentTypes --- .../content-type-structure-manager.class.ts | 28 +++++---- .../content-detail-workspace-base.ts | 60 ++++++++++++++++++- .../entity-detail-workspace-base.ts | 9 ++- .../document-blueprint-workspace.context.ts | 1 + .../workspace/document-workspace.context.ts | 1 + .../workspace/media-workspace.context.ts | 1 + .../member/member-workspace.context.ts | 3 +- 7 files changed, 87 insertions(+), 16 deletions(-) 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 aceca9154478..473371f7b669 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 @@ -35,7 +35,10 @@ const UmbFilterDuplicateStrings = (value: string, index: number, array: Array extends UmbControllerBase { - #init!: Promise; + #initResolver?: () => void; + #init = new Promise((resolve) => { + this.#initResolver = resolve; + }); #repository?: UmbDetailRepository; #initRepositoryResolver?: () => void; @@ -48,13 +51,10 @@ export class UmbContentTypeStructureManager< } }); - /* async whenLoaded() { - await this.#initRepository; await this.#init; return true; } - */ #ownerContentTypeUnique?: string; #contentTypeObservers = new Array(); @@ -133,16 +133,17 @@ export class UmbContentTypeStructureManager< * @returns {Promise} - Promise resolved */ public async loadType(unique?: string) { - //if (!unique) return; - //if (this.#ownerContentTypeUnique === unique) return; + if (this.#ownerContentTypeUnique === unique) { + // Its the same, but we do not know if its done loading jet, so we will wait for the load promise to finish. [NL] + await this.#init; + return; + } this.#clear(); - this.#ownerContentTypeUnique = unique; - - const promise = this.#loadType(unique); - this.#init = promise; - await this.#init; - return promise; + if (!unique) return; + const result = await this.#loadType(unique); + this.#initResolver?.(); + return result; } public async createScaffold(preset?: Partial) { @@ -787,6 +788,9 @@ export class UmbContentTypeStructureManager< } #clear() { + this.#init = new Promise((resolve) => { + this.#initResolver = resolve; + }); this.#contentTypes.setValue([]); this.#contentTypeObservers.forEach((observer) => observer.destroy()); this.#contentTypeObservers = []; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts index 4fecb6c53689..63b00307444f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -25,7 +25,7 @@ import { type UmbEntityVariantOptionModel, } from '@umbraco-cms/backoffice/variant'; import { UmbDeprecation, UmbReadOnlyVariantStateManager } from '@umbraco-cms/backoffice/utils'; -import { UmbDataTypeItemRepositoryManager } from '@umbraco-cms/backoffice/data-type'; +import { UmbDataTypeDetailRepository, UmbDataTypeItemRepositoryManager } from '@umbraco-cms/backoffice/data-type'; import { appendToFrozenArray, mergeObservables, UmbArrayState } from '@umbraco-cms/backoffice/observable-api'; import { UmbLanguageCollectionRepository, type UmbLanguageDetailModel } from '@umbraco-cms/backoffice/language'; import type { Observable } from '@umbraco-cms/backoffice/external/rxjs'; @@ -47,6 +47,11 @@ import { UmbRequestReloadStructureForEntityEvent, } from '@umbraco-cms/backoffice/entity-action'; import type { ClassConstructor } from '@umbraco-cms/backoffice/extension-api'; +import { + UmbPropertyValuePresetVariantBuilderController, + type UmbPropertyTypePresetModel, + type UmbPropertyTypePresetModelTypeModel, +} from '@umbraco-cms/backoffice/property'; export interface UmbContentDetailWorkspaceContextArgs< DetailModelType extends UmbContentDetailModel, @@ -60,6 +65,7 @@ export interface UmbContentDetailWorkspaceContextArgs< contentValidationRepository?: ClassConstructor>; skipValidationOnSubmit?: boolean; contentVariantScaffold: VariantModelType; + contentTypePropertyName: string; saveModalToken?: UmbModalToken, UmbContentVariantPickerValue>; } @@ -145,6 +151,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< #validationRepository?: UmbContentValidationRepository; #saveModalToken?: UmbModalToken, UmbContentVariantPickerValue>; + #contentTypePropertyName: string; constructor( host: UmbControllerHost, @@ -159,6 +166,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< this._data.setVariantScaffold(args.contentVariantScaffold); this.#saveModalToken = args.saveModalToken; + this.#contentTypePropertyName = args.contentTypePropertyName; const contentTypeDetailRepository = new args.contentTypeDetailRepository(this); this.#validationRepositoryClass = args.contentValidationRepository; @@ -245,6 +253,56 @@ export abstract class UmbContentDetailWorkspaceContextBase< this.#languages.setValue(data?.items ?? []); } + protected override async _scaffoldProcessData(data: DetailModelType): Promise { + // Load the content type structure, usually this comes from the data, but in this case we are making the data, and we need this to be able to complete the data. [NL] + await this.structure.loadType((data as any)[this.#contentTypePropertyName].unique); + + // Set culture and segment for all values: + const cutlures = this.#languages.getValue().map((x) => x.unique); + + if (this.structure.variesBySegment) { + console.warn('Segments are not yet implemented for preset'); + } + const segments: Array | undefined = this.structure.variesBySegment ? [] : undefined; + + const repo = new UmbDataTypeDetailRepository(this); + + const propertyTypes = await this.structure.getContentTypeProperties(); + const valueDefinitions = await Promise.all( + propertyTypes.map(async (property) => { + // TODO: Implement caching for data-type requests. [NL] + const dataType = (await repo.requestByUnique(property.dataType.unique)).data; + // This means if its not loaded this will never resolve and the error below will never happen. + if (!dataType) { + throw new Error(`DataType of "${property.dataType.unique}" not found.`); + } + if (!dataType.editorUiAlias) { + throw new Error(`DataType of "${property.dataType.unique}" did not have a editorUiAlias.`); + } + + return { + alias: property.alias, + propertyEditorUiAlias: dataType.editorUiAlias, + propertyEditorSchemaAlias: dataType.editorAlias, + config: dataType.values, + typeArgs: { + variesByCulture: property.variesByCulture, + variesBySegment: property.variesBySegment, + } as UmbPropertyTypePresetModelTypeModel, + } as UmbPropertyTypePresetModel; + }), + ); + + const controller = new UmbPropertyValuePresetVariantBuilderController(this); + controller.setCultures(cutlures); + if (segments) { + controller.setSegments(segments); + } + data.values = await controller.create(valueDefinitions); + + return data; + } + /** * Get the name of a variant * @param {UmbVariantId } [variantId] - The variant id diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts index 3b2e0d805ddd..b3876a7d0426 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts @@ -231,18 +231,19 @@ export abstract class UmbEntityDetailWorkspaceContextBase< await this.#init; this.setParent(args.parent); - // TODO: Handle presets here [NL] const request = this._detailRepository!.createScaffold(args.preset); this._getDataPromise = request; let { data } = await request; if (data) { - this.#entityContext.setUnique(data.unique); + data = await this._scaffoldProcessData(data); if (this.modalContext) { + // Notice if the preset comes with values, they will overwrite the scaffolded values... [NL] data = { ...data, ...this.modalContext.data.preset }; } + this.#entityContext.setUnique(data.unique); this.setIsNew(true); this._data.setPersisted(data); this._data.setCurrent(data); @@ -253,6 +254,10 @@ export abstract class UmbEntityDetailWorkspaceContextBase< return data; } + protected async _scaffoldProcessData(data: DetailModelType): Promise { + return data; + } + async submit() { await this.#init; const currentData = this.getData(); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts index d1213629f5a4..aacaad252d7e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts @@ -44,6 +44,7 @@ export class UmbDocumentBlueprintWorkspaceContext detailRepositoryAlias: UMB_DOCUMENT_BLUEPRINT_DETAIL_REPOSITORY_ALIAS, contentTypeDetailRepository: UmbDocumentTypeDetailRepository, contentVariantScaffold: UMB_DOCUMENT_DETAIL_MODEL_VARIANT_SCAFFOLD, + contentTypePropertyName: 'documentType', }); this.observe(this.contentTypeUnique, (unique) => this.structure.loadType(unique), null); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts index 4f989c98aee1..b09b29dc0f1b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -82,6 +82,7 @@ export class UmbDocumentWorkspaceContext contentValidationRepository: UmbDocumentValidationRepository, skipValidationOnSubmit: true, contentVariantScaffold: UMB_DOCUMENT_DETAIL_MODEL_VARIANT_SCAFFOLD, + contentTypePropertyName: 'documentType', saveModalToken: UMB_DOCUMENT_SAVE_MODAL, }); diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/workspace/media-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/workspace/media-workspace.context.ts index 2a2e35395b21..901b81b4d526 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/workspace/media-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/workspace/media-workspace.context.ts @@ -51,6 +51,7 @@ export class UmbMediaWorkspaceContext contentTypeDetailRepository: UmbMediaTypeDetailRepository, contentValidationRepository: UmbMediaValidationRepository, contentVariantScaffold: UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD, + contentTypePropertyName: 'mediaType', }); this.observe(this.contentTypeUnique, (unique) => this.structure.loadType(unique), null); diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/member-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/member-workspace.context.ts index 6cab3770f190..40c0643e5a92 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/member-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/member-workspace.context.ts @@ -41,6 +41,7 @@ export class UmbMemberWorkspaceContext // TODO: Enable Validation Repository when we have UI for showing validation issues on other tabs. [NL] //contentValidationRepository: UmbMemberValidationRepository, contentVariantScaffold: UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD, + contentTypePropertyName: 'memberType', }); this.observe(this.contentTypeUnique, (unique) => this.structure.loadType(unique), null); @@ -78,7 +79,7 @@ export class UmbMemberWorkspaceContext preset: { memberType: { unique: memberTypeUnique, - icon: "icon-user" + icon: 'icon-user', }, }, }); From 4159f44fedcf69c13e8a8ae98e8a05cb539c37cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Sat, 22 Feb 2025 21:47:09 +0100 Subject: [PATCH 27/57] always set culture and segment for variant values --- ...property-value-preset-variant-builder.controller.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts index a1438f6eab75..f130e4de7830 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts @@ -49,7 +49,7 @@ export class UmbPropertyValuePresetVariantBuilderController extends UmbPropertyV } for (const culture of this.#cultures) { - const value = await super._generatePropertyValue(apis, propertyType, { + const value = await this._generatePropertyValue(apis, propertyType, { variantId: new UmbVariantId(culture), }); value.culture = culture; @@ -58,7 +58,7 @@ export class UmbPropertyValuePresetVariantBuilderController extends UmbPropertyV } } else if (propertyType.typeArgs.varyBySegment) { for (const segment of this.#segments) { - const value = await super._generatePropertyValue(apis, propertyType, { + const value = await this._generatePropertyValue(apis, propertyType, { variantId: new UmbVariantId(null, segment), }); // Be aware this maybe should have been the default culture? @@ -67,7 +67,11 @@ export class UmbPropertyValuePresetVariantBuilderController extends UmbPropertyV values.push(value); } } else { - values.push(await this._generatePropertyValue(apis, propertyType, {})); + const value = await this._generatePropertyValue(apis, propertyType, {}); + // Be aware this maybe should have been the default culture? + value.culture = null; + value.segment = null; + values.push(value); } return values; } From 2666e019a2f7e6742440392867ecbd9a4ad86f84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Sat, 22 Feb 2025 22:29:39 +0100 Subject: [PATCH 28/57] only set values that got a value --- ...roperty-value-preset-builder.controller.ts | 9 +++-- ...value-preset-variant-builder.controller.ts | 36 +++++++++++-------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts index 883aa1aca9ad..95c2e2eb49dc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts @@ -71,14 +71,15 @@ export class UmbPropertyValuePresetBuilderController< apis: Array, propertyType: UmbPropertyTypePresetModel | UmbPropertyTypePresetWithSchemaAliasModel, ): Promise> { - return [await this._generatePropertyValue(apis, propertyType, EMPTY_CALL_ARGS)]; + const property = await this._generatePropertyValue(apis, propertyType, EMPTY_CALL_ARGS); + return property ? [property] : []; } protected async _generatePropertyValue( apis: Array, propertyType: UmbPropertyTypePresetModel | UmbPropertyTypePresetWithSchemaAliasModel, callArgs: UmbPropertyValuePresetApiCallArgs, - ): Promise { + ): Promise { let value: unknown = undefined; // Important to use a inline for loop, to secure that each entry is processed(asynchronously) in order for (const api of apis) { @@ -89,6 +90,10 @@ export class UmbPropertyValuePresetBuilderController< value = await api.processValue(value, propertyType.config, propertyType.typeArgs, callArgs); } + if (!value) { + return; + } + if ((propertyType as UmbPropertyTypePresetWithSchemaAliasModel).propertyEditorSchemaAlias) { return { editorAlias: (propertyType as UmbPropertyTypePresetWithSchemaAliasModel).propertyEditorSchemaAlias, diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts index f130e4de7830..3f199bcdfe31 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts @@ -26,7 +26,7 @@ export class UmbPropertyValuePresetVariantBuilderController extends UmbPropertyV apis: Array, propertyType: UmbPropertyTypePresetModel | UmbPropertyTypePresetWithSchemaAliasModel, ): Promise> { - let values = []; + let values: Array = []; if (propertyType.typeArgs.varyBySegment && propertyType.typeArgs.varyByCulture) { if (this.#cultures.length === 0) { @@ -38,9 +38,11 @@ export class UmbPropertyValuePresetVariantBuilderController extends UmbPropertyV const value = await this._generatePropertyValue(apis, propertyType, { variantId: new UmbVariantId(culture, segment), }); - value.culture = culture; - value.segment = segment; - values.push(value); + if (value) { + value.culture = culture; + value.segment = segment; + values.push(value); + } } } } else if (propertyType.typeArgs.varyByCulture) { @@ -52,26 +54,32 @@ export class UmbPropertyValuePresetVariantBuilderController extends UmbPropertyV const value = await this._generatePropertyValue(apis, propertyType, { variantId: new UmbVariantId(culture), }); - value.culture = culture; - value.segment = null; - values.push(value); + if (value) { + value.culture = culture; + value.segment = null; + values.push(value); + } } } else if (propertyType.typeArgs.varyBySegment) { for (const segment of this.#segments) { const value = await this._generatePropertyValue(apis, propertyType, { variantId: new UmbVariantId(null, segment), }); + if (value) { + // Be aware this maybe should have been the default culture? + value.culture = null; + value.segment = segment; + values.push(value); + } + } + } else { + const value = await this._generatePropertyValue(apis, propertyType, {}); + if (value) { // Be aware this maybe should have been the default culture? value.culture = null; - value.segment = segment; + value.segment = null; values.push(value); } - } else { - const value = await this._generatePropertyValue(apis, propertyType, {}); - // Be aware this maybe should have been the default culture? - value.culture = null; - value.segment = null; - values.push(value); } return values; } From 61b03e8346b69d33f50fc3cb207cae4e40595da9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Sat, 22 Feb 2025 22:29:48 +0100 Subject: [PATCH 29/57] todo notes --- .../workspace/content-detail-workspace-base.ts | 18 +++++++++++++++++- .../entity-detail-workspace-base.ts | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts index 63b00307444f..72ce8e0c938b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -731,8 +731,23 @@ export abstract class UmbContentDetailWorkspaceContextBase< } this._data.setPersisted(data); + console.log('setPersisted', data); - const currentData = this._data.getCurrent(); + let currentData = this._data.getCurrent(); + + // TODO: fix sorting of properties, I think its the currentData.values that needs to be sorted. [NL] + /* + if (currentData) { + const persistedValueOrder = data.values; + // Sort values of currentData in the same order as persisted data: + const values = currentData.values.sort((a, b) => { + let aIndex = persistedValueOrder.findIndex((x) => x.alias === a.alias); + let bIndex = persistedValueOrder.findIndex((x) => x.alias === b.alias); + return aIndex - bIndex; + }); + currentData = { ...currentData, values }; + } + */ const variantIdsIncludingInvariant = [...variantIds, UmbVariantId.CreateInvariant()]; @@ -744,6 +759,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< variantIdsIncludingInvariant, ); + console.log('setCurrent', newCurrentData); this._data.setCurrent(newCurrentData); const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts index b3876a7d0426..bb2f454c2c19 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts @@ -358,6 +358,7 @@ export abstract class UmbEntityDetailWorkspaceContextBase< /* TODO: temp removal of discard changes in workspace modals. The modal closes before the discard changes dialog is resolved.*/ + // TODO: I think this can go away now??? if (newUrl.includes('/modal/umb-modal-workspace/')) { return true; } From de4ae7e0766df6b30775f5180fbb1cfd32627848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 24 Feb 2025 15:29:21 +0100 Subject: [PATCH 30/57] also resolve init when createScaffold --- .../structure/content-type-structure-manager.class.ts | 1 + 1 file changed, 1 insertion(+) 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 473371f7b669..7082ebc763f2 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 @@ -157,6 +157,7 @@ export class UmbContentTypeStructureManager< // Add the new content type to the list of content types, this holds our draft state of this scaffold. this.#contentTypes.appendOne(data); + this.#initResolver?.(); return { data }; } From 2c5bdc25c01d341c97123cb479d023c8c650ccec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 24 Feb 2025 19:04:23 +0100 Subject: [PATCH 31/57] property-value-preset.Slider --- .../property-editors/slider/manifests.ts | 7 ++++ .../property-editor-ui-slider.element.ts | 5 ++- .../slider/property-value-preset.Slider.ts | 36 +++++++++++++++++++ .../packages/property-editors/slider/types.ts | 6 ++++ .../src/packages/property-editors/types.ts | 1 + 5 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/types.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/manifests.ts index fd4519a59c19..c0fee318d13b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/manifests.ts @@ -1,6 +1,13 @@ import { manifest as sliderSchemaManifest } from './Umbraco.Slider.js'; export const manifests: Array = [ + { + type: 'propertyValuePreset', + forPropertyEditorSchemaAlias: 'Umbraco.Slider', + alias: 'Umb.PropertyValuePreset.Slider', + name: 'Property Editor Schema Slider Preset for Initial Values', + api: () => import('./property-value-preset.Slider.js'), + }, { type: 'propertyEditorUi', alias: 'Umb.PropertyEditorUi.Slider', diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts index d9a719922c6b..f01fdc75dcda 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts @@ -7,8 +7,7 @@ import type { UmbPropertyEditorConfigCollection, UmbPropertyEditorUiElement, } from '@umbraco-cms/backoffice/property-editor'; - -export type UmbSliderValue = { from: number; to: number } | undefined; +import type { UmbPropertyEditorUISliderValue } from './types.js'; /** * @element umb-property-editor-ui-slider @@ -16,7 +15,7 @@ export type UmbSliderValue = { from: number; to: number } | undefined; @customElement('umb-property-editor-ui-slider') export class UmbPropertyEditorUISliderElement extends UmbLitElement implements UmbPropertyEditorUiElement { @property({ type: Object }) - value: UmbSliderValue | undefined; + value: UmbPropertyEditorUISliderValue | undefined; /** * Sets the input to readonly mode, meaning value cannot be changed but still able to read and select its content. diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts new file mode 100644 index 000000000000..d98347ee8f8a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts @@ -0,0 +1,36 @@ +import type { UmbPropertyValuePresetApi } from '@umbraco-cms/backoffice/property'; +import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; +import type { UmbPropertyEditorUISliderValue } from './types.js'; + +export class UmbPropertyValuePresetSliderApi + implements UmbPropertyValuePresetApi +{ + async processValue(value: undefined | UmbPropertyEditorUISliderValue, config: UmbPropertyEditorConfig) { + const enableRange = Boolean(config.find((x) => x.alias === 'enableRange') ?? false); + + /* + const min = Number(config.find((x) => x.alias === 'minVal') ?? 0); + const max = Number(config.find((x) => x.alias === 'maxVal') ?? 100); + const minVerified = isNaN(min) ? undefined : min; + const maxVerified = isNaN(max) ? undefined : max; + */ + + const step = (config.find((x) => x.alias === 'step') as number | undefined) ?? 0; + const stepVerified = step > 0 ? step : 1; + + const initValueMin = Number(config.find((x) => x.alias === 'initVal1')?.value) ?? 0; + const initValueMinVerified = isNaN(initValueMin) ? 0 : initValueMin; + + const initValueMax = Number(config.find((x) => x.alias === 'initVal2')?.value) ?? 0; + const initValueMaxVerified = isNaN(initValueMax) ? initValueMinVerified + stepVerified : initValueMax; + + const initialState = enableRange + ? { from: initValueMinVerified, to: initValueMaxVerified } + : { from: initValueMinVerified, to: initValueMinVerified }; + return value !== undefined ? value : initialState; + } + + destroy(): void {} +} + +export { UmbPropertyValuePresetSliderApi as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/types.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/types.ts new file mode 100644 index 000000000000..127729b2f0a8 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/types.ts @@ -0,0 +1,6 @@ +export type UmbPropertyEditorUISliderValue = { from: number; to: number } | undefined; + +/** + * @deprecated this type will be removed in v.17.0, use `UmbPropertyEditorUISliderValue` instead + */ +export type UmbSliderValue = UmbPropertyEditorUISliderValue; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/types.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/types.ts index 7333c40dc669..1213e71e2859 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/types.ts @@ -1 +1,2 @@ export type * from './toggle/types.js'; +export type * from './slider/types.js'; From 9753c74e891bc7b45ab4e7970f4681174ca02281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 24 Feb 2025 19:32:08 +0100 Subject: [PATCH 32/57] leaving some concept code for another time --- ...ray-and-string-comparison.function.temp_ts | 15 ++++++++++ ...n-array-and-string-comparison.test.temp_ts | 29 +++++++++++++++++++ .../utils/json-string-comparison.function.ts | 6 ++-- 3 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-array-and-string-comparison.function.temp_ts create mode 100644 src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-array-and-string-comparison.test.temp_ts diff --git a/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-array-and-string-comparison.function.temp_ts b/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-array-and-string-comparison.function.temp_ts new file mode 100644 index 000000000000..17e327a16eed --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-array-and-string-comparison.function.temp_ts @@ -0,0 +1,15 @@ +import { diffJson } from '@umbraco-cms/backoffice/external/diff'; + +/** + * @function umbJsonDeepComparison + * @param {object} a - The first object to compare. + * @param {object} b - The second object to compare. + * @returns {boolean} - Returns true if the JSON Structure are identical. + * @description - Compares two objects by converting them to JSON strings. + * This is a JSON comparison and should only be used for simple objects. + * Meaning no class instances can take part in this data. + */ +export function umbJsonDeepComparison(a: object, b: object): boolean { + const result = diffJson(a, b); + return result.some((change) => change.added || change.removed); +} diff --git a/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-array-and-string-comparison.test.temp_ts b/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-array-and-string-comparison.test.temp_ts new file mode 100644 index 000000000000..ee1440675b0e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-array-and-string-comparison.test.temp_ts @@ -0,0 +1,29 @@ +import { expect } from '@open-wc/testing'; +import { umbJsonDeepComparison } from './json-array-and-string-comparison.function.js'; + +describe('umbJsonDeepComparison', () => { + beforeEach(() => {}); + + it('gives a result', (done) => { + const a = { + property: 'hello', + arr: [1, 2, 3], + obj: { + deep: 'value', + deep2: 'value2', + }, + }; + + const b = { + property: 'hello', + arr: [1, 2, 3], + obj: { + deep2: 'value2', + deep: 'value', + }, + }; + + const result = umbJsonDeepComparison(a, b); + expect(result).to.be.false; + }); +}); diff --git a/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-string-comparison.function.ts b/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-string-comparison.function.ts index 7f0a1a008b7a..eaeb03cd712e 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-string-comparison.function.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-string-comparison.function.ts @@ -1,12 +1,12 @@ /** * @function jsonStringComparison - * @param {unknown} a - The first object to compare. - * @param {unknown} b - The second object to compare. + * @param {object} a - The first object to compare. + * @param {object} b - The second object to compare. * @returns {boolean} - Returns true if the JSON strings are identical. * @description - Compares two objects by converting them to JSON strings. * This is a JSON comparison and should only be used for simple objects. * Meaning no class instances can take part in this data. */ -export function jsonStringComparison(a: unknown, b: unknown): boolean { +export function jsonStringComparison(a: object, b: object): boolean { return JSON.stringify(a) === JSON.stringify(b); } From 3bf748830451a280eb1cc4974e1a5761dbd71c8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 24 Feb 2025 19:37:22 +0100 Subject: [PATCH 33/57] enable undefined --- .../observable-api/utils/json-string-comparison.function.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-string-comparison.function.ts b/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-string-comparison.function.ts index eaeb03cd712e..ff95105ffcf4 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-string-comparison.function.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-string-comparison.function.ts @@ -1,12 +1,12 @@ /** * @function jsonStringComparison - * @param {object} a - The first object to compare. - * @param {object} b - The second object to compare. + * @param {object | undefined} a - The first object to compare. + * @param {object | undefined} b - The second object to compare. * @returns {boolean} - Returns true if the JSON strings are identical. * @description - Compares two objects by converting them to JSON strings. * This is a JSON comparison and should only be used for simple objects. * Meaning no class instances can take part in this data. */ -export function jsonStringComparison(a: object, b: object): boolean { +export function jsonStringComparison(a: object | undefined, b: object | undefined): boolean { return JSON.stringify(a) === JSON.stringify(b); } From 4e3d635d5eb9f173ffcadaddb6e893bc55f4ed84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 24 Feb 2025 19:40:27 +0100 Subject: [PATCH 34/57] revert --- .../observable-api/utils/json-string-comparison.function.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-string-comparison.function.ts b/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-string-comparison.function.ts index ff95105ffcf4..7f0a1a008b7a 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-string-comparison.function.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-string-comparison.function.ts @@ -1,12 +1,12 @@ /** * @function jsonStringComparison - * @param {object | undefined} a - The first object to compare. - * @param {object | undefined} b - The second object to compare. + * @param {unknown} a - The first object to compare. + * @param {unknown} b - The second object to compare. * @returns {boolean} - Returns true if the JSON strings are identical. * @description - Compares two objects by converting them to JSON strings. * This is a JSON comparison and should only be used for simple objects. * Meaning no class instances can take part in this data. */ -export function jsonStringComparison(a: object | undefined, b: object | undefined): boolean { +export function jsonStringComparison(a: unknown, b: unknown): boolean { return JSON.stringify(a) === JSON.stringify(b); } From 4b50d2863107d77b79641e9fb8fc734600448107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 24 Feb 2025 19:48:45 +0100 Subject: [PATCH 35/57] sort properties when creating --- .../content-detail-workspace-base.ts | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts index 72ce8e0c938b..8e5d263e00e6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -731,24 +731,9 @@ export abstract class UmbContentDetailWorkspaceContextBase< } this._data.setPersisted(data); - console.log('setPersisted', data); let currentData = this._data.getCurrent(); - // TODO: fix sorting of properties, I think its the currentData.values that needs to be sorted. [NL] - /* - if (currentData) { - const persistedValueOrder = data.values; - // Sort values of currentData in the same order as persisted data: - const values = currentData.values.sort((a, b) => { - let aIndex = persistedValueOrder.findIndex((x) => x.alias === a.alias); - let bIndex = persistedValueOrder.findIndex((x) => x.alias === b.alias); - return aIndex - bIndex; - }); - currentData = { ...currentData, values }; - } - */ - const variantIdsIncludingInvariant = [...variantIds, UmbVariantId.CreateInvariant()]; // Retrieve a data set which only contains updates from the selected variants + invariant. [NL] @@ -759,7 +744,17 @@ export abstract class UmbContentDetailWorkspaceContextBase< variantIdsIncludingInvariant, ); - console.log('setCurrent', newCurrentData); + // Sort the values in the same order as the persisted data: + const persistedValues = data.values; + newCurrentData.values.sort(function (a, b) { + return persistedValues.indexOf(a) - persistedValues.indexOf(b); + }); + + // Sort the variants in the same order as the persisted data: + const persistedVariants = data.variants; + newCurrentData.variants.sort(function (a, b) { + return persistedVariants.indexOf(a) - persistedVariants.indexOf(b); + }); this._data.setCurrent(newCurrentData); const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); From 194a09c883544f02d76f793b4aa8f004b3baa892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 24 Feb 2025 19:51:08 +0100 Subject: [PATCH 36/57] refactor into setCurrentData --- .../content-detail-workspace-base.ts | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts index 8e5d263e00e6..dca45959c6f3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -719,6 +719,22 @@ export abstract class UmbContentDetailWorkspaceContextBase< } } + #setCurrentData(persistedData: DetailModelType, newCurrentData: DetailModelType) { + // Sort the values in the same order as the persisted data: + const persistedValues = persistedData.values; + newCurrentData.values.sort(function (a, b) { + return persistedValues.indexOf(a) - persistedValues.indexOf(b); + }); + + // Sort the variants in the same order as the persisted data: + const persistedVariants = persistedData.variants; + newCurrentData.variants.sort(function (a, b) { + return persistedVariants.indexOf(a) - persistedVariants.indexOf(b); + }); + + this._data.setCurrent(newCurrentData); + } + async #create(variantIds: Array, saveData: DetailModelType) { if (!this._detailRepository) throw new Error('Detail repository is not set'); @@ -743,19 +759,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< variantIds, variantIdsIncludingInvariant, ); - - // Sort the values in the same order as the persisted data: - const persistedValues = data.values; - newCurrentData.values.sort(function (a, b) { - return persistedValues.indexOf(a) - persistedValues.indexOf(b); - }); - - // Sort the variants in the same order as the persisted data: - const persistedVariants = data.variants; - newCurrentData.variants.sort(function (a, b) { - return persistedVariants.indexOf(a) - persistedVariants.indexOf(b); - }); - this._data.setCurrent(newCurrentData); + this.#setCurrentData(data, newCurrentData); const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); const event = new UmbRequestReloadChildrenOfEntityEvent({ @@ -788,7 +792,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< variantIds, variantIdsIncludingInvariant, ); - this._data.setCurrent(newCurrentData); + this.#setCurrentData(data, newCurrentData); const unique = this.getUnique()!; const entityType = this.getEntityType(); From d09f3fd90a1d8eeea118c74145bf54c880274cdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 24 Feb 2025 20:32:25 +0100 Subject: [PATCH 37/57] refactor to content data manager --- .../content/manager/content-data-manager.ts | 21 +++++++++++++++++++ .../content-detail-workspace-base.ts | 20 ++---------------- 2 files changed, 23 insertions(+), 18 deletions(-) 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 d8d375eb4c7e..9535ef8113fc 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 @@ -19,6 +19,27 @@ export class UmbContentWorkspaceDataManager< this.#variantScaffold = variantScaffold; } + override setCurrent(data: ModelType | undefined): void { + if (data) { + const persistedData = this.getPersisted(); + if (persistedData) { + // Sort the values in the same order as the persisted data: + const persistedValues = persistedData.values; + data.values.sort(function (a, b) { + return persistedValues.indexOf(a) - persistedValues.indexOf(b); + }); + + // Sort the variants in the same order as the persisted data: + const persistedVariants = persistedData.variants; + data.variants.sort(function (a, b) { + return persistedVariants.indexOf(a) - persistedVariants.indexOf(b); + }); + } + } + + super.setCurrent(data); + } + /** * Sets the variant scaffold data * @param {ModelVariantType} variantScaffold The variant scaffold data diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts index dca45959c6f3..5b99c84ce7ac 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -719,22 +719,6 @@ export abstract class UmbContentDetailWorkspaceContextBase< } } - #setCurrentData(persistedData: DetailModelType, newCurrentData: DetailModelType) { - // Sort the values in the same order as the persisted data: - const persistedValues = persistedData.values; - newCurrentData.values.sort(function (a, b) { - return persistedValues.indexOf(a) - persistedValues.indexOf(b); - }); - - // Sort the variants in the same order as the persisted data: - const persistedVariants = persistedData.variants; - newCurrentData.variants.sort(function (a, b) { - return persistedVariants.indexOf(a) - persistedVariants.indexOf(b); - }); - - this._data.setCurrent(newCurrentData); - } - async #create(variantIds: Array, saveData: DetailModelType) { if (!this._detailRepository) throw new Error('Detail repository is not set'); @@ -759,7 +743,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< variantIds, variantIdsIncludingInvariant, ); - this.#setCurrentData(data, newCurrentData); + this._data.setCurrent(newCurrentData); const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); const event = new UmbRequestReloadChildrenOfEntityEvent({ @@ -792,7 +776,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< variantIds, variantIdsIncludingInvariant, ); - this.#setCurrentData(data, newCurrentData); + this._data.setCurrent(newCurrentData); const unique = this.getUnique()!; const entityType = this.getEntityType(); From af96ad4dbe83370ed8e66211402bdf6379d59a9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 24 Feb 2025 20:36:49 +0100 Subject: [PATCH 38/57] Keep order from persisted data --- .../content/manager/content-data-manager.ts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) 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 d8d375eb4c7e..9535ef8113fc 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 @@ -19,6 +19,27 @@ export class UmbContentWorkspaceDataManager< this.#variantScaffold = variantScaffold; } + override setCurrent(data: ModelType | undefined): void { + if (data) { + const persistedData = this.getPersisted(); + if (persistedData) { + // Sort the values in the same order as the persisted data: + const persistedValues = persistedData.values; + data.values.sort(function (a, b) { + return persistedValues.indexOf(a) - persistedValues.indexOf(b); + }); + + // Sort the variants in the same order as the persisted data: + const persistedVariants = persistedData.variants; + data.variants.sort(function (a, b) { + return persistedVariants.indexOf(a) - persistedVariants.indexOf(b); + }); + } + } + + super.setCurrent(data); + } + /** * Sets the variant scaffold data * @param {ModelVariantType} variantScaffold The variant scaffold data From 7e42a50e02094763771684ff884b8c2cf9def031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 24 Feb 2025 20:49:47 +0100 Subject: [PATCH 39/57] refactor to also cover updateCurrent --- .../content/manager/content-data-manager.ts | 32 ++++++------------- .../content/manager/element-data-manager.ts | 11 ++++++- .../entity/entity-workspace-data-manager.ts | 16 ++++++++++ 3 files changed, 35 insertions(+), 24 deletions(-) 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 9535ef8113fc..90975395d25f 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 @@ -19,25 +19,13 @@ export class UmbContentWorkspaceDataManager< this.#variantScaffold = variantScaffold; } - override setCurrent(data: ModelType | undefined): void { - if (data) { - const persistedData = this.getPersisted(); - if (persistedData) { - // Sort the values in the same order as the persisted data: - const persistedValues = persistedData.values; - data.values.sort(function (a, b) { - return persistedValues.indexOf(a) - persistedValues.indexOf(b); - }); - - // Sort the variants in the same order as the persisted data: - const persistedVariants = persistedData.variants; - data.variants.sort(function (a, b) { - return persistedVariants.indexOf(a) - persistedVariants.indexOf(b); - }); - } - } - - super.setCurrent(data); + protected override _sortCurrentData(persistedData: ModelType, currentData: Partial) { + super._sortCurrentData(persistedData, currentData); + // Sort the variants in the same order as the persisted data: + const persistedVariants = persistedData.variants; + currentData.variants?.sort(function (a, b) { + return persistedVariants.indexOf(a) - persistedVariants.indexOf(b); + }); } /** @@ -71,8 +59,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(); @@ -86,8 +73,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 dfac318c5d8f..6a954e4d7bd8 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 @@ -11,6 +11,15 @@ export class UmbElementWorkspaceDataManager) { + super._sortCurrentData(persistedData, currentData); + // Sort the values in the same order as the persisted data: + const persistedValues = persistedData.values; + currentData.values?.sort(function (a, b) { + return persistedValues.indexOf(a) - persistedValues.indexOf(b); + }); + } + #updateLock = 0; initiatePropertyValueChange() { this.#updateLock++; @@ -54,7 +63,7 @@ export class UmbElementWorkspaceDataManager */ public readonly current = this._current.asObservable(); + protected _sortCurrentData(persistedData: ModelType, currentData: Partial) { + // do nothing. + } + /** * Gets persisted data * @returns {(ModelType | undefined)} @@ -81,6 +85,12 @@ export class UmbEntityWorkspaceDataManager * @memberof UmbSubmittableWorkspaceDataManager */ setCurrent(data: ModelType | undefined) { + if (data) { + const persistedData = this._persisted.getValue(); + if (persistedData) { + this._sortCurrentData(persistedData, data); + } + } this._current.setValue(data); } @@ -90,6 +100,12 @@ export class UmbEntityWorkspaceDataManager * @memberof UmbSubmittableWorkspaceDataManager */ updateCurrent(partialData: Partial) { + if (partialData) { + const persistedData = this._persisted.getValue(); + if (persistedData) { + this._sortCurrentData(persistedData, partialData); + } + } this._current.update(partialData); } From 3c11ec3218ba24618b8f693118696f10577d7d8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 24 Feb 2025 20:52:38 +0100 Subject: [PATCH 40/57] add type safety by making persisted partial as well --- .../core/content/manager/content-data-manager.ts | 10 ++++++---- .../core/content/manager/element-data-manager.ts | 10 ++++++---- .../workspace/entity/entity-workspace-data-manager.ts | 2 +- 3 files changed, 13 insertions(+), 9 deletions(-) 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 90975395d25f..55073de8ffab 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 @@ -19,13 +19,15 @@ export class UmbContentWorkspaceDataManager< this.#variantScaffold = variantScaffold; } - protected override _sortCurrentData(persistedData: ModelType, currentData: Partial) { + protected override _sortCurrentData(persistedData: Partial, currentData: Partial) { super._sortCurrentData(persistedData, currentData); // Sort the variants in the same order as the persisted data: const persistedVariants = persistedData.variants; - currentData.variants?.sort(function (a, b) { - return persistedVariants.indexOf(a) - persistedVariants.indexOf(b); - }); + if (persistedVariants) { + currentData.variants?.sort(function (a, b) { + return persistedVariants.indexOf(a) - persistedVariants.indexOf(b); + }); + } } /** 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 6a954e4d7bd8..ba4fdf865cb8 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 @@ -11,13 +11,15 @@ export class UmbElementWorkspaceDataManager) { + protected override _sortCurrentData(persistedData: Partial, currentData: Partial) { super._sortCurrentData(persistedData, currentData); // Sort the values in the same order as the persisted data: const persistedValues = persistedData.values; - currentData.values?.sort(function (a, b) { - return persistedValues.indexOf(a) - persistedValues.indexOf(b); - }); + if (persistedValues) { + currentData.values?.sort(function (a, b) { + return persistedValues.indexOf(a) - persistedValues.indexOf(b); + }); + } } #updateLock = 0; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity/entity-workspace-data-manager.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity/entity-workspace-data-manager.ts index 736313b0f3ef..9747442b26d2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity/entity-workspace-data-manager.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity/entity-workspace-data-manager.ts @@ -28,7 +28,7 @@ export class UmbEntityWorkspaceDataManager */ public readonly current = this._current.asObservable(); - protected _sortCurrentData(persistedData: ModelType, currentData: Partial) { + protected _sortCurrentData(persistedData: Partial, currentData: Partial) { // do nothing. } From aceebd31d500723404afc9e0eb9825ea3161b895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 24 Feb 2025 20:59:40 +0100 Subject: [PATCH 41/57] lint corrections --- .../packages/core/property/property-value-preset/index.ts | 2 +- .../property-value-preset-builder.controller.ts | 6 +++--- .../property-value-preset-variant-builder.controller.ts | 6 +++--- .../packages/core/property/property-value-preset/types.ts | 2 +- .../slider/property-editor-ui-slider.element.ts | 2 +- .../property-editors/slider/property-value-preset.Slider.ts | 2 +- .../toggle/property-editor-ui-toggle.element.ts | 2 +- .../toggle/property-value-preset.TrueFalse.ts | 2 +- .../user-group/user-group-workspace-editor.element.ts | 4 +++- 9 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/index.ts index 9fc6259f578b..4218dccc1c42 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/index.ts @@ -1,4 +1,4 @@ -export * from './property-value-preset.extension.js'; +export type * from './property-value-preset.extension.js'; export * from './property-value-preset-builder.controller.js'; export * from './property-value-preset-variant-builder.controller.js'; export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts index 95c2e2eb49dc..041de9763c55 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts @@ -1,7 +1,4 @@ import type { UmbPropertyValueData, UmbPropertyValueDataPotentiallyWithEditorAlias } from '../index.js'; -import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; -import { createExtensionApi } from '@umbraco-cms/backoffice/extension-api'; -import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import type { ManifestPropertyValuePreset, UmbPropertyTypePresetModel, @@ -9,6 +6,9 @@ import type { UmbPropertyValuePresetApi, UmbPropertyValuePresetApiCallArgs, } from './types.js'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import { createExtensionApi } from '@umbraco-cms/backoffice/extension-api'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; const EMPTY_CALL_ARGS = Object.freeze({}); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts index 3f199bcdfe31..ebaeaf98cf71 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts @@ -1,11 +1,11 @@ -import type { UmbElementValueModel } from '@umbraco-cms/backoffice/content'; +import { UmbVariantId } from '../../variant/variant-id.class.js'; import { UmbPropertyValuePresetBuilderController } from './property-value-preset-builder.controller.js'; import type { UmbPropertyTypePresetModel, UmbPropertyTypePresetWithSchemaAliasModel, UmbPropertyValuePresetApi, } from './types.js'; -import { UmbVariantId } from '../../variant/variant-id.class.js'; +import type { UmbElementValueModel } from '@umbraco-cms/backoffice/content'; type ReturnType = UmbElementValueModel; @@ -26,7 +26,7 @@ export class UmbPropertyValuePresetVariantBuilderController extends UmbPropertyV apis: Array, propertyType: UmbPropertyTypePresetModel | UmbPropertyTypePresetWithSchemaAliasModel, ): Promise> { - let values: Array = []; + const values: Array = []; if (propertyType.typeArgs.varyBySegment && propertyType.typeArgs.varyByCulture) { if (this.#cultures.length === 0) { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts index 67e1b3f71495..6e3a8d3026b0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts @@ -1,6 +1,6 @@ +import type { UmbVariantId } from '../../variant/variant-id.class.js'; import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; -import type { UmbVariantId } from '../../variant/variant-id.class.js'; export type * from './property-value-preset.extension.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts index f01fdc75dcda..d27ff1405b49 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts @@ -1,3 +1,4 @@ +import type { UmbPropertyEditorUISliderValue } from './types.js'; import type { UmbInputSliderElement } from '@umbraco-cms/backoffice/components'; import { customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; @@ -7,7 +8,6 @@ import type { UmbPropertyEditorConfigCollection, UmbPropertyEditorUiElement, } from '@umbraco-cms/backoffice/property-editor'; -import type { UmbPropertyEditorUISliderValue } from './types.js'; /** * @element umb-property-editor-ui-slider diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts index d98347ee8f8a..20aeb9d3923b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts @@ -1,6 +1,6 @@ +import type { UmbPropertyEditorUISliderValue } from './types.js'; import type { UmbPropertyValuePresetApi } from '@umbraco-cms/backoffice/property'; import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; -import type { UmbPropertyEditorUISliderValue } from './types.js'; export class UmbPropertyValuePresetSliderApi implements UmbPropertyValuePresetApi diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts index 9bc790b20fec..6e814da4a26b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts @@ -1,3 +1,4 @@ +import type { UmbPropertyEditorUIToggleValue } from './types.js'; import type { UmbInputToggleElement } from '@umbraco-cms/backoffice/components'; import { customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; @@ -7,7 +8,6 @@ import type { UmbPropertyEditorUiElement, } from '@umbraco-cms/backoffice/property-editor'; import { UMB_VALIDATION_FALSE_LOCALIZATION_KEY, UmbFormControlMixin } from '@umbraco-cms/backoffice/validation'; -import type { UmbPropertyEditorUIToggleValue } from './types'; @customElement('umb-property-editor-ui-toggle') export class UmbPropertyEditorUIToggleElement diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts index 1dd35919f4ce..d3cbfc60e1ec 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts @@ -1,6 +1,6 @@ +import type { UmbPropertyEditorUIToggleValue } from './types.js'; import type { UmbPropertyValuePresetApi } from '@umbraco-cms/backoffice/property'; import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; -import type { UmbPropertyEditorUIToggleValue } from './types.js'; export class UmbPropertyValuePresetTrueFalseApi implements UmbPropertyValuePresetApi diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/user-group-workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/user-group-workspace-editor.element.ts index aae6d579e995..e44a4a6a7cb1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/user-group-workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group/user-group-workspace-editor.element.ts @@ -244,7 +244,9 @@ export class UmbUserGroupWorkspaceEditorElement extends UmbLitElement {
- +
From 36dcb5733fadc06532c909cb49a3497209f4d195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 24 Feb 2025 21:40:08 +0100 Subject: [PATCH 42/57] preset for markdown --- .../input-markdown.element.ts | 4 +++- .../property-editor-ui-markdown-editor.element.ts | 9 ++++----- .../property-value-preset.MarkdownEditor.ts | 14 ++++++++++++++ .../property-editors/markdown-editor/types.ts | 1 + 4 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-value-preset.MarkdownEditor.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/types.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/components/input-markdown-editor/input-markdown.element.ts b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/components/input-markdown-editor/input-markdown.element.ts index b85eb539fcb7..f0a0f64d7ec5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/components/input-markdown-editor/input-markdown.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/components/input-markdown-editor/input-markdown.element.ts @@ -33,7 +33,9 @@ interface UmbMarkdownEditorAction extends monaco.editor.IActionDescriptor { * @fires change - when the value of the input changes */ @customElement('umb-input-markdown') -export class UmbInputMarkdownElement extends UmbFormControlMixin(UmbLitElement, '') { +export class UmbInputMarkdownElement extends UmbFormControlMixin( + UmbLitElement, +) { protected override getFormElement() { return this._codeEditor; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-editor-ui-markdown-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-editor-ui-markdown-editor.element.ts index a49d71053bc2..4316d8014bca 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-editor-ui-markdown-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-editor-ui-markdown-editor.element.ts @@ -10,14 +10,13 @@ import type { UUIModalSidebarSize } from '@umbraco-cms/backoffice/external/uui'; import '../../components/input-markdown-editor/index.js'; -const elementName = 'umb-property-editor-ui-markdown-editor'; /** * @element umb-property-editor-ui-markdown-editor */ -@customElement(elementName) +@customElement('umb-property-editor-ui-markdown-editor') export class UmbPropertyEditorUIMarkdownEditorElement extends UmbLitElement implements UmbPropertyEditorUiElement { @property() - value = ''; + value?: string; /** * Sets the input to readonly mode, meaning value cannot be changed but still able to read and select its content. @@ -55,7 +54,7 @@ export class UmbPropertyEditorUIMarkdownEditorElement extends UmbLitElement impl override render() { return html` { + async processValue(value: undefined | UmbPropertyEditorUIMarkdownValue, config: UmbPropertyEditorConfig) { + const defaultValue = config.find((x) => x.alias === 'defaultvalue')?.value as string | undefined; + return value !== undefined ? value : defaultValue; + } + + destroy(): void {} +} + +export { UmbPropertyValuePresetMarkdownApi as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/types.ts b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/types.ts new file mode 100644 index 000000000000..f7e21d5a0539 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/types.ts @@ -0,0 +1 @@ +export type UmbPropertyEditorUIMarkdownValue = string | undefined; From c253a332ffb0b709903c0419e90a9949987136cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 24 Feb 2025 21:45:44 +0100 Subject: [PATCH 43/57] refactor to work with frozen data --- .../content/manager/content-data-manager.ts | 19 +++++++++++++------ .../content/manager/element-data-manager.ts | 19 +++++++++++++------ .../entity/entity-workspace-data-manager.ts | 10 +++++++--- 3 files changed, 33 insertions(+), 15 deletions(-) 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 55073de8ffab..70a79c482186 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 @@ -19,15 +19,22 @@ export class UmbContentWorkspaceDataManager< this.#variantScaffold = variantScaffold; } - protected override _sortCurrentData(persistedData: Partial, currentData: Partial) { - super._sortCurrentData(persistedData, currentData); + 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?.sort(function (a, b) { - return persistedVariants.indexOf(a) - persistedVariants.indexOf(b); - }); + if (persistedVariants && currentData.variants) { + return { + ...currentData, + variants: [...currentData.variants].sort(function (a, b) { + return persistedVariants.indexOf(a) - persistedVariants.indexOf(b); + }), + }; } + return currentData; } /** 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 ba4fdf865cb8..805e752df540 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 @@ -11,15 +11,22 @@ export class UmbElementWorkspaceDataManager, currentData: Partial) { - super._sortCurrentData(persistedData, currentData); + protected override _sortCurrentData = 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?.sort(function (a, b) { - return persistedValues.indexOf(a) - persistedValues.indexOf(b); - }); + if (persistedValues && currentData.values) { + return { + ...currentData, + values: [...currentData.values].sort(function (a, b) { + return persistedValues.indexOf(a) - persistedValues.indexOf(b); + }), + }; } + return currentData; } #updateLock = 0; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity/entity-workspace-data-manager.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity/entity-workspace-data-manager.ts index 9747442b26d2..46dc375e3e2f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity/entity-workspace-data-manager.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity/entity-workspace-data-manager.ts @@ -28,8 +28,12 @@ export class UmbEntityWorkspaceDataManager */ public readonly current = this._current.asObservable(); - protected _sortCurrentData(persistedData: Partial, currentData: Partial) { + protected _sortCurrentData = Partial>( + persistedData: Partial, + currentData: GivenType, + ): GivenType { // do nothing. + return currentData; } /** @@ -88,7 +92,7 @@ export class UmbEntityWorkspaceDataManager if (data) { const persistedData = this._persisted.getValue(); if (persistedData) { - this._sortCurrentData(persistedData, data); + data = this._sortCurrentData(persistedData, data); } } this._current.setValue(data); @@ -103,7 +107,7 @@ export class UmbEntityWorkspaceDataManager if (partialData) { const persistedData = this._persisted.getValue(); if (persistedData) { - this._sortCurrentData(persistedData, partialData); + partialData = this._sortCurrentData(persistedData, partialData); } } this._current.update(partialData); From 883757e48139a674e22b90c677b6059ab8a0f7fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 24 Feb 2025 21:58:32 +0100 Subject: [PATCH 44/57] implement for MarkDown --- .../property-value-preset-variant-builder.controller.ts | 6 +++--- .../packages/core/property/property-value-preset/types.ts | 4 ++-- .../property-editors/markdown-editor/manifests.ts | 7 +++++++ .../property-editor-ui-markdown-editor.element.ts | 6 ------ .../property-value-preset.MarkdownEditor.ts | 2 +- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts index ebaeaf98cf71..405852840d73 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts @@ -28,7 +28,7 @@ export class UmbPropertyValuePresetVariantBuilderController extends UmbPropertyV ): Promise> { const values: Array = []; - if (propertyType.typeArgs.varyBySegment && propertyType.typeArgs.varyByCulture) { + if (propertyType.typeArgs.variesBySegment && propertyType.typeArgs.variesByCulture) { if (this.#cultures.length === 0) { throw new Error('Cultures must be set when varying by culture.'); } @@ -45,7 +45,7 @@ export class UmbPropertyValuePresetVariantBuilderController extends UmbPropertyV } } } - } else if (propertyType.typeArgs.varyByCulture) { + } else if (propertyType.typeArgs.variesByCulture) { if (this.#cultures.length === 0) { throw new Error('Cultures must be set when varying by culture.'); } @@ -60,7 +60,7 @@ export class UmbPropertyValuePresetVariantBuilderController extends UmbPropertyV values.push(value); } } - } else if (propertyType.typeArgs.varyBySegment) { + } else if (propertyType.typeArgs.variesBySegment) { for (const segment of this.#segments) { const value = await this._generatePropertyValue(apis, propertyType, { variantId: new UmbVariantId(null, segment), diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts index 6e3a8d3026b0..c75dcf642979 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts @@ -30,8 +30,8 @@ export interface UmbPropertyTypePresetModel { export interface UmbPropertyTypePresetModelTypeModel { isMandatory?: boolean; - varyByCulture?: boolean; - varyBySegment?: boolean; + variesByCulture?: boolean; + variesBySegment?: boolean; } export interface UmbPropertyValuePresetApiCallArgs { variantId?: UmbVariantId; diff --git a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/manifests.ts index 11be0a8d8764..0fe159fa584b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/manifests.ts @@ -1,6 +1,13 @@ import { manifest as schemaManifest } from './Umbraco.MarkdownEditor.js'; export const manifests: Array = [ + { + type: 'propertyValuePreset', + forPropertyEditorSchemaAlias: 'Umbraco.MarkdownEditor', + alias: 'Umbraco.MarkdownEditor', + name: 'Markdown Editor Property Value Preset', + api: () => import('./property-value-preset.MarkdownEditor.js'), + }, { type: 'propertyEditorUi', alias: 'Umb.PropertyEditorUi.MarkdownEditor', diff --git a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-editor-ui-markdown-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-editor-ui-markdown-editor.element.ts index 4316d8014bca..3c54910cd6fb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-editor-ui-markdown-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-editor-ui-markdown-editor.element.ts @@ -38,12 +38,6 @@ export class UmbPropertyEditorUIMarkdownEditorElement extends UmbLitElement impl this._preview = config.getValueByAlias('preview'); this._overlaySize = config.getValueByAlias('overlaySize') ?? 'small'; - - // TODO: To be removed once the "Property Value Presets" feature has been implemented. - const defaultValue = config.getValueByAlias('defaultValue'); - if (defaultValue && this.value === undefined) { - this.value = defaultValue; - } } #onChange(event: Event & { target: UmbInputMarkdownElement }) { diff --git a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-value-preset.MarkdownEditor.ts b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-value-preset.MarkdownEditor.ts index cf6bf4b44a8c..ef22afa4a3d1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-value-preset.MarkdownEditor.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-value-preset.MarkdownEditor.ts @@ -4,7 +4,7 @@ import type { UmbPropertyEditorUIMarkdownValue } from './types.js'; export class UmbPropertyValuePresetMarkdownApi implements UmbPropertyValuePresetApi { async processValue(value: undefined | UmbPropertyEditorUIMarkdownValue, config: UmbPropertyEditorConfig) { - const defaultValue = config.find((x) => x.alias === 'defaultvalue')?.value as string | undefined; + const defaultValue = config.find((x) => x.alias === 'defaultValue')?.value as string | undefined; return value !== undefined ? value : defaultValue; } From fe746e11fccff02b22211a80cb4149d4d6ba3006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 24 Feb 2025 22:05:55 +0100 Subject: [PATCH 45/57] compare based on object properties not object as a whole --- .../core/content/manager/content-data-manager.ts | 7 +++++-- .../core/content/manager/element-data-manager.ts | 11 +++++++++-- .../src/packages/core/variant/index.ts | 1 + .../src/packages/core/variant/types.ts | 5 +++++ .../src/packages/core/variant/variant-id.class.ts | 6 +----- .../core/variant/variant-object-compare.function.ts | 5 +++++ 6 files changed, 26 insertions(+), 9 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 70a79c482186..85b6ae51e80d 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, @@ -30,7 +30,10 @@ export class UmbContentWorkspaceDataManager< return { ...currentData, variants: [...currentData.variants].sort(function (a, b) { - return persistedVariants.indexOf(a) - persistedVariants.indexOf(b); + return ( + persistedVariants.findIndex((x) => umbVariantObjectCompare(x, a)) - + persistedVariants.findIndex((x) => umbVariantObjectCompare(x, b)) + ); }), }; } 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 805e752df540..623f99a2c42d 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 @@ -22,7 +26,10 @@ export class UmbElementWorkspaceDataManager valueObjectCompare(x, a)) - + persistedValues.findIndex((x) => valueObjectCompare(x, b)) + ); }), }; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/variant/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/variant/index.ts index 64906c41c026..5a6c69cbf2ec 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/variant/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/variant/index.ts @@ -1,2 +1,3 @@ export * from './variant-id.class.js'; +export * from './variant-object-compare.function.js'; export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/variant/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/variant/types.ts index 7b552fa22957..80444415e000 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/variant/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/variant/types.ts @@ -3,6 +3,11 @@ import type { UmbLanguageDetailModel } from '@umbraco-cms/backoffice/language'; import type { ScheduleRequestModel } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbPropertyValueData } from '@umbraco-cms/backoffice/property'; +export type UmbObjectWithVariantProperties = { + culture: string | null; + segment: string | null; +}; + export interface UmbVariantDataModel { culture: string | null; segment: string | null; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/variant/variant-id.class.ts b/src/Umbraco.Web.UI.Client/src/packages/core/variant/variant-id.class.ts index a6fdb62d198c..a8a2f4be60ea 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/variant/variant-id.class.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/variant/variant-id.class.ts @@ -1,9 +1,5 @@ import { UmbDeprecation } from '../utils/index.js'; - -export type UmbObjectWithVariantProperties = { - culture: string | null; - segment: string | null; -}; +import type { UmbObjectWithVariantProperties } from './types.js'; /** * diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/variant/variant-object-compare.function.ts b/src/Umbraco.Web.UI.Client/src/packages/core/variant/variant-object-compare.function.ts new file mode 100644 index 000000000000..546667db9df7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/variant/variant-object-compare.function.ts @@ -0,0 +1,5 @@ +import type { UmbObjectWithVariantProperties } from './types.js'; + +export function umbVariantObjectCompare(a: UmbObjectWithVariantProperties, b: UmbObjectWithVariantProperties): boolean { + return a.culture === b.culture && a.segment === b.segment; +} From e1778615c93ee82a87b31781037ae68ebc388a52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 24 Feb 2025 22:15:22 +0100 Subject: [PATCH 46/57] only update persisted data in regards to what was saved --- .../content-detail-workspace-base.ts | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts index 5b99c84ce7ac..e5bcd66792d4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -730,13 +730,20 @@ export abstract class UmbContentDetailWorkspaceContextBase< throw new Error('Error creating content'); } - this._data.setPersisted(data); - - let currentData = this._data.getCurrent(); - const variantIdsIncludingInvariant = [...variantIds, UmbVariantId.CreateInvariant()]; - // Retrieve a data set which only contains updates from the selected variants + invariant. [NL] + // Only update the variants that was chosen to be saved: + const persistedData = this._data.getCurrent(); + const newPersistedData = await new UmbMergeContentVariantDataController(this).process( + persistedData, + data, + variantIds, + variantIdsIncludingInvariant, + ); + this._data.setPersisted(newPersistedData); + + // Only update the variants that was chosen to be saved: + let currentData = this._data.getCurrent(); const newCurrentData = await new UmbMergeContentVariantDataController(this).process( currentData, data, @@ -764,12 +771,20 @@ export abstract class UmbContentDetailWorkspaceContextBase< throw new Error('Error saving content'); } - this._data.setPersisted(data); - // TODO: Only update the variants that was chosen to be saved: - const currentData = this._data.getCurrent(); - const variantIdsIncludingInvariant = [...variantIds, UmbVariantId.CreateInvariant()]; + // Only update the variants that was chosen to be saved: + const persistedData = this._data.getCurrent(); + const newPersistedData = await new UmbMergeContentVariantDataController(this).process( + persistedData, + data, + variantIds, + variantIdsIncludingInvariant, + ); + this._data.setPersisted(newPersistedData); + + // Only update the variants that was chosen to be saved: + const currentData = this._data.getCurrent(); const newCurrentData = await new UmbMergeContentVariantDataController(this).process( currentData, data, From 313e0b1ba3cbc55316085611b4dd688768585dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 24 Feb 2025 22:34:02 +0100 Subject: [PATCH 47/57] fix tests --- ...rty-value-preset-variant-builder.controller.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.test.ts index ddab1128e9e8..5a23a9a44d1e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.test.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.test.ts @@ -59,7 +59,7 @@ describe('UmbPropertyValuePresetVariantBuilderController', () => { alias: 'test', propertyEditorUiAlias: 'test-editor-ui', config: [], - typeArgs: { varyByCulture: true }, + typeArgs: { variesByCulture: true }, }, ]; @@ -81,7 +81,7 @@ describe('UmbPropertyValuePresetVariantBuilderController', () => { alias: 'test', propertyEditorUiAlias: 'test-editor-ui', config: [], - typeArgs: { varyByCulture: true }, + typeArgs: { variesByCulture: true }, }, ]; @@ -101,7 +101,7 @@ describe('UmbPropertyValuePresetVariantBuilderController', () => { alias: 'test', propertyEditorUiAlias: 'test-editor-ui', config: [], - typeArgs: { varyBySegment: true }, + typeArgs: { variesBySegment: true }, }, ]; @@ -128,7 +128,7 @@ describe('UmbPropertyValuePresetVariantBuilderController', () => { alias: 'test', propertyEditorUiAlias: 'test-editor-ui', config: [], - typeArgs: { varyBySegment: true }, + typeArgs: { variesBySegment: true }, }, ]; @@ -151,7 +151,7 @@ describe('UmbPropertyValuePresetVariantBuilderController', () => { alias: 'test', propertyEditorUiAlias: 'test-editor-ui', config: [], - typeArgs: { varyByCulture: true, varyBySegment: true }, + typeArgs: { variesByCulture: true, variesBySegment: true }, }, ]; From 0e077d4b3560b8617554d1bbe0e3a89044da1d10 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 25 Feb 2025 12:01:03 +0100 Subject: [PATCH 48/57] rename --- .../property-editors/slider/property-value-preset.Slider.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts index 20aeb9d3923b..99535cb2d24a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts @@ -2,7 +2,7 @@ import type { UmbPropertyEditorUISliderValue } from './types.js'; import type { UmbPropertyValuePresetApi } from '@umbraco-cms/backoffice/property'; import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; -export class UmbPropertyValuePresetSliderApi +export class UmbSliderPropertyValuePreset implements UmbPropertyValuePresetApi { async processValue(value: undefined | UmbPropertyEditorUISliderValue, config: UmbPropertyEditorConfig) { @@ -33,4 +33,4 @@ export class UmbPropertyValuePresetSliderApi destroy(): void {} } -export { UmbPropertyValuePresetSliderApi as api }; +export { UmbSliderPropertyValuePreset as api }; From 238bbb09ea4609e979efb914977995bb801a5691 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 25 Feb 2025 12:17:16 +0100 Subject: [PATCH 49/57] remove api from name --- .../property-value-preset-builder.controller.test.ts | 8 ++++---- .../property-value-preset-builder.controller.ts | 8 ++++---- ...operty-value-preset-variant-builder.controller.test.ts | 4 ++-- .../property-value-preset-variant-builder.controller.ts | 4 ++-- .../property-value-preset.extension.ts | 4 ++-- .../packages/core/property/property-value-preset/types.ts | 6 +++--- .../property-value-preset.MarkdownEditor.ts | 4 ++-- .../slider/property-value-preset.Slider.ts | 4 ++-- .../toggle/property-value-preset.TrueFalse.ts | 4 ++-- 9 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts index dfbbbb47e0bb..55a274478504 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.test.ts @@ -6,7 +6,7 @@ import type { ManifestPropertyValuePreset, UmbPropertyTypePresetModel, UmbPropertyTypePresetWithSchemaAliasModel, - UmbPropertyValuePresetApi, + UmbPropertyValuePreset, } from './types.js'; import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; import { UmbPropertyValuePresetBuilderController } from './property-value-preset-builder.controller.js'; @@ -17,7 +17,7 @@ export class UmbTestControllerHostElement extends UmbControllerHostElementMixin( // TODO: Write test with config, investigate oppertunity to retrieve Config Object, for an simpler DX. [NL] // Test with async APIs, espcially where the first one is slower than the last one. -export class TestPropertyValuePresetFirstApi implements UmbPropertyValuePresetApi { +export class TestPropertyValuePresetFirstApi implements UmbPropertyValuePreset { async processValue(value: undefined | string, config: UmbPropertyEditorConfig) { return value ? value + '_first' : 'first'; } @@ -25,7 +25,7 @@ export class TestPropertyValuePresetFirstApi implements UmbPropertyValuePresetAp destroy(): void {} } -export class TestPropertyValuePresetSecondApi implements UmbPropertyValuePresetApi { +export class TestPropertyValuePresetSecondApi implements UmbPropertyValuePreset { async processValue(value: undefined | string, config: UmbPropertyEditorConfig) { return value ? value + '_second' : 'second'; } @@ -33,7 +33,7 @@ export class TestPropertyValuePresetSecondApi implements UmbPropertyValuePresetA destroy(): void {} } -export class TestPropertyValuePresetAsyncApi implements UmbPropertyValuePresetApi { +export class TestPropertyValuePresetAsyncApi implements UmbPropertyValuePreset { async processValue(value: undefined | string, config: UmbPropertyEditorConfig) { await new Promise((resolve) => setTimeout(resolve, 10)); return value ? value + '_async' : 'async'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts index 041de9763c55..6f94a67dd08a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-builder.controller.ts @@ -3,7 +3,7 @@ import type { ManifestPropertyValuePreset, UmbPropertyTypePresetModel, UmbPropertyTypePresetWithSchemaAliasModel, - UmbPropertyValuePresetApi, + UmbPropertyValuePreset, UmbPropertyValuePresetApiCallArgs, } from './types.js'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; @@ -56,7 +56,7 @@ export class UmbPropertyValuePresetBuilderController< const apis = (await Promise.all(manifests.map((x) => createExtensionApi(this, x)))).filter( (x) => x !== undefined, - ) as Array; + ) as Array; const result = await this._generatePropertyValues(apis, propertyType); @@ -68,7 +68,7 @@ export class UmbPropertyValuePresetBuilderController< }; protected async _generatePropertyValues( - apis: Array, + apis: Array, propertyType: UmbPropertyTypePresetModel | UmbPropertyTypePresetWithSchemaAliasModel, ): Promise> { const property = await this._generatePropertyValue(apis, propertyType, EMPTY_CALL_ARGS); @@ -76,7 +76,7 @@ export class UmbPropertyValuePresetBuilderController< } protected async _generatePropertyValue( - apis: Array, + apis: Array, propertyType: UmbPropertyTypePresetModel | UmbPropertyTypePresetWithSchemaAliasModel, callArgs: UmbPropertyValuePresetApiCallArgs, ): Promise { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.test.ts index 5a23a9a44d1e..74f04d849eff 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.test.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.test.ts @@ -7,7 +7,7 @@ import type { UmbPropertyTypePresetModel, UmbPropertyTypePresetModelTypeModel, UmbPropertyTypePresetWithSchemaAliasModel, - UmbPropertyValuePresetApi, + UmbPropertyValuePreset, UmbPropertyValuePresetApiCallArgs, } from './types.js'; import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; @@ -17,7 +17,7 @@ import { UmbPropertyValuePresetVariantBuilderController } from './property-value export class UmbTestControllerHostElement extends UmbControllerHostElementMixin(HTMLElement) {} // Test with async APIs, espcially where the first one is slower than the last one. -export class TestPropertyValuePresetFirstApi implements UmbPropertyValuePresetApi { +export class TestPropertyValuePresetFirstApi implements UmbPropertyValuePreset { async processValue( value: undefined | string, config: UmbPropertyEditorConfig, diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts index 405852840d73..ab5a4aa358fc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset-variant-builder.controller.ts @@ -3,7 +3,7 @@ import { UmbPropertyValuePresetBuilderController } from './property-value-preset import type { UmbPropertyTypePresetModel, UmbPropertyTypePresetWithSchemaAliasModel, - UmbPropertyValuePresetApi, + UmbPropertyValuePreset, } from './types.js'; import type { UmbElementValueModel } from '@umbraco-cms/backoffice/content'; @@ -23,7 +23,7 @@ export class UmbPropertyValuePresetVariantBuilderController extends UmbPropertyV } protected override async _generatePropertyValues( - apis: Array, + apis: Array, propertyType: UmbPropertyTypePresetModel | UmbPropertyTypePresetWithSchemaAliasModel, ): Promise> { const values: Array = []; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset.extension.ts index ad0341524fa3..88813e393017 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/property-value-preset.extension.ts @@ -1,7 +1,7 @@ -import type { UmbPropertyValuePresetApi } from './types.js'; +import type { UmbPropertyValuePreset } from './types.js'; import type { ManifestApi } from '@umbraco-cms/backoffice/extension-api'; -export interface ManifestPropertyValuePreset extends ManifestApi> { +export interface ManifestPropertyValuePreset extends ManifestApi> { type: 'propertyValuePreset'; forPropertyEditorSchemaAlias?: string; forPropertyEditorUiAlias?: string; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts index c75dcf642979..de87eed76680 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-value-preset/types.ts @@ -4,14 +4,14 @@ import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; export type * from './property-value-preset.extension.js'; -export interface UmbPropertyValuePresetApi< +export interface UmbPropertyValuePreset< ValueType = unknown, ConfigType extends UmbPropertyEditorConfig = UmbPropertyEditorConfig, > extends UmbApi { - processValue: UmbPropertyValuePresetApiValuesProcessor; + processValue: UmbPropertyValuePresetValuesProcessor; } -export type UmbPropertyValuePresetApiValuesProcessor< +export type UmbPropertyValuePresetValuesProcessor< ValueType = unknown, ConfigType extends UmbPropertyEditorConfig = UmbPropertyEditorConfig, > = ( diff --git a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-value-preset.MarkdownEditor.ts b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-value-preset.MarkdownEditor.ts index ef22afa4a3d1..ab42c689921f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-value-preset.MarkdownEditor.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-value-preset.MarkdownEditor.ts @@ -1,8 +1,8 @@ -import type { UmbPropertyValuePresetApi } from '@umbraco-cms/backoffice/property'; +import type { UmbPropertyValuePreset } from '@umbraco-cms/backoffice/property'; import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; import type { UmbPropertyEditorUIMarkdownValue } from './types.js'; -export class UmbPropertyValuePresetMarkdownApi implements UmbPropertyValuePresetApi { +export class UmbPropertyValuePresetMarkdownApi implements UmbPropertyValuePreset { async processValue(value: undefined | UmbPropertyEditorUIMarkdownValue, config: UmbPropertyEditorConfig) { const defaultValue = config.find((x) => x.alias === 'defaultValue')?.value as string | undefined; return value !== undefined ? value : defaultValue; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts index 99535cb2d24a..079b41f2c172 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts @@ -1,9 +1,9 @@ import type { UmbPropertyEditorUISliderValue } from './types.js'; -import type { UmbPropertyValuePresetApi } from '@umbraco-cms/backoffice/property'; +import type { UmbPropertyValuePreset } from '@umbraco-cms/backoffice/property'; import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; export class UmbSliderPropertyValuePreset - implements UmbPropertyValuePresetApi + implements UmbPropertyValuePreset { async processValue(value: undefined | UmbPropertyEditorUISliderValue, config: UmbPropertyEditorConfig) { const enableRange = Boolean(config.find((x) => x.alias === 'enableRange') ?? false); diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts index d3cbfc60e1ec..8d03cc96f48c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts @@ -1,9 +1,9 @@ import type { UmbPropertyEditorUIToggleValue } from './types.js'; -import type { UmbPropertyValuePresetApi } from '@umbraco-cms/backoffice/property'; +import type { UmbPropertyValuePreset } from '@umbraco-cms/backoffice/property'; import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; export class UmbPropertyValuePresetTrueFalseApi - implements UmbPropertyValuePresetApi + implements UmbPropertyValuePreset { async processValue(value: undefined | UmbPropertyEditorUIToggleValue, config: UmbPropertyEditorConfig) { const initialState = (config.find((x) => x.alias === 'default')?.value as boolean | undefined) ?? false; From 3749afde2cc76e6ceb7c9b9c68276ee0e59e918c Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 25 Feb 2025 12:20:50 +0100 Subject: [PATCH 50/57] rename class --- .../toggle/property-value-preset.TrueFalse.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts index 8d03cc96f48c..317f12a22b7d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts @@ -2,7 +2,7 @@ import type { UmbPropertyEditorUIToggleValue } from './types.js'; import type { UmbPropertyValuePreset } from '@umbraco-cms/backoffice/property'; import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; -export class UmbPropertyValuePresetTrueFalseApi +export class UmbTrueFalsePropertyValuePreset implements UmbPropertyValuePreset { async processValue(value: undefined | UmbPropertyEditorUIToggleValue, config: UmbPropertyEditorConfig) { @@ -13,4 +13,4 @@ export class UmbPropertyValuePresetTrueFalseApi destroy(): void {} } -export { UmbPropertyValuePresetTrueFalseApi as api }; +export { UmbTrueFalsePropertyValuePreset as api }; From a4db51e2ed35a41981601f32fad8e1830f8d985f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 25 Feb 2025 12:27:49 +0100 Subject: [PATCH 51/57] rename --- .../markdown-editor/property-value-preset.MarkdownEditor.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-value-preset.MarkdownEditor.ts b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-value-preset.MarkdownEditor.ts index ab42c689921f..723485f2ad3e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-value-preset.MarkdownEditor.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-value-preset.MarkdownEditor.ts @@ -2,7 +2,7 @@ import type { UmbPropertyValuePreset } from '@umbraco-cms/backoffice/property'; import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; import type { UmbPropertyEditorUIMarkdownValue } from './types.js'; -export class UmbPropertyValuePresetMarkdownApi implements UmbPropertyValuePreset { +export class UmbMarkdownPropertyValuePreset implements UmbPropertyValuePreset { async processValue(value: undefined | UmbPropertyEditorUIMarkdownValue, config: UmbPropertyEditorConfig) { const defaultValue = config.find((x) => x.alias === 'defaultValue')?.value as string | undefined; return value !== undefined ? value : defaultValue; @@ -11,4 +11,4 @@ export class UmbPropertyValuePresetMarkdownApi implements UmbPropertyValuePreset destroy(): void {} } -export { UmbPropertyValuePresetMarkdownApi as api }; +export { UmbMarkdownPropertyValuePreset as api }; From a46ff843ddbf489fcadf895126eeb66de4ca9732 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 25 Feb 2025 12:30:45 +0100 Subject: [PATCH 52/57] rename --- .../markdown-editor/property-value-preset.MarkdownEditor.ts | 6 +++--- .../property-editors/markdown-editor/types.ts | 2 +- .../slider/property-editor-ui-slider.element.ts | 4 ++-- .../property-editors/slider/property-value-preset.Slider.ts | 6 +++--- .../src/packages/property-editors/slider/types.ts | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-value-preset.MarkdownEditor.ts b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-value-preset.MarkdownEditor.ts index 723485f2ad3e..95951de39183 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-value-preset.MarkdownEditor.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-value-preset.MarkdownEditor.ts @@ -1,9 +1,9 @@ import type { UmbPropertyValuePreset } from '@umbraco-cms/backoffice/property'; import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; -import type { UmbPropertyEditorUIMarkdownValue } from './types.js'; +import type { UmbMarkdownPropertyEditorUiValue } from './types.js'; -export class UmbMarkdownPropertyValuePreset implements UmbPropertyValuePreset { - async processValue(value: undefined | UmbPropertyEditorUIMarkdownValue, config: UmbPropertyEditorConfig) { +export class UmbMarkdownPropertyValuePreset implements UmbPropertyValuePreset { + async processValue(value: undefined | UmbMarkdownPropertyEditorUiValue, config: UmbPropertyEditorConfig) { const defaultValue = config.find((x) => x.alias === 'defaultValue')?.value as string | undefined; return value !== undefined ? value : defaultValue; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/types.ts b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/types.ts index f7e21d5a0539..10e84cbc70c0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/types.ts @@ -1 +1 @@ -export type UmbPropertyEditorUIMarkdownValue = string | undefined; +export type UmbMarkdownPropertyEditorUiValue = string | undefined; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts index d27ff1405b49..f61e4e83b624 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts @@ -1,4 +1,4 @@ -import type { UmbPropertyEditorUISliderValue } from './types.js'; +import type { UmbSliderPropertyEditorUiValue } from './types.js'; import type { UmbInputSliderElement } from '@umbraco-cms/backoffice/components'; import { customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; @@ -15,7 +15,7 @@ import type { @customElement('umb-property-editor-ui-slider') export class UmbPropertyEditorUISliderElement extends UmbLitElement implements UmbPropertyEditorUiElement { @property({ type: Object }) - value: UmbPropertyEditorUISliderValue | undefined; + value: UmbSliderPropertyEditorUiValue | undefined; /** * Sets the input to readonly mode, meaning value cannot be changed but still able to read and select its content. diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts index 079b41f2c172..175915c4c15a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts @@ -1,11 +1,11 @@ -import type { UmbPropertyEditorUISliderValue } from './types.js'; +import type { UmbSliderPropertyEditorUiValue } from './types.js'; import type { UmbPropertyValuePreset } from '@umbraco-cms/backoffice/property'; import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; export class UmbSliderPropertyValuePreset - implements UmbPropertyValuePreset + implements UmbPropertyValuePreset { - async processValue(value: undefined | UmbPropertyEditorUISliderValue, config: UmbPropertyEditorConfig) { + async processValue(value: undefined | UmbSliderPropertyEditorUiValue, config: UmbPropertyEditorConfig) { const enableRange = Boolean(config.find((x) => x.alias === 'enableRange') ?? false); /* diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/types.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/types.ts index 127729b2f0a8..3d6d1fd39aff 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/types.ts @@ -1,6 +1,6 @@ -export type UmbPropertyEditorUISliderValue = { from: number; to: number } | undefined; +export type UmbSliderPropertyEditorUiValue = { from: number; to: number } | undefined; /** * @deprecated this type will be removed in v.17.0, use `UmbPropertyEditorUISliderValue` instead */ -export type UmbSliderValue = UmbPropertyEditorUISliderValue; +export type UmbSliderValue = UmbSliderPropertyEditorUiValue; From e0b6cad4537201142ecccdbab2b3589b82bdc388 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 25 Feb 2025 12:32:05 +0100 Subject: [PATCH 53/57] rename --- .../toggle/property-editor-ui-toggle.element.ts | 4 ++-- .../toggle/property-value-preset.TrueFalse.ts | 6 +++--- .../src/packages/property-editors/toggle/types.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts index 6e814da4a26b..f0e34bb06522 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts @@ -1,4 +1,4 @@ -import type { UmbPropertyEditorUIToggleValue } from './types.js'; +import type { UmbTogglePropertyEditorUiValue } from './types.js'; import type { UmbInputToggleElement } from '@umbraco-cms/backoffice/components'; import { customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; @@ -11,7 +11,7 @@ import { UMB_VALIDATION_FALSE_LOCALIZATION_KEY, UmbFormControlMixin } from '@umb @customElement('umb-property-editor-ui-toggle') export class UmbPropertyEditorUIToggleElement - extends UmbFormControlMixin(UmbLitElement) + extends UmbFormControlMixin(UmbLitElement) implements UmbPropertyEditorUiElement { @property({ type: String }) diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts index 317f12a22b7d..8d3681d1d70c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts @@ -1,11 +1,11 @@ -import type { UmbPropertyEditorUIToggleValue } from './types.js'; +import type { UmbTogglePropertyEditorUiValue } from './types.js'; import type { UmbPropertyValuePreset } from '@umbraco-cms/backoffice/property'; import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; export class UmbTrueFalsePropertyValuePreset - implements UmbPropertyValuePreset + implements UmbPropertyValuePreset { - async processValue(value: undefined | UmbPropertyEditorUIToggleValue, config: UmbPropertyEditorConfig) { + async processValue(value: undefined | UmbTogglePropertyEditorUiValue, config: UmbPropertyEditorConfig) { const initialState = (config.find((x) => x.alias === 'default')?.value as boolean | undefined) ?? false; return value !== undefined ? value : initialState; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/types.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/types.ts index 69a021a31068..d2a6e1a2b4b1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/types.ts @@ -1 +1 @@ -export type UmbPropertyEditorUIToggleValue = boolean; +export type UmbTogglePropertyEditorUiValue = boolean; From 04ff837095dc1b87f93958612cb57f35e2c5d976 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 25 Feb 2025 12:41:03 +0100 Subject: [PATCH 54/57] make linter happy --- .../block/block-grid/context/block-grid-manager.context.ts | 2 ++ .../block/block-list/context/block-list-manager.context.ts | 2 ++ .../block/block-rte/context/block-rte-manager.context.ts | 2 ++ .../src/packages/block/block/context/block-manager.context.ts | 2 +- .../core/content/workspace/content-detail-workspace-base.ts | 2 +- .../property-editors/slider/property-value-preset.Slider.ts | 4 ++-- 6 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-manager.context.ts index d32b1c185c68..7fb16cd57374 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-manager.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-manager.context.ts @@ -95,7 +95,9 @@ export class UmbBlockGridManagerContext< * @deprecated Use createWithPresets instead. Will be removed in v.17. */ create( + // eslint-disable-next-line @typescript-eslint/no-unused-vars contentElementTypeKey: string, + // eslint-disable-next-line @typescript-eslint/no-unused-vars partialLayoutEntry?: Omit, // This property is used by some implementations, but not used in this. Do not remove. [NL] // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-manager.context.ts index 9b30b9bf1180..6dd0267cb3f2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-manager.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-manager.context.ts @@ -25,7 +25,9 @@ export class UmbBlockListManagerContext< * @deprecated Use createWithPresets instead. Will be removed in v.17. */ create( + // eslint-disable-next-line @typescript-eslint/no-unused-vars contentElementTypeKey: string, + // eslint-disable-next-line @typescript-eslint/no-unused-vars partialLayoutEntry?: Omit, // This property is used by some implementations, but not used in this. Do not remove. [NL] // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-manager.context.ts index 504e109fa34f..30458896c18e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-manager.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-manager.context.ts @@ -22,7 +22,9 @@ export class UmbBlockRteManagerContext< * @deprecated Use createWithPresets instead. Will be removed in v.17. */ create( + // eslint-disable-next-line @typescript-eslint/no-unused-vars contentElementTypeKey: string, + // eslint-disable-next-line @typescript-eslint/no-unused-vars partialLayoutEntry?: Omit, // This property is used by some implementations, but not used in this. Do not remove. [NL] // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts index b48641c87866..2ed85ca7c095 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts @@ -410,7 +410,7 @@ export abstract class UmbBlockManagerContext< if (segments) { controller.setSegments(segments); } - let values = await controller.create(valueDefinitions); + const values = await controller.create(valueDefinitions); // Set culture and segment for all values: diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts index e5bcd66792d4..363a73bdf3d8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -743,7 +743,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< this._data.setPersisted(newPersistedData); // Only update the variants that was chosen to be saved: - let currentData = this._data.getCurrent(); + const currentData = this._data.getCurrent(); const newCurrentData = await new UmbMergeContentVariantDataController(this).process( currentData, data, diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts index 175915c4c15a..8c27b41147d3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts @@ -18,10 +18,10 @@ export class UmbSliderPropertyValuePreset const step = (config.find((x) => x.alias === 'step') as number | undefined) ?? 0; const stepVerified = step > 0 ? step : 1; - const initValueMin = Number(config.find((x) => x.alias === 'initVal1')?.value) ?? 0; + const initValueMin = Number(config.find((x) => x.alias === 'initVal1')?.value) || 0; const initValueMinVerified = isNaN(initValueMin) ? 0 : initValueMin; - const initValueMax = Number(config.find((x) => x.alias === 'initVal2')?.value) ?? 0; + const initValueMax = Number(config.find((x) => x.alias === 'initVal2')?.value) || 0; const initValueMaxVerified = isNaN(initValueMax) ? initValueMinVerified + stepVerified : initValueMax; const initialState = enableRange From e61e23b3b7f908ed6c9dc2bf376dc0b44605d35c Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 25 Feb 2025 12:43:47 +0100 Subject: [PATCH 55/57] align file names --- .../property-editors/markdown-editor/manifests.ts | 2 +- ...rkdownEditor.ts => markdown-editor-property-value-preset.ts} | 0 .../src/packages/property-editors/slider/manifests.ts | 2 +- ...y-value-preset.Slider.ts => slider-property-value-preset.ts} | 0 .../src/packages/property-editors/toggle/manifests.ts | 2 +- ...-preset.TrueFalse.ts => true-false-property-value-preset.ts} | 0 6 files changed, 3 insertions(+), 3 deletions(-) rename src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/{property-value-preset.MarkdownEditor.ts => markdown-editor-property-value-preset.ts} (100%) rename src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/{property-value-preset.Slider.ts => slider-property-value-preset.ts} (100%) rename src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/{property-value-preset.TrueFalse.ts => true-false-property-value-preset.ts} (100%) diff --git a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/manifests.ts index 0fe159fa584b..91e6d44082e7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/manifests.ts @@ -6,7 +6,7 @@ export const manifests: Array = [ forPropertyEditorSchemaAlias: 'Umbraco.MarkdownEditor', alias: 'Umbraco.MarkdownEditor', name: 'Markdown Editor Property Value Preset', - api: () => import('./property-value-preset.MarkdownEditor.js'), + api: () => import('./markdown-editor-property-value-preset.js'), }, { type: 'propertyEditorUi', diff --git a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-value-preset.MarkdownEditor.ts b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/markdown-editor-property-value-preset.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/property-value-preset.MarkdownEditor.ts rename to src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/markdown-editor-property-value-preset.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/manifests.ts index c0fee318d13b..d313ac784957 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/manifests.ts @@ -6,7 +6,7 @@ export const manifests: Array = [ forPropertyEditorSchemaAlias: 'Umbraco.Slider', alias: 'Umb.PropertyValuePreset.Slider', name: 'Property Editor Schema Slider Preset for Initial Values', - api: () => import('./property-value-preset.Slider.js'), + api: () => import('./slider-property-value-preset.js'), }, { type: 'propertyEditorUi', diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/slider-property-value-preset.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-value-preset.Slider.ts rename to src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/slider-property-value-preset.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/manifests.ts index f71eaa878007..efd7f2292d2a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/manifests.ts @@ -6,7 +6,7 @@ export const manifests: Array = [ forPropertyEditorSchemaAlias: 'Umbraco.TrueFalse', alias: 'Umb.PropertyValuePreset.TrueFalse', name: 'Property Editor Schema True/False Preset for Initial State', - api: () => import('./property-value-preset.TrueFalse.js'), + api: () => import('./true-false-property-value-preset.js'), }, { type: 'propertyEditorUi', diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/true-false-property-value-preset.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-value-preset.TrueFalse.ts rename to src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/true-false-property-value-preset.ts From 2fa3e2ae9be880de5a36a15b2682ea027bc87e23 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 25 Feb 2025 12:47:36 +0100 Subject: [PATCH 56/57] delete temp files --- ...ray-and-string-comparison.function.temp_ts | 15 ---------- ...n-array-and-string-comparison.test.temp_ts | 29 ------------------- 2 files changed, 44 deletions(-) delete mode 100644 src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-array-and-string-comparison.function.temp_ts delete mode 100644 src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-array-and-string-comparison.test.temp_ts diff --git a/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-array-and-string-comparison.function.temp_ts b/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-array-and-string-comparison.function.temp_ts deleted file mode 100644 index 17e327a16eed..000000000000 --- a/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-array-and-string-comparison.function.temp_ts +++ /dev/null @@ -1,15 +0,0 @@ -import { diffJson } from '@umbraco-cms/backoffice/external/diff'; - -/** - * @function umbJsonDeepComparison - * @param {object} a - The first object to compare. - * @param {object} b - The second object to compare. - * @returns {boolean} - Returns true if the JSON Structure are identical. - * @description - Compares two objects by converting them to JSON strings. - * This is a JSON comparison and should only be used for simple objects. - * Meaning no class instances can take part in this data. - */ -export function umbJsonDeepComparison(a: object, b: object): boolean { - const result = diffJson(a, b); - return result.some((change) => change.added || change.removed); -} diff --git a/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-array-and-string-comparison.test.temp_ts b/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-array-and-string-comparison.test.temp_ts deleted file mode 100644 index ee1440675b0e..000000000000 --- a/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/json-array-and-string-comparison.test.temp_ts +++ /dev/null @@ -1,29 +0,0 @@ -import { expect } from '@open-wc/testing'; -import { umbJsonDeepComparison } from './json-array-and-string-comparison.function.js'; - -describe('umbJsonDeepComparison', () => { - beforeEach(() => {}); - - it('gives a result', (done) => { - const a = { - property: 'hello', - arr: [1, 2, 3], - obj: { - deep: 'value', - deep2: 'value2', - }, - }; - - const b = { - property: 'hello', - arr: [1, 2, 3], - obj: { - deep2: 'value2', - deep: 'value', - }, - }; - - const result = umbJsonDeepComparison(a, b); - expect(result).to.be.false; - }); -}); From a683851fb292e7576bbada0cc4ad8843b348d700 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 25 Feb 2025 12:53:03 +0100 Subject: [PATCH 57/57] fix alias --- .../property-editors/markdown-editor/manifests.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/manifests.ts index 91e6d44082e7..10f5ef989073 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/manifests.ts @@ -4,7 +4,7 @@ export const manifests: Array = [ { type: 'propertyValuePreset', forPropertyEditorSchemaAlias: 'Umbraco.MarkdownEditor', - alias: 'Umbraco.MarkdownEditor', + alias: 'Umb.PropertyValuePreset.MarkdownEditor', name: 'Markdown Editor Property Value Preset', api: () => import('./markdown-editor-property-value-preset.js'), },