@acorex/modules 20.7.7 → 20.7.9

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 (68) hide show
  1. package/auth/index.d.ts +16 -2
  2. package/document-management/index.d.ts +33 -10
  3. package/fesm2022/acorex-modules-application-management.mjs +16 -1
  4. package/fesm2022/acorex-modules-application-management.mjs.map +1 -1
  5. package/fesm2022/{acorex-modules-auth-acorex-modules-auth-CyabqFR8.mjs → acorex-modules-auth-acorex-modules-auth-Dg9sg98-.mjs} +32 -13
  6. package/fesm2022/acorex-modules-auth-acorex-modules-auth-Dg9sg98-.mjs.map +1 -0
  7. package/fesm2022/{acorex-modules-auth-app-chooser.component-CizgE3Bb.mjs → acorex-modules-auth-app-chooser.component-Dr8EZ7ZX.mjs} +2 -2
  8. package/fesm2022/{acorex-modules-auth-app-chooser.component-CizgE3Bb.mjs.map → acorex-modules-auth-app-chooser.component-Dr8EZ7ZX.mjs.map} +1 -1
  9. package/fesm2022/{acorex-modules-auth-login.module-DRVqUojm.mjs → acorex-modules-auth-login.module-C7Rt6tLk.mjs} +6 -4
  10. package/fesm2022/acorex-modules-auth-login.module-C7Rt6tLk.mjs.map +1 -0
  11. package/fesm2022/{acorex-modules-auth-master.layout-C1zCbrQh.mjs → acorex-modules-auth-master.layout-CgD5kk65.mjs} +2 -2
  12. package/fesm2022/{acorex-modules-auth-master.layout-C1zCbrQh.mjs.map → acorex-modules-auth-master.layout-CgD5kk65.mjs.map} +1 -1
  13. package/fesm2022/{acorex-modules-auth-oauth-callback.component-DmNV6zL4.mjs → acorex-modules-auth-oauth-callback.component-CuGIGBVO.mjs} +2 -2
  14. package/fesm2022/{acorex-modules-auth-oauth-callback.component-DmNV6zL4.mjs.map → acorex-modules-auth-oauth-callback.component-CuGIGBVO.mjs.map} +1 -1
  15. package/fesm2022/{acorex-modules-auth-password.component-BmTCzp3t.mjs → acorex-modules-auth-password.component-C6TCAUm4.mjs} +2 -2
  16. package/fesm2022/{acorex-modules-auth-password.component-BmTCzp3t.mjs.map → acorex-modules-auth-password.component-C6TCAUm4.mjs.map} +1 -1
  17. package/fesm2022/{acorex-modules-auth-password.component-DSysOOu9.mjs → acorex-modules-auth-password.component-DmohsIxt.mjs} +2 -2
  18. package/fesm2022/{acorex-modules-auth-password.component-DSysOOu9.mjs.map → acorex-modules-auth-password.component-DmohsIxt.mjs.map} +1 -1
  19. package/fesm2022/{acorex-modules-auth-routes-oYfOJjLO.mjs → acorex-modules-auth-routes-C3162bwa.mjs} +2 -2
  20. package/fesm2022/{acorex-modules-auth-routes-oYfOJjLO.mjs.map → acorex-modules-auth-routes-C3162bwa.mjs.map} +1 -1
  21. package/fesm2022/{acorex-modules-auth-tenant-chooser.component-DqrZiwp6.mjs → acorex-modules-auth-tenant-chooser.component-Ce-n3WC9.mjs} +2 -2
  22. package/fesm2022/{acorex-modules-auth-tenant-chooser.component-DqrZiwp6.mjs.map → acorex-modules-auth-tenant-chooser.component-Ce-n3WC9.mjs.map} +1 -1
  23. package/fesm2022/{acorex-modules-auth-two-factor.module-Cc3x-76V.mjs → acorex-modules-auth-two-factor.module-B2nPzX-3.mjs} +2 -2
  24. package/fesm2022/{acorex-modules-auth-two-factor.module-Cc3x-76V.mjs.map → acorex-modules-auth-two-factor.module-B2nPzX-3.mjs.map} +1 -1
  25. package/fesm2022/{acorex-modules-auth-user-sessions.component-CiGEYKgb.mjs → acorex-modules-auth-user-sessions.component-wVKJ2KIm.mjs} +2 -2
  26. package/fesm2022/{acorex-modules-auth-user-sessions.component-CiGEYKgb.mjs.map → acorex-modules-auth-user-sessions.component-wVKJ2KIm.mjs.map} +1 -1
  27. package/fesm2022/acorex-modules-auth.mjs +1 -1
  28. package/fesm2022/acorex-modules-content-management.mjs +3 -3
  29. package/fesm2022/acorex-modules-content-management.mjs.map +1 -1
  30. package/fesm2022/acorex-modules-dashboard-management.mjs +24 -23
  31. package/fesm2022/acorex-modules-dashboard-management.mjs.map +1 -1
  32. package/fesm2022/acorex-modules-data-management.mjs +68 -61
  33. package/fesm2022/acorex-modules-data-management.mjs.map +1 -1
  34. package/fesm2022/{acorex-modules-document-management-drive-choose.component-CJRrn2XH.mjs → acorex-modules-document-management-drive-choose.component-ovwhHP2n.mjs} +4 -4
  35. package/fesm2022/{acorex-modules-document-management-drive-choose.component-CJRrn2XH.mjs.map → acorex-modules-document-management-drive-choose.component-ovwhHP2n.mjs.map} +1 -1
  36. package/fesm2022/acorex-modules-document-management.mjs +363 -231
  37. package/fesm2022/acorex-modules-document-management.mjs.map +1 -1
  38. package/fesm2022/{acorex-modules-help-desk-acorex-modules-help-desk-DGgHWrL0.mjs → acorex-modules-help-desk-acorex-modules-help-desk-CydmGF5Q.mjs} +8 -4
  39. package/fesm2022/{acorex-modules-help-desk-acorex-modules-help-desk-DGgHWrL0.mjs.map → acorex-modules-help-desk-acorex-modules-help-desk-CydmGF5Q.mjs.map} +1 -1
  40. package/fesm2022/{acorex-modules-help-desk-capture-screen.component-CAknGKEK.mjs → acorex-modules-help-desk-capture-screen.component-Bsq1FJId.mjs} +2 -2
  41. package/fesm2022/{acorex-modules-help-desk-capture-screen.component-CAknGKEK.mjs.map → acorex-modules-help-desk-capture-screen.component-Bsq1FJId.mjs.map} +1 -1
  42. package/fesm2022/acorex-modules-help-desk.mjs +1 -1
  43. package/fesm2022/acorex-modules-human-capital-management.mjs +41 -26
  44. package/fesm2022/acorex-modules-human-capital-management.mjs.map +1 -1
  45. package/fesm2022/{acorex-modules-organization-management-org-chart.page-C85uluWf.mjs → acorex-modules-organization-management-org-chart.page-Ca_aJDbu.mjs} +19 -13
  46. package/fesm2022/acorex-modules-organization-management-org-chart.page-Ca_aJDbu.mjs.map +1 -0
  47. package/fesm2022/acorex-modules-organization-management.mjs +2 -2
  48. package/fesm2022/{acorex-modules-person-management-person.entity-BtaGNj8n.mjs → acorex-modules-person-management-person.entity-CaEVw1mL.mjs} +2 -2
  49. package/fesm2022/acorex-modules-person-management-person.entity-CaEVw1mL.mjs.map +1 -0
  50. package/fesm2022/acorex-modules-person-management.mjs +1 -1
  51. package/fesm2022/{acorex-modules-platform-management-acorex-modules-platform-management-DEx13GSy.mjs → acorex-modules-platform-management-acorex-modules-platform-management-DVkP3JKC.mjs} +1188 -341
  52. package/fesm2022/acorex-modules-platform-management-acorex-modules-platform-management-DVkP3JKC.mjs.map +1 -0
  53. package/fesm2022/acorex-modules-platform-management-menu-list.component-C_mdsuRc.mjs +519 -0
  54. package/fesm2022/acorex-modules-platform-management-menu-list.component-C_mdsuRc.mjs.map +1 -0
  55. package/fesm2022/acorex-modules-platform-management.mjs +1 -1
  56. package/fesm2022/acorex-modules-report-management.mjs +27 -6
  57. package/fesm2022/acorex-modules-report-management.mjs.map +1 -1
  58. package/fesm2022/acorex-modules-workflow-management.mjs +15 -9
  59. package/fesm2022/acorex-modules-workflow-management.mjs.map +1 -1
  60. package/package.json +2 -2
  61. package/platform-management/index.d.ts +12 -1
  62. package/fesm2022/acorex-modules-auth-acorex-modules-auth-CyabqFR8.mjs.map +0 -1
  63. package/fesm2022/acorex-modules-auth-login.module-DRVqUojm.mjs.map +0 -1
  64. package/fesm2022/acorex-modules-organization-management-org-chart.page-C85uluWf.mjs.map +0 -1
  65. package/fesm2022/acorex-modules-person-management-person.entity-BtaGNj8n.mjs.map +0 -1
  66. package/fesm2022/acorex-modules-platform-management-acorex-modules-platform-management-DEx13GSy.mjs.map +0 -1
  67. package/fesm2022/acorex-modules-platform-management-menu-list.component-DLg61Nf8.mjs +0 -853
  68. package/fesm2022/acorex-modules-platform-management-menu-list.component-DLg61Nf8.mjs.map +0 -1
