@acorex/platform 19.1.7 → 19.1.8

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 (45) hide show
  1. package/common/lib/common.module.d.ts +6 -7
  2. package/common/lib/layout/menu/menu.types.d.ts +2 -2
  3. package/common/lib/layout/menu/search.provider.d.ts +2 -2
  4. package/common/lib/search/search.provider.d.ts +4 -0
  5. package/common/lib/store/common.actions.d.ts +0 -12
  6. package/common/lib/store/index.d.ts +0 -1
  7. package/common/lib/workflows/index.d.ts +1 -0
  8. package/common/lib/workflows/navigate.workflow.d.ts +9 -0
  9. package/core/lib/types.d.ts +19 -0
  10. package/fesm2022/acorex-platform-common.mjs +805 -793
  11. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  12. package/fesm2022/acorex-platform-core.mjs.map +1 -1
  13. package/fesm2022/acorex-platform-layout-builder.mjs +1 -0
  14. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  15. package/fesm2022/acorex-platform-layout-entity.mjs +93 -6
  16. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  17. package/fesm2022/acorex-platform-layout-search.mjs +18 -5
  18. package/fesm2022/acorex-platform-layout-search.mjs.map +1 -1
  19. package/fesm2022/acorex-platform-themes-default-search-popup.component-BiKt6Mvr.mjs +84 -0
  20. package/fesm2022/acorex-platform-themes-default-search-popup.component-BiKt6Mvr.mjs.map +1 -0
  21. package/fesm2022/acorex-platform-themes-default.mjs +5 -5
  22. package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
  23. package/fesm2022/acorex-platform-widgets.mjs +308 -33
  24. package/fesm2022/acorex-platform-widgets.mjs.map +1 -1
  25. package/layout/builder/lib/builder/widget-map.d.ts +1 -0
  26. package/layout/entity/lib/entity-registery.service.d.ts +16 -0
  27. package/layout/entity/lib/entity.config.d.ts +2 -2
  28. package/layout/entity/lib/entity.module.d.ts +3 -0
  29. package/layout/entity/lib/search-definition.provider.d.ts +6 -0
  30. package/layout/entity/lib/search.provider.d.ts +4 -0
  31. package/layout/search/lib/search.viewmodel.d.ts +5 -1
  32. package/layout/search/lib/workflows/search.workflow.d.ts +2 -1
  33. package/package.json +13 -13
  34. package/themes/default/lib/layouts/search-layout/search-popup.component.d.ts +3 -1
  35. package/widgets/lib/properties/layout.props.d.ts +1 -0
  36. package/widgets/lib/widgets/index.d.ts +1 -0
  37. package/widgets/lib/widgets/layout/grid/grid-widget-designer.component.d.ts +3 -1
  38. package/widgets/lib/widgets/property-editors/grid-options/grid-options-widget-editor.component.d.ts +39 -0
  39. package/widgets/lib/widgets/property-editors/grid-options/grid-options-widget.config.d.ts +7 -0
  40. package/widgets/lib/widgets/property-editors/grid-options/grid-options-widget.type.d.ts +19 -0
  41. package/widgets/lib/widgets/property-editors/grid-options/index.d.ts +3 -0
  42. package/widgets/lib/widgets/property-editors/property-editor-helper.d.ts +15 -0
  43. package/common/lib/store/common.effects.d.ts +0 -13
  44. package/fesm2022/acorex-platform-themes-default-search-popup.component-Blpan821.mjs +0 -62
  45. package/fesm2022/acorex-platform-themes-default-search-popup.component-Blpan821.mjs.map +0 -1
@@ -1,15 +1,12 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Injectable, provideAppInitializer, inject, RendererFactory2, InjectionToken, Injector, ErrorHandler, Directive, Input, EventEmitter, Output, runInInjectionContext, NgModule, Optional, Inject, Component, ViewEncapsulation } from '@angular/core';
3
- import { kebabCase, sortBy, merge, cloneDeep, get, omit } from 'lodash-es';
3
+ import { kebabCase, sortBy, omit, merge, cloneDeep, get } from 'lodash-es';
4
4
  import { AXPopupModule } from '@acorex/components/popup';
5
5
  import { AXToastService, AXToastModule } from '@acorex/components/toast';
6
6
  import { AXDateTimeModule } from '@acorex/core/date-time';
7
- import * as i5 from '@acorex/platform/workflow';
8
- import { createWorkFlowEvent, AXPWorkflowAction, AXPWorkflowError, AXPWorkflowModule } from '@acorex/platform/workflow';
9
- import * as i2$1 from '@angular/router';
7
+ import * as i4 from '@acorex/platform/workflow';
8
+ import { AXPWorkflowService, createWorkFlowEvent, AXPWorkflowAction, AXPWorkflowError, AXPWorkflowModule } from '@acorex/platform/workflow';
10
9
  import { Router, RouterModule } from '@angular/router';
11
- import * as i1$1 from '@ngrx/effects';
12
- import { createEffect, ofType, EffectsModule } from '@ngrx/effects';
13
10
  import { applySortArray, applyFilterArray } from '@acorex/platform/core';
14
11
  import Dexie from 'dexie';
15
12
  import * as i3 from '@acorex/components/decorators';
@@ -19,9 +16,9 @@ import { AXImageModule } from '@acorex/components/image';
19
16
  import * as i1 from '@angular/common';
20
17
  import { CommonModule } from '@angular/common';
21
18
  import { signalStore, withState, withMethods, patchState, withHooks } from '@ngrx/signals';
22
- import { createAction, props, Store } from '@ngrx/store';
23
- import { Subject, switchMap, of } from 'rxjs';
24
19
  import { AXTranslationService } from '@acorex/core/translation';
20
+ import { Store, createAction } from '@ngrx/store';
21
+ import { Subject } from 'rxjs';
25
22
  import { AXDialogService } from '@acorex/components/dialog';
26
23
 
27
24
  class AXPAppStartUpService {
@@ -1277,68 +1274,491 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImpor
1277
1274
  args: [{ providedIn: 'root' }]
1278
1275
  }] });
1279
1276
 
1280
- const AXPNavigateAction = createAction('[Navigate] Action', props());
1281
- const AXPSignOutAction = createAction('[SignOut] Action');
1282
- const AXPSignInAction = createAction('[SignIn] Action');
1277
+ const AXPMenuService = signalStore({ providedIn: 'root' },
1278
+ // Initial State
1279
+ withState((router = inject(Router)) => {
1280
+ return {
1281
+ items: [],
1282
+ selectedMenuItem: {
1283
+ item: null,
1284
+ isFullMatch: false
1285
+ },
1286
+ };
1287
+ }),
1288
+ // Methods for State Management
1289
+ withMethods((store, router = inject(Router), workflow = inject(AXPWorkflowService)) => {
1290
+ return {
1291
+ setMenuItems(items) {
1292
+ patchState(store, { items: items });
1293
+ },
1294
+ selectMenuItemByRoute(path) {
1295
+ const findItem = (items) => {
1296
+ for (const item of items) {
1297
+ // Recursively search children first
1298
+ if (item.children) {
1299
+ const foundChild = findItem(item.children);
1300
+ if (foundChild.item) {
1301
+ return foundChild;
1302
+ }
1303
+ }
1304
+ if (item.path) {
1305
+ // Check if the item path matches the current path
1306
+ const matchResult = pathsMatch(item.path, path, ["list", "view", "edit", "create"]);
1307
+ if (matchResult.isMatch) {
1308
+ return { item, isPartialMatch: matchResult.isPartial };
1309
+ }
1310
+ }
1311
+ }
1312
+ return { item: null, isPartialMatch: false };
1313
+ };
1314
+ const pathsMatch = (itemPath, currentPath, trailingSegmentsToIgnore = []) => {
1315
+ const itemSegments = itemPath.split('/').filter(segment => segment.length > 0);
1316
+ const pathSegments = currentPath.split('/').filter(segment => segment.length > 0);
1317
+ const menuLength = itemSegments.length;
1318
+ const pathLength = pathSegments.length;
1319
+ // Identify the effective base length for the menuPath
1320
+ let effectiveMenuLength = menuLength;
1321
+ if (menuLength > 0 &&
1322
+ trailingSegmentsToIgnore.includes(itemSegments[menuLength - 1])) {
1323
+ effectiveMenuLength--; // Exclude trailing non-hierarchical segments
1324
+ }
1325
+ // Check if the menuPath (base segments) is a prefix of browserPath
1326
+ let isPrefix = true;
1327
+ for (let i = 0; i < effectiveMenuLength; i++) {
1328
+ if (itemSegments[i] !== pathSegments[i]) {
1329
+ isPrefix = false;
1330
+ break;
1331
+ }
1332
+ }
1333
+ // Partial match: menuPath base is a strict prefix of browserPath
1334
+ const isPartialMatch = isPrefix && effectiveMenuLength < pathLength;
1335
+ // Exact match: all segments match completely
1336
+ const isExactMatch = isPrefix && effectiveMenuLength === pathLength;
1337
+ return {
1338
+ isMatch: isExactMatch || isPartialMatch,
1339
+ isPartial: isPartialMatch && !isExactMatch,
1340
+ };
1341
+ };
1342
+ const items = store.items();
1343
+ const { item, isPartialMatch } = findItem(items);
1344
+ patchState(store, { selectedMenuItem: { item, isFullMatch: !isPartialMatch } });
1345
+ },
1346
+ executeCommand(item) {
1347
+ if (item.path) {
1348
+ workflow.execute('navigate', { command: { type: 'router', options: { path: item.path } } });
1349
+ }
1350
+ if (item.command) {
1351
+ workflow.execute('navigate', { command: item.command });
1352
+ }
1353
+ patchState(store, { selectedMenuItem: { item, isFullMatch: true } });
1354
+ },
1355
+ isItemOpen(item) {
1356
+ const selectedItem = store.selectedMenuItem();
1357
+ if (!selectedItem) {
1358
+ return false;
1359
+ }
1360
+ const findParent = (currentItem, targetItem) => {
1361
+ if (currentItem.children?.includes(targetItem)) {
1362
+ return true;
1363
+ }
1364
+ return currentItem.children?.some(child => findParent(child, targetItem)) ?? false;
1365
+ };
1366
+ return item === selectedItem?.item || findParent(item, selectedItem.item);
1367
+ }
1368
+ };
1369
+ }), withHooks((store, menuProviderService = inject(AXPMenuProviderService)) => ({
1370
+ onInit() {
1371
+ (async () => {
1372
+ const items = await menuProviderService.items();
1373
+ patchState(store, { items: items });
1374
+ })();
1375
+ },
1376
+ onDestroy() {
1377
+ },
1378
+ })));
1283
1379
 
