@acorex-platform/module-dashboard-management-client 0.0.38 → 0.0.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/fesm2022/{acorex-platform-module-dashboard-management-client-acorex-platform-module-dashboard-management-client-BUmHWNqL.mjs → acorex-platform-module-dashboard-management-client-acorex-platform-module-dashboard-management-client-Ey27MqFo.mjs} +976 -2957
  2. package/fesm2022/acorex-platform-module-dashboard-management-client-acorex-platform-module-dashboard-management-client-Ey27MqFo.mjs.map +1 -0
  3. package/fesm2022/acorex-platform-module-dashboard-management-client-bar-chart-widget.component-5c4X-lEC.mjs +151 -0
  4. package/fesm2022/acorex-platform-module-dashboard-management-client-bar-chart-widget.component-5c4X-lEC.mjs.map +1 -0
  5. package/fesm2022/acorex-platform-module-dashboard-management-client-chart-card-widget.component-BYdlIBv9.mjs +126 -0
  6. package/fesm2022/acorex-platform-module-dashboard-management-client-chart-card-widget.component-BYdlIBv9.mjs.map +1 -0
  7. package/fesm2022/acorex-platform-module-dashboard-management-client-chart-configurator-widget-column.component-DxNKy3bB.mjs +76 -0
  8. package/fesm2022/acorex-platform-module-dashboard-management-client-chart-configurator-widget-column.component-DxNKy3bB.mjs.map +1 -0
  9. package/fesm2022/acorex-platform-module-dashboard-management-client-chart-configurator-widget-edit.component-FhtkU52L.mjs +559 -0
  10. package/fesm2022/acorex-platform-module-dashboard-management-client-chart-configurator-widget-edit.component-FhtkU52L.mjs.map +1 -0
  11. package/fesm2022/acorex-platform-module-dashboard-management-client-chart-legend.util-C1zqTQEf.mjs +31 -0
  12. package/fesm2022/acorex-platform-module-dashboard-management-client-chart-legend.util-C1zqTQEf.mjs.map +1 -0
  13. package/fesm2022/acorex-platform-module-dashboard-management-client-chart-widget-data.util-DgCBHS1p.mjs +589 -0
  14. package/fesm2022/acorex-platform-module-dashboard-management-client-chart-widget-data.util-DgCBHS1p.mjs.map +1 -0
  15. package/fesm2022/acorex-platform-module-dashboard-management-client-contracts-entities-dashboard.mjs +30 -1
  16. package/fesm2022/acorex-platform-module-dashboard-management-client-contracts-entities-dashboard.mjs.map +1 -1
  17. package/fesm2022/{acorex-platform-module-dashboard-management-client-contracts-entity-catalog-acorex-platform-module-dashboard-management-client-contracts-entity-catalog-CPDwiLWC.mjs → acorex-platform-module-dashboard-management-client-contracts-entity-catalog-acorex-platform-module-dashboard-management-client-contracts-entity-catalog-C3ZKIYgQ.mjs} +2 -2
  18. package/fesm2022/{acorex-platform-module-dashboard-management-client-contracts-entity-catalog-acorex-platform-module-dashboard-management-client-contracts-entity-catalog-CPDwiLWC.mjs.map → acorex-platform-module-dashboard-management-client-contracts-entity-catalog-acorex-platform-module-dashboard-management-client-contracts-entity-catalog-C3ZKIYgQ.mjs.map} +1 -1
  19. package/fesm2022/{acorex-platform-module-dashboard-management-client-contracts-entity-catalog-dashboard.entity-C1ju-BQM.mjs → acorex-platform-module-dashboard-management-client-contracts-entity-catalog-dashboard.entity-D2uqZMd4.mjs} +32 -3
  20. package/fesm2022/acorex-platform-module-dashboard-management-client-contracts-entity-catalog-dashboard.entity-D2uqZMd4.mjs.map +1 -0
  21. package/fesm2022/acorex-platform-module-dashboard-management-client-contracts-entity-catalog.mjs +1 -1
  22. package/fesm2022/acorex-platform-module-dashboard-management-client-contracts.mjs +21 -1
  23. package/fesm2022/acorex-platform-module-dashboard-management-client-contracts.mjs.map +1 -1
  24. package/fesm2022/acorex-platform-module-dashboard-management-client-donut-chart-widget.component-DRiIRbhX.mjs +145 -0
  25. package/fesm2022/acorex-platform-module-dashboard-management-client-donut-chart-widget.component-DRiIRbhX.mjs.map +1 -0
  26. package/fesm2022/acorex-platform-module-dashboard-management-client-funnel-chart-widget.component-BPY1NchM.mjs +135 -0
  27. package/fesm2022/acorex-platform-module-dashboard-management-client-funnel-chart-widget.component-BPY1NchM.mjs.map +1 -0
  28. package/fesm2022/acorex-platform-module-dashboard-management-client-gauge-chart-widget.component-Cy6fgife.mjs +138 -0
  29. package/fesm2022/acorex-platform-module-dashboard-management-client-gauge-chart-widget.component-Cy6fgife.mjs.map +1 -0
  30. package/fesm2022/acorex-platform-module-dashboard-management-client-heatmap-chart-widget.component-CTelqGbm.mjs +154 -0
  31. package/fesm2022/acorex-platform-module-dashboard-management-client-heatmap-chart-widget.component-CTelqGbm.mjs.map +1 -0
  32. package/fesm2022/{acorex-platform-module-dashboard-management-client-index-C1Te5cDf.mjs → acorex-platform-module-dashboard-management-client-index-P-PzUrbN.mjs} +3 -3
  33. package/fesm2022/{acorex-platform-module-dashboard-management-client-index-C1Te5cDf.mjs.map → acorex-platform-module-dashboard-management-client-index-P-PzUrbN.mjs.map} +1 -1
  34. package/fesm2022/acorex-platform-module-dashboard-management-client-line-chart-widget.component-B18VZb9t.mjs +158 -0
  35. package/fesm2022/acorex-platform-module-dashboard-management-client-line-chart-widget.component-B18VZb9t.mjs.map +1 -0
  36. package/fesm2022/acorex-platform-module-dashboard-management-client.mjs +1 -1
  37. package/package.json +1 -1
  38. package/types/acorex-platform-module-dashboard-management-client-contracts.d.ts +19 -5
  39. package/types/acorex-platform-module-dashboard-management-client.d.ts +49 -267
  40. package/fesm2022/acorex-platform-module-dashboard-management-client-acorex-platform-module-dashboard-management-client-BUmHWNqL.mjs.map +0 -1
  41. package/fesm2022/acorex-platform-module-dashboard-management-client-contracts-entity-catalog-dashboard.entity-C1ju-BQM.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"acorex-platform-module-dashboard-management-client-contracts.mjs","sources":["../../../../libs/modules/dashboard-management/contracts/src/features.keys.ts","../../../../libs/modules/dashboard-management/contracts/src/menu.keys.ts","../../../../libs/modules/dashboard-management/contracts/src/permission.keys.ts","../../../../libs/modules/dashboard-management/contracts/src/settings.keys.ts","../../../../libs/modules/dashboard-management/contracts/src/DASHBOARD_LAYOUT_PAGE_COMPONENT_KEY.ts","../../../../libs/modules/dashboard-management/contracts/src/root-config.ts","../../../../libs/modules/dashboard-management/contracts/src/dashboard-scope.types.ts","../../../../libs/modules/dashboard-management/contracts/src/dashboard.types.ts","../../../../libs/modules/dashboard-management/contracts/src/chart-query.types.ts","../../../../libs/modules/dashboard-management/contracts/src/chart-card.types.ts","../../../../libs/modules/dashboard-management/contracts/src/entities/dashboard/dashboard-scope.util.ts","../../../../libs/modules/dashboard-management/contracts/src/index.ts","../../../../libs/modules/dashboard-management/contracts/src/acorex-platform-module-dashboard-management-client-contracts.ts"],"sourcesContent":["// Management feature removed - module name is used directly as feature key\nexport const AXPDashboardManagementFeatureKeys = {} as const;\n\n","export const AXPDashboardManagementMenuKeys = {\n Root: 'DashboardManagement:Menu',\n Dashboards: 'DashboardManagement:Menu:Dashboards',\n} as const;\n\n","/**\n * Administration capabilities used by this module.\n * Domain capability keys for this module. Root groups live in `AXPCommonPermissionGroupKeys` (common contracts).\n */\nexport const AXPAdministrationPermissionKeys = {\n Access: 'Administration:Permission:Access',\n MaintainUsersAndRoles: 'Administration:Permission:MaintainUsersAndRoles',\n ManageSessions: 'Administration:Permission:ManageSessions',\n MaintainPolicies: 'Administration:Permission:MaintainPolicies',\n ViewIntegrations: 'Administration:Permission:ViewIntegrations',\n MaintainConnections: 'Administration:Permission:MaintainConnections',\n MaintainWorkflows: 'Administration:Permission:MaintainWorkflows',\n ManageWorkflowActions: 'Administration:Permission:ManageWorkflowActions',\n ViewRules: 'Administration:Permission:ViewRules',\n MaintainRules: 'Administration:Permission:MaintainRules',\n ManageRuleActions: 'Administration:Permission:ManageRuleActions',\n MaintainAi: 'Administration:Permission:MaintainAi',\n UseAiAssist: 'Administration:Permission:UseAiAssist',\n MaintainDashboards: 'Administration:Permission:MaintainDashboards',\n ViewJobs: 'Administration:Permission:ViewJobs',\n ManageJobActions: 'Administration:Permission:ManageJobActions',\n ViewObservability: 'Administration:Permission:ViewObservability',\n MaintainObservability: 'Administration:Permission:MaintainObservability',\n} as const;\n\n/**\n * @deprecated Prefer {@link AXPAdministrationPermissionKeys}.\n * Legacy nested shape kept so existing imports compile during migration.\n */\nexport const AXMPermissionsKeys = {\n DashboardManagement: {\n Management: AXPAdministrationPermissionKeys.MaintainDashboards,\n Dashboard: {\n Management: AXPAdministrationPermissionKeys.MaintainDashboards,\n View: AXPAdministrationPermissionKeys.MaintainDashboards,\n Edit: AXPAdministrationPermissionKeys.MaintainDashboards,\n Delete: AXPAdministrationPermissionKeys.MaintainDashboards,\n Create: AXPAdministrationPermissionKeys.MaintainDashboards,\n },\n },\n} as const;\n","export enum AXPHomeDashboardSetting {\n CurrentDashboard = 'DashboardManagement:Setting:Home.CurrentDashboard',\n}\n","/** Component key for the dashboard Layout page tab. Register via AXP_PAGE_COMPONENT_PROVIDER. */\nexport const DASHBOARD_LAYOUT_PAGE_COMPONENT_KEY = 'dashboard-layout-page';\n","const config = {\n i18n: 'dashboard-management',\n module: 'DashboardManagement',\n} as const;\n\n/** Builds shared dashboard widget type ids: `{module}:Widget:Dashboard:{Segment}`. */\nconst dashboardWidgetId = (segment: string): string =>\n `${config.module}:Widget:Dashboard:${segment}`;\n\nexport const RootConfig = {\n config,\n module: {\n module: config.module,\n name: config.module,\n title: `@${config.i18n}:module.title`,\n icon: 'fa-regular fa-tachometer-alt',\n },\n entities: {\n dashboard: {\n name: 'Dashboard',\n title: '@dashboard-management:dashboards.terms.dashboard',\n titlePlural: '@dashboard-management:dashboards.terms.dashboards',\n icon: 'fa-regular fa-tachometer-alt',\n },\n },\n /** Dashboard widget type ids owned by dashboard-management. */\n widgets: {\n barChart: dashboardWidgetId('BarChart'),\n donutChart: dashboardWidgetId('DonutChart'),\n lineChart: dashboardWidgetId('LineChart'),\n gaugeChart: dashboardWidgetId('GaugeChart'),\n funnelChart: dashboardWidgetId('FunnelChart'),\n heatmapChart: dashboardWidgetId('HeatmapChart'),\n chartCard: dashboardWidgetId('ChartCard'),\n stickyNote: dashboardWidgetId('StickyNote'),\n clockCalendar: dashboardWidgetId('ClockCalendar'),\n weather: dashboardWidgetId('Weather'),\n shortcut: dashboardWidgetId('Shortcut'),\n kpiProgress: dashboardWidgetId('KpiProgress'),\n kpiSegmented: dashboardWidgetId('KpiSegmented'),\n kpiDetails: dashboardWidgetId('KpiDetails'),\n kpiStatCard: dashboardWidgetId('KpiStatCard'),\n },\n /**\n * @deprecated Dashboard queries moved to owning modules (`{Module}:Dashboard:*`).\n * Update seeds/widgets to module keys; these aliases remain for transitional references only.\n */\n queries: {\n tenantAdmin: {\n activeUsersKpi: `${config.module}:Dashboard:TenantAdmin:ActiveUsersKpi`,\n employeesKpi: `${config.module}:Dashboard:TenantAdmin:EmployeesKpi`,\n openTasksKpi: `${config.module}:Dashboard:TenantAdmin:OpenTasksKpi`,\n activeProjectsKpi: `${config.module}:Dashboard:TenantAdmin:ActiveProjectsKpi`,\n openHazardsKpi: `${config.module}:Dashboard:TenantAdmin:OpenHazardsKpi`,\n documentsKpi: `${config.module}:Dashboard:TenantAdmin:DocumentsKpi`,\n workflowDefinitionsKpi: `${config.module}:Dashboard:TenantAdmin:WorkflowDefinitionsKpi`,\n subscriptionKpi: `${config.module}:Dashboard:TenantAdmin:SubscriptionKpi`,\n usersByRoleDonut: `${config.module}:Dashboard:TenantAdmin:UsersByRoleDonut`,\n taskStatusDonut: `${config.module}:Dashboard:TenantAdmin:TaskStatusDonut`,\n deliveryStatusDonut: `${config.module}:Dashboard:TenantAdmin:DeliveryStatusDonut`,\n integrationsDonut: `${config.module}:Dashboard:TenantAdmin:IntegrationsDonut`,\n jobsByStatusBar: `${config.module}:Dashboard:TenantAdmin:JobsByStatusBar`,\n jobSchedulesByStatusBar: `${config.module}:Dashboard:TenantAdmin:JobSchedulesByStatusBar`,\n workflowsByStatusBar: `${config.module}:Dashboard:TenantAdmin:WorkflowsByStatusBar`,\n teamsBar: `${config.module}:Dashboard:TenantAdmin:TeamsBar`,\n projectsByStatusBar: `${config.module}:Dashboard:TenantAdmin:ProjectsByStatusBar`,\n trainingComplianceGauge: `${config.module}:Dashboard:TenantAdmin:TrainingComplianceGauge`,\n },\n },\n};\n","//#region ---- Dashboard Scope Types ----\n\n/**\n * Dashboard visibility scope.\n * - `T`: Tenant shared dashboard\n * - `U`: User personal dashboard\n * - `E`: Entity-scoped dashboard\n */\nexport type AXMDashboardScope = 'U' | 'T' | 'E';\n\n/** Scope reference for personal dashboards. */\nexport interface AXMDashboardUserScopeRef {\n userId: string;\n}\n\n/** Scope reference for tenant dashboards. */\nexport interface AXMDashboardTenantScopeRef {\n tenantId: string;\n roleIds: string[];\n}\n\n/** Scope reference for entity-type dashboards (one layout shared by all records of the type). */\nexport interface AXMDashboardEntityScopeRef {\n entityType: string;\n}\n\n/**\n * Scope-specific reference payload.\n * Shape depends on {@link AXMDashboardScope}.\n */\nexport type AXMDashboardScopeRef =\n | AXMDashboardUserScopeRef\n | AXMDashboardTenantScopeRef\n | AXMDashboardEntityScopeRef;\n\n//#endregion\n","import type { AXMDashboardScope, AXMDashboardScopeRef } from './dashboard-scope.types';\n\nexport type { AXMDashboardScope, AXMDashboardScopeRef } from './dashboard-scope.types';\n\n//#region ---- Widget Layout Contract Types ----\n\n/** Grid size preset as `[width, height]` in column/row units. */\nexport type AXGridLayoutSize = readonly [width: number, height: number];\n\nexport interface AXGridLayoutNode {\n id?: string;\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n minWidth?: number;\n minHeight?: number;\n maxWidth?: number;\n maxHeight?: number;\n /** When set, resize snaps to one of these `[width, height]` presets. */\n allowedSizes?: readonly AXGridLayoutSize[];\n}\n\nexport type AXMDashboardBreakpoint = 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl';\n\nexport interface AXMDashboardWidgetLayoutMap {\n id: string;\n title?: string;\n lg: AXGridLayoutNode;\n md: AXGridLayoutNode;\n sm: AXGridLayoutNode;\n xl?: AXGridLayoutNode;\n '2xl'?: AXGridLayoutNode;\n '3xl'?: AXGridLayoutNode;\n '4xl'?: AXGridLayoutNode;\n}\n\nexport interface AXMDashboardWidgetData {\n config: AXMDashboardWidgetLayoutMap;\n node?: unknown;\n}\n\n//#endregion\n\n//#region ---- Dashboard Entity Contract Types ----\n\nexport type AXPMultiLanguageString = string | Record<string, string>;\n\nexport interface AXPEntityModel<Id> {\n id: Id;\n auditInfo?: {\n created?: { at?: string | Date; by?: { id: string; type?: string } };\n updated?: { at?: string | Date; by?: { id: string; type?: string } };\n };\n stateInfo?: Record<string, unknown>;\n scopeInfo?: { tenantId?: string; userId?: string; applicationId?: string };\n}\n\nexport interface AXMCommonDashboardEntityModel extends AXPEntityModel<string> {\n title: AXPMultiLanguageString;\n description?: AXPMultiLanguageString;\n widgets: AXMDashboardWidgetData[];\n isArchived?: boolean;\n archivedAt?: string | Date;\n locked?: boolean;\n scope: AXMDashboardScope;\n scopeRef: AXMDashboardScopeRef;\n categoryIds?: string[];\n}\n\n//#endregion\n","/**\n * Strict DTOs for dashboard chart / KPI queries.\n * Chart widgets fetch an AXPQuery whose result matches one of these shapes.\n */\n\n//#region ---- Result type keys (query metadata `resultType`) ----\n\n/** Stable result-type ids stored on query definitions for designer filtering. */\nexport const AXP_CHART_QUERY_RESULT_TYPE = {\n barSeries: 'AXPBarChartQueryResult',\n lineSeries: 'AXPLineChartQueryResult',\n donutSeries: 'AXPDonutChartQueryResult',\n gaugeValue: 'AXPGaugeChartQueryResult',\n funnelSeries: 'AXPFunnelChartQueryResult',\n heatmapSeries: 'AXPHeatmapChartQueryResult',\n kpiStatCard: 'AXPKpiStatCardQueryResult',\n kpiSegmented: 'AXPKpiSegmentedQueryResult',\n kpiProgress: 'AXPKpiProgressQueryResult',\n kpiDetails: 'AXPKpiDetailsQueryResult',\n} as const;\n\nexport type AXPChartQueryResultType =\n (typeof AXP_CHART_QUERY_RESULT_TYPE)[keyof typeof AXP_CHART_QUERY_RESULT_TYPE];\n\n//#endregion\n\n//#region ---- Series item shapes ----\n\nexport interface AXPBarChartQueryItem {\n id: string;\n label: string;\n value: number;\n color?: string;\n tooltipLabel?: string;\n}\n\nexport interface AXPLineChartQueryPoint {\n x: number | string;\n y: number;\n tooltipLabel?: string;\n}\n\nexport interface AXPLineChartQuerySeries {\n id?: string;\n label?: string;\n lineColor?: string;\n fillColor?: string;\n data: AXPLineChartQueryPoint[];\n}\n\nexport interface AXPDonutChartQueryItem {\n id: string;\n label: string;\n value: number;\n color?: string;\n tooltipLabel?: string;\n}\n\nexport interface AXPFunnelChartQueryItem {\n id?: string;\n name: string;\n value: number;\n color?: string;\n}\n\nexport interface AXPHeatmapChartQueryItem {\n x: number | string;\n y: number | string;\n value: number;\n label?: string;\n}\n\n//#endregion\n\n//#region ---- Query result envelopes ----\n\nexport interface AXPBarChartQueryResult {\n items: AXPBarChartQueryItem[];\n}\n\nexport interface AXPLineChartQueryResult {\n series: AXPLineChartQuerySeries[];\n}\n\nexport interface AXPDonutChartQueryResult {\n items: AXPDonutChartQueryItem[];\n}\n\nexport interface AXPGaugeChartQueryResult {\n value: number;\n}\n\nexport interface AXPFunnelChartQueryResult {\n items: AXPFunnelChartQueryItem[];\n}\n\nexport interface AXPHeatmapChartQueryResult {\n items: AXPHeatmapChartQueryItem[];\n}\n\nexport interface AXPKpiStatCardQueryResult {\n title?: string;\n titleBadgeText?: string;\n titleBadgeTone?: string;\n value?: number | string;\n valuePrefix?: string;\n valueSuffix?: string;\n format?: {\n style?: 'decimal' | 'currency' | 'percent';\n currency?: string;\n minimumFractionDigits?: number;\n maximumFractionDigits?: number;\n };\n icon?: string;\n iconTone?: string;\n trendValue?: string;\n trendLabel?: string;\n trendStatus?: 'success' | 'danger' | 'neutral';\n}\n\nexport interface AXPKpiSegmentedQueryResult {\n title?: string;\n icon?: string;\n segments: Array<{ label: string; value: number; color?: string }>;\n}\n\nexport interface AXPKpiProgressQueryResult {\n title?: string;\n icon?: string;\n value?: number | string;\n valuePrefix?: string;\n valueSuffix?: string;\n subtitle?: string;\n targetValue?: number | string;\n progressValue?: number;\n progressPercent?: number;\n}\n\nexport interface AXPKpiDetailsQueryResult {\n title?: string;\n value?: number | string;\n valuePrefix?: string;\n valueSuffix?: string;\n subtitle?: string;\n details: Array<{ label: string; value: string | number; color?: string }>;\n}\n\n//#endregion\n\n//#region ---- Widget options ----\n\n/** Chart/KPI widget options for data binding (dashboard query and/or AI inline data). */\nexport interface AXPChartQueryWidgetOptions {\n /** Runtime AXPQuery key (e.g. `PlatformManagement:Dashboard:TenantsByStatusBar`). */\n query?: string;\n /** Optional input payload passed to `queryExecutor.fetch(query, queryInput)`. */\n queryInput?: Record<string, unknown>;\n /** Inline chart rows/series for AI chat (see chart-widget-data.util.ts). */\n dataSource?: unknown;\n}\n\n//#endregion\n","/**\n * Chart card options: one dashboard tile hosting mixed-type chart tabs.\n * Each tab is an {@link AXPWidgetNode} of a typed chart widget (donut, bar, line, gauge).\n */\n\nimport type { AXPWidgetNode } from '@acorex-platform/framework-shared/core';\n\n//#region ----- Types -----\n\n/** Editor widget name used as the repeater row in chart-card properties. */\nexport const AXP_CHART_CONFIGURATOR_WIDGET_NAME = 'chart-configurator';\n\nexport interface AXPChartCardWidgetOptions {\n /** Card heading (domain name). */\n title?: string;\n /** One typed chart widget node per tab. */\n tabs?: AXPWidgetNode[];\n}\n\n//#endregion\n","//#region ---- Imports ----\n\nimport { castArray, get, isArray, isString } from 'lodash';\n\nimport type {\n AXMDashboardEntityScopeRef,\n AXMDashboardScope,\n AXMDashboardScopeRef,\n AXMDashboardTenantScopeRef,\n AXMDashboardUserScopeRef,\n} from '../../dashboard-scope.types';\n\n//#endregion\n\n//#region ---- Builders ----\n\nexport function buildUserScopeRef(userId: string): AXMDashboardUserScopeRef {\n return { userId: userId.trim() };\n}\n\nexport function buildTenantScopeRef(tenantId: string, roleIds: readonly string[]): AXMDashboardTenantScopeRef {\n return {\n tenantId: tenantId.trim(),\n roleIds: [...new Set(roleIds.map((id) => id.trim()).filter(Boolean))],\n };\n}\n\nexport function buildEntityScopeRef(entityType: string): AXMDashboardEntityScopeRef {\n return { entityType: entityType.trim() };\n}\n\n//#endregion\n\n//#region ---- Readers ----\n\nexport function readScopeUserId(scopeRef: AXMDashboardScopeRef | undefined): string | undefined {\n const userId = get(scopeRef, 'userId');\n return isString(userId) && userId.trim() ? userId.trim() : undefined;\n}\n\nexport function readScopeTenantId(scopeRef: AXMDashboardScopeRef | undefined): string | undefined {\n const tenantId = get(scopeRef, 'tenantId');\n return isString(tenantId) && tenantId.trim() ? tenantId.trim() : undefined;\n}\n\nexport function readScopeRoleIds(scopeRef: AXMDashboardScopeRef | undefined): string[] {\n const roleIds = get(scopeRef, 'roleIds');\n if (!isArray(roleIds)) {\n return [];\n }\n return roleIds.filter((id): id is string => isString(id) && id.trim().length > 0);\n}\n\nexport function readScopeEntityType(scopeRef: AXMDashboardScopeRef | undefined): string | undefined {\n const entityType = get(scopeRef, 'entityType');\n return isString(entityType) && entityType.trim() ? entityType.trim() : undefined;\n}\n\n//#endregion\n\n//#region ---- Normalization ----\n\n/**\n * Ensures {@link scopeRef} matches {@link scope} and strips incompatible keys.\n */\nexport function normalizeDashboardScopeRef(\n scope: AXMDashboardScope,\n scopeRef: unknown,\n fallback?: Partial<{\n userId: string;\n tenantId: string;\n roleIds: readonly string[];\n entityType: string;\n }>,\n): AXMDashboardScopeRef {\n switch (scope) {\n case 'U':\n return buildUserScopeRef(readScopeUserId(scopeRef as AXMDashboardScopeRef) ?? fallback?.userId ?? '');\n case 'T':\n return buildTenantScopeRef(\n readScopeTenantId(scopeRef as AXMDashboardScopeRef) ?? fallback?.tenantId ?? '',\n readScopeRoleIds(scopeRef as AXMDashboardScopeRef).length > 0\n ? readScopeRoleIds(scopeRef as AXMDashboardScopeRef)\n : castArray(fallback?.roleIds ?? []),\n );\n case 'E':\n return buildEntityScopeRef(\n readScopeEntityType(scopeRef as AXMDashboardScopeRef) ?? fallback?.entityType ?? '',\n );\n default:\n return buildUserScopeRef(fallback?.userId ?? '');\n }\n}\n\n//#endregion\n","//#region ---- Contracts barrel ----\n\nexport * from './features.keys';\nexport * from './menu.keys';\nexport * from './permission.keys';\nexport * from './settings.keys';\n\nexport * from './DASHBOARD_LAYOUT_PAGE_COMPONENT_KEY';\n\nexport * from './root-config';\n\nexport * from './dashboard-scope.types';\nexport * from './dashboard.types';\nexport * from './chart-query.types';\nexport * from './chart-card.types';\n\n//#endregion\n\nexport * from './entities';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"acorex-platform-module-dashboard-management-client-contracts.mjs","sources":["../../../../libs/modules/dashboard-management/contracts/src/features.keys.ts","../../../../libs/modules/dashboard-management/contracts/src/menu.keys.ts","../../../../libs/modules/dashboard-management/contracts/src/permission.keys.ts","../../../../libs/modules/dashboard-management/contracts/src/settings.keys.ts","../../../../libs/modules/dashboard-management/contracts/src/DASHBOARD_LAYOUT_PAGE_COMPONENT_KEY.ts","../../../../libs/modules/dashboard-management/contracts/src/root-config.ts","../../../../libs/modules/dashboard-management/contracts/src/manifest.ts","../../../../libs/modules/dashboard-management/contracts/src/dashboard-scope.types.ts","../../../../libs/modules/dashboard-management/contracts/src/dashboard.types.ts","../../../../libs/modules/dashboard-management/contracts/src/chart-query.types.ts","../../../../libs/modules/dashboard-management/contracts/src/chart-card.types.ts","../../../../libs/modules/dashboard-management/contracts/src/entities/dashboard/dashboard-scope.util.ts","../../../../libs/modules/dashboard-management/contracts/src/index.ts","../../../../libs/modules/dashboard-management/contracts/src/acorex-platform-module-dashboard-management-client-contracts.ts"],"sourcesContent":["// Management feature removed - module name is used directly as feature key\nexport const AXPDashboardManagementFeatureKeys = {} as const;\n\n","export const AXPDashboardManagementMenuKeys = {\n Root: 'DashboardManagement:Menu',\n Dashboards: 'DashboardManagement:Menu:Dashboards',\n} as const;\n\n","/**\n * Administration capabilities used by this module.\n * Domain capability keys for this module. Root groups live in `AXPCommonPermissionGroupKeys` (common contracts).\n */\nexport const AXPAdministrationPermissionKeys = {\n Access: 'Administration:Permission:Access',\n MaintainUsersAndRoles: 'Administration:Permission:MaintainUsersAndRoles',\n ManageSessions: 'Administration:Permission:ManageSessions',\n MaintainPolicies: 'Administration:Permission:MaintainPolicies',\n ViewIntegrations: 'Administration:Permission:ViewIntegrations',\n MaintainConnections: 'Administration:Permission:MaintainConnections',\n MaintainWorkflows: 'Administration:Permission:MaintainWorkflows',\n ManageWorkflowActions: 'Administration:Permission:ManageWorkflowActions',\n ViewRules: 'Administration:Permission:ViewRules',\n MaintainRules: 'Administration:Permission:MaintainRules',\n ManageRuleActions: 'Administration:Permission:ManageRuleActions',\n MaintainAi: 'Administration:Permission:MaintainAi',\n UseAiAssist: 'Administration:Permission:UseAiAssist',\n MaintainDashboards: 'Administration:Permission:MaintainDashboards',\n ViewJobs: 'Administration:Permission:ViewJobs',\n ManageJobActions: 'Administration:Permission:ManageJobActions',\n ViewObservability: 'Administration:Permission:ViewObservability',\n MaintainObservability: 'Administration:Permission:MaintainObservability',\n} as const;\n\n/**\n * @deprecated Prefer {@link AXPAdministrationPermissionKeys}.\n * Legacy nested shape kept so existing imports compile during migration.\n */\nexport const AXMPermissionsKeys = {\n DashboardManagement: {\n Management: AXPAdministrationPermissionKeys.MaintainDashboards,\n Dashboard: {\n Management: AXPAdministrationPermissionKeys.MaintainDashboards,\n View: AXPAdministrationPermissionKeys.MaintainDashboards,\n Edit: AXPAdministrationPermissionKeys.MaintainDashboards,\n Delete: AXPAdministrationPermissionKeys.MaintainDashboards,\n Create: AXPAdministrationPermissionKeys.MaintainDashboards,\n },\n },\n} as const;\n","export enum AXPHomeDashboardSetting {\n CurrentDashboard = 'DashboardManagement:Setting:Home.CurrentDashboard',\n}\n","/** Component key for the dashboard Layout page tab. Register via AXP_PAGE_COMPONENT_PROVIDER. */\nexport const DASHBOARD_LAYOUT_PAGE_COMPONENT_KEY = 'dashboard-layout-page';\n","const config = {\n i18n: 'dashboard-management',\n module: 'DashboardManagement',\n} as const;\n\n/** Builds shared dashboard widget type ids: `{module}:Widget:Dashboard:{Segment}`. */\nconst dashboardWidgetId = (segment: string): string =>\n `${config.module}:Widget:Dashboard:${segment}`;\n\nexport const RootConfig = {\n config,\n module: {\n module: config.module,\n name: config.module,\n title: `@${config.i18n}:module.title`,\n icon: 'fa-regular fa-tachometer-alt',\n },\n entities: {\n dashboard: {\n name: 'Dashboard',\n title: '@dashboard-management:dashboards.terms.dashboard',\n titlePlural: '@dashboard-management:dashboards.terms.dashboards',\n icon: 'fa-regular fa-tachometer-alt',\n },\n },\n /** Dashboard widget type ids owned by dashboard-management. */\n widgets: {\n barChart: dashboardWidgetId('BarChart'),\n donutChart: dashboardWidgetId('DonutChart'),\n lineChart: dashboardWidgetId('LineChart'),\n gaugeChart: dashboardWidgetId('GaugeChart'),\n funnelChart: dashboardWidgetId('FunnelChart'),\n heatmapChart: dashboardWidgetId('HeatmapChart'),\n chartCard: dashboardWidgetId('ChartCard'),\n stickyNote: dashboardWidgetId('StickyNote'),\n clockCalendar: dashboardWidgetId('ClockCalendar'),\n weather: dashboardWidgetId('Weather'),\n shortcut: dashboardWidgetId('Shortcut'),\n kpiProgress: dashboardWidgetId('KpiProgress'),\n kpiSegmented: dashboardWidgetId('KpiSegmented'),\n kpiDetails: dashboardWidgetId('KpiDetails'),\n kpiStatCard: dashboardWidgetId('KpiStatCard'),\n },\n /**\n * @deprecated Dashboard queries moved to owning modules (`{Module}:Dashboard:*`).\n * Update seeds/widgets to module keys; these aliases remain for transitional references only.\n */\n queries: {\n tenantAdmin: {\n activeUsersKpi: `${config.module}:Dashboard:TenantAdmin:ActiveUsersKpi`,\n employeesKpi: `${config.module}:Dashboard:TenantAdmin:EmployeesKpi`,\n openTasksKpi: `${config.module}:Dashboard:TenantAdmin:OpenTasksKpi`,\n activeProjectsKpi: `${config.module}:Dashboard:TenantAdmin:ActiveProjectsKpi`,\n openHazardsKpi: `${config.module}:Dashboard:TenantAdmin:OpenHazardsKpi`,\n documentsKpi: `${config.module}:Dashboard:TenantAdmin:DocumentsKpi`,\n workflowDefinitionsKpi: `${config.module}:Dashboard:TenantAdmin:WorkflowDefinitionsKpi`,\n subscriptionKpi: `${config.module}:Dashboard:TenantAdmin:SubscriptionKpi`,\n usersByRoleDonut: `${config.module}:Dashboard:TenantAdmin:UsersByRoleDonut`,\n taskStatusDonut: `${config.module}:Dashboard:TenantAdmin:TaskStatusDonut`,\n deliveryStatusDonut: `${config.module}:Dashboard:TenantAdmin:DeliveryStatusDonut`,\n integrationsDonut: `${config.module}:Dashboard:TenantAdmin:IntegrationsDonut`,\n jobsByStatusBar: `${config.module}:Dashboard:TenantAdmin:JobsByStatusBar`,\n jobSchedulesByStatusBar: `${config.module}:Dashboard:TenantAdmin:JobSchedulesByStatusBar`,\n workflowsByStatusBar: `${config.module}:Dashboard:TenantAdmin:WorkflowsByStatusBar`,\n teamsBar: `${config.module}:Dashboard:TenantAdmin:TeamsBar`,\n projectsByStatusBar: `${config.module}:Dashboard:TenantAdmin:ProjectsByStatusBar`,\n trainingComplianceGauge: `${config.module}:Dashboard:TenantAdmin:TrainingComplianceGauge`,\n },\n },\n};\n","//#region ---- Imports ----\n\nimport { AXPModuleManifest } from '@acorex-platform/framework-shared/core';\nimport { RootConfig } from './root-config';\n\n//#endregion\n\n//#region ---- Manifest Definition ----\n\n/**\n * Dashboard Management Module Manifest.\n * Defines module metadata, features, and provider references.\n */\nexport const DashboardManagementManifest: AXPModuleManifest = {\n name: RootConfig.module.name,\n version: '1.0.0',\n title: RootConfig.module.title,\n icon: RootConfig.module.icon,\n i18n: RootConfig.config.i18n,\n type: 'platform',\n domain: 'platform',\n required: true,\n\n // Module dependencies (optional)\n};\n\n//#endregion\n\n","//#region ---- Dashboard Scope Types ----\n\n/**\n * Dashboard visibility scope.\n * - `T`: Tenant shared dashboard\n * - `U`: User personal dashboard\n * - `E`: Entity-scoped dashboard\n */\nexport type AXMDashboardScope = 'U' | 'T' | 'E';\n\n/** Scope reference for personal dashboards. */\nexport interface AXMDashboardUserScopeRef {\n userId: string;\n}\n\n/** Scope reference for tenant dashboards. */\nexport interface AXMDashboardTenantScopeRef {\n tenantId: string;\n roleIds: string[];\n}\n\n/** Scope reference for entity-type dashboards (one layout shared by all records of the type). */\nexport interface AXMDashboardEntityScopeRef {\n entityType: string;\n}\n\n/**\n * Scope-specific reference payload.\n * Shape depends on {@link AXMDashboardScope}.\n */\nexport type AXMDashboardScopeRef =\n | AXMDashboardUserScopeRef\n | AXMDashboardTenantScopeRef\n | AXMDashboardEntityScopeRef;\n\n//#endregion\n","import type { AXMDashboardScope, AXMDashboardScopeRef } from './dashboard-scope.types';\n\nexport type { AXMDashboardScope, AXMDashboardScopeRef } from './dashboard-scope.types';\n\n//#region ---- Widget Layout Contract Types ----\n\n/** Grid size preset as `[width, height]` in column/row units. */\nexport type AXGridLayoutSize = readonly [width: number, height: number];\n\nexport interface AXGridLayoutNode {\n id?: string;\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n minWidth?: number;\n minHeight?: number;\n maxWidth?: number;\n maxHeight?: number;\n /** When set, resize snaps to one of these `[width, height]` presets. */\n allowedSizes?: readonly AXGridLayoutSize[];\n}\n\nexport type AXMDashboardBreakpoint = 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl';\n\nexport interface AXMDashboardWidgetLayoutMap {\n id: string;\n title?: AXPMultiLanguageString;\n lg: AXGridLayoutNode;\n md: AXGridLayoutNode;\n sm: AXGridLayoutNode;\n xl?: AXGridLayoutNode;\n '2xl'?: AXGridLayoutNode;\n '3xl'?: AXGridLayoutNode;\n '4xl'?: AXGridLayoutNode;\n}\n\nexport interface AXMDashboardWidgetData {\n config: AXMDashboardWidgetLayoutMap;\n node?: unknown;\n}\n\n//#endregion\n\n//#region ---- Dashboard Entity Contract Types ----\n\nexport type AXPMultiLanguageString = string | Record<string, string>;\n\nexport interface AXPEntityModel<Id> {\n id: Id;\n auditInfo?: {\n created?: { at?: string | Date; by?: { id: string; type?: string } };\n updated?: { at?: string | Date; by?: { id: string; type?: string } };\n };\n stateInfo?: Record<string, unknown>;\n scopeInfo?: { tenantId?: string; userId?: string; applicationId?: string };\n}\n\nexport interface AXMCommonDashboardEntityModel extends AXPEntityModel<string> {\n title: AXPMultiLanguageString;\n description?: AXPMultiLanguageString;\n widgets: AXMDashboardWidgetData[];\n isArchived?: boolean;\n archivedAt?: string | Date;\n locked?: boolean;\n scope: AXMDashboardScope;\n scopeRef: AXMDashboardScopeRef;\n categoryIds?: string[];\n}\n\n//#endregion\n","/**\n * Strict DTOs for dashboard chart / KPI queries.\n * Chart widgets fetch an AXPQuery whose result matches one of these shapes.\n */\n\nimport type { AXPFilterClause } from '@acorex-platform/framework-shared/core';\n\n//#region ---- Result type keys (query metadata `resultType`) ----\n\n/** Stable result-type ids stored on query definitions for designer filtering. */\nexport const AXP_CHART_QUERY_RESULT_TYPE = {\n barSeries: 'AXPBarChartQueryResult',\n lineSeries: 'AXPLineChartQueryResult',\n donutSeries: 'AXPDonutChartQueryResult',\n gaugeValue: 'AXPGaugeChartQueryResult',\n funnelSeries: 'AXPFunnelChartQueryResult',\n heatmapSeries: 'AXPHeatmapChartQueryResult',\n kpiStatCard: 'AXPKpiStatCardQueryResult',\n kpiSegmented: 'AXPKpiSegmentedQueryResult',\n kpiProgress: 'AXPKpiProgressQueryResult',\n kpiDetails: 'AXPKpiDetailsQueryResult',\n} as const;\n\nexport type AXPChartQueryResultType =\n (typeof AXP_CHART_QUERY_RESULT_TYPE)[keyof typeof AXP_CHART_QUERY_RESULT_TYPE];\n\n//#endregion\n\n//#region ---- Series item shapes ----\n\nexport interface AXPBarChartQueryItem {\n id: string;\n label: string;\n value: number;\n color?: string;\n tooltipLabel?: string;\n}\n\nexport interface AXPLineChartQueryPoint {\n x: number | string;\n y: number;\n tooltipLabel?: string;\n}\n\nexport interface AXPLineChartQuerySeries {\n id?: string;\n label?: string;\n lineColor?: string;\n fillColor?: string;\n data: AXPLineChartQueryPoint[];\n}\n\nexport interface AXPDonutChartQueryItem {\n id: string;\n label: string;\n value: number;\n color?: string;\n tooltipLabel?: string;\n}\n\nexport interface AXPFunnelChartQueryItem {\n id?: string;\n name: string;\n value: number;\n color?: string;\n}\n\nexport interface AXPHeatmapChartQueryItem {\n x: number | string;\n y: number | string;\n value: number;\n label?: string;\n}\n\n//#endregion\n\n//#region ---- Query result envelopes ----\n\nexport interface AXPBarChartQueryResult {\n items: AXPBarChartQueryItem[];\n}\n\nexport interface AXPLineChartQueryResult {\n series: AXPLineChartQuerySeries[];\n}\n\nexport interface AXPDonutChartQueryResult {\n items: AXPDonutChartQueryItem[];\n}\n\nexport interface AXPGaugeChartQueryResult {\n value: number;\n}\n\nexport interface AXPFunnelChartQueryResult {\n items: AXPFunnelChartQueryItem[];\n}\n\nexport interface AXPHeatmapChartQueryResult {\n items: AXPHeatmapChartQueryItem[];\n}\n\nexport interface AXPKpiStatCardQueryResult {\n title?: string;\n titleBadgeText?: string;\n titleBadgeTone?: string;\n value?: number | string;\n valuePrefix?: string;\n valueSuffix?: string;\n format?: {\n style?: 'decimal' | 'currency' | 'percent';\n currency?: string;\n minimumFractionDigits?: number;\n maximumFractionDigits?: number;\n };\n icon?: string;\n iconTone?: string;\n trendValue?: string;\n trendLabel?: string;\n trendStatus?: 'success' | 'danger' | 'neutral';\n}\n\nexport interface AXPKpiSegmentedQueryResult {\n title?: string;\n icon?: string;\n segments: Array<{ label: string; value: number; color?: string }>;\n}\n\nexport interface AXPKpiProgressQueryResult {\n title?: string;\n icon?: string;\n value?: number | string;\n valuePrefix?: string;\n valueSuffix?: string;\n subtitle?: string;\n targetValue?: number | string;\n progressValue?: number;\n progressPercent?: number;\n}\n\nexport interface AXPKpiDetailsQueryResult {\n title?: string;\n value?: number | string;\n valuePrefix?: string;\n valueSuffix?: string;\n subtitle?: string;\n details: Array<{ label: string; value: string | number; color?: string }>;\n}\n\n//#endregion\n\n//#region ---- Widget options ----\n\n/** One designer rule: when the result row matches `when`, overlay `color`. First match wins. */\nexport interface AXPChartColorRule {\n when?: AXPFilterClause;\n color?: string;\n}\n\n/** Chart/KPI widget options for data binding (dashboard query and/or AI inline data). */\nexport interface AXPChartQueryWidgetOptions {\n /** Runtime AXPQuery key (e.g. `PlatformManagement:Dashboard:TenantsByStatusBar`). */\n query?: string;\n /** Optional input payload passed to `queryExecutor.fetch(query, queryInput)`. */\n queryInput?: Record<string, unknown>;\n /** Inline chart rows/series for AI chat (see chart-widget-data.util.ts). */\n dataSource?: unknown;\n /** Condition-based colour overlay applied after the query (or inline data) loads. */\n colorRules?: AXPChartColorRule[];\n}\n\n//#endregion\n","/**\n * Chart card options: one dashboard tile hosting mixed-type chart tabs.\n * Each tab is an {@link AXPWidgetNode} of a typed chart widget (donut, bar, line, gauge).\n */\n\nimport type { AXPMultiLanguageString, AXPWidgetNode } from '@acorex-platform/framework-shared/core';\n\n//#region ----- Types -----\n\n/** Editor widget name used as the repeater row in chart-card properties. */\nexport const AXP_CHART_CONFIGURATOR_WIDGET_NAME = 'chart-configurator';\n\nexport interface AXPChartCardWidgetOptions {\n /** Card heading (domain name). */\n title?: AXPMultiLanguageString;\n /** One typed chart widget node per tab. */\n tabs?: AXPWidgetNode[];\n}\n\n//#endregion\n","//#region ---- Imports ----\n\nimport { castArray, get, isArray, isString } from 'lodash';\n\nimport type {\n AXMDashboardEntityScopeRef,\n AXMDashboardScope,\n AXMDashboardScopeRef,\n AXMDashboardTenantScopeRef,\n AXMDashboardUserScopeRef,\n} from '../../dashboard-scope.types';\n\n//#endregion\n\n//#region ---- Builders ----\n\nexport function buildUserScopeRef(userId: string): AXMDashboardUserScopeRef {\n return { userId: userId.trim() };\n}\n\nexport function buildTenantScopeRef(tenantId: string, roleIds: readonly string[]): AXMDashboardTenantScopeRef {\n return {\n tenantId: tenantId.trim(),\n roleIds: [...new Set(roleIds.map((id) => id.trim()).filter(Boolean))],\n };\n}\n\nexport function buildEntityScopeRef(entityType: string): AXMDashboardEntityScopeRef {\n return { entityType: entityType.trim() };\n}\n\n//#endregion\n\n//#region ---- Readers ----\n\nexport function readScopeUserId(scopeRef: AXMDashboardScopeRef | undefined): string | undefined {\n const userId = get(scopeRef, 'userId');\n return isString(userId) && userId.trim() ? userId.trim() : undefined;\n}\n\nexport function readScopeTenantId(scopeRef: AXMDashboardScopeRef | undefined): string | undefined {\n const tenantId = get(scopeRef, 'tenantId');\n return isString(tenantId) && tenantId.trim() ? tenantId.trim() : undefined;\n}\n\nexport function readScopeRoleIds(scopeRef: AXMDashboardScopeRef | undefined): string[] {\n const roleIds = get(scopeRef, 'roleIds');\n if (!isArray(roleIds)) {\n return [];\n }\n return roleIds.filter((id): id is string => isString(id) && id.trim().length > 0);\n}\n\nexport function readScopeEntityType(scopeRef: AXMDashboardScopeRef | undefined): string | undefined {\n const entityType = get(scopeRef, 'entityType');\n return isString(entityType) && entityType.trim() ? entityType.trim() : undefined;\n}\n\n//#endregion\n\n//#region ---- Normalization ----\n\n/**\n * Ensures {@link scopeRef} matches {@link scope} and strips incompatible keys.\n */\nexport function normalizeDashboardScopeRef(\n scope: AXMDashboardScope,\n scopeRef: unknown,\n fallback?: Partial<{\n userId: string;\n tenantId: string;\n roleIds: readonly string[];\n entityType: string;\n }>,\n): AXMDashboardScopeRef {\n switch (scope) {\n case 'U':\n return buildUserScopeRef(readScopeUserId(scopeRef as AXMDashboardScopeRef) ?? fallback?.userId ?? '');\n case 'T':\n return buildTenantScopeRef(\n readScopeTenantId(scopeRef as AXMDashboardScopeRef) ?? fallback?.tenantId ?? '',\n readScopeRoleIds(scopeRef as AXMDashboardScopeRef).length > 0\n ? readScopeRoleIds(scopeRef as AXMDashboardScopeRef)\n : castArray(fallback?.roleIds ?? []),\n );\n case 'E':\n return buildEntityScopeRef(\n readScopeEntityType(scopeRef as AXMDashboardScopeRef) ?? fallback?.entityType ?? '',\n );\n default:\n return buildUserScopeRef(fallback?.userId ?? '');\n }\n}\n\n//#endregion\n","//#region ---- Contracts barrel ----\n\nexport * from './features.keys';\nexport * from './menu.keys';\nexport * from './permission.keys';\nexport * from './settings.keys';\n\nexport * from './DASHBOARD_LAYOUT_PAGE_COMPONENT_KEY';\n\nexport * from './root-config';\nexport * from './manifest';\n\nexport * from './dashboard-scope.types';\nexport * from './dashboard.types';\nexport * from './chart-query.types';\nexport * from './chart-card.types';\n\n//#endregion\n\nexport * from './entities';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,145 @@
1
+ import { AXChartLegendComponent } from '@acorex/charts/chart-legend';
2
+ import { AXDonutChartComponent } from '@acorex/charts/donut-chart';
3
+ import { AXTranslationService } from '@acorex/core/translation';
4
+ import { AXPQueryExecutor } from '@acorex-platform/framework-client/runtime';
5
+ import * as i0 from '@angular/core';
6
+ import { inject, signal, effect, computed, ChangeDetectionStrategy, Component } from '@angular/core';
7
+ import { e as AXPDashboardWidgetComponent, f as resolveChartQueryTabs, g as AXPChartQueryTabsComponent } from './acorex-platform-module-dashboard-management-client-acorex-platform-module-dashboard-management-client-Ey27MqFo.mjs';
8
+ import { a as loadDonutChartItems } from './acorex-platform-module-dashboard-management-client-chart-widget-data.util-DgCBHS1p.mjs';
9
+ import { a as AXP_CHART_LEGEND_OPTIONS_DONUT, o as omitChartFixedSize } from './acorex-platform-module-dashboard-management-client-chart-legend.util-C1zqTQEf.mjs';
10
+
11
+ /**
12
+ * Donut Chart Widget Component
13
+ * Displays data in a circular donut chart with interactive segments
14
+ */
15
+ class AXPDonutChartWidgetViewComponent extends AXPDashboardWidgetComponent {
16
+ //#endregion
17
+ //#region ----- Localization -----
18
+ async resolveChartOptionLabel(value) {
19
+ if (value != null && typeof value === 'object' && !Array.isArray(value)) {
20
+ return this.translationService.resolve(value);
21
+ }
22
+ const s = String(value ?? '');
23
+ if (s.startsWith('@')) {
24
+ return this.translationService.translateAsync(s);
25
+ }
26
+ return s;
27
+ }
28
+ /**
29
+ * Resolves segment labels from plain text, @i18n keys, or multi-language maps.
30
+ */
31
+ async resolveLocalizedChartText(value) {
32
+ if (value == null) {
33
+ return '';
34
+ }
35
+ if (typeof value === 'string') {
36
+ if (value.startsWith('@')) {
37
+ return this.translationService.translateAsync(value);
38
+ }
39
+ return value;
40
+ }
41
+ if (typeof value === 'object' &&
42
+ !Array.isArray(value) &&
43
+ this.translationService.isValidMultiLanguageObject(value)) {
44
+ return this.translationService.resolve(value);
45
+ }
46
+ return String(value);
47
+ }
48
+ selectQueryTab(index) {
49
+ this.activeTabIndex.set(index);
50
+ }
51
+ //#endregion
52
+ constructor() {
53
+ super();
54
+ //#region ----- Services & Dependencies -----
55
+ this.queryExecutor = inject(AXPQueryExecutor);
56
+ this.translationService = inject(AXTranslationService);
57
+ //#endregion
58
+ //#region ----- Chart state -----
59
+ this.data = signal([], /* @ts-ignore */
60
+ ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
61
+ this.donutChartOptions = signal({}, /* @ts-ignore */
62
+ ...(ngDevMode ? [{ debugName: "donutChartOptions" }] : /* istanbul ignore next */ []));
63
+ this.legendOptions = AXP_CHART_LEGEND_OPTIONS_DONUT;
64
+ this.labelResolveGeneration = 0;
65
+ this.resolveDonutOptionsEffect = effect(() => {
66
+ const raw = this.options();
67
+ const generation = ++this.labelResolveGeneration;
68
+ void (async () => {
69
+ const title = await this.resolveChartOptionLabel(raw['title']);
70
+ const totalLabel = raw['totalLabel'] !== undefined ? await this.resolveChartOptionLabel(raw['totalLabel']) : undefined;
71
+ if (generation !== this.labelResolveGeneration) {
72
+ return;
73
+ }
74
+ const base = omitChartFixedSize(raw);
75
+ this.donutChartOptions.set({
76
+ ...base,
77
+ title,
78
+ ...(totalLabel !== undefined ? { totalLabel } : {}),
79
+ });
80
+ })();
81
+ }, /* @ts-ignore */
82
+ ...(ngDevMode ? [{ debugName: "resolveDonutOptionsEffect" }] : /* istanbul ignore next */ []));
83
+ //#endregion
84
+ //#region ----- Query tabs -----
85
+ this.queryTabs = computed(() => resolveChartQueryTabs(this.options(), this.entityContext()?.entityId), /* @ts-ignore */
86
+ ...(ngDevMode ? [{ debugName: "queryTabs" }] : /* istanbul ignore next */ []));
87
+ this.activeTabIndex = signal(0, /* @ts-ignore */
88
+ ...(ngDevMode ? [{ debugName: "activeTabIndex" }] : /* istanbul ignore next */ []));
89
+ this.activeQuery = computed(() => {
90
+ const tabs = this.queryTabs();
91
+ if (tabs.length === 0) {
92
+ return undefined;
93
+ }
94
+ const index = Math.min(Math.max(this.activeTabIndex(), 0), tabs.length - 1);
95
+ return tabs[index];
96
+ }, /* @ts-ignore */
97
+ ...(ngDevMode ? [{ debugName: "activeQuery" }] : /* istanbul ignore next */ []));
98
+ this.clampTabIndexEffect = effect(() => {
99
+ const tabs = this.queryTabs();
100
+ if (this.activeTabIndex() >= tabs.length) {
101
+ this.activeTabIndex.set(0);
102
+ }
103
+ }, /* @ts-ignore */
104
+ ...(ngDevMode ? [{ debugName: "clampTabIndexEffect" }] : /* istanbul ignore next */ []));
105
+ //#endregion
106
+ //#region ----- Query loading -----
107
+ this.dataLoadEffect = effect(async () => {
108
+ const opts = this.options();
109
+ const active = this.activeQuery();
110
+ const items = await loadDonutChartItems(opts, {
111
+ queryExecutor: this.queryExecutor,
112
+ queryKey: active?.query,
113
+ queryInput: active?.queryInput,
114
+ });
115
+ const resolved = await Promise.all(items.map(async (item) => ({
116
+ ...item,
117
+ label: await this.resolveLocalizedChartText(item.label),
118
+ })));
119
+ this.data.set(resolved);
120
+ }, /* @ts-ignore */
121
+ ...(ngDevMode ? [{ debugName: "dataLoadEffect" }] : /* istanbul ignore next */ []));
122
+ this.setOptions({
123
+ showDataLabels: false,
124
+ donutWidth: 22,
125
+ cornerRadius: 4,
126
+ showTooltip: true,
127
+ animationEasing: 'cubic-out',
128
+ animationDuration: 800,
129
+ ...omitChartFixedSize(this.options()),
130
+ });
131
+ this.donutChartOptions.set(omitChartFixedSize(this.options()));
132
+ }
133
+ handleDonutChartSegmentClick(_event) {
134
+ // reserved for future drill-down
135
+ }
136
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDonutChartWidgetViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
137
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPDonutChartWidgetViewComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<div class=\"axp-chart-widget-host\">\n <axp-chart-query-tabs\n [tabs]=\"queryTabs()\"\n [activeIndex]=\"activeTabIndex()\"\n (activeIndexChange)=\"selectQueryTab($event)\"\n />\n <div class=\"axp-chart-widget-host__body axp-chart-widget-host__body--with-legend\">\n <div class=\"axp-chart-widget-host__chart axp-chart-widget-host__chart--radial\">\n <ax-donut-chart\n #chart\n [data]=\"data()\"\n [options]=\"donutChartOptions()\"\n (segmentClick)=\"handleDonutChartSegmentClick($event)\"\n ></ax-donut-chart>\n </div>\n <!-- ----- Series indicator (legend) ----- -->\n @if (data().length > 0) {\n <div class=\"axp-chart-widget-host__legend\">\n <ax-chart-legend [chart]=\"chart\" [options]=\"legendOptions\"></ax-chart-legend>\n </div>\n }\n </div>\n</div>\n", styles: ["@layer properties;:host{display:block;width:100%;height:100%;min-height:0px;overflow:hidden}:host:has(.axp-chart-widget-host__chart--heatmap){block-size:auto;overflow:visible;min-block-size:0}.axp-chart-widget-host{display:flex;height:100%;min-height:0px;width:100%;flex-direction:column;gap:var(--spacing, .25rem)}.axp-chart-widget-host:has(.axp-chart-widget-host__chart--heatmap){block-size:auto;min-block-size:0;overflow:visible}.axp-chart-widget-host__body{display:flex;min-height:0px;flex:1;flex-direction:column;gap:var(--spacing, .25rem);padding-bottom:calc(var(--spacing, .25rem) * 2)}.axp-chart-widget-host__body:not(.axp-chart-widget-host__body--with-legend)>.axp-chart-widget-host__chart--radial{flex:1 1 auto}.axp-chart-widget-host__body--with-legend{min-height:0px;flex:1;gap:var(--spacing, .25rem);display:grid;grid-template-rows:minmax(0,1fr) auto}.axp-chart-widget-host__chart{position:relative;min-height:calc(var(--spacing, .25rem) * 64);width:100%;overflow:hidden;grid-row:1}.axp-chart-widget-host__chart--radial{position:relative;margin-inline:auto;align-self:center;justify-self:center;overflow:hidden;grid-row:1;flex:0 0 auto;height:auto;width:min(100%,18rem);max-width:100%;min-height:12rem;min-width:8rem;aspect-ratio:1 / 1}.axp-chart-widget-host__chart--funnel{position:relative;width:100%;overflow:hidden;block-size:20rem;flex:0 0 auto;max-block-size:24rem;min-block-size:16rem}.axp-chart-widget-host__chart--funnel ax-funnel-chart,.axp-chart-widget-host__chart--funnel .ax-funnel-chart-container{display:block;block-size:100%;inline-size:100%;min-block-size:0}.axp-chart-widget-host__body:has(.axp-chart-widget-host__chart--funnel){flex:none}.axp-chart-widget-host__chart--heatmap{position:relative;width:100%;max-width:100%;inline-size:100%;block-size:auto;flex:0 0 auto;overflow:visible;min-height:0!important;min-block-size:0!important;max-block-size:none}.axp-chart-widget-host__chart--heatmap ax-heatmap-chart,.axp-chart-widget-host__chart--heatmap .ax-heatmap-chart-container{display:block;inline-size:100%;max-inline-size:100%;block-size:auto;min-block-size:0;overflow:visible}.axp-chart-widget-host__body:has(.axp-chart-widget-host__chart--heatmap){flex:none;block-size:auto;min-block-size:0;overflow:visible}.axp-chart-widget-host__legend{width:100%;flex:none;grid-row:2;min-height:0;min-width:0;max-width:100%;display:flex;justify-content:flex-start;overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;scrollbar-color:rgb(var(--ax-sys-color-border-lighter-surface)) transparent}:host ::ng-deep ax-chart-legend{display:block!important;height:auto!important;max-height:none;width:max-content;min-width:100%;max-width:none}:host ::ng-deep .ax-chart-legend{--ax-legend-bg: var(--ax-sys-color-lighter-surface);--ax-legend-text: var(--ax-sys-color-on-lighter-surface);--ax-legend-border: var(--ax-sys-color-border-lighter-surface);--ax-legend-radius: .625rem;--ax-legend-padding: .375rem .5rem;--ax-legend-gap: .375rem;--ax-legend-item-height: auto;height:auto;max-height:none;width:100%;overflow:visible;padding:var(--ax-legend-padding);gap:var(--ax-legend-gap);color:rgb(var(--ax-legend-text))}:host ::ng-deep .ax-chart-legend.ax-legend-horizontal{flex-direction:row;flex-wrap:nowrap;align-items:center;justify-content:flex-start;width:max-content;min-width:100%;max-width:none;overflow:visible;border:none;background:transparent;background-color:transparent;padding:.125rem .75rem .7rem;gap:.5rem}:host ::ng-deep .ax-legend-item{align-items:center;flex-shrink:0;gap:.375rem;height:auto;min-height:1.5rem;padding-block:.2rem;padding-inline:.5rem;border-radius:9999px;border:1px solid rgb(var(--ax-sys-color-border-lightest-surface));background-color:rgb(var(--ax-sys-color-lightest-surface));white-space:nowrap;transition:background-color .15s ease,border-color .15s ease,box-shadow .15s ease,opacity .15s ease,transform .15s ease}:host ::ng-deep .ax-legend-item:hover{border-color:rgb(var(--ax-sys-color-primary-500));background-color:rgb(var(--ax-sys-color-primary-500));box-shadow:0 1px 2px #0f172a0f}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep .ax-legend-item:hover{border-color:color-mix(in srgb,rgb(var(--ax-sys-color-primary-500)) 35%,rgb(var(--ax-sys-color-border-lightest-surface)))}}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep .ax-legend-item:hover{background-color:color-mix(in srgb,rgb(var(--ax-sys-color-primary-500)) 6%,rgb(var(--ax-sys-color-lightest-surface)))}}:host ::ng-deep .ax-legend-item:active{transform:scale(.98)}:host ::ng-deep .ax-legend-item.ax-legend-item-hidden{opacity:.62}:host ::ng-deep .ax-legend-color{width:.625rem;height:.625rem;flex-shrink:0;border-radius:9999px;box-shadow:0 0 0 1px rgb(var(--ax-legend-text))}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep .ax-legend-color{box-shadow:0 0 0 1px color-mix(in srgb,rgb(var(--ax-legend-text)) 18%,transparent)}}:host ::ng-deep .ax-legend-name{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);max-width:9rem;overflow:hidden;text-overflow:ellipsis}:host ::ng-deep .ax-legend-value{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);margin-inline-start:0;opacity:1;color:rgb(var(--ax-sys-color-on-lightest-surface))}:host ::ng-deep .ax-legend-percentage{margin-inline-start:0;border-radius:9999px;padding-inline:.4rem;padding-block:.125rem;font-size:.6875rem;line-height:1;font-weight:600;font-variant-numeric:tabular-nums;background-color:rgb(var(--ax-legend-text))}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep .ax-legend-percentage{background-color:color-mix(in srgb,rgb(var(--ax-legend-text)) 12%,transparent)}}:host ::ng-deep ax-donut-chart,:host ::ng-deep ax-gauge-chart,:host ::ng-deep ax-bar-chart,:host ::ng-deep ax-line-chart,:host ::ng-deep ax-funnel-chart{display:block!important;width:100%!important;height:100%!important;min-height:0!important;max-height:100%!important}:host ::ng-deep .axp-chart-widget-host__chart--heatmap ax-heatmap-chart{display:block!important;width:100%!important;max-width:100%!important;height:auto!important;min-height:0!important;max-height:none!important;overflow:visible!important}:host ::ng-deep ax-donut-chart .ax-donut-chart,:host ::ng-deep ax-gauge-chart .ax-gauge-chart,:host ::ng-deep ax-bar-chart .ax-bar-chart,:host ::ng-deep ax-line-chart .ax-line-chart,:host ::ng-deep ax-funnel-chart .ax-funnel-chart-container{min-height:0!important;height:100%!important;width:100%!important;padding:.25rem!important}:host ::ng-deep .axp-chart-widget-host__chart--heatmap ax-heatmap-chart .ax-heatmap-chart-container,:host ::ng-deep .axp-chart-widget-host__chart--heatmap .ax-heatmap-chart{min-height:0!important;height:auto!important;width:100%!important;max-width:100%!important;padding:.25rem!important;overflow:visible!important}:host ::ng-deep .axp-chart-widget-host__chart--heatmap svg{display:block;width:100%!important;max-width:100%!important;height:auto!important;overflow:visible!important}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-ordinal{syntax: \"*\"; inherits: false;}@property --tw-slashed-zero{syntax: \"*\"; inherits: false;}@property --tw-numeric-figure{syntax: \"*\"; inherits: false;}@property --tw-numeric-spacing{syntax: \"*\"; inherits: false;}@property --tw-numeric-fraction{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-ordinal: initial;--tw-slashed-zero: initial;--tw-numeric-figure: initial;--tw-numeric-spacing: initial;--tw-numeric-fraction: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXDonutChartComponent, selector: "ax-donut-chart", inputs: ["data", "options"], outputs: ["segmentClick", "segmentHover"] }, { kind: "component", type: AXChartLegendComponent, selector: "ax-chart-legend", inputs: ["chart", "options"], outputs: ["itemClick", "itemMouseEnter", "itemMouseLeave"] }, { kind: "component", type: AXPChartQueryTabsComponent, selector: "axp-chart-query-tabs", inputs: ["tabs", "activeIndex"], outputs: ["activeIndexChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
138
+ }
139
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDonutChartWidgetViewComponent, decorators: [{
140
+ type: Component,
141
+ args: [{ imports: [AXDonutChartComponent, AXChartLegendComponent, AXPChartQueryTabsComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"axp-chart-widget-host\">\n <axp-chart-query-tabs\n [tabs]=\"queryTabs()\"\n [activeIndex]=\"activeTabIndex()\"\n (activeIndexChange)=\"selectQueryTab($event)\"\n />\n <div class=\"axp-chart-widget-host__body axp-chart-widget-host__body--with-legend\">\n <div class=\"axp-chart-widget-host__chart axp-chart-widget-host__chart--radial\">\n <ax-donut-chart\n #chart\n [data]=\"data()\"\n [options]=\"donutChartOptions()\"\n (segmentClick)=\"handleDonutChartSegmentClick($event)\"\n ></ax-donut-chart>\n </div>\n <!-- ----- Series indicator (legend) ----- -->\n @if (data().length > 0) {\n <div class=\"axp-chart-widget-host__legend\">\n <ax-chart-legend [chart]=\"chart\" [options]=\"legendOptions\"></ax-chart-legend>\n </div>\n }\n </div>\n</div>\n", styles: ["@layer properties;:host{display:block;width:100%;height:100%;min-height:0px;overflow:hidden}:host:has(.axp-chart-widget-host__chart--heatmap){block-size:auto;overflow:visible;min-block-size:0}.axp-chart-widget-host{display:flex;height:100%;min-height:0px;width:100%;flex-direction:column;gap:var(--spacing, .25rem)}.axp-chart-widget-host:has(.axp-chart-widget-host__chart--heatmap){block-size:auto;min-block-size:0;overflow:visible}.axp-chart-widget-host__body{display:flex;min-height:0px;flex:1;flex-direction:column;gap:var(--spacing, .25rem);padding-bottom:calc(var(--spacing, .25rem) * 2)}.axp-chart-widget-host__body:not(.axp-chart-widget-host__body--with-legend)>.axp-chart-widget-host__chart--radial{flex:1 1 auto}.axp-chart-widget-host__body--with-legend{min-height:0px;flex:1;gap:var(--spacing, .25rem);display:grid;grid-template-rows:minmax(0,1fr) auto}.axp-chart-widget-host__chart{position:relative;min-height:calc(var(--spacing, .25rem) * 64);width:100%;overflow:hidden;grid-row:1}.axp-chart-widget-host__chart--radial{position:relative;margin-inline:auto;align-self:center;justify-self:center;overflow:hidden;grid-row:1;flex:0 0 auto;height:auto;width:min(100%,18rem);max-width:100%;min-height:12rem;min-width:8rem;aspect-ratio:1 / 1}.axp-chart-widget-host__chart--funnel{position:relative;width:100%;overflow:hidden;block-size:20rem;flex:0 0 auto;max-block-size:24rem;min-block-size:16rem}.axp-chart-widget-host__chart--funnel ax-funnel-chart,.axp-chart-widget-host__chart--funnel .ax-funnel-chart-container{display:block;block-size:100%;inline-size:100%;min-block-size:0}.axp-chart-widget-host__body:has(.axp-chart-widget-host__chart--funnel){flex:none}.axp-chart-widget-host__chart--heatmap{position:relative;width:100%;max-width:100%;inline-size:100%;block-size:auto;flex:0 0 auto;overflow:visible;min-height:0!important;min-block-size:0!important;max-block-size:none}.axp-chart-widget-host__chart--heatmap ax-heatmap-chart,.axp-chart-widget-host__chart--heatmap .ax-heatmap-chart-container{display:block;inline-size:100%;max-inline-size:100%;block-size:auto;min-block-size:0;overflow:visible}.axp-chart-widget-host__body:has(.axp-chart-widget-host__chart--heatmap){flex:none;block-size:auto;min-block-size:0;overflow:visible}.axp-chart-widget-host__legend{width:100%;flex:none;grid-row:2;min-height:0;min-width:0;max-width:100%;display:flex;justify-content:flex-start;overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;scrollbar-color:rgb(var(--ax-sys-color-border-lighter-surface)) transparent}:host ::ng-deep ax-chart-legend{display:block!important;height:auto!important;max-height:none;width:max-content;min-width:100%;max-width:none}:host ::ng-deep .ax-chart-legend{--ax-legend-bg: var(--ax-sys-color-lighter-surface);--ax-legend-text: var(--ax-sys-color-on-lighter-surface);--ax-legend-border: var(--ax-sys-color-border-lighter-surface);--ax-legend-radius: .625rem;--ax-legend-padding: .375rem .5rem;--ax-legend-gap: .375rem;--ax-legend-item-height: auto;height:auto;max-height:none;width:100%;overflow:visible;padding:var(--ax-legend-padding);gap:var(--ax-legend-gap);color:rgb(var(--ax-legend-text))}:host ::ng-deep .ax-chart-legend.ax-legend-horizontal{flex-direction:row;flex-wrap:nowrap;align-items:center;justify-content:flex-start;width:max-content;min-width:100%;max-width:none;overflow:visible;border:none;background:transparent;background-color:transparent;padding:.125rem .75rem .7rem;gap:.5rem}:host ::ng-deep .ax-legend-item{align-items:center;flex-shrink:0;gap:.375rem;height:auto;min-height:1.5rem;padding-block:.2rem;padding-inline:.5rem;border-radius:9999px;border:1px solid rgb(var(--ax-sys-color-border-lightest-surface));background-color:rgb(var(--ax-sys-color-lightest-surface));white-space:nowrap;transition:background-color .15s ease,border-color .15s ease,box-shadow .15s ease,opacity .15s ease,transform .15s ease}:host ::ng-deep .ax-legend-item:hover{border-color:rgb(var(--ax-sys-color-primary-500));background-color:rgb(var(--ax-sys-color-primary-500));box-shadow:0 1px 2px #0f172a0f}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep .ax-legend-item:hover{border-color:color-mix(in srgb,rgb(var(--ax-sys-color-primary-500)) 35%,rgb(var(--ax-sys-color-border-lightest-surface)))}}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep .ax-legend-item:hover{background-color:color-mix(in srgb,rgb(var(--ax-sys-color-primary-500)) 6%,rgb(var(--ax-sys-color-lightest-surface)))}}:host ::ng-deep .ax-legend-item:active{transform:scale(.98)}:host ::ng-deep .ax-legend-item.ax-legend-item-hidden{opacity:.62}:host ::ng-deep .ax-legend-color{width:.625rem;height:.625rem;flex-shrink:0;border-radius:9999px;box-shadow:0 0 0 1px rgb(var(--ax-legend-text))}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep .ax-legend-color{box-shadow:0 0 0 1px color-mix(in srgb,rgb(var(--ax-legend-text)) 18%,transparent)}}:host ::ng-deep .ax-legend-name{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);max-width:9rem;overflow:hidden;text-overflow:ellipsis}:host ::ng-deep .ax-legend-value{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);margin-inline-start:0;opacity:1;color:rgb(var(--ax-sys-color-on-lightest-surface))}:host ::ng-deep .ax-legend-percentage{margin-inline-start:0;border-radius:9999px;padding-inline:.4rem;padding-block:.125rem;font-size:.6875rem;line-height:1;font-weight:600;font-variant-numeric:tabular-nums;background-color:rgb(var(--ax-legend-text))}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep .ax-legend-percentage{background-color:color-mix(in srgb,rgb(var(--ax-legend-text)) 12%,transparent)}}:host ::ng-deep ax-donut-chart,:host ::ng-deep ax-gauge-chart,:host ::ng-deep ax-bar-chart,:host ::ng-deep ax-line-chart,:host ::ng-deep ax-funnel-chart{display:block!important;width:100%!important;height:100%!important;min-height:0!important;max-height:100%!important}:host ::ng-deep .axp-chart-widget-host__chart--heatmap ax-heatmap-chart{display:block!important;width:100%!important;max-width:100%!important;height:auto!important;min-height:0!important;max-height:none!important;overflow:visible!important}:host ::ng-deep ax-donut-chart .ax-donut-chart,:host ::ng-deep ax-gauge-chart .ax-gauge-chart,:host ::ng-deep ax-bar-chart .ax-bar-chart,:host ::ng-deep ax-line-chart .ax-line-chart,:host ::ng-deep ax-funnel-chart .ax-funnel-chart-container{min-height:0!important;height:100%!important;width:100%!important;padding:.25rem!important}:host ::ng-deep .axp-chart-widget-host__chart--heatmap ax-heatmap-chart .ax-heatmap-chart-container,:host ::ng-deep .axp-chart-widget-host__chart--heatmap .ax-heatmap-chart{min-height:0!important;height:auto!important;width:100%!important;max-width:100%!important;padding:.25rem!important;overflow:visible!important}:host ::ng-deep .axp-chart-widget-host__chart--heatmap svg{display:block;width:100%!important;max-width:100%!important;height:auto!important;overflow:visible!important}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-ordinal{syntax: \"*\"; inherits: false;}@property --tw-slashed-zero{syntax: \"*\"; inherits: false;}@property --tw-numeric-figure{syntax: \"*\"; inherits: false;}@property --tw-numeric-spacing{syntax: \"*\"; inherits: false;}@property --tw-numeric-fraction{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-ordinal: initial;--tw-slashed-zero: initial;--tw-numeric-figure: initial;--tw-numeric-spacing: initial;--tw-numeric-fraction: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
142
+ }], ctorParameters: () => [] });
143
+
144
+ export { AXPDonutChartWidgetViewComponent };
145
+ //# sourceMappingURL=acorex-platform-module-dashboard-management-client-donut-chart-widget.component-DRiIRbhX.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-module-dashboard-management-client-donut-chart-widget.component-DRiIRbhX.mjs","sources":["../../../../libs/modules/dashboard-management/client/src/lib/features/shared/widgets/chart/donut-chart/donut-chart-widget.component.ts","../../../../libs/modules/dashboard-management/client/src/lib/features/shared/widgets/chart/donut-chart/donut-chart-widget.component.html"],"sourcesContent":["import { AXChartLegendComponent } from '@acorex/charts/chart-legend';\nimport { AXDonutChartComponent, AXDonutChartData, AXDonutChartOption } from '@acorex/charts/donut-chart';\nimport { AXTranslationService } from '@acorex/core/translation';\nimport { AXPMultiLanguageString } from '@acorex-platform/framework-shared/core';\nimport { AXPQueryExecutor } from '@acorex-platform/framework-client/runtime';\nimport { ChangeDetectionStrategy, Component, computed, effect, inject, signal } from '@angular/core';\nimport { AXPDashboardWidgetComponent } from '../../dashboard-widget-base';\nimport { resolveChartQueryTabs } from '../chart-query-load.util';\nimport { loadDonutChartItems } from '../chart-widget-data.util';\nimport { AXPChartQueryTabsComponent } from '../chart-query-tabs.component';\nimport { AXP_CHART_LEGEND_OPTIONS_DONUT, omitChartFixedSize } from '../chart-legend.util';\n\n/**\n * Donut Chart Widget Component\n * Displays data in a circular donut chart with interactive segments\n */\n@Component({\n templateUrl: './donut-chart-widget.component.html',\n styleUrls: ['./donut-chart-widget.component.css'],\n imports: [AXDonutChartComponent, AXChartLegendComponent, AXPChartQueryTabsComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AXPDonutChartWidgetViewComponent extends AXPDashboardWidgetComponent {\n //#region ----- Services & Dependencies -----\n\n private readonly queryExecutor = inject(AXPQueryExecutor);\n private readonly translationService = inject(AXTranslationService);\n\n //#endregion\n\n //#region ----- Chart state -----\n\n protected data = signal<AXDonutChartData[]>([]);\n\n protected donutChartOptions = signal<AXDonutChartOption & { title: string }>(\n {} as AXDonutChartOption & { title: string },\n );\n\n protected readonly legendOptions = AXP_CHART_LEGEND_OPTIONS_DONUT;\n\n private labelResolveGeneration = 0;\n\n //#endregion\n\n //#region ----- Localization -----\n\n private async resolveChartOptionLabel(value: unknown): Promise<string> {\n if (value != null && typeof value === 'object' && !Array.isArray(value)) {\n return this.translationService.resolve(value as AXPMultiLanguageString);\n }\n const s = String(value ?? '');\n if (s.startsWith('@')) {\n return this.translationService.translateAsync(s);\n }\n return s;\n }\n\n /**\n * Resolves segment labels from plain text, @i18n keys, or multi-language maps.\n */\n private async resolveLocalizedChartText(value: unknown): Promise<string> {\n if (value == null) {\n return '';\n }\n if (typeof value === 'string') {\n if (value.startsWith('@')) {\n return this.translationService.translateAsync(value);\n }\n return value;\n }\n if (\n typeof value === 'object' &&\n !Array.isArray(value) &&\n this.translationService.isValidMultiLanguageObject(value)\n ) {\n return this.translationService.resolve(value as AXPMultiLanguageString);\n }\n return String(value);\n }\n\n private readonly resolveDonutOptionsEffect = effect(() => {\n const raw = this.options() as Record<string, unknown>;\n const generation = ++this.labelResolveGeneration;\n void (async () => {\n const title = await this.resolveChartOptionLabel(raw['title']);\n const totalLabel =\n raw['totalLabel'] !== undefined ? await this.resolveChartOptionLabel(raw['totalLabel']) : undefined;\n if (generation !== this.labelResolveGeneration) {\n return;\n }\n const base = omitChartFixedSize(raw) as unknown as AXDonutChartOption & { title: string };\n this.donutChartOptions.set({\n ...base,\n title,\n ...(totalLabel !== undefined ? { totalLabel } : {}),\n });\n })();\n });\n\n //#endregion\n\n //#region ----- Query tabs -----\n\n protected readonly queryTabs = computed(() =>\n resolveChartQueryTabs(this.options() as Record<string, unknown>, this.entityContext()?.entityId),\n );\n\n protected readonly activeTabIndex = signal(0);\n\n private readonly activeQuery = computed(() => {\n const tabs = this.queryTabs();\n if (tabs.length === 0) {\n return undefined;\n }\n const index = Math.min(Math.max(this.activeTabIndex(), 0), tabs.length - 1);\n return tabs[index];\n });\n\n protected selectQueryTab(index: number): void {\n this.activeTabIndex.set(index);\n }\n\n private readonly clampTabIndexEffect = effect(() => {\n const tabs = this.queryTabs();\n if (this.activeTabIndex() >= tabs.length) {\n this.activeTabIndex.set(0);\n }\n });\n\n //#endregion\n\n //#region ----- Query loading -----\n\n private readonly dataLoadEffect = effect(async () => {\n const opts = this.options() as Record<string, unknown>;\n const active = this.activeQuery();\n const items = await loadDonutChartItems(opts, {\n queryExecutor: this.queryExecutor,\n queryKey: active?.query,\n queryInput: active?.queryInput,\n });\n const resolved = await Promise.all(\n items.map(async (item) => ({\n ...item,\n label: await this.resolveLocalizedChartText(item.label),\n })),\n );\n this.data.set(resolved as AXDonutChartData[]);\n });\n\n //#endregion\n\n constructor() {\n super();\n this.setOptions({\n showDataLabels: false,\n donutWidth: 22,\n cornerRadius: 4,\n showTooltip: true,\n animationEasing: 'cubic-out',\n animationDuration: 800,\n ...omitChartFixedSize(this.options() as Record<string, unknown>),\n });\n this.donutChartOptions.set(\n omitChartFixedSize(this.options() as Record<string, unknown>) as unknown as AXDonutChartOption & {\n title: string;\n },\n );\n }\n\n handleDonutChartSegmentClick(_event: unknown) {\n // reserved for future drill-down\n }\n}\n","<div class=\"axp-chart-widget-host\">\n <axp-chart-query-tabs\n [tabs]=\"queryTabs()\"\n [activeIndex]=\"activeTabIndex()\"\n (activeIndexChange)=\"selectQueryTab($event)\"\n />\n <div class=\"axp-chart-widget-host__body axp-chart-widget-host__body--with-legend\">\n <div class=\"axp-chart-widget-host__chart axp-chart-widget-host__chart--radial\">\n <ax-donut-chart\n #chart\n [data]=\"data()\"\n [options]=\"donutChartOptions()\"\n (segmentClick)=\"handleDonutChartSegmentClick($event)\"\n ></ax-donut-chart>\n </div>\n <!-- ----- Series indicator (legend) ----- -->\n @if (data().length > 0) {\n <div class=\"axp-chart-widget-host__legend\">\n <ax-chart-legend [chart]=\"chart\" [options]=\"legendOptions\"></ax-chart-legend>\n </div>\n }\n </div>\n</div>\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,135 @@
1
+ import { AXFunnelChartComponent } from '@acorex/charts/funnel-chart';
2
+ import { AXTranslationService } from '@acorex/core/translation';
3
+ import { AXPQueryExecutor } from '@acorex-platform/framework-client/runtime';
4
+ import * as i0 from '@angular/core';
5
+ import { inject, signal, computed, effect, ChangeDetectionStrategy, Component } from '@angular/core';
6
+ import { e as AXPDashboardWidgetComponent, f as resolveChartQueryTabs, g as AXPChartQueryTabsComponent } from './acorex-platform-module-dashboard-management-client-acorex-platform-module-dashboard-management-client-Ey27MqFo.mjs';
7
+ import { b as loadFunnelChartItems } from './acorex-platform-module-dashboard-management-client-chart-widget-data.util-DgCBHS1p.mjs';
8
+
9
+ /**
10
+ * Funnel Chart Widget Component
11
+ * Displays step-wise conversion/flow data as a funnel.
12
+ */
13
+ class AXPFunnelChartWidgetViewComponent extends AXPDashboardWidgetComponent {
14
+ selectQueryTab(index) {
15
+ this.activeTabIndex.set(index);
16
+ }
17
+ //#endregion
18
+ //#region ----- Localization -----
19
+ async resolveChartText(value) {
20
+ if (value == null) {
21
+ return '';
22
+ }
23
+ if (typeof value === 'string') {
24
+ return value.startsWith('@') ? this.translationService.translateAsync(value) : value;
25
+ }
26
+ if (typeof value === 'object' &&
27
+ !Array.isArray(value) &&
28
+ this.translationService.isValidMultiLanguageObject(value)) {
29
+ return this.translationService.resolve(value);
30
+ }
31
+ return String(value);
32
+ }
33
+ //#endregion
34
+ constructor() {
35
+ super();
36
+ //#region ----- Services & Dependencies -----
37
+ this.queryExecutor = inject(AXPQueryExecutor);
38
+ this.translationService = inject(AXTranslationService);
39
+ //#endregion
40
+ //#region ----- Chart state -----
41
+ this.data = signal([], /* @ts-ignore */
42
+ ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
43
+ /** Options passed to the chart with resolved messages/labels (multi-language and @i18n keys). */
44
+ this.funnelOptions = signal({}, /* @ts-ignore */
45
+ ...(ngDevMode ? [{ debugName: "funnelOptions" }] : /* istanbul ignore next */ []));
46
+ this.labelResolveGeneration = 0;
47
+ //#endregion
48
+ //#region ----- Query tabs -----
49
+ this.queryTabs = computed(() => resolveChartQueryTabs(this.options(), this.entityContext()?.entityId), /* @ts-ignore */
50
+ ...(ngDevMode ? [{ debugName: "queryTabs" }] : /* istanbul ignore next */ []));
51
+ this.activeTabIndex = signal(0, /* @ts-ignore */
52
+ ...(ngDevMode ? [{ debugName: "activeTabIndex" }] : /* istanbul ignore next */ []));
53
+ this.activeQuery = computed(() => {
54
+ const tabs = this.queryTabs();
55
+ if (tabs.length === 0) {
56
+ return undefined;
57
+ }
58
+ const index = Math.min(Math.max(this.activeTabIndex(), 0), tabs.length - 1);
59
+ return tabs[index];
60
+ }, /* @ts-ignore */
61
+ ...(ngDevMode ? [{ debugName: "activeQuery" }] : /* istanbul ignore next */ []));
62
+ this.resolveOptionLabelsEffect = effect(() => {
63
+ const raw = this.options();
64
+ const generation = ++this.labelResolveGeneration;
65
+ void (async () => {
66
+ const messagesRaw = raw['messages'];
67
+ const messages = messagesRaw && typeof messagesRaw === 'object' && !Array.isArray(messagesRaw)
68
+ ? messagesRaw
69
+ : undefined;
70
+ const noData = await this.resolveChartText(messages?.['noData']);
71
+ if (generation !== this.labelResolveGeneration) {
72
+ return;
73
+ }
74
+ const base = raw;
75
+ this.funnelOptions.set({
76
+ ...base,
77
+ ...(messages
78
+ ? {
79
+ messages: {
80
+ ...base.messages,
81
+ ...(noData ? { noData } : {}),
82
+ ...(messages['noDataIcon'] ? { noDataIcon: String(messages['noDataIcon']) } : {}),
83
+ },
84
+ }
85
+ : {}),
86
+ });
87
+ })();
88
+ }, /* @ts-ignore */
89
+ ...(ngDevMode ? [{ debugName: "resolveOptionLabelsEffect" }] : /* istanbul ignore next */ []));
90
+ //#endregion
91
+ //#region ----- Query loading -----
92
+ this.clampTabIndexEffect = effect(() => {
93
+ const tabs = this.queryTabs();
94
+ if (this.activeTabIndex() >= tabs.length) {
95
+ this.activeTabIndex.set(0);
96
+ }
97
+ }, /* @ts-ignore */
98
+ ...(ngDevMode ? [{ debugName: "clampTabIndexEffect" }] : /* istanbul ignore next */ []));
99
+ this.dataLoadEffect = effect(async () => {
100
+ const opts = this.options();
101
+ const active = this.activeQuery();
102
+ const items = await loadFunnelChartItems(opts, {
103
+ queryExecutor: this.queryExecutor,
104
+ queryKey: active?.query,
105
+ queryInput: active?.queryInput,
106
+ });
107
+ const resolved = await Promise.all(items.map(async (item) => ({
108
+ ...item,
109
+ name: await this.resolveChartText(item.name),
110
+ })));
111
+ this.data.set(resolved);
112
+ }, /* @ts-ignore */
113
+ ...(ngDevMode ? [{ debugName: "dataLoadEffect" }] : /* istanbul ignore next */ []));
114
+ this.setOptions({
115
+ showLabels: true,
116
+ showTooltip: true,
117
+ neckWidth: 0.3,
118
+ animationEasing: 'cubic-out',
119
+ color: 'rgb(var(--ax-sys-color-primary-500))',
120
+ animationDuration: 800,
121
+ margin: { top: 16, right: 16, bottom: 16, left: 16 },
122
+ ...this.options(),
123
+ });
124
+ this.funnelOptions.set(this.options());
125
+ }
126
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPFunnelChartWidgetViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
127
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: AXPFunnelChartWidgetViewComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<div class=\"axp-chart-widget-host\">\n <axp-chart-query-tabs\n [tabs]=\"queryTabs()\"\n [activeIndex]=\"activeTabIndex()\"\n (activeIndexChange)=\"selectQueryTab($event)\"\n />\n <div class=\"axp-chart-widget-host__body\">\n <div class=\"axp-chart-widget-host__chart axp-chart-widget-host__chart--funnel\">\n <ax-funnel-chart [data]=\"data()\" [options]=\"funnelOptions()\"></ax-funnel-chart>\n </div>\n </div>\n</div>\n", styles: ["@layer properties;:host{display:block;width:100%;height:100%;min-height:0px;overflow:hidden}:host:has(.axp-chart-widget-host__chart--heatmap){block-size:auto;overflow:visible;min-block-size:0}.axp-chart-widget-host{display:flex;height:100%;min-height:0px;width:100%;flex-direction:column;gap:var(--spacing, .25rem)}.axp-chart-widget-host:has(.axp-chart-widget-host__chart--heatmap){block-size:auto;min-block-size:0;overflow:visible}.axp-chart-widget-host__body{display:flex;min-height:0px;flex:1;flex-direction:column;gap:var(--spacing, .25rem);padding-bottom:calc(var(--spacing, .25rem) * 2)}.axp-chart-widget-host__body:not(.axp-chart-widget-host__body--with-legend)>.axp-chart-widget-host__chart--radial{flex:1 1 auto}.axp-chart-widget-host__body--with-legend{min-height:0px;flex:1;gap:var(--spacing, .25rem);display:grid;grid-template-rows:minmax(0,1fr) auto}.axp-chart-widget-host__chart{position:relative;min-height:calc(var(--spacing, .25rem) * 64);width:100%;overflow:hidden;grid-row:1}.axp-chart-widget-host__chart--radial{position:relative;margin-inline:auto;align-self:center;justify-self:center;overflow:hidden;grid-row:1;flex:0 0 auto;height:auto;width:min(100%,18rem);max-width:100%;min-height:12rem;min-width:8rem;aspect-ratio:1 / 1}.axp-chart-widget-host__chart--funnel{position:relative;width:100%;overflow:hidden;block-size:20rem;flex:0 0 auto;max-block-size:24rem;min-block-size:16rem}.axp-chart-widget-host__chart--funnel ax-funnel-chart,.axp-chart-widget-host__chart--funnel .ax-funnel-chart-container{display:block;block-size:100%;inline-size:100%;min-block-size:0}.axp-chart-widget-host__body:has(.axp-chart-widget-host__chart--funnel){flex:none}.axp-chart-widget-host__chart--heatmap{position:relative;width:100%;max-width:100%;inline-size:100%;block-size:auto;flex:0 0 auto;overflow:visible;min-height:0!important;min-block-size:0!important;max-block-size:none}.axp-chart-widget-host__chart--heatmap ax-heatmap-chart,.axp-chart-widget-host__chart--heatmap .ax-heatmap-chart-container{display:block;inline-size:100%;max-inline-size:100%;block-size:auto;min-block-size:0;overflow:visible}.axp-chart-widget-host__body:has(.axp-chart-widget-host__chart--heatmap){flex:none;block-size:auto;min-block-size:0;overflow:visible}.axp-chart-widget-host__legend{width:100%;flex:none;grid-row:2;min-height:0;min-width:0;max-width:100%;display:flex;justify-content:flex-start;overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;scrollbar-color:rgb(var(--ax-sys-color-border-lighter-surface)) transparent}:host ::ng-deep ax-chart-legend{display:block!important;height:auto!important;max-height:none;width:max-content;min-width:100%;max-width:none}:host ::ng-deep .ax-chart-legend{--ax-legend-bg: var(--ax-sys-color-lighter-surface);--ax-legend-text: var(--ax-sys-color-on-lighter-surface);--ax-legend-border: var(--ax-sys-color-border-lighter-surface);--ax-legend-radius: .625rem;--ax-legend-padding: .375rem .5rem;--ax-legend-gap: .375rem;--ax-legend-item-height: auto;height:auto;max-height:none;width:100%;overflow:visible;padding:var(--ax-legend-padding);gap:var(--ax-legend-gap);color:rgb(var(--ax-legend-text))}:host ::ng-deep .ax-chart-legend.ax-legend-horizontal{flex-direction:row;flex-wrap:nowrap;align-items:center;justify-content:flex-start;width:max-content;min-width:100%;max-width:none;overflow:visible;border:none;background:transparent;background-color:transparent;padding:.125rem .75rem .7rem;gap:.5rem}:host ::ng-deep .ax-legend-item{align-items:center;flex-shrink:0;gap:.375rem;height:auto;min-height:1.5rem;padding-block:.2rem;padding-inline:.5rem;border-radius:9999px;border:1px solid rgb(var(--ax-sys-color-border-lightest-surface));background-color:rgb(var(--ax-sys-color-lightest-surface));white-space:nowrap;transition:background-color .15s ease,border-color .15s ease,box-shadow .15s ease,opacity .15s ease,transform .15s ease}:host ::ng-deep .ax-legend-item:hover{border-color:rgb(var(--ax-sys-color-primary-500));background-color:rgb(var(--ax-sys-color-primary-500));box-shadow:0 1px 2px #0f172a0f}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep .ax-legend-item:hover{border-color:color-mix(in srgb,rgb(var(--ax-sys-color-primary-500)) 35%,rgb(var(--ax-sys-color-border-lightest-surface)))}}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep .ax-legend-item:hover{background-color:color-mix(in srgb,rgb(var(--ax-sys-color-primary-500)) 6%,rgb(var(--ax-sys-color-lightest-surface)))}}:host ::ng-deep .ax-legend-item:active{transform:scale(.98)}:host ::ng-deep .ax-legend-item.ax-legend-item-hidden{opacity:.62}:host ::ng-deep .ax-legend-color{width:.625rem;height:.625rem;flex-shrink:0;border-radius:9999px;box-shadow:0 0 0 1px rgb(var(--ax-legend-text))}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep .ax-legend-color{box-shadow:0 0 0 1px color-mix(in srgb,rgb(var(--ax-legend-text)) 18%,transparent)}}:host ::ng-deep .ax-legend-name{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);max-width:9rem;overflow:hidden;text-overflow:ellipsis}:host ::ng-deep .ax-legend-value{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);margin-inline-start:0;opacity:1;color:rgb(var(--ax-sys-color-on-lightest-surface))}:host ::ng-deep .ax-legend-percentage{margin-inline-start:0;border-radius:9999px;padding-inline:.4rem;padding-block:.125rem;font-size:.6875rem;line-height:1;font-weight:600;font-variant-numeric:tabular-nums;background-color:rgb(var(--ax-legend-text))}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep .ax-legend-percentage{background-color:color-mix(in srgb,rgb(var(--ax-legend-text)) 12%,transparent)}}:host ::ng-deep ax-donut-chart,:host ::ng-deep ax-gauge-chart,:host ::ng-deep ax-bar-chart,:host ::ng-deep ax-line-chart,:host ::ng-deep ax-funnel-chart{display:block!important;width:100%!important;height:100%!important;min-height:0!important;max-height:100%!important}:host ::ng-deep .axp-chart-widget-host__chart--heatmap ax-heatmap-chart{display:block!important;width:100%!important;max-width:100%!important;height:auto!important;min-height:0!important;max-height:none!important;overflow:visible!important}:host ::ng-deep ax-donut-chart .ax-donut-chart,:host ::ng-deep ax-gauge-chart .ax-gauge-chart,:host ::ng-deep ax-bar-chart .ax-bar-chart,:host ::ng-deep ax-line-chart .ax-line-chart,:host ::ng-deep ax-funnel-chart .ax-funnel-chart-container{min-height:0!important;height:100%!important;width:100%!important;padding:.25rem!important}:host ::ng-deep .axp-chart-widget-host__chart--heatmap ax-heatmap-chart .ax-heatmap-chart-container,:host ::ng-deep .axp-chart-widget-host__chart--heatmap .ax-heatmap-chart{min-height:0!important;height:auto!important;width:100%!important;max-width:100%!important;padding:.25rem!important;overflow:visible!important}:host ::ng-deep .axp-chart-widget-host__chart--heatmap svg{display:block;width:100%!important;max-width:100%!important;height:auto!important;overflow:visible!important}:host{display:block;width:100%;height:100%;min-height:0px}:host .axp-chart-widget-host{width:100%;height:100%;min-height:0px}:host ax-funnel-chart{display:block;width:100%;height:100%;min-height:0px}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-ordinal{syntax: \"*\"; inherits: false;}@property --tw-slashed-zero{syntax: \"*\"; inherits: false;}@property --tw-numeric-figure{syntax: \"*\"; inherits: false;}@property --tw-numeric-spacing{syntax: \"*\"; inherits: false;}@property --tw-numeric-fraction{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-ordinal: initial;--tw-slashed-zero: initial;--tw-numeric-figure: initial;--tw-numeric-spacing: initial;--tw-numeric-fraction: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXFunnelChartComponent, selector: "ax-funnel-chart", inputs: ["data", "options"], outputs: ["segmentClick"] }, { kind: "component", type: AXPChartQueryTabsComponent, selector: "axp-chart-query-tabs", inputs: ["tabs", "activeIndex"], outputs: ["activeIndexChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
128
+ }
129
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPFunnelChartWidgetViewComponent, decorators: [{
130
+ type: Component,
131
+ args: [{ imports: [AXFunnelChartComponent, AXPChartQueryTabsComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"axp-chart-widget-host\">\n <axp-chart-query-tabs\n [tabs]=\"queryTabs()\"\n [activeIndex]=\"activeTabIndex()\"\n (activeIndexChange)=\"selectQueryTab($event)\"\n />\n <div class=\"axp-chart-widget-host__body\">\n <div class=\"axp-chart-widget-host__chart axp-chart-widget-host__chart--funnel\">\n <ax-funnel-chart [data]=\"data()\" [options]=\"funnelOptions()\"></ax-funnel-chart>\n </div>\n </div>\n</div>\n", styles: ["@layer properties;:host{display:block;width:100%;height:100%;min-height:0px;overflow:hidden}:host:has(.axp-chart-widget-host__chart--heatmap){block-size:auto;overflow:visible;min-block-size:0}.axp-chart-widget-host{display:flex;height:100%;min-height:0px;width:100%;flex-direction:column;gap:var(--spacing, .25rem)}.axp-chart-widget-host:has(.axp-chart-widget-host__chart--heatmap){block-size:auto;min-block-size:0;overflow:visible}.axp-chart-widget-host__body{display:flex;min-height:0px;flex:1;flex-direction:column;gap:var(--spacing, .25rem);padding-bottom:calc(var(--spacing, .25rem) * 2)}.axp-chart-widget-host__body:not(.axp-chart-widget-host__body--with-legend)>.axp-chart-widget-host__chart--radial{flex:1 1 auto}.axp-chart-widget-host__body--with-legend{min-height:0px;flex:1;gap:var(--spacing, .25rem);display:grid;grid-template-rows:minmax(0,1fr) auto}.axp-chart-widget-host__chart{position:relative;min-height:calc(var(--spacing, .25rem) * 64);width:100%;overflow:hidden;grid-row:1}.axp-chart-widget-host__chart--radial{position:relative;margin-inline:auto;align-self:center;justify-self:center;overflow:hidden;grid-row:1;flex:0 0 auto;height:auto;width:min(100%,18rem);max-width:100%;min-height:12rem;min-width:8rem;aspect-ratio:1 / 1}.axp-chart-widget-host__chart--funnel{position:relative;width:100%;overflow:hidden;block-size:20rem;flex:0 0 auto;max-block-size:24rem;min-block-size:16rem}.axp-chart-widget-host__chart--funnel ax-funnel-chart,.axp-chart-widget-host__chart--funnel .ax-funnel-chart-container{display:block;block-size:100%;inline-size:100%;min-block-size:0}.axp-chart-widget-host__body:has(.axp-chart-widget-host__chart--funnel){flex:none}.axp-chart-widget-host__chart--heatmap{position:relative;width:100%;max-width:100%;inline-size:100%;block-size:auto;flex:0 0 auto;overflow:visible;min-height:0!important;min-block-size:0!important;max-block-size:none}.axp-chart-widget-host__chart--heatmap ax-heatmap-chart,.axp-chart-widget-host__chart--heatmap .ax-heatmap-chart-container{display:block;inline-size:100%;max-inline-size:100%;block-size:auto;min-block-size:0;overflow:visible}.axp-chart-widget-host__body:has(.axp-chart-widget-host__chart--heatmap){flex:none;block-size:auto;min-block-size:0;overflow:visible}.axp-chart-widget-host__legend{width:100%;flex:none;grid-row:2;min-height:0;min-width:0;max-width:100%;display:flex;justify-content:flex-start;overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;scrollbar-color:rgb(var(--ax-sys-color-border-lighter-surface)) transparent}:host ::ng-deep ax-chart-legend{display:block!important;height:auto!important;max-height:none;width:max-content;min-width:100%;max-width:none}:host ::ng-deep .ax-chart-legend{--ax-legend-bg: var(--ax-sys-color-lighter-surface);--ax-legend-text: var(--ax-sys-color-on-lighter-surface);--ax-legend-border: var(--ax-sys-color-border-lighter-surface);--ax-legend-radius: .625rem;--ax-legend-padding: .375rem .5rem;--ax-legend-gap: .375rem;--ax-legend-item-height: auto;height:auto;max-height:none;width:100%;overflow:visible;padding:var(--ax-legend-padding);gap:var(--ax-legend-gap);color:rgb(var(--ax-legend-text))}:host ::ng-deep .ax-chart-legend.ax-legend-horizontal{flex-direction:row;flex-wrap:nowrap;align-items:center;justify-content:flex-start;width:max-content;min-width:100%;max-width:none;overflow:visible;border:none;background:transparent;background-color:transparent;padding:.125rem .75rem .7rem;gap:.5rem}:host ::ng-deep .ax-legend-item{align-items:center;flex-shrink:0;gap:.375rem;height:auto;min-height:1.5rem;padding-block:.2rem;padding-inline:.5rem;border-radius:9999px;border:1px solid rgb(var(--ax-sys-color-border-lightest-surface));background-color:rgb(var(--ax-sys-color-lightest-surface));white-space:nowrap;transition:background-color .15s ease,border-color .15s ease,box-shadow .15s ease,opacity .15s ease,transform .15s ease}:host ::ng-deep .ax-legend-item:hover{border-color:rgb(var(--ax-sys-color-primary-500));background-color:rgb(var(--ax-sys-color-primary-500));box-shadow:0 1px 2px #0f172a0f}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep .ax-legend-item:hover{border-color:color-mix(in srgb,rgb(var(--ax-sys-color-primary-500)) 35%,rgb(var(--ax-sys-color-border-lightest-surface)))}}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep .ax-legend-item:hover{background-color:color-mix(in srgb,rgb(var(--ax-sys-color-primary-500)) 6%,rgb(var(--ax-sys-color-lightest-surface)))}}:host ::ng-deep .ax-legend-item:active{transform:scale(.98)}:host ::ng-deep .ax-legend-item.ax-legend-item-hidden{opacity:.62}:host ::ng-deep .ax-legend-color{width:.625rem;height:.625rem;flex-shrink:0;border-radius:9999px;box-shadow:0 0 0 1px rgb(var(--ax-legend-text))}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep .ax-legend-color{box-shadow:0 0 0 1px color-mix(in srgb,rgb(var(--ax-legend-text)) 18%,transparent)}}:host ::ng-deep .ax-legend-name{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);max-width:9rem;overflow:hidden;text-overflow:ellipsis}:host ::ng-deep .ax-legend-value{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);margin-inline-start:0;opacity:1;color:rgb(var(--ax-sys-color-on-lightest-surface))}:host ::ng-deep .ax-legend-percentage{margin-inline-start:0;border-radius:9999px;padding-inline:.4rem;padding-block:.125rem;font-size:.6875rem;line-height:1;font-weight:600;font-variant-numeric:tabular-nums;background-color:rgb(var(--ax-legend-text))}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep .ax-legend-percentage{background-color:color-mix(in srgb,rgb(var(--ax-legend-text)) 12%,transparent)}}:host ::ng-deep ax-donut-chart,:host ::ng-deep ax-gauge-chart,:host ::ng-deep ax-bar-chart,:host ::ng-deep ax-line-chart,:host ::ng-deep ax-funnel-chart{display:block!important;width:100%!important;height:100%!important;min-height:0!important;max-height:100%!important}:host ::ng-deep .axp-chart-widget-host__chart--heatmap ax-heatmap-chart{display:block!important;width:100%!important;max-width:100%!important;height:auto!important;min-height:0!important;max-height:none!important;overflow:visible!important}:host ::ng-deep ax-donut-chart .ax-donut-chart,:host ::ng-deep ax-gauge-chart .ax-gauge-chart,:host ::ng-deep ax-bar-chart .ax-bar-chart,:host ::ng-deep ax-line-chart .ax-line-chart,:host ::ng-deep ax-funnel-chart .ax-funnel-chart-container{min-height:0!important;height:100%!important;width:100%!important;padding:.25rem!important}:host ::ng-deep .axp-chart-widget-host__chart--heatmap ax-heatmap-chart .ax-heatmap-chart-container,:host ::ng-deep .axp-chart-widget-host__chart--heatmap .ax-heatmap-chart{min-height:0!important;height:auto!important;width:100%!important;max-width:100%!important;padding:.25rem!important;overflow:visible!important}:host ::ng-deep .axp-chart-widget-host__chart--heatmap svg{display:block;width:100%!important;max-width:100%!important;height:auto!important;overflow:visible!important}:host{display:block;width:100%;height:100%;min-height:0px}:host .axp-chart-widget-host{width:100%;height:100%;min-height:0px}:host ax-funnel-chart{display:block;width:100%;height:100%;min-height:0px}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-ordinal{syntax: \"*\"; inherits: false;}@property --tw-slashed-zero{syntax: \"*\"; inherits: false;}@property --tw-numeric-figure{syntax: \"*\"; inherits: false;}@property --tw-numeric-spacing{syntax: \"*\"; inherits: false;}@property --tw-numeric-fraction{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-ordinal: initial;--tw-slashed-zero: initial;--tw-numeric-figure: initial;--tw-numeric-spacing: initial;--tw-numeric-fraction: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
132
+ }], ctorParameters: () => [] });
133
+
134
+ export { AXPFunnelChartWidgetViewComponent };
135
+ //# sourceMappingURL=acorex-platform-module-dashboard-management-client-funnel-chart-widget.component-BPY1NchM.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-module-dashboard-management-client-funnel-chart-widget.component-BPY1NchM.mjs","sources":["../../../../libs/modules/dashboard-management/client/src/lib/features/shared/widgets/chart/funnel-chart/funnel-chart-widget.component.ts","../../../../libs/modules/dashboard-management/client/src/lib/features/shared/widgets/chart/funnel-chart/funnel-chart-widget.component.html"],"sourcesContent":["import { AXFunnelChartComponent, AXFunnelChartOption, AXFunnelData } from '@acorex/charts/funnel-chart';\nimport { AXTranslationService } from '@acorex/core/translation';\nimport { AXPMultiLanguageString } from '@acorex-platform/framework-shared/core';\nimport { AXPQueryExecutor } from '@acorex-platform/framework-client/runtime';\nimport { ChangeDetectionStrategy, Component, computed, effect, inject, signal } from '@angular/core';\nimport { AXPDashboardWidgetComponent } from '../../dashboard-widget-base';\nimport { resolveChartQueryTabs } from '../chart-query-load.util';\nimport { loadFunnelChartItems } from '../chart-widget-data.util';\nimport { AXPChartQueryTabsComponent } from '../chart-query-tabs.component';\n\n/**\n * Funnel Chart Widget Component\n * Displays step-wise conversion/flow data as a funnel.\n */\n@Component({\n templateUrl: './funnel-chart-widget.component.html',\n styleUrls: ['./funnel-chart-widget.component.css'],\n imports: [AXFunnelChartComponent, AXPChartQueryTabsComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AXPFunnelChartWidgetViewComponent extends AXPDashboardWidgetComponent {\n //#region ----- Services & Dependencies -----\n\n private readonly queryExecutor = inject(AXPQueryExecutor);\n private readonly translationService = inject(AXTranslationService);\n\n //#endregion\n\n //#region ----- Chart state -----\n\n protected data = signal<AXFunnelData[]>([]);\n\n /** Options passed to the chart with resolved messages/labels (multi-language and @i18n keys). */\n protected funnelOptions = signal<AXFunnelChartOption>({} as AXFunnelChartOption);\n\n private labelResolveGeneration = 0;\n\n //#endregion\n\n //#region ----- Query tabs -----\n\n protected readonly queryTabs = computed(() =>\n resolveChartQueryTabs(this.options() as Record<string, unknown>, this.entityContext()?.entityId),\n );\n\n protected readonly activeTabIndex = signal(0);\n\n private readonly activeQuery = computed(() => {\n const tabs = this.queryTabs();\n if (tabs.length === 0) {\n return undefined;\n }\n const index = Math.min(Math.max(this.activeTabIndex(), 0), tabs.length - 1);\n return tabs[index];\n });\n\n protected selectQueryTab(index: number): void {\n this.activeTabIndex.set(index);\n }\n\n //#endregion\n\n //#region ----- Localization -----\n\n private async resolveChartText(value: unknown): Promise<string> {\n if (value == null) {\n return '';\n }\n if (typeof value === 'string') {\n return value.startsWith('@') ? this.translationService.translateAsync(value) : value;\n }\n if (\n typeof value === 'object' &&\n !Array.isArray(value) &&\n this.translationService.isValidMultiLanguageObject(value)\n ) {\n return this.translationService.resolve(value as AXPMultiLanguageString);\n }\n return String(value);\n }\n\n private readonly resolveOptionLabelsEffect = effect(() => {\n const raw = this.options() as Record<string, unknown>;\n const generation = ++this.labelResolveGeneration;\n\n void (async () => {\n const messagesRaw = raw['messages'];\n const messages =\n messagesRaw && typeof messagesRaw === 'object' && !Array.isArray(messagesRaw)\n ? (messagesRaw as Record<string, unknown>)\n : undefined;\n\n const noData = await this.resolveChartText(messages?.['noData']);\n\n if (generation !== this.labelResolveGeneration) {\n return;\n }\n\n const base = raw as unknown as AXFunnelChartOption;\n this.funnelOptions.set({\n ...base,\n ...(messages\n ? {\n messages: {\n ...base.messages,\n ...(noData ? { noData } : {}),\n ...(messages['noDataIcon'] ? { noDataIcon: String(messages['noDataIcon']) } : {}),\n },\n }\n : {}),\n });\n })();\n });\n\n //#endregion\n\n //#region ----- Query loading -----\n\n private readonly clampTabIndexEffect = effect(() => {\n const tabs = this.queryTabs();\n if (this.activeTabIndex() >= tabs.length) {\n this.activeTabIndex.set(0);\n }\n });\n\n private readonly dataLoadEffect = effect(async () => {\n const opts = this.options() as Record<string, unknown>;\n const active = this.activeQuery();\n const items = await loadFunnelChartItems(opts, {\n queryExecutor: this.queryExecutor,\n queryKey: active?.query,\n queryInput: active?.queryInput,\n });\n const resolved = await Promise.all(\n items.map(async (item) => ({\n ...item,\n name: await this.resolveChartText(item.name),\n })),\n );\n this.data.set(resolved as AXFunnelData[]);\n });\n\n //#endregion\n\n constructor() {\n super();\n this.setOptions({\n showLabels: true,\n showTooltip: true,\n neckWidth: 0.3,\n animationEasing: 'cubic-out',\n color: 'rgb(var(--ax-sys-color-primary-500))',\n animationDuration: 800,\n margin: { top: 16, right: 16, bottom: 16, left: 16 },\n ...this.options(),\n });\n\n this.funnelOptions.set(this.options() as AXFunnelChartOption);\n }\n}\n","<div class=\"axp-chart-widget-host\">\n <axp-chart-query-tabs\n [tabs]=\"queryTabs()\"\n [activeIndex]=\"activeTabIndex()\"\n (activeIndexChange)=\"selectQueryTab($event)\"\n />\n <div class=\"axp-chart-widget-host__body\">\n <div class=\"axp-chart-widget-host__chart axp-chart-widget-host__chart--funnel\">\n <ax-funnel-chart [data]=\"data()\" [options]=\"funnelOptions()\"></ax-funnel-chart>\n </div>\n </div>\n</div>\n"],"names":[],"mappings":"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"}