@@ -1,65 +1,1098 @@
1
- import { AXPTokenDefinitionService, AXP_TOKEN_DEFINITION_PROVIDER, AXPSettingsService, createAllQueryView, AXPEntityCommandScope, AXP_MENU_MIDDLEWARE, AXP_MENU_PROVIDER } from '@acorex/platform/common';
2
- import { AXPExpressionEvaluatorService, AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER, AXPPlatformScope, AXP_MODULE_MANIFEST_PROVIDER, AXP_FEATURE_DEFINITION_PROVIDER } from '@acorex/platform/core';
3
- import { AXMEntityCrudServiceImpl, AXPEntityService, entityMasterCrudActions, entityMasterRecordActions, AXP_ENTITY_DEFINITION_LOADER } from '@acorex/platform/layout/entity';
4
1
  import { AXPAuthGuard, AXP_PERMISSION_DEFINITION_PROVIDER } from '@acorex/platform/auth';
2
+ import { AXPSettingsService, AXPMenuProviderService, AXPTokenDefinitionService, AXP_TOKEN_DEFINITION_PROVIDER, createAllQueryView, AXPEntityCommandScope, AXP_MENU_MIDDLEWARE, AXP_MENU_PROVIDER } from '@acorex/platform/common';
3
+ import { AXPPlatformScope, AXPExpressionEvaluatorService, AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER, AXP_MODULE_MANIFEST_PROVIDER, AXP_FEATURE_DEFINITION_PROVIDER } from '@acorex/platform/core';
4
+ import { AXMEntityCrudServiceImpl, AXPEntityService, entityMasterCrudActions, entityMasterRecordActions, AXP_ENTITY_DEFINITION_LOADER } from '@acorex/platform/layout/entity';
5
5
  import { AXPRootLayoutComponent } from '@acorex/platform/themes/default';
6
6
  import * as i0 from '@angular/core';
7
- import { Injectable, inject, Injector, NgModule } from '@angular/core';
7
+ import { inject, Injector, Injectable, viewChild, signal, computed, ViewEncapsulation, Component, NgModule } from '@angular/core';
8
8
  import { ROUTES } from '@angular/router';
