@vc-shell/framework 1.1.22 → 1.1.24

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.
Files changed (78) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/core/composables/useAppInsights/index.ts +11 -1
  3. package/core/composables/useBladeRegistry/index.ts +176 -0
  4. package/core/composables/useDynamicProperties/index.ts +380 -255
  5. package/core/composables/useErrorHandler/index.ts +2 -3
  6. package/core/composables/useLanguages/index.ts +78 -78
  7. package/core/plugins/modularity/index.ts +17 -6
  8. package/core/services/global-search-service/index.ts +36 -0
  9. package/dist/core/composables/useAppInsights/index.d.ts +5 -2
  10. package/dist/core/composables/useAppInsights/index.d.ts.map +1 -1
  11. package/dist/core/composables/useBladeRegistry/index.d.ts +48 -0
  12. package/dist/core/composables/useBladeRegistry/index.d.ts.map +1 -0
  13. package/dist/core/composables/useDynamicProperties/index.d.ts +11 -9
  14. package/dist/core/composables/useDynamicProperties/index.d.ts.map +1 -1
  15. package/dist/core/composables/useErrorHandler/index.d.ts.map +1 -1
  16. package/dist/core/plugins/modularity/index.d.ts.map +1 -1
  17. package/dist/core/services/global-search-service/index.d.ts +10 -0
  18. package/dist/core/services/global-search-service/index.d.ts.map +1 -0
  19. package/dist/framework.js +1 -1
  20. package/dist/{index-BQtOyLub.js → index-BLmjssqE.js} +1 -1
  21. package/dist/{index-C_zSZ2pX.js → index-BYcoxn-f.js} +1 -1
  22. package/dist/{index-wjw1DwqR.js → index-BbuBDu8A.js} +1 -1
  23. package/dist/{index-DqDgL4W3.js → index-BnqqEJTE.js} +1 -1
  24. package/dist/{index--KQZx7Nr.js → index-Br7ZwtRW.js} +1 -1
  25. package/dist/{index-DwjKpYAo.js → index-CGL9e-cM.js} +1 -1
  26. package/dist/{index-DoHQrH4a.js → index-CIzLBvgg.js} +1 -1
  27. package/dist/{index-DFdFt54f.js → index-CLAYu8Qj.js} +1 -1
  28. package/dist/{index-BxrA7EzT.js → index-CRwMOCjN.js} +1 -1
  29. package/dist/{index-DL0-yUXC.js → index-Cmbxdwnl.js} +1 -1
  30. package/dist/{index-Bf4s6An9.js → index-Cxkjjuah.js} +1 -1
  31. package/dist/{index-xCbUzsUb.js → index-DAnceKLv.js} +1 -1
  32. package/dist/{index-BAngL0ix.js → index-Dk1K3-27.js} +1 -1
  33. package/dist/{index-d16x5dY_.js → index-DoArZBIw.js} +1 -1
  34. package/dist/{index-C-y5H4_R.js → index-DvenBxy6.js} +45753 -45502
  35. package/dist/{index-DI3UVoln.js → index-cuex9jil.js} +1 -1
  36. package/dist/{index--F0eI_oT.js → index-eOG-NNYN.js} +1 -1
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/index.d.ts +7 -12
  39. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/index.d.ts.map +1 -1
  40. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeActions.d.ts +15 -0
  41. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeActions.d.ts.map +1 -0
  42. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeRouteResolver.d.ts +11 -0
  43. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeRouteResolver.d.ts.map +1 -0
  44. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeState.d.ts +15 -0
  45. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeState.d.ts.map +1 -0
  46. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeWatchers.d.ts +6 -0
  47. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeWatchers.d.ts.map +1 -0
  48. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/internal/routerUtils.d.ts +28 -0
  49. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/internal/routerUtils.d.ts.map +1 -0
  50. package/dist/shared/components/blade-navigation/plugin.d.ts.map +1 -1
  51. package/dist/shared/components/blade-navigation/types/index.d.ts +5 -5
  52. package/dist/shared/components/blade-navigation/types/index.d.ts.map +1 -1
  53. package/dist/shared/components/notification-template/notification-template.vue.d.ts +2 -2
  54. package/dist/shared/components/notification-template/notification-template.vue.d.ts.map +1 -1
  55. package/dist/shared/modules/dynamic/components/fields/storybook/pages/DynamicRender.d.ts +1 -9
  56. package/dist/shared/modules/dynamic/components/fields/storybook/pages/DynamicRender.d.ts.map +1 -1
  57. package/dist/shared/modules/dynamic/index.d.ts.map +1 -1
  58. package/dist/shared/modules/dynamic/pages/dynamic-blade-form.vue.d.ts +2 -18
  59. package/dist/shared/modules/dynamic/pages/dynamic-blade-form.vue.d.ts.map +1 -1
  60. package/dist/tsconfig.tsbuildinfo +1 -1
  61. package/dist/ui/components/molecules/vc-input-dropdown/vc-input-dropdown.vue.d.ts +2 -0
  62. package/dist/ui/components/molecules/vc-input-dropdown/vc-input-dropdown.vue.d.ts.map +1 -1
  63. package/dist/ui/components/organisms/vc-app/vc-app.vue.d.ts.map +1 -1
  64. package/dist/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue.d.ts.map +1 -1
  65. package/package.json +4 -4
  66. package/shared/components/blade-navigation/composables/useBladeNavigation/index.ts +199 -597
  67. package/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeActions.ts +151 -0
  68. package/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeRouteResolver.ts +243 -0
  69. package/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeState.ts +93 -0
  70. package/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeWatchers.ts +90 -0
  71. package/shared/components/blade-navigation/composables/useBladeNavigation/internal/routerUtils.ts +150 -0
  72. package/shared/components/blade-navigation/plugin.ts +17 -12
  73. package/shared/components/blade-navigation/types/index.ts +2 -4
  74. package/shared/components/notification-template/notification-template.vue +2 -2
  75. package/shared/modules/dynamic/index.ts +2 -8
  76. package/ui/components/molecules/vc-input-dropdown/vc-input-dropdown.vue +4 -0
  77. package/ui/components/organisms/vc-app/vc-app.vue +11 -6
  78. package/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue +10 -1
