@masterteam/dashboard-builder 0.0.10 → 0.0.11
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.
- package/fesm2022/{masterteam-dashboard-builder-dashboard-dialog.component-697C4AOo.mjs → masterteam-dashboard-builder-dashboard-dialog.component-CF1Lnyxf.mjs} +2 -2
- package/fesm2022/{masterteam-dashboard-builder-dashboard-dialog.component-697C4AOo.mjs.map → masterteam-dashboard-builder-dashboard-dialog.component-CF1Lnyxf.mjs.map} +1 -1
- package/fesm2022/masterteam-dashboard-builder.mjs +78 -16
- package/fesm2022/masterteam-dashboard-builder.mjs.map +1 -1
- package/package.json +2 -2
- package/types/masterteam-dashboard-builder.d.ts +16 -2
|
@@ -15230,7 +15230,7 @@ class ActionService {
|
|
|
15230
15230
|
const actionData = this.handleActionsConfig(action.config, data, config);
|
|
15231
15231
|
debugger;
|
|
15232
15232
|
// Dynamically import DashboardDialogComponent to avoid circular dependency
|
|
15233
|
-
import('./masterteam-dashboard-builder-dashboard-dialog.component-
|
|
15233
|
+
import('./masterteam-dashboard-builder-dashboard-dialog.component-CF1Lnyxf.mjs').then(({ DashboardDialogComponent }) => {
|
|
15234
15234
|
// Open dialog using ModalService
|
|
15235
15235
|
this.modalService.openModal(DashboardDialogComponent, 'dialog', {
|
|
15236
15236
|
header: config.clientConfig?.title?.['en'] || '',
|
|
@@ -18291,6 +18291,10 @@ class DashboardItem {
|
|
|
18291
18291
|
isDialog = input(false, ...(ngDevMode ? [{ debugName: "isDialog" }] : []));
|
|
18292
18292
|
/** Query params passed from parent (e.g., dialog) */
|
|
18293
18293
|
queryParams = input({}, ...(ngDevMode ? [{ debugName: "queryParams" }] : []));
|
|
18294
|
+
/** Dashboard-wide extra filters passed from viewer/context */
|
|
18295
|
+
extraFilters = input({}, ...(ngDevMode ? [{ debugName: "extraFilters" }] : []));
|
|
18296
|
+
/** Skip global route/query filters for this item */
|
|
18297
|
+
ignoreQueryFilter = input(false, ...(ngDevMode ? [{ debugName: "ignoreQueryFilter" }] : []));
|
|
18294
18298
|
// ============================================
|
|
18295
18299
|
// Outputs
|
|
18296
18300
|
// ============================================
|
|
@@ -18462,11 +18466,7 @@ class DashboardItem {
|
|
|
18462
18466
|
this.isLoading.set(false);
|
|
18463
18467
|
return;
|
|
18464
18468
|
}
|
|
18465
|
-
|
|
18466
|
-
const queryParams = this.storeService.getQueryParams() || {};
|
|
18467
|
-
const extraFilters = this.storeService.getExtraFilterForCurrentAction(dashboardId) || {};
|
|
18468
|
-
// Merge all filters
|
|
18469
|
-
const filters = { ...queryParams, ...extraFilters };
|
|
18469
|
+
const filters = this.buildRequestFilters(dashboardId);
|
|
18470
18470
|
this.isLoading.set(true);
|
|
18471
18471
|
this.hasError.set(false);
|
|
18472
18472
|
// Use ChartDataService for ALL request types
|
|
@@ -18527,8 +18527,7 @@ class DashboardItem {
|
|
|
18527
18527
|
if (!dashboardId) {
|
|
18528
18528
|
return;
|
|
18529
18529
|
}
|
|
18530
|
-
|
|
18531
|
-
const parentFilter = this.storeService.getExtraFilterForCurrentAction(dashboardId) || {};
|
|
18530
|
+
const parentFilter = this.buildParentFilter(dashboardId);
|
|
18532
18531
|
// Merge event data with parent filter context
|
|
18533
18532
|
const enrichedData = {
|
|
18534
18533
|
...eventData?.data,
|
|
@@ -18543,8 +18542,40 @@ class DashboardItem {
|
|
|
18543
18542
|
config,
|
|
18544
18543
|
});
|
|
18545
18544
|
}
|
|
18545
|
+
buildRequestFilters(dashboardId) {
|
|
18546
|
+
const globalQueryParams = this.ignoreQueryFilter()
|
|
18547
|
+
? {}
|
|
18548
|
+
: (this.storeService.getQueryParams() ?? {});
|
|
18549
|
+
const globalExtraFilters = this.extraFilters() ?? {};
|
|
18550
|
+
const itemStoreQueryParams = this.itemStoreService.getQueryParams(dashboardId) ?? {};
|
|
18551
|
+
const preQueryParams = this.itemStoreService.getStore(dashboardId)?.preQueryParams ?? {};
|
|
18552
|
+
const inputQueryParams = this.queryParams() ?? {};
|
|
18553
|
+
const itemExtraFilters = this.itemStoreService.getExtraFilterForCurrentAction(dashboardId) ?? {};
|
|
18554
|
+
return this.mergeRequestFilters(globalQueryParams, globalExtraFilters, preQueryParams, itemStoreQueryParams, inputQueryParams, itemExtraFilters);
|
|
18555
|
+
}
|
|
18556
|
+
buildParentFilter(dashboardId) {
|
|
18557
|
+
return this.buildRequestFilters(dashboardId);
|
|
18558
|
+
}
|
|
18559
|
+
mergeRequestFilters(...sources) {
|
|
18560
|
+
const merged = {};
|
|
18561
|
+
sources.forEach((source) => {
|
|
18562
|
+
if (!source) {
|
|
18563
|
+
return;
|
|
18564
|
+
}
|
|
18565
|
+
Object.entries(source).forEach(([key, value]) => {
|
|
18566
|
+
if (value === undefined || value === null || value === '') {
|
|
18567
|
+
return;
|
|
18568
|
+
}
|
|
18569
|
+
if (Array.isArray(value) && value.length === 0) {
|
|
18570
|
+
return;
|
|
18571
|
+
}
|
|
18572
|
+
merged[key] = value;
|
|
18573
|
+
});
|
|
18574
|
+
});
|
|
18575
|
+
return merged;
|
|
18576
|
+
}
|
|
18546
18577
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DashboardItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
18547
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DashboardItem, isStandalone: true, selector: "mt-dashboard-item", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, chartTypeId: { classPropertyName: "chartTypeId", publicName: "chartTypeId", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, inGroup: { classPropertyName: "inGroup", publicName: "inGroup", isSignal: true, isRequired: false, transformFunction: null }, isDialog: { classPropertyName: "isDialog", publicName: "isDialog", isSignal: true, isRequired: false, transformFunction: null }, queryParams: { classPropertyName: "queryParams", publicName: "queryParams", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionTriggered: "actionTriggered" }, ngImport: i0, template: "@if (isLoading()) {\r\n <mt-skeleton-card [dashboardId]=\"dashboardId()\"></mt-skeleton-card>\r\n} @else if (hasError()) {\r\n <div class=\"flex flex-col items-center justify-center h-full p-4 text-center\">\r\n <mt-icon\r\n icon=\"general.alert-circle\"\r\n class=\"text-4xl text-red-500 mb-2\"\r\n ></mt-icon>\r\n <p class=\"text-red-500 font-medium\">\r\n {{ errorMessage() || \"Error loading data\" }}\r\n </p>\r\n <mt-button\r\n class=\"mt-2\"\r\n [label]=\"'Retry'\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n icon=\"arrow.refresh-cw-01\"\r\n (onClick)=\"refresh()\"\r\n />\r\n </div>\r\n} @else {\r\n @switch (componentName()) {\r\n <!-- Chart Types -->\r\n @case (\"chart\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Map Chart -->\r\n @case (\"map\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Background Text -->\r\n @case (\"BackgroundTextChart\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Chart Custom With Card Info -->\r\n @case (\"chartCustomWithCardInfo\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- List of Charts -->\r\n @case (\"listOfcharts\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- List of Cards Statistic -->\r\n @case (\"listOfCardsStatistic\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Cards Statistic (single) -->\r\n @case (\"cardsStatistic\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Header -->\r\n @case (\"header\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Footer (same as header) -->\r\n @case (\"footer\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Label (same as header) -->\r\n @case (\"label\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- List of Level Cards -->\r\n @case (\"listOfLevelCards\") {\r\n <mt-level-card-list\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-level-card-list>\r\n }\r\n\r\n <!-- Table -->\r\n @case (\"table\") {\r\n <mt-table-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-table-card>\r\n }\r\n\r\n <!-- Phase Gate Table -->\r\n @case (\"phaseGateTable\") {\r\n <mt-table-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-table-card>\r\n }\r\n\r\n <!-- Topbar -->\r\n @case (\"topbar\") {\r\n <!-- Topbar handled at viewer level -->\r\n }\r\n\r\n <!-- Timeline -->\r\n @case (\"timeline\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Timeline Project Dependencies -->\r\n @case (\"timelineProjectDependencies\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Last History Level Card -->\r\n @case (\"lastHistoryLevelCard\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Entity Preview -->\r\n @case (\"entityPreview\") {\r\n <mt-entity-preview-card [dashboardId]=\"dashboardId()\">\r\n </mt-entity-preview-card>\r\n }\r\n\r\n <!-- Cluster Stacked Chart -->\r\n @case (\"clusterStackedChart\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- List Component S+ Card -->\r\n @case (\"listComponentSplusCard\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Splitter Chart -->\r\n @case (\"splitterChart\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Repeater (same as header) -->\r\n @case (\"repeater\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Level Cards With Static -->\r\n @case (\"levelCardsWithStatic\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Phase Gate Stepper Card -->\r\n @case (\"phaseGateStepperCard\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Dialog -->\r\n @case (\"dialog\") {\r\n <!-- Dialog handled separately via ModalService -->\r\n }\r\n\r\n <!-- Default: try chart -->\r\n @default {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n }\r\n}\r\n", styles: [":host{display:block;width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: ChartCardComponent, selector: "mt-chart-card", inputs: ["dashboardId", "inGroup", "isConfigMode"], outputs: ["onAction"] }, { kind: "component", type: TableCardComponent, selector: "mt-table-card", inputs: ["dashboardId", "inGroup"], outputs: ["onAction"] }, { kind: "component", type: ListStatisticCardComponent, selector: "mt-list-statistic-card", inputs: ["dashboardId"] }, { kind: "component", type: HeaderCardComponent, selector: "mt-header-card", inputs: ["dashboardId"], outputs: ["onAction"] }, { kind: "component", type: SkeletonCardComponent, selector: "mt-skeleton-card", inputs: ["dashboardId"] }, { kind: "component", type: EntityPreviewCardComponent, selector: "mt-entity-preview-card", inputs: ["dashboardId"] }, { kind: "component", type: LevelCardListComponent, selector: "mt-level-card-list", inputs: ["dashboardId", "inGroup", "hideProperties"], outputs: ["onAction"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
18578
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DashboardItem, isStandalone: true, selector: "mt-dashboard-item", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, chartTypeId: { classPropertyName: "chartTypeId", publicName: "chartTypeId", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, inGroup: { classPropertyName: "inGroup", publicName: "inGroup", isSignal: true, isRequired: false, transformFunction: null }, isDialog: { classPropertyName: "isDialog", publicName: "isDialog", isSignal: true, isRequired: false, transformFunction: null }, queryParams: { classPropertyName: "queryParams", publicName: "queryParams", isSignal: true, isRequired: false, transformFunction: null }, extraFilters: { classPropertyName: "extraFilters", publicName: "extraFilters", isSignal: true, isRequired: false, transformFunction: null }, ignoreQueryFilter: { classPropertyName: "ignoreQueryFilter", publicName: "ignoreQueryFilter", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionTriggered: "actionTriggered" }, ngImport: i0, template: "@if (isLoading()) {\r\n <mt-skeleton-card [dashboardId]=\"dashboardId()\"></mt-skeleton-card>\r\n} @else if (hasError()) {\r\n <div class=\"flex flex-col items-center justify-center h-full p-4 text-center\">\r\n <mt-icon\r\n icon=\"general.alert-circle\"\r\n class=\"text-4xl text-red-500 mb-2\"\r\n ></mt-icon>\r\n <p class=\"text-red-500 font-medium\">\r\n {{ errorMessage() || \"Error loading data\" }}\r\n </p>\r\n <mt-button\r\n class=\"mt-2\"\r\n [label]=\"'Retry'\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n icon=\"arrow.refresh-cw-01\"\r\n (onClick)=\"refresh()\"\r\n />\r\n </div>\r\n} @else {\r\n @switch (componentName()) {\r\n <!-- Chart Types -->\r\n @case (\"chart\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Map Chart -->\r\n @case (\"map\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Background Text -->\r\n @case (\"BackgroundTextChart\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Chart Custom With Card Info -->\r\n @case (\"chartCustomWithCardInfo\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- List of Charts -->\r\n @case (\"listOfcharts\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- List of Cards Statistic -->\r\n @case (\"listOfCardsStatistic\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Cards Statistic (single) -->\r\n @case (\"cardsStatistic\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Header -->\r\n @case (\"header\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Footer (same as header) -->\r\n @case (\"footer\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Label (same as header) -->\r\n @case (\"label\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- List of Level Cards -->\r\n @case (\"listOfLevelCards\") {\r\n <mt-level-card-list\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-level-card-list>\r\n }\r\n\r\n <!-- Table -->\r\n @case (\"table\") {\r\n <mt-table-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-table-card>\r\n }\r\n\r\n <!-- Phase Gate Table -->\r\n @case (\"phaseGateTable\") {\r\n <mt-table-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-table-card>\r\n }\r\n\r\n <!-- Topbar -->\r\n @case (\"topbar\") {\r\n <!-- Topbar handled at viewer level -->\r\n }\r\n\r\n <!-- Timeline -->\r\n @case (\"timeline\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Timeline Project Dependencies -->\r\n @case (\"timelineProjectDependencies\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Last History Level Card -->\r\n @case (\"lastHistoryLevelCard\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Entity Preview -->\r\n @case (\"entityPreview\") {\r\n <mt-entity-preview-card [dashboardId]=\"dashboardId()\">\r\n </mt-entity-preview-card>\r\n }\r\n\r\n <!-- Cluster Stacked Chart -->\r\n @case (\"clusterStackedChart\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- List Component S+ Card -->\r\n @case (\"listComponentSplusCard\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Splitter Chart -->\r\n @case (\"splitterChart\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Repeater (same as header) -->\r\n @case (\"repeater\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Level Cards With Static -->\r\n @case (\"levelCardsWithStatic\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Phase Gate Stepper Card -->\r\n @case (\"phaseGateStepperCard\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Dialog -->\r\n @case (\"dialog\") {\r\n <!-- Dialog handled separately via ModalService -->\r\n }\r\n\r\n <!-- Default: try chart -->\r\n @default {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n }\r\n}\r\n", styles: [":host{display:block;width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: ChartCardComponent, selector: "mt-chart-card", inputs: ["dashboardId", "inGroup", "isConfigMode"], outputs: ["onAction"] }, { kind: "component", type: TableCardComponent, selector: "mt-table-card", inputs: ["dashboardId", "inGroup"], outputs: ["onAction"] }, { kind: "component", type: ListStatisticCardComponent, selector: "mt-list-statistic-card", inputs: ["dashboardId"] }, { kind: "component", type: HeaderCardComponent, selector: "mt-header-card", inputs: ["dashboardId"], outputs: ["onAction"] }, { kind: "component", type: SkeletonCardComponent, selector: "mt-skeleton-card", inputs: ["dashboardId"] }, { kind: "component", type: EntityPreviewCardComponent, selector: "mt-entity-preview-card", inputs: ["dashboardId"] }, { kind: "component", type: LevelCardListComponent, selector: "mt-level-card-list", inputs: ["dashboardId", "inGroup", "hideProperties"], outputs: ["onAction"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
18548
18579
|
}
|
|
18549
18580
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DashboardItem, decorators: [{
|
|
18550
18581
|
type: Component,
|
|
@@ -18562,7 +18593,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
18562
18593
|
EntityPreviewCardComponent,
|
|
18563
18594
|
LevelCardListComponent,
|
|
18564
18595
|
], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (isLoading()) {\r\n <mt-skeleton-card [dashboardId]=\"dashboardId()\"></mt-skeleton-card>\r\n} @else if (hasError()) {\r\n <div class=\"flex flex-col items-center justify-center h-full p-4 text-center\">\r\n <mt-icon\r\n icon=\"general.alert-circle\"\r\n class=\"text-4xl text-red-500 mb-2\"\r\n ></mt-icon>\r\n <p class=\"text-red-500 font-medium\">\r\n {{ errorMessage() || \"Error loading data\" }}\r\n </p>\r\n <mt-button\r\n class=\"mt-2\"\r\n [label]=\"'Retry'\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n icon=\"arrow.refresh-cw-01\"\r\n (onClick)=\"refresh()\"\r\n />\r\n </div>\r\n} @else {\r\n @switch (componentName()) {\r\n <!-- Chart Types -->\r\n @case (\"chart\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Map Chart -->\r\n @case (\"map\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Background Text -->\r\n @case (\"BackgroundTextChart\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Chart Custom With Card Info -->\r\n @case (\"chartCustomWithCardInfo\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- List of Charts -->\r\n @case (\"listOfcharts\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- List of Cards Statistic -->\r\n @case (\"listOfCardsStatistic\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Cards Statistic (single) -->\r\n @case (\"cardsStatistic\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Header -->\r\n @case (\"header\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Footer (same as header) -->\r\n @case (\"footer\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Label (same as header) -->\r\n @case (\"label\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- List of Level Cards -->\r\n @case (\"listOfLevelCards\") {\r\n <mt-level-card-list\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-level-card-list>\r\n }\r\n\r\n <!-- Table -->\r\n @case (\"table\") {\r\n <mt-table-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-table-card>\r\n }\r\n\r\n <!-- Phase Gate Table -->\r\n @case (\"phaseGateTable\") {\r\n <mt-table-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-table-card>\r\n }\r\n\r\n <!-- Topbar -->\r\n @case (\"topbar\") {\r\n <!-- Topbar handled at viewer level -->\r\n }\r\n\r\n <!-- Timeline -->\r\n @case (\"timeline\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Timeline Project Dependencies -->\r\n @case (\"timelineProjectDependencies\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Last History Level Card -->\r\n @case (\"lastHistoryLevelCard\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Entity Preview -->\r\n @case (\"entityPreview\") {\r\n <mt-entity-preview-card [dashboardId]=\"dashboardId()\">\r\n </mt-entity-preview-card>\r\n }\r\n\r\n <!-- Cluster Stacked Chart -->\r\n @case (\"clusterStackedChart\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- List Component S+ Card -->\r\n @case (\"listComponentSplusCard\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Splitter Chart -->\r\n @case (\"splitterChart\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Repeater (same as header) -->\r\n @case (\"repeater\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Level Cards With Static -->\r\n @case (\"levelCardsWithStatic\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Phase Gate Stepper Card -->\r\n @case (\"phaseGateStepperCard\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Dialog -->\r\n @case (\"dialog\") {\r\n <!-- Dialog handled separately via ModalService -->\r\n }\r\n\r\n <!-- Default: try chart -->\r\n @default {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n }\r\n}\r\n", styles: [":host{display:block;width:100%;height:100%}\n"] }]
|
|
18565
|
-
}], ctorParameters: () => [], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], chartTypeId: [{ type: i0.Input, args: [{ isSignal: true, alias: "chartTypeId", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], inGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "inGroup", required: false }] }], isDialog: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDialog", required: false }] }], queryParams: [{ type: i0.Input, args: [{ isSignal: true, alias: "queryParams", required: false }] }], actionTriggered: [{ type: i0.Output, args: ["actionTriggered"] }] } });
|
|
18596
|
+
}], ctorParameters: () => [], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], chartTypeId: [{ type: i0.Input, args: [{ isSignal: true, alias: "chartTypeId", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], inGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "inGroup", required: false }] }], isDialog: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDialog", required: false }] }], queryParams: [{ type: i0.Input, args: [{ isSignal: true, alias: "queryParams", required: false }] }], extraFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "extraFilters", required: false }] }], ignoreQueryFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "ignoreQueryFilter", required: false }] }], actionTriggered: [{ type: i0.Output, args: ["actionTriggered"] }] } });
|
|
18566
18597
|
|
|
18567
18598
|
/**
|
|
18568
18599
|
* Chart Viewer Component
|
|
@@ -18585,7 +18616,7 @@ class ChartViewer {
|
|
|
18585
18616
|
}, 500);
|
|
18586
18617
|
}
|
|
18587
18618
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ChartViewer, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
18588
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ChartViewer, isStandalone: true, selector: "mt-chart-viewer", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, chartTypeId: { classPropertyName: "chartTypeId", publicName: "chartTypeId", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <div class=\"h-full flex flex-col bg-surface-50 border-l border-surface-200\">\r\n <!-- Header -->\r\n <div\r\n class=\"flex items-center justify-between px-4 py-3 bg-surface-0 border-b border-surface-200\"\r\n >\r\n <span class=\"text-sm font-medium text-surface-700\">{{\r\n t(\"preview\")\r\n }}</span>\r\n <mt-button\r\n icon=\"arrow.refresh-cw-01\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n severity=\"help\"\r\n [tooltip]=\"t('refresh')\"\r\n (onClick)=\"refresh()\"\r\n />\r\n </div>\r\n\r\n <!-- Preview Content -->\r\n <div class=\"flex-1 p-4 overflow-auto\">\r\n @if (loading()) {\r\n <div class=\"flex items-center justify-center h-full\">\r\n <mt-icon\r\n icon=\"general.loading-02\"\r\n class=\"text-3xl text-primary animate-spin\"\r\n />\r\n </div>\r\n } @else if (config() && chartTypeId()) {\r\n <div\r\n class=\"h-full bg-surface-0 rounded-lg shadow-sm border border-surface-200 overflow-hidden\"\r\n >\r\n <mt-dashboard-item\r\n [config]=\"config()\"\r\n [chartTypeId]=\"chartTypeId()\"\r\n [readonly]=\"true\"\r\n />\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex flex-col items-center justify-center h-full text-muted-color\"\r\n >\r\n <mt-icon icon=\"chart.bar-chart-10\" class=\"text-4xl mb-3 opacity-50\" />\r\n <p class=\"text-sm\">{{ t(\"noPreviewAvailable\") }}</p>\r\n <p class=\"text-xs opacity-70\">{{ t(\"configureChartToPreview\") }}</p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n</ng-container>\r\n", styles: [":host{display:block;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { 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: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: DashboardItem, selector: "mt-dashboard-item", inputs: ["config", "chartTypeId", "readonly", "inGroup", "isDialog", "queryParams"], outputs: ["actionTriggered"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
18619
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ChartViewer, isStandalone: true, selector: "mt-chart-viewer", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, chartTypeId: { classPropertyName: "chartTypeId", publicName: "chartTypeId", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <div class=\"h-full flex flex-col bg-surface-50 border-l border-surface-200\">\r\n <!-- Header -->\r\n <div\r\n class=\"flex items-center justify-between px-4 py-3 bg-surface-0 border-b border-surface-200\"\r\n >\r\n <span class=\"text-sm font-medium text-surface-700\">{{\r\n t(\"preview\")\r\n }}</span>\r\n <mt-button\r\n icon=\"arrow.refresh-cw-01\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n severity=\"help\"\r\n [tooltip]=\"t('refresh')\"\r\n (onClick)=\"refresh()\"\r\n />\r\n </div>\r\n\r\n <!-- Preview Content -->\r\n <div class=\"flex-1 p-4 overflow-auto\">\r\n @if (loading()) {\r\n <div class=\"flex items-center justify-center h-full\">\r\n <mt-icon\r\n icon=\"general.loading-02\"\r\n class=\"text-3xl text-primary animate-spin\"\r\n />\r\n </div>\r\n } @else if (config() && chartTypeId()) {\r\n <div\r\n class=\"h-full bg-surface-0 rounded-lg shadow-sm border border-surface-200 overflow-hidden\"\r\n >\r\n <mt-dashboard-item\r\n [config]=\"config()\"\r\n [chartTypeId]=\"chartTypeId()\"\r\n [readonly]=\"true\"\r\n />\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex flex-col items-center justify-center h-full text-muted-color\"\r\n >\r\n <mt-icon icon=\"chart.bar-chart-10\" class=\"text-4xl mb-3 opacity-50\" />\r\n <p class=\"text-sm\">{{ t(\"noPreviewAvailable\") }}</p>\r\n <p class=\"text-xs opacity-70\">{{ t(\"configureChartToPreview\") }}</p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n</ng-container>\r\n", styles: [":host{display:block;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { 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: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: DashboardItem, selector: "mt-dashboard-item", inputs: ["config", "chartTypeId", "readonly", "inGroup", "isDialog", "queryParams", "extraFilters", "ignoreQueryFilter"], outputs: ["actionTriggered"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
18589
18620
|
}
|
|
18590
18621
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ChartViewer, decorators: [{
|
|
18591
18622
|
type: Component,
|
|
@@ -20033,7 +20064,7 @@ class DashboardBuilder {
|
|
|
20033
20064
|
this.emittingDashboardData = false;
|
|
20034
20065
|
}
|
|
20035
20066
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DashboardBuilder, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20036
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", 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 }, dashboardData: { classPropertyName: "dashboardData", publicName: "dashboardData", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", 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 />\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 />\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", "inGroup", "isDialog", "queryParams"], outputs: ["actionTriggered"] }, { kind: "pipe", type: FilterByGroupPipe, name: "filterByGroup" }, { kind: "pipe", type: GetChartActionsPipe, name: "getChartActions" }], encapsulation: i0.ViewEncapsulation.None });
|
|
20067
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", 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 }, dashboardData: { classPropertyName: "dashboardData", publicName: "dashboardData", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", 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 />\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 />\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", "inGroup", "isDialog", "queryParams", "extraFilters", "ignoreQueryFilter"], outputs: ["actionTriggered"] }, { kind: "pipe", type: FilterByGroupPipe, name: "filterByGroup" }, { kind: "pipe", type: GetChartActionsPipe, name: "getChartActions" }], encapsulation: i0.ViewEncapsulation.None });
|
|
20037
20068
|
}
|
|
20038
20069
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DashboardBuilder, decorators: [{
|
|
20039
20070
|
type: Component,
|
|
@@ -20076,6 +20107,8 @@ class DashboardViewer {
|
|
|
20076
20107
|
cdr = inject(ChangeDetectorRef);
|
|
20077
20108
|
dashboardService = inject(DashboardBuilderService);
|
|
20078
20109
|
storeService = inject(DashboardStoreService);
|
|
20110
|
+
itemStoreService = inject(DashboardItemStoreService);
|
|
20111
|
+
route = inject(ActivatedRoute, { optional: true });
|
|
20079
20112
|
// ============================================
|
|
20080
20113
|
// Inputs
|
|
20081
20114
|
// ============================================
|
|
@@ -20095,6 +20128,8 @@ class DashboardViewer {
|
|
|
20095
20128
|
dialogsData = input([], ...(ngDevMode ? [{ debugName: "dialogsData" }] : []));
|
|
20096
20129
|
/** Pre-loaded filters (optional) */
|
|
20097
20130
|
filtersData = input([], ...(ngDevMode ? [{ debugName: "filtersData" }] : []));
|
|
20131
|
+
/** Dashboard-wide extra filters applied to every item request */
|
|
20132
|
+
extraFilters = input({}, ...(ngDevMode ? [{ debugName: "extraFilters" }] : []));
|
|
20098
20133
|
/** Show filters sidebar */
|
|
20099
20134
|
showFilters = input(true, ...(ngDevMode ? [{ debugName: "showFilters" }] : []));
|
|
20100
20135
|
// ============================================
|
|
@@ -20150,6 +20185,7 @@ class DashboardViewer {
|
|
|
20150
20185
|
// ============================================
|
|
20151
20186
|
subscription = new Subscription();
|
|
20152
20187
|
rowHeight = 60;
|
|
20188
|
+
lastExtraFiltersSignature = null;
|
|
20153
20189
|
hasSplitPreloadedData = computed(() => {
|
|
20154
20190
|
return (this.chartsData().length > 0 ||
|
|
20155
20191
|
this.dialogsData().length > 0 ||
|
|
@@ -20181,6 +20217,17 @@ class DashboardViewer {
|
|
|
20181
20217
|
this.filters.set(data ?? []);
|
|
20182
20218
|
this.dashboardService.filters.set(this.filters());
|
|
20183
20219
|
}, { ...(ngDevMode ? { debugName: "filtersDataEffect" } : {}), allowSignalWrites: true });
|
|
20220
|
+
extraFiltersEffect = effect(() => {
|
|
20221
|
+
const signature = JSON.stringify(this.extraFilters() ?? {});
|
|
20222
|
+
if (this.lastExtraFiltersSignature === null) {
|
|
20223
|
+
this.lastExtraFiltersSignature = signature;
|
|
20224
|
+
return;
|
|
20225
|
+
}
|
|
20226
|
+
if (this.lastExtraFiltersSignature !== signature) {
|
|
20227
|
+
this.lastExtraFiltersSignature = signature;
|
|
20228
|
+
this.refreshAllItems();
|
|
20229
|
+
}
|
|
20230
|
+
}, ...(ngDevMode ? [{ debugName: "extraFiltersEffect" }] : []));
|
|
20184
20231
|
// Preloaded split inputs do not include page metadata, so clear stale page state.
|
|
20185
20232
|
preloadedInputsEffect = effect(() => {
|
|
20186
20233
|
if (this.dashboardData() || !this.hasSplitPreloadedData())
|
|
@@ -20208,8 +20255,15 @@ class DashboardViewer {
|
|
|
20208
20255
|
}
|
|
20209
20256
|
ngOnDestroy() {
|
|
20210
20257
|
this.subscription.unsubscribe();
|
|
20258
|
+
this.storeService.updateQueryParams({});
|
|
20211
20259
|
}
|
|
20212
20260
|
setupSubscriptions() {
|
|
20261
|
+
if (this.route) {
|
|
20262
|
+
this.subscription.add(this.route.queryParams.subscribe((params) => {
|
|
20263
|
+
this.storeService.updateQueryParams(params ?? {});
|
|
20264
|
+
this.refreshAllItems();
|
|
20265
|
+
}));
|
|
20266
|
+
}
|
|
20213
20267
|
// Subscribe to reload events from store
|
|
20214
20268
|
this.subscription.add(this.storeService.reloadCurrentPage$.subscribe(() => {
|
|
20215
20269
|
this.reloadPage();
|
|
@@ -20413,8 +20467,16 @@ class DashboardViewer {
|
|
|
20413
20467
|
trackByDashboardId(_index, item) {
|
|
20414
20468
|
return item.config?.serviceConfig?.dashboardId || String(_index);
|
|
20415
20469
|
}
|
|
20470
|
+
refreshAllItems() {
|
|
20471
|
+
this.charts().forEach((chart) => {
|
|
20472
|
+
const dashboardId = chart.config?.serviceConfig?.dashboardId;
|
|
20473
|
+
if (dashboardId) {
|
|
20474
|
+
this.itemStoreService.triggerDataFetch(dashboardId);
|
|
20475
|
+
}
|
|
20476
|
+
});
|
|
20477
|
+
}
|
|
20416
20478
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DashboardViewer, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20417
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DashboardViewer, isStandalone: true, selector: "mt-dashboard-viewer", 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 }, dashboardData: { classPropertyName: "dashboardData", publicName: "dashboardData", isSignal: true, isRequired: false, transformFunction: null }, chartsData: { classPropertyName: "chartsData", publicName: "chartsData", isSignal: true, isRequired: false, transformFunction: null }, dialogsData: { classPropertyName: "dialogsData", publicName: "dialogsData", isSignal: true, isRequired: false, transformFunction: null }, filtersData: { classPropertyName: "filtersData", publicName: "filtersData", isSignal: true, isRequired: false, transformFunction: null }, showFilters: { classPropertyName: "showFilters", publicName: "showFilters", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageLoaded: "pageLoaded", onBack: "onBack", chartClick: "chartClick" }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\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('dashboard')\r\n \"\r\n [backButton]=\"backButton()\"\r\n (backButtonClick)=\"onBack.emit()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"viewerContent\" />\r\n </mt-page>\r\n } @else {\r\n <!-- Non-page mode -->\r\n <ng-container *ngTemplateOutlet=\"viewerContent\" />\r\n }\r\n\r\n <!-- Reusable viewer content template -->\r\n <ng-template #viewerContent>\r\n <div class=\"relative h-full min-h-[600px] mt-dashboard-viewer\">\r\n @if (!loading() && hasRenderableContent()) {\r\n <div class=\"dashboard-viewer-layout-wrapper\">\r\n <div\r\n class=\"dashboard-viewer-layout\"\r\n [style.min-height]=\"layoutHeight()\"\r\n >\r\n @for (\r\n item of visibleItems();\r\n track trackByDashboardId($index, item)\r\n ) {\r\n <div\r\n class=\"dashboard-viewer-item\"\r\n [class.dashboard-viewer-item--group]=\"isGroup(item)\"\r\n [class.dashboard-viewer-item--header]=\"isHeader(item)\"\r\n [class.dashboard-viewer-item--topbar]=\"isTopbar(item)\"\r\n [style.grid-column]=\"getGridColumn(item)\"\r\n [style.grid-row]=\"getGridRow(item)\"\r\n >\r\n <!-- Group Container -->\r\n @if (isGroup(item)) {\r\n @if (!item.loading) {\r\n <div\r\n class=\"group-container h-full flex flex-col rounded-lg border border-surface-200 overflow-hidden\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'var(--surface-card)'\r\n \"\r\n >\r\n <!-- Group Header with Tabs -->\r\n <div\r\n class=\"group-header flex items-center justify-between px-4 py-2 bg-surface-50 border-b border-surface-200\"\r\n >\r\n <span class=\"font-medium text-sm\">{{\r\n getGroupTitle(item)\r\n }}</span>\r\n <div class=\"group-tabs flex items-center gap-1\">\r\n @for (\r\n child of getGroupChildren(item);\r\n track child.config?.serviceConfig?.dashboardId;\r\n let gIndex = $index\r\n ) {\r\n @if (getItemIcon(child); as icon) {\r\n <button\r\n type=\"button\"\r\n class=\"w-8 h-8 flex items-center justify-center rounded transition-colors\"\r\n [class.bg-primary-100]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.text-primary-600]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.text-muted-color]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n [class.hover:bg-surface-100]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n (click)=\"selectGroupChild(item, gIndex)\"\r\n >\r\n <i class=\"mti mti-{{ icon }}\"></i>\r\n </button>\r\n } @else {\r\n <button\r\n pButton\r\n type=\"button\"\r\n class=\"p-button-text p-button-sm\"\r\n [class.p-button-primary]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.p-button-secondary]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n [label]=\"getItemTitle(child)\"\r\n (click)=\"selectGroupChild(item, gIndex)\"\r\n ></button>\r\n }\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Group Body - Selected Child Content -->\r\n <div class=\"group-body flex-1 min-h-0 p-2\">\r\n @if (\r\n item.selectedGroupIndex !== null &&\r\n item.selectedGroupIndex !== undefined\r\n ) {\r\n @for (\r\n child of getGroupChildren(item);\r\n track child.config?.serviceConfig?.dashboardId;\r\n let cIndex = $index\r\n ) {\r\n @if (\r\n cIndex === item.selectedGroupIndex &&\r\n !child.loading\r\n ) {\r\n <div class=\"w-full h-full\">\r\n <mt-dashboard-item\r\n [config]=\"child.config\"\r\n [chartTypeId]=\"\r\n child.config?.serviceConfig?.dashboardId ||\r\n child.id\r\n \"\r\n [inGroup]=\"true\"\r\n >\r\n </mt-dashboard-item>\r\n </div>\r\n }\r\n }\r\n }\r\n </div>\r\n </div>\r\n }\r\n }\r\n <!-- Header Item -->\r\n @else if (isHeader(item)) {\r\n @if (!item.loading) {\r\n <div\r\n class=\"header-item flex items-center h-full px-4 border-b-2 border-primary\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'transparent'\r\n \"\r\n [style.color]=\"getStyleConfig(item)['color'] || 'inherit'\"\r\n >\r\n <h3 class=\"font-semibold text-lg m-0\">\r\n {{ getItemTitle(item) }}\r\n </h3>\r\n </div>\r\n }\r\n }\r\n <!-- Topbar Item -->\r\n @else if (isTopbar(item)) {\r\n @if (!item.loading) {\r\n <div\r\n class=\"topbar-item flex items-center h-full px-4 bg-surface-50\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'var(--surface-50)'\r\n \"\r\n >\r\n <nav class=\"flex items-center gap-2 text-sm\">\r\n @for (\r\n crumb of getBreadcrumb(item);\r\n track $index;\r\n let last = $last\r\n ) {\r\n <span\r\n class=\"text-muted-color hover:text-primary cursor-pointer transition-colors\"\r\n >\r\n {{\r\n crumb.label?.[languageCode()] ||\r\n crumb.label?.[\"en\"] ||\r\n crumb.label\r\n }}\r\n </span>\r\n @if (!last) {\r\n <i\r\n class=\"mti mti-chevron-right text-xs text-muted-color\"\r\n ></i>\r\n }\r\n }\r\n @if (getBreadcrumb(item).length === 0) {\r\n <span class=\"text-muted-color italic\">{{\r\n t(\"noBreadcrumb\")\r\n }}</span>\r\n }\r\n </nav>\r\n </div>\r\n }\r\n }\r\n <!-- Regular Chart Item -->\r\n @else {\r\n @if (!item.loading) {\r\n <div\r\n class=\"chart-item h-full flex flex-col rounded-lg border border-surface-200 overflow-hidden\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'var(--surface-card)'\r\n \"\r\n >\r\n <mt-dashboard-item\r\n [config]=\"item.config\"\r\n [chartTypeId]=\"\r\n item.config?.serviceConfig?.dashboardId || item.id\r\n \"\r\n [inGroup]=\"false\"\r\n >\r\n </mt-dashboard-item>\r\n </div>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Hidden Dialogs (for modal rendering) -->\r\n @if (dialogs().length > 0) {\r\n <div class=\"hidden\">\r\n @for (\r\n dialog of dialogs();\r\n track dialog.config?.serviceConfig?.dashboardId\r\n ) {\r\n <!-- Dialog placeholder - will be rendered in modal when triggered -->\r\n <div\r\n [attr.data-dialog-id]=\"\r\n dialog.config?.serviceConfig?.dashboardId\r\n \"\r\n ></div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Filters Sidebar Placeholder -->\r\n @if (showFilters() && filters().length > 0) {\r\n <div\r\n class=\"filters-sidebar fixed end-0 top-0 bottom-0 w-64 bg-surface-card border-s border-surface-200 p-4 shadow-lg z-50 hidden\"\r\n >\r\n <!-- Filter sidebar content - integrate with actual filter component -->\r\n <h4 class=\"font-semibold mb-4\">{{ t(\"filters\") }}</h4>\r\n @for (filter of filters(); track $index) {\r\n <div class=\"filter-item mb-3 p-2 bg-surface-50 rounded\">\r\n <span class=\"text-sm\">{{\r\n filter.label || filter.propertyKey\r\n }}</span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n } @else if (loading()) {\r\n <!-- Loading State -->\r\n <div class=\"flex items-center justify-center h-64\">\r\n <div class=\"text-center\">\r\n <i\r\n class=\"mti mti-loader-2 text-4xl text-primary animate-spin mb-2\"\r\n ></i>\r\n <p class=\"text-muted-color\">{{ t(\"loading\") }}</p>\r\n </div>\r\n </div>\r\n } @else {\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: [".mt-dashboard-viewer{width:100%;height:100%}.dashboard-viewer-layout-wrapper{width:100%}.dashboard-viewer-layout{display:grid;grid-template-columns:repeat(36,minmax(0,1fr));grid-auto-rows:60px;gap:10px;width:100%;align-items:stretch}.dashboard-viewer-item{min-width:0;min-height:0}.dashboard-viewer-item>*{width:100%;height:100%}.dashboard-viewer-item--header{z-index:1}.dashboard-viewer-item--topbar{z-index:2}.group-container{background-color:var(--surface-card)}.group-header{flex-shrink:0}.group-tabs{flex-wrap:wrap}.group-body{background-color:var(--surface-0)}.chart-item{background-color:var(--surface-card)}.header-item{background-color:transparent}.topbar-item{background-color:var(--surface-50)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.filters-sidebar{transform:translate(100%);transition:transform .3s ease-in-out}.filters-sidebar.open{transform:translate(0)}[dir=rtl] .filters-sidebar{transform:translate(-100%)}[dir=rtl] .filters-sidebar.open{transform:translate(0)}.table-responsive{max-height:75vh;overflow-y:auto;overflow-x:auto}.modal-content{border:0!important}.custom-donut-chart{display:flex;justify-content:center;height:auto!important}.custom-donut-chart canvas{margin-top:-1.5rem!important}@media(max-width:768px){.dashboard-viewer-layout{display:flex;flex-direction:column;min-height:0!important}.dashboard-viewer-item{min-height:220px}.dashboard-viewer-item--header,.dashboard-viewer-item--topbar{min-height:72px}.dashboard-viewer-item--group{min-height:280px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$3.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: DashboardItem, selector: "mt-dashboard-item", inputs: ["config", "chartTypeId", "readonly", "inGroup", "isDialog", "queryParams"], outputs: ["actionTriggered"] }, { kind: "component", type: Page, selector: "mt-page", inputs: ["backButton", "backButtonIcon", "avatarIcon", "avatarStyle", "avatarShape", "title", "tabs", "activeTab", "contentClass", "contentId"], outputs: ["backButtonClick", "tabChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
20479
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DashboardViewer, isStandalone: true, selector: "mt-dashboard-viewer", 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 }, dashboardData: { classPropertyName: "dashboardData", publicName: "dashboardData", isSignal: true, isRequired: false, transformFunction: null }, chartsData: { classPropertyName: "chartsData", publicName: "chartsData", isSignal: true, isRequired: false, transformFunction: null }, dialogsData: { classPropertyName: "dialogsData", publicName: "dialogsData", isSignal: true, isRequired: false, transformFunction: null }, filtersData: { classPropertyName: "filtersData", publicName: "filtersData", isSignal: true, isRequired: false, transformFunction: null }, extraFilters: { classPropertyName: "extraFilters", publicName: "extraFilters", isSignal: true, isRequired: false, transformFunction: null }, showFilters: { classPropertyName: "showFilters", publicName: "showFilters", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageLoaded: "pageLoaded", onBack: "onBack", chartClick: "chartClick" }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\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('dashboard')\r\n \"\r\n [backButton]=\"backButton()\"\r\n (backButtonClick)=\"onBack.emit()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"viewerContent\" />\r\n </mt-page>\r\n } @else {\r\n <!-- Non-page mode -->\r\n <ng-container *ngTemplateOutlet=\"viewerContent\" />\r\n }\r\n\r\n <!-- Reusable viewer content template -->\r\n <ng-template #viewerContent>\r\n <div class=\"relative h-full min-h-[600px] mt-dashboard-viewer\">\r\n @if (!loading() && hasRenderableContent()) {\r\n <div class=\"dashboard-viewer-layout-wrapper\">\r\n <div\r\n class=\"dashboard-viewer-layout\"\r\n [style.min-height]=\"layoutHeight()\"\r\n >\r\n @for (\r\n item of visibleItems();\r\n track trackByDashboardId($index, item)\r\n ) {\r\n <div\r\n class=\"dashboard-viewer-item\"\r\n [class.dashboard-viewer-item--group]=\"isGroup(item)\"\r\n [class.dashboard-viewer-item--header]=\"isHeader(item)\"\r\n [class.dashboard-viewer-item--topbar]=\"isTopbar(item)\"\r\n [style.grid-column]=\"getGridColumn(item)\"\r\n [style.grid-row]=\"getGridRow(item)\"\r\n >\r\n <!-- Group Container -->\r\n @if (isGroup(item)) {\r\n @if (!item.loading) {\r\n <div\r\n class=\"group-container h-full flex flex-col rounded-lg border border-surface-200 overflow-hidden\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'var(--surface-card)'\r\n \"\r\n >\r\n <!-- Group Header with Tabs -->\r\n <div\r\n class=\"group-header flex items-center justify-between px-4 py-2 bg-surface-50 border-b border-surface-200\"\r\n >\r\n <span class=\"font-medium text-sm\">{{\r\n getGroupTitle(item)\r\n }}</span>\r\n <div class=\"group-tabs flex items-center gap-1\">\r\n @for (\r\n child of getGroupChildren(item);\r\n track child.config?.serviceConfig?.dashboardId;\r\n let gIndex = $index\r\n ) {\r\n @if (getItemIcon(child); as icon) {\r\n <button\r\n type=\"button\"\r\n class=\"w-8 h-8 flex items-center justify-center rounded transition-colors\"\r\n [class.bg-primary-100]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.text-primary-600]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.text-muted-color]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n [class.hover:bg-surface-100]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n (click)=\"selectGroupChild(item, gIndex)\"\r\n >\r\n <i class=\"mti mti-{{ icon }}\"></i>\r\n </button>\r\n } @else {\r\n <button\r\n pButton\r\n type=\"button\"\r\n class=\"p-button-text p-button-sm\"\r\n [class.p-button-primary]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.p-button-secondary]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n [label]=\"getItemTitle(child)\"\r\n (click)=\"selectGroupChild(item, gIndex)\"\r\n ></button>\r\n }\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Group Body - Selected Child Content -->\r\n <div class=\"group-body flex-1 min-h-0\">\n @if (\n item.selectedGroupIndex !== null &&\n item.selectedGroupIndex !== undefined\n ) {\n @for (\r\n child of getGroupChildren(item);\r\n track child.config?.serviceConfig?.dashboardId;\r\n let cIndex = $index\r\n ) {\r\n @if (\n cIndex === item.selectedGroupIndex &&\n !child.loading\n ) {\n <mt-dashboard-item\n class=\"dashboard-viewer-content-item\"\n [config]=\"child.config\"\n [chartTypeId]=\"\n child.config?.serviceConfig?.dashboardId ||\n child.id\n \"\n [extraFilters]=\"extraFilters()\"\n [ignoreQueryFilter]=\"\n pageConfig()?.dashboardConfig\n ?.ignoreQueryFilter ?? false\n \"\n [inGroup]=\"true\"\n >\n </mt-dashboard-item>\n }\n }\n }\n </div>\n </div>\r\n }\r\n }\r\n <!-- Header Item -->\r\n @else if (isHeader(item)) {\r\n @if (!item.loading) {\r\n <div\r\n class=\"header-item flex items-center h-full px-4 border-b-2 border-primary\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'transparent'\r\n \"\r\n [style.color]=\"getStyleConfig(item)['color'] || 'inherit'\"\r\n >\r\n <h3 class=\"font-semibold text-lg m-0\">\r\n {{ getItemTitle(item) }}\r\n </h3>\r\n </div>\r\n }\r\n }\r\n <!-- Topbar Item -->\r\n @else if (isTopbar(item)) {\r\n @if (!item.loading) {\r\n <div\r\n class=\"topbar-item flex items-center h-full px-4 bg-surface-50\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'var(--surface-50)'\r\n \"\r\n >\r\n <nav class=\"flex items-center gap-2 text-sm\">\r\n @for (\r\n crumb of getBreadcrumb(item);\r\n track $index;\r\n let last = $last\r\n ) {\r\n <span\r\n class=\"text-muted-color hover:text-primary cursor-pointer transition-colors\"\r\n >\r\n {{\r\n crumb.label?.[languageCode()] ||\r\n crumb.label?.[\"en\"] ||\r\n crumb.label\r\n }}\r\n </span>\r\n @if (!last) {\r\n <i\r\n class=\"mti mti-chevron-right text-xs text-muted-color\"\r\n ></i>\r\n }\r\n }\r\n @if (getBreadcrumb(item).length === 0) {\r\n <span class=\"text-muted-color italic\">{{\r\n t(\"noBreadcrumb\")\r\n }}</span>\r\n }\r\n </nav>\r\n </div>\r\n }\r\n }\r\n <!-- Regular Chart Item -->\n @else {\n @if (!item.loading) {\n <mt-dashboard-item\n class=\"dashboard-viewer-content-item\"\n [config]=\"item.config\"\n [chartTypeId]=\"\n item.config?.serviceConfig?.dashboardId || item.id\n \"\n [extraFilters]=\"extraFilters()\"\n [ignoreQueryFilter]=\"\n pageConfig()?.dashboardConfig?.ignoreQueryFilter ??\n false\n \"\n [inGroup]=\"false\"\n >\n </mt-dashboard-item>\n }\n }\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Hidden Dialogs (for modal rendering) -->\r\n @if (dialogs().length > 0) {\r\n <div class=\"hidden\">\r\n @for (\r\n dialog of dialogs();\r\n track dialog.config?.serviceConfig?.dashboardId\r\n ) {\r\n <!-- Dialog placeholder - will be rendered in modal when triggered -->\r\n <div\r\n [attr.data-dialog-id]=\"\r\n dialog.config?.serviceConfig?.dashboardId\r\n \"\r\n ></div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Filters Sidebar Placeholder -->\r\n @if (showFilters() && filters().length > 0) {\r\n <div\r\n class=\"filters-sidebar fixed end-0 top-0 bottom-0 w-64 bg-surface-card border-s border-surface-200 p-4 shadow-lg z-50 hidden\"\r\n >\r\n <!-- Filter sidebar content - integrate with actual filter component -->\r\n <h4 class=\"font-semibold mb-4\">{{ t(\"filters\") }}</h4>\r\n @for (filter of filters(); track $index) {\r\n <div class=\"filter-item mb-3 p-2 bg-surface-50 rounded\">\r\n <span class=\"text-sm\">{{\r\n filter.label || filter.propertyKey\r\n }}</span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n } @else if (loading()) {\r\n <!-- Loading State -->\r\n <div class=\"flex items-center justify-center h-64\">\r\n <div class=\"text-center\">\r\n <i\r\n class=\"mti mti-loader-2 text-4xl text-primary animate-spin mb-2\"\r\n ></i>\r\n <p class=\"text-muted-color\">{{ t(\"loading\") }}</p>\r\n </div>\r\n </div>\r\n } @else {\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: [".mt-dashboard-viewer{width:100%;height:100%}.dashboard-viewer-layout-wrapper{width:100%}.dashboard-viewer-layout{display:grid;grid-template-columns:repeat(36,minmax(0,1fr));grid-auto-rows:60px;gap:10px;width:100%;align-items:stretch}.dashboard-viewer-item{display:flex;min-width:0;min-height:0}.dashboard-viewer-item>*{width:100%;height:100%}.dashboard-viewer-content-item{display:block;flex:1 1 auto;min-width:0;min-height:0;width:100%;height:100%}.dashboard-viewer-item--header{z-index:1}.dashboard-viewer-item--topbar{z-index:2}.group-container{background-color:var(--surface-card)}.group-header{flex-shrink:0}.group-tabs{flex-wrap:wrap}.group-body{background-color:var(--surface-0)}.header-item{background-color:transparent}.topbar-item{background-color:var(--surface-50)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.filters-sidebar{transform:translate(100%);transition:transform .3s ease-in-out}.filters-sidebar.open{transform:translate(0)}[dir=rtl] .filters-sidebar{transform:translate(-100%)}[dir=rtl] .filters-sidebar.open{transform:translate(0)}.table-responsive{max-height:75vh;overflow-y:auto;overflow-x:auto}.modal-content{border:0!important}.custom-donut-chart{display:flex;justify-content:center;height:auto!important}.custom-donut-chart canvas{margin-top:-1.5rem!important}@media(max-width:768px){.dashboard-viewer-layout{display:flex;flex-direction:column;min-height:0!important}.dashboard-viewer-item{min-height:220px}.dashboard-viewer-item--header,.dashboard-viewer-item--topbar{min-height:72px}.dashboard-viewer-item--group{min-height:280px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$3.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: DashboardItem, selector: "mt-dashboard-item", inputs: ["config", "chartTypeId", "readonly", "inGroup", "isDialog", "queryParams", "extraFilters", "ignoreQueryFilter"], outputs: ["actionTriggered"] }, { kind: "component", type: Page, selector: "mt-page", inputs: ["backButton", "backButtonIcon", "avatarIcon", "avatarStyle", "avatarShape", "title", "tabs", "activeTab", "contentClass", "contentId"], outputs: ["backButtonClick", "tabChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
20418
20480
|
}
|
|
20419
20481
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DashboardViewer, decorators: [{
|
|
20420
20482
|
type: Component,
|
|
@@ -20424,8 +20486,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
20424
20486
|
ButtonModule,
|
|
20425
20487
|
DashboardItem,
|
|
20426
20488
|
Page,
|
|
20427
|
-
], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\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('dashboard')\r\n \"\r\n [backButton]=\"backButton()\"\r\n (backButtonClick)=\"onBack.emit()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"viewerContent\" />\r\n </mt-page>\r\n } @else {\r\n <!-- Non-page mode -->\r\n <ng-container *ngTemplateOutlet=\"viewerContent\" />\r\n }\r\n\r\n <!-- Reusable viewer content template -->\r\n <ng-template #viewerContent>\r\n <div class=\"relative h-full min-h-[600px] mt-dashboard-viewer\">\r\n @if (!loading() && hasRenderableContent()) {\r\n <div class=\"dashboard-viewer-layout-wrapper\">\r\n <div\r\n class=\"dashboard-viewer-layout\"\r\n [style.min-height]=\"layoutHeight()\"\r\n >\r\n @for (\r\n item of visibleItems();\r\n track trackByDashboardId($index, item)\r\n ) {\r\n <div\r\n class=\"dashboard-viewer-item\"\r\n [class.dashboard-viewer-item--group]=\"isGroup(item)\"\r\n [class.dashboard-viewer-item--header]=\"isHeader(item)\"\r\n [class.dashboard-viewer-item--topbar]=\"isTopbar(item)\"\r\n [style.grid-column]=\"getGridColumn(item)\"\r\n [style.grid-row]=\"getGridRow(item)\"\r\n >\r\n <!-- Group Container -->\r\n @if (isGroup(item)) {\r\n @if (!item.loading) {\r\n <div\r\n class=\"group-container h-full flex flex-col rounded-lg border border-surface-200 overflow-hidden\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'var(--surface-card)'\r\n \"\r\n >\r\n <!-- Group Header with Tabs -->\r\n <div\r\n class=\"group-header flex items-center justify-between px-4 py-2 bg-surface-50 border-b border-surface-200\"\r\n >\r\n <span class=\"font-medium text-sm\">{{\r\n getGroupTitle(item)\r\n }}</span>\r\n <div class=\"group-tabs flex items-center gap-1\">\r\n @for (\r\n child of getGroupChildren(item);\r\n track child.config?.serviceConfig?.dashboardId;\r\n let gIndex = $index\r\n ) {\r\n @if (getItemIcon(child); as icon) {\r\n <button\r\n type=\"button\"\r\n class=\"w-8 h-8 flex items-center justify-center rounded transition-colors\"\r\n [class.bg-primary-100]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.text-primary-600]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.text-muted-color]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n [class.hover:bg-surface-100]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n (click)=\"selectGroupChild(item, gIndex)\"\r\n >\r\n <i class=\"mti mti-{{ icon }}\"></i>\r\n </button>\r\n } @else {\r\n <button\r\n pButton\r\n type=\"button\"\r\n class=\"p-button-text p-button-sm\"\r\n [class.p-button-primary]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.p-button-secondary]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n [label]=\"getItemTitle(child)\"\r\n (click)=\"selectGroupChild(item, gIndex)\"\r\n ></button>\r\n }\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Group Body - Selected Child Content -->\r\n <div class=\"group-body flex-1 min-h-0 p-2\">\r\n @if (\r\n item.selectedGroupIndex !== null &&\r\n item.selectedGroupIndex !== undefined\r\n ) {\r\n @for (\r\n child of getGroupChildren(item);\r\n track child.config?.serviceConfig?.dashboardId;\r\n let cIndex = $index\r\n ) {\r\n @if (\r\n cIndex === item.selectedGroupIndex &&\r\n !child.loading\r\n ) {\r\n <div class=\"w-full h-full\">\r\n <mt-dashboard-item\r\n [config]=\"child.config\"\r\n [chartTypeId]=\"\r\n child.config?.serviceConfig?.dashboardId ||\r\n child.id\r\n \"\r\n [inGroup]=\"true\"\r\n >\r\n </mt-dashboard-item>\r\n </div>\r\n }\r\n }\r\n }\r\n </div>\r\n </div>\r\n }\r\n }\r\n <!-- Header Item -->\r\n @else if (isHeader(item)) {\r\n @if (!item.loading) {\r\n <div\r\n class=\"header-item flex items-center h-full px-4 border-b-2 border-primary\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'transparent'\r\n \"\r\n [style.color]=\"getStyleConfig(item)['color'] || 'inherit'\"\r\n >\r\n <h3 class=\"font-semibold text-lg m-0\">\r\n {{ getItemTitle(item) }}\r\n </h3>\r\n </div>\r\n }\r\n }\r\n <!-- Topbar Item -->\r\n @else if (isTopbar(item)) {\r\n @if (!item.loading) {\r\n <div\r\n class=\"topbar-item flex items-center h-full px-4 bg-surface-50\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'var(--surface-50)'\r\n \"\r\n >\r\n <nav class=\"flex items-center gap-2 text-sm\">\r\n @for (\r\n crumb of getBreadcrumb(item);\r\n track $index;\r\n let last = $last\r\n ) {\r\n <span\r\n class=\"text-muted-color hover:text-primary cursor-pointer transition-colors\"\r\n >\r\n {{\r\n crumb.label?.[languageCode()] ||\r\n crumb.label?.[\"en\"] ||\r\n crumb.label\r\n }}\r\n </span>\r\n @if (!last) {\r\n <i\r\n class=\"mti mti-chevron-right text-xs text-muted-color\"\r\n ></i>\r\n }\r\n }\r\n @if (getBreadcrumb(item).length === 0) {\r\n <span class=\"text-muted-color italic\">{{\r\n t(\"noBreadcrumb\")\r\n }}</span>\r\n }\r\n </nav>\r\n </div>\r\n }\r\n }\r\n <!-- Regular Chart Item -->\r\n @else {\r\n @if (!item.loading) {\r\n <div\r\n class=\"chart-item h-full flex flex-col rounded-lg border border-surface-200 overflow-hidden\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'var(--surface-card)'\r\n \"\r\n >\r\n <mt-dashboard-item\r\n [config]=\"item.config\"\r\n [chartTypeId]=\"\r\n item.config?.serviceConfig?.dashboardId || item.id\r\n \"\r\n [inGroup]=\"false\"\r\n >\r\n </mt-dashboard-item>\r\n </div>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Hidden Dialogs (for modal rendering) -->\r\n @if (dialogs().length > 0) {\r\n <div class=\"hidden\">\r\n @for (\r\n dialog of dialogs();\r\n track dialog.config?.serviceConfig?.dashboardId\r\n ) {\r\n <!-- Dialog placeholder - will be rendered in modal when triggered -->\r\n <div\r\n [attr.data-dialog-id]=\"\r\n dialog.config?.serviceConfig?.dashboardId\r\n \"\r\n ></div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Filters Sidebar Placeholder -->\r\n @if (showFilters() && filters().length > 0) {\r\n <div\r\n class=\"filters-sidebar fixed end-0 top-0 bottom-0 w-64 bg-surface-card border-s border-surface-200 p-4 shadow-lg z-50 hidden\"\r\n >\r\n <!-- Filter sidebar content - integrate with actual filter component -->\r\n <h4 class=\"font-semibold mb-4\">{{ t(\"filters\") }}</h4>\r\n @for (filter of filters(); track $index) {\r\n <div class=\"filter-item mb-3 p-2 bg-surface-50 rounded\">\r\n <span class=\"text-sm\">{{\r\n filter.label || filter.propertyKey\r\n }}</span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n } @else if (loading()) {\r\n <!-- Loading State -->\r\n <div class=\"flex items-center justify-center h-64\">\r\n <div class=\"text-center\">\r\n <i\r\n class=\"mti mti-loader-2 text-4xl text-primary animate-spin mb-2\"\r\n ></i>\r\n <p class=\"text-muted-color\">{{ t(\"loading\") }}</p>\r\n </div>\r\n </div>\r\n } @else {\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: [".mt-dashboard-viewer{width:100%;height:100%}.dashboard-viewer-layout-wrapper{width:100%}.dashboard-viewer-layout{display:grid;grid-template-columns:repeat(36,minmax(0,1fr));grid-auto-rows:60px;gap:10px;width:100%;align-items:stretch}.dashboard-viewer-item{min-width:0;min-height:0}.dashboard-viewer-item>*{width:100%;height:100%}.dashboard-viewer-item--header{z-index:1}.dashboard-viewer-item--topbar{z-index:2}.group-container{background-color:var(--surface-card)}.group-header{flex-shrink:0}.group-tabs{flex-wrap:wrap}.group-body{background-color:var(--surface-0)}.chart-item{background-color:var(--surface-card)}.header-item{background-color:transparent}.topbar-item{background-color:var(--surface-50)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.filters-sidebar{transform:translate(100%);transition:transform .3s ease-in-out}.filters-sidebar.open{transform:translate(0)}[dir=rtl] .filters-sidebar{transform:translate(-100%)}[dir=rtl] .filters-sidebar.open{transform:translate(0)}.table-responsive{max-height:75vh;overflow-y:auto;overflow-x:auto}.modal-content{border:0!important}.custom-donut-chart{display:flex;justify-content:center;height:auto!important}.custom-donut-chart canvas{margin-top:-1.5rem!important}@media(max-width:768px){.dashboard-viewer-layout{display:flex;flex-direction:column;min-height:0!important}.dashboard-viewer-item{min-height:220px}.dashboard-viewer-item--header,.dashboard-viewer-item--topbar{min-height:72px}.dashboard-viewer-item--group{min-height:280px}}\n"] }]
|
|
20428
|
-
}], propDecorators: { isPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "isPage", required: false }] }], pageTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageTitle", required: false }] }], backButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "backButton", required: false }] }], pageId: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageId", required: false }] }], dashboardData: [{ type: i0.Input, args: [{ isSignal: true, alias: "dashboardData", required: false }] }], chartsData: [{ type: i0.Input, args: [{ isSignal: true, alias: "chartsData", required: false }] }], dialogsData: [{ type: i0.Input, args: [{ isSignal: true, alias: "dialogsData", required: false }] }], filtersData: [{ type: i0.Input, args: [{ isSignal: true, alias: "filtersData", required: false }] }], showFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFilters", required: false }] }], pageLoaded: [{ type: i0.Output, args: ["pageLoaded"] }], onBack: [{ type: i0.Output, args: ["onBack"] }], chartClick: [{ type: i0.Output, args: ["chartClick"] }] } });
|
|
20489
|
+
], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\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('dashboard')\r\n \"\r\n [backButton]=\"backButton()\"\r\n (backButtonClick)=\"onBack.emit()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"viewerContent\" />\r\n </mt-page>\r\n } @else {\r\n <!-- Non-page mode -->\r\n <ng-container *ngTemplateOutlet=\"viewerContent\" />\r\n }\r\n\r\n <!-- Reusable viewer content template -->\r\n <ng-template #viewerContent>\r\n <div class=\"relative h-full min-h-[600px] mt-dashboard-viewer\">\r\n @if (!loading() && hasRenderableContent()) {\r\n <div class=\"dashboard-viewer-layout-wrapper\">\r\n <div\r\n class=\"dashboard-viewer-layout\"\r\n [style.min-height]=\"layoutHeight()\"\r\n >\r\n @for (\r\n item of visibleItems();\r\n track trackByDashboardId($index, item)\r\n ) {\r\n <div\r\n class=\"dashboard-viewer-item\"\r\n [class.dashboard-viewer-item--group]=\"isGroup(item)\"\r\n [class.dashboard-viewer-item--header]=\"isHeader(item)\"\r\n [class.dashboard-viewer-item--topbar]=\"isTopbar(item)\"\r\n [style.grid-column]=\"getGridColumn(item)\"\r\n [style.grid-row]=\"getGridRow(item)\"\r\n >\r\n <!-- Group Container -->\r\n @if (isGroup(item)) {\r\n @if (!item.loading) {\r\n <div\r\n class=\"group-container h-full flex flex-col rounded-lg border border-surface-200 overflow-hidden\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'var(--surface-card)'\r\n \"\r\n >\r\n <!-- Group Header with Tabs -->\r\n <div\r\n class=\"group-header flex items-center justify-between px-4 py-2 bg-surface-50 border-b border-surface-200\"\r\n >\r\n <span class=\"font-medium text-sm\">{{\r\n getGroupTitle(item)\r\n }}</span>\r\n <div class=\"group-tabs flex items-center gap-1\">\r\n @for (\r\n child of getGroupChildren(item);\r\n track child.config?.serviceConfig?.dashboardId;\r\n let gIndex = $index\r\n ) {\r\n @if (getItemIcon(child); as icon) {\r\n <button\r\n type=\"button\"\r\n class=\"w-8 h-8 flex items-center justify-center rounded transition-colors\"\r\n [class.bg-primary-100]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.text-primary-600]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.text-muted-color]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n [class.hover:bg-surface-100]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n (click)=\"selectGroupChild(item, gIndex)\"\r\n >\r\n <i class=\"mti mti-{{ icon }}\"></i>\r\n </button>\r\n } @else {\r\n <button\r\n pButton\r\n type=\"button\"\r\n class=\"p-button-text p-button-sm\"\r\n [class.p-button-primary]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.p-button-secondary]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n [label]=\"getItemTitle(child)\"\r\n (click)=\"selectGroupChild(item, gIndex)\"\r\n ></button>\r\n }\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Group Body - Selected Child Content -->\r\n <div class=\"group-body flex-1 min-h-0\">\n @if (\n item.selectedGroupIndex !== null &&\n item.selectedGroupIndex !== undefined\n ) {\n @for (\r\n child of getGroupChildren(item);\r\n track child.config?.serviceConfig?.dashboardId;\r\n let cIndex = $index\r\n ) {\r\n @if (\n cIndex === item.selectedGroupIndex &&\n !child.loading\n ) {\n <mt-dashboard-item\n class=\"dashboard-viewer-content-item\"\n [config]=\"child.config\"\n [chartTypeId]=\"\n child.config?.serviceConfig?.dashboardId ||\n child.id\n \"\n [extraFilters]=\"extraFilters()\"\n [ignoreQueryFilter]=\"\n pageConfig()?.dashboardConfig\n ?.ignoreQueryFilter ?? false\n \"\n [inGroup]=\"true\"\n >\n </mt-dashboard-item>\n }\n }\n }\n </div>\n </div>\r\n }\r\n }\r\n <!-- Header Item -->\r\n @else if (isHeader(item)) {\r\n @if (!item.loading) {\r\n <div\r\n class=\"header-item flex items-center h-full px-4 border-b-2 border-primary\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'transparent'\r\n \"\r\n [style.color]=\"getStyleConfig(item)['color'] || 'inherit'\"\r\n >\r\n <h3 class=\"font-semibold text-lg m-0\">\r\n {{ getItemTitle(item) }}\r\n </h3>\r\n </div>\r\n }\r\n }\r\n <!-- Topbar Item -->\r\n @else if (isTopbar(item)) {\r\n @if (!item.loading) {\r\n <div\r\n class=\"topbar-item flex items-center h-full px-4 bg-surface-50\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'var(--surface-50)'\r\n \"\r\n >\r\n <nav class=\"flex items-center gap-2 text-sm\">\r\n @for (\r\n crumb of getBreadcrumb(item);\r\n track $index;\r\n let last = $last\r\n ) {\r\n <span\r\n class=\"text-muted-color hover:text-primary cursor-pointer transition-colors\"\r\n >\r\n {{\r\n crumb.label?.[languageCode()] ||\r\n crumb.label?.[\"en\"] ||\r\n crumb.label\r\n }}\r\n </span>\r\n @if (!last) {\r\n <i\r\n class=\"mti mti-chevron-right text-xs text-muted-color\"\r\n ></i>\r\n }\r\n }\r\n @if (getBreadcrumb(item).length === 0) {\r\n <span class=\"text-muted-color italic\">{{\r\n t(\"noBreadcrumb\")\r\n }}</span>\r\n }\r\n </nav>\r\n </div>\r\n }\r\n }\r\n <!-- Regular Chart Item -->\n @else {\n @if (!item.loading) {\n <mt-dashboard-item\n class=\"dashboard-viewer-content-item\"\n [config]=\"item.config\"\n [chartTypeId]=\"\n item.config?.serviceConfig?.dashboardId || item.id\n \"\n [extraFilters]=\"extraFilters()\"\n [ignoreQueryFilter]=\"\n pageConfig()?.dashboardConfig?.ignoreQueryFilter ??\n false\n \"\n [inGroup]=\"false\"\n >\n </mt-dashboard-item>\n }\n }\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Hidden Dialogs (for modal rendering) -->\r\n @if (dialogs().length > 0) {\r\n <div class=\"hidden\">\r\n @for (\r\n dialog of dialogs();\r\n track dialog.config?.serviceConfig?.dashboardId\r\n ) {\r\n <!-- Dialog placeholder - will be rendered in modal when triggered -->\r\n <div\r\n [attr.data-dialog-id]=\"\r\n dialog.config?.serviceConfig?.dashboardId\r\n \"\r\n ></div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Filters Sidebar Placeholder -->\r\n @if (showFilters() && filters().length > 0) {\r\n <div\r\n class=\"filters-sidebar fixed end-0 top-0 bottom-0 w-64 bg-surface-card border-s border-surface-200 p-4 shadow-lg z-50 hidden\"\r\n >\r\n <!-- Filter sidebar content - integrate with actual filter component -->\r\n <h4 class=\"font-semibold mb-4\">{{ t(\"filters\") }}</h4>\r\n @for (filter of filters(); track $index) {\r\n <div class=\"filter-item mb-3 p-2 bg-surface-50 rounded\">\r\n <span class=\"text-sm\">{{\r\n filter.label || filter.propertyKey\r\n }}</span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n } @else if (loading()) {\r\n <!-- Loading State -->\r\n <div class=\"flex items-center justify-center h-64\">\r\n <div class=\"text-center\">\r\n <i\r\n class=\"mti mti-loader-2 text-4xl text-primary animate-spin mb-2\"\r\n ></i>\r\n <p class=\"text-muted-color\">{{ t(\"loading\") }}</p>\r\n </div>\r\n </div>\r\n } @else {\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: [".mt-dashboard-viewer{width:100%;height:100%}.dashboard-viewer-layout-wrapper{width:100%}.dashboard-viewer-layout{display:grid;grid-template-columns:repeat(36,minmax(0,1fr));grid-auto-rows:60px;gap:10px;width:100%;align-items:stretch}.dashboard-viewer-item{display:flex;min-width:0;min-height:0}.dashboard-viewer-item>*{width:100%;height:100%}.dashboard-viewer-content-item{display:block;flex:1 1 auto;min-width:0;min-height:0;width:100%;height:100%}.dashboard-viewer-item--header{z-index:1}.dashboard-viewer-item--topbar{z-index:2}.group-container{background-color:var(--surface-card)}.group-header{flex-shrink:0}.group-tabs{flex-wrap:wrap}.group-body{background-color:var(--surface-0)}.header-item{background-color:transparent}.topbar-item{background-color:var(--surface-50)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.filters-sidebar{transform:translate(100%);transition:transform .3s ease-in-out}.filters-sidebar.open{transform:translate(0)}[dir=rtl] .filters-sidebar{transform:translate(-100%)}[dir=rtl] .filters-sidebar.open{transform:translate(0)}.table-responsive{max-height:75vh;overflow-y:auto;overflow-x:auto}.modal-content{border:0!important}.custom-donut-chart{display:flex;justify-content:center;height:auto!important}.custom-donut-chart canvas{margin-top:-1.5rem!important}@media(max-width:768px){.dashboard-viewer-layout{display:flex;flex-direction:column;min-height:0!important}.dashboard-viewer-item{min-height:220px}.dashboard-viewer-item--header,.dashboard-viewer-item--topbar{min-height:72px}.dashboard-viewer-item--group{min-height:280px}}\n"] }]
|
|
20490
|
+
}], propDecorators: { isPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "isPage", required: false }] }], pageTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageTitle", required: false }] }], backButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "backButton", required: false }] }], pageId: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageId", required: false }] }], dashboardData: [{ type: i0.Input, args: [{ isSignal: true, alias: "dashboardData", required: false }] }], chartsData: [{ type: i0.Input, args: [{ isSignal: true, alias: "chartsData", required: false }] }], dialogsData: [{ type: i0.Input, args: [{ isSignal: true, alias: "dialogsData", required: false }] }], filtersData: [{ type: i0.Input, args: [{ isSignal: true, alias: "filtersData", required: false }] }], extraFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "extraFilters", required: false }] }], showFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFilters", required: false }] }], pageLoaded: [{ type: i0.Output, args: ["pageLoaded"] }], onBack: [{ type: i0.Output, args: ["onBack"] }], chartClick: [{ type: i0.Output, args: ["chartClick"] }] } });
|
|
20429
20491
|
|
|
20430
20492
|
/**
|
|
20431
20493
|
* Dashboard List Component
|
|
@@ -20631,7 +20693,7 @@ class DashboardList {
|
|
|
20631
20693
|
this.dashboards.reload();
|
|
20632
20694
|
}
|
|
20633
20695
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DashboardList, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20634
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DashboardList, isStandalone: true, selector: "mt-dashboard-list", inputs: { isPage: { classPropertyName: "isPage", publicName: "isPage", isSignal: true, isRequired: false, transformFunction: null }, pageTitle: { classPropertyName: "pageTitle", publicName: "pageTitle", isSignal: true, isRequired: false, transformFunction: null }, baseRoute: { classPropertyName: "baseRoute", publicName: "baseRoute", isSignal: true, isRequired: false, transformFunction: null }, showCreateButton: { classPropertyName: "showCreateButton", publicName: "showCreateButton", isSignal: true, isRequired: false, transformFunction: null }, showViewButton: { classPropertyName: "showViewButton", publicName: "showViewButton", isSignal: true, isRequired: false, transformFunction: null }, showEditButton: { classPropertyName: "showEditButton", publicName: "showEditButton", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dashboardAction: "dashboardAction", dashboardCreated: "dashboardCreated" }, viewQueries: [{ propertyName: "nameTpl", first: true, predicate: ["nameTpl"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder.dashboard'\">\r\n <!-- Page mode -->\r\n @if (isPage()) {\r\n <mt-page [title]=\"pageTitle() || t('dashboards')\">\r\n <!-- Header actions -->\r\n <ng-template #headerEnd>\r\n @if (showCreateButton()) {\r\n <mt-button\r\n [label]=\"t('createDashboard')\"\r\n icon=\"general.plus\"\r\n (onClick)=\"openCreateModal()\"\r\n severity=\"primary\"\r\n size=\"small\"\r\n />\r\n }\r\n </ng-template>\r\n\r\n <!-- Content -->\r\n <ng-container *ngTemplateOutlet=\"tableContent\" />\r\n </mt-page>\r\n } @else {\r\n <!-- Non-page mode -->\r\n <div class=\"dashboard-list space-y-3\">\r\n <!-- Header -->\r\n <div class=\"flex justify-between items-center gap-4\">\r\n <h2 class=\"text-2xl font-semibold text-surface-900 dark:text-surface-0\">\r\n {{ t(\"dashboards\") }}\r\n </h2>\r\n\r\n @if (showCreateButton()) {\r\n <mt-button\r\n [label]=\"t('createDashboard')\"\r\n icon=\"general.plus\"\r\n (onClick)=\"openCreateModal()\"\r\n severity=\"primary\"\r\n />\r\n }\r\n </div>\r\n\r\n <!-- Content -->\r\n <ng-container *ngTemplateOutlet=\"tableContent\" />\r\n </div>\r\n }\r\n\r\n <!-- Reusable table content template -->\r\n <ng-template #tableContent>\r\n <!-- Custom cell templates -->\r\n <ng-template #nameTpl let-row>\r\n <span class=\"font-semibold text-surface-900 dark:text-surface-0\">\r\n {{ getDashboardName(row) }}\r\n </span>\r\n </ng-template>\r\n\r\n <!-- Dashboard Table -->\r\n <mt-table\r\n [data]=\"dashboardList()\"\r\n [columns]=\"tableColumns()\"\r\n [rowActions]=\"rowActions()\"\r\n [loading]=\"isLoading()\"\r\n [showFilters]=\"true\"\r\n [generalSearch]=\"true\"\r\n dataKey=\"id\"\r\n />\r\n </ng-template>\r\n</ng-container>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { 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: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "showFilters", "loading", "updating", "lazy", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "exportable", "exportFilename", "actionShape", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "paginatorPosition", "pageSize", "currentPage", "first", "filterTerm"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange"] }, { kind: "component", type: Page, selector: "mt-page", inputs: ["backButton", "backButtonIcon", "avatarIcon", "avatarStyle", "avatarShape", "title", "tabs", "activeTab", "contentClass", "contentId"], outputs: ["backButtonClick", "tabChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
20696
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DashboardList, isStandalone: true, selector: "mt-dashboard-list", inputs: { isPage: { classPropertyName: "isPage", publicName: "isPage", isSignal: true, isRequired: false, transformFunction: null }, pageTitle: { classPropertyName: "pageTitle", publicName: "pageTitle", isSignal: true, isRequired: false, transformFunction: null }, baseRoute: { classPropertyName: "baseRoute", publicName: "baseRoute", isSignal: true, isRequired: false, transformFunction: null }, showCreateButton: { classPropertyName: "showCreateButton", publicName: "showCreateButton", isSignal: true, isRequired: false, transformFunction: null }, showViewButton: { classPropertyName: "showViewButton", publicName: "showViewButton", isSignal: true, isRequired: false, transformFunction: null }, showEditButton: { classPropertyName: "showEditButton", publicName: "showEditButton", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dashboardAction: "dashboardAction", dashboardCreated: "dashboardCreated" }, viewQueries: [{ propertyName: "nameTpl", first: true, predicate: ["nameTpl"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder.dashboard'\">\r\n <!-- Page mode -->\r\n @if (isPage()) {\r\n <mt-page [title]=\"pageTitle() || t('dashboards')\">\r\n <!-- Header actions -->\r\n <ng-template #headerEnd>\r\n @if (showCreateButton()) {\r\n <mt-button\r\n [label]=\"t('createDashboard')\"\r\n icon=\"general.plus\"\r\n (onClick)=\"openCreateModal()\"\r\n severity=\"primary\"\r\n size=\"small\"\r\n />\r\n }\r\n </ng-template>\r\n\r\n <!-- Content -->\r\n <ng-container *ngTemplateOutlet=\"tableContent\" />\r\n </mt-page>\r\n } @else {\r\n <!-- Non-page mode -->\r\n <div class=\"dashboard-list space-y-3\">\r\n <!-- Header -->\r\n <div class=\"flex justify-between items-center gap-4\">\r\n <h2 class=\"text-2xl font-semibold text-surface-900 dark:text-surface-0\">\r\n {{ t(\"dashboards\") }}\r\n </h2>\r\n\r\n @if (showCreateButton()) {\r\n <mt-button\r\n [label]=\"t('createDashboard')\"\r\n icon=\"general.plus\"\r\n (onClick)=\"openCreateModal()\"\r\n severity=\"primary\"\r\n />\r\n }\r\n </div>\r\n\r\n <!-- Content -->\r\n <ng-container *ngTemplateOutlet=\"tableContent\" />\r\n </div>\r\n }\r\n\r\n <!-- Reusable table content template -->\r\n <ng-template #tableContent>\r\n <!-- Custom cell templates -->\r\n <ng-template #nameTpl let-row>\r\n <span class=\"font-semibold text-surface-900 dark:text-surface-0\">\r\n {{ getDashboardName(row) }}\r\n </span>\r\n </ng-template>\r\n\r\n <!-- Dashboard Table -->\r\n <mt-table\r\n [data]=\"dashboardList()\"\r\n [columns]=\"tableColumns()\"\r\n [rowActions]=\"rowActions()\"\r\n [loading]=\"isLoading()\"\r\n [showFilters]=\"true\"\r\n [generalSearch]=\"true\"\r\n dataKey=\"id\"\r\n />\r\n </ng-template>\r\n</ng-container>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { 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: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "lazyLocalSearch", "showFilters", "loading", "updating", "lazy", "lazyLocalSort", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "exportable", "exportFilename", "actionShape", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "paginatorPosition", "pageSize", "currentPage", "first", "filterTerm"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange"] }, { kind: "component", type: Page, selector: "mt-page", inputs: ["backButton", "backButtonIcon", "avatarIcon", "avatarStyle", "avatarShape", "title", "tabs", "activeTab", "contentClass", "contentId"], outputs: ["backButtonClick", "tabChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
20635
20697
|
}
|
|
20636
20698
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DashboardList, decorators: [{
|
|
20637
20699
|
type: Component,
|