9
+ import { AXPMenuCustomizerService, AXPMenuCustomizerComponent, AXPThemeLayoutBlockComponent, AXP_MENU_CUSTOMIZER_SERVICE } from '@acorex/platform/layout/components';
10
+ import * as i1 from '@acorex/platform/workflow';
11
+ import { AXPWorkflowAction, AXPWorkflowModule } from '@acorex/platform/workflow';
12
+ import { cloneDeep } from 'lodash-es';
13
+ import { AXPopupService } from '@acorex/components/popup';
14
+ import { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';
15
+ import { AXPPopupLayoutBaseComponent, AXPPopupLayoutComponent, AXPPopupLayoutBase } from '@acorex/platform/layout/views';
16
+ import { CommonModule } from '@angular/common';
9
17
  import { provideCommandSetups } from '@acorex/platform/runtime';
10
18
  import { AXDialogService } from '@acorex/components/dialog';
11
- import { AXTranslationService } from '@acorex/core/translation';
12
19
  import { SwUpdate } from '@angular/service-worker';
13
20
  import { AXPCommonMenuKeys, AXPWidgetsList } from '@acorex/modules/common';
14
21
  import { AXPWidgetsCatalog } from '@acorex/platform/layout/widget-core';
15
22
 
16
- const config = {
17
- i18n: 'platform-management',
18
- };
19
- const RootConfig = {
20
- config,
21
- module: {
22
- route: 'platform-management',
23
- name: 'PlatformManagement',
24
- title: `@${config.i18n}:module.title`,
25
- icon: 'fa-light fa-cogs',
26
- },
27
- entities: {
28
- localizationManagement: {
29
- name: 'Localization Management',
30
- title: `@${config.i18n}:localization-management.entities.localization-management.title`,
31
- icon: 'fa-light fa-globe',
23
+ const config = {
24
+ i18n: 'platform-management',
25
+ };
26
+ const RootConfig = {
27
+ config,
28
+ module: {
29
+ route: 'platform-management',
30
+ name: 'PlatformManagement',
31
+ title: `@${config.i18n}:module.title`,
32
+ icon: 'fa-light fa-cogs',
33
+ },
34
+ entities: {
35
+ localizationManagement: {
36
+ name: 'Localization Management',
37
+ title: `@${config.i18n}:localization-management.entities.localization-management.title`,
38
+ icon: 'fa-light fa-globe',
39
+ },
40
+ token: {
41
+ name: 'Tokens',
42
+ title: `@${config.i18n}:tokens.entities.token.title`,
43
+ icon: 'fa-light fa-object-exclude',
44
+ },
45
+ },
46
+ };
47
+
48
+ class AXMEntityLoader {
49
+ constructor() {
50
+ this.injector = inject(Injector);
51
+ }
52
+ preload() {
53
+ const module = RootConfig.module.name;
54
+ return Array.from(Object.values(RootConfig.entities)).map((entity) => ({
55
+ module: module,
56
+ entity: entity.name,
57
+ }));
58
+ }
59
+ async get(moduleName, entityName) {
60
+ if (moduleName == RootConfig.module.name) {
61
+ return new Promise(async (resolve) => {
62
+ switch (entityName) {
63
+ case RootConfig.entities.token.name: {
64
+ const entity = (await Promise.resolve().then(function () { return index; })).tokenEntityFactory;
65
+ resolve(entity(this.injector));
66
+ break;
67
+ }
68
+ default:
69
+ resolve(null);
70
+ }
71
+ });
72
+ }
73
+ return null;
74
+ }
75
+ async list() {
76
+ const m = RootConfig.module.name;
77
+ return Promise.resolve(Object.values(RootConfig.entities).map((e) => ({ name: e.name, module: m })));
78
+ }
79
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXMEntityLoader, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
80
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXMEntityLoader }); }
81
+ }
82
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXMEntityLoader, decorators: [{
83
+ type: Injectable
84
+ }] });
85
+
86
+ const AXPPlatformManagementFeatureKeys = {
87
+ MenuCustomization: 'PlatformManagement:Feature:menu-customization',
88
+ AutoCheckUpdates: 'PlatformManagement:Feature:auto-check-updates',
89
+ MaxTokens: 'PlatformManagement:Feature:max-tokens',
90
+ };
91
+
92
+ //#region ---- Imports ----
93
+ //#endregion
94
+ //#region ---- Feature Definition Provider ----
95
+ /**
96
+ * Platform Management Feature Definition Provider.
97
+ * Provides feature definitions for the Platform Management module.
98
+ */
99
+ class AXPPlatformManagementFeatureDefinitionProvider {
100
+ async provide(context) {
101
+ context.addFeature(AXPPlatformManagementFeatureKeys.MenuCustomization, {
102
+ title: '@platform-management:features.menu-customization.title',
103
+ description: '@platform-management:features.menu-customization.description',
104
+ defaultValue: true,
105
+ type: 'boolean',
106
+ });
107
+ context.addFeature(AXPPlatformManagementFeatureKeys.AutoCheckUpdates, {
108
+ title: '@platform-management:features.auto-check-updates.title',
109
+ description: '@platform-management:features.auto-check-updates.description',
110
+ defaultValue: true,
111
+ type: 'boolean',
112
+ });
113
+ context.addFeature(AXPPlatformManagementFeatureKeys.MaxTokens, {
114
+ title: '@platform-management:features.max-tokens.title',
115
+ description: '@platform-management:features.max-tokens.description',
116
+ defaultValue: 100,
117
+ type: 'number',
118
+ interface: {
119
+ type: 'number-editor',
120
+ options: {
121
+ min: 1,
122
+ max: 1000,
123
+ step: 1,
124
+ },
125
+ },
126
+ });
127
+ }
128
+ }
129
+ //#endregion
130
+
131
+ //#region ---- Menu Customization Constants ----
132
+ /**
133
+ * Setting key for menu customizations
134
+ */
135
+ const AXP_MENU_CUSTOMIZATION_KEY = 'axp.platform-management.menu-customization';
136
+ /**
137
+ * Current version of menu customization schema
138
+ */
139
+ const AXP_MENU_CUSTOMIZATION_VERSION = '1.0.0';
140
+ /**
141
+ * Default menu customization
142
+ */
143
+ const AXP_MENU_CUSTOMIZATION_DEFAULT = {
144
+ version: AXP_MENU_CUSTOMIZATION_VERSION,
145
+ overrides: {},
146
+ customItems: [],
147
+ };
148
+ /**
149
+ * Menu management feature configuration
150
+ */
151
+ const MenuManagementConfig = {
152
+ route: 'menus',
153
+ title: `@${RootConfig.config.i18n}:menu-management.components.menu-list.title`,
154
+ icon: 'fa-light fa-bars',
155
+ };
156
+ //#endregion
157
+
158
+ //#region ---- Custom Menu Middleware ----
159
+ /**
160
+ * Middleware that applies menu customizations using the enhanced context API
161
+ * Applies user/tenant customizations from settings with priority support
162
+ */
163
+ class AXPCustomMenuMiddleware {
164
+ constructor() {
165
+ //#region ---- Middleware Properties ----
166
+ this.name = 'menu-customization';
167
+ this.priority = 100; // High priority to apply customizations early
168
+ //#endregion
169
+ //#region ---- Dependencies ----
170
+ this.settingsService = inject(AXPSettingsService);
171
+ //#endregion
172
+ }
173
+ //#endregion
174
+ //#region ---- Middleware Implementation ----
175
+ async process(context) {
176
+ try {
177
+ // Load menu customization from settings
178
+ const customization = await this.loadCustomization();
179
+ // Apply overrides to existing menu items using context API
180
+ this.applyOverrides(context, customization);
181
+ // Add custom menu items
182
+ this.addCustomItems(context, customization);
183
+ // Re-sort after applying priority overrides
184
+ context.sort();
185
+ }
186
+ catch (error) {
187
+ console.error('Error applying menu customizations:', error);
188
+ }
189
+ }
190
+ //#endregion
191
+ //#region ---- Private Methods ----
192
+ /**
193
+ * Load menu customization from settings
194
+ * Merges Tenant and User scope customizations (User overrides Tenant)
195
+ */
196
+ async loadCustomization() {
197
+ try {
198
+ // Load both scopes
199
+ const tenantSettings = this.settingsService.scope(AXPPlatformScope.Tenant);
200
+ const userSettings = this.settingsService.scope(AXPPlatformScope.User);
201
+ const tenantCustomization = await tenantSettings.get(AXP_MENU_CUSTOMIZATION_KEY);
202
+ const userCustomization = await userSettings.get(AXP_MENU_CUSTOMIZATION_KEY);
203
+ // Merge customizations: Tenant as base, User overrides
204
+ const merged = {
205
+ version: userCustomization?.version || tenantCustomization?.version || AXP_MENU_CUSTOMIZATION_DEFAULT.version,
206
+ overrides: {
207
+ ...(tenantCustomization?.overrides || {}),
208
+ ...(userCustomization?.overrides || {}), // User overrides win
209
+ },
210
+ customItems: [...(tenantCustomization?.customItems || []), ...(userCustomization?.customItems || [])],
211
+ };
212
+ // Return merged result or default if both are empty
213
+ const hasCustomizations = Object.keys(merged.overrides).length > 0 || merged.customItems.length > 0;
214
+ return hasCustomizations ? merged : AXP_MENU_CUSTOMIZATION_DEFAULT;
215
+ }
216
+ catch (error) {
217
+ console.error('Failed to load menu customization:', error);
218
+ return AXP_MENU_CUSTOMIZATION_DEFAULT;
219
+ }
220
+ }
221
+ /**
222
+ * Apply overrides to existing menu items using enhanced context API
223
+ */
224
+ applyOverrides(context, customization) {
225
+ Object.entries(customization.overrides).forEach(([menuName, override]) => {
226
+ const finder = context.findByName(menuName);
227
+ if (!finder.exists()) {
228
+ return;
229
+ }
230
+ // Hide menu item
231
+ if (override.hidden) {
232
+ finder.remove();
233
+ return;
234
+ }
235
+ // Apply priority override
236
+ if (override.priority !== undefined) {
237
+ finder.setPriority(override.priority);
238
+ }
239
+ // Apply property overrides
240
+ if (override.properties) {
241
+ finder.update(override.properties);
242
+ }
243
+ // Move to different parent
244
+ if (override.parentName !== undefined) {
245
+ finder.moveTo(override.parentName);
246
+ }
247
+ });
248
+ }
249
+ /**
250
+ * Add custom menu items using context API
251
+ */
252
+ addCustomItems(context, customization) {
253
+ if (customization.customItems && customization.customItems.length > 0) {
254
+ context.add(...customization.customItems);
255
+ }
256
+ }
257
+ }
258
+ //#endregion
259
+
260
+ /**
261
+ * Builds a customization key from a scope key
262
+ * @param scopeKey The scope key (e.g., 'edition:123', 'tenant:456')
263
+ * @returns The full customization storage key
264
+ */
265
+ function buildCustomizationKey(scopeKey) {
266
+ return `${AXP_MENU_CUSTOMIZATION_KEY}.${scopeKey}`;
267
+ }
268
+ //#region ---- Menu Management Service ----
269
+ /**
270
+ * Constants for priority calculation
271
+ */
272
+ const PRIORITY_BASE_ROOT = 0;
273
+ const PRIORITY_BASE_NESTED = 1000;
274
+ const PRIORITY_STEP = 10;
275
+ class AXPMenuManagementService extends AXPMenuCustomizerService {
276
+ constructor() {
277
+ super(...arguments);
278
+ //#region ---- Dependencies ----
279
+ this.settingsService = inject(AXPSettingsService);
280
+ this.menuProviderService = inject(AXPMenuProviderService);
281
+ }
282
+ //#endregion
283
+ //#region ---- AXPMenuCustomizerService Interface Implementation ----
284
+ /**
285
+ * Interface implementation: Get menu tree for the given scope key
286
+ */
287
+ async getMenuTree(scopeKey) {
288
+ return this.getMenuTreeByKey(scopeKey);
289
+ }
290
+ /**
291
+ * Interface implementation: Sync tree changes
292
+ */
293
+ async syncTreeChanges(scopeKey, treeNodes) {
294
+ return this.syncTreeChangesByKey(scopeKey, treeNodes);
295
+ }
296
+ /**
297
+ * Interface implementation: Show menu item
298
+ */
299
+ async showMenuItem(scopeKey, menuName) {
300
+ return this.showMenuItemByKey(scopeKey, menuName);
301
+ }
302
+ /**
303
+ * Interface implementation: Hide menu item
304
+ */
305
+ async hideMenuItem(scopeKey, menuName) {
306
+ return this.hideMenuItemByKey(scopeKey, menuName);
307
+ }
308
+ /**
309
+ * Interface implementation: Add custom menu item
310
+ */
311
+ async addCustomMenuItem(scopeKey, menuItem, parentName) {
312
+ return this.addCustomMenuItemByKey(scopeKey, menuItem, parentName);
313
+ }
314
+ /**
315
+ * Interface implementation: Update custom menu item
316
+ */
317
+ async updateCustomMenuItem(scopeKey, menuName, menuItem) {
318
+ return this.updateCustomMenuItemByKey(scopeKey, menuName, menuItem);
319
+ }
320
+ /**
321
+ * Interface implementation: Update menu properties
322
+ */
323
+ async updateMenuProperties(scopeKey, menuName, properties) {
324
+ return this.updateMenuPropertiesByKey(scopeKey, menuName, properties);
325
+ }
326
+ /**
327
+ * Interface implementation: Delete custom menu item
328
+ */
329
+ async deleteCustomMenuItem(scopeKey, menuName) {
330
+ return this.deleteCustomMenuItemByKey(scopeKey, menuName);
331
+ }
332
+ /**
333
+ * Interface implementation: Reset customizations
334
+ */
335
+ async resetCustomizations(scopeKey) {
336
+ return this.resetCustomizationsByKey(scopeKey);
337
+ }
338
+ //#endregion
339
+ //#region ---- Scope-Based Public Methods ----
340
+ /**
341
+ * Get menu tree as AXTreeViewNode[] for ax-tree-view component (scope-based)
342
+ */
343
+ async getMenuTreeByScope(scope) {
344
+ // Get RAW menu items WITHOUT middleware (for management purposes)
345
+ const baseItems = await this.menuProviderService.rawItems();
346
+ // Load customizations for the given scope
347
+ const customization = await this.loadCustomization(scope);
348
+ // Merge custom items with base items
349
+ const allItems = [...baseItems, ...customization.customItems];
350
+ // Apply parent overrides to restructure items BEFORE building tree
351
+ const restructuredItems = this.applyParentOverrides(allItems, customization);
352
+ // Convert to tree nodes with metadata
353
+ return this.convertToTreeNodes(restructuredItems, customization);
354
+ }
355
+ /**
356
+ * Sync tree changes back to customization (scope-based)
357
+ * Called automatically when tree structure changes via drag-drop
358
+ */
359
+ async syncTreeChangesByScope(scope, treeNodes) {
360
+ const customization = await this.loadCustomization(scope);
361
+ // Extract and update priorities and parent relationships from tree structure
362
+ this.updateCustomizationFromTree(treeNodes, customization);
363
+ await this.saveCustomization(scope, customization);
364
+ }
365
+ /**
366
+ * Load menu customization for a specific scope
367
+ */
368
+ async loadCustomization(scope) {
369
+ try {
370
+ const scopedSettings = this.settingsService.scope(scope);
371
+ const saved = await scopedSettings.get(AXP_MENU_CUSTOMIZATION_KEY);
372
+ if (saved && saved.version) {
373
+ return saved;
374
+ }
375
+ return cloneDeep(AXP_MENU_CUSTOMIZATION_DEFAULT);
376
+ }
377
+ catch {
378
+ return cloneDeep(AXP_MENU_CUSTOMIZATION_DEFAULT);
379
+ }
380
+ }
381
+ /**
382
+ * Save menu customization for a specific scope
383
+ */
384
+ async saveCustomization(scope, customization) {
385
+ const scopedSettings = this.settingsService.scope(scope);
386
+ await scopedSettings.set(AXP_MENU_CUSTOMIZATION_KEY, customization);
387
+ // Clear menu cache to force reload
388
+ this.menuProviderService.clearCache();
389
+ }
390
+ /**
391
+ * Hide a menu item (scope-based)
392
+ */
393
+ async hideMenuItemByScope(scope, menuName) {
394
+ this.validateMenuName(menuName, 'hide');
395
+ const customization = await this.loadCustomization(scope);
396
+ this.ensureOverrideExists(customization, menuName);
397
+ customization.overrides[menuName].hidden = true;
398
+ await this.saveCustomization(scope, customization);
399
+ }
400
+ /**
401
+ * Show a menu item (scope-based)
402
+ */
403
+ async showMenuItemByScope(scope, menuName) {
404
+ this.validateMenuName(menuName, 'show');
405
+ const customization = await this.loadCustomization(scope);
406
+ if (customization.overrides[menuName]) {
407
+ delete customization.overrides[menuName].hidden;
408
+ this.cleanupEmptyOverride(customization, menuName);
409
+ }
410
+ await this.saveCustomization(scope, customization);
411
+ }
412
+ /**
413
+ * Update menu item priority (scope-based)
414
+ */
415
+ async updateMenuPriorityByScope(scope, menuName, priority) {
416
+ this.validateMenuName(menuName, 'update priority for');
417
+ const customization = await this.loadCustomization(scope);
418
+ this.ensureOverrideExists(customization, menuName);
419
+ customization.overrides[menuName].priority = priority;
420
+ await this.saveCustomization(scope, customization);
421
+ }
422
+ /**
423
+ * Update menu item properties (scope-based)
424
+ */
425
+ async updateMenuPropertiesByScope(scope, menuName, properties) {
426
+ this.validateMenuName(menuName, 'update properties for');
427
+ const customization = await this.loadCustomization(scope);
428
+ this.ensureOverrideExists(customization, menuName);
429
+ customization.overrides[menuName].properties = {
430
+ ...customization.overrides[menuName].properties,
431
+ ...properties,
432
+ };
433
+ await this.saveCustomization(scope, customization);
434
+ }
435
+ /**
436
+ * Add custom menu item (scope-based)
437
+ */
438
+ async addCustomMenuItemByScope(scope, menuItem, parent) {
439
+ const customization = await this.loadCustomization(scope);
440
+ // Generate unique name if not provided
441
+ if (!menuItem.name) {
442
+ menuItem.name = `custom-menu-${Date.now()}`;
443
+ }
444
+ customization.customItems.push(menuItem);
445
+ await this.saveCustomization(scope, customization);
446
+ }
447
+ /**
448
+ * Update custom menu item (scope-based)
449
+ */
450
+ async updateCustomMenuItemByScope(scope, menuName, menuItem) {
451
+ this.validateMenuName(menuName, 'update');
452
+ const customization = await this.loadCustomization(scope);
453
+ const index = customization.customItems.findIndex((item) => item.name === menuName);
454
+ if (index === -1) {
455
+ throw new Error(`Custom menu item '${menuName}' not found`);
456
+ }
457
+ customization.customItems[index] = menuItem;
458
+ await this.saveCustomization(scope, customization);
459
+ }
460
+ /**
461
+ * Delete custom menu item (scope-based)
462
+ */
463
+ async deleteCustomMenuItemByScope(scope, menuName) {
464
+ this.validateMenuName(menuName, 'delete');
465
+ const customization = await this.loadCustomization(scope);
466
+ const initialLength = customization.customItems.length;
467
+ customization.customItems = customization.customItems.filter((item) => item.name !== menuName);
468
+ if (customization.customItems.length === initialLength) {
469
+ throw new Error(`Custom menu item '${menuName}' not found`);
470
+ }
471
+ await this.saveCustomization(scope, customization);
472
+ }
473
+ /**
474
+ * Reset all customizations for a scope (scope-based)
475
+ */
476
+ async resetCustomizationsByScope(scope) {
477
+ await this.saveCustomization(scope, cloneDeep(AXP_MENU_CUSTOMIZATION_DEFAULT));
478
+ }
479
+ //#endregion
480
+ //#region ---- Key-Based Public Methods ----
481
+ /**
482
+ * Get menu tree using a generic scope key (e.g., 'edition:123', 'tenant:456')
483
+ */
484
+ async getMenuTreeByKey(scopeKey) {
485
+ // Get RAW menu items WITHOUT middleware (for management purposes)
486
+ const baseItems = await this.menuProviderService.rawItems();
487
+ // Load customizations for the given scope key
488
+ const customization = await this.loadCustomizationByKey(scopeKey);
489
+ // Merge custom items with base items
490
+ const allItems = [...baseItems, ...customization.customItems];
491
+ // Apply parent overrides to restructure items BEFORE building tree
492
+ const restructuredItems = this.applyParentOverrides(allItems, customization);
493
+ // Convert to tree nodes with metadata
494
+ return this.convertToTreeNodes(restructuredItems, customization);
495
+ }
496
+ /**
497
+ * Sync tree changes using a generic scope key
498
+ */
499
+ async syncTreeChangesByKey(scopeKey, treeNodes) {
500
+ const customization = await this.loadCustomizationByKey(scopeKey);
501
+ // Extract and update priorities and parent relationships from tree structure
502
+ this.updateCustomizationFromTree(treeNodes, customization);
503
+ await this.saveCustomizationByKey(scopeKey, customization);
504
+ }
505
+ /**
506
+ * Load menu customization using a generic scope key
507
+ */
508
+ async loadCustomizationByKey(scopeKey) {
509
+ try {
510
+ const storageKey = buildCustomizationKey(scopeKey);
511
+ const scopedSettings = this.settingsService.scope(AXPPlatformScope.Tenant);
512
+ const saved = await scopedSettings.get(storageKey);
513
+ if (saved && saved.version) {
514
+ return saved;
515
+ }
516
+ return cloneDeep(AXP_MENU_CUSTOMIZATION_DEFAULT);
517
+ }
518
+ catch {
519
+ return cloneDeep(AXP_MENU_CUSTOMIZATION_DEFAULT);
520
+ }
521
+ }
522
+ /**
523
+ * Save menu customization using a generic scope key
524
+ */
525
+ async saveCustomizationByKey(scopeKey, customization) {
526
+ const storageKey = buildCustomizationKey(scopeKey);
527
+ const scopedSettings = this.settingsService.scope(AXPPlatformScope.Tenant);
528
+ await scopedSettings.set(storageKey, customization);
529
+ // Clear menu cache to force reload
530
+ this.menuProviderService.clearCache();
531
+ }
532
+ /**
533
+ * Hide a menu item using a generic scope key
534
+ */
535
+ async hideMenuItemByKey(scopeKey, menuName) {
536
+ this.validateMenuName(menuName, 'hide');
537
+ const customization = await this.loadCustomizationByKey(scopeKey);
538
+ this.ensureOverrideExists(customization, menuName);
539
+ customization.overrides[menuName].hidden = true;
540
+ await this.saveCustomizationByKey(scopeKey, customization);
541
+ }
542
+ /**
543
+ * Show a menu item using a generic scope key
544
+ */
545
+ async showMenuItemByKey(scopeKey, menuName) {
546
+ this.validateMenuName(menuName, 'show');
547
+ const customization = await this.loadCustomizationByKey(scopeKey);
548
+ if (customization.overrides[menuName]) {
549
+ delete customization.overrides[menuName].hidden;
550
+ this.cleanupEmptyOverride(customization, menuName);
551
+ }
552
+ await this.saveCustomizationByKey(scopeKey, customization);
553
+ }
554
+ /**
555
+ * Update menu item properties using a generic scope key
556
+ */
557
+ async updateMenuPropertiesByKey(scopeKey, menuName, properties) {
558
+ this.validateMenuName(menuName, 'update properties for');
559
+ const customization = await this.loadCustomizationByKey(scopeKey);
560
+ this.ensureOverrideExists(customization, menuName);
561
+ customization.overrides[menuName].properties = {
562
+ ...customization.overrides[menuName].properties,
563
+ ...properties,
564
+ };
565
+ await this.saveCustomizationByKey(scopeKey, customization);
566
+ }
567
+ /**
568
+ * Add custom menu item using a generic scope key
569
+ */
570
+ async addCustomMenuItemByKey(scopeKey, menuItem, parent) {
571
+ const customization = await this.loadCustomizationByKey(scopeKey);
572
+ // Generate unique name if not provided
573
+ if (!menuItem.name) {
574
+ menuItem.name = `custom-menu-${Date.now()}`;
575
+ }
576
+ customization.customItems.push(menuItem);
577
+ await this.saveCustomizationByKey(scopeKey, customization);
578
+ }
579
+ /**
580
+ * Update custom menu item using a generic scope key
581
+ */
582
+ async updateCustomMenuItemByKey(scopeKey, menuName, menuItem) {
583
+ this.validateMenuName(menuName, 'update');
584
+ const customization = await this.loadCustomizationByKey(scopeKey);
585
+ const index = customization.customItems.findIndex((item) => item.name === menuName);
586
+ if (index === -1) {
587
+ throw new Error(`Custom menu item '${menuName}' not found`);
588
+ }
589
+ customization.customItems[index] = menuItem;
590
+ await this.saveCustomizationByKey(scopeKey, customization);
591
+ }
592
+ /**
593
+ * Delete custom menu item using a generic scope key
594
+ */
595
+ async deleteCustomMenuItemByKey(scopeKey, menuName) {
596
+ this.validateMenuName(menuName, 'delete');
597
+ const customization = await this.loadCustomizationByKey(scopeKey);
598
+ const initialLength = customization.customItems.length;
599
+ customization.customItems = customization.customItems.filter((item) => item.name !== menuName);
600
+ if (customization.customItems.length === initialLength) {
601
+ throw new Error(`Custom menu item '${menuName}' not found`);
602
+ }
603
+ await this.saveCustomizationByKey(scopeKey, customization);
604
+ }
605
+ /**
606
+ * Reset all customizations using a generic scope key
607
+ */
608
+ async resetCustomizationsByKey(scopeKey) {
609
+ await this.saveCustomizationByKey(scopeKey, cloneDeep(AXP_MENU_CUSTOMIZATION_DEFAULT));
610
+ }
611
+ //#endregion
612
+ //#region ---- Private Methods ----
613
+ /**
614
+ * Apply parent overrides from customization to restructure menu items
615
+ * This ensures the tree reflects saved parent changes (moves)
616
+ */
617
+ applyParentOverrides(items, customization) {
618
+ // First, flatten all items into a map for easy lookup
619
+ const itemMap = this.flattenMenuItems(items);
620
+ // Build new structure based on effective parent relationships
621
+ const rootItems = [];
622
+ const childrenMap = new Map();
623
+ for (const [itemName, item] of itemMap.entries()) {
624
+ const override = customization.overrides[itemName];
625
+ // Determine effective parent (override takes precedence)
626
+ let effectiveParent;
627
+ if (override?.parentName !== undefined) {
628
+ // parentName is explicitly set (could be null for root, or a parent name)
629
+ effectiveParent = override.parentName;
630
+ }
631
+ else {
632
+ // No override - find original parent by searching original structure
633
+ effectiveParent = this.findOriginalParent(items, itemName);
634
+ }
635
+ if (effectiveParent === null || effectiveParent === undefined) {
636
+ // Root level item
637
+ rootItems.push(item);
638
+ }
639
+ else {
640
+ // Child item - add to parent's children
641
+ if (!childrenMap.has(effectiveParent)) {
642
+ childrenMap.set(effectiveParent, []);
643
+ }
644
+ childrenMap.get(effectiveParent).push(item);
645
+ }
646
+ }
647
+ // Attach children to their parents recursively
648
+ const attachChildren = (item) => {
649
+ if (item.name && childrenMap.has(item.name)) {
650
+ item.children = childrenMap.get(item.name);
651
+ item.children?.forEach(attachChildren);
652
+ }
653
+ };
654
+ rootItems.forEach(attachChildren);
655
+ return rootItems;
656
+ }
657
+ /**
658
+ * Find the original parent name of an item in the original structure
659
+ * Returns undefined for root items, string for items with parents, null for not found
660
+ */
661
+ findOriginalParent(items, targetName, currentParent) {
662
+ for (const item of items) {
663
+ if (item.name === targetName) {
664
+ return currentParent; // undefined if root, string if has parent
665
+ }
666
+ if (item.children) {
667
+ const found = this.findOriginalParent(item.children, targetName, item.name);
668
+ if (found !== null) {
669
+ // Found in children (could be undefined for root of subtree, or string for nested item)
670
+ return found;
671
+ }
672
+ // found === null means not found in this subtree, continue searching
673
+ }
674
+ }
675
+ return null; // Not found in this level or any children
676
+ }
677
+ /**
678
+ * Convert menu items to AXTreeNode[] with metadata
679
+ */
680
+ convertToTreeNodes(items, customization, parentName) {
681
+ const nodes = items.map((item) => {
682
+ const itemName = item.name;
683
+ const override = itemName ? customization.overrides[itemName] : undefined;
684
+ const isCustom = itemName ? customization.customItems.some((ci) => ci.name === itemName) : false;
685
+ // Create metadata
686
+ const metadata = {
687
+ isBuiltIn: !isCustom,
688
+ isCustom,
689
+ isHidden: override?.hidden || false,
690
+ originalPriority: item.priority,
691
+ originalParentName: parentName,
692
+ };
693
+ // Apply priority override
694
+ const effectivePriority = override?.priority !== undefined ? override.priority : item.priority;
695
+ const itemWithPriority = { ...item, priority: effectivePriority };
696
+ // Create tree node data
697
+ const nodeData = {
698
+ menuItem: itemWithPriority,
699
+ metadata,
700
+ };
701
+ // Create tree node
702
+ const treeNode = {
703
+ id: itemName || item.path || this.generateNodeId(),
704
+ title: item.text || item.path || 'Unnamed',
705
+ icon: item.icon,
706
+ expanded: false,
707
+ selected: false,
708
+ ['children']: item.children ? this.convertToTreeNodes(item.children, customization, itemName) : undefined,
709
+ childrenCount: item.children?.length,
710
+ data: nodeData,
711
+ };
712
+ return treeNode;
713
+ });
714
+ // Sort by priority
715
+ nodes.sort((a, b) => {
716
+ const aPriority = a['data']?.menuItem.priority ?? 0;
717
+ const bPriority = b['data']?.menuItem.priority ?? 0;
718
+ return aPriority - bPriority;
719
+ });
720
+ return nodes;
721
+ }
722
+ /**
723
+ * Update customization from tree structure
724
+ * Extracts priorities and parent relationships from tree nodes
725
+ */
726
+ updateCustomizationFromTree(treeNodes, customization, parentName) {
727
+ // Calculate base priority for this level to maintain relative ordering
728
+ const basePriority = parentName ? PRIORITY_BASE_NESTED : PRIORITY_BASE_ROOT;
729
+ const priorityStep = PRIORITY_STEP;
730
+ treeNodes.forEach((node, index) => {
731
+ const nodeData = node['data'] || null;
732
+ const menuItem = nodeData?.menuItem;
733
+ if (menuItem?.name) {
734
+ this.ensureOverrideExists(customization, menuItem.name);
735
+ // Calculate new priority based on current position
736
+ const newPriority = basePriority + index * priorityStep;
737
+ // Get current effective priority (considering existing overrides)
738
+ const currentEffectivePriority = customization.overrides[menuItem.name]?.priority ?? nodeData.metadata.originalPriority ?? 0;
739
+ // Always update priority to reflect current position in tree
740
+ // This ensures reordering works correctly even after multiple moves
741
+ if (newPriority !== currentEffectivePriority) {
742
+ customization.overrides[menuItem.name].priority = newPriority;
743
+ }
744
+ // Determine current effective parent (considering existing overrides)
745
+ const currentEffectiveParent = customization.overrides[menuItem.name]?.parentName ?? nodeData.metadata.originalParentName;
746
+ // Update parent relationship if it changed from current effective parent
747
+ if (parentName !== currentEffectiveParent) {
748
+ if (parentName) {
749
+ customization.overrides[menuItem.name].parentName = parentName;
750
+ }
751
+ else {
752
+ // Moving to root - set to null (not undefined) so middleware will process it
753
+ // moveTo(null) moves the item to root level
754
+ customization.overrides[menuItem.name].parentName = null;
755
+ }
756
+ }
757
+ // Clean up empty overrides
758
+ this.cleanupEmptyOverride(customization, menuItem.name);
759
+ // Recursively process children
760
+ const nodeChildren = node['children'];
761
+ if (nodeChildren && nodeChildren.length > 0) {
762
+ this.updateCustomizationFromTree(nodeChildren, customization, menuItem.name);
763
+ }
764
+ }
765
+ });
766
+ }
767
+ /**
768
+ * Validate menu name before operations
769
+ */
770
+ validateMenuName(menuName, operation) {
771
+ if (!menuName) {
772
+ throw new Error(`Menu item must have a name to be ${operation}`);
773
+ }
774
+ }
775
+ /**
776
+ * Ensure override object exists for a menu item
777
+ */
778
+ ensureOverrideExists(customization, menuName) {
779
+ if (!customization.overrides[menuName]) {
780
+ customization.overrides[menuName] = {};
781
+ }
782
+ }
783
+ /**
784
+ * Clean up empty override objects
785
+ */
786
+ cleanupEmptyOverride(customization, menuName) {
787
+ if (Object.keys(customization.overrides[menuName] || {}).length === 0) {
788
+ delete customization.overrides[menuName];
789
+ }
790
+ }
791
+ /**
792
+ * Flatten menu items recursively into a map
793
+ */
794
+ flattenMenuItems(items) {
795
+ const itemMap = new Map();
796
+ const flatten = (itemList) => {
797
+ for (const item of itemList) {
798
+ if (item.name) {
799
+ // Clone item without children to rebuild structure
800
+ itemMap.set(item.name, { ...item, children: undefined });
801
+ }
802
+ if (item.children) {
803
+ flatten(item.children);
804
+ }
805
+ }
806
+ };
807
+ flatten(items);
808
+ return itemMap;
809
+ }
810
+ /**
811
+ * Generate unique ID for tree nodes
812
+ */
813
+ generateNodeId() {
814
+ return `node-${Date.now()}-${Math.floor(Math.random() * 10000)}`;
815
+ }
816
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPMenuManagementService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
817
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPMenuManagementService, providedIn: 'root' }); }
818
+ }
819
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPMenuManagementService, decorators: [{
820
+ type: Injectable,
821
+ args: [{ providedIn: 'root' }]
822
+ }] });
823
+
824
+ //#endregion
825
+ //#region ---- Menu Customizer Popup Component ----
826
+ /**
827
+ * Popup wrapper for the menu customizer component.
828
+ * Provides a popup layout with actions for managing menu customizations.
829
+ *
830
+ * Pass the following data when opening the popup:
831
+ * - scopeKey: string - The scope key for menu customizations
832
+ * - showToolbar?: boolean - Whether to show the toolbar (default: true)
833
+ * - allowAddItems?: boolean - Whether to allow adding items (default: true)
834
+ * - dragBehavior?: AXTreeViewDragBehavior - Drag behavior (default: 'move')
835
+ * - dragArea?: AXTreeViewDragArea - Drag area (default: 'handler')
836
+ */
837
+ class AXPMenuCustomizerPopupComponent extends AXPPopupLayoutBaseComponent {
838
+ constructor() {
839
+ super(...arguments);
840
+ //#region ---- Component State ----
841
+ /** Reference to the menu customizer component */
842
+ this.menuCustomizer = viewChild(AXPMenuCustomizerComponent, ...(ngDevMode ? [{ debugName: "menuCustomizer" }] : []));
843
+ /** The scope key for menu customizations (set by popup service) */
844
+ this.scopeKey = signal('', ...(ngDevMode ? [{ debugName: "scopeKey" }] : []));
845
+ /** Whether to show the toolbar */
846
+ this.showToolbar = signal(true, ...(ngDevMode ? [{ debugName: "showToolbar" }] : []));
847
+ /** Whether to allow adding custom items */
848
+ this.allowAddItems = signal(true, ...(ngDevMode ? [{ debugName: "allowAddItems" }] : []));
849
+ /** Drag behavior for the tree view */
850
+ this.dragBehavior = signal('both', ...(ngDevMode ? [{ debugName: "dragBehavior" }] : []));
851
+ /** Drag area for the tree view */
852
+ this.dragArea = signal('handler', ...(ngDevMode ? [{ debugName: "dragArea" }] : []));
853
+ /** Whether the component is ready to render (scopeKey is set) */
854
+ this.isReady = computed(() => this.scopeKey() !== '', ...(ngDevMode ? [{ debugName: "isReady" }] : []));
855
+ }
856
+ //#endregion
857
+ //#region ---- Lifecycle Methods ----
858
+ async ngOnInit() {
859
+ await super.ngOnInit();
860
+ // Popup-specific initialization can go here
861
+ }
862
+ //#endregion
863
+ //#region ---- UI Handlers ----
864
+ /**
865
+ * Returns the primary menu items for the popup layout.
866
+ */
867
+ getPrimaryMenuItems() {
868
+ return [
869
+ {
870
+ title: '@general:actions.close.title',
871
+ icon: 'fa-solid fa-xmark',
872
+ command: {
873
+ name: 'close',
874
+ },
875
+ },
876
+ ];
877
+ }
878
+ /**
879
+ * Handles when changes are saved
880
+ */
881
+ onSaved() {
882
+ this.close(true);
883
+ }
884
+ /**
885
+ * Handles when customization is cancelled
886
+ */
887
+ onCancelled() {
888
+ this.close(false);
889
+ }
890
+ /**
891
+ * Executes popup commands
892
+ */
893
+ execute(command) {
894
+ if (command.name === 'close') {
895
+ this.close(false);
896
+ }
897
+ }
898
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPMenuCustomizerPopupComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
899
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: AXPMenuCustomizerPopupComponent, isStandalone: true, selector: "axp-menu-customizer-popup", host: { classAttribute: "axp-menu-customizer-popup" }, providers: [
900
+ {
901
+ provide: AXPPopupLayoutBase,
902
+ useExisting: AXPMenuCustomizerPopupComponent,
903
+ },
904
+ ], viewQueries: [{ propertyName: "menuCustomizer", first: true, predicate: AXPMenuCustomizerComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
905
+ <axp-popup-layout>
906
+ <axp-page-content>
907
+ @if (isReady()) {
908
+ <axp-menu-customizer
909
+ [scopeKey]="scopeKey()"
910
+ [showToolbar]="showToolbar()"
911
+ [allowAddItems]="allowAddItems()"
912
+ [dragBehavior]="dragBehavior()"
913
+ [dragArea]="dragArea()"
914
+ (saved)="onSaved()"
915
+ (cancelled)="onCancelled()"
916
+ ></axp-menu-customizer>
917
+ }
918
+ </axp-page-content>
919
+ </axp-popup-layout>
920
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPPopupLayoutComponent, selector: "axp-popup-layout" }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: " axp-page-content, axp-page-footer-container, axp-page-footer, axp-page-header, axp-page-header-container, axp-page-toolbar, axp-layout-content, axp-layout-page-content, axp-layout-sections, axp-layout-body, axp-layout-page-body, axp-layout-prefix, axp-layout-suffix, axp-layout-title-bar, axp-layout-title, axp-layout-title-actions, axp-layout-nav-button, axp-layout-description, axp-layout-breadcrumbs, axp-layout-list-action, " }, { kind: "component", type: AXPMenuCustomizerComponent, selector: "axp-menu-customizer", inputs: ["scopeKey", "showToolbar", "allowAddItems", "dragBehavior", "dragArea"], outputs: ["saved", "cancelled"] }], encapsulation: i0.ViewEncapsulation.None }); }
921
+ }
922
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPMenuCustomizerPopupComponent, decorators: [{
923
+ type: Component,
924
+ args: [{
925
+ selector: 'axp-menu-customizer-popup',
926
+ template: `
927
+ <axp-popup-layout>
928
+ <axp-page-content>
929
+ @if (isReady()) {
930
+ <axp-menu-customizer
931
+ [scopeKey]="scopeKey()"
932
+ [showToolbar]="showToolbar()"
933
+ [allowAddItems]="allowAddItems()"
934
+ [dragBehavior]="dragBehavior()"
935
+ [dragArea]="dragArea()"
936
+ (saved)="onSaved()"
937
+ (cancelled)="onCancelled()"
938
+ ></axp-menu-customizer>
939
+ }
940
+ </axp-page-content>
941
+ </axp-popup-layout>
942
+ `,
943
+ imports: [
944
+ CommonModule,
945
+ AXTranslationModule,
946
+ AXPPopupLayoutComponent,
947
+ AXPThemeLayoutBlockComponent,
948
+ AXPMenuCustomizerComponent,
949
+ ],
950
+ encapsulation: ViewEncapsulation.None,
951
+ providers: [
952
+ {
953
+ provide: AXPPopupLayoutBase,
954
+ useExisting: AXPMenuCustomizerPopupComponent,
955
+ },
956
+ ],
957
+ host: { class: 'axp-menu-customizer-popup' },
958
+ }]
959
+ }], propDecorators: { menuCustomizer: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXPMenuCustomizerComponent), { isSignal: true }] }] } });
960
+
961
+ //#region ---- Imports ----
962
+ //#endregion
963
+ //#region ---- Open Menu Customizer Action ----
964
+ /**
965
+ * Workflow action that opens the menu customizer popup.
966
+ * Expects the context to contain:
967
+ * - data: The entity data (must have an 'id' property)
968
+ * - options.scopePrefix: The prefix for the scope key (e.g., 'edition', 'tenant')
969
+ * - options.title: Optional custom title for the popup
970
+ * - options.showToolbar: Whether to show toolbar (default: true)
971
+ * - options.allowAddItems: Whether to allow adding items (default: true)
972
+ * - options.dragBehavior: Drag behavior - 'none' | 'move' | 'copy' (default: 'move')
973
+ * - options.dragArea: Drag area - 'node' | 'handler' (default: 'handler')
974
+ */
975
+ class AXMOpenMenuCustomizerAction extends AXPWorkflowAction {
976
+ constructor() {
977
+ super(...arguments);
978
+ //#region ---- Dependencies ----
979
+ this.popupService = inject(AXPopupService);
980
+ this.translateService = inject(AXTranslationService);
981
+ }
982
+ //#endregion
983
+ //#region ---- Execute ----
984
+ async execute(context) {
985
+ // Get entity data
986
+ const data = context.getVariable('data');
987
+ const entityId = data?.id;
988
+ if (!entityId) {
989
+ console.error('Menu customizer requires entity data with an id property');
990
+ context.setOutput('result', false);
991
+ return;
992
+ }
993
+ // Get scope configuration
994
+ const scopePrefix = context.getVariable('options.scopePrefix') || 'entity';
995
+ const scopeKey = `${scopePrefix}:${entityId}`;
996
+ // Get optional title
997
+ const customTitle = context.getVariable('options.title');
998
+ const defaultTitle = await this.translateService.translateAsync('@platform-management:menu-management.components.menu-customizer-popup.title');
999
+ const entityTitle = data?.title || data?.name || entityId;
1000
+ const title = customTitle || `${defaultTitle} - ${entityTitle}`;
1001
+ // Open popup using the component from platform/layout/components
1002
+ // Pass signals to properly bind to the popup component's signal properties
1003
+ const result = await this.popupService.open(AXPMenuCustomizerPopupComponent, {
1004
+ title,
1005
+ size: 'lg',
1006
+ data: {
1007
+ scopeKey: signal(scopeKey),
1008
+ showToolbar: signal(context.getVariable('options.showToolbar') ?? true),
1009
+ allowAddItems: signal(context.getVariable('options.allowAddItems') ?? true),
1010
+ dragBehavior: signal(context.getVariable('options.dragBehavior') ?? 'both'),
1011
+ dragArea: signal(context.getVariable('options.dragArea') ?? 'handler'),
1012
+ },
1013
+ });
1014
+ // Set result based on popup outcome
1015
+ context.setOutput('result', result?.data === true);
1016
+ }
1017
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXMOpenMenuCustomizerAction, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
1018
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXMOpenMenuCustomizerAction }); }
1019
+ }
1020
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXMOpenMenuCustomizerAction, decorators: [{
1021
+ type: Injectable
1022
+ }] });
1023
+ //#endregion
1024
+ //#region ---- Customize Menu Workflow ----
1025
+ /**
1026
+ * Workflow definition for customizing menus.
1027
+ * Opens the menu customizer popup and handles the result.
1028
+ */
1029
+ const AXMCustomizeMenuWorkflow = {
1030
+ startStepId: 'open-customizer',
1031
+ steps: {
1032
+ 'open-customizer': {
1033
+ action: 'open-menu-customizer',
1034
+ nextSteps: [
1035
+ {
1036
+ conditions: [{ type: 'SINGLE', expression: 'context.getOutput("result") == true' }],
1037
+ nextStepId: 'show-success-toast',
1038
+ },
1039
+ ],
32
1040
  },
33
- token: {
34
- name: 'Tokens',
35
- title: `@${config.i18n}:tokens.entities.token.title`,
36
- icon: 'fa-light fa-object-exclude',
1041
+ 'show-success-toast': {
1042
+ action: 'AXPToastAction',
1043
+ input: {
1044
+ color: 'success',
1045
+ title: '@platform-management:menu-management.messages.success.customization-saved',
1046
+ },
37
1047
  },
38
1048
  },
39
1049
  };
40
1050
 
41
1051
  //#region ---- Imports ----
42
1052
  //#endregion
43
- //#region ---- Manifest Definition ----
1053
+ //#region ---- Module ----
44
1054
  /**
45
- * Platform Management Module Manifest.
46
- * Defines module metadata, features, and provider references.
1055
+ * Module for menu management features including the menu customizer
1056
+ * and related workflows.
47
1057
  */
48
- const PlatformManagementManifest = {
49
- name: RootConfig.module.name,
50
- version: '1.0.0',
51
- title: RootConfig.module.title,
52
- icon: RootConfig.module.icon,
53
- i18n: RootConfig.config.i18n,
54
- dependencies: [
55
- 'SecurityManagement',
56
- 'ApplicationManagement',
57
- 'SystemInsight',
58
- 'TenantManagement',
59
- 'SubscriptionManagement',
60
- ],
61
- };
62
- //#endregion
1058
+ class AXMMenuManagementModule {
1059
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXMMenuManagementModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1060
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.16", ngImport: i0, type: AXMMenuManagementModule, imports: [i1.AXPWorkflowModule] }); }
1061
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXMMenuManagementModule, providers: [
1062
+ {
1063
+ provide: AXP_MENU_CUSTOMIZER_SERVICE,
1064
+ useExisting: AXPMenuManagementService,
1065
+ },
1066
+ ], imports: [AXPWorkflowModule.forChild({
1067
+ workflows: {
1068
+ 'customize-menu': AXMCustomizeMenuWorkflow,
1069
+ },
1070
+ actions: {
1071
+ 'open-menu-customizer': AXMOpenMenuCustomizerAction,
1072
+ },
1073
+ })] }); }
1074
+ }
1075
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXMMenuManagementModule, decorators: [{
1076
+ type: NgModule,
1077
+ args: [{
1078
+ imports: [
1079
+ AXPWorkflowModule.forChild({
1080
+ workflows: {
1081
+ 'customize-menu': AXMCustomizeMenuWorkflow,
1082
+ },
1083
+ actions: {
1084
+ 'open-menu-customizer': AXMOpenMenuCustomizerAction,
1085
+ },
1086
+ }),
1087
+ ],
1088
+ providers: [
1089
+ {
1090
+ provide: AXP_MENU_CUSTOMIZER_SERVICE,
1091
+ useExisting: AXPMenuManagementService,
1092
+ },
1093
+ ],
1094
+ }]
1095
+ }] });
63
1096
 