1284
- var AXPSettingScope;
1285
- (function (AXPSettingScope) {
1286
- AXPSettingScope["Environment"] = "C";
1287
- AXPSettingScope["Global"] = "G";
1288
- AXPSettingScope["Tenant"] = "T";
1289
- AXPSettingScope["User"] = "U";
1290
- })(AXPSettingScope || (AXPSettingScope = {}));
1291
- ;
1380
+ class AXPMenuSearchDefinitionProvider {
1381
+ async provide(context) {
1382
+ context.addDefinition('menu', 'Menu', 'fa-thin fa-bars', [
1383
+ {
1384
+ name: 'open',
1385
+ command: {
1386
+ name: 'view',
1387
+ options: {},
1388
+ },
1389
+ type: 'view',
1390
+ priority: 'primary',
1391
+ },
1392
+ ]);
1393
+ }
1394
+ }
1292
1395
 
1293
- class AXPSettingDefinitionProviderContext {
1396
+ class AXPMenuSearchProvider {
1294
1397
  constructor() {
1295
- this.rootGroups = [];
1296
- this.groupMap = new Map();
1398
+ this.menuService = inject(AXPMenuProviderService);
1399
+ this.translateService = inject(AXTranslationService);
1297
1400
  }
1298
- addGroup(name, title, description, icon) {
1299
- const newGroup = {
1300
- name,
1301
- title,
1302
- description,
1303
- icon,
1304
- groups: [],
1305
- sections: [],
1306
- };
1307
- this.rootGroups.push(newGroup);
1308
- this.groupMap.set(name, newGroup); // Index by name
1309
- return new AXPSettingDefinitionGroupBuilder(this, newGroup);
1401
+ async search(text) {
1402
+ const menuItems = await this.searchMenuItems(await this.menuService.items(), text);
1403
+ return sortBy(menuItems.map((item) => ({
1404
+ name: 'menu', // Use `name` or empty string if undefined
1405
+ title: item.text, // Use `text` for the `title`
1406
+ icon: item.icon, // Include the `icon` if present
1407
+ data: {
1408
+ command: {
1409
+ name: 'navigate',
1410
+ options: {
1411
+ command: item.command ?? {
1412
+ type: 'router',
1413
+ options: {
1414
+ path: item.path
1415
+ }
1416
+ }
1417
+ }
1418
+ },
1419
+ },
1420
+ parent: item.parent
1421
+ ? {
1422
+ title: item.parent.text,
1423
+ data: item.parent,
1424
+ }
1425
+ : undefined,
1426
+ })), [(o) => this.translateService.translateSync(o.title)]);
1310
1427
  }
1311
- group(name) {
1312
- const foundGroup = this.groupMap.get(name);
1313
- if (!foundGroup) {
1314
- throw new Error(`Group with name "${name}" not found.`);
1428
+ /**
1429
+ * Recursively searches AXPMenuItem and its children for a matching text.
1430
+ *
1431
+ * @param menuItems - The array of AXPMenuItem to search in.
1432
+ * @param searchText - The text to search for (case-insensitive).
1433
+ * @returns An array of AXPMenuItem that match the search text.
1434
+ */
1435
+ async searchMenuItems(menuItems, searchText) {
1436
+ const result = [];
1437
+ for (const item of menuItems) {
1438
+ // Check if the current item's text matches the search text
1439
+ if (item.type != 'group' &&
1440
+ (item.children?.length ?? 0) == 0 &&
1441
+ (await this.translateService.translateAsync(item.text)).toLowerCase().includes(searchText.toLowerCase())) {
1442
+ result.push(item);
1443
+ }
1444
+ // Recursively search in children if they exist
1445
+ if (item.children && item.children.length > 0) {
1446
+ const childResults = await this.searchMenuItems(item.children, searchText);
1447
+ result.push(...childResults.map((x) => ({ ...x, parent: item })));
1448
+ }
1315
1449
  }
1316
- return new AXPSettingDefinitionGroupBuilder(this, foundGroup);
1317
- }
1318
- getGroups() {
1319
- return this.rootGroups;
1450
+ return result;
1320
1451
  }
1321
- // Expose groupMap for controlled access
1322
- hasGroup(name) {
1323
- return this.groupMap.has(name);
1452
+ }
1453
+
1454
+ class AXPFooterTextSlotComponent {
1455
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPFooterTextSlotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1456
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.3", type: AXPFooterTextSlotComponent, isStandalone: true, selector: "ng-component", inputs: { text: "text" }, ngImport: i0, template: `
1457
+ <small class="ax-text-sm" [innerHTML]="text"></small>
1458
+ `, isInline: true }); }
1459
+ }
1460
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPFooterTextSlotComponent, decorators: [{
1461
+ type: Component,
1462
+ args: [{
1463
+ template: `
1464
+ <small class="ax-text-sm" [innerHTML]="text"></small>
1465
+ `,
1466
+ standalone: true
1467
+ }]
1468
+ }], propDecorators: { text: [{
1469
+ type: Input
1470
+ }] } });
1471
+
1472
+ class AXPNavBarSlotComponent {
1473
+ constructor() {
1474
+ this.store = inject(Store);
1324
1475
  }
1325
- getGroup(name) {
1326
- return this.groupMap.get(name);
1476
+ handleCommand(action) {
1477
+ if (action)
1478
+ this.store.dispatch(action);
1327
1479
  }
1480
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPNavBarSlotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1481
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.3", type: AXPNavBarSlotComponent, isStandalone: true, selector: "ng-component", inputs: { items: "items" }, ngImport: i0, template: `
1482
+ <div class="ax-flex ax-items-center ax-justify-between ax-gap-5">
1483
+ <a *ngFor="let link of items" (click)="handleCommand(link.command)" >{{ link.text }}</a>
1484
+ </div>
1485
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], encapsulation: i0.ViewEncapsulation.None }); }
1328
1486
  }
1329
- class AXPSettingDefinitionGroupBuilder {
1330
- constructor(context, group) {
1331
- this.context = context;
1332
- this.group = group;
1487
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPNavBarSlotComponent, decorators: [{
1488
+ type: Component,
1489
+ args: [{
1490
+ template: `
1491
+ <div class="ax-flex ax-items-center ax-justify-between ax-gap-5">
1492
+ <a *ngFor="let link of items" (click)="handleCommand(link.command)" >{{ link.text }}</a>
1493
+ </div>
1494
+ `,
1495
+ imports: [CommonModule],
1496
+ encapsulation: ViewEncapsulation.None
1497
+ }]
1498
+ }], propDecorators: { items: [{
1499
+ type: Input
1500
+ }] } });
1501
+
1502
+ class AXPSearchDefinitionProviderContext {
1503
+ constructor() {
1504
+ this.definitions = [];
1505
+ this.definitionMap = new Map();
1333
1506
  }
1334
- addSection(name, title, description) {
1335
- const newSection = {
1507
+ addDefinition(name, title, icon, actions) {
1508
+ const definitionSearch = {
1336
1509
  name,
1337
1510
  title,
1338
- description: description,
1339
- settings: [],
1511
+ icon,
1512
+ actions: actions ?? [],
1340
1513
  };
1341
- this.group.sections.push(newSection);
1514
+ this.definitions.push(definitionSearch);
1515
+ this.definitionMap.set(name, definitionSearch); // Index by name
1516
+ return new AXPSearchDefinitionBuilder(this, definitionSearch);
1517
+ }
1518
+ definition(name) {
1519
+ const foundDefinition = this.definitionMap.get(name);
1520
+ if (!foundDefinition) {
1521
+ throw new Error(`definition with name "${name}" not found.`);
1522
+ }
1523
+ return new AXPSearchDefinitionBuilder(this, foundDefinition);
1524
+ }
1525
+ getDefinitions() {
1526
+ return this.definitions;
1527
+ }
1528
+ // Expose groupMap for controlled access
1529
+ hasEntity(name) {
1530
+ return this.definitionMap.has(name);
1531
+ }
1532
+ getDefinition(name) {
1533
+ return this.definitionMap.get(name);
1534
+ }
1535
+ }
1536
+ class AXPSearchDefinitionBuilder {
1537
+ constructor(context, definition) {
1538
+ this.context = context;
1539
+ this.definition = definition;
1540
+ }
1541
+ addAction(name) {
1542
+ const newAction = {
1543
+ name,
1544
+ type: 'view',
1545
+ command: '',
1546
+ priority: 'primary',
1547
+ };
1548
+ this.definition.actions.push(newAction);
1549
+ return new AXPSearchDefinitionActionBuilder(this);
1550
+ }
1551
+ action(name) {
1552
+ const foundAction = this.definition.actions.find((action) => action.name === name);
1553
+ if (!foundAction) {
1554
+ throw new Error(`action with name "${name}" not found in entity "${this.definition.name}".`);
1555
+ }
1556
+ return new AXPSearchDefinitionActionBuilder(this);
1557
+ }
1558
+ // addGroup(name: string, title: string, description?: string, icon?: string): AXPTextSearchEntityBuilder {
1559
+ // const newGroup: AXPTextSearchEntity = {
1560
+ // name,
1561
+ // title,
1562
+ // description: description,
1563
+ // icon,
1564
+ // groups: [],
1565
+ // sections: [],
1566
+ // };
1567
+ // this.entity.groups.push(newGroup);
1568
+ // if (this.context.hasGroup(name)) {
1569
+ // throw new Error(`Group with name "${name}" already exists.`);
1570
+ // }
1571
+ // this.context['groupMap'].set(name, newGroup);
1572
+ // return new AXPTextSearchEntityBuilder(this.context, newGroup);
1573
+ // }
1574
+ endEntity() {
1575
+ return this.context;
1576
+ }
1577
+ }
1578
+ class AXPSearchDefinitionActionBuilder {
1579
+ constructor(entityBuilder) {
1580
+ this.entityBuilder = entityBuilder;
1581
+ }
1582
+ endAction() {
1583
+ return this.entityBuilder;
1584
+ }
1585
+ }
1586
+
1587
+ // Injection token for setting providers
1588
+ const AXP_SEARCH_DEFINITION_PROVIDER = new InjectionToken('AXP_SEARCH_DEFINITION_PROVIDER');
1589
+ class AXPSearchDefinitionProviderService {
1590
+ constructor() {
1591
+ this.providers = inject(AXP_SEARCH_DEFINITION_PROVIDER, { optional: true });
1592
+ this.cache = null;
1593
+ }
1594
+ async load() {
1595
+ if (this.cache) {
1596
+ return;
1597
+ }
1598
+ const context = new AXPSearchDefinitionProviderContext();
1599
+ if (Array.isArray(this.providers)) {
1600
+ for (const provider of this.providers) {
1601
+ await provider.provide(context);
1602
+ }
1603
+ }
1604
+ this.cache = context.getDefinitions();
1605
+ }
1606
+ async getListAsync() {
1607
+ await this.load();
1608
+ return this.getList();
1609
+ }
1610
+ getList() {
1611
+ if (!this.cache) {
1612
+ return [];
1613
+ }
1614
+ else {
1615
+ return this.cache;
1616
+ }
1617
+ }
1618
+ findDefinition(definitionName) {
1619
+ const definition = this.getList().find((definition) => definition.name === definitionName);
1620
+ if (!definition) {
1621
+ throw new Error(`Definition with name ${definitionName} not found`);
1622
+ }
1623
+ return definition;
1624
+ }
1625
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSearchDefinitionProviderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1626
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSearchDefinitionProviderService, providedIn: 'root' }); }
1627
+ }
1628
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSearchDefinitionProviderService, decorators: [{
1629
+ type: Injectable,
1630
+ args: [{ providedIn: 'root' }]
1631
+ }] });
1632
+
1633
+ class AXPCommandSearchProvider {
1634
+ async search(text) {
1635
+ return this.commands.filter((command) => command.title.toLowerCase().includes(text.toLowerCase()));
1636
+ }
1637
+ }
1638
+
1639
+ // Injection token for setting providers
1640
+ const AXP_SEARCH_PROVIDER = new InjectionToken('AXP_SEARCH_PROVIDER');
1641
+ class AXPSearchService {
1642
+ constructor() {
1643
+ this.providers = inject(AXP_SEARCH_PROVIDER, { optional: true });
1644
+ this.definitionService = inject(AXPSearchDefinitionProviderService);
1645
+ }
1646
+ async search(text) {
1647
+ //TODO better handle this
1648
+ if (this.definitionService.getList().length == 0) {
1649
+ await this.definitionService.getListAsync();
1650
+ }
1651
+ if (!this.providers || (this.providers?.length || 0) === 0) {
1652
+ throw new Error('No search providers available'); // No providers available
1653
+ }
1654
+ const mergeData = [];
1655
+ const promises = this.providers.map((provider) => provider.search(text));
1656
+ const results = await Promise.all(promises);
1657
+ for (const resultArray of results) {
1658
+ for (const result of resultArray) {
1659
+ try {
1660
+ const definition = this.definitionService.findDefinition(result.name);
1661
+ mergeData.push({
1662
+ definitionName: definition.name,
1663
+ definitionTitle: definition.title,
1664
+ name: result.name,
1665
+ title: result.title,
1666
+ icon: result.icon ?? definition.icon,
1667
+ data: result.data,
1668
+ actions: definition.actions,
1669
+ description: result.description,
1670
+ parent: result.parent,
1671
+ });
1672
+ }
1673
+ catch (e) {
1674
+ console.error(e);
1675
+ }
1676
+ }
1677
+ }
1678
+ // Group data
1679
+ const groupedData = [];
1680
+ const groupMap = {};
1681
+ // Create groups
1682
+ for (const item of mergeData) {
1683
+ const groupName = item.definitionName; // Change this to the property you want to group by
1684
+ if (!groupMap[groupName]) {
1685
+ groupMap[groupName] = {
1686
+ name: groupName,
1687
+ title: item.definitionTitle, // You can adjust the title logic if needed
1688
+ children: [],
1689
+ };
1690
+ groupedData.push(groupMap[groupName]);
1691
+ }
1692
+ groupMap[groupName].children.push(omit(item, ['definitionName', 'definitionTitle']));
1693
+ }
1694
+ return groupedData;
1695
+ }
1696
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSearchService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1697
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSearchService, providedIn: 'root' }); }
1698
+ }
1699
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSearchService, decorators: [{
1700
+ type: Injectable,
1701
+ args: [{ providedIn: 'root' }]
1702
+ }] });
1703
+
1704
+ var AXPSettingScope;
1705
+ (function (AXPSettingScope) {
1706
+ AXPSettingScope["Environment"] = "C";
1707
+ AXPSettingScope["Global"] = "G";
1708
+ AXPSettingScope["Tenant"] = "T";
1709
+ AXPSettingScope["User"] = "U";
1710
+ })(AXPSettingScope || (AXPSettingScope = {}));
1711
+ ;
1712
+
1713
+ class AXPSettingDefinitionProviderContext {
1714
+ constructor() {
1715
+ this.rootGroups = [];
1716
+ this.groupMap = new Map();
1717
+ }
1718
+ addGroup(name, title, description, icon) {
1719
+ const newGroup = {
1720
+ name,
1721
+ title,
1722
+ description,
1723
+ icon,
1724
+ groups: [],
1725
+ sections: [],
1726
+ };
1727
+ this.rootGroups.push(newGroup);
1728
+ this.groupMap.set(name, newGroup); // Index by name
1729
+ return new AXPSettingDefinitionGroupBuilder(this, newGroup);
1730
+ }
1731
+ group(name) {
1732
+ const foundGroup = this.groupMap.get(name);
1733
+ if (!foundGroup) {
1734
+ throw new Error(`Group with name "${name}" not found.`);
1735
+ }
1736
+ return new AXPSettingDefinitionGroupBuilder(this, foundGroup);
1737
+ }
1738
+ getGroups() {
1739
+ return this.rootGroups;
1740
+ }
1741
+ // Expose groupMap for controlled access
1742
+ hasGroup(name) {
1743
+ return this.groupMap.has(name);
1744
+ }
1745
+ getGroup(name) {
1746
+ return this.groupMap.get(name);
1747
+ }
1748
+ }
1749
+ class AXPSettingDefinitionGroupBuilder {
1750
+ constructor(context, group) {
1751
+ this.context = context;
1752
+ this.group = group;
1753
+ }
1754
+ addSection(name, title, description) {
1755
+ const newSection = {
1756
+ name,
1757
+ title,
1758
+ description: description,
1759
+ settings: [],
1760
+ };
1761
+ this.group.sections.push(newSection);
1342
1762
  return new AXPSettingDefinitionSectionBuilder(this, newSection);
1343
1763
  }
1344
1764
  section(name) {
@@ -1388,768 +1808,335 @@ class AXPSettingDefinitionSectionBuilder {
1388
1808
  name: setting.key,
1389
1809
  path: setting.key,
1390
1810
  defaultValue: setting.defaultValue,
1391
- options: merge(setting.widget.options ?? {}, {
1392
- label: setting.widget.options?.['label'] ?? setting.title,
1393
- validationRules: setting.validationRules ?? [],
1394
- }),
1395
- valueTransforms: setting.valueTransforms,
1396
- triggers: setting.widget.triggers,
1397
- },
1398
- };
1399
- this.section.settings.push(newSetting);
1400
- return this;
1401
- }
1402
- endSection() {
1403
- return this.groupBuilder;
1404
- }
1405
- }
1406
-
1407
- // Injection token for setting providers
1408
- const AXP_SETTING_DEFINITION_PROVIDER = new InjectionToken('AXP_SETTING_DEFINITION_PROVIDER');
1409
- class AXPSettingDefinitionProviderService {
1410
- constructor() {
1411
- this.providers = inject(AXP_SETTING_DEFINITION_PROVIDER, { optional: true });
1412
- this.cache = null;
1413
- }
1414
- async load() {
1415
- if (this.cache) {
1416
- return;
1417
- }
1418
- const context = new AXPSettingDefinitionProviderContext();
1419
- if (Array.isArray(this.providers)) {
1420
- for (const provider of this.providers) {
1421
- await provider.provide(context);
1422
- }
1423
- }
1424
- this.cache = context.getGroups();
1425
- }
1426
- async getListAsync(scope) {
1427
- await this.load();
1428
- return this.getList(scope);
1429
- }
1430
- getList(scope) {
1431
- if (!this.cache) {
1432
- return [];
1433
- }
1434
- const scopeOrder = ['C', 'G', 'T', 'U']; // Scopes hierarchy in ascending order
1435
- const filterByScope = (groups, currentScope) => {
1436
- const currentScopeIndex = scopeOrder.indexOf(currentScope);
1437
- return groups
1438
- .map((group) => ({
1439
- ...group,
1440
- sections: group.sections.map((section) => ({
1441
- ...section,
1442
- settings: section.settings.filter((setting) => {
1443
- const settingScopeIndex = scopeOrder.indexOf(setting.scope);
1444
- // Include settings where:
1445
- // 1. The scope matches the requested scope.
1446
- if (setting.scope === currentScope)
1447
- return true;
1448
- // 2. The setting scope is higher (closer to 'U') and is inherited.
1449
- if (setting.isInherited &&
1450
- settingScopeIndex > currentScopeIndex // Higher scope
1451
- ) {
1452
- return true;
1453
- }
1454
- // 3. Exclude settings with a lower or irrelevant scope.
1455
- return false;
1456
- }),
1457
- })).filter((section) => section.settings.length > 0), // Keep only sections with settings
1458
- groups: filterByScope(group.groups, currentScope), // Recursively filter nested groups
1459
- }))
1460
- .filter((group) => group.sections.length > 0 || group.groups.length > 0); // Keep groups with valid sections or nested groups
1461
- };
1462
- return filterByScope(this.cache, scope);
1463
- }
1464
- async defaultValues() {
1465
- const defaults = {};
1466
- const collectDefaults = (groups) => {
1467
- groups.forEach((group) => {
1468
- group.sections.forEach((section) => {
1469
- section.settings.forEach((setting) => {
1470
- if (setting.defaultValue !== undefined) {
1471
- defaults[setting.name] = setting.defaultValue;
1472
- }
1473
- });
1474
- });
1475
- collectDefaults(group.groups);
1476
- });
1477
- };
1478
- if (!this.cache) {
1479
- await this.load();
1480
- }
1481
- collectDefaults(this.cache);
1482
- return defaults;
1483
- }
1484
- findGroup(scope, groupName) {
1485
- return this.searchRecursive(this.getList(scope), groupName, []); // Initialize with an empty breadcrumb
1486
- }
1487
- searchRecursive(groups, groupName, breadcrumb) {
1488
- for (const group of groups) {
1489
- const currentBreadcrumb = [...breadcrumb, { name: group.name, title: group.title, description: group.description }];
1490
- // If the group name matches, return its details
1491
- if (group.name === groupName) {
1492
- return {
1493
- breadcrumb: currentBreadcrumb,
1494
- sections: group.sections.length > 0 ? group.sections : null,
1495
- groups: group.groups.length > 0 ? group.groups : null,
1496
- };
1497
- }
1498
- // Recursively search in nested groups
1499
- const nestedResult = this.searchRecursive(group.groups, groupName, currentBreadcrumb);
1500
- if (nestedResult.breadcrumb.length > 0) {
1501
- return nestedResult;
1502
- }
1503
- }
1504
- // If no matching group is found
1505
- return {
1506
- breadcrumb: [],
1507
- groups: [],
1508
- sections: []
1509
- };
1510
- }
1511
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSettingDefinitionProviderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1512
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSettingDefinitionProviderService, providedIn: 'root' }); }
1513
- }
1514
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSettingDefinitionProviderService, decorators: [{
1515
- type: Injectable,
1516
- args: [{ providedIn: 'root' }]
1517
- }] });
1518
- class AXPSettingDefaultValueProvider {
1519
- constructor() {
1520
- this.definitionProvider = inject(AXPSettingDefinitionProviderService);
1521
- }
1522
- get scope() {
1523
- return AXPSettingScope.Global;
1524
- }
1525
- async load() {
1526
- return Object.entries(await this.definitionProvider.defaultValues()).map(c => ({ key: c[0], value: c[1] }));
1527
- }
1528
- set(key, value) {
1529
- throw new Error('Method not implemented.');
1530
- }
1531
- }
1532
-
1533
- const AXP_SETTING_VALUE_PROVIDER = new InjectionToken('AXP_SETTING_VALUE_PROVIDER', {
1534
- providedIn: 'root',
1535
- factory: () => {
1536
- return [
1537
- //new AXPSettingDefaultValueProvider(),
1538
- new AXPSettingValueProviderDefault(AXPSettingScope.Tenant),
1539
- new AXPSettingValueProviderDefault(AXPSettingScope.User)
1540
- ];
1541
- }
1542
- });
1543
- class AXPSettingValueProviderDefault {
1544
- get scope() {
1545
- return this._scope;
1546
- }
1547
- constructor(_scope) {
1548
- this._scope = _scope;
1549
- this.cache = new Map();
1550
- this.localStorageKey = `AXP_SETTINGS_SCOPE(${this.scope})`;
1551
- }
1552
- async load() {
1553
- // Load settings from localStorage as a single key
1554
- const storedSettings = localStorage.getItem(this.localStorageKey);
1555
- if (storedSettings) {
1556
- const parsedSettings = JSON.parse(storedSettings);
1557
- Object.entries(parsedSettings).forEach(([key, value]) => {
1558
- this.cache.set(key, value);
1559
- });
1560
- return Promise.resolve(Array.from(this.cache.entries()).map(c => ({ key: c[0], value: c[1] })));
1561
- }
1562
- return Promise.resolve([]);
1563
- }
1564
- async set(keyOrValues, value) {
1565
- if (typeof keyOrValues === 'string') {
1566
- // Single value update
1567
- this.cache.set(keyOrValues, value);
1568
- }
1569
- else {
1570
- // Bulk update
1571
- for (const [key, val] of Object.entries(keyOrValues)) {
1572
- this.cache.set(key, val);
1573
- }
1574
- }
1575
- await this.saveToLocalStorage();
1576
- }
1577
- async saveToLocalStorage() {
1578
- const settingsObject = {};
1579
- this.cache.forEach((value, key) => {
1580
- settingsObject[key] = value;
1581
- });
1582
- localStorage.setItem(this.localStorageKey, JSON.stringify(settingsObject));
1583
- }
1584
- }
1585
-
1586
- class AXPSettingValueProviderService {
1587
- constructor() {
1588
- this.providers = inject(AXP_SETTING_VALUE_PROVIDER);
1589
- this.definitionService = inject(AXPSettingDefinitionProviderService);
1590
- this.scopedSettingsCache = new Map();
1591
- this.onChanged = new Subject();
1592
- // Initialize scoped caches for dynamic scopes
1593
- const staticScopes = [AXPSettingScope.Environment, AXPSettingScope.Global, AXPSettingScope.Tenant, AXPSettingScope.User];
1594
- staticScopes.forEach((scope) => {
1595
- if (!this.scopedSettingsCache.has(scope)) {
1596
- this.scopedSettingsCache.set(scope, new Map());
1597
- }
1598
- });
1599
- }
1600
- async load() {
1601
- try {
1602
- const settingsList = [];
1603
- for (const provider of this.providers) {
1604
- const scopeCache = this.scopedSettingsCache.get(provider.scope);
1605
- const providerSettings = await provider.load();
1606
- providerSettings.forEach((setting) => {
1607
- scopeCache.set(setting.key, setting.value);
1608
- });
1609
- settingsList.push(...providerSettings);
1610
- }
1611
- return settingsList;
1612
- }
1613
- catch (error) {
1614
- console.error('Error loading settings', error);
1615
- throw error;
1616
- }
1617
- }
1618
- async get(key) {
1619
- if (this.scopedSettingsCache.size === 0) {
1620
- await this.load();
1621
- }
1622
- const scopeOrder = [AXPSettingScope.User, AXPSettingScope.Tenant, AXPSettingScope.Global, AXPSettingScope.Environment];
1623
- for (const scope of scopeOrder) {
1624
- const scopeCache = this.scopedSettingsCache.get(scope);
1625
- if (scopeCache && scopeCache.has(key)) {
1626
- const value = scopeCache.get(key);
1627
- if (value !== undefined && value !== null) {
1628
- return cloneDeep(value);
1629
- }
1630
- }
1631
- }
1632
- const defaults = await this.definitionService.defaultValues();
1633
- return get(defaults, key); // Fallback if no value is found
1634
- }
1635
- async defaultValues(scope) {
1636
- let scopeOrder = [AXPSettingScope.Environment, AXPSettingScope.Global, AXPSettingScope.Tenant, AXPSettingScope.User].reverse();
1637
- const scopeIndex = scopeOrder.indexOf(scope);
1638
- if (scopeIndex === -1) {
1639
- throw new Error(`Invalid scope: ${scope}`);
1640
- }
1641
- scopeOrder = scopeOrder.slice(scopeIndex + 1);
1642
- // Accumulate defaults from the current scope and higher scopes
1643
- const accumulatedDefaults = {};
1644
- for (let i = scopeIndex; i < scopeOrder.length; i++) {
1645
- const currentScope = scopeOrder[i];
1646
- const scopeCache = this.scopedSettingsCache.get(currentScope);
1647
- if (scopeCache) {
1648
- scopeCache.forEach((value, key) => {
1649
- if (!(key in accumulatedDefaults)) {
1650
- accumulatedDefaults[key] = value;
1651
- }
1652
- });
1653
- }
1654
- }
1655
- // Merge with global default values from the definition service
1656
- const globalDefaults = await this.definitionService.defaultValues();
1657
- return { ...globalDefaults, ...accumulatedDefaults };
1658
- }
1659
- scope(scope) {
1660
- const provider = this.providers.find((p) => p.scope === scope);
1661
- if (!provider) {
1662
- throw new Error(`No provider found for scope: ${scope}`);
1663
- }
1664
- return new ScopedSettingService(this, provider, this.onChanged, this.scopedSettingsCache.get(scope));
1665
- }
1666
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSettingValueProviderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1667
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSettingValueProviderService, providedIn: 'root' }); }
1668
- }
1669
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSettingValueProviderService, decorators: [{
1670
- type: Injectable,
1671
- args: [{
1672
- providedIn: 'root',
1673
- }]
1674
- }], ctorParameters: () => [] });
1675
- class ScopedSettingService {
1676
- constructor(parent, provider, onChanged, scopeCache) {
1677
- this.parent = parent;
1678
- this.provider = provider;
1679
- this.onChanged = onChanged;
1680
- this.scopeCache = scopeCache;
1681
- }
1682
- async get(key) {
1683
- const settings = await this.provider.load();
1684
- const setting = settings.find((s) => s.key === key);
1685
- return setting ? cloneDeep(setting.value) : undefined;
1686
- }
1687
- async all() {
1688
- const settings = await this.provider.load();
1689
- return Object.fromEntries(settings.map((s) => [s.key, cloneDeep(s.value)]));
1690
- }
1691
- async defaultValues() {
1692
- return this.parent.defaultValues(this.provider.scope);
1693
- }
1694
- async set(keyOrValues, value) {
1695
- if (typeof keyOrValues === 'string') {
1696
- // Single key-value pair
1697
- await this.provider.set(keyOrValues, value);
1698
- this.scopeCache.set(keyOrValues, value); // Sync the cache
1699
- this.onChanged.next({
1700
- scope: this.provider.scope,
1701
- keys: [keyOrValues],
1702
- values: { [keyOrValues]: value },
1703
- entries: [{ key: keyOrValues, value }],
1704
- });
1705
- }
1706
- else {
1707
- // Multiple key-value pairs
1708
- await this.provider.set(keyOrValues);
1709
- Object.entries(keyOrValues).forEach(([key, val]) => this.scopeCache.set(key, val)); // Sync the cache
1710
- const entries = Object.entries(keyOrValues).map(([key, val]) => ({ key, value: val }));
1711
- this.onChanged.next({
1712
- scope: this.provider.scope,
1713
- keys: Object.keys(keyOrValues),
1714
- values: keyOrValues,
1715
- entries,
1716
- });
1717
- }
1718
- }
1719
- }
1720
-
1721
- class AXPCommonEffects {
1722
- constructor(actions$, router, settingService) {
1723
- this.actions$ = actions$;
1724
- this.router = router;
1725
- this.settingService = settingService;
1726
- this.command$ = createEffect(() => this.actions$.pipe(ofType(AXPNavigateAction), switchMap((action) => {
1727
- if (Array.isArray(action.payload.commands))
1728
- this.router.navigate(action.payload.commands, action.payload.extras);
1729
- else {
1730
- if (action.payload.commands.toLowerCase().startsWith('http'))
1731
- window.open(action.payload.commands, '_blank');
1732
- else
1733
- this.router.navigate([action.payload.commands], action.payload.extras);
1734
- }
1735
- return of();
1736
- })), { dispatch: false });
1737
- }
1738
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPCommonEffects, deps: [{ token: i1$1.Actions }, { token: i2$1.Router }, { token: AXPSettingValueProviderService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1739
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPCommonEffects }); }
1740
- }
1741
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPCommonEffects, decorators: [{
1742
- type: Injectable
1743
- }], ctorParameters: () => [{ type: i1$1.Actions }, { type: i2$1.Router }, { type: AXPSettingValueProviderService }] });
1744
-
1745
- const AXPMenuService = signalStore({ providedIn: 'root' },
1746
- // Initial State
1747
- withState((router = inject(Router)) => {
1748
- return {
1749
- items: [],
1750
- selectedMenuItem: {
1751
- item: null,
1752
- isFullMatch: false
1753
- },
1754
- };
1755
- }),
1756
- // Methods for State Management
1757
- withMethods((store, router = inject(Router), globalStore = inject(Store)) => {
1758
- return {
1759
- setMenuItems(items) {
1760
- patchState(store, { items: items });
1761
- },
1762
- selectMenuItemByRoute(path) {
1763
- const findItem = (items) => {
1764
- for (const item of items) {
1765
- // Recursively search children first
1766
- if (item.children) {
1767
- const foundChild = findItem(item.children);
1768
- if (foundChild.item) {
1769
- return foundChild;
1770
- }
1771
- }
1772
- if (item.path) {
1773
- // Check if the item path matches the current path
1774
- const matchResult = pathsMatch(item.path, path, ["list", "view", "edit", "create"]);
1775
- if (matchResult.isMatch) {
1776
- return { item, isPartialMatch: matchResult.isPartial };
1777
- }
1778
- }
1779
- }
1780
- return { item: null, isPartialMatch: false };
1781
- };
1782
- const pathsMatch = (itemPath, currentPath, trailingSegmentsToIgnore = []) => {
1783
- const itemSegments = itemPath.split('/').filter(segment => segment.length > 0);
1784
- const pathSegments = currentPath.split('/').filter(segment => segment.length > 0);
1785
- const menuLength = itemSegments.length;
1786
- const pathLength = pathSegments.length;
1787
- // Identify the effective base length for the menuPath
1788
- let effectiveMenuLength = menuLength;
1789
- if (menuLength > 0 &&
1790
- trailingSegmentsToIgnore.includes(itemSegments[menuLength - 1])) {
1791
- effectiveMenuLength--; // Exclude trailing non-hierarchical segments
1792
- }
1793
- // Check if the menuPath (base segments) is a prefix of browserPath
1794
- let isPrefix = true;
1795
- for (let i = 0; i < effectiveMenuLength; i++) {
1796
- if (itemSegments[i] !== pathSegments[i]) {
1797
- isPrefix = false;
1798
- break;
1799
- }
1800
- }
1801
- // Partial match: menuPath base is a strict prefix of browserPath
1802
- const isPartialMatch = isPrefix && effectiveMenuLength < pathLength;
1803
- // Exact match: all segments match completely
1804
- const isExactMatch = isPrefix && effectiveMenuLength === pathLength;
1805
- return {
1806
- isMatch: isExactMatch || isPartialMatch,
1807
- isPartial: isPartialMatch && !isExactMatch,
1808
- };
1809
- };
1810
- const items = store.items();
1811
- const { item, isPartialMatch } = findItem(items);
1812
- patchState(store, { selectedMenuItem: { item, isFullMatch: !isPartialMatch } });
1813
- },
1814
- executeCommand(item) {
1815
- if (item.command) {
1816
- globalStore.dispatch(item.command);
1817
- }
1818
- else if (item.path) {
1819
- globalStore.dispatch(AXPNavigateAction({ payload: { commands: item.path } }));
1820
- }
1821
- patchState(store, { selectedMenuItem: { item, isFullMatch: true } });
1822
- },
1823
- isItemOpen(item) {
1824
- const selectedItem = store.selectedMenuItem();
1825
- if (!selectedItem) {
1826
- return false;
1827
- }
1828
- const findParent = (currentItem, targetItem) => {
1829
- if (currentItem.children?.includes(targetItem)) {
1830
- return true;
1831
- }
1832
- return currentItem.children?.some(child => findParent(child, targetItem)) ?? false;
1833
- };
1834
- return item === selectedItem?.item || findParent(item, selectedItem.item);
1835
- }
1836
- };
1837
- }), withHooks((store, menuProviderService = inject(AXPMenuProviderService)) => ({
1838
- onInit() {
1839
- (async () => {
1840
- const items = await menuProviderService.items();
1841
- patchState(store, { items: items });
1842
- })();
1843
- },
1844
- onDestroy() {
1845
- },
1846
- })));
1847
-
1848
- class AXPMenuSearchDefinitionProvider {
1849
- async provide(context) {
1850
- context.addDefinition('menu', 'Menu', 'fa-thin fa-bars', [
1851
- {
1852
- name: 'open',
1853
- command: {
1854
- name: 'view',
1855
- options: {},
1856
- },
1857
- type: 'view',
1858
- priority: 'primary',
1859
- },
1860
- ]);
1861
- }
1862
- }
1863
-
1864
- class AXPMenuSearchProvider {
1865
- constructor() {
1866
- this.menuService = inject(AXPMenuProviderService);
1867
- this.trService = inject(AXTranslationService);
1868
- }
1869
- async search(text) {
1870
- const menuItems = await this.searchMenuItems(await this.menuService.items(), text);
1871
- return sortBy(menuItems.map((item) => ({
1872
- name: 'menu', // Use `name` or empty string if undefined
1873
- title: item.text, // Use `text` for the `title`
1874
- icon: item.icon, // Include the `icon` if present
1875
- data: item,
1876
- parent: item.parent
1877
- ? {
1878
- title: item.parent.text,
1879
- data: item.parent,
1880
- }
1881
- : undefined,
1882
- })), [(o) => this.trService.translateSync(o.title)]);
1883
- }
1884
- /**
1885
- * Recursively searches AXPMenuItem and its children for a matching text.
1886
- *
1887
- * @param menuItems - The array of AXPMenuItem to search in.
1888
- * @param searchText - The text to search for (case-insensitive).
1889
- * @returns An array of AXPMenuItem that match the search text.
1890
- */
1891
- async searchMenuItems(menuItems, searchText) {
1892
- const result = [];
1893
- for (const item of menuItems) {
1894
- // Check if the current item's text matches the search text
1895
- if (item.type != 'group' &&
1896
- (item.children?.length ?? 0) == 0 &&
1897
- (await this.trService.translateAsync(item.text)).toLowerCase().includes(searchText.toLowerCase())) {
1898
- result.push(item);
1899
- }
1900
- // Recursively search in children if they exist
1901
- if (item.children && item.children.length > 0) {
1902
- const childResults = await this.searchMenuItems(item.children, searchText);
1903
- result.push(...childResults.map((x) => ({ ...x, parent: item })));
1904
- }
1905
- }
1906
- return result;
1811
+ options: merge(setting.widget.options ?? {}, {
1812
+ label: setting.widget.options?.['label'] ?? setting.title,
1813
+ validationRules: setting.validationRules ?? [],
1814
+ }),
1815
+ valueTransforms: setting.valueTransforms,
1816
+ triggers: setting.widget.triggers,
1817
+ },
1818
+ };
1819
+ this.section.settings.push(newSetting);
1820
+ return this;
1821
+ }
1822
+ endSection() {
1823
+ return this.groupBuilder;
1907
1824
  }
