Skip to content

Commit ee51f2a

Browse files
authored
Merge pull request #18194 from umbraco/v15/bugfix/17206
Fix: 17206
2 parents fc8ae20 + 13bcf16 commit ee51f2a

File tree

5 files changed

+62
-33
lines changed

5 files changed

+62
-33
lines changed

src/Umbraco.Web.UI.Client/src/packages/block/block-list/property-editors/block-list-editor/property-editor-ui-block-list.element.ts

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,14 @@ export class UmbPropertyEditorUIBlockListElement
5454
#contentDataPathTranslator?: UmbBlockElementDataValidationPathTranslator;
5555
#settingsDataPathTranslator?: UmbBlockElementDataValidationPathTranslator;
5656

57-
//#catalogueModal: UmbModalRouteRegistrationController<typeof UMB_BLOCK_CATALOGUE_MODAL.DATA, undefined>;
58-
59-
private _value: UmbBlockListValueModel | undefined = undefined;
60-
6157
#lastValue: UmbBlockListValueModel | undefined = undefined;
6258

6359
@property({ attribute: false })
6460
public override set value(value: UmbBlockListValueModel | undefined) {
6561
this.#lastValue = value;
6662

6763
if (!value) {
68-
this._value = undefined;
64+
super.value = undefined;
6965
return;
7066
}
7167

@@ -74,15 +70,15 @@ export class UmbPropertyEditorUIBlockListElement
7470
buildUpValue.contentData ??= [];
7571
buildUpValue.settingsData ??= [];
7672
buildUpValue.expose ??= [];
77-
this._value = buildUpValue as UmbBlockListValueModel;
73+
super.value = buildUpValue as UmbBlockListValueModel;
7874

79-
this.#managerContext.setLayouts(this._value.layout[UMB_BLOCK_LIST_PROPERTY_EDITOR_SCHEMA_ALIAS] ?? []);
80-
this.#managerContext.setContents(this._value.contentData);
81-
this.#managerContext.setSettings(this._value.settingsData);
82-
this.#managerContext.setExposes(this._value.expose);
75+
this.#managerContext.setLayouts(super.value.layout[UMB_BLOCK_LIST_PROPERTY_EDITOR_SCHEMA_ALIAS] ?? []);
76+
this.#managerContext.setContents(super.value.contentData);
77+
this.#managerContext.setSettings(super.value.settingsData);
78+
this.#managerContext.setExposes(super.value.expose);
8379
}
8480
public override get value(): UmbBlockListValueModel | undefined {
85-
return this._value;
81+
return super.value;
8682
}
8783

