@umbraco-cms/backoffice 16.3.2 → 16.3.4

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.
@@ -157,6 +157,26 @@ export declare class UmbArrayState<T, U = unknown> extends UmbDeepState<T[]> {
157
157
  * ]);
158
158
  */
159
159
  append(entries: T[]): this;
160
+ /**
161
+ * @function replace
162
+ * @param {Partial<T>} entires - data of entries to be replaced.
163
+ * @returns {UmbArrayState<T>} Reference to it self.
164
+ * @description - Replaces one or more entries, requires the ArrayState to be constructed with a getUnique method.
165
+ * @example <caption>Example append some data.</caption>
166
+ * const data = [
167
+ * { key: 1, value: 'foo'},
168
+ * { key: 2, value: 'bar'}
169
+ * ];
170
+ * const myState = new UmbArrayState(data, (x) => x.key);
171
+ * const updates = [
172
+ * { key: 1, value: 'foo2'},
173
+ * { key: 3, value: 'bar2'}
174
+ * ];
175
+ * myState.replace(updates);
176
+ * // Only the existing item gets replaced:
177
+ * myState.getValue(); // -> [{ key: 1, value: 'foo2'}, { key: 2, value: 'bar'}]
178
+ */
179
+ replace(entries: Array<T>): UmbArrayState<T>;
160
180
  /**
161
181
  * @function updateOne
162
182
  * @param {U} unique - Unique value to find entry to update.
@@ -1,6 +1,7 @@
1
1
  import { partialUpdateFrozenArray } from '../utils/partial-update-frozen-array.function.js';
2
2
  import { pushAtToUniqueArray } from '../utils/push-at-to-unique-array.function.js';
3
3
  import { pushToUniqueArray } from '../utils/push-to-unique-array.function.js';
4
+ import { replaceInUniqueArray } from '../utils/replace-in-unique-array.function.js';
4
5
  import { UmbDeepState } from './deep-state.js';
5
6
  /**
6
7
  * @class UmbArrayState
@@ -254,6 +255,38 @@ export class UmbArrayState extends UmbDeepState {
254
255
  }
255
256
  return this;
256
257
  }
258
+ /**
259
+ * @function replace
260
+ * @param {Partial<T>} entires - data of entries to be replaced.
261
+ * @returns {UmbArrayState<T>} Reference to it self.
262
+ * @description - Replaces one or more entries, requires the ArrayState to be constructed with a getUnique method.
263
+ * @example <caption>Example append some data.</caption>
264
+ * const data = [
265
+ * { key: 1, value: 'foo'},
266
+ * { key: 2, value: 'bar'}
267
+ * ];
268
+ * const myState = new UmbArrayState(data, (x) => x.key);
269
+ * const updates = [
270
+ * { key: 1, value: 'foo2'},
271
+ * { key: 3, value: 'bar2'}
272
+ * ];
273
+ * myState.replace(updates);
274
+ * // Only the existing item gets replaced:
275
+ * myState.getValue(); // -> [{ key: 1, value: 'foo2'}, { key: 2, value: 'bar'}]
276
+ */
277
+ replace(entries) {
278
+ if (this.getUniqueMethod) {
279
+ const next = [...this.getValue()];
280
+ entries.forEach((entry) => {
281
+ replaceInUniqueArray(next, entry, this.getUniqueMethod);
282
+ });
283
+ this.setValue(next);
284
+ }
285
+ else {
286
+ throw new Error("Can't replace entries of an ArrayState without a getUnique method provided when constructed.");
287
+ }
288
+ return this;
289
+ }
257
290
  /**
258
291
  * @function updateOne
259
292
  * @param {U} unique - Unique value to find entry to update.
@@ -12,5 +12,6 @@ export * from './observe-multiple.function.js';
12
12
  export * from './partial-update-frozen-array.function.js';
13
13
  export * from './push-at-to-unique-array.function.js';
14
14
  export * from './push-to-unique-array.function.js';
15
+ export * from './replace-in-unique-array.function.js';
15
16
  export * from './simple-hash-code.function.js';
16
17
  export * from './strict-equality-memoization.function.js';
@@ -12,5 +12,6 @@ export * from './observe-multiple.function.js';
12
12
  export * from './partial-update-frozen-array.function.js';
13
13
  export * from './push-at-to-unique-array.function.js';
14
14
  export * from './push-to-unique-array.function.js';
15
+ export * from './replace-in-unique-array.function.js';
15
16
  export * from './simple-hash-code.function.js';
16
17
  export * from './strict-equality-memoization.function.js';
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @function replaceInUniqueArray
3
+ * @param {T[]} data - An array of objects.
4
+ * @param {T} entry - The object to replace with.
5
+ * @param {getUniqueMethod: (entry: T) => unknown} [getUniqueMethod] - Method to get the unique value of an entry.
6
+ * @description - Replaces an item of an Array.
7
+ * @example <caption>Example replace an entry of an Array. Where the key is unique and the item will only be replaced if matched with existing.</caption>
8
+ * const data = [{key: 'myKey', value:'initialValue'}];
9
+ * const entry = {key: 'myKey', value: 'replacedValue'};
10
+ * const newDataSet = replaceInUniqueArray(data, entry, x => x.key === key);
11
+ */
12
+ export declare function replaceInUniqueArray<T>(data: T[], entry: T, getUniqueMethod: (entry: T) => unknown): T[];
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @function replaceInUniqueArray
3
+ * @param {T[]} data - An array of objects.
4
+ * @param {T} entry - The object to replace with.
5
+ * @param {getUniqueMethod: (entry: T) => unknown} [getUniqueMethod] - Method to get the unique value of an entry.
6
+ * @description - Replaces an item of an Array.
7
+ * @example <caption>Example replace an entry of an Array. Where the key is unique and the item will only be replaced if matched with existing.</caption>
8
+ * const data = [{key: 'myKey', value:'initialValue'}];
9
+ * const entry = {key: 'myKey', value: 'replacedValue'};
10
+ * const newDataSet = replaceInUniqueArray(data, entry, x => x.key === key);
11
+ */
12
+ export function replaceInUniqueArray(data, entry, getUniqueMethod) {
13
+ const unique = getUniqueMethod(entry);
14
+ const indexToReplace = data.findIndex((x) => getUniqueMethod(x) === unique);
15
+ if (indexToReplace !== -1) {
16
+ data[indexToReplace] = entry;
17
+ }
18
+ return data;
19
+ }
@@ -92,7 +92,6 @@ export class UmbPickerInputContext extends UmbContextBase {
92
92
  #removeItem(unique) {
93
93
  const newSelection = this.getSelection().filter((value) => value !== unique);
94
94
  this.setSelection(newSelection);
95
- this.#itemManager.removeStatus(unique);
96
95
  this.getHostElement().dispatchEvent(new UmbChangeEvent());
97
96
  }