1908
1825
  }
1909
1826
 
1910
- class AXPFooterTextSlotComponent {
1911
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPFooterTextSlotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1912
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.3", type: AXPFooterTextSlotComponent, isStandalone: true, selector: "ng-component", inputs: { text: "text" }, ngImport: i0, template: `
1913
- <small class="ax-text-sm" [innerHTML]="text"></small>
1914
- `, isInline: true }); }
1915
- }
1916
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPFooterTextSlotComponent, decorators: [{
1917
- type: Component,
1918
- args: [{
1919
- template: `
1920
- <small class="ax-text-sm" [innerHTML]="text"></small>
1921
- `,
1922
- standalone: true
1923
- }]
1924
- }], propDecorators: { text: [{
1925
- type: Input
1926
- }] } });
1927
-
1928
- class AXPNavBarSlotComponent {
1827
+ // Injection token for setting providers
1828
+ const AXP_SETTING_DEFINITION_PROVIDER = new InjectionToken('AXP_SETTING_DEFINITION_PROVIDER');
1829
+ class AXPSettingDefinitionProviderService {
1929
1830
  constructor() {
1930
- this.store = inject(Store);
1831
+ this.providers = inject(AXP_SETTING_DEFINITION_PROVIDER, { optional: true });
1832
+ this.cache = null;
1931
1833
  }
1932
- handleCommand(action) {
1933
- if (action)
1934
- this.store.dispatch(action);
1834
+ async load() {
1835
+ if (this.cache) {
1836
+ return;
1837
+ }
1838
+ const context = new AXPSettingDefinitionProviderContext();
1839
+ if (Array.isArray(this.providers)) {
1840
+ for (const provider of this.providers) {
1841
+ await provider.provide(context);
1842
+ }
1843
+ }
1844
+ this.cache = context.getGroups();
1935
1845
  }
1936
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPNavBarSlotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1937
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.3", type: AXPNavBarSlotComponent, isStandalone: true, selector: "ng-component", inputs: { items: "items" }, ngImport: i0, template: `
1938
- <div class="ax-flex ax-items-center ax-justify-between ax-gap-5">
1939
- <a *ngFor="let link of items" (click)="handleCommand(link.command)" >{{ link.text }}</a>
1940
- </div>
1941
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], encapsulation: i0.ViewEncapsulation.None }); }
1942
- }
1943
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPNavBarSlotComponent, decorators: [{
1944
- type: Component,
1945
- args: [{
1946
- template: `
1947
- <div class="ax-flex ax-items-center ax-justify-between ax-gap-5">
1948
- <a *ngFor="let link of items" (click)="handleCommand(link.command)" >{{ link.text }}</a>
1949
- </div>
1950
- `,
1951
- imports: [CommonModule],
1952
- encapsulation: ViewEncapsulation.None
1953
- }]
1954
- }], propDecorators: { items: [{
1955
- type: Input
1956
- }] } });
1957
-
1958
- class AXPSearchDefinitionProviderContext {
1959
- constructor() {
1960
- this.definitions = [];
1961
- this.definitionMap = new Map();
1846
+ async getListAsync(scope) {
1847
+ await this.load();
1848
+ return this.getList(scope);
1962
1849
  }
1963
- addDefinition(name, title, icon, actions) {
1964
- const definitionSearch = {
1965
- name,
1966
- title,
1967
- icon,
1968
- actions: actions ?? [],
1850
+ getList(scope) {
1851
+ if (!this.cache) {
1852
+ return [];
1853
+ }
1854
+ const scopeOrder = ['C', 'G', 'T', 'U']; // Scopes hierarchy in ascending order
1855
+ const filterByScope = (groups, currentScope) => {
1856
+ const currentScopeIndex = scopeOrder.indexOf(currentScope);
1857
+ return groups
1858
+ .map((group) => ({
1859
+ ...group,
1860
+ sections: group.sections.map((section) => ({
1861
+ ...section,
1862
+ settings: section.settings.filter((setting) => {
1863
+ const settingScopeIndex = scopeOrder.indexOf(setting.scope);
1864
+ // Include settings where:
1865
+ // 1. The scope matches the requested scope.
1866
+ if (setting.scope === currentScope)
1867
+ return true;
1868
+ // 2. The setting scope is higher (closer to 'U') and is inherited.
1869
+ if (setting.isInherited &&
1870
+ settingScopeIndex > currentScopeIndex // Higher scope
1871
+ ) {
1872
+ return true;
1873
+ }
1874
+ // 3. Exclude settings with a lower or irrelevant scope.
1875
+ return false;
1876
+ }),
1877
+ })).filter((section) => section.settings.length > 0), // Keep only sections with settings
1878
+ groups: filterByScope(group.groups, currentScope), // Recursively filter nested groups
1879
+ }))
1880
+ .filter((group) => group.sections.length > 0 || group.groups.length > 0); // Keep groups with valid sections or nested groups
1969
1881
  };
1970
- this.definitions.push(definitionSearch);
1971
- this.definitionMap.set(name, definitionSearch); // Index by name
1972
- return new AXPSearchDefinitionBuilder(this, definitionSearch);
1882
+ return filterByScope(this.cache, scope);
1973
1883
  }
1974
- definition(name) {
1975
- const foundDefinition = this.definitionMap.get(name);
1976
- if (!foundDefinition) {
1977
- throw new Error(`definition with name "${name}" not found.`);
1884
+ async defaultValues() {
1885
+ const defaults = {};
1886
+ const collectDefaults = (groups) => {
1887
+ groups.forEach((group) => {
1888
+ group.sections.forEach((section) => {
1889
+ section.settings.forEach((setting) => {
1890
+ if (setting.defaultValue !== undefined) {
1891
+ defaults[setting.name] = setting.defaultValue;
1892
+ }
1893
+ });
1894
+ });
1895
+ collectDefaults(group.groups);
1896
+ });
1897
+ };
1898
+ if (!this.cache) {
1899
+ await this.load();
1978
1900
  }
1979
- return new AXPSearchDefinitionBuilder(this, foundDefinition);
1901
+ collectDefaults(this.cache);
1902
+ return defaults;
1980
1903
  }
1981
- getDefinitions() {
1982
- return this.definitions;
1904
+ findGroup(scope, groupName) {
1905
+ return this.searchRecursive(this.getList(scope), groupName, []); // Initialize with an empty breadcrumb
1983
1906
  }
1984
- // Expose groupMap for controlled access
1985
- hasEntity(name) {
1986
- return this.definitionMap.has(name);
1907
+ searchRecursive(groups, groupName, breadcrumb) {
1908
+ for (const group of groups) {
1909
+ const currentBreadcrumb = [...breadcrumb, { name: group.name, title: group.title, description: group.description }];
1910
+ // If the group name matches, return its details
1911
+ if (group.name === groupName) {
1912
+ return {
1913
+ breadcrumb: currentBreadcrumb,
1914
+ sections: group.sections.length > 0 ? group.sections : null,
1915
+ groups: group.groups.length > 0 ? group.groups : null,
1916
+ };
1917
+ }
1918
+ // Recursively search in nested groups
1919
+ const nestedResult = this.searchRecursive(group.groups, groupName, currentBreadcrumb);
1920
+ if (nestedResult.breadcrumb.length > 0) {
1921
+ return nestedResult;
1922
+ }
1923
+ }
1924
+ // If no matching group is found
1925
+ return {
1926
+ breadcrumb: [],
1927
+ groups: [],
1928
+ sections: []
1929
+ };
1987
1930
  }
1988
- getDefinition(name) {
1989
- return this.definitionMap.get(name);
1931
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSettingDefinitionProviderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1932
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSettingDefinitionProviderService, providedIn: 'root' }); }
1933
+ }
1934
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSettingDefinitionProviderService, decorators: [{
1935
+ type: Injectable,
1936
+ args: [{ providedIn: 'root' }]
1937
+ }] });
1938
+ class AXPSettingDefaultValueProvider {
1939
+ constructor() {
1940
+ this.definitionProvider = inject(AXPSettingDefinitionProviderService);
1941
+ }
1942
+ get scope() {
1943
+ return AXPSettingScope.Global;
1944
+ }
1945
+ async load() {
1946
+ return Object.entries(await this.definitionProvider.defaultValues()).map(c => ({ key: c[0], value: c[1] }));
1947
+ }
1948
+ set(key, value) {
1949
+ throw new Error('Method not implemented.');
1990
1950
  }
1991
1951
  }
1992
- class AXPSearchDefinitionBuilder {
1993
- constructor(context, definition) {
1994
- this.context = context;
1995
- this.definition = definition;
1952
+
1953
+ const AXP_SETTING_VALUE_PROVIDER = new InjectionToken('AXP_SETTING_VALUE_PROVIDER', {
1954
+ providedIn: 'root',
1955
+ factory: () => {
1956
+ return [
1957
+ //new AXPSettingDefaultValueProvider(),
1958
+ new AXPSettingValueProviderDefault(AXPSettingScope.Tenant),
1959
+ new AXPSettingValueProviderDefault(AXPSettingScope.User)
1960
+ ];
1996
1961
  }
1997
- addAction(name) {
1998
- const newAction = {
1999
- name,
2000
- type: 'view',
2001
- command: '',
2002
- priority: 'primary',
2003
- };
2004
- this.definition.actions.push(newAction);
2005
- return new AXPSearchDefinitionActionBuilder(this);
1962
+ });
1963
+ class AXPSettingValueProviderDefault {
1964
+ get scope() {
1965
+ return this._scope;
2006
1966
  }
2007
- action(name) {
2008
- const foundAction = this.definition.actions.find((action) => action.name === name);
2009
- if (!foundAction) {
2010
- throw new Error(`action with name "${name}" not found in entity "${this.definition.name}".`);
2011
- }
2012
- return new AXPSearchDefinitionActionBuilder(this);
1967
+ constructor(_scope) {
1968
+ this._scope = _scope;
1969
+ this.cache = new Map();
1970
+ this.localStorageKey = `AXP_SETTINGS_SCOPE(${this.scope})`;
2013
1971
  }
2014
- // addGroup(name: string, title: string, description?: string, icon?: string): AXPTextSearchEntityBuilder {
2015
- // const newGroup: AXPTextSearchEntity = {
2016
- // name,
2017
- // title,
2018
- // description: description,
2019
- // icon,
2020
- // groups: [],
2021
- // sections: [],
2022
- // };
2023
- // this.entity.groups.push(newGroup);
2024
- // if (this.context.hasGroup(name)) {
2025
- // throw new Error(`Group with name "${name}" already exists.`);
2026
- // }
2027
- // this.context['groupMap'].set(name, newGroup);
2028
- // return new AXPTextSearchEntityBuilder(this.context, newGroup);
2029
- // }
2030
- endEntity() {
2031
- return this.context;
1972
+ async load() {
1973
+ // Load settings from localStorage as a single key
1974
+ const storedSettings = localStorage.getItem(this.localStorageKey);
1975
+ if (storedSettings) {
1976
+ const parsedSettings = JSON.parse(storedSettings);
1977
+ Object.entries(parsedSettings).forEach(([key, value]) => {
1978
+ this.cache.set(key, value);
1979
+ });
1980
+ return Promise.resolve(Array.from(this.cache.entries()).map(c => ({ key: c[0], value: c[1] })));
1981
+ }
1982
+ return Promise.resolve([]);
2032
1983
  }
2033
- }
2034
- class AXPSearchDefinitionActionBuilder {
2035
- constructor(entityBuilder) {
2036
- this.entityBuilder = entityBuilder;
1984
+ async set(keyOrValues, value) {
1985
+ if (typeof keyOrValues === 'string') {
1986
+ // Single value update
1987
+ this.cache.set(keyOrValues, value);
1988
+ }
1989
+ else {
1990
+ // Bulk update
1991
+ for (const [key, val] of Object.entries(keyOrValues)) {
1992
+ this.cache.set(key, val);
1993
+ }
1994
+ }
1995
+ await this.saveToLocalStorage();
2037
1996
  }
2038
- endAction() {
2039
- return this.entityBuilder;
1997
+ async saveToLocalStorage() {
1998
+ const settingsObject = {};
1999
+ this.cache.forEach((value, key) => {
2000
+ settingsObject[key] = value;
2001
+ });
2002
+ localStorage.setItem(this.localStorageKey, JSON.stringify(settingsObject));
2040
2003
  }
2041
2004
  }
2042
2005
 
2043
- // Injection token for setting providers
2044
- const AXP_SEARCH_DEFINITION_PROVIDER = new InjectionToken('AXP_SEARCH_DEFINITION_PROVIDER');
2045
- class AXPSearchDefinitionProviderService {
2006
+ class AXPSettingValueProviderService {
2046
2007
  constructor() {
2047
- this.providers = inject(AXP_SEARCH_DEFINITION_PROVIDER, { optional: true });
2048
- this.cache = null;
2008
+ this.providers = inject(AXP_SETTING_VALUE_PROVIDER);
2009
+ this.definitionService = inject(AXPSettingDefinitionProviderService);
2010
+ this.scopedSettingsCache = new Map();
2011
+ this.onChanged = new Subject();
2012
+ // Initialize scoped caches for dynamic scopes
2013
+ const staticScopes = [AXPSettingScope.Environment, AXPSettingScope.Global, AXPSettingScope.Tenant, AXPSettingScope.User];
2014
+ staticScopes.forEach((scope) => {
2015
+ if (!this.scopedSettingsCache.has(scope)) {
2016
+ this.scopedSettingsCache.set(scope, new Map());
2017
+ }
2018
+ });
2049
2019
  }
2050
2020
  async load() {
2051
- if (this.cache) {
2052
- return;
2053
- }
2054
- const context = new AXPSearchDefinitionProviderContext();
2055
- if (Array.isArray(this.providers)) {
2021
+ try {
2022
+ const settingsList = [];
2056
2023
  for (const provider of this.providers) {
2057
- await provider.provide(context);
2024
+ const scopeCache = this.scopedSettingsCache.get(provider.scope);
2025
+ const providerSettings = await provider.load();
2026
+ providerSettings.forEach((setting) => {
2027
+ scopeCache.set(setting.key, setting.value);
2028
+ });
2029
+ settingsList.push(...providerSettings);
2058
2030
  }
2031
+ return settingsList;
2032
+ }
2033
+ catch (error) {
2034
+ console.error('Error loading settings', error);
2035
+ throw error;
2059
2036
  }
2060
- this.cache = context.getDefinitions();
2061
2037
  }
2062
- async getListAsync() {
2063
- await this.load();
2064
- return this.getList();
2038
+ async get(key) {
2039
+ if (this.scopedSettingsCache.size === 0) {
2040
+ await this.load();
2041
+ }
2042
+ const scopeOrder = [AXPSettingScope.User, AXPSettingScope.Tenant, AXPSettingScope.Global, AXPSettingScope.Environment];
2043
+ for (const scope of scopeOrder) {
2044
+ const scopeCache = this.scopedSettingsCache.get(scope);
2045
+ if (scopeCache && scopeCache.has(key)) {
2046
+ const value = scopeCache.get(key);
2047
+ if (value !== undefined && value !== null) {
2048
+ return cloneDeep(value);
2049
+ }
2050
+ }
2051
+ }
2052
+ const defaults = await this.definitionService.defaultValues();
2053
+ return get(defaults, key); // Fallback if no value is found
2065
2054
  }
2066
- getList() {
2067
- if (!this.cache) {
2068
- return [];
2055
+ async defaultValues(scope) {
2056
+ let scopeOrder = [AXPSettingScope.Environment, AXPSettingScope.Global, AXPSettingScope.Tenant, AXPSettingScope.User].reverse();
2057
+ const scopeIndex = scopeOrder.indexOf(scope);
2058
+ if (scopeIndex === -1) {
2059
+ throw new Error(`Invalid scope: ${scope}`);
2069
2060
  }
2070
- else {
2071
- return this.cache;
2061
+ scopeOrder = scopeOrder.slice(scopeIndex + 1);
2062
+ // Accumulate defaults from the current scope and higher scopes
2063
+ const accumulatedDefaults = {};
2064
+ for (let i = scopeIndex; i < scopeOrder.length; i++) {
2065
+ const currentScope = scopeOrder[i];
2066
+ const scopeCache = this.scopedSettingsCache.get(currentScope);
2067
+ if (scopeCache) {
2068
+ scopeCache.forEach((value, key) => {
2069
+ if (!(key in accumulatedDefaults)) {
2070
+ accumulatedDefaults[key] = value;
2071
+ }
2072
+ });
2073
+ }
2072
2074
  }
2075
+ // Merge with global default values from the definition service
2076
+ const globalDefaults = await this.definitionService.defaultValues();
2077
+ return { ...globalDefaults, ...accumulatedDefaults };
2073
2078
  }
2074
- findDefinition(definitionName) {
2075
- const definition = this.getList().find((definition) => definition.name === definitionName);
2076
- if (!definition) {
2077
- throw new Error(`Definition with name ${definitionName} not found`);
2079
+ scope(scope) {
2080
+ const provider = this.providers.find((p) => p.scope === scope);
2081
+ if (!provider) {
2082
+ throw new Error(`No provider found for scope: ${scope}`);
2078
2083
  }
2079
- return definition;
2084
+ return new ScopedSettingService(this, provider, this.onChanged, this.scopedSettingsCache.get(scope));
2080
2085
  }
2081
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSearchDefinitionProviderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2082
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSearchDefinitionProviderService, providedIn: 'root' }); }
2086
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSettingValueProviderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2087
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSettingValueProviderService, providedIn: 'root' }); }
2083
2088
  }
2084
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSearchDefinitionProviderService, decorators: [{
2089
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSettingValueProviderService, decorators: [{
2085
2090
  type: Injectable,
2086
- args: [{ providedIn: 'root' }]
2087
- }] });
2088
-
2089
- // Injection token for setting providers
2090
- const AXP_SEARCH_PROVIDER = new InjectionToken('AXP_SEARCH_PROVIDER');
2091
- class AXPSearchService {
2092
- constructor() {
2093
- this.providers = inject(AXP_SEARCH_PROVIDER, { optional: true });
2094
- this.definitionService = inject(AXPSearchDefinitionProviderService);
2091
+ args: [{
2092
+ providedIn: 'root',
2093
+ }]
2094
+ }], ctorParameters: () => [] });
2095
+ class ScopedSettingService {
2096
+ constructor(parent, provider, onChanged, scopeCache) {
2097
+ this.parent = parent;
2098
+ this.provider = provider;
2099
+ this.onChanged = onChanged;
2100
+ this.scopeCache = scopeCache;
2095
2101
  }
2096
- async search(text) {
2097
- //TODO better handle this
2098
- if (this.definitionService.getList().length == 0) {
2099
- await this.definitionService.getListAsync();
2100
- }
2101
- if (!this.providers || (this.providers?.length || 0) === 0) {
2102
- throw new Error('No search providers available'); // No providers available
2103
- }
2104
- const mergeData = [];
2105
- const promises = this.providers.map((provider) => provider.search(text));
2106
- const results = await Promise.all(promises);
2107
- for (const resultArray of results) {
2108
- for (const result of resultArray) {
2109
- try {
2110
- const definition = this.definitionService.findDefinition(result.name);
2111
- mergeData.push({
2112
- definitionName: definition.name,
2113
- definitionTitle: definition.title,
2114
- name: result.name,
2115
- title: result.title,
2116
- icon: result.icon ?? definition.icon,
2117
- data: result.data,
2118
- actions: definition.actions,
2119
- description: result.description,
2120
- parent: result.parent,
2121
- });
2122
- }
2123
- catch (e) {
2124
- console.error(e);
2125
- }
2126
- }
2102
+ async get(key) {
2103
+ const settings = await this.provider.load();
2104
+ const setting = settings.find((s) => s.key === key);
2105
+ return setting ? cloneDeep(setting.value) : undefined;
2106
+ }
2107
+ async all() {
2108
+ const settings = await this.provider.load();
2109
+ return Object.fromEntries(settings.map((s) => [s.key, cloneDeep(s.value)]));
2110
+ }
2111
+ async defaultValues() {
2112
+ return this.parent.defaultValues(this.provider.scope);
2113
+ }
2114
+ async set(keyOrValues, value) {
2115
+ if (typeof keyOrValues === 'string') {
2116
+ // Single key-value pair
2117
+ await this.provider.set(keyOrValues, value);
2118
+ this.scopeCache.set(keyOrValues, value); // Sync the cache
2119
+ this.onChanged.next({
2120
+ scope: this.provider.scope,
2121
+ keys: [keyOrValues],
2122
+ values: { [keyOrValues]: value },
2123
+ entries: [{ key: keyOrValues, value }],
2124
+ });
2127
2125
  }
2128
- // Group data
2129
- const groupedData = [];
2130
- const groupMap = {};
2131
- // Create groups
2132
- for (const item of mergeData) {
2133
- const groupName = item.definitionName; // Change this to the property you want to group by
2134
- if (!groupMap[groupName]) {
2135
- groupMap[groupName] = {
2136
- name: groupName,
2137
- title: item.definitionTitle, // You can adjust the title logic if needed
2138
- children: [],
2139
- };
2140
- groupedData.push(groupMap[groupName]);
2141
- }
2142
- groupMap[groupName].children.push(omit(item, ['definitionName', 'definitionTitle']));
2126
+ else {
2127
+ // Multiple key-value pairs
2128
+ await this.provider.set(keyOrValues);
2129
+ Object.entries(keyOrValues).forEach(([key, val]) => this.scopeCache.set(key, val)); // Sync the cache
2130
+ const entries = Object.entries(keyOrValues).map(([key, val]) => ({ key, value: val }));
2131
+ this.onChanged.next({
2132
+ scope: this.provider.scope,
2133
+ keys: Object.keys(keyOrValues),
2134
+ values: keyOrValues,
2135
+ entries,
2136
+ });
2143
2137
  }
2144
- return groupedData;
2145
2138
  }
2146
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSearchService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2147
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSearchService, providedIn: 'root' }); }
2148
2139
  }
2149
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPSearchService, decorators: [{
2150
- type: Injectable,
2151
- args: [{ providedIn: 'root' }]
2152
- }] });
2153
2140
 
2154
2141
  class AXPSettingSearchDefinitionProvider {
2155
2142
  async provide(context) {
@@ -2273,6 +2260,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImpor
2273
2260
  type: Injectable
2274
2261
  }] });
2275
2262
 
2263
+ class AXPWorkflowRouterNavigateAction extends AXPWorkflowAction {
2264
+ constructor() {
2265
+ super(...arguments);
2266
+ this.router = inject(Router);
2267
+ }
2268
+ async execute(context) {
2269
+ const command = context.getVariable('command');
2270
+ if (command.options.path.toLowerCase().startsWith('http') || command.options?.extras?.target == 'blank') {
2271
+ window.open(command.options.path, '_blank');
2272
+ }
2273
+ else {
2274
+ this.router.navigate([command.options.path], command.options.extras);
2275
+ }
2276
+ }
2277
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPWorkflowRouterNavigateAction, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
2278
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPWorkflowRouterNavigateAction }); }
2279
+ }
2280
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPWorkflowRouterNavigateAction, decorators: [{
2281
+ type: Injectable
2282
+ }] });
2283
+ const AXPNavigateWorkflow = {
2284
+ startStepId: 'start',
2285
+ steps: {
2286
+ 'start': {
2287
+ action: 'navigate-router',
2288
+ },
2289
+ },
2290
+ };
2291
+
2276
2292
  class AXMWorkflowErrorHandler {
2277
2293
  constructor() {
2278
2294
  this.dialog = inject(AXDialogService);
@@ -2333,17 +2349,6 @@ class AXPCommonModule {
2333
2349
  instances.forEach((f) => {
2334
2350
  f();
2335
2351
  });
2336
- // appInitService.registerTask({
2337
- // name: 'Modules',
2338
- // statusText: 'Initializing Modules ...',
2339
- // run: () =>
2340
- // new Promise<void>((resolve) => {
2341
- // setTimeout(() => {
2342
- // resolve();
2343
- // }, 250);
2344
- // }),
2345
- // });
2346
- //
2347
2352
  appInitService.registerTask({
2348
2353
  name: 'Settings',
2349
2354
  statusText: 'Loading Settings ...',
@@ -2362,7 +2367,7 @@ class AXPCommonModule {
2362
2367
  });
2363
2368
  }
2364
2369
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPCommonModule, deps: [{ token: 'AXPCommonModuleFactory' }, { token: AXPAppStartUpService }, { token: AXPSettingValueProviderService }, { token: AXPDataSeederService }], target: i0.ɵɵFactoryTarget.NgModule }); }
2365
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.3", ngImport: i0, type: AXPCommonModule, imports: [i1$1.EffectsFeatureModule, i5.AXPWorkflowModule, AXPopupModule,
2370
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.3", ngImport: i0, type: AXPCommonModule, imports: [i4.AXPWorkflowModule, AXPopupModule,
2366
2371
  AXDateTimeModule,
2367
2372
  AXToastModule], exports: [RouterModule] }); }