8884
@state()
@@ -214,10 +210,10 @@ export class UmbPropertyEditorUIBlockListElement
214210
]).pipe(debounceTime(20)),
215211
([layouts, contents, settings, exposes]) => {
216212
if (layouts.length === 0) {
217-
this._value = undefined;
213+
super.value = undefined;
218214
} else {
219-
this._value = {
220-
...this._value,
215+
super.value = {
216+
...super.value,
221217
layout: { [UMB_BLOCK_LIST_PROPERTY_EDITOR_SCHEMA_ALIAS]: layouts },
222218
contentData: contents,
223219
settingsData: settings,
@@ -227,11 +223,11 @@ export class UmbPropertyEditorUIBlockListElement
227223

228224
// If we don't have a value set from the outside or an internal value, we don't want to set the value.
229225
// This is added to prevent the block list from setting an empty value on startup.
230-
if (this.#lastValue === undefined && this._value === undefined) {
226+
if (this.#lastValue === undefined && super.value === undefined) {
231227
return;
232228
}
233229

234-
context.setValue(this._value);
230+
context.setValue(super.value);
235231
},
236232
'motherObserver',
237233
);

src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/validation.controller.ts

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,7 @@ import type { UmbContextProviderController } from '@umbraco-cms/backoffice/conte
77
import { type UmbClassInterface, UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
88
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
99
import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
10-
11-
/**
12-
* Helper method to replace the start of a string with another string.
13-
* @param path {string}
14-
* @param startFrom {string}
15-
* @param startTo {string}
16-
* @returns {string}
17-
*/
18-
function ReplaceStartOfString(path: string, startFrom: string, startTo: string): string {
19-
if (path.startsWith(startFrom + '.')) {
20-
return startTo + path.slice(startFrom.length);
21-
}
22-
return path;
23-
}
10+
import { ReplaceStartOfPath } from '../utils/replace-start-of-path.function.js';
2411

2512
/**
2613
* Validation Context is the core of Validation.
@@ -143,7 +130,12 @@ export class UmbValidationController extends UmbControllerBase implements UmbVal
143130
}
144131
this.#parentMessages = msgs;
145132
msgs.forEach((msg) => {
146-
const path = ReplaceStartOfString(msg.path, this.#baseDataPath!, '$');
133+
const path = ReplaceStartOfPath(msg.path, this.#baseDataPath!, '$');
134+
if (path === undefined) {
135+
throw new Error(
136+
'Path was not transformed correctly and can therefor not be transfered to the local validation context messages.',
137+
);
138+
}
147139
// Notice, the local message uses the same key. [NL]
148140
this.messages.addMessage(msg.type, path, msg.body, msg.key);
149141
});
@@ -164,7 +156,12 @@ export class UmbValidationController extends UmbControllerBase implements UmbVal
164156
this.#localMessages = msgs;
165157
msgs.forEach((msg) => {
166158
// replace this.#baseDataPath (if it starts with it) with $ in the path, so it becomes relative to the parent context
167-
const path = ReplaceStartOfString(msg.path, '$', this.#baseDataPath!);
159+
const path = ReplaceStartOfPath(msg.path, '$', this.#baseDataPath!);
160+
if (path === undefined) {
161+
throw new Error(
162+
'Path was not transformed correctly and can therefor not be synced with parent messages.',
163+
);
164+
}
168165
// Notice, the parent message uses the same key. [NL]
169166
this.#parent!.messages.addMessage(msg.type, path, msg.body, msg.key);
170167
});

src/Umbraco.Web.UI.Client/src/packages/core/validation/mixins/form-control.mixin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,11 @@ export function UmbFormControlMixin<
125125
*/
126126
@property({ reflect: false }) // Do not 'reflect' as the attribute value is used as fallback. [NL]
127127
get value(): ValueType | DefaultValueType {
128+
// For some reason we need to keep this as setters and getters for inherited classes for work properly when they override these methods. [NL]
128129
return this.#value;
129130
}
130131
set value(newValue: ValueType | DefaultValueType) {
131132
this.#value = newValue;
132-
this._runValidators();
133133
}
134134

135135
// Validation
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* Helper method to replace the start of a JSON Path with another JSON Path.
3+
* @param path {string}
4+
* @param startFrom {string}
5+
* @param startTo {string}
6+
* @returns {string}
7+
*/
8+
export function ReplaceStartOfPath(path: string, startFrom: string, startTo: string): string | undefined {
9+
// if the path conitnues with a . or [ aftr startFrom, then replace it with startTo, otherwise if identical then it is also a match. [NL]
10+
if (path.startsWith(startFrom + '.') || path === startFrom) {
11+
return startTo + path.slice(startFrom.length);
12+
}
13+
return;
14+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { expect } from '@open-wc/testing';
2+
import { ReplaceStartOfPath } from './replace-start-of-path.function.js';
3+
4+
describe('ReplaceStartOfPath', () => {
5+
it('replaces a dot path', () => {
6+
const result = ReplaceStartOfPath('$.start.test', '$.start', '$');
7+
8+
expect(result).to.eq('$.test');
9+
});
10+
11+
it('replaces a array path', () => {
12+
const result = ReplaceStartOfPath('$.start[0].test', '$.start[0]', '$');
13+
14+
expect(result).to.eq('$.test');
15+
});
16+
17+
it('replaces a exact path', () => {
18+
const result = ReplaceStartOfPath('$.start.test', '$.start.test', '$');
19+
20+
expect(result).to.eq('$');
21+
});
22+
});

0 commit comments

Comments
 (0)