64
1097
  /**
65
1098
  * Token that returns current ISO date-time string.
@@ -394,192 +1427,95 @@ class AXPUpdaterService {
394
1427
  icon: 'fa-regular fa-info',
395
1428
  content: translateService.translateSync('updater.content', { scope: scope }),
396
1429
  title: translateService.translateSync('updater.title', { scope: scope }),
397
- type: 'primary',
398
- orientation: 'horizontal',
399
- buttons: [
400
- {
401
- text: translateService.translateSync('updater.update', { scope: scope }),
402
- color: 'primary',
403
- onClick: async (e) => {
404
- try {
405
- document.location.reload();
406
- dialog.close();
407
- }
408
- catch (error) {
409
- console.error(error);
410
- }
411
- },
412
- },
413
- {
414
- text: translateService.translateSync('updater.cancel', { scope: scope }),
415
- color: 'default',
416
- autofocus: true,
417
- onClick: (e) => {
418
- dialog.close();
419
- },
420
- },
421
- ],
422
- closeButton: false,
423
- });
424
- }
425
- });
426
- }
427
- }
428
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPUpdaterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
429
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPUpdaterService, providedIn: 'root' }); }
430
- }
431
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPUpdaterService, decorators: [{
432
- type: Injectable,
433
- args: [{ providedIn: 'root' }]
434
- }], ctorParameters: () => [] });
435
-
436
- class AXMUpdaterModule {
437
- constructor(updaterService) {
438
- this.updaterService = updaterService;
439
- }
440
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXMUpdaterModule, deps: [{ token: AXPUpdaterService }], target: i0.ɵɵFactoryTarget.NgModule }); }
441
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.16", ngImport: i0, type: AXMUpdaterModule }); }
442
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXMUpdaterModule, providers: [AXPUpdaterService] }); }
443
- }
444
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXMUpdaterModule, decorators: [{
445
- type: NgModule,
446
- args: [{
447
- imports: [],
448
- exports: [],
449
- declarations: [],
450
- providers: [AXPUpdaterService],
451
- }]
452
- }], ctorParameters: () => [{ type: AXPUpdaterService }] });
453
-
454
- //#region ---- Menu Customization Constants ----
455
- /**
456
- * Setting key for menu customizations
457
- */
458
- const AXP_MENU_CUSTOMIZATION_KEY = 'axp.platform-management.menu-customization';
459
- /**
460
- * Current version of menu customization schema
461
- */
462
- const AXP_MENU_CUSTOMIZATION_VERSION = '1.0.0';
463
- /**
464
- * Default menu customization
465
- */
466
- const AXP_MENU_CUSTOMIZATION_DEFAULT = {
467
- version: AXP_MENU_CUSTOMIZATION_VERSION,
468
- overrides: {},
469
- customItems: [],
470
- };
471
- /**
472
- * Menu management feature configuration
473
- */
474
- const MenuManagementConfig = {
475
- route: 'menus',
476
- title: `@${RootConfig.config.i18n}:menu-management.components.menu-list.title`,
477
- icon: 'fa-light fa-bars',
478
- };
479
- //#endregion
480
-
481
- //#region ---- Custom Menu Middleware ----
482
- /**
483
- * Middleware that applies menu customizations using the enhanced context API
484
- * Applies user/tenant customizations from settings with priority support
485
- */
486
- class AXPCustomMenuMiddleware {
487
- constructor() {
488
- //#region ---- Middleware Properties ----
489
- this.name = 'menu-customization';
490
- this.priority = 100; // High priority to apply customizations early
491
- //#endregion
492
- //#region ---- Dependencies ----
493
- this.settingsService = inject(AXPSettingsService);
494
- //#endregion
495
- }
496
- //#endregion
497
- //#region ---- Middleware Implementation ----
498
- async process(context) {
499
- try {
500
- // Load menu customization from settings
501
- const customization = await this.loadCustomization();
502
- // Apply overrides to existing menu items using context API
503
- this.applyOverrides(context, customization);
504
- // Add custom menu items
505
- this.addCustomItems(context, customization);
506
- // Re-sort after applying priority overrides
507
- context.sort();
508
- }
509
- catch (error) {
510
- console.error('Error applying menu customizations:', error);
511
- }
512
- }
513
- //#endregion
514
- //#region ---- Private Methods ----
515
- /**
516
- * Load menu customization from settings
517
- * Merges Tenant and User scope customizations (User overrides Tenant)
518
- */
519
- async loadCustomization() {
520
- try {
521
- // Load both scopes
522
- const tenantSettings = this.settingsService.scope(AXPPlatformScope.Tenant);
523
- const userSettings = this.settingsService.scope(AXPPlatformScope.User);
524
- const tenantCustomization = await tenantSettings.get(AXP_MENU_CUSTOMIZATION_KEY);
525
- const userCustomization = await userSettings.get(AXP_MENU_CUSTOMIZATION_KEY);
526
- // Merge customizations: Tenant as base, User overrides
527
- const merged = {
528
- version: userCustomization?.version || tenantCustomization?.version || AXP_MENU_CUSTOMIZATION_DEFAULT.version,
529
- overrides: {
530
- ...(tenantCustomization?.overrides || {}),
531
- ...(userCustomization?.overrides || {}), // User overrides win
532
- },
533
- customItems: [...(tenantCustomization?.customItems || []), ...(userCustomization?.customItems || [])],
534
- };
535
- // Return merged result or default if both are empty
536
- const hasCustomizations = Object.keys(merged.overrides).length > 0 || merged.customItems.length > 0;
537
- return hasCustomizations ? merged : AXP_MENU_CUSTOMIZATION_DEFAULT;
538
- }
539
- catch (error) {
540
- console.error('Failed to load menu customization:', error);
541
- return AXP_MENU_CUSTOMIZATION_DEFAULT;
1430
+ type: 'primary',
1431
+ orientation: 'horizontal',
1432
+ buttons: [
1433
+ {
1434
+ text: translateService.translateSync('updater.update', { scope: scope }),
1435
+ color: 'primary',
1436
+ onClick: async (e) => {
1437
+ try {
1438
+ document.location.reload();
1439
+ dialog.close();
1440
+ }
1441
+ catch (error) {
1442
+ console.error(error);
1443
+ }
1444
+ },
1445
+ },
1446
+ {
1447
+ text: translateService.translateSync('updater.cancel', { scope: scope }),
1448
+ color: 'default',
1449
+ autofocus: true,
1450
+ onClick: (e) => {
1451
+ dialog.close();
1452
+ },
1453
+ },
1454
+ ],
1455
+ closeButton: false,
1456
+ });
1457
+ }
1458
+ });
542
1459
  }