2368
2373
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPCommonModule, providers: [
@@ -2399,13 +2404,15 @@ class AXPCommonModule {
2399
2404
  useClass: AXPMenuSearchDefinitionProvider,
2400
2405
  multi: true,
2401
2406
  },
2402
- ], imports: [EffectsModule.forFeature([AXPCommonEffects]),
2403
- AXPWorkflowModule.forChild({
2407
+ ], imports: [AXPWorkflowModule.forChild({
2404
2408
  actions: {
2405
- navigate: AXPDialogConfirmAction,
2409
+ 'navigate-router': AXPWorkflowRouterNavigateAction,
2406
2410
  'show-prompt-dialog': AXPDialogConfirmAction,
2407
2411
  'show-toast': AXPToastAction,
2408
2412
  },
2413
+ workflows: {
2414
+ 'navigate': AXPNavigateWorkflow
2415
+ }
2409
2416
  }),
2410
2417
  AXPopupModule,
2411
2418
  AXDateTimeModule,
@@ -2415,13 +2422,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImpor
2415
2422
  type: NgModule,
2416
2423
  args: [{
2417
2424
  imports: [
2418
- EffectsModule.forFeature([AXPCommonEffects]),
2419
2425
  AXPWorkflowModule.forChild({
2420
2426
  actions: {
2421
- navigate: AXPDialogConfirmAction,
2427
+ 'navigate-router': AXPWorkflowRouterNavigateAction,
2422
2428
  'show-prompt-dialog': AXPDialogConfirmAction,
2423
2429
  'show-toast': AXPToastAction,
2424
2430
  },
2431
+ workflows: {
2432
+ 'navigate': AXPNavigateWorkflow
2433
+ }
2425
2434
  }),
2426
2435
  AXPopupModule,
2427
2436
  AXDateTimeModule,
@@ -2528,9 +2537,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImpor
2528
2537
  }]
2529
2538
  }] });
