@acorex/modules 20.0.21 → 20.0.22

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,478 @@
1
+ import { AXBadgeModule } from '@acorex/components/badge';
2
+ import { AXBreadcrumbsModule } from '@acorex/components/breadcrumbs';
3
+ import { AXButtonModule } from '@acorex/components/button';
4
+ import * as i4 from '@acorex/components/decorators';
5
+ import { AXDecoratorModule } from '@acorex/components/decorators';
6
+ import { AXDropdownButtonModule } from '@acorex/components/dropdown-button';
7
+ import { AXLoadingModule } from '@acorex/components/loading';
8
+ import * as i3 from '@acorex/components/search-box';
9
+ import { AXSearchBoxModule } from '@acorex/components/search-box';
10
+ import { AXTabsModule } from '@acorex/components/tabs';
11
+ import * as i5 from '@acorex/core/translation';
12
+ import { AXTranslationService, AXTranslationModule } from '@acorex/core/translation';
13
+ import { AXUnsubscriber } from '@acorex/core/utils';
14
+ import { AXPReportDefinitionService } from '@acorex/platform/common';
15
+ import { AXPThemeLayoutBlockComponent, AXPThemeLayoutToolbarComponent, AXPThemeLayoutHeaderComponent, AXPThemeLayoutStartSideComponent } from '@acorex/platform/layout/components';
16
+ import { AXPPageLayoutBaseComponent, AXPPageLayoutComponent, AXPPageLayoutBase } from '@acorex/platform/layout/views';
17
+ import { AXPLayoutThemeService } from '@acorex/platform/themes/shared';
18
+ import * as i1 from '@angular/common';
19
+ import { CommonModule } from '@angular/common';
20
+ import * as i0 from '@angular/core';
21
+ import { computed, inject, output, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
22
+ import * as i1$1 from '@angular/forms';
23
+ import { FormsModule } from '@angular/forms';
24
+ import { ActivatedRoute, Router, NavigationEnd, RouterModule } from '@angular/router';
25
+ import { merge, filter, startWith, firstValueFrom } from 'rxjs';
26
+ import { AXPPageStatus } from '@acorex/platform/layout/builder';
27
+ import { signalStore, withState, withComputed, withMethods, patchState, withHooks } from '@ngrx/signals';
28
+ import { isNil, isEmpty } from 'lodash-es';
29
+ import { AXLocaleService } from '@acorex/core/locale';
30
+ import { RootConfig } from './acorex-modules-report-management.mjs';
31
+ import * as i2 from '@acorex/components/tree-view';
32
+ import { AXTreeViewModule } from '@acorex/components/tree-view';
33
+ import { AXPWorkflowService } from '@acorex/platform/workflow';
34
+
35
+ const AXPReportRunnerRootViewModel = signalStore(withState(() => ({
36
+ activeCategory: undefined,
37
+ categories: [],
38
+ reports: [],
39
+ activeCategoriesPath: [],
40
+ //
41
+ searchExpression: null,
42
+ //
43
+ status: AXPPageStatus.Processing,
44
+ })), withComputed((store, layout = inject(AXPLayoutThemeService)) => ({
45
+ searchResults: computed(() => []),
46
+ hasActiveCategory: computed(() => store.activeCategory() != null),
47
+ showSideMenu: computed(() => layout.isLarge()),
48
+ isSearching: computed(() => store.searchExpression() != null),
49
+ isBusy: computed(() => store.status() == AXPPageStatus.Processing),
50
+ isLoaded: computed(() => store.activeCategory() != null),
51
+ title: computed(() => store.activeCategory()?.title ?? `@${RootConfig.config.i18n}:features.report-runner.page-title`),
52
+ description: computed(() => store.activeCategory()?.description ?? `@${RootConfig.config.i18n}:features.report-runner.page-description`),
53
+ })), withMethods((store, reportDefinitionService = inject(AXPReportDefinitionService)) => ({
54
+ async loadRootCategories() {
55
+ patchState(store, {
56
+ activeCategory: undefined,
57
+ reports: [],
58
+ activeCategoriesPath: [],
59
+ });
60
+ //
61
+ patchState(store, {
62
+ status: AXPPageStatus.Processing,
63
+ });
64
+ patchState(store, {
65
+ categories: await reportDefinitionService.getCategories(),
66
+ });
67
+ patchState(store, {
68
+ status: AXPPageStatus.Idle,
69
+ });
70
+ },
71
+ async getCategories(parentId) {
72
+ patchState(store, {
73
+ status: AXPPageStatus.Processing,
74
+ });
75
+ //
76
+ const result = await reportDefinitionService.getCategories(parentId);
77
+ //
78
+ patchState(store, {
79
+ status: AXPPageStatus.Idle,
80
+ });
81
+ //
82
+ return result;
83
+ },
84
+ async getReports(categoryId) {
85
+ patchState(store, {
86
+ status: AXPPageStatus.Processing,
87
+ });
88
+ //
89
+ const result = await reportDefinitionService.getReportsByCategoryId(categoryId);
90
+ //
91
+ patchState(store, {
92
+ status: AXPPageStatus.Idle,
93
+ });
94
+ //
95
+ return result;
96
+ },
97
+ async setActiveCategory(category) {
98
+ //
99
+ patchState(store, {
100
+ status: AXPPageStatus.Processing,
101
+ });
102
+ //
103
+ patchState(store, {
104
+ activeCategory: category,
105
+ });
106
+ //
107
+ patchState(store, {
108
+ categories: await reportDefinitionService.getCategories(category.id),
109
+ reports: await reportDefinitionService.getReportsByCategoryId(category.id),
110
+ activeCategoriesPath: await reportDefinitionService.getCategoriesPathById(category.id),
111
+ });
112
+ //
113
+ patchState(store, {
114
+ status: AXPPageStatus.Idle,
115
+ });
116
+ },
117
+ async setActiveCategoryById(id) {
118
+ //
119
+ patchState(store, {
120
+ status: AXPPageStatus.Processing,
121
+ });
122
+ //
123
+ const category = await reportDefinitionService.getCategoryById(id);
124
+ if (category) {
125
+ patchState(store, {
126
+ activeCategory: category,
127
+ });
128
+ //
129
+ patchState(store, {
130
+ categories: await reportDefinitionService.getCategories(category.id),
131
+ reports: await reportDefinitionService.getReportsByCategoryId(category.id),
132
+ activeCategoriesPath: await reportDefinitionService.getCategoriesPathById(category.id),
133
+ });
134
+ }
135
+ //
136
+ patchState(store, {
137
+ status: AXPPageStatus.Idle,
138
+ });
139
+ },
140
+ //
141
+ async search(expression) {
142
+ if (!isNil(expression) && !isEmpty(expression)) {
143
+ patchState(store, {
144
+ searchExpression: expression,
145
+ });
146
+ }
147
+ else {
148
+ patchState(store, {
149
+ searchExpression: null,
150
+ });
151
+ }
152
+ },
153
+ clearSearch() {
154
+ patchState(store, {
155
+ searchExpression: null,
156
+ });
157
+ },
158
+ })), withHooks((store, translationService = inject(AXTranslationService), localeService = inject(AXLocaleService)) => ({
159
+ async onInit() {
160
+ merge(translationService.langChanges$, localeService.profileChanged$).subscribe(async () => {
161
+ });
162
+ //
163
+ await store.loadRootCategories();
164
+ },
165
+ onDestroy() { },
166
+ })));
167
+
168
+ //#region ---- Imports ----
169
+ //#endregion
170
+ class AXPReportCategoriesTreeComponent {
171
+ constructor() {
172
+ //#region ---- Services & Dependencies ----
173
+ this.reportDefinitionService = inject(AXPReportDefinitionService);
174
+ //#endregion
175
+ //#region ---- Output Events ----
176
+ /**
177
+ * Emitted when a category node is clicked
178
+ */
179
+ this.categoryClick = output();
180
+ /**
181
+ * Emitted when a report node is clicked
182
+ */
183
+ this.reportClick = output();
184
+ //#endregion
185
+ //#region ---- Data Loading Methods ----
186
+ /**
187
+ * Provide lazy loading tree data
188
+ */
189
+ this.provideLazyTreeView = async (selectedItemId) => {
190
+ if (selectedItemId) {
191
+ const categories = (await this.reportDefinitionService.getCategories(selectedItemId)).map((item) => ({
192
+ id: item.id,
193
+ title: item.title,
194
+ hasChild: (item.hasChild || item.hasReport) ?? false,
195
+ item: item,
196
+ type: 'category',
197
+ expanded: isNil(item.parentId) ? true : false,
198
+ }));
199
+ const definitions = (await this.reportDefinitionService.getReportsByCategoryId(selectedItemId)).map((item) => ({
200
+ id: item.id,
201
+ title: item.title,
202
+ hasChild: false,
203
+ item: item,
204
+ type: 'definition',
205
+ expanded: false,
206
+ }));
207
+ return [...categories, ...definitions];
208
+ }
209
+ else {
210
+ const categories = await this.reportDefinitionService.getCategories();
211
+ const items = categories.map((item) => ({
212
+ id: item.id,
213
+ title: item.title,
214
+ hasChild: (item.hasChild || item.hasReport) ?? false,
215
+ item: item,
216
+ type: 'category',
217
+ expanded: false,
218
+ }));
219
+ return items;
220
+ }
221
+ };
222
+ }
223
+ //#endregion
224
+ //#region ---- Event Handlers ----
225
+ /**
226
+ * Handle tree node click events
227
+ */
228
+ async handleNodeClick(event) {
229
+ const node = event.data;
230
+ if (node.type === 'category') {
231
+ this.categoryClick.emit(node.item);
232
+ }
233
+ else if (node.type === 'definition') {
234
+ this.reportClick.emit(node.item);
235
+ }
236
+ }
237
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: AXPReportCategoriesTreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
238
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.7", type: AXPReportCategoriesTreeComponent, isStandalone: true, selector: "axp-report-categories-tree", outputs: { categoryClick: "categoryClick", reportClick: "reportClick" }, host: { classAttribute: "axp-report-categories-tree" }, ngImport: i0, template: "<ax-tree-view\n [showCheckbox]=\"false\"\n [itemTemplate]=\"itemTemplate\"\n [textField]=\"'title'\"\n [hasChildField]=\"'hasChild'\"\n [valueField]=\"'id'\"\n [expandedField]=\"'expanded'\"\n [items]=\"provideLazyTreeView\"\n (onNodeClick)=\"handleNodeClick($event)\"\n>\n</ax-tree-view>\n\n<ng-template #itemTemplate let-item>\n @if (item.type === 'category') {\n <ax-icon class=\"fas ax-text-warning fa-folder\"></ax-icon>\n } @else {\n <ax-icon class=\"fas ax-text-accent1 fa-file-chart-column\"></ax-icon>\n }\n {{ item.title }}\n</ng-template>\n", styles: [".axp-report-categories-tree{height:100%;width:100%}.axp-report-categories-tree .__tree-view .__item{display:flex;align-items:center;gap:.5rem}.axp-report-categories-tree .__tree-view .__item .__icon{flex-shrink:0}.axp-report-categories-tree .__tree-view .__item .__title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.axp-report-categories-tree .__tree-view .__item:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i4.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTreeViewModule }, { kind: "component", type: i2.AXTreeViewComponent, selector: "ax-tree-view", inputs: ["items", "showCheckbox", "hasCheckboxField", "selectionMode", "selectionBehavior", "selectionScope", "focusNodeEnabled", "valueField", "textField", "visibleField", "disableField", "hasChildField", "selectedField", "expandedField", "tooltipField", "childrenField", "activeField", "indeterminateField", "parentField", "iconField", "toggleIcons", "look", "showEmptyNodeMassage", "itemTemplate", "emptyTemplate", "expandOn"], outputs: ["onSelectionChanged", "onItemSelectedChanged", "onNodeClick", "onCollapsedChanged", "onNodedbClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
239
+ }
240
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: AXPReportCategoriesTreeComponent, decorators: [{
241
+ type: Component,
242
+ args: [{ selector: 'axp-report-categories-tree', standalone: true, imports: [
243
+ CommonModule,
244
+ AXDecoratorModule,
245
+ AXTreeViewModule,
246
+ ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { class: 'axp-report-categories-tree' }, template: "<ax-tree-view\n [showCheckbox]=\"false\"\n [itemTemplate]=\"itemTemplate\"\n [textField]=\"'title'\"\n [hasChildField]=\"'hasChild'\"\n [valueField]=\"'id'\"\n [expandedField]=\"'expanded'\"\n [items]=\"provideLazyTreeView\"\n (onNodeClick)=\"handleNodeClick($event)\"\n>\n</ax-tree-view>\n\n<ng-template #itemTemplate let-item>\n @if (item.type === 'category') {\n <ax-icon class=\"fas ax-text-warning fa-folder\"></ax-icon>\n } @else {\n <ax-icon class=\"fas ax-text-accent1 fa-file-chart-column\"></ax-icon>\n }\n {{ item.title }}\n</ng-template>\n", styles: [".axp-report-categories-tree{height:100%;width:100%}.axp-report-categories-tree .__tree-view .__item{display:flex;align-items:center;gap:.5rem}.axp-report-categories-tree .__tree-view .__item .__icon{flex-shrink:0}.axp-report-categories-tree .__tree-view .__item .__title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.axp-report-categories-tree .__tree-view .__item:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}\n"] }]
247
+ }] });
248
+
249
+ class AXMReportRunnerRootPageComponent extends AXPPageLayoutBaseComponent {
250
+ constructor() {
251
+ super(...arguments);
252
+ this.vm = inject(AXPReportRunnerRootViewModel);
253
+ this.layoutService = inject(AXPLayoutThemeService);
254
+ this.activatedRoute = inject(ActivatedRoute);
255
+ this.unsubscribe = inject(AXUnsubscriber);
256
+ this.reportDefinitionService = inject(AXPReportDefinitionService);
257
+ this.workflow = inject(AXPWorkflowService);
258
+ this.router = inject(Router);
259
+ this.baseRoutes = [this.sessionService.application?.name, 'report-management', 'reports'];
260
+ }
261
+ async ngOnInit() {
262
+ await super.ngOnInit();
263
+ //
264
+ this.router.events
265
+ .pipe(this.unsubscribe.takeUntilDestroy, filter((event) => event instanceof NavigationEnd), startWith(null))
266
+ .subscribe(async () => {
267
+ await this.loadFromRoute();
268
+ });
269
+ }
270
+ async loadFromRoute() {
271
+ const snapshot = this.activatedRoute.snapshot;
272
+ const segments = await firstValueFrom(this.activatedRoute.url);
273
+ let categoryId = segments[segments.length - 1]?.path ?? null;
274
+ if (categoryId) {
275
+ await this.vm.setActiveCategoryById(categoryId);
276
+ }
277
+ else {
278
+ await this.vm.loadRootCategories();
279
+ return;
280
+ }
281
+ //
282
+ let reportId = snapshot.queryParamMap.get('report') ?? null;
283
+ if (reportId) {
284
+ // Navigate directly to viewer instead of showing parameters
285
+ await this.navigateToViewer(reportId);
286
+ }
287
+ }
288
+ //#region ---- Event Handlers ----
289
+ /**
290
+ * Handle category selection from tree
291
+ */
292
+ async onCategoryClick(category) {
293
+ await this.navigateToCategory(category);
294
+ }
295
+ /**
296
+ * Handle report selection from tree
297
+ */
298
+ async onReportClick(report) {
299
+ await this.navigateToReport(report);
300
+ }
301
+ /**
302
+ * Navigate directly to report viewer with the selected report
303
+ */
304
+ async navigateToViewer(reportId) {
305
+ const baseViewerRoute = [this.sessionService.application?.name, 'report-management', 'viewer'];
306
+ await this.router.navigate(baseViewerRoute, {
307
+ queryParams: { reportId }
308
+ });
309
+ }
310
+ //#endregion
311
+ async navigateToCategory(category) {
312
+ // Find the path to this category
313
+ const path = await this.reportDefinitionService.getCategoriesPathById(category.id);
314
+ // Find the index of the target category in the path
315
+ let urlParts = [...this.baseRoutes];
316
+ for (const cat of path) {
317
+ urlParts.push(cat.id);
318
+ }
319
+ await this.router.navigate(urlParts);
320
+ }
321
+ async navigateToReport(report) {
322
+ // Navigate directly to viewer instead of showing parameters in runner
323
+ await this.navigateToViewer(report.id);
324
+ }
325
+ //#region ---- Page Configuration Overrides ----
326
+ async getPageBreadcrumbs() {
327
+ const path = this.vm.activeCategoriesPath();
328
+ const report = {
329
+ name: 'reports',
330
+ title: await this.translateService.translateAsync('@report-management:root-menu'),
331
+ command: {
332
+ name: 'navigate-to-reports-root',
333
+ },
334
+ };
335
+ if (!path || path.length === 0) {
336
+ return [report];
337
+ }
338
+ const breadcrumbs = [report];
339
+ let urlParts = [...this.baseRoutes];
340
+ for (const cat of path) {
341
+ urlParts = [...urlParts, cat.id];
342
+ breadcrumbs.push({
343
+ name: cat.id,
344
+ title: cat.title,
345
+ command: {
346
+ name: 'navigate-to-category',
347
+ options: {
348
+ category: cat,
349
+ },
350
+ },
351
+ });
352
+ }
353
+ return breadcrumbs;
354
+ }
355
+ async getSecondaryMenuItems() {
356
+ return [];
357
+ }
358
+ async getPageTitle() {
359
+ return this.vm.title();
360
+ }
361
+ async getPageDescription() {
362
+ return this.vm.description();
363
+ }
364
+ async getBackButton() {
365
+ const categoriesPath = this.vm.activeCategoriesPath();
366
+ if (!categoriesPath || categoriesPath.length === 0) {
367
+ // At root level, no back button
368
+ return null;
369
+ }
370
+ if (categoriesPath.length === 1) {
371
+ // At first level category, back to reports root
372
+ return {
373
+ title: await this.translateService.translateAsync('@report-management:root-menu'),
374
+ };
375
+ }
376
+ // At deeper level, back to parent category
377
+ const parentCategory = categoriesPath[categoriesPath.length - 2];
378
+ return {
379
+ title: parentCategory.title,
380
+ };
381
+ }
382
+ async onBackButtonClick() {
383
+ const categoriesPath = this.vm.activeCategoriesPath();
384
+ if (!categoriesPath || categoriesPath.length <= 1) {
385
+ // Navigate back to reports root
386
+ await this.router.navigate([...this.baseRoutes]);
387
+ }
388
+ else {
389
+ // Navigate to parent category
390
+ const parentCategoriesPath = categoriesPath.slice(0, -1);
391
+ let urlParts = [...this.baseRoutes];
392
+ for (const cat of parentCategoriesPath) {
393
+ urlParts.push(cat.id);
394
+ }
395
+ await this.router.navigate(urlParts);
396
+ }
397
+ }
398
+ async execute(command) {
399
+ switch (command.name) {
400
+ case 'navigate-to-category':
401
+ await this.navigateToCategory(command.options?.['category']);
402
+ break;
403
+ case 'navigate-to-reports-root':
404
+ await this.router.navigate([...this.baseRoutes]);
405
+ break;
406
+ case 'create-report':
407
+ await this.workflow.execute('report-create', {
408
+ data: {
409
+ categoryId: this.vm.activeCategory()?.id ?? null,
410
+ },
411
+ });
412
+ break;
413
+ }
414
+ }
415
+ async getPrimaryMenuItems() {
416
+ return [
417
+ {
418
+ title: 't("actions.create")',
419
+ icon: 'fa-light fa-plus',
420
+ color: 'primary',
421
+ command: {
422
+ name: 'create-report',
423
+ },
424
+ },
425
+ ];
426
+ }
427
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: AXMReportRunnerRootPageComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
428
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.7", type: AXMReportRunnerRootPageComponent, isStandalone: true, selector: "ng-component", host: { classAttribute: "axp-report-runner-root-page" }, providers: [
429
+ AXUnsubscriber,
430
+ AXPReportRunnerRootViewModel,
431
+ {
432
+ provide: AXPPageLayoutBase,
433
+ useExisting: AXMReportRunnerRootPageComponent,
434
+ },
435
+ ], usesInheritance: true, ngImport: i0, template: "<axp-page-layout *translate=\"let t\">\n @if (vm.showSideMenu()) {\n <axp-layout-start-side>\n <axp-layout-header>\n <axp-layout-title>{{ t('@report-management:features.report-runner.menu-title') | async }}</axp-layout-title>\n <axp-layout-toolbar>\n <ax-search-box\n [delayTime]=\"300\"\n [ngModel]=\"vm.searchExpression()\"\n (onValueChanged)=\"vm.search($event.value)\"\n [placeholder]=\"t('search.placeholder') | async\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n </axp-layout-toolbar>\n </axp-layout-header>\n <axp-layout-content>\n <axp-report-categories-tree (categoryClick)=\"onCategoryClick($event)\" (reportClick)=\"onReportClick($event)\" />\n </axp-layout-content>\n </axp-layout-start-side>\n }\n\n <axp-page-content>\n <!-- Desktop and Mobile: Always show browser template -->\n <ng-container *ngTemplateOutlet=\"browser\"> </ng-container>\n </axp-page-content>\n\n <!-- Desktop: Grid-based browser for main content -->\n <ng-template #browser>\n <div class=\"__reports-browser\">\n @if (vm.categories().length > 0) {\n <div class=\"__section\">\n <h3 class=\"__section-title\">Categories</h3>\n <div class=\"__items-grid\">\n @for (category of vm.categories(); track category.id) {\n <div class=\"__item __category\" (click)=\"navigateToCategory(category)\">\n <div class=\"__item-icon\">\n <ax-icon class=\"fa-solid fa-folder\"></ax-icon>\n </div>\n <div class=\"__item-content\">\n <div class=\"__item-title\">{{ category.title }}</div>\n @if (category.description) {\n <div class=\"__item-description\">{{ category.description }}</div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n @if (vm.reports().length > 0) {\n <div class=\"__section\">\n <h3 class=\"__section-title\">Reports</h3>\n <div class=\"__items-grid\">\n @for (report of vm.reports(); track report.id) {\n <div class=\"__item __report\" (click)=\"navigateToReport(report)\">\n <div class=\"__item-icon\">\n <ax-icon class=\"fa-solid fa-file-chart-column\"></ax-icon>\n </div>\n <div class=\"__item-content\">\n <div class=\"__item-title\">{{ report.title }}</div>\n @if (report.description) {\n <div class=\"__item-description\">{{ report.description }}</div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n @if (vm.categories().length === 0 && vm.reports().length === 0) {\n <div class=\"__empty-state\">\n <div class=\"__empty-icon\">\n <ax-icon class=\"fa-light fa-folder-open\"></ax-icon>\n </div>\n <div class=\"__empty-content\">\n <h4>No items found</h4>\n <p>There are no categories or reports available in this location.</p>\n </div>\n </div>\n }\n </div>\n </ng-template>\n</axp-page-layout>\n", styles: [".axp-report-runner-root-page axp-layout-start-side{height:100%;width:20rem;border-inline-end-width:1px;background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}@media (min-width: 1920px){.axp-report-runner-root-page axp-layout-start-side{width:24rem}}.axp-report-runner-root-page axp-layout-start-side axp-layout-content{overflow-x:auto;padding-left:1rem;padding-right:1rem}.axp-report-runner-root-page .__reports-browser>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem * var(--tw-space-y-reverse))}.axp-report-runner-root-page .__reports-browser{padding:.75rem}@media (min-width: 1024px){.axp-report-runner-root-page .__reports-browser{padding:1.5rem}}.axp-report-runner-root-page .__reports-browser .__section>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.axp-report-runner-root-page .__reports-browser .__section .__section-title{display:flex;align-items:center;gap:.5rem;font-size:1.125rem;line-height:1.75rem;font-weight:600}.axp-report-runner-root-page .__reports-browser .__section .__section-title ax-icon{--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-primary-500),var(--tw-text-opacity, 1))}.axp-report-runner-root-page .__reports-browser .__section .__items-grid{display:grid;grid-template-columns:repeat(1,minmax(0,1fr));gap:1rem}@media (min-width: 768px){.axp-report-runner-root-page .__reports-browser .__section .__items-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width: 1280px){.axp-report-runner-root-page .__reports-browser .__section .__items-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (min-width: 1536px){.axp-report-runner-root-page .__reports-browser .__section .__items-grid{grid-template-columns:repeat(4,minmax(0,1fr))}}@media (min-width: 2560px){.axp-report-runner-root-page .__reports-browser .__section .__items-grid{grid-template-columns:repeat(5,minmax(0,1fr))}}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item{cursor:pointer;border-radius:.5rem;border-width:1px;padding:1rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s;background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item{display:flex;align-items:flex-start;gap:.75rem}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item .__item-icon{display:flex;height:2.5rem;width:2.5rem;flex-shrink:0;align-items:center;justify-content:center;border-radius:.25rem;font-size:1.125rem;line-height:1.75rem}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item .__item-content{min-width:0px;flex:1 1 0%}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item .__item-content .__item-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item .__item-content .__item-description{margin-top:.25rem;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;font-size:.875rem;line-height:1.25rem;opacity:.75}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item.__category .__item-icon{background-color:rgba(var(--ax-sys-color-warning-500),.1)}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item.__category .__item-icon ax-icon{--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-warning-500),var(--tw-text-opacity, 1))}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item.__category:hover{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-warning-500),var(--tw-border-opacity, 1));background-color:rgba(var(--ax-sys-color-warning-500),.05)}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item.__report .__item-icon{background-color:rgba(var(--ax-sys-color-primary-500),.1)}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item.__report .__item-icon ax-icon{--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-primary-500),var(--tw-text-opacity, 1))}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item.__report:hover{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-primary-500),var(--tw-border-opacity, 1));background-color:rgba(var(--ax-sys-color-primary-500),.05)}.axp-report-runner-root-page .__reports-browser .__empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding-top:4rem;padding-bottom:4rem;text-align:center}.axp-report-runner-root-page .__reports-browser .__empty-state .__empty-icon{margin-bottom:1rem;font-size:3.75rem;line-height:1;opacity:.5}.axp-report-runner-root-page .__reports-browser .__empty-state .__empty-content h4{margin-bottom:.5rem;font-size:1.5rem;font-weight:500;line-height:1.5rem}.axp-report-runner-root-page .__reports-browser .__empty-state .__empty-content p{max-width:28rem;opacity:74%;display:block;font-size:1rem;font-weight:400;line-height:1.625rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type:
436
+ //
437
+ AXSearchBoxModule }, { kind: "component", type: i3.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i4.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i4.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "ngmodule", type: AXBreadcrumbsModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i5.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXTabsModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "component", type:
438
+ //
439
+ AXPPageLayoutComponent, selector: "axp-page-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: AXPThemeLayoutToolbarComponent, selector: "axp-layout-toolbar" }, { kind: "component", type: AXPThemeLayoutHeaderComponent, selector: "axp-layout-header" }, { kind: "component", type: AXPThemeLayoutStartSideComponent, selector: "axp-layout-page-start-side, axp-layout-start-side" }, { kind: "component", type:
440
+ //
441
+ AXPReportCategoriesTreeComponent, selector: "axp-report-categories-tree", outputs: ["categoryClick", "reportClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
442
+ }
443
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: AXMReportRunnerRootPageComponent, decorators: [{
444
+ type: Component,
445
+ args: [{ standalone: true, imports: [
446
+ CommonModule,
447
+ FormsModule,
448
+ RouterModule,
449
+ //
450
+ AXSearchBoxModule,
451
+ AXDecoratorModule,
452
+ AXBreadcrumbsModule,
453
+ AXTranslationModule,
454
+ AXButtonModule,
455
+ AXTabsModule,
456
+ AXBadgeModule,
457
+ AXLoadingModule,
458
+ AXDropdownButtonModule,
459
+ //
460
+ AXPPageLayoutComponent,
461
+ AXPThemeLayoutBlockComponent,
462
+ AXPThemeLayoutToolbarComponent,
463
+ AXPThemeLayoutHeaderComponent,
464
+ AXPThemeLayoutStartSideComponent,
465
+ //
466
+ AXPReportCategoriesTreeComponent,
467
+ ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
468
+ AXUnsubscriber,
469
+ AXPReportRunnerRootViewModel,
470
+ {
471
+ provide: AXPPageLayoutBase,
472
+ useExisting: AXMReportRunnerRootPageComponent,
473
+ },
474
+ ], host: { class: 'axp-report-runner-root-page' }, template: "<axp-page-layout *translate=\"let t\">\n @if (vm.showSideMenu()) {\n <axp-layout-start-side>\n <axp-layout-header>\n <axp-layout-title>{{ t('@report-management:features.report-runner.menu-title') | async }}</axp-layout-title>\n <axp-layout-toolbar>\n <ax-search-box\n [delayTime]=\"300\"\n [ngModel]=\"vm.searchExpression()\"\n (onValueChanged)=\"vm.search($event.value)\"\n [placeholder]=\"t('search.placeholder') | async\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n </axp-layout-toolbar>\n </axp-layout-header>\n <axp-layout-content>\n <axp-report-categories-tree (categoryClick)=\"onCategoryClick($event)\" (reportClick)=\"onReportClick($event)\" />\n </axp-layout-content>\n </axp-layout-start-side>\n }\n\n <axp-page-content>\n <!-- Desktop and Mobile: Always show browser template -->\n <ng-container *ngTemplateOutlet=\"browser\"> </ng-container>\n </axp-page-content>\n\n <!-- Desktop: Grid-based browser for main content -->\n <ng-template #browser>\n <div class=\"__reports-browser\">\n @if (vm.categories().length > 0) {\n <div class=\"__section\">\n <h3 class=\"__section-title\">Categories</h3>\n <div class=\"__items-grid\">\n @for (category of vm.categories(); track category.id) {\n <div class=\"__item __category\" (click)=\"navigateToCategory(category)\">\n <div class=\"__item-icon\">\n <ax-icon class=\"fa-solid fa-folder\"></ax-icon>\n </div>\n <div class=\"__item-content\">\n <div class=\"__item-title\">{{ category.title }}</div>\n @if (category.description) {\n <div class=\"__item-description\">{{ category.description }}</div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n @if (vm.reports().length > 0) {\n <div class=\"__section\">\n <h3 class=\"__section-title\">Reports</h3>\n <div class=\"__items-grid\">\n @for (report of vm.reports(); track report.id) {\n <div class=\"__item __report\" (click)=\"navigateToReport(report)\">\n <div class=\"__item-icon\">\n <ax-icon class=\"fa-solid fa-file-chart-column\"></ax-icon>\n </div>\n <div class=\"__item-content\">\n <div class=\"__item-title\">{{ report.title }}</div>\n @if (report.description) {\n <div class=\"__item-description\">{{ report.description }}</div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n @if (vm.categories().length === 0 && vm.reports().length === 0) {\n <div class=\"__empty-state\">\n <div class=\"__empty-icon\">\n <ax-icon class=\"fa-light fa-folder-open\"></ax-icon>\n </div>\n <div class=\"__empty-content\">\n <h4>No items found</h4>\n <p>There are no categories or reports available in this location.</p>\n </div>\n </div>\n }\n </div>\n </ng-template>\n</axp-page-layout>\n", styles: [".axp-report-runner-root-page axp-layout-start-side{height:100%;width:20rem;border-inline-end-width:1px;background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}@media (min-width: 1920px){.axp-report-runner-root-page axp-layout-start-side{width:24rem}}.axp-report-runner-root-page axp-layout-start-side axp-layout-content{overflow-x:auto;padding-left:1rem;padding-right:1rem}.axp-report-runner-root-page .__reports-browser>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem * var(--tw-space-y-reverse))}.axp-report-runner-root-page .__reports-browser{padding:.75rem}@media (min-width: 1024px){.axp-report-runner-root-page .__reports-browser{padding:1.5rem}}.axp-report-runner-root-page .__reports-browser .__section>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.axp-report-runner-root-page .__reports-browser .__section .__section-title{display:flex;align-items:center;gap:.5rem;font-size:1.125rem;line-height:1.75rem;font-weight:600}.axp-report-runner-root-page .__reports-browser .__section .__section-title ax-icon{--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-primary-500),var(--tw-text-opacity, 1))}.axp-report-runner-root-page .__reports-browser .__section .__items-grid{display:grid;grid-template-columns:repeat(1,minmax(0,1fr));gap:1rem}@media (min-width: 768px){.axp-report-runner-root-page .__reports-browser .__section .__items-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width: 1280px){.axp-report-runner-root-page .__reports-browser .__section .__items-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (min-width: 1536px){.axp-report-runner-root-page .__reports-browser .__section .__items-grid{grid-template-columns:repeat(4,minmax(0,1fr))}}@media (min-width: 2560px){.axp-report-runner-root-page .__reports-browser .__section .__items-grid{grid-template-columns:repeat(5,minmax(0,1fr))}}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item{cursor:pointer;border-radius:.5rem;border-width:1px;padding:1rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s;background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item{display:flex;align-items:flex-start;gap:.75rem}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item .__item-icon{display:flex;height:2.5rem;width:2.5rem;flex-shrink:0;align-items:center;justify-content:center;border-radius:.25rem;font-size:1.125rem;line-height:1.75rem}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item .__item-content{min-width:0px;flex:1 1 0%}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item .__item-content .__item-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item .__item-content .__item-description{margin-top:.25rem;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;font-size:.875rem;line-height:1.25rem;opacity:.75}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item.__category .__item-icon{background-color:rgba(var(--ax-sys-color-warning-500),.1)}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item.__category .__item-icon ax-icon{--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-warning-500),var(--tw-text-opacity, 1))}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item.__category:hover{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-warning-500),var(--tw-border-opacity, 1));background-color:rgba(var(--ax-sys-color-warning-500),.05)}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item.__report .__item-icon{background-color:rgba(var(--ax-sys-color-primary-500),.1)}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item.__report .__item-icon ax-icon{--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-primary-500),var(--tw-text-opacity, 1))}.axp-report-runner-root-page .__reports-browser .__section .__items-grid .__item.__report:hover{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-primary-500),var(--tw-border-opacity, 1));background-color:rgba(var(--ax-sys-color-primary-500),.05)}.axp-report-runner-root-page .__reports-browser .__empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding-top:4rem;padding-bottom:4rem;text-align:center}.axp-report-runner-root-page .__reports-browser .__empty-state .__empty-icon{margin-bottom:1rem;font-size:3.75rem;line-height:1;opacity:.5}.axp-report-runner-root-page .__reports-browser .__empty-state .__empty-content h4{margin-bottom:.5rem;font-size:1.5rem;font-weight:500;line-height:1.5rem}.axp-report-runner-root-page .__reports-browser .__empty-state .__empty-content p{max-width:28rem;opacity:74%;display:block;font-size:1rem;font-weight:400;line-height:1.625rem}\n"] }]
475
+ }] });
476
+
477
+ export { AXMReportRunnerRootPageComponent };
478
+ //# sourceMappingURL=acorex-modules-report-management-report-runner-root-page.component-C3UP9Jsi.mjs.map