543
1460
  }
544
- /**
545
- * Apply overrides to existing menu items using enhanced context API
546
- */
547
- applyOverrides(context, customization) {
548
- Object.entries(customization.overrides).forEach(([menuName, override]) => {
549
- const finder = context.findByName(menuName);
550
- if (!finder.exists()) {
551
- return;
552
- }
553
- // Hide menu item
554
- if (override.hidden) {
555
- finder.remove();
556
- return;
557
- }
558
- // Apply priority override
559
- if (override.priority !== undefined) {
560
- finder.setPriority(override.priority);
561
- }
562
- // Apply property overrides
563
- if (override.properties) {
564
- finder.update(override.properties);
565
- }
566
- // Move to different parent
567
- if (override.parentName !== undefined) {
568
- finder.moveTo(override.parentName);
569
- }
570
- });
571
- }
572
- /**
573
- * Add custom menu items using context API
574
- */
575
- addCustomItems(context, customization) {
576
- if (customization.customItems && customization.customItems.length > 0) {
577
- context.add(...customization.customItems);
578
- }
1461
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPUpdaterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1462
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPUpdaterService, providedIn: 'root' }); }
1463
+ }
1464
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPUpdaterService, decorators: [{
1465
+ type: Injectable,
1466
+ args: [{ providedIn: 'root' }]
1467
+ }], ctorParameters: () => [] });
1468
+
1469
+ class AXMUpdaterModule {
1470
+ constructor(updaterService) {
1471
+ this.updaterService = updaterService;
579
1472
  }
1473
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXMUpdaterModule, deps: [{ token: AXPUpdaterService }], target: i0.ɵɵFactoryTarget.NgModule }); }
1474
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.16", ngImport: i0, type: AXMUpdaterModule }); }
1475
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXMUpdaterModule, providers: [AXPUpdaterService] }); }
580
1476
  }
