@umbraco-cms/backoffice 17.4.0-rc3 → 17.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -25,7 +25,6 @@ export declare class UmbContentTypeStructureManager<T extends UmbContentTypeMode
25
25
  getOwnerContentTypeCompositions(): Promise<import("../types.js").UmbContentTypeCompositionModel[]>;
26
26
  readonly contentTypeProperties: Observable<UmbPropertyTypeModel[]>;
27
27
  getContentTypeProperties(): Promise<UmbPropertyTypeModel[]>;
28
- readonly contentTypeDataTypeUniques: Observable<string[]>;
29
28
  /**
30
29
  * Get an observable for the data type detail of a data type that is in use by this content type structure.
31
30
  * @param {string} dataTypeUnique - The unique identifier of the data type.
@@ -37,6 +36,8 @@ export declare class UmbContentTypeStructureManager<T extends UmbContentTypeMode
37
36
  readonly contentTypeUniques: Observable<string[]>;
38
37
  readonly contentTypeAliases: Observable<string[]>;
39
38
  readonly contentTypeLoaded: Observable<boolean>;
39
+ readonly contentTypeDataTypeUniques: Observable<string[]>;
40
+ getContentTypeDataTypeUniques(): string[];
40
41
  readonly variesByCulture: Observable<boolean | undefined>;
41
42
  readonly variesBySegment: Observable<boolean | undefined>;
42
43
  containerById(id: string): Observable<UmbPropertyTypeContainerModel | undefined>;
@@ -54,6 +54,12 @@ export class UmbContentTypeStructureManager extends UmbControllerBase {
54
54
  contentTypeDataTypeDetailOf(dataTypeUnique) {
55
55
  return this.#dataTypeDetails.asObservablePart((details) => details.find((d) => d.unique === dataTypeUnique));
56
56
  }
57
+ getContentTypeDataTypeUniques() {
58
+ return this.#contentTypes
59
+ .getValue()
60
+ .flatMap((x) => x.properties?.map((p) => p.dataType.unique) ?? [])
61
+ .filter(UmbFilterDuplicateStrings);
62
+ }
57
63
  containerById(id) {
58
64
  return createObservablePart(this.#contentTypeContainers, (x) => x.find((y) => y.id === id));
59
65
  }
@@ -92,11 +98,6 @@ export class UmbContentTypeStructureManager extends UmbControllerBase {
92
98
  this.contentTypeProperties = this.#contentTypes.asObservablePart((contentTypes) => {
93
99
  return contentTypes.flatMap((x) => x.properties ?? []);
94
100
  });
95
- this.contentTypeDataTypeUniques = this.#contentTypes.asObservablePart((contentTypes) => {
96
- return contentTypes
97
- .flatMap((x) => x.properties?.map((p) => p.dataType.unique) ?? [])
98
- .filter(UmbFilterDuplicateStrings);
99
- });
100
101
  this.contentTypeHasProperties = this.#contentTypes.asObservablePart((contentTypes) => {
101
102
  return contentTypes.some((x) => x.properties.length > 0);
102
103
  });
@@ -104,7 +105,16 @@ export class UmbContentTypeStructureManager extends UmbControllerBase {
104
105
  this.contentTypeUniques = this.#contentTypes.asObservablePart((x) => x.map((y) => y.unique));
105
106
  this.contentTypeAliases = this.#contentTypes.asObservablePart((x) => x.map((y) => y.alias));
106
107
  this.contentTypeLoaded = mergeObservables([this.contentTypeCompositions, this.contentTypeUniques], ([comps, uniques]) => {
107
- return comps.every((x) => uniques.includes(x.contentType.unique));
108
+ return uniques.length > 0 && comps.every((x) => uniques.includes(x.contentType.unique));
109
+ });
110
+ // Derived from #contentTypes (single source) and gated on contentTypeLoaded, so property
111
+ // changes re-emit and properties can't lag behind loaded across separate microtasks. [NL]
112
+ this.contentTypeDataTypeUniques = mergeObservables([this.contentTypeLoaded, this.contentTypes], ([loaded, contentTypes]) => {
113
+ if (!loaded)
114
+ return [];
115
+ return contentTypes
116
+ .flatMap((x) => x.properties?.map((p) => p.dataType.unique) ?? [])
117
+ .filter(UmbFilterDuplicateStrings);
108
118
  });
109
119
  this.variesByCulture = createObservablePart(this.ownerContentType, (x) => x?.variesByCulture);
110
120
  this.variesBySegment = createObservablePart(this.ownerContentType, (x) => x?.variesBySegment);
@@ -184,8 +194,15 @@ export class UmbContentTypeStructureManager extends UmbControllerBase {
184
194
  // Uses nested observation: outer watches which data types are needed,
185
195
  // inner subscribes to the store-backed observable for reactivity.
186
196
  this.observe(this.contentTypeDataTypeUniques, async (dataTypeUniques) => {
187
- if (dataTypeUniques.length > 0) {
197
+ if (dataTypeUniques && dataTypeUniques.length > 0) {
188
198
  const { asObservable } = await this.#dataTypeDetailRepository.requestByUniques(dataTypeUniques);
199
+ // TODO: We should avoid this check, but architecturally, we currently lack a way to cancel previous requests. [NL]
200
+ // This is unlikely to happen, but we keep this check to avoid potential race conditions. [NL]
201
+ const currentDataTypeUniques = this.getContentTypeDataTypeUniques();
202
+ if (dataTypeUniques.length !== currentDataTypeUniques.length ||
203
+ !dataTypeUniques.every((unique) => currentDataTypeUniques.includes(unique))) {
204
+ return;
205
+ }
189
206
  if (asObservable) {
190
207
  this.observe(asObservable(), (dataTypeDetails) => {
191
208
  this.#dataTypeDetails.setValue(dataTypeDetails ?? []);
@@ -186,6 +186,15 @@ export class UmbDataTypeWorkspaceContext extends UmbEntityNamedDetailWorkspaceCo
186
186
  this.#propertyEditorDataSourceSettingsProperties,
187
187
  ].filter((x) => Array.isArray(x) && x.length > 0);
188
188
  const mergedSettings = settings.flat();
189
+ // check if there is alias duplicates:
190
+ const aliasSet = new Set();
191
+ for (const setting of mergedSettings) {
192
+ if (aliasSet.has(setting.alias)) {
193
+ console.error(`There is a duplicate alias "${setting.alias}" in the Property Editor configuration.`);
194
+ continue;
195
+ }
196
+ aliasSet.add(setting.alias);
197
+ }
189
198
  if (mergedSettings) {
190
199
  this.#properties.setValue(mergedSettings);
191
200
  // If new or if the alias was changed then set default values. This 'complexity' to prevent setting default data when initialized [NL]
@@ -215,16 +224,15 @@ export class UmbDataTypeWorkspaceContext extends UmbEntityNamedDetailWorkspaceCo
215
224
  ];
216
225
  const values = [];
217
226
  // We want to keep the existing data, if it is not in the default data, and if it is in the default data, then we want to keep the default data.
218
- for (const defaultDataItem of this.#properties.getValue()) {
227
+ for (const property of this.#properties.getValue()) {
219
228
  // We are matching on the alias, as we assume that the alias is unique for the data type.
220
- // TODO: Consider if we should also match on the editorAlias just to be on the safe side [JOV]
221
- const existingData = data.values?.find((x) => x.alias === defaultDataItem.alias);
229
+ const existingData = data.values?.find((x) => x.alias === property.alias);
222
230
  if (existingData) {
223
231
  values.push(existingData);
224
232
  continue;
225
233
  }
226
234
  // If the data is not in the existing data, then we want to add the default data if it exists.
227
- const existingDefaultData = this.#settingsDefaultData.find((x) => x.alias === defaultDataItem.alias);
235
+ const existingDefaultData = this.#settingsDefaultData.find((x) => x.alias === property.alias);
228
236
  if (existingDefaultData) {
229
237
  values.push(existingDefaultData);
230
238
  }
@@ -23,7 +23,7 @@ export const manifest = {
23
23
  {
24
24
  alias: 'minimumRange',
25
25
  label: 'Minimum range',
26
- description: '',
26
+ description: 'Minimum difference between the low and high values when range is enabled. Set to 0 to allow equal values.',
27
27
  propertyEditorUiAlias: 'Umb.PropertyEditorUi.Decimal',
28
28
  config: [{ alias: 'step', value: '0.00001' }],
29
29
  },
@@ -47,13 +47,6 @@ export const manifests = [
47
47
  propertyEditorUiAlias: 'Umb.PropertyEditorUi.Decimal',
48
48
  config: [{ alias: 'step', value: '0.00001' }],
49
49
  },
50
- {
51
- alias: 'minimumRange',
52
- label: 'Minimum range',
53
- description: 'Minimum difference between the low and high values when range is enabled. Set to 0 to allow equal values.',
54
- propertyEditorUiAlias: 'Umb.PropertyEditorUi.Decimal',
55
- config: [{ alias: 'step', value: '0.00001' }],
56
- },
57
50
  ],
58
51
  defaultData: [
59
52
  {
@@ -68,10 +61,6 @@ export const manifests = [
68
61
  alias: 'step',
69
62
  value: 1.0,
70
63
  },
71
- {
72
- alias: 'minimumRange',
73
- value: 0.0,
74
- },
75
64
  ],
76
65
  },
77
66
  },