@@ -1,9 +1,9 @@
1
1
  import { useLoading } from "../useLoading";
2
2
  import { useAsync } from "../useAsync";
3
- import * as _ from "lodash-es";
4
3
  import { ComputedRef } from "vue";
5
4
 
6
- // Base interfaces that can be extended by specific API client types
5
+ // === TYPE DEFINITIONS ===
6
+
7
7
  export interface IBaseProperty<TPropertyValue> {
8
8
  id?: string | null;
9
9
  name?: string | null;
@@ -11,7 +11,7 @@ export interface IBaseProperty<TPropertyValue> {
11
11
  multilanguage?: boolean | null;
12
12
  multivalue?: boolean | null;
13
13
  dictionary?: boolean | null;
14
- valueType?: string | null; // Consider using a more specific enum if possible
14
+ valueType?: string | null;
15
15
  unitOfMeasureId?: string | null;
16
16
  }
17
17
 
@@ -68,26 +68,47 @@ export interface IUseDynamicProperties<
68
68
  property: TProperty,
69
69
  locale: string,
70
70
  ) => string | TPropertyValue[] | (TPropertyDictionaryItem & { value: string })[];
71
- setPropertyValue: (data: {
72
- property: TProperty;
73
- value: string | TPropertyValue[] | (TPropertyDictionaryItem & { value: string })[];
74
- dictionary?: TPropertyDictionaryItem[];
75
- locale?: string;
76
- initialProp?: TProperty;
77
- }) => void;
71
+ setPropertyValue: (data: SetPropertyValueParams<TProperty, TPropertyValue, TPropertyDictionaryItem>) => void;
78
72
  loadMeasurements(measureId: string, keyword?: string, locale?: string): Promise<TMeasurement[] | undefined>;
79
73
  }
80
74
 
