@acorex/platform 21.0.0-beta.0 → 21.0.0-beta.10

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 (44) hide show
  1. package/fesm2022/acorex-platform-auth.mjs +4 -0
  2. package/fesm2022/acorex-platform-auth.mjs.map +1 -1
  3. package/fesm2022/{acorex-platform-common-common-settings.provider-G9XcXXOG.mjs → acorex-platform-common-common-settings.provider-Bi1RYif5.mjs} +58 -22
  4. package/fesm2022/acorex-platform-common-common-settings.provider-Bi1RYif5.mjs.map +1 -0
  5. package/fesm2022/acorex-platform-common.mjs +275 -130
  6. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-core.mjs +106 -5
  8. package/fesm2022/acorex-platform-core.mjs.map +1 -1
  9. package/fesm2022/acorex-platform-layout-builder.mjs +104 -13
  10. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  11. package/fesm2022/acorex-platform-layout-components.mjs +224 -6
  12. package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
  13. package/fesm2022/acorex-platform-layout-designer.mjs +37 -2
  14. package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
  15. package/fesm2022/acorex-platform-layout-entity.mjs +1107 -72
  16. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  17. package/fesm2022/acorex-platform-layout-views.mjs +7 -5
  18. package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
  19. package/fesm2022/acorex-platform-layout-widget-core.mjs +72 -6
  20. package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
  21. package/fesm2022/acorex-platform-layout-widgets.mjs +181 -158
  22. package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
  23. package/fesm2022/acorex-platform-runtime.mjs +65 -2
  24. package/fesm2022/acorex-platform-runtime.mjs.map +1 -1
  25. package/fesm2022/acorex-platform-themes-default.mjs +121 -15
  26. package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
  27. package/fesm2022/{acorex-platform-themes-shared-settings.provider-D13QB3Hr.mjs → acorex-platform-themes-shared-settings.provider-DK6R87Lf.mjs} +23 -24
  28. package/fesm2022/acorex-platform-themes-shared-settings.provider-DK6R87Lf.mjs.map +1 -0
  29. package/fesm2022/acorex-platform-themes-shared.mjs +2 -2
  30. package/fesm2022/acorex-platform-workflow.mjs +85 -4
  31. package/fesm2022/acorex-platform-workflow.mjs.map +1 -1
  32. package/package.json +2 -4
  33. package/types/acorex-platform-common.d.ts +105 -52
  34. package/types/acorex-platform-core.d.ts +26 -3
  35. package/types/acorex-platform-layout-builder.d.ts +26 -3
  36. package/types/acorex-platform-layout-components.d.ts +52 -1
  37. package/types/acorex-platform-layout-entity.d.ts +262 -8
  38. package/types/acorex-platform-layout-widget-core.d.ts +15 -0
  39. package/types/acorex-platform-layout-widgets.d.ts +33 -23
  40. package/types/acorex-platform-runtime.d.ts +6 -0
  41. package/types/acorex-platform-themes-default.d.ts +8 -0
  42. package/types/acorex-platform-workflow.d.ts +68 -2
  43. package/fesm2022/acorex-platform-common-common-settings.provider-G9XcXXOG.mjs.map +0 -1
  44. package/fesm2022/acorex-platform-themes-shared-settings.provider-D13QB3Hr.mjs.map +0 -1
@@ -4,8 +4,7 @@ import { kebabCase, merge, sortBy, cloneDeep, get, omit } from 'lodash-es';
4
4
  import { Router, ROUTES, RouterModule } from '@angular/router';
5
5
  import { AXPSessionService, AXPSessionStatus } from '@acorex/platform/auth';
6
6
  import { Subject, distinctUntilChanged, merge as merge$1 } from 'rxjs';
7
- import { AXPPlatformScope, AXPBroadcastEventService, objectKeyValueTransforms, AXPSystemActionType, AXPModuleManifestModule, AXPAppStartUpProvider, AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER, AXPHookService, AXPDataGenerator, AXPModuleManifestRegistry } from '@acorex/platform/core';
8
- import { AXTranslationService } from '@acorex/core/translation';
7
+ import { unwrapValueProperty, coerceUnknownToDate, coerceUnknownToFiniteNumber, coerceUnknownToBoolean, coerceUnknownToTrimmedString, AXPPlatformScope, AXPBroadcastEventService, objectKeyValueTransforms, AXPSystemActionType, searchInMultiLanguageString, AXPModuleManifestModule, AXPAppStartUpProvider, AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER, AXPHookService, AXPDataGenerator, AXPModuleManifestRegistry } from '@acorex/platform/core';
9
8
  import { AXPWidgetsCatalog } from '@acorex/platform/layout/widget-core';
10
9
  import { AXPopupModule, AXPopupService } from '@acorex/components/popup';
11
10
  import { AXToastService, AXToastModule } from '@acorex/components/toast';
@@ -15,6 +14,7 @@ import { AXPWorkflowService, createWorkFlowEvent, AXPWorkflowAction, AXPWorkflow
15
14
  import { AXDataSource } from '@acorex/cdk/common';
16
15
  import { AXPCommandExecutor, AXPCommandService } from '@acorex/platform/runtime';
17
16
  import { signalStore, withState, withMethods, patchState, withHooks } from '@ngrx/signals';
17
+ import { AXTranslationService } from '@acorex/core/translation';
18
18
  import { AXFormatService } from '@acorex/core/format';
19
19
  import { AXDialogService } from '@acorex/components/dialog';
20
20
  import { AXFileService } from '@acorex/core/file';
@@ -239,99 +239,16 @@ var AXPRegionalSetting;
239
239
  AXPRegionalSetting["MultiLanguageSupport"] = "LocaleManagement:Setting:Regional.MultiLanguageSupport";
240
240
  })(AXPRegionalSetting || (AXPRegionalSetting = {}));