2530
2539
 
2540
+ const AXPSignOutAction = createAction('[SignOut] Action');
2541
+ const AXPSignInAction = createAction('[SignIn] Action');
2542
+
2531
2543
  /**
2532
2544
  * Generated bundle index. Do not edit.
2533
2545
  */
2534
2546
 
2535
- export { ALL_DEFAULT_OPERATORS, AXMEntityCrudService, AXMEntityCrudServiceImpl, AXMWorkflowErrorHandler, AXPAppStartUpProvider, AXPAppStartUpService, AXPClipBoardService, AXPCommonEffects, AXPCommonModule, AXPComponentLogoConfig, AXPComponentSlotDirective, AXPComponentSlotLoaderService, AXPComponentSlotModule, AXPComponentSlotRegistryService, AXPCustomOperatorService, AXPCustomOperatorServiceImpl, AXPDataGenerator, AXPDataProvider, AXPDataSeederService, AXPDexieEntityStorageService, AXPDialogConfirmAction, AXPEntityCommandScope, AXPEntityDataProvider, AXPEntityDataProviderImpl, AXPEntityQueryType, AXPEntityStorageService, AXPErrorHandlerRegistryService, AXPFileStorageService, AXPFileStorageStatus, AXPFilterOperatorMiddlewareService, AXPFilterOperatorMiddlewareServiceImpl, AXPFiltersProviderService, AXPFontIconLogoConfig, AXPFooterTextSlotComponent, AXPGlobalErrorHandler, AXPGridLayoutDirective, AXPImageUrlLogoConfig, AXPLogoComponent, AXPMenuProviderService, AXPMenuSearchDefinitionProvider, AXPMenuSearchProvider, AXPMenuService, AXPNavBarSlotComponent, AXPNavigateAction, AXPPdfPageSize, AXPPdfService, AXPPlatformDefaultConfigs, AXPRedirectEvent, AXPRefreshEvent, AXPRelationshipCardinality, AXPRelationshipKind, AXPSearchDefinitionActionBuilder, AXPSearchDefinitionBuilder, AXPSearchDefinitionProviderContext, AXPSearchDefinitionProviderService, AXPSearchService, AXPSettingDefaultValueProvider, AXPSettingDefinitionGroupBuilder, AXPSettingDefinitionProviderContext, AXPSettingDefinitionProviderService, AXPSettingDefinitionSectionBuilder, AXPSettingScope, AXPSettingValueProviderService, AXPSignInAction, AXPSignOutAction, AXPStickyDirective, AXPTextLogoConfig, AXPToastAction, AXPWorkflowNavigateAction, AXP_DATA_SEEDER_TOKEN, AXP_MENU_PROVIDER, AXP_PLATFORM_CONFIG_TOKEN, AXP_ROOT_CONFIG_TOKEN, AXP_SEARCH_DEFINITION_PROVIDER, AXP_SEARCH_PROVIDER, AXP_SETTING_DEFINITION_PROVIDER, AXP_SETTING_VALUE_PROVIDER, BETWEEN_OPER, BOOLEAN_OPERATORS, CONTAINS_OPER, DATE_OPERATORS, ENDS_WITH_OPER, ENVIRONMENT, EQ_OPER, GTE_OPER, GT_OPER, IS_EMPTY_OPER, IS_NOT_EMPTY_OPER, LTE_OPER, LT_OPER, NOT_CONTAINS_OPER, NOT_EQ_OPER, NUMBER_OPERATORS, STARTS_WITH_OPER, STRING_OPERATORS, configPlatform, getEntityInfo, resolveActionLook };
2547
+ export { ALL_DEFAULT_OPERATORS, AXMEntityCrudService, AXMEntityCrudServiceImpl, AXMWorkflowErrorHandler, AXPAppStartUpProvider, AXPAppStartUpService, AXPClipBoardService, AXPCommandSearchProvider, AXPCommonModule, AXPComponentLogoConfig, AXPComponentSlotDirective, AXPComponentSlotLoaderService, AXPComponentSlotModule, AXPComponentSlotRegistryService, AXPCustomOperatorService, AXPCustomOperatorServiceImpl, AXPDataGenerator, AXPDataProvider, AXPDataSeederService, AXPDexieEntityStorageService, AXPDialogConfirmAction, AXPEntityCommandScope, AXPEntityDataProvider, AXPEntityDataProviderImpl, AXPEntityQueryType, AXPEntityStorageService, AXPErrorHandlerRegistryService, AXPFileStorageService, AXPFileStorageStatus, AXPFilterOperatorMiddlewareService, AXPFilterOperatorMiddlewareServiceImpl, AXPFiltersProviderService, AXPFontIconLogoConfig, AXPFooterTextSlotComponent, AXPGlobalErrorHandler, AXPGridLayoutDirective, AXPImageUrlLogoConfig, AXPLogoComponent, AXPMenuProviderService, AXPMenuSearchDefinitionProvider, AXPMenuSearchProvider, AXPMenuService, AXPNavBarSlotComponent, AXPNavigateWorkflow, AXPPdfPageSize, AXPPdfService, AXPPlatformDefaultConfigs, AXPRedirectEvent, AXPRefreshEvent, AXPRelationshipCardinality, AXPRelationshipKind, AXPSearchDefinitionActionBuilder, AXPSearchDefinitionBuilder, AXPSearchDefinitionProviderContext, AXPSearchDefinitionProviderService, AXPSearchService, AXPSettingDefaultValueProvider, AXPSettingDefinitionGroupBuilder, AXPSettingDefinitionProviderContext, AXPSettingDefinitionProviderService, AXPSettingDefinitionSectionBuilder, AXPSettingScope, AXPSettingValueProviderService, AXPSignInAction, AXPSignOutAction, AXPStickyDirective, AXPTextLogoConfig, AXPToastAction, AXPWorkflowNavigateAction, AXPWorkflowRouterNavigateAction, AXP_DATA_SEEDER_TOKEN, AXP_MENU_PROVIDER, AXP_PLATFORM_CONFIG_TOKEN, AXP_ROOT_CONFIG_TOKEN, AXP_SEARCH_DEFINITION_PROVIDER, AXP_SEARCH_PROVIDER, AXP_SETTING_DEFINITION_PROVIDER, AXP_SETTING_VALUE_PROVIDER, BETWEEN_OPER, BOOLEAN_OPERATORS, CONTAINS_OPER, DATE_OPERATORS, ENDS_WITH_OPER, ENVIRONMENT, EQ_OPER, GTE_OPER, GT_OPER, IS_EMPTY_OPER, IS_NOT_EMPTY_OPER, LTE_OPER, LT_OPER, NOT_CONTAINS_OPER, NOT_EQ_OPER, NUMBER_OPERATORS, STARTS_WITH_OPER, STRING_OPERATORS, configPlatform, getEntityInfo, resolveActionLook };
2536
2548
  //# sourceMappingURL=acorex-platform-common.mjs.map