1477
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXMUpdaterModule, decorators: [{
1478
+ type: NgModule,
1479
+ args: [{
1480
+ imports: [],
1481
+ exports: [],
1482
+ declarations: [],
1483
+ providers: [AXPUpdaterService],
1484
+ }]
1485
+ }], ctorParameters: () => [{ type: AXPUpdaterService }] });
1486
+
1487
+ //#region ---- Imports ----
1488
+ //#endregion
1489
+ //#region ---- Manifest Definition ----
1490
+ /**
1491
+ * Platform Management Module Manifest.
1492
+ * Defines module metadata, features, and provider references.
1493
+ */
1494
+ const PlatformManagementManifest = {
1495
+ name: RootConfig.module.name,
1496
+ version: '1.0.0',
1497
+ title: RootConfig.module.title,
1498
+ icon: RootConfig.module.icon,
1499
+ i18n: RootConfig.config.i18n,
1500
+ dependencies: [
1501
+ 'SecurityManagement',
1502
+ 'ApplicationManagement',
1503
+ 'SystemInsight',
1504
+ 'TenantManagement',
1505
+ 'SubscriptionManagement',
1506
+ ],
1507
+ };
581
1508
  //#endregion
582
1509
 
1510
+ const AXPPlatformManagementMenuKeys = {
1511
+ AdministrationGroup: 'administration:group',
1512
+ Root: 'platform-management:menu',
1513
+ Tokens: 'platform-management:menu:tokens',
1514
+ Glossary: 'platform-management:menu:glossary',
1515
+ UserMenuManagement: 'platform-management:user:menus',
1516
+ MenuManagement: 'platform-management:menus',
1517
+ };
1518
+
583
1519
  const AXPPlatformManagementPermissionKeys = {
584
1520
  PlatformManagement: {
585
1521
  Management: 'PlatformManagement:Permission:Management',
@@ -601,11 +1537,29 @@ const AXPPlatformManagementPermissionKeys = {
601
1537
  },
602
1538
  };
603
1539
 
604
- const AXPPlatformManagementFeatureKeys = {
605
- MenuCustomization: 'PlatformManagement:Feature:menu-customization',
606
- AutoCheckUpdates: 'PlatformManagement:Feature:auto-check-updates',
607
- MaxTokens: 'PlatformManagement:Feature:max-tokens',
608
- };
1540
+ class AXMMenuProvider {
1541
+ constructor() {
1542
+ this.entityService = inject(AXPEntityService);
1543
+ }
1544
+ async provide(context) {
1545
+ const scope = RootConfig.config.i18n;
1546
+ //#region ---- Administration Menu (Authorized Users) ----
1547
+ context.find(AXPCommonMenuKeys.FoundationData).addItems([
1548
+ {
1549
+ name: AXPPlatformManagementMenuKeys.Tokens,
1550
+ priority: 20000101,
1551
+ text: `@${scope}:tokens.terms.tokens`,
1552
+ path: this.entityService.createPath(RootConfig.module.name, RootConfig.entities.token.name),
1553
+ icon: RootConfig.entities.token.icon,
1554
+ policy: {
1555
+ features: [RootConfig.module.name],
1556
+ permissions: [AXPPlatformManagementPermissionKeys.PlatformManagement.Token.Management],
1557
+ },
1558
+ },
1559
+ ]);
1560
+ //#endregion
1561
+ }
1562
+ }
609
1563
 
610
1564
  class AXMPermissionDefinitionProvider {
611
1565
  constructor(injector) {
@@ -640,116 +1594,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
640
1594
  type: Injectable
641
1595
  }], ctorParameters: () => [{ type: i0.Injector }] });