241
241
 
242
- const AXP_SETTING_VALUE_PROVIDER = new InjectionToken('AXP_SETTING_VALUE_PROVIDER', {
243
- providedIn: 'root',
244
- factory: () => {
245
- const injector = inject(Injector);
246
- return [
247
- new AXPSettingValueProviderDefault(AXPPlatformScope.Platform, injector),
248
- new AXPSettingValueProviderDefault(AXPPlatformScope.Tenant, injector),
249
- new AXPSettingValueProviderDefault(AXPPlatformScope.User, injector)
250
- ];
251
- }
252
- });
253
- class AXPSettingValueProviderDefault {
254
- constructor(_scope, injector) {
255
- this._scope = _scope;
256
- this.injector = injector;
257
- this.cache = new Map();
258
- this.localStorageKey = null;
259
- this.sessionService = this.injector.get(AXPSessionService);
260
- // Platform scope doesn't depend on session, initialize immediately
261
- if (this.scope === AXPPlatformScope.Platform) {
262
- this.localStorageKey = `AXP_SETTINGS_SCOPE(P)`;
263
- }
264
- else {
265
- this.sessionService.status$.subscribe((status) => {
266
- if (status === AXPSessionStatus.Authorized || status === AXPSessionStatus.Authenticated) {
267
- if (this.scope === AXPPlatformScope.User) {
268
- this.localStorageKey = `AXP_SETTINGS_SCOPE(${this.sessionService.user?.id ?? 'U'})`;
269
- }
270
- else if (this.scope === AXPPlatformScope.Tenant) {
271
- this.localStorageKey = `AXP_SETTINGS_SCOPE(${this.sessionService.tenant?.id ?? 'T'})`;
272
- }
273
- }
274
- });
275
- }
276
- }
277
- get scope() {
278
- return this._scope;
279
- }
280
- async load() {
281
- if (!this.localStorageKey) {
282
- return Promise.resolve([]);
283
- }
284
- // Load settings from localStorage as a single key
285
- const storedSettings = localStorage.getItem(this.localStorageKey);
286
- if (storedSettings) {
287
- const parsedSettings = JSON.parse(storedSettings);
288
- Object.entries(parsedSettings).forEach(([key, value]) => {
289
- this.cache.set(key, value);
290
- });
291
- return Promise.resolve(Array.from(this.cache.entries()).map(c => ({ key: c[0], value: c[1] })));
292
- }
293
- return Promise.resolve([]);
294
- }
295
- async set(keyOrValues, value) {
296
- if (typeof keyOrValues === 'string') {
297
- // Single value update
298
- this.cache.set(keyOrValues, value);
299
- }
300
- else {
301
- // Bulk update
302
- for (const [key, val] of Object.entries(keyOrValues)) {
303
- this.cache.set(key, val);
304
- }
305
- }
306
- await this.saveToLocalStorage();
307
- }
308
- async saveToLocalStorage() {
309
- if (!this.localStorageKey) {
310
- return;
311
- }
312
- const settingsObject = {};
313
- this.cache.forEach((value, key) => {
314
- settingsObject[key] = value;
315
- });
316
- localStorage.setItem(this.localStorageKey, JSON.stringify(settingsObject));
317
- }
318
- async clear() {
319
- if (!this.localStorageKey) {
320
- return;
321
- }
322
- localStorage.removeItem(this.localStorageKey);
323
- }
324
- }
325
-
326
242
  class AXPSettingDefinitionProviderContext {
327
243
  constructor() {
328
244
  this.rootGroups = [];
329
245
  this.groupMap = new Map();
330
246
  }
331
- addGroup(name, title, description, icon) {
247
+ addGroup(name, title, description, icon, pageTitle) {
332
248
  const newGroup = {
333
249
  name,
334
250
  title,
251
+ pageTitle,
335
252
  description,
336
253
  icon,
337
254
  groups: [],
@@ -382,10 +299,11 @@ class AXPSettingDefinitionGroupBuilder {
382
299
  }
383
300
  return new AXPSettingDefinitionSectionBuilder(this, foundSection);
384
301
  }
385
- addGroup(name, title, description, icon) {
302
+ addGroup(name, title, description, icon, pageTitle) {
386
303
  const newGroup = {
387
304
  name,
388
305
  title,
306
+ pageTitle,
389
307
  description: description,
390
308
  icon,
391
309
  groups: [],
@@ -412,6 +330,7 @@ class AXPSettingDefinitionSectionBuilder {
412
330
  name: setting.key,
413
331
  title: setting.title,
414
332
  description: setting.description,
333
+ searchTagKeys: setting.searchTagKeys,
415
334
  isRequired: setting.isRequired ?? false,
416
335
  isInherited: setting.isInherited ?? false,
417
336
  isEncrypted: setting.isEncrypted ?? false,
@@ -485,7 +404,8 @@ class AXPSettingDefinitionProviderService {
485
404
  return groups
486
405
  .map((group) => ({
487
406
  ...group,
488
- sections: group.sections.map((section) => ({
407
+ sections: group.sections
408
+ .map((section) => ({
489
409
  ...section,
490
410
  settings: section.settings.filter((setting) => {
491
411
  const settingScopeIndex = scopeOrder.indexOf(setting.scope);
@@ -502,7 +422,8 @@ class AXPSettingDefinitionProviderService {
502
422
  // 3. Exclude settings with a lower or irrelevant scope.
503
423
  return false;
504
424
  }),
505
- })).filter((section) => section.settings.length > 0), // Keep only sections with settings
425
+ }))
426
+ .filter((section) => section.settings.length > 0), // Keep only sections with settings
506
427
  groups: filterByScope(group.groups, currentScope), // Recursively filter nested groups
507
428
  }))
508
429
  .filter((group) => group.sections.length > 0 || group.groups.length > 0); // Keep groups with valid sections or nested groups
@@ -529,12 +450,33 @@ class AXPSettingDefinitionProviderService {
529
450
  collectDefaults(this.cache);
530
451
  return defaults;
531
452
  }
453
+ async settingScopeByKey() {
454
+ const scopes = {};
455
+ const collect = (groups) => {
456
+ groups.forEach((group) => {
457
+ group.sections.forEach((section) => {
458
+ section.settings.forEach((setting) => {
459
+ scopes[setting.name] = setting.scope;
460
+ });
461
+ });
462
+ collect(group.groups);
463
+ });
464
+ };
465
+ if (!this.cache) {
466
+ await this.load();
467
+ }
468
+ collect(this.cache);
469
+ return scopes;
470
+ }
532
471
  findGroup(scope, groupName) {
533
472
  return this.searchRecursive(this.getList(scope), groupName, []); // Initialize with an empty breadcrumb
534
473
  }
535
474
  searchRecursive(groups, groupName, breadcrumb) {
536
475
  for (const group of groups) {
537
- const currentBreadcrumb = [...breadcrumb, { name: group.name, title: group.title, description: group.description }];
476
+ const currentBreadcrumb = [
477
+ ...breadcrumb,
478
+ { name: group.name, title: group.title, description: group.description },
479
+ ];
538
480
  // If the group name matches, return its details
539
481
  if (group.name === groupName) {
540
482
  return {
@@ -553,7 +495,7 @@ class AXPSettingDefinitionProviderService {
553
495
  return {
554
496
  breadcrumb: [],
555
497
  groups: [],
556
- sections: []
498
+ sections: [],
557
499
  };
558
500
  }
559
501
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPSettingDefinitionProviderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
@@ -597,6 +539,154 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
597
539
  args: [{ providedIn: 'root' }]
598
540
  }] });
599
541
 
542
+ //#region ---- Imports ----
543
+ //#endregion
544
+ //#region ---- Kind inference ----
545
+ /**
546
+ * If the payload uses the common `{ value: T }` shape from setting widgets, returns the inner value; otherwise returns `raw`.
547
+ */
548
+ function peelSettingValueKey(raw) {
549
+ return unwrapValueProperty(raw);
550
+ }
551
+ function coercionKindFromScalarSample(v) {
552
+ if (v === null || v === undefined) {
553
+ return null;
554
+ }
555
+ if (typeof v === 'boolean') {
556
+ return 'boolean';
557
+ }
558
+ if (typeof v === 'number' && Number.isFinite(v)) {
559
+ return 'number';
560
+ }
561
+ if (v instanceof Date) {
562
+ return 'date';
563
+ }
564
+ if (typeof v === 'string') {
565
+ if (v === 'true' || v === 'false') {
566
+ return 'boolean';
567
+ }
568
+ return 'string';
569
+ }
570
+ return null;
571
+ }
572
+ /**
573
+ * Picks a primitive coercion kind from the setting definition default and/or the effective stored value.
574
+ * Type argument `T` on the settings service `get` method is compile-time only; runtime behavior follows this inference.
575
+ */
576
+ function inferSettingCoercionKind(defaultSample, effective) {
577
+ const fromDefault = coercionKindFromScalarSample(defaultSample);
578
+ if (fromDefault) {
579
+ return fromDefault;
580
+ }
581
+ return coercionKindFromScalarSample(unwrapValueProperty(effective));
582
+ }
583
+ //#endregion
584
+ //#region ---- Value coercion ----
585
+ function coerceAXPSettingRawValueByKind(raw, kind) {
586
+ switch (kind) {
587
+ case 'string':
588
+ return coerceUnknownToTrimmedString(raw);
589
+ case 'boolean':
590
+ return coerceUnknownToBoolean(raw);
591
+ case 'number':
592
+ return coerceUnknownToFiniteNumber(raw);
593
+ case 'date':
594
+ return coerceUnknownToDate(raw);
595
+ default: {
596
+ const _exhaustive = kind;
597
+ return _exhaustive;
598
+ }
599
+ }
600
+ }
601
+ function coerceAXPSettingRawValue(raw, kind) {
602
+ return coerceAXPSettingRawValueByKind(raw, kind);
603
+ }
604
+ //#endregion
605
+
606
+ const AXP_SETTING_VALUE_PROVIDER = new InjectionToken('AXP_SETTING_VALUE_PROVIDER', {
607
+ providedIn: 'root',
608
+ factory: () => {
609
+ const injector = inject(Injector);
610
+ return [
611
+ new AXPSettingValueProviderDefault(AXPPlatformScope.Platform, injector),
612
+ new AXPSettingValueProviderDefault(AXPPlatformScope.Tenant, injector),
613
+ new AXPSettingValueProviderDefault(AXPPlatformScope.User, injector),
614
+ ];
615
+ },
616
+ });
617
+ class AXPSettingValueProviderDefault {
618
+ constructor(_scope, injector) {
619
+ this._scope = _scope;
620
+ this.injector = injector;
621
+ this.cache = new Map();
622
+ this.localStorageKey = null;
623
+ this.sessionService = this.injector.get(AXPSessionService);
624
+ // Platform scope doesn't depend on session, initialize immediately
625
+ if (this.scope === AXPPlatformScope.Platform) {
626
+ this.localStorageKey = `AXP_SETTINGS_SCOPE(P)`;
627
+ }
628
+ else {
629
+ this.sessionService.status$.subscribe((status) => {
630
+ if (status === AXPSessionStatus.Authorized || status === AXPSessionStatus.Authenticated) {
631
+ if (this.scope === AXPPlatformScope.User) {
632
+ this.localStorageKey = `AXP_SETTINGS_SCOPE(${this.sessionService.user?.id ?? 'U'})`;
633
+ }
634
+ else if (this.scope === AXPPlatformScope.Tenant) {
635
+ this.localStorageKey = `AXP_SETTINGS_SCOPE(${this.sessionService.tenant?.id ?? 'T'})`;
636
+ }
637
+ }
638
+ });
639
+ }
640
+ }
641
+ get scope() {
642
+ return this._scope;
643
+ }
644
+ async load() {
645
+ if (!this.localStorageKey) {
646
+ return Promise.resolve([]);
647
+ }
648
+ // Load settings from localStorage as a single key
649
+ const storedSettings = localStorage.getItem(this.localStorageKey);
650
+ if (storedSettings) {
651
+ const parsedSettings = JSON.parse(storedSettings);
652
+ Object.entries(parsedSettings).forEach(([key, value]) => {
653
+ this.cache.set(key, value);
654
+ });
655
+ return Promise.resolve(Array.from(this.cache.entries()).map((c) => ({ key: c[0], value: c[1] })));
656
+ }
657
+ return Promise.resolve([]);
658
+ }
659
+ async set(keyOrValues, value) {
660
+ if (typeof keyOrValues === 'string') {
661
+ // Single value update
662
+ this.cache.set(keyOrValues, value);
663
+ }
664
+ else {
665
+ // Bulk update
666
+ for (const [key, val] of Object.entries(keyOrValues)) {
667
+ this.cache.set(key, val);
668
+ }
669
+ }
670
+ await this.saveToLocalStorage();
671
+ }
672
+ async saveToLocalStorage() {
673
+ if (!this.localStorageKey) {
674
+ return;
675
+ }
676
+ const settingsObject = {};
677
+ this.cache.forEach((value, key) => {
678
+ settingsObject[key] = value;
679
+ });
680
+ localStorage.setItem(this.localStorageKey, JSON.stringify(settingsObject));
681
+ }
682
+ async clear() {
683
+ if (!this.localStorageKey) {
684
+ return;
685
+ }
686
+ localStorage.removeItem(this.localStorageKey);
687
+ }
688
+ }
689
+
600
690
  class AXPSettingsService {
601
691
  constructor() {
602
692
  this.providers = inject(AXP_SETTING_VALUE_PROVIDER);
@@ -607,11 +697,7 @@ class AXPSettingsService {
607
697
  this.onChanged = new Subject();
608
698
  this.onLoaded = new Subject();
609
699
  // Initialize scoped caches for dynamic scopes
610
- const staticScopes = [
611
- AXPPlatformScope.Platform,
612
- AXPPlatformScope.Tenant,
613
- AXPPlatformScope.User,
614
- ];
700
+ const staticScopes = [AXPPlatformScope.Platform, AXPPlatformScope.Tenant, AXPPlatformScope.User];
615
701
  staticScopes.forEach((scope) => {
616
702
  if (!this.scopedSettingsCache.has(scope)) {
617
703
  this.scopedSettingsCache.set(scope, new Map());
@@ -646,6 +732,7 @@ class AXPSettingsService {
646
732
  });
647
733
  settingsList.push(...providerSettings);
648
734
  }
735
+ await this.seedMissingDefaults();
649
736
  this.onLoaded.next();
650
737
  return settingsList;
651
738
  }
@@ -654,33 +741,45 @@ class AXPSettingsService {
654
741
  throw error;
655
742
  }
656
743
  }
744
+ /**
745
+ * Returns the effective setting value. Primitive coercion (string, boolean, number, date) is inferred from the
746
+ * definition default and/or the stored shape (including `{ value: ... }`). Type argument `T` is compile-time only;
747
+ * it is not read at runtime—use it to document the expected result (e.g. `get<boolean>(key)`).
748
+ */
657
749
  async get(key) {
750
+ const { effective, defaultSample } = await this.resolveEffectiveAndDefault(key);
751
+ const kind = inferSettingCoercionKind(defaultSample, effective);
752
+ if (kind !== null) {
753
+ return coerceAXPSettingRawValueByKind(effective, kind);
754
+ }
755
+ if (effective === undefined) {
756
+ return effective;
757
+ }
758
+ return cloneDeep(effective);
759
+ }
760
+ /**
761
+ * Effective value (user → tenant → platform) when set; otherwise the definition default. Used for reads and coercion hints.
762
+ */
763
+ async resolveEffectiveAndDefault(key) {
658
764
  if (this.scopedSettingsCache.size === 0) {
659
765
  await this.load();
660
766
  }
661
- const scopeOrder = [
662
- AXPPlatformScope.User,
663
- AXPPlatformScope.Tenant,
664
- AXPPlatformScope.Platform,
665
- ];
767
+ const defaults = await this.injector.get(AXPSettingDefaultValuesAggregatorService).getDefaults();
768
+ const defaultSample = get(defaults, key);
769
+ const scopeOrder = [AXPPlatformScope.User, AXPPlatformScope.Tenant, AXPPlatformScope.Platform];
666
770
  for (const scope of scopeOrder) {
667
771
  const scopeCache = this.scopedSettingsCache.get(scope);
668
772
  if (scopeCache && scopeCache.has(key)) {
669
773
  const value = scopeCache.get(key);
670
774
  if (value !== undefined && value !== null) {
671
- return cloneDeep(value);
775
+ return { effective: value, defaultSample };
672
776
  }
673
777
  }
674
778
  }
675
- const defaults = await this.injector.get(AXPSettingDefaultValuesAggregatorService).getDefaults();
676
- return get(defaults, key); // Fallback if no value is found
779
+ return { effective: defaultSample, defaultSample };
677
780
  }
678
781
  async defaultValues(scope) {
679
- let scopeOrder = [
680
- AXPPlatformScope.Platform,
681
- AXPPlatformScope.Tenant,
682
- AXPPlatformScope.User,
683
- ].reverse();
782
+ let scopeOrder = [AXPPlatformScope.Platform, AXPPlatformScope.Tenant, AXPPlatformScope.User].reverse();
684
783
  const scopeIndex = scopeOrder.indexOf(scope);
685
784
  if (scopeIndex === -1) {
686
785
  throw new Error(`Invalid scope: ${scope}`);
@@ -714,6 +813,29 @@ class AXPSettingsService {
714
813
  this.onChanged.next(event);
715
814
  this.eventService.publish('AXPSettingChangedEvent', event);
716
815
  }
816
+ async seedMissingDefaults() {
817
+ const definitionService = this.injector.get(AXPSettingDefinitionProviderService);
818
+ const aggregator = this.injector.get(AXPSettingDefaultValuesAggregatorService);
819
+ const [defaults, scopeByKey] = await Promise.all([aggregator.getDefaults(), definitionService.settingScopeByKey()]);
820
+ const persistedKeysByScope = new Map(await Promise.all(this.providers.map(async (provider) => {
821
+ const stored = await provider.load();
822
+ return [provider.scope, new Set(stored.map((s) => s.key))];
823
+ })));
824
+ const toPersist = {};
825
+ for (const [key, value] of Object.entries(defaults)) {
826
+ const scope = scopeByKey[key];
827
+ if (!scope || value === undefined || persistedKeysByScope.get(scope)?.has(key)) {
828
+ continue;
829
+ }
830
+ toPersist[scope] ??= {};
831
+ toPersist[scope][key] = value;
832
+ }
833
+ for (const [scope, values] of Object.entries(toPersist)) {
834
+ if (Object.keys(values).length > 0) {
835
+ await this.scope(scope).set(values);
836
+ }
837
+ }
838
+ }
717
839
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPSettingsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
718
840
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPSettingsService, providedIn: 'root' }); }
719
841
  }
@@ -732,7 +854,17 @@ class ScopedSettingService {
732
854
  async get(key) {
733
855
  const settings = await this.provider.load();
734
856
  const setting = settings.find((s) => s.key === key);
735
- return setting ? cloneDeep(setting.value) : undefined;
857
+ const effective = setting?.value;
858
+ const defaults = await this.parent.defaultValues(this.provider.scope);
859
+ const defaultSample = get(defaults, key);
860
+ const kind = inferSettingCoercionKind(defaultSample, effective);
861
+ if (kind !== null) {
862
+ return coerceAXPSettingRawValueByKind(effective, kind);
863
+ }
864
+ if (effective === undefined) {
865
+ return effective;
866
+ }
867
+ return cloneDeep(effective);
736
868
  }
737
869
  async all() {
738
870
  const settings = await this.provider.load();
@@ -1129,28 +1261,27 @@ function provideDynamicHomePage() {
1129
1261
  ]);
1130
1262
  }
1131
1263
 
1264
+ const I18N = '@general:settings';
1132
1265
  class AXPHomePageSettingProvider {
1133
1266
  constructor(injector) {
1134
1267
  this.injector = injector;
1135
- this.translateService = this.injector.get(AXTranslationService);
1136
1268
  this.homePageService = this.injector.get(AXPHomePageService);
1137
1269
  this.defaultHomePageKey = inject(AXP_HOME_PAGE_DEFAULT_KEY, { optional: true }) ?? 'home';
1138
1270
  }
1139
1271
  async provide(context) {
1140
- const trans = async (key) => await this.translateService.translateAsync(`@general:settings.${key}`);
1141
- const list = await this.homePageService.getRegisteredList().map((c) => ({ id: c.key, title: c.title }));
1272
+ const list = this.homePageService.getRegisteredList().map((c) => ({ id: c.key, title: c.title }));
1142
1273
  if (list.length === 0) {
1143
1274
  return;
1144
1275
  }
1145
1276
  // Define the 'General Settings' group
1146
1277
  context
1147
- .addGroup('general', await trans('general.title'), await trans('general.description'), 'fa-light fa-palette')
1278
+ .addGroup('general', `${I18N}.general.nav-title`, `${I18N}.general.description`, 'fa-light fa-palette', `${I18N}.general.title`)
1148
1279
  // Add the 'Startup' section
1149
- .addSection('startup', await trans('general.startup.title'), await trans('general.startup.description'))
1280
+ .addSection('startup', `${I18N}.general.startup.title`, `${I18N}.general.startup.description`)
1150
1281
  // Add the 'Home Page' setting
1151
1282
  .addSetting({
1152
1283
  key: AXPHomePageSettings.UserHomePath,
1153
- title: await trans('general.startup.home-page.title'),
1284
+ title: `${I18N}.general.startup.home-page.title`,
1154
1285
  scope: AXPPlatformScope.User,
1155
1286
  isInherited: true,
1156
1287
  defaultValue: this.defaultHomePageKey || list[0].id,
@@ -1163,7 +1294,7 @@ class AXPHomePageSettingProvider {
1163
1294
  dataSource: list,
1164
1295
  },
1165
1296
  },
1166
- description: await trans('general.startup.home-page.description'),
1297
+ description: `${I18N}.general.startup.home-page.description`,
1167
1298
  })
1168
1299
  // End the 'Startup' section
1169
1300
  .endSection()
@@ -2731,21 +2862,23 @@ class AXPMenuSearchProvider {
2731
2862
  title: item.text, // Use `text` for the `title`
2732
2863
  icon: item.icon, // Include the `icon` if present
2733
2864
  data: omit(item, ['parent', 'children']), // Include all data except `parent` and `children`
2734
- command: item.path ? {
2735
- name: 'navigate',
2736
- options: {
2737
- type: 'router',
2865
+ command: item.path
2866
+ ? {
2867
+ name: 'navigate',
2738
2868
  options: {
2739
- path: item.path,
2869
+ type: 'router',
2870
+ options: {
2871
+ path: item.path,
2872
+ },
2740
2873
  },
2741
2874
  }
2742
- } : item.command,
2875
+ : item.command,
2743
2876
  parent: item.parent
2744
2877
  ? {
2745
2878
  title: item.parent.text,
2746
2879
  }
2747
2880
  : undefined,
2748
- })), [(o) => this.translateService.translateSync(o.title)]);
2881
+ })), [(o) => this.translateService.translateSync(String(o.title ?? ''))]);
2749
2882
  }
2750
2883
  /**
2751
2884
  * Recursively searches AXPMenuItem and its children for a matching text.
@@ -2949,8 +3082,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
2949
3082
  }] });
2950
3083
 
2951
3084
  class AXPSearchCommandProvider {
3085
+ constructor() {
3086
+ this.translationService = inject(AXTranslationService);
3087
+ }
2952
3088
  async search(text) {
2953
- return this.commands.filter((command) => command.title.toLowerCase().includes(text.toLowerCase()));
3089
+ const locale = this.translationService.getActiveLang() ?? 'en-US';
3090
+ return this.commands.filter((command) => searchInMultiLanguageString(command.title, text, locale));
2954
3091
  }
2955
3092
  }
2956
3093
 
@@ -3017,11 +3154,17 @@ class AXPSearchService {
3017
3154
  }
3018
3155
  }
3019
3156
  }
3157
+ const locale = this.translationService.getActiveLang() ?? 'en-US';
3158
+ const normalizedQuery = text.trim();
3159
+ const visibleData = normalizedQuery.length === 0
3160
+ ? mergeData
3161
+ : mergeData.filter((item) => searchInMultiLanguageString(item.title, normalizedQuery, locale) ||
3162
+ searchInMultiLanguageString(item.description, normalizedQuery, locale));
3020
3163
  // Group data
3021
3164
  const groupedData = [];
3022
3165
  const groupMap = {};
3023
3166
  // Create groups
3024
- for (const item of mergeData) {
3167
+ for (const item of visibleData) {
3025
3168
  const groupName = item.definitionName; // Change this to the property you want to group by
3026
3169
  if (!groupMap[groupName]) {
3027
3170
  groupMap[groupName] = {
@@ -3094,6 +3237,8 @@ var AXPCommonSettings;
3094
3237
  AXPCommonSettings["RedirectToDetailsAfterCreate"] = "Common:Setting:Entity.RedirectToDetailsAfterCreate";
3095
3238
  AXPCommonSettings["ShowPageBadge"] = "Common:Setting:Entity.ShowPageBadge";
3096
3239
  AXPCommonSettings["DebugMode"] = "PlatformDevTools:Setting:Developer.DebugMode";
3240
+ AXPCommonSettings["ShowRowIndexColumn"] = "Common:Setting:Entity.ShowRowIndexColumn";
3241
+ AXPCommonSettings["EntityListPersistenceMode"] = "Common:Setting:Entity.ListPersistenceMode";
3097
3242
  })(AXPCommonSettings || (AXPCommonSettings = {}));
3098
3243
 
3099
3244
  //TODO Loading, Redirect, Drawer, Show toast
@@ -3339,7 +3484,7 @@ class AXPCommonModule {
3339
3484
  provide: AXP_SETTING_DEFINITION_PROVIDER,
3340
3485
  useFactory: async () => {
3341
3486
  const injector = inject(Injector);
3342
- const provider = (await import('./acorex-platform-common-common-settings.provider-G9XcXXOG.mjs')).AXPCommonSettingProvider;
3487
+ const provider = (await import('./acorex-platform-common-common-settings.provider-Bi1RYif5.mjs')).AXPCommonSettingProvider;
3343
3488
  return new provider(injector);
3344
3489
  },
3345
3490
  multi: true,
@@ -3419,7 +3564,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
3419
3564
  provide: AXP_SETTING_DEFINITION_PROVIDER,
3420
3565
  useFactory: async () => {
3421
3566
  const injector = inject(Injector);
3422
- const provider = (await import('./acorex-platform-common-common-settings.provider-G9XcXXOG.mjs')).AXPCommonSettingProvider;
3567
+ const provider = (await import('./acorex-platform-common-common-settings.provider-Bi1RYif5.mjs')).AXPCommonSettingProvider;
3423
3568
  return new provider(injector);
3424
3569
  },
3425
3570
  multi: true,
@@ -4619,5 +4764,5 @@ class AXPVersioningService {
4619
4764
  * Generated bundle index. Do not edit.
4620
4765
  */
4621
4766
 
4622
- export { ALL_DEFAULT_OPERATORS, AXMWorkflowErrorHandler, AXPAppVersionService, AXPCleanNestedFilters, AXPClipBoardService, AXPCommonModule, AXPCommonSettings, AXPCustomOperatorService, AXPCustomOperatorServiceImpl, AXPDataProvider, AXPDebugService, AXPDefaultMultiLanguageConfigService, AXPDialogConfirmAction, AXPEntityCommandScope, AXPEntityQueryType, AXPEntityType, AXPErrorHandlerRegistryService, AXPExportService, AXPFileActionsService, AXPFileStorageService, AXPFileStorageStatus, AXPFileTypeProviderService, AXPFilterOperatorMiddlewareService, AXPFilterOperatorMiddlewareServiceImpl, AXPFooterTextSlotComponent, AXPGlobalErrorHandler, AXPHomePageModule, AXPHomePageService, AXPLockService, AXPMenuItemsDataSourceDefinition, AXPMenuMiddlewareRegistry, AXPMenuProviderService, AXPMenuSearchDefinitionProvider, AXPMenuSearchProvider, AXPMenuService, AXPMenuVisibilityService, AXPNavBarSlotComponent, AXPNavigateWorkflow, AXPPlatformDefaultConfigs, AXPRedirectEvent, AXPRefreshEvent, AXPRegionalSetting, AXPRelationshipCardinality, AXPRelationshipKind, AXPReloadAction, AXPReloadEvent, AXPSearchCommandProvider, AXPSearchDefinitionActionBuilder, AXPSearchDefinitionBuilder, AXPSearchDefinitionProviderContext, AXPSearchDefinitionProviderService, AXPSearchService, AXPSettingDefaultValuesAggregatorService, AXPSettingDefinitionGroupBuilder, AXPSettingDefinitionProviderContext, AXPSettingDefinitionProviderService, AXPSettingDefinitionSectionBuilder, AXPSettingsEvaluatorScopeProvider, AXPSettingsService, AXPStatusDefinitionProviderService, AXPStatusProvider, AXPStickyDirective, AXPSystemStatusType, AXPSystemStatuses, AXPToastAction, AXPTokenDefinitionService, AXPTokenEvaluatorScopeProvider, AXPVersioningService, AXPWorkflowNavigateAction, AXPWorkflowRouterNavigateAction, AXP_APP_VERSION_PROVIDER, AXP_FILE_ACTION_PROVIDER, AXP_FILE_TYPE_INFO_PROVIDER, AXP_HOME_PAGES, AXP_HOME_PAGE_DEFAULT_KEY, AXP_LOCALE_MANAGEMENT_PORT, AXP_MENU_MIDDLEWARE, AXP_MENU_PROVIDER, AXP_PLATFORM_CONFIG_TOKEN, AXP_ROOT_CONFIG_TOKEN, AXP_SEARCH_DEFINITION_PROVIDER, AXP_SEARCH_PROVIDER, AXP_SETTING_DEFAULT_VALUES_PROVIDERS, AXP_SETTING_DEFINITION_PROVIDER, AXP_SETTING_VALUE_PROVIDER, AXP_STATUS_PROVIDERS, AXP_TOKEN_DEFINITION_PROVIDER, AXVChangeType, BETWEEN_OPER, BOOLEAN_OPERATORS, CONTAINS_OPER, DATE_OPERATORS, DEFAULT_MULTILANGUAGE_FIELD_NAMES, ENDS_WITH_OPER, ENVIRONMENT, EQ_OPER, GTE_OPER, GT_OPER, IN_OPER, IS_EMPTY_OPER, IS_NOT_EMPTY_OPER, LTE_OPER, LT_OPER, MENU_ITEMS_DATASOURCE_NAME, MULTILANGUAGE_CAPABLE_WIDGET_TYPES, NOT_CONTAINS_OPER, NOT_EQ_OPER, NUMBER_OPERATORS, STARTS_WITH_OPER, STRING_OPERATORS, UploadFromComputerActionProvider, configPlatform, createAllQueryView, createEntityCommandOptions, createEntitySearchCommand, createMenuContext, createMenuMiddleware, createQueryView, getEntityInfo, getStatusInfo, getSystemStatus, provideDynamicHomePage, provideMenuMiddleware, resolveStatusLook, shouldApplyDefaultMultiLanguageToEntityProperty, shouldApplyDefaultMultiLanguageToWidgetNode, shouldApplyDefaultMultiLanguageToWidgetProperty, systemStatusToDefinition, withDefaultMultiLanguageOnWidgetNodeTree, withDefaultMultiLanguageOnWidgetProperty };
4767
+ export { ALL_DEFAULT_OPERATORS, AXMWorkflowErrorHandler, AXPAppVersionService, AXPCleanNestedFilters, AXPClipBoardService, AXPCommonModule, AXPCommonSettings, AXPCustomOperatorService, AXPCustomOperatorServiceImpl, AXPDataProvider, AXPDebugService, AXPDefaultMultiLanguageConfigService, AXPDialogConfirmAction, AXPEntityCommandScope, AXPEntityQueryType, AXPEntityType, AXPErrorHandlerRegistryService, AXPExportService, AXPFileActionsService, AXPFileStorageService, AXPFileStorageStatus, AXPFileTypeProviderService, AXPFilterOperatorMiddlewareService, AXPFilterOperatorMiddlewareServiceImpl, AXPFooterTextSlotComponent, AXPGlobalErrorHandler, AXPHomePageModule, AXPHomePageService, AXPLockService, AXPMenuItemsDataSourceDefinition, AXPMenuMiddlewareRegistry, AXPMenuProviderService, AXPMenuSearchDefinitionProvider, AXPMenuSearchProvider, AXPMenuService, AXPMenuVisibilityService, AXPNavBarSlotComponent, AXPNavigateWorkflow, AXPPlatformDefaultConfigs, AXPRedirectEvent, AXPRefreshEvent, AXPRegionalSetting, AXPRelationshipCardinality, AXPRelationshipKind, AXPReloadAction, AXPReloadEvent, AXPSearchCommandProvider, AXPSearchDefinitionActionBuilder, AXPSearchDefinitionBuilder, AXPSearchDefinitionProviderContext, AXPSearchDefinitionProviderService, AXPSearchService, AXPSettingDefaultValuesAggregatorService, AXPSettingDefinitionGroupBuilder, AXPSettingDefinitionProviderContext, AXPSettingDefinitionProviderService, AXPSettingDefinitionSectionBuilder, AXPSettingsEvaluatorScopeProvider, AXPSettingsService, AXPStatusDefinitionProviderService, AXPStatusProvider, AXPStickyDirective, AXPSystemStatusType, AXPSystemStatuses, AXPToastAction, AXPTokenDefinitionService, AXPTokenEvaluatorScopeProvider, AXPVersioningService, AXPWorkflowNavigateAction, AXPWorkflowRouterNavigateAction, AXP_APP_VERSION_PROVIDER, AXP_FILE_ACTION_PROVIDER, AXP_FILE_TYPE_INFO_PROVIDER, AXP_HOME_PAGES, AXP_HOME_PAGE_DEFAULT_KEY, AXP_LOCALE_MANAGEMENT_PORT, AXP_MENU_MIDDLEWARE, AXP_MENU_PROVIDER, AXP_PLATFORM_CONFIG_TOKEN, AXP_ROOT_CONFIG_TOKEN, AXP_SEARCH_DEFINITION_PROVIDER, AXP_SEARCH_PROVIDER, AXP_SETTING_DEFAULT_VALUES_PROVIDERS, AXP_SETTING_DEFINITION_PROVIDER, AXP_SETTING_VALUE_PROVIDER, AXP_STATUS_PROVIDERS, AXP_TOKEN_DEFINITION_PROVIDER, AXVChangeType, BETWEEN_OPER, BOOLEAN_OPERATORS, CONTAINS_OPER, DATE_OPERATORS, DEFAULT_MULTILANGUAGE_FIELD_NAMES, ENDS_WITH_OPER, ENVIRONMENT, EQ_OPER, GTE_OPER, GT_OPER, IN_OPER, IS_EMPTY_OPER, IS_NOT_EMPTY_OPER, LTE_OPER, LT_OPER, MENU_ITEMS_DATASOURCE_NAME, MULTILANGUAGE_CAPABLE_WIDGET_TYPES, NOT_CONTAINS_OPER, NOT_EQ_OPER, NUMBER_OPERATORS, STARTS_WITH_OPER, STRING_OPERATORS, UploadFromComputerActionProvider, coerceAXPSettingRawValue, coerceAXPSettingRawValueByKind, configPlatform, createAllQueryView, createEntityCommandOptions, createEntitySearchCommand, createMenuContext, createMenuMiddleware, createQueryView, getEntityInfo, getStatusInfo, getSystemStatus, inferSettingCoercionKind, peelSettingValueKey, provideDynamicHomePage, provideMenuMiddleware, resolveStatusLook, shouldApplyDefaultMultiLanguageToEntityProperty, shouldApplyDefaultMultiLanguageToWidgetNode, shouldApplyDefaultMultiLanguageToWidgetProperty, systemStatusToDefinition, withDefaultMultiLanguageOnWidgetNodeTree, withDefaultMultiLanguageOnWidgetProperty };
4623
4768
  //# sourceMappingURL=acorex-platform-common.mjs.map