@masterteam/dashboard-builder 0.0.22 → 0.0.24

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.
@@ -439,7 +439,7 @@ class DashboardStoreService {
439
439
  /** Dynamic key-value store */
440
440
  dynamicStore = signal({}, ...(ngDevMode ? [{ debugName: "dynamicStore" }] : /* istanbul ignore next */ []));
441
441
  /** Language code */
442
- languageCode = signal(document.dir == 'ltr' ? 'ar' : 'en', ...(ngDevMode ? [{ debugName: "languageCode" }] : /* istanbul ignore next */ []));
442
+ languageCode = signal(document.dir == 'rtl' ? 'ar' : 'en', ...(ngDevMode ? [{ debugName: "languageCode" }] : /* istanbul ignore next */ []));
443
443
  /** Direction */
444
444
  direction = signal(document.dir || 'ltr', ...(ngDevMode ? [{ debugName: "direction" }] : /* istanbul ignore next */ []));
445
445
  /** Inside Report Viewer flag - controls text truncation in charts */
@@ -9205,29 +9205,14 @@ class BarChartHandler {
9205
9205
  }
9206
9206
  if (isHorizontal) {
9207
9207
  if (languageCode === 'ar') {
9208
- lastItem.itemStyle.borderRadius = [
9209
- borderRadius,
9210
- 0,
9211
- 0,
9212
- borderRadius,
9213
- ];
9208
+ lastItem.itemStyle.borderRadius = [borderRadius, 0, 0, borderRadius];
9214
9209
  }
9215
9210
  else {
9216
- lastItem.itemStyle.borderRadius = [
9217
- 0,
9218
- borderRadius,
9219
- borderRadius,
9220
- 0,
9221
- ];
9211
+ lastItem.itemStyle.borderRadius = [0, borderRadius, borderRadius, 0];
9222
9212
  }
9223
9213
  }
9224
9214
  else {
9225
- lastItem.itemStyle.borderRadius = [
9226
- borderRadius,
9227
- borderRadius,
9228
- 0,
9229
- 0,
9230
- ];
9215
+ lastItem.itemStyle.borderRadius = [borderRadius, borderRadius, 0, 0];
9231
9216
  }
9232
9217
  }
9233
9218
  const xAxisLabels = xAxisData;
