@acorex-platform/module-platform-dev-tools-client 0.0.21

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.
@@ -0,0 +1,1062 @@
1
+ import { AXPModuleManifestRegistry, AXP_MODULE_MANIFEST_PROVIDER, provideLazyProvider } from '@acorex-platform/framework-client/core';
2
+ import { AXP_SETTING_DEFINITION_PROVIDER, AXP_MENU_PROVIDER } from '@acorex-platform/framework-client/common';
3
+ import { AXPPermissionDefinitionService, AXPAuthGuard, AXP_PERMISSION_DEFINITION_PROVIDER } from '@acorex-platform/framework-client/auth';
4
+ import { AXPRootLayoutComponent } from '@acorex-platform/framework-client/themes/default';
5
+ import * as i0 from '@angular/core';
6
+ import { Injectable, inject, input, ChangeDetectionStrategy, ViewEncapsulation, Component, signal, effect, viewChild, output, NgModule } from '@angular/core';
7
+ import { ROUTES } from '@angular/router';
8
+ import { RootConfig, AXPApplicationsPlatformPermissionKeys, AXPPlatformDevToolsSettings, AXP_PLATFORM_DEV_TOOLS_COMMUNICATION_DEBUG_REDIRECT_SECTION } from '@acorex-platform/module-platform-dev-tools-client/contracts';
9
+ import { AXPCommonPermissionGroupKeys } from '@acorex-platform/module-common-client/contracts';
10
+ import { AXPWidgetsList } from '@acorex-platform/framework-shared/core';
11
+ import { AXPEntityResolver } from '@acorex-platform/framework-client/layout/entity';
12
+ import * as i1 from '@angular/common';
13
+ import { CommonModule } from '@angular/common';
14
+ import { AXTreeViewComponent } from '@acorex/components/tree-view';
15
+ import { AXPPageLayoutBaseComponent, AXPPageLayoutComponent, AXPPageLayoutBase } from '@acorex-platform/framework-client/layout/views';
16
+ import * as i2 from '@acorex/core/translation';
17
+ import { AXTranslationModule } from '@acorex/core/translation';
18
+ import { AXPThemeLayoutStartSideComponent, AXPThemeLayoutHeaderComponent, AXPThemeLayoutBlockComponent } from '@acorex-platform/framework-client/layout/components';
19
+ import { AXDataSource } from '@acorex/cdk/common';
20
+ import * as i1$1 from '@acorex/components/data-table';
21
+ import { AXDataTableModule } from '@acorex/components/data-table';
22
+
23
+ //#region ---- Imports ----
24
+ //#endregion
25
+ //#region ---- Manifest Definition ----
26
+ /**
27
+ * Platform Dev Tools Module Manifest.
28
+ * Development-only module for exploring platform structure (modules, entities, permissions, features).
29
+ */
30
+ const PlatformDevToolsManifest = {
31
+ name: RootConfig.module.name,
32
+ version: '1.0.0',
33
+ title: RootConfig.module.title,
34
+ icon: RootConfig.module.icon,
35
+ i18n: RootConfig.config.i18n,
36
+ type: 'platform',
37
+ domain: 'platform',
38
+ description: '@platform-dev-tools:module.description',
39
+ required: false,
40
+ };
41
+ //#endregion
42
+
43
+ //#endregion
44
+ //#region ---- Permission Definition Provider ----
45
+ /**
46
+ * Registers UseDevTools under Applications & Platform.
47
+ */
48
+ class AXMPermissionDefinitionProvider {
49
+ async define(context) {
50
+ const keys = AXPApplicationsPlatformPermissionKeys;
51
+ const groups = AXPCommonPermissionGroupKeys;
52
+ const P = '@common:applications-platform.permissions';
53
+ const G = '@common:permission-groups';
54
+ context.addGroup(groups.ApplicationsPlatform.Root, `${G}.applications-platform.title`, `${G}.applications-platform.description`, { order: 110 });
55
+ context
56
+ .addGroup(groups.ApplicationsPlatform.DevTools, `${G}.applications-platform-dev-tools.title`, `${G}.applications-platform-dev-tools.description`, { parent: groups.ApplicationsPlatform.Root, order: 40 })
57
+ .addPermission(keys.UseDevTools, `${P}.use-dev-tools.title`, `${P}.use-dev-tools.description`, {
58
+ modules: ['PlatformDevTools'],
59
+ requiredFeatures: ['PlatformDevTools'],
60
+ })
61
+ .endPermission()
62
+ .endGroup();
63
+ }
64
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMPermissionDefinitionProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
65
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMPermissionDefinitionProvider }); }
66
+ }
67
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMPermissionDefinitionProvider, decorators: [{
68
+ type: Injectable
69
+ }] });
70
+
71
+ //#region ---- Imports ----
72
+ //#endregion
73
+ //#region ---- Setting Provider ----
74
+ /**
75
+ * Defines settings for Platform Dev Tools (developer-oriented options).
76
+ */
77
+ class AXPPlatformDevToolsSettingProvider {
78
+ async provide(context) {
79
+ context
80
+ .addGroup('platform-dev-tools', '@platform-dev-tools:settings.group.nav-title', '@platform-dev-tools:settings.group.description', 'fa-light fa-wrench', '@platform-dev-tools:settings.group.title', 999)
81
+ .addSection('developer', '@platform-dev-tools:settings.developer.title', '@platform-dev-tools:settings.developer.description')
82
+ .addSetting({
83
+ key: AXPPlatformDevToolsSettings.DebugMode,
84
+ title: '@platform-dev-tools:settings.developer.items.debug-mode.title',
85
+ description: '@platform-dev-tools:settings.developer.items.debug-mode.description',
86
+ scope: 'P',
87
+ overridableAt: [],
88
+ // Platform-only developer switch (same pattern as System Insight / Auth).
89
+ isInherited: false,
90
+ defaultValue: false,
91
+ widget: {
92
+ type: AXPWidgetsList.Editors.ToggleSwitch,
93
+ },
94
+ })
95
+ .endSection()
96
+ .addSection(AXP_PLATFORM_DEV_TOOLS_COMMUNICATION_DEBUG_REDIRECT_SECTION, '@platform-dev-tools:settings.communication-debug-redirect.title', '@platform-dev-tools:settings.communication-debug-redirect.description')
97
+ .endSection()
98
+ .endGroup();
99
+ }
100
+ }
101
+ //#endregion
102
+
103
+ //#region ---- Tree node types ----
104
+ //#endregion
105
+
106
+ //#region ---- Imports ----
107
+ //#endregion
108
+ //#region ---- Service ----
109
+ class PlatformExplorerDataService {
110
+ constructor() {
111
+ this.manifestRegistry = inject(AXPModuleManifestRegistry);
112
+ this.entityResolver = inject(AXPEntityResolver);
113
+ this.permissionService = inject(AXPPermissionDefinitionService);
114
+ }
115
+ /**
116
+ * Build only root-level module nodes (no children). Children are loaded on expand via getModuleChildren.
117
+ * Includes all modules; use buildModulesOnlyFiltered() to exclude modules with no entities/permissions/features.
118
+ */
119
+ async buildModulesOnly() {
120
+ await this.manifestRegistry.initialize();
121
+ const modules = this.manifestRegistry.getAll();
122
+ const tree = modules.map((mod) => ({
123
+ id: `module-${mod.name}`,
124
+ kind: 'module',
125
+ label: mod.title,
126
+ moduleName: mod.name,
127
+ moduleTitle: mod.title,
128
+ payload: mod,
129
+ children: [],
130
+ }));
131
+ tree.sort((a, b) => {
132
+ const nameA = a.payload?.name ?? a.moduleName ?? '';
133
+ const nameB = b.payload?.name ?? b.moduleName ?? '';
134
+ return nameA.localeCompare(nameB, undefined, { sensitivity: 'base' });
135
+ });
136
+ return tree;
137
+ }
138
+ /**
139
+ * Build root-level module nodes, excluding modules that have no entities, permissions, or features.
140
+ * Each module node gets itemCount = number of non-empty subcategories (for badge).
141
+ */
142
+ async buildModulesOnlyFiltered() {
143
+ const all = await this.buildModulesOnly();
144
+ const filtered = [];
145
+ for (const modNode of all) {
146
+ const children = await this.getModuleChildren(modNode.id);
147
+ if (children.length > 0) {
148
+ filtered.push({
149
+ ...modNode,
150
+ itemCount: children.length,
151
+ });
152
+ }
153
+ }
154
+ return filtered;
155
+ }
156
+ /**
157
+ * Load entities, permissions, and features for a module (called when module node is expanded or clicked).
158
+ * Only includes subcategories that have at least one item. Returns empty array if module has no items.
159
+ */
160
+ async getModuleChildren(moduleId) {
161
+ const moduleName = moduleId.startsWith('module-') ? moduleId.slice(7) : moduleId;
162
+ const mod = this.manifestRegistry.get(moduleName);
163
+ if (!mod)
164
+ return [];
165
+ const moduleTitle = mod.title;
166
+ const [allEntries, permissions, features] = await Promise.all([
167
+ this.entityResolver.listAll(),
168
+ this.getPermissionsForModule(moduleName),
169
+ Promise.resolve(this.getFeaturesForModule(moduleName)),
170
+ ]);
171
+ const moduleEntities = allEntries.filter((e) => e.module === moduleName);
172
+ const permissionsCount = permissions.length;
173
+ const featuresCount = features.length;
174
+ const nodes = [];
175
+ if (moduleEntities.length > 0) {
176
+ nodes.push({
177
+ id: `module-${moduleName}-entities`,
178
+ kind: 'entities',
179
+ label: '@platform-dev-tools:module.terms.entities',
180
+ moduleName,
181
+ moduleTitle,
182
+ itemCount: moduleEntities.length,
183
+ children: moduleEntities.map((e) => ({
184
+ id: `entity-${moduleName}-${e.name}`,
185
+ kind: 'entity',
186
+ label: e.name,
187
+ moduleName,
188
+ moduleTitle,
189
+ payload: e,
190
+ })),
191
+ });
192
+ }
193
+ if (permissionsCount > 0) {
194
+ nodes.push({
195
+ id: `module-${moduleName}-permissions`,
196
+ kind: 'permissions',
197
+ label: '@platform-dev-tools:module.terms.permissions',
198
+ moduleName,
199
+ moduleTitle,
200
+ itemCount: permissionsCount,
201
+ });
202
+ }
203
+ if (featuresCount > 0) {
204
+ nodes.push({
205
+ id: `module-${moduleName}-features`,
206
+ kind: 'features',
207
+ label: '@platform-dev-tools:module.terms.features',
208
+ moduleName,
209
+ moduleTitle,
210
+ itemCount: featuresCount,
211
+ });
212
+ }
213
+ return nodes;
214
+ }
215
+ /**
216
+ * Get all permissions for a module (for display in module detail).
217
+ */
218
+ async getPermissionsForModule(moduleName) {
219
+ const groups = await this.permissionService.getGroups();
220
+ return this.collectPermissionsForModule(groups, moduleName);
221
+ }
222
+ /**
223
+ * Get all features for a module (for display in module detail).
224
+ */
225
+ getFeaturesForModule(moduleName) {
226
+ return this.manifestRegistry.getModuleFeatures(moduleName);
227
+ }
228
+ collectPermissionsForModule(groups, moduleName) {
229
+ const prefix = `${moduleName}:`;
230
+ const out = [];
231
+ const collect = (items) => {
232
+ for (const p of items) {
233
+ if (p.name.startsWith(prefix))
234
+ out.push(p);
235
+ if (p.children?.length)
236
+ collect(p.children);
237
+ }
238
+ };
239
+ for (const g of groups) {
240
+ if (g.name === moduleName)
241
+ collect(g.permissions);
242
+ }
243
+ return out;
244
+ }
245
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PlatformExplorerDataService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
246
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PlatformExplorerDataService }); }
247
+ }
248
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PlatformExplorerDataService, decorators: [{
249
+ type: Injectable
250
+ }] });
251
+
252
+ //#region ---- Imports ----
253
+ //#endregion
254
+ class AXPlatformExplorerModuleDetailComponent {
255
+ constructor() {
256
+ this.payload = input(/* @ts-ignore */
257
+ ...(ngDevMode ? [undefined, { debugName: "payload" }] : /* istanbul ignore next */ []));
258
+ }
259
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPlatformExplorerModuleDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
260
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPlatformExplorerModuleDetailComponent, isStandalone: true, selector: "axp-platform-explorer-module-detail", inputs: { payload: { classPropertyName: "payload", publicName: "payload", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
261
+ @if (payload()) {
262
+ <section class="axp-module-detail">
263
+ <h3 class="axp-module-detail__section-title">
264
+ {{ '@platform-dev-tools:module.terms.module-info' | translate | async }}
265
+ </h3>
266
+ <dl class="axp-detail-dl">
267
+ <dt>
268
+ {{ '@platform-dev-tools:module.terms.name' | translate | async }}
269
+ </dt>
270
+ <dd>{{ payload()!.name }}</dd>
271
+
272
+ <dt>
273
+ {{ '@platform-dev-tools:module.terms.version' | translate | async }}
274
+ </dt>
275
+ <dd>{{ payload()!.version }}</dd>
276
+
277
+ <dt>
278
+ {{ '@platform-dev-tools:module.terms.title' | translate | async }}
279
+ </dt>
280
+ <dd>{{ payload()!.title }}</dd>
281
+
282
+ @if (payload()!.description) {
283
+ <dt>
284
+ {{ '@platform-dev-tools:module.terms.description' | translate | async }}
285
+ </dt>
286
+ <dd>{{ payload()!.description }}</dd>
287
+ }
288
+
289
+ @if (payload()!.i18n) {
290
+ <dt>i18n</dt>
291
+ <dd>{{ payload()!.i18n }}</dd>
292
+ }
293
+
294
+ @if (payload()!.required !== undefined) {
295
+ <dt>
296
+ {{ '@platform-dev-tools:module.terms.required' | translate | async }}
297
+ </dt>
298
+ <dd>{{ payload()!.required }}</dd>
299
+ }
300
+ </dl>
301
+ </section>
302
+ }
303
+ `, isInline: true, styles: [".axp-module-detail{margin-bottom:24px}.axp-module-detail__section-title{margin:0 0 12px;font-size:15px;font-weight:600}.axp-detail-dl{display:grid;grid-template-columns:auto 1fr;gap:4px 16px;margin:0}.axp-detail-dl dt{font-weight:600;color:var(--ax-neutral-text-secondary, #666)}.axp-detail-dl dd{margin:0}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
304
+ }
305
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPlatformExplorerModuleDetailComponent, decorators: [{
306
+ type: Component,
307
+ args: [{ selector: 'axp-platform-explorer-module-detail', standalone: true, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, AXTranslationModule], template: `
308
+ @if (payload()) {
309
+ <section class="axp-module-detail">
310
+ <h3 class="axp-module-detail__section-title">
311
+ {{ '@platform-dev-tools:module.terms.module-info' | translate | async }}
312
+ </h3>
313
+ <dl class="axp-detail-dl">
314
+ <dt>
315
+ {{ '@platform-dev-tools:module.terms.name' | translate | async }}
316
+ </dt>
317
+ <dd>{{ payload()!.name }}</dd>
318
+
319
+ <dt>
320
+ {{ '@platform-dev-tools:module.terms.version' | translate | async }}
321
+ </dt>
322
+ <dd>{{ payload()!.version }}</dd>
323
+
324
+ <dt>
325
+ {{ '@platform-dev-tools:module.terms.title' | translate | async }}
326
+ </dt>
327
+ <dd>{{ payload()!.title }}</dd>
328
+
329
+ @if (payload()!.description) {
330
+ <dt>
331
+ {{ '@platform-dev-tools:module.terms.description' | translate | async }}
332
+ </dt>
333
+ <dd>{{ payload()!.description }}</dd>
334
+ }
335
+
336
+ @if (payload()!.i18n) {
337
+ <dt>i18n</dt>
338
+ <dd>{{ payload()!.i18n }}</dd>
339
+ }
340
+
341
+ @if (payload()!.required !== undefined) {
342
+ <dt>
343
+ {{ '@platform-dev-tools:module.terms.required' | translate | async }}
344
+ </dt>
345
+ <dd>{{ payload()!.required }}</dd>
346
+ }
347
+ </dl>
348
+ </section>
349
+ }
350
+ `, styles: [".axp-module-detail{margin-bottom:24px}.axp-module-detail__section-title{margin:0 0 12px;font-size:15px;font-weight:600}.axp-detail-dl{display:grid;grid-template-columns:auto 1fr;gap:4px 16px;margin:0}.axp-detail-dl dt{font-weight:600;color:var(--ax-neutral-text-secondary, #666)}.axp-detail-dl dd{margin:0}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
351
+ }], propDecorators: { payload: [{ type: i0.Input, args: [{ isSignal: true, alias: "payload", required: false }] }] } });
352
+
353
+ //#endregion
354
+ function isListEntry(p) {
355
+ return p != null && 'fullName' in p && !('properties' in p);
356
+ }
357
+ class AXPlatformExplorerEntityDetailComponent {
358
+ constructor() {
359
+ this.payload = input(/* @ts-ignore */
360
+ ...(ngDevMode ? [undefined, { debugName: "payload" }] : /* istanbul ignore next */ []));
361
+ this.entity = signal(null, /* @ts-ignore */
362
+ ...(ngDevMode ? [{ debugName: "entity" }] : /* istanbul ignore next */ []));
363
+ this.loading = signal(false, /* @ts-ignore */
364
+ ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
365
+ this.entityResolver = inject(AXPEntityResolver);
366
+ effect(() => {
367
+ const p = this.payload();
368
+ if (!p) {
369
+ this.entity.set(null);
370
+ this.loading.set(false);
371
+ return;
372
+ }
373
+ if (isListEntry(p)) {
374
+ this.loading.set(true);
375
+ this.entity.set(null);
376
+ this.entityResolver.get(p.module, p.name).then((e) => {
377
+ if (this.payload() === p) {
378
+ this.entity.set(e ?? null);
379
+ }
380
+ this.loading.set(false);
381
+ });
382
+ }
383
+ else {
384
+ this.entity.set(p);
385
+ this.loading.set(false);
386
+ }
387
+ });
388
+ }
389
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPlatformExplorerEntityDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
390
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPlatformExplorerEntityDetailComponent, isStandalone: true, selector: "axp-platform-explorer-entity-detail", inputs: { payload: { classPropertyName: "payload", publicName: "payload", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "flex flex-col flex-1 min-h-0" }, ngImport: i0, template: `
391
+ <div class="flex flex-col flex-1 min-h-0 pt-0 overflow-auto">
392
+ @if (entity(); as e) {
393
+ <dl class="grid grid-cols-[auto_1fr] gap-x-4 gap-y-1 mb-3 m-0">
394
+ <dt class="font-semibold text-muted">{{ '@platform-dev-tools:module.terms.module' | translate | async }}</dt><dd class="m-0">{{ e.module }}</dd>
395
+ <dt class="font-semibold text-muted">{{ '@platform-dev-tools:module.terms.name' | translate | async }}</dt><dd class="m-0">{{ e.name }}</dd>
396
+ @if (e.title) {
397
+ <dt class="font-semibold text-muted">{{ '@platform-dev-tools:module.terms.title' | translate | async }}</dt><dd class="m-0">{{ e.title | translate | async}}</dd>
398
+ }
399
+ @if (e.formats.plural) {
400
+ <dt class="font-semibold text-muted">{{ '@platform-dev-tools:module.terms.plural' | translate | async }}</dt><dd class="m-0">{{ e.formats.plural | translate | async}}</dd>
401
+ }
402
+ </dl>
403
+ @if (e.properties && e.properties.length > 0) {
404
+ <p class="mb-2 mt-3 font-bold">{{ '@platform-dev-tools:module.terms.properties' | translate | async }} ({{ e.properties.length }})</p>
405
+ <div class="flex-1 min-h-0 overflow-auto border border-lightest rounded-md">
406
+ <table class="w-full border-collapse text-[13px]">
407
+ <thead>
408
+ <tr>
409
+ <th class="text-start p-2 px-3 bg-lighter font-semibold border-b border-lightest">{{ '@platform-dev-tools:module.terms.name' | translate | async }}</th>
410
+ <th class="text-start p-2 px-3 bg-lighter font-semibold border-b border-lightest">{{ '@platform-dev-tools:module.terms.title' | translate | async }}</th>
411
+ <th class="text-start p-2 px-3 bg-lighter font-semibold border-b border-lightest">{{ '@platform-dev-tools:module.terms.type' | translate | async }}</th>
412
+ <th class="text-start p-2 px-3 bg-lighter font-semibold border-b border-lightest">{{ '@platform-dev-tools:module.terms.description' | translate | async }}</th>
413
+ </tr>
414
+ </thead>
415
+ <tbody class="axp-entity-detail-tbody">
416
+ @for (p of e.properties; track p.name) {
417
+ <tr>
418
+ <td class="p-2 px-3 border-b border-lightest"><code class="text-xs bg-lighter px-1.5 py-0.5 rounded">{{ p.name }}</code></td>
419
+ <td class="p-2 px-3 border-b border-lightest">{{ p.title | translate | async }}</td>
420
+ <td class="p-2 px-3 border-b border-lightest">{{ p.schema.dataType }}</td>
421
+ <td class="p-2 px-3 border-b border-lightest">@if (p.description) { {{ p.description | translate | async }} } @else { – }</td>
422
+ </tr>
423
+ }
424
+ </tbody>
425
+ </table>
426
+ </div>
427
+ }
428
+ } @else if (loading()) {
429
+ <p class="m-0 text-muted">{{ '@platform-dev-tools:module.terms.loading-entity' | translate | async }}</p>
430
+ }
431
+ </div>
432
+ `, isInline: true, styles: [".axp-entity-detail-tbody tr:last-child td{border-bottom:none}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
433
+ }
434
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPlatformExplorerEntityDetailComponent, decorators: [{
435
+ type: Component,
436
+ args: [{ selector: 'axp-platform-explorer-entity-detail', standalone: true, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, AXTranslationModule], host: { class: 'flex flex-col flex-1 min-h-0' }, template: `
437
+ <div class="flex flex-col flex-1 min-h-0 pt-0 overflow-auto">
438
+ @if (entity(); as e) {
439
+ <dl class="grid grid-cols-[auto_1fr] gap-x-4 gap-y-1 mb-3 m-0">
440
+ <dt class="font-semibold text-muted">{{ '@platform-dev-tools:module.terms.module' | translate | async }}</dt><dd class="m-0">{{ e.module }}</dd>
441
+ <dt class="font-semibold text-muted">{{ '@platform-dev-tools:module.terms.name' | translate | async }}</dt><dd class="m-0">{{ e.name }}</dd>
442
+ @if (e.title) {
443
+ <dt class="font-semibold text-muted">{{ '@platform-dev-tools:module.terms.title' | translate | async }}</dt><dd class="m-0">{{ e.title | translate | async}}</dd>
444
+ }
445
+ @if (e.formats.plural) {
446
+ <dt class="font-semibold text-muted">{{ '@platform-dev-tools:module.terms.plural' | translate | async }}</dt><dd class="m-0">{{ e.formats.plural | translate | async}}</dd>
447
+ }
448
+ </dl>
449
+ @if (e.properties && e.properties.length > 0) {
450
+ <p class="mb-2 mt-3 font-bold">{{ '@platform-dev-tools:module.terms.properties' | translate | async }} ({{ e.properties.length }})</p>
451
+ <div class="flex-1 min-h-0 overflow-auto border border-lightest rounded-md">
452
+ <table class="w-full border-collapse text-[13px]">
453
+ <thead>
454
+ <tr>
455
+ <th class="text-start p-2 px-3 bg-lighter font-semibold border-b border-lightest">{{ '@platform-dev-tools:module.terms.name' | translate | async }}</th>
456
+ <th class="text-start p-2 px-3 bg-lighter font-semibold border-b border-lightest">{{ '@platform-dev-tools:module.terms.title' | translate | async }}</th>
457
+ <th class="text-start p-2 px-3 bg-lighter font-semibold border-b border-lightest">{{ '@platform-dev-tools:module.terms.type' | translate | async }}</th>
458
+ <th class="text-start p-2 px-3 bg-lighter font-semibold border-b border-lightest">{{ '@platform-dev-tools:module.terms.description' | translate | async }}</th>
459
+ </tr>
460
+ </thead>
461
+ <tbody class="axp-entity-detail-tbody">
462
+ @for (p of e.properties; track p.name) {
463
+ <tr>
464
+ <td class="p-2 px-3 border-b border-lightest"><code class="text-xs bg-lighter px-1.5 py-0.5 rounded">{{ p.name }}</code></td>
465
+ <td class="p-2 px-3 border-b border-lightest">{{ p.title | translate | async }}</td>
466
+ <td class="p-2 px-3 border-b border-lightest">{{ p.schema.dataType }}</td>
467
+ <td class="p-2 px-3 border-b border-lightest">@if (p.description) { {{ p.description | translate | async }} } @else { – }</td>
468
+ </tr>
469
+ }
470
+ </tbody>
471
+ </table>
472
+ </div>
473
+ }
474
+ } @else if (loading()) {
475
+ <p class="m-0 text-muted">{{ '@platform-dev-tools:module.terms.loading-entity' | translate | async }}</p>
476
+ }
477
+ </div>
478
+ `, styles: [".axp-entity-detail-tbody tr:last-child td{border-bottom:none}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
479
+ }], ctorParameters: () => [], propDecorators: { payload: [{ type: i0.Input, args: [{ isSignal: true, alias: "payload", required: false }] }] } });
480
+
481
+ //#region ---- Imports ----
482
+ //#endregion
483
+ class AXPlatformExplorerPermissionsListDetailComponent {
484
+ constructor() {
485
+ this.moduleName = input.required(/* @ts-ignore */
486
+ ...(ngDevMode ? [{ debugName: "moduleName" }] : /* istanbul ignore next */ []));
487
+ this.dataService = inject(PlatformExplorerDataService);
488
+ this.dataSource = new AXDataSource({
489
+ key: 'name',
490
+ pageSize: 20,
491
+ load: async (e) => {
492
+ const name = this.moduleName();
493
+ if (!name)
494
+ return { items: [], total: 0 };
495
+ const list = await this.dataService.getPermissionsForModule(name);
496
+ const skip = e?.skip ?? 0;
497
+ const take = e?.take ?? 20;
498
+ const items = list.slice(skip, skip + take);
499
+ return { items, total: list.length };
500
+ },
501
+ });
502
+ effect(() => {
503
+ this.moduleName();
504
+ this.dataSource.refresh();
505
+ });
506
+ }
507
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPlatformExplorerPermissionsListDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
508
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPlatformExplorerPermissionsListDetailComponent, isStandalone: true, selector: "axp-platform-explorer-permissions-list-detail", inputs: { moduleName: { classPropertyName: "moduleName", publicName: "moduleName", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "flex flex-col flex-1 min-h-0" }, ngImport: i0, template: `
509
+ <div class="flex flex-1 min-h-0 pt-0 overflow-auto">
510
+ <ax-data-table
511
+ class="flex-1 border border-lightest rounded-md overflow-hidden"
512
+ [paging]="true"
513
+ [allowReordering]="true"
514
+ [dataSource]="dataSource"
515
+ >
516
+ <ax-text-column [dataField]="'name'" [caption]="'@platform-dev-tools:module.terms.name' | translate | async" [width]="'420px'" [allowResizing]="true"></ax-text-column>
517
+ <ax-text-column [dataField]="'title'" [caption]="'@platform-dev-tools:module.terms.title' | translate | async" [cellTemplate]="titleTpl" [width]="'260px'" [allowResizing]="true"></ax-text-column>
518
+ <ax-text-column [dataField]="'description'" [caption]="'@platform-dev-tools:module.terms.description' | translate | async" [cellTemplate]="descTpl" [width]="'380px'" [allowResizing]="true"></ax-text-column>
519
+ </ax-data-table>
520
+ </div>
521
+ <ng-template #titleTpl let-item>
522
+ {{ $safeNavigationMigration(item.data?.title) | translate | async }}</ng-template>
523
+ <ng-template #descTpl let-item>
524
+ @if (item.data?.description) { {{ item.data.description | translate | async }} } @else { – }
525
+ </ng-template>
526
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXDataTableModule }, { kind: "component", type: i1$1.AXDataTableComponent, selector: "ax-data-table", inputs: ["dataSource", "selectedRows", "parentField", "hasChildrenField", "rowDetailsTemplate", "rowCssClass", "cellCssClass", "highlightText", "look", "rowTemplate", "emptyTemplate", "noDataTemplate", "alternative", "showHeader", "fixedHeader", "showFooter", "fixedFooter", "itemHeight", "allowReordering", "paging", "fetchDataMode", "loading", "focusedRow"], outputs: ["selectedRowsChange", "focusedRowChange", "onRowClick", "onRowDbClick", "onColumnsOrderChanged", "onColumnSizeChanged", "onPageChanged"] }, { kind: "component", type: i1$1.AXDataTableTextColumnComponent, selector: "ax-text-column", inputs: ["width", "caption", "allowSorting", "allowResizing", "fixed", "hasTitle", "customExpandIcon", "customCollapseIcon", "dataField", "expandHandler", "wrapText", "cellTemplate", "footerTemplate", "headerTemplate", "format", "formatOptions"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
527
+ }
528
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPlatformExplorerPermissionsListDetailComponent, decorators: [{
529
+ type: Component,
530
+ args: [{
531
+ selector: 'axp-platform-explorer-permissions-list-detail',
532
+ standalone: true,
533
+ encapsulation: ViewEncapsulation.None,
534
+ changeDetection: ChangeDetectionStrategy.OnPush,
535
+ imports: [CommonModule, AXDataTableModule, AXTranslationModule],
536
+ host: { class: 'flex flex-col flex-1 min-h-0' },
537
+ template: `
538
+ <div class="flex flex-1 min-h-0 pt-0 overflow-auto">
539
+ <ax-data-table
540
+ class="flex-1 border border-lightest rounded-md overflow-hidden"
541
+ [paging]="true"
542
+ [allowReordering]="true"
543
+ [dataSource]="dataSource"
544
+ >
545
+ <ax-text-column [dataField]="'name'" [caption]="'@platform-dev-tools:module.terms.name' | translate | async" [width]="'420px'" [allowResizing]="true"></ax-text-column>
546
+ <ax-text-column [dataField]="'title'" [caption]="'@platform-dev-tools:module.terms.title' | translate | async" [cellTemplate]="titleTpl" [width]="'260px'" [allowResizing]="true"></ax-text-column>
547
+ <ax-text-column [dataField]="'description'" [caption]="'@platform-dev-tools:module.terms.description' | translate | async" [cellTemplate]="descTpl" [width]="'380px'" [allowResizing]="true"></ax-text-column>
548
+ </ax-data-table>
549
+ </div>
550
+ <ng-template #titleTpl let-item>
551
+ {{ $safeNavigationMigration(item.data?.title) | translate | async }}</ng-template>
552
+ <ng-template #descTpl let-item>
553
+ @if (item.data?.description) { {{ item.data.description | translate | async }} } @else { – }
554
+ </ng-template>
555
+ `,
556
+ }]
557
+ }], ctorParameters: () => [], propDecorators: { moduleName: [{ type: i0.Input, args: [{ isSignal: true, alias: "moduleName", required: true }] }] } });
558
+
559
+ //#region ---- Imports ----
560
+ //#endregion
561
+ class AXPlatformExplorerFeaturesListDetailComponent {
562
+ constructor() {
563
+ this.moduleName = input.required(/* @ts-ignore */
564
+ ...(ngDevMode ? [{ debugName: "moduleName" }] : /* istanbul ignore next */ []));
565
+ this.dataService = inject(PlatformExplorerDataService);
566
+ this.dataSource = new AXDataSource({
567
+ key: 'name',
568
+ pageSize: 20,
569
+ load: (e) => {
570
+ const name = this.moduleName();
571
+ if (!name)
572
+ return Promise.resolve({ items: [], total: 0 });
573
+ const list = this.dataService.getFeaturesForModule(name);
574
+ const skip = e?.skip ?? 0;
575
+ const take = e?.take ?? 20;
576
+ const items = list.slice(skip, skip + take);
577
+ return Promise.resolve({ items, total: list.length });
578
+ },
579
+ });
580
+ effect(() => {
581
+ this.moduleName();
582
+ this.dataSource.refresh();
583
+ });
584
+ }
585
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPlatformExplorerFeaturesListDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
586
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPlatformExplorerFeaturesListDetailComponent, isStandalone: true, selector: "axp-platform-explorer-features-list-detail", inputs: { moduleName: { classPropertyName: "moduleName", publicName: "moduleName", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "flex flex-col flex-1 min-h-0" }, ngImport: i0, template: `
587
+ <div class="flex flex-1 min-h-0 pt-0 overflow-auto">
588
+ <ax-data-table
589
+ class="flex-1 border border-lightest rounded-md overflow-hidden"
590
+ [paging]="true"
591
+ [allowReordering]="true"
592
+ [dataSource]="dataSource"
593
+ >
594
+ <ax-text-column dataField="key" [caption]="'@platform-dev-tools:module.terms.key' | translate | async" [width]="'240px'" [allowResizing]="true"></ax-text-column>
595
+ <ax-text-column dataField="title" [caption]="'@platform-dev-tools:module.terms.title' | translate | async" [cellTemplate]="titleTpl" [width]="'280px'" [allowResizing]="true"></ax-text-column>
596
+ <ax-text-column dataField="type" caption="Type" [width]="'100px'" [cellTemplate]="typeTpl" [allowResizing]="true"></ax-text-column>
597
+ <ax-text-column dataField="description" [caption]="'@platform-dev-tools:module.terms.description' | translate | async" [cellTemplate]="descTpl" [width]="'340px'" [allowResizing]="true"></ax-text-column>
598
+ <ax-text-column dataField="defaultValue" [caption]="'@platform-dev-tools:module.terms.default-value' | translate | async" [width]="'140px'" [allowResizing]="true"></ax-text-column>
599
+ </ax-data-table>
600
+ </div>
601
+ <ng-template #titleTpl let-item>{{ $safeNavigationMigration(item.data?.title) | translate | async }}</ng-template>
602
+ <ng-template #typeTpl let-item>{{ item.data?.type ?? '–' }}</ng-template>
603
+ <ng-template #descTpl let-item>@if (item.data?.description) { {{ item.data.description | translate | async }} } @else { – }</ng-template>
604
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXDataTableModule }, { kind: "component", type: i1$1.AXDataTableComponent, selector: "ax-data-table", inputs: ["dataSource", "selectedRows", "parentField", "hasChildrenField", "rowDetailsTemplate", "rowCssClass", "cellCssClass", "highlightText", "look", "rowTemplate", "emptyTemplate", "noDataTemplate", "alternative", "showHeader", "fixedHeader", "showFooter", "fixedFooter", "itemHeight", "allowReordering", "paging", "fetchDataMode", "loading", "focusedRow"], outputs: ["selectedRowsChange", "focusedRowChange", "onRowClick", "onRowDbClick", "onColumnsOrderChanged", "onColumnSizeChanged", "onPageChanged"] }, { kind: "component", type: i1$1.AXDataTableTextColumnComponent, selector: "ax-text-column", inputs: ["width", "caption", "allowSorting", "allowResizing", "fixed", "hasTitle", "customExpandIcon", "customCollapseIcon", "dataField", "expandHandler", "wrapText", "cellTemplate", "footerTemplate", "headerTemplate", "format", "formatOptions"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
605
+ }
606
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPlatformExplorerFeaturesListDetailComponent, decorators: [{
607
+ type: Component,
608
+ args: [{
609
+ selector: 'axp-platform-explorer-features-list-detail',
610
+ standalone: true,
611
+ encapsulation: ViewEncapsulation.None,
612
+ changeDetection: ChangeDetectionStrategy.OnPush,
613
+ imports: [CommonModule, AXDataTableModule, AXTranslationModule],
614
+ host: { class: 'flex flex-col flex-1 min-h-0' },
615
+ template: `
616
+ <div class="flex flex-1 min-h-0 pt-0 overflow-auto">
617
+ <ax-data-table
618
+ class="flex-1 border border-lightest rounded-md overflow-hidden"
619
+ [paging]="true"
620
+ [allowReordering]="true"
621
+ [dataSource]="dataSource"
622
+ >
623
+ <ax-text-column dataField="key" [caption]="'@platform-dev-tools:module.terms.key' | translate | async" [width]="'240px'" [allowResizing]="true"></ax-text-column>
624
+ <ax-text-column dataField="title" [caption]="'@platform-dev-tools:module.terms.title' | translate | async" [cellTemplate]="titleTpl" [width]="'280px'" [allowResizing]="true"></ax-text-column>
625
+ <ax-text-column dataField="type" caption="Type" [width]="'100px'" [cellTemplate]="typeTpl" [allowResizing]="true"></ax-text-column>
626
+ <ax-text-column dataField="description" [caption]="'@platform-dev-tools:module.terms.description' | translate | async" [cellTemplate]="descTpl" [width]="'340px'" [allowResizing]="true"></ax-text-column>
627
+ <ax-text-column dataField="defaultValue" [caption]="'@platform-dev-tools:module.terms.default-value' | translate | async" [width]="'140px'" [allowResizing]="true"></ax-text-column>
628
+ </ax-data-table>
629
+ </div>
630
+ <ng-template #titleTpl let-item>{{ $safeNavigationMigration(item.data?.title) | translate | async }}</ng-template>
631
+ <ng-template #typeTpl let-item>{{ item.data?.type ?? '–' }}</ng-template>
632
+ <ng-template #descTpl let-item>@if (item.data?.description) { {{ item.data.description | translate | async }} } @else { – }</ng-template>
633
+ `,
634
+ }]
635
+ }], ctorParameters: () => [], propDecorators: { moduleName: [{ type: i0.Input, args: [{ isSignal: true, alias: "moduleName", required: true }] }] } });
636
+
637
+ //#region ---- Imports ----
638
+ //#endregion
639
+ //#region ---- Component ----
640
+ class AXPlatformExplorerDetailComponent {
641
+ constructor() {
642
+ this.node = input.required(/* @ts-ignore */
643
+ ...(ngDevMode ? [{ debugName: "node" }] : /* istanbul ignore next */ []));
644
+ }
645
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPlatformExplorerDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
646
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPlatformExplorerDetailComponent, isStandalone: true, selector: "axp-platform-explorer-detail", inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "flex flex-col flex-1 min-h-0" }, ngImport: i0, template: `
647
+ <div class="flex flex-col flex-1 min-h-0">
648
+ @switch (node().kind) {
649
+ @case ('module') {
650
+ <axp-platform-explorer-module-detail [payload]="$any(node().payload)" />
651
+ }
652
+ @case ('entity') {
653
+ <axp-platform-explorer-entity-detail [payload]="$any(node().payload)" />
654
+ }
655
+ @case ('permissions') {
656
+ <axp-platform-explorer-permissions-list-detail [moduleName]="node().moduleName!" />
657
+ }
658
+ @case ('features') {
659
+ <axp-platform-explorer-features-list-detail [moduleName]="node().moduleName!" />
660
+ }
661
+ @default {
662
+ <p class="axp-detail__hint">{{ node().children?.length ?? 0 }} items.</p>
663
+ }
664
+ }
665
+ </div>
666
+ `, isInline: true, styles: [".axp-detail__hint{margin:0;color:var(--ax-neutral-text-secondary, #666)}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPlatformExplorerModuleDetailComponent, selector: "axp-platform-explorer-module-detail", inputs: ["payload"] }, { kind: "component", type: AXPlatformExplorerEntityDetailComponent, selector: "axp-platform-explorer-entity-detail", inputs: ["payload"] }, { kind: "component", type: AXPlatformExplorerPermissionsListDetailComponent, selector: "axp-platform-explorer-permissions-list-detail", inputs: ["moduleName"] }, { kind: "component", type: AXPlatformExplorerFeaturesListDetailComponent, selector: "axp-platform-explorer-features-list-detail", inputs: ["moduleName"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
667
+ }
668
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPlatformExplorerDetailComponent, decorators: [{
669
+ type: Component,
670
+ args: [{ selector: 'axp-platform-explorer-detail', standalone: true, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'flex flex-col flex-1 min-h-0' }, imports: [
671
+ AXTranslationModule,
672
+ AXPlatformExplorerModuleDetailComponent,
673
+ AXPlatformExplorerEntityDetailComponent,
674
+ AXPlatformExplorerPermissionsListDetailComponent,
675
+ AXPlatformExplorerFeaturesListDetailComponent
676
+ ], template: `
677
+ <div class="flex flex-col flex-1 min-h-0">
678
+ @switch (node().kind) {
679
+ @case ('module') {
680
+ <axp-platform-explorer-module-detail [payload]="$any(node().payload)" />
681
+ }
682
+ @case ('entity') {
683
+ <axp-platform-explorer-entity-detail [payload]="$any(node().payload)" />
684
+ }
685
+ @case ('permissions') {
686
+ <axp-platform-explorer-permissions-list-detail [moduleName]="node().moduleName!" />
687
+ }
688
+ @case ('features') {
689
+ <axp-platform-explorer-features-list-detail [moduleName]="node().moduleName!" />
690
+ }
691
+ @default {
692
+ <p class="axp-detail__hint">{{ node().children?.length ?? 0 }} items.</p>
693
+ }
694
+ }
695
+ </div>
696
+ `, styles: [".axp-detail__hint{margin:0;color:var(--ax-neutral-text-secondary, #666)}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
697
+ }], propDecorators: { node: [{ type: i0.Input, args: [{ isSignal: true, alias: "node", required: true }] }] } });
698
+
699
+ //#region ---- Imports ----
700
+ //#endregion
701
+ //#region ---- Convert tree to AXTreeViewNode ----
702
+ function toTreeViewNodes(nodes, markModuleExpandable = false) {
703
+ return nodes.map((n) => {
704
+ const children = n.children ?? [];
705
+ const hasChildren = children.length > 0;
706
+ const axNode = {
707
+ id: n.id,
708
+ title: n.label,
709
+ children: hasChildren ? toTreeViewNodes(children, false) : undefined,
710
+ data: { treeNode: n },
711
+ };
712
+ if (markModuleExpandable && n.kind === 'module' && !hasChildren) {
713
+ axNode['childrenCount'] = 3;
714
+ }
715
+ return axNode;
716
+ });
717
+ }
718
+ //#endregion
719
+ //#region ---- Component ----
720
+ class AXPlatformExplorerPageComponent extends AXPPageLayoutBaseComponent {
721
+ constructor() {
722
+ super();
723
+ this.dataService = inject(PlatformExplorerDataService);
724
+ this.loading = signal(true, /* @ts-ignore */
725
+ ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
726
+ this.selectedNode = signal(null, /* @ts-ignore */
727
+ ...(ngDevMode ? [{ debugName: "selectedNode" }] : /* istanbul ignore next */ []));
728
+ this.moduleNodes = signal([], /* @ts-ignore */
729
+ ...(ngDevMode ? [{ debugName: "moduleNodes" }] : /* istanbul ignore next */ []));
730
+ this.tree = viewChild('tree', /* @ts-ignore */
731
+ ...(ngDevMode ? [{ debugName: "tree" }] : /* istanbul ignore next */ []));
732
+ /** Datasource for tree: root = modules only; children loaded when module is expanded. */
733
+ this.datasource = async (parentId) => {
734
+ if (!parentId) {
735
+ const nodes = this.moduleNodes();
736
+ return toTreeViewNodes(nodes, true);
737
+ }
738
+ const children = await this.dataService.getModuleChildren(parentId);
739
+ return toTreeViewNodes(children, false);
740
+ };
741
+ this.initializeModules();
742
+ }
743
+ async initializeModules() {
744
+ this.loading.set(true);
745
+ try {
746
+ const nodes = await this.dataService.buildModulesOnlyFiltered();
747
+ this.moduleNodes.set(nodes);
748
+ }
749
+ finally {
750
+ this.loading.set(false);
751
+ }
752
+ }
753
+ async getPageTitle() {
754
+ const node = this.selectedNode();
755
+ if (!node) {
756
+ return this.translateService.translateAsync('@platform-dev-tools:module.title');
757
+ }
758
+ const moduleTitleKey = node.moduleTitle ?? node.label;
759
+ const moduleTitle = await this.translateService.translateAsync(moduleTitleKey);
760
+ const contextParts = [];
761
+ switch (node.kind) {
762
+ case 'module':
763
+ return moduleTitle;
764
+ case 'entities':
765
+ contextParts.push(await this.translateService.translateAsync('@platform-dev-tools:module.terms.entities'));
766
+ break;
767
+ case 'entity':
768
+ contextParts.push(await this.translateService.translateAsync('@platform-dev-tools:module.terms.entities'));
769
+ contextParts.push(node.label);
770
+ break;
771
+ case 'permissions':
772
+ contextParts.push(await this.translateService.translateAsync('@platform-dev-tools:module.terms.permissions'));
773
+ break;
774
+ case 'features':
775
+ contextParts.push(await this.translateService.translateAsync('@platform-dev-tools:module.terms.features'));
776
+ break;
777
+ default:
778
+ return moduleTitle;
779
+ }
780
+ return [moduleTitle, ...contextParts].join(' - ');
781
+ }
782
+ getPageDescription() {
783
+ const node = this.selectedNode();
784
+ if (!node)
785
+ return null;
786
+ const key = this.descriptionKeyForKind(node.kind);
787
+ return key ? this.translateService.translateAsync(key) : null;
788
+ }
789
+ getPageBreadcrumbs() {
790
+ const node = this.selectedNode();
791
+ const items = [
792
+ { title: '@platform-dev-tools:module.menus.platform-explorer.title' },
793
+ ];
794
+ if (node?.moduleTitle) {
795
+ items.push({ title: node.moduleTitle });
796
+ }
797
+ return items;
798
+ }
799
+ descriptionKeyForKind(kind) {
800
+ switch (kind) {
801
+ case 'module':
802
+ return '@platform-dev-tools:module.descriptions.module';
803
+ case 'entities':
804
+ return '@platform-dev-tools:module.descriptions.entities';
805
+ case 'entity':
806
+ return '@platform-dev-tools:module.descriptions.entity';
807
+ case 'permissions':
808
+ return '@platform-dev-tools:module.descriptions.permissions';
809
+ case 'features':
810
+ return '@platform-dev-tools:module.descriptions.features';
811
+ default:
812
+ return null;
813
+ }
814
+ }
815
+ onNodeClick(event) {
816
+ const node = event.node;
817
+ const data = node?.['data'];
818
+ const treeNode = data?.treeNode;
819
+ if (treeNode) {
820
+ this.selectedNode.set(treeNode);
821
+ this.recompute();
822
+ // When a module node is clicked, expand it so the tree loads its children (entities, permissions, features)
823
+ if (treeNode.kind === 'module') {
824
+ const treeRef = this.tree();
825
+ if (treeRef && typeof treeRef.expandNode === 'function') {
826
+ treeRef.expandNode(treeNode.id);
827
+ }
828
+ }
829
+ }
830
+ }
831
+ onNodeToggle(_event) {
832
+ // Tree loads children via datasource(parentId) when a node is expanded; no extra work needed.
833
+ }
834
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPlatformExplorerPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
835
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPlatformExplorerPageComponent, isStandalone: true, selector: "axp-platform-explorer-page", providers: [
836
+ PlatformExplorerDataService,
837
+ {
838
+ provide: AXPPageLayoutBase,
839
+ useExisting: AXPlatformExplorerPageComponent,
840
+ },
841
+ ], viewQueries: [{ propertyName: "tree", first: true, predicate: ["tree"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<axp-page-layout>\n <axp-layout-start-side>\n <axp-layout-header>\n <axp-layout-title>{{ '@platform-dev-tools:module.menus.platform-explorer.title' | translate | async\n }}</axp-layout-title>\n </axp-layout-header>\n <axp-layout-content class=\"axp-platform-explorer__tree-wrap\">\n @if (loading()) {\n <p class=\"axp-platform-explorer__loading\">Loading...</p>\n } @else if (moduleNodes().length === 0) {\n <p class=\"axp-platform-explorer__empty\">{{ '@platform-dev-tools:module.messages.no-modules' | translate | async }}\n </p>\n } @else {\n <ax-tree-view #tree [datasource]=\"datasource\" [selectMode]=\"'single'\" [showIcons]=\"false\"\n [showChildrenBadge]=\"true\" [dragBehavior]=\"'none'\" look=\"default\" [nodeTemplate]=\"nodeTemplate\"\n (onNodeClick)=\"onNodeClick($event)\" (onNodeToggle)=\"onNodeToggle($event)\" />\n }\n </axp-layout-content>\n </axp-layout-start-side>\n\n <axp-page-content class=\"min-h-0 pt-0\">\n @if (selectedNode()) {\n <axp-platform-explorer-detail [node]=\"selectedNode()!\" />\n } @else {\n <p class=\"axp-platform-explorer__hint\">{{ '@platform-dev-tools:module.messages.select-node' | translate | async }}\n </p>\n }\n </axp-page-content>\n</axp-page-layout>\n\n<!-- Node template: icon per kind (with color) + label (translated) + badge -->\n<ng-template #nodeTemplate let-node=\"node\">\n @let data = node['data'];\n @let treeNode = $safeNavigationMigration(data?.treeNode);\n @let kind = $safeNavigationMigration(treeNode?.kind);\n @let count = node['childrenCount'] ?? treeNode?.itemCount;\n <span class=\"axp-platform-explorer__node\">\n @switch (kind) {\n @case ('module') {\n <i class=\"axp-platform-explorer__node-icon axp-platform-explorer__node-icon--module fa-light fa-cube\"\n aria-hidden=\"true\"></i>\n }\n @case ('entities') {\n <i class=\"axp-platform-explorer__node-icon axp-platform-explorer__node-icon--entities fa-light fa-table-list\"\n aria-hidden=\"true\"></i>\n }\n @case ('entity') {\n <i class=\"axp-platform-explorer__node-icon axp-platform-explorer__node-icon--entity fa-light fa-table\"\n aria-hidden=\"true\"></i>\n }\n @case ('permissions') {\n <i class=\"axp-platform-explorer__node-icon axp-platform-explorer__node-icon--permissions fa-light fa-shield-halved\"\n aria-hidden=\"true\"></i>\n }\n @case ('features') {\n <i class=\"axp-platform-explorer__node-icon axp-platform-explorer__node-icon--features fa-light fa-sliders\"\n aria-hidden=\"true\"></i>\n }\n @default {\n <i class=\"axp-platform-explorer__node-icon axp-platform-explorer__node-icon--default fa-light fa-circle-dot\"\n aria-hidden=\"true\"></i>\n }\n }\n <span class=\"axp-platform-explorer__node-label\">{{ node['title'] | translate | async }}</span>\n @if (count != null && count > 0) {\n <span class=\"axp-platform-explorer__node-badge\">{{ count }}</span>\n }\n </span>\n</ng-template>", styles: ["@layer properties;.axp-platform-explorer .axp-platform-explorer__tree-wrap{display:flex;min-height:0px;min-width:calc(var(--spacing, .25rem) * 64);flex-direction:column;overflow-x:auto;overflow-y:auto;padding:calc(var(--spacing, .25rem) * 2);padding-inline:calc(var(--spacing, .25rem) * 4);max-height:calc(100vh - 180px)}.axp-platform-explorer .axp-platform-explorer__loading,.axp-platform-explorer .axp-platform-explorer__empty{margin:0;padding:calc(var(--spacing, .25rem) * 4);color:var(--color-neutral-500, oklch(55.6% 0 none))}.axp-platform-explorer .axp-platform-explorer__hint{padding:calc(var(--spacing, .25rem) * 6);color:var(--color-neutral-500, oklch(55.6% 0 none))}.axp-platform-explorer .axp-platform-explorer__node{display:flex;width:100%;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-platform-explorer .axp-platform-explorer__node-icon{width:1em;flex-shrink:0}.axp-platform-explorer .axp-platform-explorer__node-icon--module{color:rgba(var(--ax-sys-color-primary-surface))}.axp-platform-explorer .axp-platform-explorer__node-icon--entities{color:var(--color-neutral-500, oklch(55.6% 0 none))}.axp-platform-explorer .axp-platform-explorer__node-icon--entity{color:rgba(var(--ax-sys-color-accent1-surface))}.axp-platform-explorer .axp-platform-explorer__node-icon--permissions{color:rgba(var(--ax-sys-color-success-surface))}.axp-platform-explorer .axp-platform-explorer__node-icon--features{color:rgba(var(--ax-sys-color-warning-surface))}.axp-platform-explorer .axp-platform-explorer__node-icon--default{color:var(--color-neutral-500, oklch(55.6% 0 none))}.axp-platform-explorer .axp-platform-explorer__node-label{min-width:0px;flex:1;white-space:nowrap}.axp-platform-explorer .axp-platform-explorer__node-badge{margin-left:auto;min-width:calc(var(--spacing, .25rem) * 5);flex-shrink:0;border-radius:calc(infinity * 1px);padding-inline:calc(var(--spacing, .25rem) * 1.5);text-align:center;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: calc(var(--spacing, .25rem) * 5);line-height:calc(var(--spacing, .25rem) * 5);--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);background-color:rgba(var(--ax-sys-color-primary-lightest-surface));color:rgba(var(--ax-sys-color-primary-surface))}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-leading: initial;--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPPageLayoutComponent, selector: "axp-page-layout" }, { kind: "component", type: AXPThemeLayoutStartSideComponent, selector: "axp-layout-page-start-side, axp-layout-start-side" }, { kind: "component", type: AXPThemeLayoutHeaderComponent, selector: "axp-layout-header" }, { 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: AXTreeViewComponent, selector: "ax-tree-view", inputs: ["datasource", "selectMode", "selectionBehavior", "dragArea", "dragBehavior", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "look", "nodeTemplate", "idField", "titleField", "tooltipField", "iconField", "expandedField", "selectedField", "indeterminateField", "disabledField", "hiddenField", "childrenField", "childrenCountField", "dataField", "inheritDisabled", "expandOnDoubleClick", "doubleClickDuration", "tooltipDelay", "controlledSelection", "selectedIds"], outputs: ["datasourceChange", "selectedIdsChange", "onBeforeDrop", "onNodeToggle", "onNodeSelect", "onNodeDoubleClick", "onNodeClick", "onSelectionChange", "onOrderChange", "onMoveChange", "onItemsChange"] }, { kind: "component", type: AXPlatformExplorerDetailComponent, selector: "axp-platform-explorer-detail", inputs: ["node"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
842
+ }
843
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPlatformExplorerPageComponent, decorators: [{
844
+ type: Component,
845
+ args: [{ selector: 'axp-platform-explorer-page', standalone: true, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
846
+ CommonModule,
847
+ AXTranslationModule,
848
+ AXPPageLayoutComponent,
849
+ AXPThemeLayoutStartSideComponent,
850
+ AXPThemeLayoutHeaderComponent,
851
+ AXPThemeLayoutBlockComponent,
852
+ AXTreeViewComponent,
853
+ AXPlatformExplorerDetailComponent,
854
+ ], providers: [
855
+ PlatformExplorerDataService,
856
+ {
857
+ provide: AXPPageLayoutBase,
858
+ useExisting: AXPlatformExplorerPageComponent,
859
+ },
860
+ ], template: "<axp-page-layout>\n <axp-layout-start-side>\n <axp-layout-header>\n <axp-layout-title>{{ '@platform-dev-tools:module.menus.platform-explorer.title' | translate | async\n }}</axp-layout-title>\n </axp-layout-header>\n <axp-layout-content class=\"axp-platform-explorer__tree-wrap\">\n @if (loading()) {\n <p class=\"axp-platform-explorer__loading\">Loading...</p>\n } @else if (moduleNodes().length === 0) {\n <p class=\"axp-platform-explorer__empty\">{{ '@platform-dev-tools:module.messages.no-modules' | translate | async }}\n </p>\n } @else {\n <ax-tree-view #tree [datasource]=\"datasource\" [selectMode]=\"'single'\" [showIcons]=\"false\"\n [showChildrenBadge]=\"true\" [dragBehavior]=\"'none'\" look=\"default\" [nodeTemplate]=\"nodeTemplate\"\n (onNodeClick)=\"onNodeClick($event)\" (onNodeToggle)=\"onNodeToggle($event)\" />\n }\n </axp-layout-content>\n </axp-layout-start-side>\n\n <axp-page-content class=\"min-h-0 pt-0\">\n @if (selectedNode()) {\n <axp-platform-explorer-detail [node]=\"selectedNode()!\" />\n } @else {\n <p class=\"axp-platform-explorer__hint\">{{ '@platform-dev-tools:module.messages.select-node' | translate | async }}\n </p>\n }\n </axp-page-content>\n</axp-page-layout>\n\n<!-- Node template: icon per kind (with color) + label (translated) + badge -->\n<ng-template #nodeTemplate let-node=\"node\">\n @let data = node['data'];\n @let treeNode = $safeNavigationMigration(data?.treeNode);\n @let kind = $safeNavigationMigration(treeNode?.kind);\n @let count = node['childrenCount'] ?? treeNode?.itemCount;\n <span class=\"axp-platform-explorer__node\">\n @switch (kind) {\n @case ('module') {\n <i class=\"axp-platform-explorer__node-icon axp-platform-explorer__node-icon--module fa-light fa-cube\"\n aria-hidden=\"true\"></i>\n }\n @case ('entities') {\n <i class=\"axp-platform-explorer__node-icon axp-platform-explorer__node-icon--entities fa-light fa-table-list\"\n aria-hidden=\"true\"></i>\n }\n @case ('entity') {\n <i class=\"axp-platform-explorer__node-icon axp-platform-explorer__node-icon--entity fa-light fa-table\"\n aria-hidden=\"true\"></i>\n }\n @case ('permissions') {\n <i class=\"axp-platform-explorer__node-icon axp-platform-explorer__node-icon--permissions fa-light fa-shield-halved\"\n aria-hidden=\"true\"></i>\n }\n @case ('features') {\n <i class=\"axp-platform-explorer__node-icon axp-platform-explorer__node-icon--features fa-light fa-sliders\"\n aria-hidden=\"true\"></i>\n }\n @default {\n <i class=\"axp-platform-explorer__node-icon axp-platform-explorer__node-icon--default fa-light fa-circle-dot\"\n aria-hidden=\"true\"></i>\n }\n }\n <span class=\"axp-platform-explorer__node-label\">{{ node['title'] | translate | async }}</span>\n @if (count != null && count > 0) {\n <span class=\"axp-platform-explorer__node-badge\">{{ count }}</span>\n }\n </span>\n</ng-template>", styles: ["@layer properties;.axp-platform-explorer .axp-platform-explorer__tree-wrap{display:flex;min-height:0px;min-width:calc(var(--spacing, .25rem) * 64);flex-direction:column;overflow-x:auto;overflow-y:auto;padding:calc(var(--spacing, .25rem) * 2);padding-inline:calc(var(--spacing, .25rem) * 4);max-height:calc(100vh - 180px)}.axp-platform-explorer .axp-platform-explorer__loading,.axp-platform-explorer .axp-platform-explorer__empty{margin:0;padding:calc(var(--spacing, .25rem) * 4);color:var(--color-neutral-500, oklch(55.6% 0 none))}.axp-platform-explorer .axp-platform-explorer__hint{padding:calc(var(--spacing, .25rem) * 6);color:var(--color-neutral-500, oklch(55.6% 0 none))}.axp-platform-explorer .axp-platform-explorer__node{display:flex;width:100%;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-platform-explorer .axp-platform-explorer__node-icon{width:1em;flex-shrink:0}.axp-platform-explorer .axp-platform-explorer__node-icon--module{color:rgba(var(--ax-sys-color-primary-surface))}.axp-platform-explorer .axp-platform-explorer__node-icon--entities{color:var(--color-neutral-500, oklch(55.6% 0 none))}.axp-platform-explorer .axp-platform-explorer__node-icon--entity{color:rgba(var(--ax-sys-color-accent1-surface))}.axp-platform-explorer .axp-platform-explorer__node-icon--permissions{color:rgba(var(--ax-sys-color-success-surface))}.axp-platform-explorer .axp-platform-explorer__node-icon--features{color:rgba(var(--ax-sys-color-warning-surface))}.axp-platform-explorer .axp-platform-explorer__node-icon--default{color:var(--color-neutral-500, oklch(55.6% 0 none))}.axp-platform-explorer .axp-platform-explorer__node-label{min-width:0px;flex:1;white-space:nowrap}.axp-platform-explorer .axp-platform-explorer__node-badge{margin-left:auto;min-width:calc(var(--spacing, .25rem) * 5);flex-shrink:0;border-radius:calc(infinity * 1px);padding-inline:calc(var(--spacing, .25rem) * 1.5);text-align:center;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: calc(var(--spacing, .25rem) * 5);line-height:calc(var(--spacing, .25rem) * 5);--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);background-color:rgba(var(--ax-sys-color-primary-lightest-surface));color:rgba(var(--ax-sys-color-primary-surface))}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-leading: initial;--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
861
+ }], ctorParameters: () => [], propDecorators: { tree: [{ type: i0.ViewChild, args: ['tree', { isSignal: true }] }] } });
862
+
863
+ //#region ---- Imports ----
864
+ //#endregion
865
+ //#region ---- Component ----
866
+ class AXPlatformExplorerTreeNodeComponent {
867
+ constructor() {
868
+ this.node = input.required(/* @ts-ignore */
869
+ ...(ngDevMode ? [{ debugName: "node" }] : /* istanbul ignore next */ []));
870
+ this.selectedId = input(null, /* @ts-ignore */
871
+ ...(ngDevMode ? [{ debugName: "selectedId" }] : /* istanbul ignore next */ []));
872
+ this.nodeSelect = output();
873
+ this.expanded = signal(true, /* @ts-ignore */
874
+ ...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
875
+ }
876
+ childrenLength() {
877
+ return this.node().children?.length ?? 0;
878
+ }
879
+ hasChildren() {
880
+ const children = this.node().children;
881
+ return !!children && children.length > 0;
882
+ }
883
+ isSelected() {
884
+ return this.selectedId() === this.node().id;
885
+ }
886
+ toggle() {
887
+ if (this.hasChildren()) {
888
+ this.expanded.update((v) => !v);
889
+ }
890
+ }
891
+ select() {
892
+ this.nodeSelect.emit(this.node());
893
+ }
894
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPlatformExplorerTreeNodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
895
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPlatformExplorerTreeNodeComponent, isStandalone: true, selector: "axp-platform-explorer-tree-node", inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null }, selectedId: { classPropertyName: "selectedId", publicName: "selectedId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nodeSelect: "nodeSelect" }, ngImport: i0, template: `
896
+ <div class="axp-tree-node" [class.axp-tree-node--selected]="isSelected()">
897
+ <button
898
+ type="button"
899
+ class="axp-tree-node__toggler"
900
+ [class.axp-tree-node__toggler--open]="expanded()"
901
+ [attr.aria-expanded]="expanded()"
902
+ (click)="toggle()"
903
+ >
904
+ @if (hasChildren()) {
905
+ <span class="axp-tree-node__icon" aria-hidden="true">{{ expanded() ? '▼' : '▶' }}</span>
906
+ } @else {
907
+ <span class="axp-tree-node__icon axp-tree-node__icon--empty"></span>
908
+ }
909
+ </button>
910
+ <button
911
+ type="button"
912
+ class="axp-tree-node__label"
913
+ (click)="select()"
914
+ >
915
+ {{ node().label }}
916
+ @if (childrenLength() > 0) {
917
+ <span class="axp-tree-node__badge">({{ childrenLength() }})</span>
918
+ }
919
+ </button>
920
+ </div>
921
+ @if (hasChildren() && expanded()) {
922
+ <div class="axp-tree-node__children">
923
+ @for (child of node().children ?? []; track child.id) {
924
+ <axp-platform-explorer-tree-node
925
+ [node]="child"
926
+ [selectedId]="selectedId()"
927
+ (nodeSelect)="nodeSelect.emit($event)"
928
+ />
929
+ }
930
+ </div>
931
+ }
932
+ `, isInline: true, styles: [":host{display:block}.axp-tree-node{display:flex;align-items:center;min-height:28px}.axp-tree-node--selected .axp-tree-node__label{font-weight:600;background:var(--ax-neutral-surface-hover, rgba(0, 0, 0, .04))}.axp-tree-node__toggler{width:24px;height:28px;padding:0;border:none;background:none;cursor:pointer;color:var(--ax-neutral-text-secondary, #666);flex-shrink:0}.axp-tree-node__toggler--open .axp-tree-node__icon{transform:rotate(0)}.axp-tree-node__icon{font-size:10px;display:inline-block}.axp-tree-node__icon--empty{width:10px}.axp-tree-node__label{flex:1;text-align:start;padding:4px 8px;border:none;background:none;cursor:pointer;font-size:13px;border-radius:4px}.axp-tree-node__label:hover{background:var(--ax-neutral-surface-hover, rgba(0, 0, 0, .04))}.axp-tree-node__badge{margin-inline-start:4px;font-size:11px;color:var(--ax-neutral-text-secondary, #666);font-weight:400}.axp-tree-node__children{padding-inline-start:16px}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXPlatformExplorerTreeNodeComponent, selector: "axp-platform-explorer-tree-node", inputs: ["node", "selectedId"], outputs: ["nodeSelect"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
933
+ }
934
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPlatformExplorerTreeNodeComponent, decorators: [{
935
+ type: Component,
936
+ args: [{ selector: 'axp-platform-explorer-tree-node', standalone: true, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXPlatformExplorerTreeNodeComponent], template: `
937
+ <div class="axp-tree-node" [class.axp-tree-node--selected]="isSelected()">
938
+ <button
939
+ type="button"
940
+ class="axp-tree-node__toggler"
941
+ [class.axp-tree-node__toggler--open]="expanded()"
942
+ [attr.aria-expanded]="expanded()"
943
+ (click)="toggle()"
944
+ >
945
+ @if (hasChildren()) {
946
+ <span class="axp-tree-node__icon" aria-hidden="true">{{ expanded() ? '▼' : '▶' }}</span>
947
+ } @else {
948
+ <span class="axp-tree-node__icon axp-tree-node__icon--empty"></span>
949
+ }
950
+ </button>
951
+ <button
952
+ type="button"
953
+ class="axp-tree-node__label"
954
+ (click)="select()"
955
+ >
956
+ {{ node().label }}
957
+ @if (childrenLength() > 0) {
958
+ <span class="axp-tree-node__badge">({{ childrenLength() }})</span>
959
+ }
960
+ </button>
961
+ </div>
962
+ @if (hasChildren() && expanded()) {
963
+ <div class="axp-tree-node__children">
964
+ @for (child of node().children ?? []; track child.id) {
965
+ <axp-platform-explorer-tree-node
966
+ [node]="child"
967
+ [selectedId]="selectedId()"
968
+ (nodeSelect)="nodeSelect.emit($event)"
969
+ />
970
+ }
971
+ </div>
972
+ }
973
+ `, styles: [":host{display:block}.axp-tree-node{display:flex;align-items:center;min-height:28px}.axp-tree-node--selected .axp-tree-node__label{font-weight:600;background:var(--ax-neutral-surface-hover, rgba(0, 0, 0, .04))}.axp-tree-node__toggler{width:24px;height:28px;padding:0;border:none;background:none;cursor:pointer;color:var(--ax-neutral-text-secondary, #666);flex-shrink:0}.axp-tree-node__toggler--open .axp-tree-node__icon{transform:rotate(0)}.axp-tree-node__icon{font-size:10px;display:inline-block}.axp-tree-node__icon--empty{width:10px}.axp-tree-node__label{flex:1;text-align:start;padding:4px 8px;border:none;background:none;cursor:pointer;font-size:13px;border-radius:4px}.axp-tree-node__label:hover{background:var(--ax-neutral-surface-hover, rgba(0, 0, 0, .04))}.axp-tree-node__badge{margin-inline-start:4px;font-size:11px;color:var(--ax-neutral-text-secondary, #666);font-weight:400}.axp-tree-node__children{padding-inline-start:16px}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
974
+ }], propDecorators: { node: [{ type: i0.Input, args: [{ isSignal: true, alias: "node", required: true }] }], selectedId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedId", required: false }] }], nodeSelect: [{ type: i0.Output, args: ["nodeSelect"] }] } });
975
+
976
+ //#region ---- Imports ----
977
+ //#endregion
978
+ //#region ---- Routes ----
979
+ function routesFactory() {
980
+ return [
981
+ {
982
+ path: ':app/dev/platform-explorer',
983
+ canActivate: [AXPAuthGuard],
984
+ data: { rootLayout: true },
985
+ loadComponent: () => AXPRootLayoutComponent,
986
+ children: [
987
+ {
988
+ path: '',
989
+ loadComponent: () => AXPlatformExplorerPageComponent,
990
+ data: { reuse: true },
991
+ },
992
+ ],
993
+ },
994
+ ];
995
+ }
996
+ //#endregion
997
+ //#region ---- Module ----
998
+ class AXMPlatformDevToolsModule {
999
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMPlatformDevToolsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1000
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AXMPlatformDevToolsModule }); }
1001
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMPlatformDevToolsModule, providers: [
1002
+ {
1003
+ provide: AXP_MODULE_MANIFEST_PROVIDER,
1004
+ useValue: PlatformDevToolsManifest,
1005
+ multi: true,
1006
+ },
1007
+ {
1008
+ provide: AXP_PERMISSION_DEFINITION_PROVIDER,
1009
+ useClass: AXMPermissionDefinitionProvider,
1010
+ multi: true,
1011
+ },
1012
+ provideLazyProvider(AXP_MENU_PROVIDER, () => import('./acorex-platform-module-platform-dev-tools-client-menu.provider-RHLrPSuX.mjs').then(m => m.AXMPlatformDevToolsMenuProvider)),
1013
+ {
1014
+ provide: AXP_SETTING_DEFINITION_PROVIDER,
1015
+ useClass: AXPPlatformDevToolsSettingProvider,
1016
+ multi: true,
1017
+ },
1018
+ {
1019
+ provide: ROUTES,
1020
+ multi: true,
1021
+ useFactory: routesFactory,
1022
+ },
1023
+ ] }); }
1024
+ }
1025
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMPlatformDevToolsModule, decorators: [{
1026
+ type: NgModule,
1027
+ args: [{
1028
+ imports: [],
1029
+ exports: [],
1030
+ declarations: [],
1031
+ providers: [
1032
+ {
1033
+ provide: AXP_MODULE_MANIFEST_PROVIDER,
1034
+ useValue: PlatformDevToolsManifest,
1035
+ multi: true,
1036
+ },
1037
+ {
1038
+ provide: AXP_PERMISSION_DEFINITION_PROVIDER,
1039
+ useClass: AXMPermissionDefinitionProvider,
1040
+ multi: true,
1041
+ },
1042
+ provideLazyProvider(AXP_MENU_PROVIDER, () => import('./acorex-platform-module-platform-dev-tools-client-menu.provider-RHLrPSuX.mjs').then(m => m.AXMPlatformDevToolsMenuProvider)),
1043
+ {
1044
+ provide: AXP_SETTING_DEFINITION_PROVIDER,
1045
+ useClass: AXPPlatformDevToolsSettingProvider,
1046
+ multi: true,
1047
+ },
1048
+ {
1049
+ provide: ROUTES,
1050
+ multi: true,
1051
+ useFactory: routesFactory,
1052
+ },
1053
+ ],
1054
+ }]
1055
+ }] });
1056
+
1057
+ /**
1058
+ * Generated bundle index. Do not edit.
1059
+ */
1060
+
1061
+ export { AXMPermissionDefinitionProvider, AXMPlatformDevToolsModule, AXPlatformExplorerDetailComponent, AXPlatformExplorerEntityDetailComponent, AXPlatformExplorerFeaturesListDetailComponent, AXPlatformExplorerModuleDetailComponent, AXPlatformExplorerPageComponent, AXPlatformExplorerPermissionsListDetailComponent, AXPlatformExplorerTreeNodeComponent, PlatformDevToolsManifest, PlatformExplorerDataService };
1062
+ //# sourceMappingURL=acorex-platform-module-platform-dev-tools-client.mjs.map