98
97
  }
@@ -23,6 +23,10 @@ export declare class UmbRepositoryItemsManager<ItemType extends {
23
23
  setUniques(uniques: string[] | undefined): void;
24
24
  getItems(): Array<ItemType>;
25
25
  itemByUnique(unique: string): import("rxjs").Observable<ItemType | undefined>;
26
+ /**
27
+ * @deprecated - This is resolved by setUniques, no need to update statuses.
28
+ * @param unique {string} - The unique identifier of the item to remove the status of.
29
+ */
26
30
  removeStatus(unique: string): void;
27
31
  getItemByUnique(unique: string): Promise<Exclude<ItemType, undefined>>;
28
32
  destroy(): void;
@@ -61,14 +61,17 @@ export class UmbRepositoryItemsManager extends UmbControllerBase {
61
61
  this.observe(this.uniques, (uniques) => {
62
62
  if (uniques.length === 0) {
63
63
  this.#items.setValue([]);
64
+ this.#statuses.setValue([]);
64
65
  return;
65
66
  }
66
67
  // TODO: This could be optimized so we only load the appended items, but this requires that the response checks that an item is still present in uniques. [NL]
67
- // Check if we already have the items, and then just sort them:
68
- const items = this.#items.getValue();
69
- if (uniques.length === items.length &&
70
- uniques.every((unique) => items.find((item) => this.#getUnique(item) === unique))) {
68
+ // Check if we already have the statuses, and then just sort them:
69
+ const statuses = this.#statuses.getValue();
70
+ if (uniques.length === statuses.length &&
71
+ uniques.every((unique) => statuses.find((status) => status.unique === unique))) {
72
+ const items = this.#items.getValue();
71
73
  this.#items.setValue(this.#sortByUniques(items));
74
+ this.#statuses.setValue(this.#sortStatusByUniques(statuses));
72
75
  }
73
76
  else {
74
77
  // We need to load new items, so ...
@@ -93,9 +96,17 @@ export class UmbRepositoryItemsManager extends UmbControllerBase {
93
96
  itemByUnique(unique) {
94
97
  return this.#items.asObservablePart((items) => items.find((item) => this.#getUnique(item) === unique));
95
98
  }
99
+ /**
100
+ * @deprecated - This is resolved by setUniques, no need to update statuses.
101
+ * @param unique {string} - The unique identifier of the item to remove the status of.
102
+ */
96
103
  removeStatus(unique) {
97
- const newStatuses = this.#statuses.getValue().filter((status) => status.unique !== unique);
98
- this.#statuses.setValue(newStatuses);
104
+ new UmbDeprecation({
105
+ removeInVersion: '18.0.0',
106
+ deprecated: 'removeStatus',
107
+ solution: 'Statuses are removed automatically when setting uniques',
108
+ }).warn();
109
+ this.#statuses.filter((status) => status.unique !== unique);
99
110
  }
100
111
  async getItemByUnique(unique) {
101
112
  // TODO: Make an observeOnce feature, to avoid this amount of code: [NL]
@@ -109,7 +120,9 @@ export class UmbRepositoryItemsManager extends UmbControllerBase {
109
120
  if (!this.repository)
110
121
  throw new Error('Repository is not initialized');
111
122
  const requestedUniques = this.getUniques();
112
- this.#statuses.setValue(requestedUniques.map((unique) => ({
123
+ this.#statuses.setValue(
124
+ // No need to do sorting here as we just got the unique in the right order above.
125
+ requestedUniques.map((unique) => ({
113
126
  state: {
114
127
  type: 'loading',
115
128
  },
@@ -125,7 +138,7 @@ export class UmbRepositoryItemsManager extends UmbControllerBase {
125
138
  return;
126
139
  }
127
140
  if (error) {
128
- this.#statuses.append(requestedUniques.map((unique) => ({
141
+ this.#statuses.replace(requestedUniques.map((unique) => ({
129
142
  state: {
130
143
  type: 'error',
131
144
  error: '#general_error',
@@ -140,7 +153,7 @@ export class UmbRepositoryItemsManager extends UmbControllerBase {
140
153
  const rejectedUniques = requestedUniques.filter((unique) => !data.find((item) => this.#getUnique(item) === unique));
141
154
  const resolvedUniques = requestedUniques.filter((unique) => !rejectedUniques.includes(unique));
142
155
  this.#items.remove(rejectedUniques);
143
- this.#statuses.append([
156
+ this.#statuses.replace([
144
157
  ...rejectedUniques.map((unique) => ({
145
158
  state: {
146
159
  type: 'error',
@@ -168,12 +181,11 @@ export class UmbRepositoryItemsManager extends UmbControllerBase {
168
181
  throw new Error('Repository is not initialized');
169
182
  const { data, error } = await this.repository.requestItems([unique]);
170
183
  if (error) {
171
- this.#statuses.appendOne({
184
+ this.#statuses.updateOne(unique, {
172
185
  state: {
173
186
  type: 'error',
174
187
  error: '#general_notFound',
175
188
  },
176
- unique,
177
189
  });
178
190
  }
179
191
  if (data) {
@@ -184,6 +196,7 @@ export class UmbRepositoryItemsManager extends UmbControllerBase {
184
196
  const newItems = [...items];
185
197
  newItems[index] = data[0];
186
198
  this.#items.setValue(this.#sortByUniques(newItems));
199
+ // No need to update statuses here, as the item is the same, just updated.
187
200
  }
188
201
  }
189
202
  }
@@ -197,6 +210,17 @@ export class UmbRepositoryItemsManager extends UmbControllerBase {
197
210
  return aIndex - bIndex;
198
211
  });
199
212
  }
213
+ /** Just needed for the deprecation implementation to work, do not bring this into 17.0 [NL] */
214
+ #sortStatusByUniques(data) {
215
+ if (!data)
216
+ return [];
217
+ const uniques = this.getUniques();
218
+ return [...data].sort((a, b) => {
219
+ const aIndex = uniques.indexOf(a.unique ?? '');
220
+ const bIndex = uniques.indexOf(b.unique ?? '');
221
+ return aIndex - bIndex;
222
+ });
223
+ }
200
224
  #onEntityUpdatedEvent;
201
225
  destroy() {
202
226
  this.#eventContext?.removeEventListener(UmbEntityUpdatedEvent.TYPE, this.#onEntityUpdatedEvent);