@@ -9270,7 +9255,9 @@ class BarChartHandler {
9270
9255
  * - number/string => that numeric value
9271
9256
  */
9272
9257
  resolveBarBorderRadius(borderRadius) {
9273
- if (borderRadius === undefined || borderRadius === null || borderRadius === true) {
9258
+ if (borderRadius === undefined ||
9259
+ borderRadius === null ||
9260
+ borderRadius === true) {
9274
9261
  return 8;
9275
9262
  }
9276
9263
  if (borderRadius === false) {
@@ -10114,7 +10101,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
10114
10101
  class StackBarChartHandler {
10115
10102
  storeService = inject(DashboardStoreService);
10116
10103
  resolveStackBarBorderRadius(borderRadius) {
10117
- if (borderRadius === undefined || borderRadius === null || borderRadius === true) {
10104
+ if (borderRadius === undefined ||
10105
+ borderRadius === null ||
10106
+ borderRadius === true) {
10118
10107
  return 8;
10119
10108
  }
10120
10109
  if (borderRadius === false) {
@@ -10776,7 +10765,8 @@ class StackBarChartHandler {
10776
10765
  if (!yAxis.axisLabel) {
10777
10766
  yAxis.axisLabel = {};
10778
10767
  }
10779
- yAxis.axisLabel.fontFamily = generalConfiguration?.fontConfig?.fontFamily;
10768
+ yAxis.axisLabel.fontFamily =
10769
+ generalConfiguration?.fontConfig?.fontFamily;
10780
10770
  if (!yAxis.axisLabel.formatter) {
10781
10771
  yAxis.axisLabel.formatter = (value) => {
10782
10772
  const yAxisFormat = stackBarOverride?.yAxisFormat;
@@ -19898,29 +19888,34 @@ class DashboardBuilder {
19898
19888
  this.dashboardService.getReportById(id).subscribe({
19899
19889
  next: (response) => {
19900
19890
  const report = response.data;
19901
- this.pageConfig.set(report);
19891
+ const normalizedFilters = this.normalizeFiltersConfig(report.dashboardConfig?.filters);
19892
+ const normalizedReport = {
19893
+ ...report,
19894
+ dashboardConfig: {
19895
+ ...(report.dashboardConfig ?? {}),
19896
+ filters: [...normalizedFilters],
19897
+ },
19898
+ };
19899
+ this.pageConfig.set(normalizedReport);
19902
19900
  // Handle chartLinks format from new API
19903
19901
  if (report.chartLinks && report.chartLinks.length > 0) {
19904
19902
  // New API: charts come from chartLinks
19905
19903
  const charts = report.chartLinks.map((link) => {
19906
- // Parse configration if it's a string
19907
- const configData = typeof link.configration === 'string'
19908
- ? JSON.parse(link.configration)
19909
- : link.configration;
19904
+ const configData = this.readSerializedObject(link.configration) ?? {};
19910
19905
  // Reconstruct DashboardChartItem structure
19911
19906
  // configData has: serviceConfig, clientConfig, x, y, cols, rows, chartTypeId, group, orderInGroup, dashboardId
19912
19907
  return {
19913
- x: configData.x ?? 0,
19914
- y: configData.y ?? 0,
19915
- cols: configData.cols ?? 3,
19916
- rows: configData.rows ?? 2,
19908
+ x: configData['x'] ?? 0,
19909
+ y: configData['y'] ?? 0,
19910
+ cols: configData['cols'] ?? 3,
19911
+ rows: configData['rows'] ?? 2,
19917
19912
  config: {
19918
- serviceConfig: configData.serviceConfig,
19919
- clientConfig: configData.clientConfig,
19913
+ serviceConfig: configData['serviceConfig'],
19914
+ clientConfig: configData['clientConfig'],
19920
19915
  },
19921
- chartTypeId: configData.chartTypeId,
19922
- group: configData.group,
19923
- orderInGroup: configData.orderInGroup,
19916
+ chartTypeId: configData['chartTypeId'],
19917
+ group: configData['group'],
19918
+ orderInGroup: configData['orderInGroup'],
19924
19919
  // Add link metadata
19925
19920
  id: link.id,
19926
19921
  chartComponentId: link.chartComponentId,
@@ -19928,22 +19923,15 @@ class DashboardBuilder {
19928
19923
  });
19929
19924
  this.charts.set(charts);
19930
19925
  this.dialogs.set([]);
19931
- const filters = report.dashboardConfig?.filters
19932
- ? typeof report.dashboardConfig.filters === 'string'
19933
- ? [JSON.parse(report.dashboardConfig.filters)]
19934
- : [report.dashboardConfig.filters]
19935
- : [];
19936
- this.filtersConfig.set(filters);
19937
19926
  }
19938
19927
  else {
19939
19928
  // No chart links yet
19940
19929
  this.charts.set([]);
19941
19930
  this.dialogs.set([]);
19942
- this.filtersConfig.set([]);
19943
19931
  }
19944
- this.dashboardService.filters.set(this.filtersConfig());
19932
+ this.setFiltersConfig(normalizedFilters);
19945
19933
  this.loading.set(false);
19946
- this.pageChange.emit(report);
19934
+ this.pageChange.emit(normalizedReport);
19947
19935
  this.chartsChange.emit(this.charts());
19948
19936
  },
19949
19937
  error: () => {
@@ -20000,10 +19988,8 @@ class DashboardBuilder {
20000
19988
  // Find matching response by dashboardId in configration
20001
19989
  const dashboardId = chart.config?.serviceConfig?.dashboardId;
20002
19990
  const matchingResponse = responseData.find((r) => {
20003
- const config = typeof r.configration === 'string'
20004
- ? JSON.parse(r.configration)
20005
- : r.configration;
20006
- return config?.dashboardId === dashboardId;
19991
+ const config = this.readSerializedObject(r.configration);
19992
+ return config?.['dashboardId'] === dashboardId;
20007
19993
  });
20008
19994
  if (matchingResponse) {
20009
19995
  return {
@@ -20832,8 +20818,7 @@ class DashboardBuilder {
20832
20818
  this.pageConfig.set(data.page ?? null);
20833
20819
  this.charts.set(data.charts ?? []);
20834
20820
  this.dialogs.set(data.dialogs ?? []);
20835
- this.filtersConfig.set(Array.isArray(filters) ? [...filters] : filters ? [filters] : []);
20836
- this.dashboardService.filters.set(this.filtersConfig());
20821
+ this.setFiltersConfig(filters);
20837
20822
  this.applyingDashboardData = false;
20838
20823
  this.cdr.detectChanges();
20839
20824
  }
@@ -20841,14 +20826,68 @@ class DashboardBuilder {
20841
20826
  if (!this.standalone())
20842
20827
  return;
20843
20828
  this.emittingDashboardData = true;
20829
+ const filters = [...this.filtersConfig()];
20830
+ const page = this.pageConfig();
20844
20831
  this.dashboardData.set({
20845
- page: this.pageConfig(),
20832
+ page: page
20833
+ ? {
20834
+ ...page,
20835
+ dashboardConfig: {
20836
+ ...(page.dashboardConfig ?? {}),
20837
+ filters,
20838
+ },
20839
+ }
20840
+ : null,
20846
20841
  charts: this.charts(),
20847
20842
  dialogs: this.dialogs(),
20848
- filters: this.filtersConfig(),
20843
+ filters,
20849
20844
  });
20850
20845
  this.emittingDashboardData = false;
20851
20846
  }
20847
+ setFiltersConfig(filters) {
20848
+ const normalizedFilters = this.normalizeFiltersConfig(filters);
20849
+ this.filtersConfig.set([...normalizedFilters]);
20850
+ this.dashboardService.filters.set(normalizedFilters);
20851
+ this.pageConfig.update((page) => page
20852
+ ? {
20853
+ ...page,
20854
+ dashboardConfig: {
20855
+ ...(page.dashboardConfig ?? {}),
20856
+ filters: [...normalizedFilters],
20857
+ },
20858
+ }
20859
+ : page);
20860
+ }
20861
+ normalizeFiltersConfig(filters) {
20862
+ const parsed = this.parseSerializedValue(filters);
20863
+ if (Array.isArray(parsed)) {
20864
+ return parsed;
20865
+ }
20866
+ return parsed ? [parsed] : [];
20867
+ }
20868
+ readSerializedObject(value) {
20869
+ const parsed = this.parseSerializedValue(value);
20870
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
20871
+ return null;
20872
+ }
20873
+ return parsed;
20874
+ }
20875
+ parseSerializedValue(value) {
20876
+ let current = value;
20877
+ while (typeof current === 'string') {
20878
+ const trimmed = current.trim();
20879
+ if (!trimmed) {
20880
+ return null;
20881
+ }
20882
+ try {
20883
+ current = JSON.parse(trimmed);
20884
+ }
20885
+ catch {
20886
+ return current;
20887
+ }
20888
+ }
20889
+ return current;
20890
+ }
20852
20891
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: DashboardBuilder, deps: [], target: i0.ɵɵFactoryTarget.Component });
20853
20892
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: DashboardBuilder, isStandalone: true, selector: "mt-dashboard-builder", inputs: { isPage: { classPropertyName: "isPage", publicName: "isPage", isSignal: true, isRequired: false, transformFunction: null }, pageTitle: { classPropertyName: "pageTitle", publicName: "pageTitle", isSignal: true, isRequired: false, transformFunction: null }, backButton: { classPropertyName: "backButton", publicName: "backButton", isSignal: true, isRequired: false, transformFunction: null }, pageId: { classPropertyName: "pageId", publicName: "pageId", isSignal: true, isRequired: false, transformFunction: null }, standalone: { classPropertyName: "standalone", publicName: "standalone", isSignal: true, isRequired: false, transformFunction: null }, services: { classPropertyName: "services", publicName: "services", isSignal: true, isRequired: false, transformFunction: null }, dashboardData: { classPropertyName: "dashboardData", publicName: "dashboardData", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, informativeContext: { classPropertyName: "informativeContext", publicName: "informativeContext", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dashboardData: "dashboardDataChange", pageChange: "pageChange", chartsChange: "chartsChange", onSave: "onSave", onBack: "onBack", onAddChart: "onAddChart", onEditChart: "onEditChart" }, host: { listeners: { "window:keydown": "onKeyDown($event)" } }, viewQueries: [{ propertyName: "contextMenu", first: true, predicate: ["contextMenu"], descendants: true, isSignal: true }, { propertyName: "gridsterContainer", first: true, predicate: ["gridsterContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <!-- Shared Actions Template -->\r\n <ng-template #actionsTemplate let-inPage=\"inPage\">\r\n <mt-button\r\n [label]=\"t('addWidget')\"\r\n icon=\"general.plus\"\r\n (onClick)=\"toggleWidgetPalette()\"\r\n severity=\"primary\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n\r\n <mt-button\r\n [label]=\"t('save')\"\r\n icon=\"general.save-02\"\r\n [loading]=\"saving()\"\r\n [disabled]=\"saving()\"\r\n (onClick)=\"saveDash()\"\r\n severity=\"primary\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n\r\n <span [class]=\"'w-px h-5 bg-surface-300'\"></span>\r\n\r\n <mt-button\r\n [icon]=\"stopActionsOnCards() ? 'media.play' : 'media.stop'\"\r\n [tooltip]=\"stopActionsOnCards() ? t('activateActions') : t('stopActions')\"\r\n (onClick)=\"stopAndActiveActions()\"\r\n [severity]=\"'warn'\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n\r\n <mt-button\r\n icon=\"general.edit-05\"\r\n [tooltip]=\"t('pageSettings')\"\r\n (onClick)=\"addOrEditPage(pageConfig()!)\"\r\n [severity]=\"'help'\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n\r\n <mt-button\r\n icon=\"general.filter-lines\"\r\n [tooltip]=\"t('manageFilter')\"\r\n (onClick)=\"openManageFilter()\"\r\n [severity]=\"'info'\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n </ng-template>\r\n\r\n <!-- Page mode -->\r\n @if (isPage()) {\r\n <mt-page\r\n [title]=\"\r\n pageTitle() ||\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n t('builder')\r\n \"\r\n [backButton]=\"backButton()\"\r\n (backButtonClick)=\"onBack.emit()\"\r\n >\r\n <!-- Header actions -->\r\n <ng-template #headerEnd>\r\n <div class=\"flex items-center gap-2\">\r\n <ng-container\r\n *ngTemplateOutlet=\"actionsTemplate; context: { inPage: true }\"\r\n />\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Content -->\r\n <ng-container *ngTemplateOutlet=\"builderContent\" />\r\n </mt-page>\r\n } @else {\r\n <!-- Non-page mode -->\r\n <ng-container *ngTemplateOutlet=\"builderContent\" />\r\n }\r\n\r\n <!-- Reusable builder content template -->\r\n <ng-template #builderContent>\r\n <div class=\"relative h-full min-h-[600px]\">\r\n <!-- Loading State -->\r\n @if (loading()) {\r\n <div class=\"flex items-center justify-center h-64\">\r\n <i class=\"mti mti-spinner-third mti-spin text-4xl text-primary\"></i>\r\n </div>\r\n }\r\n\r\n <!-- Main Content -->\r\n @if (!loading() && pageConfig()) {\r\n <!-- Fixed Actions Bar (only when NOT page mode) -->\r\n @if (!isPage()) {\r\n <div\r\n class=\"fixed bottom-4 left-1/2 -translate-x-1/2 z-50 flex items-center gap-2 bg-surface-0 rounded-full shadow-lg px-4 py-2 border border-surface-200\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"actionsTemplate; context: { inPage: false }\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Gridster Container -->\r\n <gridster\r\n #gridsterContainer\r\n [options]=\"options\"\r\n class=\"h-full min-h-[500px] bg-surface-50!\"\r\n [class.is-page]=\"isPage()\"\r\n [class.pointer-events-none]=\"readonly()\"\r\n (dragover)=\"onGridDragOver($event)\"\r\n (drop)=\"onGridDrop($event)\"\r\n >\r\n @for (chart of charts() | filterByGroup: undefined; track $index) {\r\n <gridster-item\r\n [item]=\"chart\"\r\n class=\"bg-surface-0 rounded-lg shadow-sm border border-surface-200 overflow-hidden transition-all duration-200 hover:shadow-md hover:border-surface-300\"\r\n [class.ring-2]=\"isSelected(chart)\"\r\n [class.ring-primary]=\"isSelected(chart)\"\r\n [class.ring-offset-2]=\"isSelected(chart)\"\r\n (click)=\"onSelect(chart, $event)\"\r\n >\r\n <!-- Chart Content -->\r\n <div class=\"h-full w-full relative group\">\r\n <!-- Drag Handle -->\r\n @if (!readonly()) {\r\n <div\r\n class=\"drag-handler absolute top-0 left-0 right-0 h-6 cursor-move bg-gradient-to-b from-black/10 to-transparent opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center z-10\"\r\n >\r\n <i\r\n class=\"mti mti-grip-horizontal text-white/70 text-sm\"\r\n ></i>\r\n </div>\r\n }\r\n\r\n <!-- Action Buttons -->\r\n @if (!readonly()) {\r\n <div\r\n class=\"absolute top-1 right-1 flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity z-20\"\r\n >\r\n <!-- Quick Manage Button -->\r\n @if (showQuickManageButton(chart)) {\r\n <mt-button\r\n icon=\"editor.palette\"\r\n [tooltip]=\"t('quickManage')\"\r\n (onClick)=\"openQuickManage($event, chart)\"\r\n severity=\"primary\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Breadcrumb Button (for topbar) -->\r\n @if (\r\n chart.config?.clientConfig?.componentName === \"topbar\"\r\n ) {\r\n <mt-button\r\n icon=\"general.slash-divider\"\r\n [tooltip]=\"t('manageBreadcrumb')\"\r\n (onClick)=\"openBreadcrumb(chart)\"\r\n severity=\"info\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Edit Button -->\r\n @if (\r\n chart.config?.clientConfig?.componentName !== \"header\" &&\r\n chart.config?.clientConfig?.componentName !== \"topbar\" &&\r\n chart.config?.clientConfig?.componentName !== \"Group\"\r\n ) {\r\n <mt-button\r\n icon=\"general.edit-05\"\r\n [tooltip]=\"t('edit')\"\r\n (onClick)=\"editItem(chart)\"\r\n severity=\"warn\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Delete Button -->\r\n @if (\r\n chart.config?.clientConfig?.componentName === \"Group\"\r\n ) {\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n [tooltip]=\"t('removeGroup')\"\r\n (onClick)=\"removeGroup(chart)\"\r\n severity=\"danger\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n } @else {\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n [tooltip]=\"t('delete')\"\r\n (onClick)=\"deleteItem(chart)\"\r\n severity=\"danger\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Advanced/Dialog Actions Button (pipe handles all conditions) -->\r\n @let dialogActions =\r\n chart | getChartActions: chartActionsContext;\r\n @if (dialogActions.length > 0) {\r\n <mt-button\r\n icon=\"general.dots-vertical\"\r\n [tooltip]=\"t('advanced')\"\r\n (onClick)=\"advancedPopover.toggle($event)\"\r\n severity=\"info\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n <p-popover #advancedPopover appendTo=\"body\">\r\n <div class=\"flex flex-col gap-1 min-w-[160px]\">\r\n @for (action of dialogActions; track action.label) {\r\n <mt-button\r\n [label]=\"action.label\"\r\n [icon]=\"action.icon\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"\r\n action.command?.({\r\n originalEvent: $event,\r\n item: action,\r\n });\r\n advancedPopover.hide()\r\n \"\r\n />\r\n }\r\n </div>\r\n </p-popover>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Chart Rendering -->\r\n @if (!chart.loading) {\r\n <mt-dashboard-item\r\n [config]=\"chart.config\"\r\n [chartTypeId]=\"chart.chartTypeId\"\r\n [readonly]=\"readonly()\"\r\n [pageName]=\"\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n pageConfig()?.name?.['ar'] ||\r\n ''\r\n \"\r\n />\r\n } @else {\r\n <div class=\"flex items-center justify-center h-full\">\r\n <i\r\n class=\"mti mti-spinner-third mti-spin text-2xl text-primary\"\r\n ></i>\r\n </div>\r\n }\r\n\r\n <!-- Group Children -->\r\n @if (chart.config?.clientConfig?.componentName === \"Group\") {\r\n <div class=\"h-full flex flex-col p-2\">\r\n @for (\r\n childChart of charts()\r\n | filterByGroup\r\n : chart.config?.serviceConfig?.dashboardId;\r\n track childChart.config?.serviceConfig?.dashboardId;\r\n let idx = $index\r\n ) {\r\n @if (idx === chart.selectedGroupIndex) {\r\n <div class=\"flex-1 min-h-0\">\r\n <mt-dashboard-item\r\n [config]=\"childChart.config\"\r\n [chartTypeId]=\"childChart.chartTypeId\"\r\n [readonly]=\"readonly()\"\r\n [pageName]=\"\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n pageConfig()?.name?.['ar'] ||\r\n ''\r\n \"\r\n />\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Group Tabs -->\r\n <div\r\n class=\"absolute bottom-0 left-0 right-0 flex gap-1 p-1 bg-surface-100 rounded-b-lg overflow-x-auto\"\r\n >\r\n @for (\r\n childChart of charts()\r\n | filterByGroup\r\n : chart.config?.serviceConfig?.dashboardId;\r\n track childChart.config?.serviceConfig?.dashboardId;\r\n let idx = $index\r\n ) {\r\n <mt-button\r\n [label]=\"\r\n childChart.config?.clientConfig?.title?.[\r\n languageCode()\r\n ] ||\r\n childChart.config?.clientConfig?.title?.['en'] ||\r\n 'Chart ' + (idx + 1)\r\n \"\r\n [severity]=\"\r\n idx === chart.selectedGroupIndex\r\n ? 'primary'\r\n : 'secondary'\r\n \"\r\n [text]=\"idx !== chart.selectedGroupIndex\"\r\n size=\"small\"\r\n (onClick)=\"chart.selectedGroupIndex = idx\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </gridster-item>\r\n }\r\n </gridster>\r\n\r\n <!-- Context Menu -->\r\n <p-contextMenu #contextMenu [model]=\"menuItems()\" appendTo=\"body\" />\r\n }\r\n\r\n <!-- Empty State -->\r\n @if (!loading() && !pageConfig()) {\r\n <div\r\n class=\"flex flex-col items-center justify-center h-64 text-muted-color\"\r\n >\r\n <i class=\"mti mti-layout text-6xl mb-4\"></i>\r\n <p class=\"text-lg\">{{ t(\"noPageSelected\") }}</p>\r\n <p class=\"text-sm\">{{ t(\"selectPageToStart\") }}</p>\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n</ng-container>\r\n", styles: [":host{display:block;height:100%}gridster{min-height:calc(100vh - 120px);height:100%}gridster .gridster-column{border-left:1px solid var(--p-primary-100)!important;border-right:1px solid var(--p-primary-100)!important}gridster .gridster-row{border-top:1px solid var(--p-primary-100)!important;border-bottom:1px solid var(--p-primary-100)!important}gridster.is-page{min-height:calc(100vh - 200px)}.mti-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.gridster-drop-indicator{position:absolute;background:var(--p-primary-100);border:2px dashed var(--p-primary-400);border-radius:8px;pointer-events:none;z-index:100}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "ngmodule", type: GridsterModule }, { kind: "component", type: i2$2.GridsterComponent, selector: "gridster", inputs: ["options"] }, { kind: "component", type: i2$2.GridsterItemComponent, selector: "gridster-item", inputs: ["item"], outputs: ["itemInit", "itemChange", "itemResize"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Page, selector: "mt-page", inputs: ["backButton", "backButtonIcon", "avatarIcon", "avatarStyle", "avatarShape", "title", "tabs", "activeTab", "contentClass", "contentId"], outputs: ["backButtonClick", "tabChange"] }, { kind: "component", type: Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: ContextMenuModule }, { kind: "component", type: i3$1.ContextMenu, selector: "p-contextMenu, p-contextmenu, p-context-menu", inputs: ["model", "triggerEvent", "target", "global", "style", "styleClass", "autoZIndex", "baseZIndex", "id", "breakpoint", "ariaLabel", "ariaLabelledBy", "pressDelay", "appendTo", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: DashboardItem, selector: "mt-dashboard-item", inputs: ["config", "chartTypeId", "readonly", "pageName", "inGroup", "isDialog", "queryParams", "extraFilters", "ignoreQueryFilter"], outputs: ["actionTriggered"] }, { kind: "pipe", type: FilterByGroupPipe, name: "filterByGroup" }, { kind: "pipe", type: GetChartActionsPipe, name: "getChartActions" }], encapsulation: i0.ViewEncapsulation.None });
20854
20893
  }