642
1596
 
643
- const AXPPlatformManagementMenuKeys = {
644
- AdministrationGroup: 'administration:group',
645
- Root: 'platform-management:menu',
646
- Tokens: 'platform-management:menu:tokens',
647
- Glossary: 'platform-management:menu:glossary',
648
- UserMenuManagement: 'platform-management:user:menus',
649
- MenuManagement: 'platform-management:menus',
650
- };
651
-
652
- class AXMMenuProvider {
653
- constructor() {
654
- this.entityService = inject(AXPEntityService);
655
- }
656
- async provide(context) {
657
- const scope = RootConfig.config.i18n;
658
- //#region ---- Administration Menu (Authorized Users) ----
659
- context.find(AXPCommonMenuKeys.FoundationData).addItems([
660
- {
661
- name: AXPPlatformManagementMenuKeys.Tokens,
662
- priority: 20000101,
663
- text: `@${scope}:tokens.terms.tokens`,
664
- path: this.entityService.createPath(RootConfig.module.name, RootConfig.entities.token.name),
665
- icon: RootConfig.entities.token.icon,
666
- policy: {
667
- features: [RootConfig.module.name],
668
- permissions: [AXPPlatformManagementPermissionKeys.PlatformManagement.Token.Management],
669
- },
670
- },
671
- ]);
672
- //#endregion
673
- }
674
- }
675
-
676
- class AXMEntityLoader {
677
- constructor() {
678
- this.injector = inject(Injector);
679
- }
680
- preload() {
681
- const module = RootConfig.module.name;
682
- return Array.from(Object.values(RootConfig.entities)).map((entity) => ({
683
- module: module,
684
- entity: entity.name,
685
- }));
686
- }
687
- async get(moduleName, entityName) {
688
- if (moduleName == RootConfig.module.name) {
689
- return new Promise(async (resolve) => {
690
- switch (entityName) {
691
- case RootConfig.entities.token.name: {
692
- const entity = (await Promise.resolve().then(function () { return index; })).tokenEntityFactory;
693
- resolve(entity(this.injector));
694
- break;
695
- }
696
- default:
697
- resolve(null);
698
- }
699
- });
700
- }
701
- return null;
702
- }
703
- async list() {
704
- const m = RootConfig.module.name;
705
- return Promise.resolve(Object.values(RootConfig.entities).map((e) => ({ name: e.name, module: m })));
706
- }
707
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXMEntityLoader, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
708
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXMEntityLoader }); }
709
- }
710
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXMEntityLoader, decorators: [{
711
- type: Injectable
712
- }] });
713
-
714
- //#region ---- Imports ----
715
- //#endregion
716
- //#region ---- Feature Definition Provider ----
717
- /**
718
- * Platform Management Feature Definition Provider.
719
- * Provides feature definitions for the Platform Management module.
720
- */
721
- class AXPPlatformManagementFeatureDefinitionProvider {
722
- async provide(context) {
723
- context.addFeature(AXPPlatformManagementFeatureKeys.MenuCustomization, {
724
- title: '@platform-management:features.menu-customization.title',
725
- description: '@platform-management:features.menu-customization.description',
726
- defaultValue: true,
727
- type: 'boolean',
728
- });
729
- context.addFeature(AXPPlatformManagementFeatureKeys.AutoCheckUpdates, {
730
- title: '@platform-management:features.auto-check-updates.title',
731
- description: '@platform-management:features.auto-check-updates.description',
732
- defaultValue: true,
733
- type: 'boolean',
734
- });
735
- context.addFeature(AXPPlatformManagementFeatureKeys.MaxTokens, {
736
- title: '@platform-management:features.max-tokens.title',
737
- description: '@platform-management:features.max-tokens.description',
738
- defaultValue: 100,
739
- type: 'number',
740
- interface: {
741
- type: 'number-editor',
742
- options: {
743
- min: 1,
744
- max: 1000,
745
- step: 1,
746
- },
747
- },
748
- });
749
- }
750
- }
751
- //#endregion
752
-
753
1597
  async function tokenEntityFactory(injector) {
754
1598
  const i18n = RootConfig.config.i18n;
755
1599
  const entityDef = {
@@ -1189,7 +2033,7 @@ function routesFactory() {
1189
2033
  children: [
1190
2034
  {
1191
2035
  path: '',
1192
- loadComponent: () => import('./acorex-modules-platform-management-menu-list.component-DLg61Nf8.mjs').then((c) => c.AXMMenuListComponent),
2036
+ loadComponent: () => import('./acorex-modules-platform-management-menu-list.component-C_mdsuRc.mjs').then((c) => c.AXMMenuListComponent),
1193
2037
  data: { reuse: true },
1194
2038
  },
1195
2039
  ],
@@ -1202,6 +2046,7 @@ class AXMPlatformManagementModule {
1202
2046
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXMPlatformManagementModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1203
2047
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.16", ngImport: i0, type: AXMPlatformManagementModule, imports: [AXMUpdaterModule,
1204
2048
  AXMTokenModule,
2049
+ AXMMenuManagementModule,
1205
2050
  // Entity Modules
1206
2051
  AXMTokenEntityModule] }); }