81
- function isEmptyValues(value: unknown) {
82
- return (
83
- value === undefined ||
84
- value === null ||
85
- (typeof value === "number" && isNaN(value)) ||
86
- (typeof value === "object" && Object.keys(value).length === 0) ||
87
- (typeof value === "string" && value.trim().length === 0)
88
- );
75
+ export interface SetPropertyValueParams<TProperty, TPropertyValue, TPropertyDictionaryItem> {
76
+ property: TProperty;
77
+ value: string | TPropertyValue[] | (TPropertyDictionaryItem & { value: string })[];
78
+ dictionary?: TPropertyDictionaryItem[];
79
+ locale?: string;
80
+ initialProp?: TProperty;
81
+ unitOfMeasureId?: string;
82
+ }
83
+
84
+ // === UTILITY FUNCTIONS ===
85
+
86
+ function isEmptyValue(value: unknown): boolean {
87
+ if (value === undefined || value === null) return true;
88
+ if (typeof value === "number" && isNaN(value)) return true;
89
+ if (typeof value === "string" && value.trim().length === 0) return true;
90
+ if (typeof value === "object" && Object.keys(value).length === 0) return true;
91
+ return false;
92
+ }
93
+
94
+ function isMultilanguageProperty<T extends IBaseProperty<unknown>>(property: T): boolean {
95
+ return Boolean(property.multilanguage);
96
+ }
97
+
98
+ function isMultivalueProperty<T extends IBaseProperty<unknown>>(property: T): boolean {
99
+ return Boolean(property.multivalue);
89
100
  }
90
101
 
102
+ function isDictionaryProperty<T extends IBaseProperty<unknown>>(property: T): boolean {
103
+ return Boolean(property.dictionary);
104
+ }
105
+
106
+ function isMeasureProperty<T extends IBaseProperty<unknown>>(property: T): boolean {
107
+ return property.valueType === "Measure";
108
+ }
109
+
110
+ // === MAIN COMPOSABLE ===
111
+
91
112
  export const useDynamicProperties = <
92
113
  TProperty extends IBaseProperty<TPropertyValue>,
93
114
  TPropertyValue extends IBasePropertyValue,
@@ -102,274 +123,378 @@ export const useDynamicProperties = <
102
123
  PropertyDictionaryItemConstructor: new (data?: Partial<TPropertyDictionaryItem>) => TPropertyDictionaryItem,
103
124
  searchMeasurementFunction?: (measureId: string, locale?: string) => Promise<TMeasurement[] | undefined>,
104
125
  ): IUseDynamicProperties<TProperty, TPropertyValue, TPropertyDictionaryItem, TPropertyDictionaryItemSearchCriteria> => {
126
+ // === ASYNC OPERATIONS ===
127
+
105
128
  const { loading: dictionaryItemsLoading, action: searchDictionaryItems } = useAsync<
106
129
  TPropertyDictionaryItemSearchCriteria,
107
130
  TPropertyDictionaryItem[] | undefined
108
131
  >(async (args: TPropertyDictionaryItemSearchCriteria | undefined) => {
109
- if (args === undefined) {
110
- return undefined;
111
- }
132
+ if (!args) return undefined;
112
133
  return await searchDictionaryItemsFunction(args);
113
134
  });
114
135
 
115
- function getPropertyValue(property: TProperty, locale: string) {
116
- if (property.multilanguage) {
117
- const propValue = property.values?.find((x) => x.languageCode == locale);
118
-
119
- if (property.multivalue) {
120
- return property.values?.filter((x) => x.languageCode === locale) as TPropertyValue[];
121
- } else if (!propValue) {
122
- const aliasProp = property.values?.find((x) => x.propertyId === property.id);
123
-
124
- if (aliasProp) {
125
- property.values?.push(
126
- new PropertyValueConstructor({
127
- propertyName: property.name,
128
- propertyId: property.id,
129
- languageCode: locale,
130
- alias: aliasProp?.alias,
131
- valueType: property.valueType,
132
- valueId: aliasProp?.valueId,
133
- } as unknown as Partial<TPropertyValue>),
134
- );
135
- }
136
- }
136
+ async function loadDictionaries(propertyId: string, keyword?: string, locale?: string) {
137
+ if (!propertyId) return undefined;
138
+
139
+ const dictionaryItems = await searchDictionaryItems({
140
+ propertyIds: [propertyId],
141
+ keyword,
142
+ skip: 0,
143
+ } as TPropertyDictionaryItemSearchCriteria);
144
+
145
+ if (!locale || !dictionaryItems) return dictionaryItems;
137
146
 
138
- if (property.dictionary) {
139
- return (propValue && propValue?.valueId) as string;
147
+ return dictionaryItems.map((item: TPropertyDictionaryItem) => {
148
+ const localizedValue = item.localizedValues?.find((localized) => localized.languageCode === locale)?.value;
149
+
150
+ return Object.assign(new PropertyDictionaryItemConstructor(item), {
151
+ value: localizedValue ?? item.alias,
152
+ });
153
+ });
154
+ }
155
+
156
+ async function loadMeasurements(measureId: string, locale?: string) {
157
+ if (!measureId || !searchMeasurementFunction) return undefined;
158
+ return await searchMeasurementFunction(measureId, locale);
159
+ }
160
+
161
+ // === VALUE GETTERS ===
162
+
163
+ function getMultilanguageValue(property: TProperty, locale: string): string | TPropertyValue[] {
164
+ const valueForLocale = property.values?.find((x) => x.languageCode === locale);
165
+
166
+ if (isMultivalueProperty(property)) {
167
+ return property.values?.filter((x) => x.languageCode === locale) as TPropertyValue[];
168
+ }
169
+
170
+ // Create default value if not exists
171
+ if (!valueForLocale) {
172
+ const aliasValue = property.values?.find((x) => x.propertyId === property.id);
173
+ if (aliasValue) {
174
+ const newValue = new PropertyValueConstructor({
175
+ propertyName: property.name,
176
+ propertyId: property.id,
177
+ languageCode: locale,
178
+ alias: aliasValue.alias,
179
+ valueType: property.valueType,
180
+ valueId: aliasValue.valueId,
181
+ } as unknown as Partial<TPropertyValue>);
182
+
183
+ property.values?.push(newValue);
140
184
  }
141
- return propValue?.value as string;
185
+ }
186
+
187
+ if (isDictionaryProperty(property)) {
188
+ return valueForLocale?.valueId as string;
189
+ }
190
+
191
+ return valueForLocale?.value as string;
192
+ }
193
+
194
+ function getSingleLanguageValue(property: TProperty): string | TPropertyValue[] {
195
+ if (isMultivalueProperty(property)) {
196
+ return property.values as TPropertyValue[];
197
+ }
198
+
199
+ const firstValue = property.values?.[0];
200
+ if (!firstValue) return "";
201
+
202
+ if (isDictionaryProperty(property)) {
203
+ return firstValue.valueId as string;
204
+ }
205
+
206
+ return firstValue.value as string;
207
+ }
208
+
209
+ function getPropertyValue(property: TProperty, locale: string) {
210
+ if (isMultilanguageProperty(property)) {
211
+ return getMultilanguageValue(property, locale);
212
+ }
213
+ return getSingleLanguageValue(property);
214
+ }
215
+
216
+ // === VALUE SETTERS ===
217
+
218
+ function createPropertyValue(params: Partial<TPropertyValue>): TPropertyValue {
219
+ return new PropertyValueConstructor({
220
+ isInherited: false,
221
+ ...params,
222
+ } as unknown as Partial<TPropertyValue>);
223
+ }
224
+
225
+ function setMeasurePropertyValue(property: TProperty, value: unknown, unitOfMeasureId?: string): void {
226
+ property.values = [
227
+ createPropertyValue({
228
+ value,
229
+ unitOfMeasureId,
230
+ } as Partial<TPropertyValue>),
231
+ ];
232
+ }
233
+
234
+ function setDictionaryPropertyValue(
235
+ property: TProperty,
236
+ value: string | TPropertyValue[] | (TPropertyDictionaryItem & { value: string })[],
237
+ dictionary: TPropertyDictionaryItem[],
238
+ ): void {
239
+ const dict = dictionary.map((x) => new PropertyDictionaryItemConstructor(x));
240
+
241
+ if (isMultilanguageProperty(property)) {
242
+ handleMultilanguageDictionary(property, value, dict);
142
243
  } else {
143
- if (property.multivalue) {
144
- return property.values as TPropertyValue[];
244
+ handleSingleLanguageDictionary(property, value, dict);
245
+ }
246
+ }
247
+
248
+ function handleMultilanguageDictionary(
249
+ property: TProperty,
250
+ value: string | TPropertyValue[] | (TPropertyDictionaryItem & { value: string })[],
251
+ dict: TPropertyDictionaryItem[],
252
+ ): void {
253
+ if (Array.isArray(value)) {
254
+ handleMultilanguageMultivalueDictionary(property, value as (TPropertyDictionaryItem & { value: string })[], dict);
255
+ } else {
256
+ handleMultilanguageSingleValueDictionary(property, value as string, dict);
257
+ }
258
+ }
259
+
260
+ function handleMultilanguageMultivalueDictionary(
261
+ property: TProperty,
262
+ values: (TPropertyDictionaryItem & { value: string })[],
263
+ dict: TPropertyDictionaryItem[],
264
+ ): void {
265
+ property.values = values.flatMap((item) => {
266
+ const dictItem = dict.find((x) => x.id === (item as unknown as TPropertyValue).valueId || x.id === item.id);
267
+
268
+ if (dictItem?.localizedValues?.length) {
269
+ return dictItem.localizedValues.map((locValue) =>
270
+ createPropertyValue({
271
+ propertyId: dictItem.propertyId,
272
+ alias: dictItem.alias,
273
+ languageCode: locValue.languageCode,
274
+ value: locValue.value ?? dictItem.alias,
275
+ valueId: dictItem.id,
276
+ } as Partial<TPropertyValue>),
277
+ );
145
278
  }
146
- if (property.dictionary) {
147
- return property.values?.[0]?.valueId as string;
279
+
280
+ return createPropertyValue(item as unknown as Partial<TPropertyValue>);
281
+ });
282
+ }
283
+
284
+ function handleMultilanguageSingleValueDictionary(
285
+ property: TProperty,
286
+ value: string,
287
+ dict: TPropertyDictionaryItem[],
288
+ ): void {
289
+ const dictionaryItem = dict.find((x) => x.id === value);
290
+
291
+ if (dictionaryItem?.localizedValues) {
292
+ property.values = dictionaryItem.localizedValues.map((locValue) =>
293
+ createPropertyValue({
294
+ propertyId: dictionaryItem.propertyId,
295
+ alias: dictionaryItem.alias,
296
+ languageCode: locValue.languageCode,
297
+ value: locValue.value ?? dictionaryItem.alias,
298
+ valueId: dictionaryItem.id,
299
+ } as Partial<TPropertyValue>),
300
+ );
301
+ } else {
302
+ property.values = [];
303
+ }
304
+ }
305
+
306
+ function handleSingleLanguageDictionary(
307
+ property: TProperty,
308
+ value: string | TPropertyValue[] | (TPropertyDictionaryItem & { value: string })[],
309
+ dict: TPropertyDictionaryItem[],
310
+ ): void {
311
+ if (Array.isArray(value)) {
312
+ handleSingleLanguageMultivalueDictionary(
313
+ property,
314
+ value as (TPropertyDictionaryItem & { value: string })[],
315
+ dict,
316
+ );
317
+ } else {
318
+ handleSingleLanguageSingleValueDictionary(property, value as string, dict);
319
+ }
320
+ }
321
+
322
+ function handleSingleLanguageMultivalueDictionary(
323
+ property: TProperty,
324
+ values: (TPropertyDictionaryItem & { value: string })[],
325
+ dict: TPropertyDictionaryItem[],
326
+ ): void {
327
+ property.values = values.flatMap((item) => {
328
+ const dictItem = dict.find((x) => x.id === (item as unknown as TPropertyValue).valueId || x.id === item.id);
329
+
330
+ if (dictItem) {
331
+ return createPropertyValue({
332
+ propertyId: dictItem.propertyId,
333
+ alias: dictItem.alias,
334
+ value: item.value ?? dictItem.alias,
335
+ valueId: dictItem.id,
336
+ } as Partial<TPropertyValue>);
148
337
  }
149
- return property.values?.[0]?.value as string;
338
+
339
+ return createPropertyValue(item as unknown as Partial<TPropertyValue>);
340
+ });
341
+ }
342
+
343
+ function handleSingleLanguageSingleValueDictionary(
344
+ property: TProperty,
345
+ value: string,
346
+ dict: TPropertyDictionaryItem[],
347
+ ): void {
348
+ if (isEmptyValue(value)) {
349
+ property.values = [];
350
+ return;
150
351
  }
352
+
353
+ const dictionaryItem = dict.find((x) => x.id === value);
354
+ property.values = [
355
+ createPropertyValue({
356
+ propertyId: dictionaryItem?.propertyId,
357
+ alias: dictionaryItem?.alias,
358
+ value: (dictionaryItem as TPropertyDictionaryItem & { value: string })?.value ?? dictionaryItem?.alias,
359
+ valueId: value,
360
+ } as Partial<TPropertyValue>),
361
+ ];
151
362
  }
152
363
 
153
- async function loadDictionaries(propertyId: string, keyword?: string, locale?: string) {
154
- if (propertyId) {
155
- let dictionaryItems = await searchDictionaryItems({
156
- propertyIds: [propertyId],
157
- keyword,
158
- skip: 0,
159
- } as TPropertyDictionaryItemSearchCriteria);
160
- if (locale) {
161
- dictionaryItems = dictionaryItems?.map((x: TPropertyDictionaryItem) => {
162
- const localizedValue = x.localizedValues?.find(
163
- (v: { languageCode?: string | null; value?: string | null }) => v.languageCode == locale,
164
- )?.value;
165
- return Object.assign(new PropertyDictionaryItemConstructor(x), {
166
- value: localizedValue ?? x.alias,
167
- });
168
- });
364
+ function setRegularPropertyValue(
365
+ property: TProperty,
366
+ value: string | TPropertyValue[] | (TPropertyDictionaryItem & { value: string })[],
367
+ locale?: string,
368
+ initialProp?: TProperty,
369
+ ): void {
370
+ if (isMultilanguageProperty(property)) {
371
+ handleMultilanguageRegularProperty(property, value, locale);
372
+ } else {
373
+ handleSingleLanguageRegularProperty(property, value, locale, initialProp);
374
+ }
375
+ }
376
+
377
+ function handleMultilanguageRegularProperty(
378
+ property: TProperty,
379
+ value: string | TPropertyValue[] | (TPropertyDictionaryItem & { value: string })[],
380
+ locale?: string,
381
+ ): void {
382
+ if (Array.isArray(value)) {
383
+ // Multivalue multilanguage
384
+ property.values =
385
+ property.values &&
386
+ ([
387
+ ...property.values.filter((x) => x.languageCode !== locale),
388
+ ...(value as TPropertyValue[]).map((item) =>
389
+ createPropertyValue({ ...item, languageCode: locale } as Partial<TPropertyValue>),
390
+ ),
391
+ ] as TPropertyValue[]);
392
+ } else {
393
+ // Single value multilanguage
394
+ const existingValue = property.values?.find((x) => x.languageCode === locale);
395
+ if (existingValue) {
396
+ existingValue.value = value as string;
397
+ } else {
398
+ property.values = [
399
+ createPropertyValue({
400
+ value: value as string,
401
+ languageCode: locale,
402
+ } as Partial<TPropertyValue>),
403
+ ];
169
404
  }
170
- return dictionaryItems;
171
405
  }
172
406
  }
173
407
 
174
- async function loadMeasurements(measureId: string, locale?: string) {
175
- if (!measureId || !searchMeasurementFunction) return undefined;
176
- return await searchMeasurementFunction(measureId, locale);
408
+ function handleSingleLanguageRegularProperty(
409
+ property: TProperty,
410
+ value: string | TPropertyValue[] | (TPropertyDictionaryItem & { value: string })[],
411
+ locale?: string,
412
+ initialProp?: TProperty,
413
+ ): void {
414
+ if (Array.isArray(value)) {
415
+ // Multivalue
416
+ property.values = (value as TPropertyValue[]).map((item) => createPropertyValue(item as Partial<TPropertyValue>));
417
+ } else {
418
+ handleSingleValueRegularProperty(property, value, locale, initialProp);
419
+ }
177
420
  }
178
421
 
179
- function isMeasureObject(val: unknown): val is { value: unknown; unitOfMeasureId?: string; measureId?: string } {
180
- return !!val && typeof val === "object" && "value" in val && ("unitOfMeasureId" in val || "measureId" in val);
422
+ function handleSingleValueRegularProperty(
423
+ property: TProperty,
424
+ value: string | (TPropertyDictionaryItem & { value: string }),
425
+ locale?: string,
426
+ initialProp?: TProperty,
427
+ ): void {
428
+ if (typeof value === "boolean") {
429
+ handleBooleanValue(property, value, initialProp);
430
+ } else if (isEmptyValue(value)) {
431
+ handleEmptyValue(property, value, locale, initialProp);
432
+ } else {
433
+ handleNonEmptyValue(property, value as string);
434
+ }
181
435
  }
182
436
 
183
- function setPropertyValue(data: {
184
- property: TProperty;
185
- value: string | TPropertyValue[] | (TPropertyDictionaryItem & { value: string })[];
186
- dictionary?: TPropertyDictionaryItem[];
187
- locale?: string;
188
- initialProp?: TProperty;
189
- unitOfMeasureId?: string;
190
- }) {
191
- const { property, value, dictionary, locale } = data;
192
-
193
- if (property.valueType === "Measure") {
437
+ function handleBooleanValue(property: TProperty, value: boolean, initialProp?: TProperty): void {
438
+ if (initialProp?.values?.length) {
194
439
  property.values = [
195
- new PropertyValueConstructor({
196
- value,
197
- unitOfMeasureId: data.unitOfMeasureId,
198
- isInherited: false,
199
- } as unknown as Partial<TPropertyValue>),
440
+ property.values?.[0]
441
+ ? Object.assign(property.values[0], { value })
442
+ : createPropertyValue({ value } as Partial<TPropertyValue>),
200
443
  ];
201
- return;
444
+ } else if (value) {
445
+ property.values = [createPropertyValue({ value } as Partial<TPropertyValue>)];
446
+ } else {
447
+ property.values = [];
202
448
  }
449
+ }
203
450
 
204
- if (dictionary && dictionary.length > 0) {
205
- const dict = dictionary.map((x) => new PropertyDictionaryItemConstructor(x));
206
-
207
- if (property.multilanguage) {
208
- // Multivalue Dictionary Multilanguage
209
- if (Array.isArray(value)) {
210
- property.values = (value as (TPropertyDictionaryItem & { value: string })[]).flatMap((item) => {
211
- const dictItem = dict.find((x) => x.id === (item as unknown as TPropertyValue).valueId || x.id === item.id);
212
- if (dictItem?.localizedValues?.length) {
213
- return dictItem.localizedValues.map(
214
- (x) =>
215
- new PropertyValueConstructor({
216
- propertyId: dictItem.propertyId,
217
- alias: dictItem.alias,
218
- languageCode: x.languageCode,
219
- value: x.value ?? dictItem.alias,
220
- valueId: dictItem.id,
221
- } as unknown as Partial<TPropertyValue>),
222
- );
223
- }
224
- return new PropertyValueConstructor(item as unknown as Partial<TPropertyValue>);
225
- });
226
- }
227
- // Single value Dictionary Multilanguage
228
- else {
229
- const dictionaryItem = dictionary.find((x) => x.id === (value as string));
230
- if (dictionaryItem) {
231
- property.values = dictionaryItem?.localizedValues?.map(
232
- (x) =>
233
- new PropertyValueConstructor({
234
- propertyId: dictionaryItem.propertyId,
235
- alias: dictionaryItem.alias,
236
- languageCode: x.languageCode,
237
- value: x.value ?? dictionaryItem.alias,
238
- valueId: dictionaryItem.id,
239
- } as unknown as Partial<TPropertyValue>),
240
- );
241
- } else {
242
- property.values = [];
243
- }
244
- }
245
- } else {
246
- // Multivalue Dictionary
247
- if (Array.isArray(value)) {
248
- property.values = (value as (TPropertyDictionaryItem & { value: string })[]).flatMap((item) => {
249
- const dictItem = dict.find((x) => x.id === (item as unknown as TPropertyValue).valueId || x.id === item.id);
250
- if (dictItem) {
251
- return new PropertyValueConstructor({
252
- propertyId: dictItem.propertyId,
253
- alias: dictItem.alias,
254
- value: item.value ?? dictItem.alias,
255
- valueId: dictItem.id,
256
- } as unknown as Partial<TPropertyValue>);
257
- }
258
- return new PropertyValueConstructor(item as unknown as Partial<TPropertyValue>);
259
- });
260
- }
261
- // Single value Dictionary
262
- else {
263
- const dictionaryItem = dictionary.find((x) => x.id === (value as string));
264
-
265
- if (isEmptyValues(value)) {
266
- property.values = [];
267
- } else {
268
- property.values = [
269
- new PropertyValueConstructor({
270
- propertyId: dictionaryItem?.propertyId,
271
- alias: dictionaryItem?.alias,
272
- value: (dictionaryItem as TPropertyDictionaryItem & { value: string })?.value ?? dictionaryItem?.alias,
273
- valueId: value as string,
274
- } as unknown as Partial<TPropertyValue>),
275
- ];
276
- }
277
- }
278
- }
451
+ function handleEmptyValue(property: TProperty, value: unknown, locale?: string, initialProp?: TProperty): void {
452
+ const hadOriginalValue = initialProp?.values?.find((v) =>
453
+ isMultilanguageProperty(property) ? v.languageCode === locale : true,
454
+ )?.value;
455
+
456
+ const originalWasEmpty = isEmptyValue(hadOriginalValue);
457
+
458
+ if (originalWasEmpty) {
459
+ property.values = [
460
+ createPropertyValue({
461
+ value: value as string,
462
+ languageCode: isMultilanguageProperty(property) ? locale : undefined,
463
+ } as Partial<TPropertyValue>),
464
+ ];
279
465
  } else {
280
- if (property.multilanguage) {
281
- // Multivalue Multilanguage
282
- if (Array.isArray(value)) {
283
- property.values =
284
- property.values &&
285
- ([
286
- ...property.values.filter((x) => x.languageCode !== locale),
287
- ...(value as TPropertyValue[]).map(
288
- (item) =>
289
- new PropertyValueConstructor({ ...item, languageCode: locale } as unknown as Partial<TPropertyValue>),
290
- ),
291
- ] as TPropertyValue[]);
292
- }
293
- // Single value Multilanguage
294
- else {
295
- const propValue = property.values?.find((x) => x.languageCode == locale);
296
- if (propValue) {
297
- propValue.value = value as string;
298
- } else {
299
- property.values = [
300
- new PropertyValueConstructor({
301
- value: value as string,
302
- isInherited: false,
303
- languageCode: locale,
304
- } as unknown as Partial<TPropertyValue>),
305
- ];
306
- }
307
- }
308
- } else {
309
- // Multivalue
310
- if (Array.isArray(value)) {
311
- property.values = (value as TPropertyValue[]).map(
312
- (item) => new PropertyValueConstructor(item as unknown as Partial<TPropertyValue>),
313
- );
314
- }
315
- // Single value
316
- else {
317
- if (typeof value === "boolean") {
318
- if (data.initialProp?.values?.length) {
319
- property.values = [
320
- property.values?.[0]
321
- ? Object.assign(property.values[0], { value })
322
- : new PropertyValueConstructor({
323
- value: value,
324
- isInherited: false,
325
- } as unknown as Partial<TPropertyValue>),
326
- ];
327
- } else {
328
- if (value) {
329
- property.values = [
330
- new PropertyValueConstructor({
331
- value: value,
332
- isInherited: false,
333
- } as unknown as Partial<TPropertyValue>),
334
- ];
335
- } else {
336
- property.values = [];
337
- }
338
- }
339
- } else if (isEmptyValues(value)) {
340
- // Ensure we create an empty PropertyValue if the original value was also empty, to signify an explicit clear.
341
- // Otherwise, if there was a value and now it's empty, we clear the values array.
342
- const hadOriginalValue = data.initialProp?.values?.find((v) =>
343
- property.multilanguage ? v.languageCode === locale : true,
344
- )?.value;
345
- const originalValueWasEmpty = isEmptyValues(hadOriginalValue);
346
-
347
- if (originalValueWasEmpty) {
348
- property.values = [
349
- new PropertyValueConstructor({
350
- value: value as string,
351
- isInherited: false,
352
- languageCode: property.multilanguage ? locale : undefined,
353
- } as unknown as Partial<TPropertyValue>),
354
- ];
355
- } else {
356
- property.values = [];
357
- }
358
- } else {
359
- property.values = property.values?.[0]
360
- ? [Object.assign(property.values[0], { value: value as string })]
361
- : [
362
- new PropertyValueConstructor({
363
- value: value as string,
364
- isInherited: false,
365
- } as unknown as Partial<TPropertyValue>),
366
- ];
367
- }
368
- }
369
- }
466
+ property.values = [];
370
467
  }
371
468
  }
372
469
 
470
+ function handleNonEmptyValue(property: TProperty, value: string): void {
471
+ if (property.values?.[0]) {
472
+ Object.assign(property.values[0], { value });
473
+ } else {
474
+ property.values = [createPropertyValue({ value } as Partial<TPropertyValue>)];
475
+ }
476
+ }
477
+
478
+ // === MAIN SET PROPERTY VALUE FUNCTION ===
479
+
480
+ function setPropertyValue(params: SetPropertyValueParams<TProperty, TPropertyValue, TPropertyDictionaryItem>): void {
481
+ const { property, value, dictionary, locale, initialProp, unitOfMeasureId } = params;
482
+
483
+ if (isMeasureProperty(property)) {
484
+ setMeasurePropertyValue(property, value, unitOfMeasureId);
485
+ return;
486
+ }
487
+
488
+ if (dictionary?.length) {
489
+ setDictionaryPropertyValue(property, value, dictionary);
490
+ return;
491
+ }
492
+
493
+ setRegularPropertyValue(property, value, locale, initialProp);
494
+ }
495
+
496
+ // === RETURN API ===
497
+
373
498
  const loading = useLoading(dictionaryItemsLoading);
374
499
 
375
500
  return {