diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/property-settings/property-settings-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/property-settings/property-settings-modal.element.ts index c974c3c1ab..a88996f83c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/property-settings/property-settings-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/property-settings/property-settings-modal.element.ts @@ -64,21 +64,21 @@ export class UmbPropertySettingsModalElement extends UmbModalBaseElement< }); this._originalPropertyData = this._value; - // TODO: Use some utility method for this deep clone: - this._value = JSON.parse(JSON.stringify(this._value ?? {})); - this._value.validation ??= {}; - - const regEx = this._value.validation.regEx ?? null; + const regEx = this._value.validation?.regEx ?? null; const newlySelected = this._customValidationOptions.find((option) => { option.selected = option.value === regEx; return option.selected; }); if (newlySelected === undefined) { this._customValidationOptions[4].selected = true; - this._value.validation.regEx = this._customValidationOptions[4].value; + this.updateValue({ + validation: { ...this._value.validation, regEx: this._customValidationOptions[4].value }, + }); } else { - this._value.validation.regEx = regEx; + this.updateValue({ + validation: { ...this._value.validation, regEx: regEx }, + }); } } @@ -106,58 +106,56 @@ export class UmbPropertySettingsModalElement extends UmbModalBaseElement< #onNameChange(event: UUIInputEvent) { const oldName = this._value.name; const oldAlias = this._value.alias; - this._value.name = event.target.value.toString(); + this.updateValue({ name: event.target.value.toString() }); if (this._aliasLocked) { const expectedOldAlias = generateAlias(oldName ?? ''); // Only update the alias if the alias matches a generated alias of the old name (otherwise the alias is considered one written by the user.) if (expectedOldAlias === oldAlias) { - this._value.alias = generateAlias(this._value.name); - this.requestUpdate('_returnData'); + this.updateValue({ alias: generateAlias(this._value.name ?? '') }); } } } #onAliasChange(event: UUIInputEvent) { const alias = generateAlias(event.target.value.toString()); - if (!this._aliasLocked) { - this._value.alias = alias; - } else { - this._value.alias = this._originalPropertyData.alias; - } - this.requestUpdate('_returnData'); + this.updateValue({ alias: this._aliasLocked ? this._originalPropertyData.alias : alias }); } #onDataTypeIdChange(event: UUIInputEvent) { const dataTypeId = event.target.value.toString(); - this._value.dataTypeId = dataTypeId; - this.requestUpdate('_returnData'); + this.updateValue({ dataTypeId }); } #onMandatoryChange(event: UUIBooleanInputEvent) { - const value = event.target.checked; - this._value.validation!.mandatory = value; - this.requestUpdate('_returnData'); + const mandatory = event.target.checked; + this._value.validation!.mandatory = mandatory; + this.updateValue({ + validation: { ...this._value.validation, mandatory }, + }); } #onMandatoryMessageChange(event: UUIInputEvent) { - const value = event.target.value.toString(); - this._value.validation!.mandatoryMessage = value; - this.requestUpdate('_returnData'); + const mandatoryMessage = event.target.value.toString(); + this.updateValue({ + validation: { ...this._value.validation, mandatoryMessage }, + }); } #setAppearanceNormal() { const currentValue = this._value.appearance?.labelOnTop; if (currentValue !== true) return; - this._value.appearance!.labelOnTop = false; - this.requestUpdate('_returnData'); + this.updateValue({ + appearance: { ...this._value.appearance, labelOnTop: false }, + }); } #setAppearanceTop() { const currentValue = this._value.appearance?.labelOnTop; if (currentValue === true) return; - this._value.appearance!.labelOnTop = true; - this.requestUpdate('_returnData'); + this.updateValue({ + appearance: { ...this._value.appearance, labelOnTop: true }, + }); } #onToggleAliasLock() { @@ -170,10 +168,10 @@ export class UmbPropertySettingsModalElement extends UmbModalBaseElement< this._customValidationOptions.forEach((option) => { option.selected = option.value === regEx; }); - - this._value.validation!.regEx = regEx ?? null; - this.requestUpdate('_returnData'); this.requestUpdate('_customValidationOptions'); + this.updateValue({ + validation: { ...this._value.validation, regEx }, + }); } #onValidationRegExChange(event: UUIInputEvent) { @@ -184,19 +182,24 @@ export class UmbPropertySettingsModalElement extends UmbModalBaseElement< }); if (betterChoice === undefined) { this._customValidationOptions[4].selected = true; + this.requestUpdate('_customValidationOptions'); } - this._value.validation!.regEx = regEx; - this.requestUpdate('_returnData'); - this.requestUpdate('_customValidationOptions'); + this.updateValue({ + validation: { ...this._value.validation, regEx }, + }); } #onValidationMessageChange(event: UUIInputEvent) { - this._value.validation!.regExMessage = event.target.value.toString(); - this.requestUpdate('_returnData'); + const regExMessage = event.target.value.toString(); + this.updateValue({ + validation: { ...this._value.validation, regExMessage }, + }); } #onVaryByCultureChange(event: UUIBooleanInputEvent) { - this._value.variesByCulture = event.target.checked; - this.requestUpdate('_returnData'); + const variesByCulture = event.target.checked; + this.updateValue({ + variesByCulture, + }); } // TODO: This would conceptually be a Property Editor Workspace, should be changed at one point in the future. diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/modal-element.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/modal-element.element.ts index 8433e25c76..beecfad3c1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/modal-element.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/modal-element.element.ts @@ -11,11 +11,31 @@ export abstract class UmbModalBaseElement< extends UmbLitElement implements UmbModalExtensionElement { + #value: ModalValueType = {} as ModalValueType; + @property({ type: Object, attribute: false }) public manifest?: ModalManifestType; @property({ attribute: false }) - public modalContext?: UmbModalContext; + public get modalContext(): UmbModalContext | undefined { + return this.#modalContext; + } + public set modalContext(context: UmbModalContext | undefined) { + this.#modalContext = context; + if (context) { + this.observe( + context.value, + (value) => { + const oldValue = this.#value; + this.#value = value; + this.requestUpdate('_value', oldValue); + // Idea: we could implement a callback method on class. + }, + 'observeModalContextValue', + ); + } + } + #modalContext?: UmbModalContext | undefined; @property({ type: Object, attribute: false }) public get data(): ModalDataType | undefined { @@ -28,10 +48,14 @@ export abstract class UmbModalBaseElement< @state() public get _value(): ModalValueType { - return this.modalContext?.getValue() ?? ({} as ModalValueType); + return this.#value; } public set _value(value: ModalValueType) { - this.modalContext?.setValue(value); + this.#modalContext?.setValue(value); + } + + public updateValue(partialValue: Partial) { + this.#modalContext?.updateValue(partialValue); } /** @@ -40,7 +64,7 @@ export abstract class UmbModalBaseElement< * @memberof UmbModalBaseElement */ protected _submitModal() { - this.modalContext?.submit(); + this.#modalContext?.submit(); } /** @@ -49,6 +73,6 @@ export abstract class UmbModalBaseElement< * @memberof UmbModalBaseElement */ protected _rejectModal() { - this.modalContext?.reject(); + this.#modalContext?.reject(); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/modal-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/modal-manager.context.ts index 2927549350..a557c2898f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/modal-manager.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/modal-manager.context.ts @@ -33,7 +33,7 @@ export class UmbModalManagerContext { */ public open< ModalData extends object = object, - ModalValue extends object = object, + ModalValue = unknown, ModalAliasTypeAsToken extends UmbModalToken = UmbModalToken, >( modalAlias: UmbModalToken | string, diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/modal-token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/modal-token.ts index fe96cb9f84..117778ee1b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/modal-token.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/modal-token.ts @@ -1,6 +1,6 @@ import { UmbModalConfig } from '../modal-manager.context.js'; -export class UmbModalToken { +export class UmbModalToken { /** * Get the data type of the token's data. *