1207
2052
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXMPlatformManagementModule, providers: [
@@ -1245,6 +2090,7 @@ class AXMPlatformManagementModule {
1245
2090
  },
1246
2091
  ], imports: [AXMUpdaterModule,
1247
2092
  AXMTokenModule,
2093
+ AXMMenuManagementModule,
1248
2094
  // Entity Modules
1249
2095
  AXMTokenEntityModule] }); }
1250
2096
  }
@@ -1254,6 +2100,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
1254
2100
  imports: [
1255
2101
  AXMUpdaterModule,
1256
2102
  AXMTokenModule,
2103
+ AXMMenuManagementModule,
1257
2104
  // Entity Modules
1258
2105
  AXMTokenEntityModule,
1259
2106
  ],
@@ -1308,5 +2155,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
1308
2155
  * Generated bundle index. Do not edit.
1309
2156
  */
1310
2157
 
1311
- export { AXP_MENU_CUSTOMIZATION_KEY as A, RootConfig as R, AXP_MENU_CUSTOMIZATION_DEFAULT as a, AXMPlatformManagementModule as b, AXMTokensService as c, AXMTokensServiceImpl as d, AXMTokenEntityModule as e, AXPPlatformManagementFeatureKeys as f, tokenEntityFactory as t };
1312
- //# sourceMappingURL=acorex-modules-platform-management-acorex-modules-platform-management-DEx13GSy.mjs.map
2158
+ export { AXPMenuManagementService as A, RootConfig as R, AXMPlatformManagementModule as a, AXMTokensService as b, AXMTokensServiceImpl as c, AXMTokenEntityModule as d, AXPPlatformManagementFeatureKeys as e, tokenEntityFactory as t };
2159
+ //# sourceMappingURL=acorex-modules-platform-management-acorex-modules-platform-management-DVkP3JKC.mjs.map