@memberjunction/ng-dashboards 5.11.0 → 5.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AI/components/agents/agent-configuration.component.d.ts +34 -2
- package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-configuration.component.js +586 -223
- package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.js +2 -2
- package/dist/AI/components/agents/agent-filter-panel.component.d.ts +8 -0
- package/dist/AI/components/agents/agent-filter-panel.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-filter-panel.component.js +85 -52
- package/dist/AI/components/agents/agent-filter-panel.component.js.map +1 -1
- package/dist/AI/components/charts/performance-heatmap.component.d.ts +1 -0
- package/dist/AI/components/charts/performance-heatmap.component.d.ts.map +1 -1
- package/dist/AI/components/charts/performance-heatmap.component.js +27 -5
- package/dist/AI/components/charts/performance-heatmap.component.js.map +1 -1
- package/dist/AI/components/charts/time-series-chart.component.d.ts +5 -0
- package/dist/AI/components/charts/time-series-chart.component.d.ts.map +1 -1
- package/dist/AI/components/charts/time-series-chart.component.js +23 -8
- package/dist/AI/components/charts/time-series-chart.component.js.map +1 -1
- package/dist/AI/components/execution-monitoring.component.js +2 -2
- package/dist/AI/components/execution-monitoring.component.js.map +1 -1
- package/dist/AI/components/models/model-management.component.js +2 -2
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +2 -2
- package/dist/AI/components/prompts/prompt-filter-panel.component.js +2 -2
- package/dist/AI/components/prompts/prompt-management.component.js +3 -3
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-version-control.component.js +2 -2
- package/dist/AI/components/requests/agent-requests-resource.component.d.ts +83 -0
- package/dist/AI/components/requests/agent-requests-resource.component.d.ts.map +1 -0
- package/dist/AI/components/requests/agent-requests-resource.component.js +547 -0
- package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -0
- package/dist/AI/components/system/system-config-filter-panel.component.js +2 -2
- package/dist/AI/components/system/system-configuration.component.js +2 -2
- package/dist/AI/components/widgets/kpi-card.component.js +7 -7
- package/dist/AI/components/widgets/kpi-card.component.js.map +1 -1
- package/dist/AI/components/widgets/live-execution-widget.component.d.ts.map +1 -1
- package/dist/AI/components/widgets/live-execution-widget.component.js +6 -6
- package/dist/AI/components/widgets/live-execution-widget.component.js.map +1 -1
- package/dist/AI/index.d.ts +1 -0
- package/dist/AI/index.d.ts.map +1 -1
- package/dist/AI/index.js +2 -0
- package/dist/AI/index.js.map +1 -1
- package/dist/APIKeys/api-applications-panel.component.js +3 -3
- package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
- package/dist/APIKeys/api-key-create-dialog.component.js +3 -3
- package/dist/APIKeys/api-key-create-dialog.component.js.map +1 -1
- package/dist/APIKeys/api-key-edit-panel.component.js +1 -1
- package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -1
- package/dist/APIKeys/api-key-list.component.js +3 -3
- package/dist/APIKeys/api-key-list.component.js.map +1 -1
- package/dist/APIKeys/api-keys-resource.component.js +1 -1
- package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
- package/dist/APIKeys/api-scopes-panel.component.js +2 -2
- package/dist/APIKeys/api-usage-panel.component.js +2 -2
- package/dist/Actions/components/actions-overview.component.js +2 -2
- package/dist/Actions/components/execution-monitoring.component.js +2 -2
- package/dist/Actions/components/explorer/action-breadcrumb.component.js +2 -2
- package/dist/Actions/components/explorer/action-card.component.js +2 -2
- package/dist/Actions/components/explorer/action-explorer.component.js +2 -2
- package/dist/Actions/components/explorer/action-list-item.component.js +2 -2
- package/dist/Actions/components/explorer/action-toolbar.component.js +2 -2
- package/dist/Actions/components/explorer/action-tree-panel.component.js +2 -2
- package/dist/Actions/components/explorer/new-action-panel.component.js +2 -2
- package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -1
- package/dist/Actions/components/explorer/new-category-panel.component.js +2 -2
- package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -1
- package/dist/Communication/communication-dashboard.component.js +2 -2
- package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-logs-resource.component.js +3 -3
- package/dist/Communication/communication-logs-resource.component.js.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.js +5 -5
- package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
- package/dist/Communication/communication-providers-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-providers-resource.component.js +3 -3
- package/dist/Communication/communication-providers-resource.component.js.map +1 -1
- package/dist/Communication/communication-runs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-runs-resource.component.js +3 -3
- package/dist/Communication/communication-runs-resource.component.js.map +1 -1
- package/dist/Communication/communication-templates-resource.component.js +2 -2
- package/dist/Communication/communication-templates-resource.component.js.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +2 -2
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +2 -2
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/browser/component-browser.component.js +2 -2
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js +2 -2
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +2 -2
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js +2 -2
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/spec-editor.component.js +2 -2
- package/dist/ComponentStudio/components/editors/spec-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/text-import-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/text-import-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/workspace/component-preview.component.js +2 -2
- package/dist/ComponentStudio/components/workspace/editor-tabs.component.js +2 -2
- package/dist/ComponentStudio/components/workspace/editor-tabs.component.js.map +1 -1
- package/dist/Credentials/components/credentials-audit-resource.component.js +9 -9
- package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.js +11 -3
- package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +2 -2
- package/dist/Credentials/components/credentials-overview-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-overview-resource.component.js +12 -11
- package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +9 -9
- package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
- package/dist/Credentials/credentials-dashboard.component.js +2 -2
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +2 -2
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js +2 -2
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +2 -2
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +2 -2
- package/dist/DataExplorer/components/view-selector/view-selector.component.js +2 -2
- package/dist/DataExplorer/data-explorer-dashboard.component.js +4 -4
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/Home/home-dashboard.component.js +2 -2
- package/dist/Integration/components/activity/activity.component.d.ts +1 -1
- package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
- package/dist/Integration/components/activity/activity.component.js +5 -5
- package/dist/Integration/components/activity/activity.component.js.map +1 -1
- package/dist/Integration/components/connections/connections.component.d.ts +31 -2
- package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
- package/dist/Integration/components/connections/connections.component.js +753 -412
- package/dist/Integration/components/connections/connections.component.js.map +1 -1
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +3 -3
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
- package/dist/Integration/components/overview/overview.component.d.ts +0 -1
- package/dist/Integration/components/overview/overview.component.d.ts.map +1 -1
- package/dist/Integration/components/overview/overview.component.js +3 -6
- package/dist/Integration/components/overview/overview.component.js.map +1 -1
- package/dist/Integration/components/pipelines/pipelines.component.js +3 -3
- package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
- package/dist/Integration/components/schedules/schedules.component.d.ts +20 -0
- package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -1
- package/dist/Integration/components/schedules/schedules.component.js +97 -5
- package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
- package/dist/Integration/components/visual-editor/visual-editor.component.js +2 -2
- package/dist/Integration/components/widgets/integration-card.component.d.ts.map +1 -1
- package/dist/Integration/components/widgets/integration-card.component.js +5 -1
- package/dist/Integration/components/widgets/integration-card.component.js.map +1 -1
- package/dist/Integration/components/widgets/run-history-panel.component.js +2 -2
- package/dist/Integration/components/widgets/run-history-panel.component.js.map +1 -1
- package/dist/Integration/integration.module.d.ts +2 -1
- package/dist/Integration/integration.module.d.ts.map +1 -1
- package/dist/Integration/integration.module.js +7 -3
- package/dist/Integration/integration.module.js.map +1 -1
- package/dist/Integration/services/integration-data.service.d.ts +27 -2
- package/dist/Integration/services/integration-data.service.d.ts.map +1 -1
- package/dist/Integration/services/integration-data.service.js +107 -4
- package/dist/Integration/services/integration-data.service.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +25 -24
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-categories-resource.component.js +2 -2
- package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +26 -25
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-operations-resource.component.js +2 -2
- package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
- package/dist/Lists/components/venn-diagram/venn-diagram.component.js +3 -3
- package/dist/Lists/components/venn-diagram/venn-diagram.component.js.map +1 -1
- package/dist/MCP/components/mcp-connection-dialog.component.js +2 -2
- package/dist/MCP/components/mcp-log-detail-panel.component.js +2 -2
- package/dist/MCP/components/mcp-log-detail-panel.component.js.map +1 -1
- package/dist/MCP/components/mcp-server-dialog.component.js +2 -2
- package/dist/MCP/components/mcp-test-tool-dialog.component.js +2 -2
- package/dist/MCP/components/mcp-test-tool-dialog.component.js.map +1 -1
- package/dist/MCP/mcp-dashboard.component.js +2 -2
- package/dist/MCP/mcp-filter-panel.component.js +2 -2
- package/dist/QueryBrowser/query-browser-resource.component.js +7 -7
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/Scheduling/components/index.d.ts +0 -1
- package/dist/Scheduling/components/index.d.ts.map +1 -1
- package/dist/Scheduling/components/index.js +0 -1
- package/dist/Scheduling/components/index.js.map +1 -1
- package/dist/Scheduling/components/scheduling-activity.component.js +2 -2
- package/dist/Scheduling/components/scheduling-jobs.component.d.ts +6 -9
- package/dist/Scheduling/components/scheduling-jobs.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs.component.js +118 -110
- package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-overview.component.js +3 -3
- package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
- package/dist/Scheduling/scheduling-dashboard.component.js +2 -2
- package/dist/SystemDiagnostics/system-diagnostics.component.js +4 -4
- package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
- package/dist/Testing/components/testing-analytics.component.js +2 -2
- package/dist/Testing/components/testing-analytics.component.js.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab.component.js +4 -4
- package/dist/Testing/components/testing-dashboard-tab.component.js.map +1 -1
- package/dist/Testing/components/testing-explorer.component.js +2 -2
- package/dist/Testing/components/testing-explorer.component.js.map +1 -1
- package/dist/Testing/components/testing-review.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-review.component.js +5 -5
- package/dist/Testing/components/testing-review.component.js.map +1 -1
- package/dist/Testing/components/testing-runs.component.js +2 -2
- package/dist/Testing/components/testing-runs.component.js.map +1 -1
- package/dist/Testing/components/widgets/oracle-breakdown-table.component.js +2 -2
- package/dist/Testing/components/widgets/oracle-breakdown-table.component.js.map +1 -1
- package/dist/Testing/components/widgets/suite-tree.component.js +4 -4
- package/dist/Testing/components/widgets/suite-tree.component.js.map +1 -1
- package/dist/Testing/components/widgets/test-run-detail-panel.component.js +2 -2
- package/dist/Testing/components/widgets/test-run-detail-panel.component.js.map +1 -1
- package/dist/Testing/testing-dashboard.component.js +2 -2
- package/dist/VersionHistory/components/diff-resource.component.js +2 -2
- package/dist/VersionHistory/components/graph-resource.component.js +2 -2
- package/dist/VersionHistory/components/labels-resource.component.js +3 -3
- package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/restore-resource.component.js +3 -3
- package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
- package/dist/__tests__/integration-data-service.test.js +1 -0
- package/dist/__tests__/integration-data-service.test.js.map +1 -1
- package/dist/module.d.ts +52 -49
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +25 -6
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +1 -1
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -1
- package/dist/public-api.js.map +1 -1
- package/package.json +42 -40
- package/dist/Scheduling/components/job-slideout.component.d.ts +0 -45
- package/dist/Scheduling/components/job-slideout.component.d.ts.map +0 -1
- package/dist/Scheduling/components/job-slideout.component.js +0 -459
- package/dist/Scheduling/components/job-slideout.component.js.map +0 -1
|
@@ -824,7 +824,7 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
|
|
|
824
824
|
i0.ɵɵconditional(ctx.hasSidebarContent && !ctx.sidebarOpen ? 11 : -1);
|
|
825
825
|
i0.ɵɵadvance();
|
|
826
826
|
i0.ɵɵtwoWayProperty("ShowDialog", ctx.showConfigDialog);
|
|
827
|
-
} }, dependencies: [i3.ButtonComponent, i4.UserAppConfigComponent, i5.LoadingComponent, i6.SlicePipe], styles: [".home-dashboard[_ngcontent-%COMP%] {\n display: flex;\n height: 100%;\n background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);\n overflow: hidden;\n position: relative;\n}\n\n\n\n.main-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: 32px;\n overflow-y: auto;\n transition: margin-right 0.3s ease;\n}\n\n\n\n.home-dashboard.sidebar-open[_ngcontent-%COMP%] .main-content[_ngcontent-%COMP%] {\n margin-right: 320px;\n}\n\n\n\n.home-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 32px;\n}\n\n.greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 32px;\n font-weight: 600;\n color: #212529;\n}\n\n.greeting-section[_ngcontent-%COMP%] .date[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n color: #6c757d;\n}\n\n\n\n.sidebar-fab-toggle[_ngcontent-%COMP%] {\n position: fixed;\n top: 80px; \n\n right: 24px;\n width: 56px;\n height: 56px;\n border: none;\n border-radius: 50%;\n background: #1976d2;\n color: white;\n font-size: 20px;\n cursor: pointer;\n box-shadow: 0 4px 12px rgba(25, 118, 210, 0.4);\n transition: all 0.2s ease;\n z-index: 100;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sidebar-fab-toggle[_ngcontent-%COMP%]:hover {\n background: #1565c0;\n transform: scale(1.05);\n box-shadow: 0 6px 16px rgba(25, 118, 210, 0.5);\n}\n\n.fab-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: -4px;\n right: -4px;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: #e53935;\n color: white;\n font-size: 11px;\n font-weight: 600;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1;\n gap: 16px;\n color: #6c757d;\n}\n\n.loading-spinner[_ngcontent-%COMP%] {\n font-size: 32px;\n color: #1976d2;\n}\n\n\n\n.apps-section[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n}\n\n.section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin: 0 0 24px 0;\n font-size: 20px;\n font-weight: 600;\n color: #495057;\n}\n\n.section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6c757d;\n}\n\n\n\n.apps-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 20px;\n}\n\n\n\n.app-card[_ngcontent-%COMP%] {\n --app-color: #757575;\n display: flex;\n align-items: flex-start;\n gap: 16px;\n padding: 20px;\n background: white;\n border-radius: 14px;\n border: 1px solid #e9ecef;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\n cursor: pointer;\n transition: all 0.25s ease;\n position: relative;\n overflow: hidden;\n}\n\n.app-card[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n width: 4px;\n height: 100%;\n background: var(--app-color);\n opacity: 0;\n transition: opacity 0.25s ease;\n}\n\n.app-card[_ngcontent-%COMP%]:hover {\n border-color: var(--app-color);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);\n transform: translateY(-3px);\n}\n\n.app-card[_ngcontent-%COMP%]:hover::before {\n opacity: 1;\n}\n\n\n\n.app-icon-wrapper[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.app-icon[_ngcontent-%COMP%] {\n width: 52px;\n height: 52px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--app-color) 12%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.25s ease;\n}\n\n.app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 22px;\n color: var(--app-color);\n transition: transform 0.25s ease;\n}\n\n.app-card[_ngcontent-%COMP%]:hover .app-icon[_ngcontent-%COMP%] {\n background: var(--app-color);\n}\n\n.app-card[_ngcontent-%COMP%]:hover .app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: white;\n transform: scale(1.1);\n}\n\n\n\n.app-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.app-name[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: 17px;\n font-weight: 600;\n color: #212529;\n}\n\n.app-description[_ngcontent-%COMP%] {\n margin: 0 0 10px 0;\n font-size: 13px;\n color: #6c757d;\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n\n\n.nav-preview[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n align-items: center;\n}\n\n.nav-item-chip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 3px 8px;\n background: #f8f9fa;\n border-radius: 5px;\n font-size: 11px;\n color: #495057;\n}\n\n.nav-item-chip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n color: #6c757d;\n}\n\n.more-items[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #6c757d;\n font-style: italic;\n}\n\n\n\n.app-arrow[_ngcontent-%COMP%] {\n position: absolute;\n right: 14px;\n top: 50%;\n transform: translateY(-50%) translateX(10px);\n opacity: 0;\n transition: all 0.25s ease;\n color: var(--app-color);\n font-size: 16px;\n}\n\n.app-card[_ngcontent-%COMP%]:hover .app-arrow[_ngcontent-%COMP%] {\n opacity: 1;\n transform: translateY(-50%) translateX(0);\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 24px;\n background: white;\n border-radius: 16px;\n border: 2px dashed #dee2e6;\n text-align: center;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: #f8f9fa;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 24px;\n}\n\n.empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: #adb5bd;\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 20px;\n font-weight: 600;\n color: #495057;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: #6c757d;\n max-width: 400px;\n}\n\n.empty-state[_ngcontent-%COMP%] button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 8px;\n}\n\n\n\n\n\n.quick-access-sidebar[_ngcontent-%COMP%] {\n position: fixed;\n top: 60px; \n\n right: 0;\n bottom: 0;\n width: 320px;\n background: white;\n border-left: 1px solid #e9ecef;\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform 0.3s ease;\n overflow: hidden;\n z-index: 100;\n box-shadow: -2px 0 8px rgba(0, 0, 0, 0.08);\n}\n\n.home-dashboard.sidebar-open[_ngcontent-%COMP%] .quick-access-sidebar[_ngcontent-%COMP%] {\n transform: translateX(0);\n}\n\n.sidebar-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px;\n border-bottom: 1px solid #e9ecef;\n background: #fafbfc;\n}\n\n.sidebar-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #212529;\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.sidebar-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #1976d2;\n font-size: 14px;\n}\n\n.sidebar-close-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: #6c757d;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n}\n\n.sidebar-close-btn[_ngcontent-%COMP%]:hover {\n background: #f1f3f4;\n color: #212529;\n}\n\n.sidebar-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n}\n\n\n\n.sidebar-section[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.sidebar-section[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.sidebar-section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 12px 0;\n font-size: 13px;\n font-weight: 600;\n color: #6c757d;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.notifications-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #f57c00;\n}\n\n.favorites-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #ffc107;\n}\n\n.recents-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #1976d2;\n}\n\n.section-badge[_ngcontent-%COMP%] {\n background: #e53935;\n color: white;\n font-size: 10px;\n font-weight: 600;\n padding: 2px 6px;\n border-radius: 8px;\n margin-left: auto;\n}\n\n\n\n.sidebar-items[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sidebar-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n background: #f8f9fa;\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.sidebar-item[_ngcontent-%COMP%]:hover {\n background: #e9ecef;\n transform: translateX(4px);\n}\n\n.sidebar-item-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border-radius: 8px;\n background: white;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #6c757d;\n}\n\n.notification-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: #fff3e0;\n}\n\n.notification-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #f57c00;\n}\n\n.favorite-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: #fff8e1;\n}\n\n.favorite-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #f9a825;\n}\n\n.recent-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: #e3f2fd;\n}\n\n.recent-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #1976d2;\n}\n\n.sidebar-item-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n flex: 1;\n}\n\n.sidebar-item-title[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: #212529;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-item-subtitle[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #6c757d;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n color: #6c757d;\n font-size: 13px;\n padding: 8px 0;\n}\n\n.sidebar-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #1976d2;\n}\n\n.sidebar-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n color: #adb5bd;\n}\n\n.sidebar-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n margin-bottom: 12px;\n}\n\n.sidebar-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n}\n\n\n\n\n\n\n\n\n\n@media (max-width: 1200px) {\n .quick-access-sidebar[_ngcontent-%COMP%] {\n width: 280px;\n }\n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%] .main-content[_ngcontent-%COMP%] {\n margin-right: 280px;\n }\n\n .apps-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n }\n}\n\n\n\n@media (max-width: 992px) {\n .main-content[_ngcontent-%COMP%] {\n padding: 24px;\n }\n\n .greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 28px;\n }\n\n \n\n .quick-access-sidebar[_ngcontent-%COMP%] {\n position: fixed;\n top: 60px; \n\n right: 0;\n bottom: 0;\n width: 320px;\n z-index: 1000;\n box-shadow: -4px 0 20px rgba(0, 0, 0, 0.15);\n }\n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%] .main-content[_ngcontent-%COMP%] {\n margin-right: 0;\n }\n\n \n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::after {\n content: '';\n position: fixed;\n top: 60px;\n left: 0;\n right: 320px;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 999;\n }\n}\n\n\n\n@media (max-width: 768px) {\n .home-dashboard[_ngcontent-%COMP%] {\n height: auto;\n min-height: 100%;\n overflow: visible;\n }\n\n .main-content[_ngcontent-%COMP%] {\n padding: 20px;\n padding-bottom: 100px; \n\n overflow: visible;\n }\n\n .home-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n margin-bottom: 24px;\n }\n\n .greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 24px;\n }\n\n \n\n .quick-access-sidebar[_ngcontent-%COMP%] {\n position: fixed;\n top: 60px; \n\n right: 0;\n bottom: 0;\n width: 100%;\n max-width: 100%;\n z-index: 100; \n\n border-left: none;\n border-top: 1px solid #e9ecef;\n }\n\n \n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::before {\n content: '';\n position: fixed;\n top: 60px;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 99;\n }\n\n \n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::after {\n display: none;\n }\n\n .apps-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .app-card[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .app-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n }\n\n .app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .app-name[_ngcontent-%COMP%] {\n font-size: 15px;\n }\n\n .nav-preview[_ngcontent-%COMP%] {\n display: none;\n }\n\n \n\n .sidebar-fab-toggle[_ngcontent-%COMP%] {\n top: auto;\n bottom: 20px;\n right: 20px;\n width: 48px;\n height: 48px;\n font-size: 18px;\n }\n}\n\n@media (max-width: 480px) {\n .main-content[_ngcontent-%COMP%] {\n padding: 16px;\n padding-bottom: 80px;\n }\n\n .greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .greeting-section[_ngcontent-%COMP%] .date[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .section-title[_ngcontent-%COMP%] {\n font-size: 16px;\n margin-bottom: 16px;\n }\n\n .sidebar-fab-toggle[_ngcontent-%COMP%] {\n bottom: 16px;\n right: 16px;\n width: 44px;\n height: 44px;\n font-size: 16px;\n }\n}"], changeDetection: 0 });
|
|
827
|
+
} }, dependencies: [i3.ButtonComponent, i4.UserAppConfigComponent, i5.LoadingComponent, i6.SlicePipe], styles: [".home-dashboard[_ngcontent-%COMP%] {\n display: flex;\n height: 100%;\n background: var(--mj-bg-page);\n overflow: hidden;\n position: relative;\n}\n\n\n\n.main-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: 32px;\n overflow-y: auto;\n transition: margin-right var(--mj-transition-slow);\n}\n\n\n\n.home-dashboard.sidebar-open[_ngcontent-%COMP%] .main-content[_ngcontent-%COMP%] {\n margin-right: 320px;\n}\n\n\n\n.home-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 32px;\n}\n\n.greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: var(--mj-text-4xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.greeting-section[_ngcontent-%COMP%] .date[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-base);\n color: var(--mj-text-muted);\n}\n\n\n\n.sidebar-fab-toggle[_ngcontent-%COMP%] {\n position: fixed;\n top: 80px; \n\n right: 24px;\n width: 56px;\n height: 56px;\n border: none;\n border-radius: var(--mj-radius-full);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: var(--mj-text-xl);\n cursor: pointer;\n box-shadow: var(--mj-shadow-brand-md);\n transition: all var(--mj-transition-base);\n z-index: 100;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sidebar-fab-toggle[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n transform: scale(1.05);\n box-shadow: 0 6px 16px color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n}\n\n.fab-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: -4px;\n right: -4px;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n border-radius: var(--mj-radius-full);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1;\n gap: 16px;\n color: var(--mj-text-muted);\n}\n\n.loading-spinner[_ngcontent-%COMP%] {\n font-size: var(--mj-text-4xl);\n color: var(--mj-brand-primary);\n}\n\n\n\n.apps-section[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n}\n\n.section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin: 0 0 24px 0;\n font-size: var(--mj-text-xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n}\n\n.section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n\n\n.apps-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 20px;\n}\n\n\n\n.app-card[_ngcontent-%COMP%] {\n --app-color: var(--mj-text-muted);\n display: flex;\n align-items: flex-start;\n gap: 16px;\n padding: 20px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n cursor: pointer;\n transition: all 0.25s ease;\n position: relative;\n overflow: hidden;\n}\n\n.app-card[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n width: 4px;\n height: 100%;\n background: var(--app-color);\n opacity: 0;\n transition: opacity 0.25s ease;\n}\n\n.app-card[_ngcontent-%COMP%]:hover {\n border-color: var(--app-color);\n box-shadow: var(--mj-shadow-lg);\n transform: translateY(-3px);\n}\n\n.app-card[_ngcontent-%COMP%]:hover::before {\n opacity: 1;\n}\n\n\n\n.app-icon-wrapper[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.app-icon[_ngcontent-%COMP%] {\n width: 52px;\n height: 52px;\n border-radius: var(--mj-radius-lg);\n background: color-mix(in srgb, var(--app-color) 12%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.25s ease;\n}\n\n.app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xl);\n color: var(--app-color);\n transition: transform 0.25s ease;\n}\n\n.app-card[_ngcontent-%COMP%]:hover .app-icon[_ngcontent-%COMP%] {\n background: var(--app-color);\n}\n\n.app-card[_ngcontent-%COMP%]:hover .app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-inverse);\n transform: scale(1.1);\n}\n\n\n\n.app-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.app-name[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.app-description[_ngcontent-%COMP%] {\n margin: 0 0 10px 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n line-height: var(--mj-leading-snug);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n\n\n.nav-preview[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n align-items: center;\n}\n\n.nav-item-chip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 3px 8px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n}\n\n.nav-item-chip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n color: var(--mj-text-muted);\n}\n\n.more-items[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n\n\n.app-arrow[_ngcontent-%COMP%] {\n position: absolute;\n right: 14px;\n top: 50%;\n transform: translateY(-50%) translateX(10px);\n opacity: 0;\n transition: all 0.25s ease;\n color: var(--app-color);\n font-size: var(--mj-text-base);\n}\n\n.app-card[_ngcontent-%COMP%]:hover .app-arrow[_ngcontent-%COMP%] {\n opacity: 1;\n transform: translateY(-50%) translateX(0);\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 24px;\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n border: 2px dashed var(--mj-border-default);\n text-align: center;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n border-radius: var(--mj-radius-full);\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 24px;\n}\n\n.empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-4xl);\n color: var(--mj-text-disabled);\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: var(--mj-text-xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n max-width: 400px;\n}\n\n.empty-state[_ngcontent-%COMP%] button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 8px;\n}\n\n\n\n\n\n.quick-access-sidebar[_ngcontent-%COMP%] {\n position: fixed;\n top: 60px; \n\n right: 0;\n bottom: 0;\n width: 320px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform var(--mj-transition-slow);\n overflow: hidden;\n z-index: 100;\n box-shadow: -2px 0 8px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n.home-dashboard.sidebar-open[_ngcontent-%COMP%] .quick-access-sidebar[_ngcontent-%COMP%] {\n transform: translateX(0);\n}\n\n.sidebar-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.sidebar-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.sidebar-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: var(--mj-text-sm);\n}\n\n.sidebar-close-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all var(--mj-transition-base);\n}\n\n.sidebar-close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.sidebar-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n}\n\n\n\n.sidebar-section[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.sidebar-section[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.sidebar-section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 12px 0;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n}\n\n.notifications-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-600);\n}\n\n.favorites-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.recents-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.section-badge[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: var(--mj-font-semibold);\n padding: 2px 6px;\n border-radius: var(--mj-radius-md);\n margin-left: auto;\n}\n\n\n\n.sidebar-items[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sidebar-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n cursor: pointer;\n transition: all var(--mj-transition-base);\n}\n\n.sidebar-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n transform: translateX(4px);\n}\n\n.sidebar-item-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n}\n\n.notification-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: var(--mj-color-warning-50);\n}\n\n.notification-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-600);\n}\n\n.favorite-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: var(--mj-color-warning-50);\n}\n\n.favorite-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-500);\n}\n\n.recent-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: var(--mj-color-info-50);\n}\n\n.recent-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.sidebar-item-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n flex: 1;\n}\n\n.sidebar-item-title[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-item-subtitle[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n padding: 8px 0;\n}\n\n.sidebar-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.sidebar-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n color: var(--mj-text-disabled);\n}\n\n.sidebar-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-4xl);\n margin-bottom: 12px;\n}\n\n.sidebar-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-sm);\n}\n\n\n\n\n\n\n\n\n\n@media (max-width: 1200px) {\n .quick-access-sidebar[_ngcontent-%COMP%] {\n width: 280px;\n }\n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%] .main-content[_ngcontent-%COMP%] {\n margin-right: 280px;\n }\n\n .apps-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n }\n}\n\n\n\n@media (max-width: 992px) {\n .main-content[_ngcontent-%COMP%] {\n padding: 24px;\n }\n\n .greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: var(--mj-text-3xl);\n }\n\n \n\n .quick-access-sidebar[_ngcontent-%COMP%] {\n position: fixed;\n top: 60px; \n\n right: 0;\n bottom: 0;\n width: 320px;\n z-index: 1000;\n box-shadow: -4px 0 20px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n }\n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%] .main-content[_ngcontent-%COMP%] {\n margin-right: 0;\n }\n\n \n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::after {\n content: '';\n position: fixed;\n top: 60px;\n left: 0;\n right: 320px;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n }\n}\n\n\n\n@media (max-width: 768px) {\n .home-dashboard[_ngcontent-%COMP%] {\n height: auto;\n min-height: 100%;\n overflow: visible;\n }\n\n .main-content[_ngcontent-%COMP%] {\n padding: 20px;\n padding-bottom: 100px; \n\n overflow: visible;\n }\n\n .home-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n margin-bottom: 24px;\n }\n\n .greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: var(--mj-text-2xl);\n }\n\n \n\n .quick-access-sidebar[_ngcontent-%COMP%] {\n position: fixed;\n top: 60px; \n\n right: 0;\n bottom: 0;\n width: 100%;\n max-width: 100%;\n z-index: 100; \n\n border-left: none;\n border-top: 1px solid var(--mj-border-default);\n }\n\n \n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::before {\n content: '';\n position: fixed;\n top: 60px;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 99;\n }\n\n \n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::after {\n display: none;\n }\n\n .apps-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .app-card[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .app-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n }\n\n .app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-lg);\n }\n\n .app-name[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n }\n\n .nav-preview[_ngcontent-%COMP%] {\n display: none;\n }\n\n \n\n .sidebar-fab-toggle[_ngcontent-%COMP%] {\n top: auto;\n bottom: 20px;\n right: 20px;\n width: 48px;\n height: 48px;\n font-size: var(--mj-text-lg);\n }\n}\n\n@media (max-width: 480px) {\n .main-content[_ngcontent-%COMP%] {\n padding: 16px;\n padding-bottom: 80px;\n }\n\n .greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xl);\n }\n\n .greeting-section[_ngcontent-%COMP%] .date[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n }\n\n .section-title[_ngcontent-%COMP%] {\n font-size: var(--mj-text-base);\n margin-bottom: 16px;\n }\n\n .sidebar-fab-toggle[_ngcontent-%COMP%] {\n bottom: 16px;\n right: 16px;\n width: 44px;\n height: 44px;\n font-size: var(--mj-text-base);\n }\n}"], changeDetection: 0 });
|
|
828
828
|
};
|
|
829
829
|
HomeDashboardComponent = __decorate([
|
|
830
830
|
RegisterClass(BaseResourceComponent, 'HomeDashboard')
|
|
@@ -832,7 +832,7 @@ HomeDashboardComponent = __decorate([
|
|
|
832
832
|
export { HomeDashboardComponent };
|
|
833
833
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(HomeDashboardComponent, [{
|
|
834
834
|
type: Component,
|
|
835
|
-
args: [{ standalone: false, selector: 'mj-home-dashboard', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"home-dashboard\" [class.sidebar-open]=\"sidebarOpen && hasSidebarContent\">\n <!-- Main Content Area -->\n <div class=\"main-content\">\n <!-- Header Section -->\n <div class=\"home-header\">\n <div class=\"greeting-section\">\n <h1>{{ greeting }}, {{ currentUser?.Name }}</h1>\n <p class=\"date\">{{ formattedDate }}</p>\n </div>\n </div>\n\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading your applications...\" size=\"large\"></mj-loading>\n </div>\n }\n\n <!-- Apps Grid -->\n @if (!isLoading) {\n <div class=\"apps-section\">\n <h2 class=\"section-title\">\n <i class=\"fa-solid fa-grid-2\"></i>\n Your Applications\n </h2>\n <div class=\"apps-grid\">\n @for (appData of appsDisplayData; track trackByApp($index, appData)) {\n <div\n class=\"app-card\"\n [style.--app-color]=\"appData.color\"\n (click)=\"onAppClick(appData.app)\">\n <!-- App Icon -->\n <div class=\"app-icon-wrapper\">\n <div class=\"app-icon\">\n <i [class]=\"appData.icon\"></i>\n </div>\n </div>\n <!-- App Info -->\n <div class=\"app-info\">\n <h3 class=\"app-name\">{{ appData.app.Name }}</h3>\n @if (appData.app.Description) {\n <p class=\"app-description\">{{ appData.app.Description }}</p>\n }\n <!-- Nav Items Preview -->\n @if (appData.navItemsCount > 0) {\n <div class=\"nav-preview\">\n @for (item of appData.navItemsPreview; track trackByNavItem($index, item)) {\n <div class=\"nav-item-chip\">\n <i [class]=\"item.Icon\"></i>\n <span>{{ item.Label }}</span>\n </div>\n }\n @if (appData.showMoreItems) {\n <span class=\"more-items\">\n +{{ appData.moreItemsCount }} more\n </span>\n }\n </div>\n }\n </div>\n <!-- Hover Arrow -->\n <div class=\"app-arrow\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n </div>\n }\n </div>\n <!-- Empty State -->\n @if (apps.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-folder-open\"></i>\n </div>\n <h3>No Applications Available</h3>\n <p>You don't have any applications configured yet.</p>\n <button kendoButton\n themeColor=\"primary\"\n (click)=\"openConfigDialog()\">\n <i class=\"fa-solid fa-gear\"></i>\n Configure Applications\n </button>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Collapsible Right Sidebar -->\n @if (hasSidebarContent) {\n <div class=\"quick-access-sidebar\">\n <div class=\"sidebar-header\">\n <h3>\n <i class=\"fa-solid fa-bolt\"></i>\n Quick Access\n </h3>\n <button class=\"sidebar-close-btn\" (click)=\"toggleSidebar()\" title=\"Close panel\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div class=\"sidebar-content\">\n <!-- Unread Notifications Section -->\n @if (unreadNotifications.length > 0) {\n <div class=\"sidebar-section notifications-section\">\n <h4 class=\"sidebar-section-title\">\n <i class=\"fa-solid fa-bell\"></i>\n Notifications\n <span class=\"section-badge\">{{ unreadNotifications.length }}</span>\n </h4>\n <div class=\"sidebar-items\">\n @for (notification of unreadNotifications; track trackByNotification($index, notification)) {\n <div\n class=\"sidebar-item notification-item\"\n (click)=\"onNotificationClick(notification)\">\n <div class=\"sidebar-item-info\">\n <span class=\"sidebar-item-title\">{{ notification.Title }}</span>\n <span class=\"sidebar-item-subtitle\">{{ notification.Message | slice:0:40 }}{{ (notification.Message?.length || 0) > 40 ? '...' : '' }}</span>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Favorites Section -->\n @if (favorites.length > 0 || favoritesLoading) {\n <div class=\"sidebar-section favorites-section\">\n <h4 class=\"sidebar-section-title\">\n <i class=\"fa-solid fa-star\"></i>\n Favorites\n </h4>\n @if (!favoritesLoading) {\n <div class=\"sidebar-items\">\n @for (favorite of favorites; track trackByFavorite($index, favorite)) {\n <div\n class=\"sidebar-item favorite-item\"\n (click)=\"onFavoriteClick(favorite)\">\n <div class=\"sidebar-item-icon\">\n <i [class]=\"getEntityIconByName(favorite.Entity)\"></i>\n </div>\n <div class=\"sidebar-item-info\">\n <span class=\"sidebar-item-title\">{{ getFavoriteDisplayName(favorite) }}</span>\n <span class=\"sidebar-item-subtitle\">{{ favorite.Entity }}</span>\n </div>\n </div>\n }\n </div>\n }\n @if (favoritesLoading) {\n <div class=\"sidebar-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading...</span>\n </div>\n }\n </div>\n }\n <!-- Recents Section -->\n @if (recentItems.length > 0 || recentsLoading) {\n <div class=\"sidebar-section recents-section\">\n <h4 class=\"sidebar-section-title\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n Recent\n </h4>\n @if (!recentsLoading) {\n <div class=\"sidebar-items\">\n @for (item of recentItems; track trackByRecent($index, item)) {\n <div\n class=\"sidebar-item recent-item\"\n (click)=\"onRecentClick(item)\">\n <div class=\"sidebar-item-icon\">\n <i [class]=\"getEntityIconByName(item.entityName)\"></i>\n </div>\n <div class=\"sidebar-item-info\">\n <span class=\"sidebar-item-title\">{{ item.recordName || item.recordId }}</span>\n <span class=\"sidebar-item-subtitle\">{{ item.entityName }} \u00B7 {{ formatDate(item.latestAt) }}</span>\n </div>\n </div>\n }\n </div>\n }\n @if (recentsLoading) {\n <div class=\"sidebar-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading...</span>\n </div>\n }\n </div>\n }\n <!-- Empty sidebar state -->\n @if (!favoritesLoading && !recentsLoading && unreadNotifications.length === 0 && favorites.length === 0 && recentItems.length === 0) {\n <div class=\"sidebar-empty\">\n <i class=\"fa-solid fa-inbox\"></i>\n <p>No quick access items</p>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Quick Access FAB Toggle (Fixed Button) -->\n @if (hasSidebarContent && !sidebarOpen) {\n <button class=\"sidebar-fab-toggle\"\n (click)=\"toggleSidebar()\"\n title=\"Quick Access\">\n <i class=\"fa-solid fa-bolt\"></i>\n @if (unreadNotifications.length > 0) {\n <span class=\"fab-badge\">{{ unreadNotifications.length }}</span>\n }\n </button>\n }\n\n <!-- App Configuration Dialog -->\n <mj-user-app-config\n #appConfigDialog\n [(ShowDialog)]=\"showConfigDialog\"\n (ConfigSaved)=\"onConfigSaved()\">\n </mj-user-app-config>\n</div>\n", styles: [".home-dashboard {\n display: flex;\n height: 100%;\n background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);\n overflow: hidden;\n position: relative;\n}\n\n/* Main Content Area */\n.main-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: 32px;\n overflow-y: auto;\n transition: margin-right 0.3s ease;\n}\n\n/* Sidebar open state adjusts main content on desktop */\n.home-dashboard.sidebar-open .main-content {\n margin-right: 320px;\n}\n\n/* Header */\n.home-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 32px;\n}\n\n.greeting-section h1 {\n margin: 0 0 8px 0;\n font-size: 32px;\n font-weight: 600;\n color: #212529;\n}\n\n.greeting-section .date {\n margin: 0;\n font-size: 16px;\n color: #6c757d;\n}\n\n/* FAB Toggle Button for Quick Access - top-right on desktop */\n.sidebar-fab-toggle {\n position: fixed;\n top: 80px; /* Below shell header with some spacing */\n right: 24px;\n width: 56px;\n height: 56px;\n border: none;\n border-radius: 50%;\n background: #1976d2;\n color: white;\n font-size: 20px;\n cursor: pointer;\n box-shadow: 0 4px 12px rgba(25, 118, 210, 0.4);\n transition: all 0.2s ease;\n z-index: 100;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sidebar-fab-toggle:hover {\n background: #1565c0;\n transform: scale(1.05);\n box-shadow: 0 6px 16px rgba(25, 118, 210, 0.5);\n}\n\n.fab-badge {\n position: absolute;\n top: -4px;\n right: -4px;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: #e53935;\n color: white;\n font-size: 11px;\n font-weight: 600;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Loading State */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1;\n gap: 16px;\n color: #6c757d;\n}\n\n.loading-spinner {\n font-size: 32px;\n color: #1976d2;\n}\n\n/* Apps Section */\n.apps-section {\n flex: 0 0 auto;\n}\n\n.section-title {\n display: flex;\n align-items: center;\n gap: 12px;\n margin: 0 0 24px 0;\n font-size: 20px;\n font-weight: 600;\n color: #495057;\n}\n\n.section-title i {\n color: #6c757d;\n}\n\n/* Apps Grid */\n.apps-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 20px;\n}\n\n/* App Card */\n.app-card {\n --app-color: #757575;\n display: flex;\n align-items: flex-start;\n gap: 16px;\n padding: 20px;\n background: white;\n border-radius: 14px;\n border: 1px solid #e9ecef;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\n cursor: pointer;\n transition: all 0.25s ease;\n position: relative;\n overflow: hidden;\n}\n\n.app-card::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n width: 4px;\n height: 100%;\n background: var(--app-color);\n opacity: 0;\n transition: opacity 0.25s ease;\n}\n\n.app-card:hover {\n border-color: var(--app-color);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);\n transform: translateY(-3px);\n}\n\n.app-card:hover::before {\n opacity: 1;\n}\n\n/* App Icon */\n.app-icon-wrapper {\n flex-shrink: 0;\n}\n\n.app-icon {\n width: 52px;\n height: 52px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--app-color) 12%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.25s ease;\n}\n\n.app-icon i {\n font-size: 22px;\n color: var(--app-color);\n transition: transform 0.25s ease;\n}\n\n.app-card:hover .app-icon {\n background: var(--app-color);\n}\n\n.app-card:hover .app-icon i {\n color: white;\n transform: scale(1.1);\n}\n\n/* App Info */\n.app-info {\n flex: 1;\n min-width: 0;\n}\n\n.app-name {\n margin: 0 0 4px 0;\n font-size: 17px;\n font-weight: 600;\n color: #212529;\n}\n\n.app-description {\n margin: 0 0 10px 0;\n font-size: 13px;\n color: #6c757d;\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n/* Nav Items Preview */\n.nav-preview {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n align-items: center;\n}\n\n.nav-item-chip {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 3px 8px;\n background: #f8f9fa;\n border-radius: 5px;\n font-size: 11px;\n color: #495057;\n}\n\n.nav-item-chip i {\n font-size: 9px;\n color: #6c757d;\n}\n\n.more-items {\n font-size: 11px;\n color: #6c757d;\n font-style: italic;\n}\n\n/* App Arrow */\n.app-arrow {\n position: absolute;\n right: 14px;\n top: 50%;\n transform: translateY(-50%) translateX(10px);\n opacity: 0;\n transition: all 0.25s ease;\n color: var(--app-color);\n font-size: 16px;\n}\n\n.app-card:hover .app-arrow {\n opacity: 1;\n transform: translateY(-50%) translateX(0);\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 24px;\n background: white;\n border-radius: 16px;\n border: 2px dashed #dee2e6;\n text-align: center;\n}\n\n.empty-icon {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: #f8f9fa;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 24px;\n}\n\n.empty-icon i {\n font-size: 32px;\n color: #adb5bd;\n}\n\n.empty-state h3 {\n margin: 0 0 8px 0;\n font-size: 20px;\n font-weight: 600;\n color: #495057;\n}\n\n.empty-state p {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: #6c757d;\n max-width: 400px;\n}\n\n.empty-state button i {\n margin-right: 8px;\n}\n\n/* ========================================\n RIGHT SIDEBAR\n ======================================== */\n.quick-access-sidebar {\n position: fixed;\n top: 60px; /* Below shell header */\n right: 0;\n bottom: 0;\n width: 320px;\n background: white;\n border-left: 1px solid #e9ecef;\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform 0.3s ease;\n overflow: hidden;\n z-index: 100;\n box-shadow: -2px 0 8px rgba(0, 0, 0, 0.08);\n}\n\n.home-dashboard.sidebar-open .quick-access-sidebar {\n transform: translateX(0);\n}\n\n.sidebar-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px;\n border-bottom: 1px solid #e9ecef;\n background: #fafbfc;\n}\n\n.sidebar-header h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #212529;\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.sidebar-header h3 i {\n color: #1976d2;\n font-size: 14px;\n}\n\n.sidebar-close-btn {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: #6c757d;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n}\n\n.sidebar-close-btn:hover {\n background: #f1f3f4;\n color: #212529;\n}\n\n.sidebar-content {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n}\n\n/* Sidebar Sections */\n.sidebar-section {\n margin-bottom: 20px;\n}\n\n.sidebar-section:last-child {\n margin-bottom: 0;\n}\n\n.sidebar-section-title {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 12px 0;\n font-size: 13px;\n font-weight: 600;\n color: #6c757d;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.sidebar-section-title i {\n font-size: 12px;\n}\n\n.notifications-section .sidebar-section-title i {\n color: #f57c00;\n}\n\n.favorites-section .sidebar-section-title i {\n color: #ffc107;\n}\n\n.recents-section .sidebar-section-title i {\n color: #1976d2;\n}\n\n.section-badge {\n background: #e53935;\n color: white;\n font-size: 10px;\n font-weight: 600;\n padding: 2px 6px;\n border-radius: 8px;\n margin-left: auto;\n}\n\n/* Sidebar Items */\n.sidebar-items {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sidebar-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n background: #f8f9fa;\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.sidebar-item:hover {\n background: #e9ecef;\n transform: translateX(4px);\n}\n\n.sidebar-item-icon {\n width: 36px;\n height: 36px;\n border-radius: 8px;\n background: white;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.sidebar-item-icon i {\n font-size: 14px;\n color: #6c757d;\n}\n\n.notification-item .sidebar-item-icon {\n background: #fff3e0;\n}\n\n.notification-item .sidebar-item-icon i {\n color: #f57c00;\n}\n\n.favorite-item .sidebar-item-icon {\n background: #fff8e1;\n}\n\n.favorite-item .sidebar-item-icon i {\n color: #f9a825;\n}\n\n.recent-item .sidebar-item-icon {\n background: #e3f2fd;\n}\n\n.recent-item .sidebar-item-icon i {\n color: #1976d2;\n}\n\n.sidebar-item-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n flex: 1;\n}\n\n.sidebar-item-title {\n font-size: 13px;\n font-weight: 500;\n color: #212529;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-item-subtitle {\n font-size: 11px;\n color: #6c757d;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-loading {\n display: flex;\n align-items: center;\n gap: 8px;\n color: #6c757d;\n font-size: 13px;\n padding: 8px 0;\n}\n\n.sidebar-loading i {\n color: #1976d2;\n}\n\n.sidebar-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n color: #adb5bd;\n}\n\n.sidebar-empty i {\n font-size: 32px;\n margin-bottom: 12px;\n}\n\n.sidebar-empty p {\n margin: 0;\n font-size: 13px;\n}\n\n\n/* ========================================\n RESPONSIVE DESIGN\n ======================================== */\n\n/* Tablet and smaller desktop */\n@media (max-width: 1200px) {\n .quick-access-sidebar {\n width: 280px;\n }\n\n .home-dashboard.sidebar-open .main-content {\n margin-right: 280px;\n }\n\n .apps-grid {\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n }\n}\n\n/* Tablet */\n@media (max-width: 992px) {\n .main-content {\n padding: 24px;\n }\n\n .greeting-section h1 {\n font-size: 28px;\n }\n\n /* Make sidebar an overlay on tablet */\n .quick-access-sidebar {\n position: fixed;\n top: 60px; /* Below shell header */\n right: 0;\n bottom: 0;\n width: 320px;\n z-index: 1000;\n box-shadow: -4px 0 20px rgba(0, 0, 0, 0.15);\n }\n\n .home-dashboard.sidebar-open .main-content {\n margin-right: 0;\n }\n\n /* Show backdrop when sidebar is open on tablet */\n .home-dashboard.sidebar-open::after {\n content: '';\n position: fixed;\n top: 60px;\n left: 0;\n right: 320px;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 999;\n }\n}\n\n/* Mobile */\n@media (max-width: 768px) {\n .home-dashboard {\n height: auto;\n min-height: 100%;\n overflow: visible;\n }\n\n .main-content {\n padding: 20px;\n padding-bottom: 100px; /* Space for FAB button */\n overflow: visible;\n }\n\n .home-header {\n flex-direction: column;\n gap: 16px;\n margin-bottom: 24px;\n }\n\n .greeting-section h1 {\n font-size: 24px;\n }\n\n /* Full-width sidebar on mobile - positioned below top nav */\n .quick-access-sidebar {\n position: fixed;\n top: 60px; /* Below the shell header */\n right: 0;\n bottom: 0;\n width: 100%;\n max-width: 100%;\n z-index: 100; /* Below shell header */\n border-left: none;\n border-top: 1px solid #e9ecef;\n }\n\n /* Add backdrop on mobile when sidebar is open */\n .home-dashboard.sidebar-open::before {\n content: '';\n position: fixed;\n top: 60px;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 99;\n }\n\n /* No ::after backdrop needed on mobile */\n .home-dashboard.sidebar-open::after {\n display: none;\n }\n\n .apps-grid {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .app-card {\n padding: 16px;\n }\n\n .app-icon {\n width: 44px;\n height: 44px;\n }\n\n .app-icon i {\n font-size: 18px;\n }\n\n .app-name {\n font-size: 15px;\n }\n\n .nav-preview {\n display: none;\n }\n\n /* Move FAB to bottom-right on mobile */\n .sidebar-fab-toggle {\n top: auto;\n bottom: 20px;\n right: 20px;\n width: 48px;\n height: 48px;\n font-size: 18px;\n }\n}\n\n@media (max-width: 480px) {\n .main-content {\n padding: 16px;\n padding-bottom: 80px;\n }\n\n .greeting-section h1 {\n font-size: 20px;\n }\n\n .greeting-section .date {\n font-size: 14px;\n }\n\n .section-title {\n font-size: 16px;\n margin-bottom: 16px;\n }\n\n .sidebar-fab-toggle {\n bottom: 16px;\n right: 16px;\n width: 44px;\n height: 44px;\n font-size: 16px;\n }\n}\n"] }]
|
|
835
|
+
args: [{ standalone: false, selector: 'mj-home-dashboard', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"home-dashboard\" [class.sidebar-open]=\"sidebarOpen && hasSidebarContent\">\n <!-- Main Content Area -->\n <div class=\"main-content\">\n <!-- Header Section -->\n <div class=\"home-header\">\n <div class=\"greeting-section\">\n <h1>{{ greeting }}, {{ currentUser?.Name }}</h1>\n <p class=\"date\">{{ formattedDate }}</p>\n </div>\n </div>\n\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading your applications...\" size=\"large\"></mj-loading>\n </div>\n }\n\n <!-- Apps Grid -->\n @if (!isLoading) {\n <div class=\"apps-section\">\n <h2 class=\"section-title\">\n <i class=\"fa-solid fa-grid-2\"></i>\n Your Applications\n </h2>\n <div class=\"apps-grid\">\n @for (appData of appsDisplayData; track trackByApp($index, appData)) {\n <div\n class=\"app-card\"\n [style.--app-color]=\"appData.color\"\n (click)=\"onAppClick(appData.app)\">\n <!-- App Icon -->\n <div class=\"app-icon-wrapper\">\n <div class=\"app-icon\">\n <i [class]=\"appData.icon\"></i>\n </div>\n </div>\n <!-- App Info -->\n <div class=\"app-info\">\n <h3 class=\"app-name\">{{ appData.app.Name }}</h3>\n @if (appData.app.Description) {\n <p class=\"app-description\">{{ appData.app.Description }}</p>\n }\n <!-- Nav Items Preview -->\n @if (appData.navItemsCount > 0) {\n <div class=\"nav-preview\">\n @for (item of appData.navItemsPreview; track trackByNavItem($index, item)) {\n <div class=\"nav-item-chip\">\n <i [class]=\"item.Icon\"></i>\n <span>{{ item.Label }}</span>\n </div>\n }\n @if (appData.showMoreItems) {\n <span class=\"more-items\">\n +{{ appData.moreItemsCount }} more\n </span>\n }\n </div>\n }\n </div>\n <!-- Hover Arrow -->\n <div class=\"app-arrow\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n </div>\n }\n </div>\n <!-- Empty State -->\n @if (apps.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-folder-open\"></i>\n </div>\n <h3>No Applications Available</h3>\n <p>You don't have any applications configured yet.</p>\n <button kendoButton\n themeColor=\"primary\"\n (click)=\"openConfigDialog()\">\n <i class=\"fa-solid fa-gear\"></i>\n Configure Applications\n </button>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Collapsible Right Sidebar -->\n @if (hasSidebarContent) {\n <div class=\"quick-access-sidebar\">\n <div class=\"sidebar-header\">\n <h3>\n <i class=\"fa-solid fa-bolt\"></i>\n Quick Access\n </h3>\n <button class=\"sidebar-close-btn\" (click)=\"toggleSidebar()\" title=\"Close panel\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div class=\"sidebar-content\">\n <!-- Unread Notifications Section -->\n @if (unreadNotifications.length > 0) {\n <div class=\"sidebar-section notifications-section\">\n <h4 class=\"sidebar-section-title\">\n <i class=\"fa-solid fa-bell\"></i>\n Notifications\n <span class=\"section-badge\">{{ unreadNotifications.length }}</span>\n </h4>\n <div class=\"sidebar-items\">\n @for (notification of unreadNotifications; track trackByNotification($index, notification)) {\n <div\n class=\"sidebar-item notification-item\"\n (click)=\"onNotificationClick(notification)\">\n <div class=\"sidebar-item-info\">\n <span class=\"sidebar-item-title\">{{ notification.Title }}</span>\n <span class=\"sidebar-item-subtitle\">{{ notification.Message | slice:0:40 }}{{ (notification.Message?.length || 0) > 40 ? '...' : '' }}</span>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Favorites Section -->\n @if (favorites.length > 0 || favoritesLoading) {\n <div class=\"sidebar-section favorites-section\">\n <h4 class=\"sidebar-section-title\">\n <i class=\"fa-solid fa-star\"></i>\n Favorites\n </h4>\n @if (!favoritesLoading) {\n <div class=\"sidebar-items\">\n @for (favorite of favorites; track trackByFavorite($index, favorite)) {\n <div\n class=\"sidebar-item favorite-item\"\n (click)=\"onFavoriteClick(favorite)\">\n <div class=\"sidebar-item-icon\">\n <i [class]=\"getEntityIconByName(favorite.Entity)\"></i>\n </div>\n <div class=\"sidebar-item-info\">\n <span class=\"sidebar-item-title\">{{ getFavoriteDisplayName(favorite) }}</span>\n <span class=\"sidebar-item-subtitle\">{{ favorite.Entity }}</span>\n </div>\n </div>\n }\n </div>\n }\n @if (favoritesLoading) {\n <div class=\"sidebar-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading...</span>\n </div>\n }\n </div>\n }\n <!-- Recents Section -->\n @if (recentItems.length > 0 || recentsLoading) {\n <div class=\"sidebar-section recents-section\">\n <h4 class=\"sidebar-section-title\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n Recent\n </h4>\n @if (!recentsLoading) {\n <div class=\"sidebar-items\">\n @for (item of recentItems; track trackByRecent($index, item)) {\n <div\n class=\"sidebar-item recent-item\"\n (click)=\"onRecentClick(item)\">\n <div class=\"sidebar-item-icon\">\n <i [class]=\"getEntityIconByName(item.entityName)\"></i>\n </div>\n <div class=\"sidebar-item-info\">\n <span class=\"sidebar-item-title\">{{ item.recordName || item.recordId }}</span>\n <span class=\"sidebar-item-subtitle\">{{ item.entityName }} \u00B7 {{ formatDate(item.latestAt) }}</span>\n </div>\n </div>\n }\n </div>\n }\n @if (recentsLoading) {\n <div class=\"sidebar-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading...</span>\n </div>\n }\n </div>\n }\n <!-- Empty sidebar state -->\n @if (!favoritesLoading && !recentsLoading && unreadNotifications.length === 0 && favorites.length === 0 && recentItems.length === 0) {\n <div class=\"sidebar-empty\">\n <i class=\"fa-solid fa-inbox\"></i>\n <p>No quick access items</p>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Quick Access FAB Toggle (Fixed Button) -->\n @if (hasSidebarContent && !sidebarOpen) {\n <button class=\"sidebar-fab-toggle\"\n (click)=\"toggleSidebar()\"\n title=\"Quick Access\">\n <i class=\"fa-solid fa-bolt\"></i>\n @if (unreadNotifications.length > 0) {\n <span class=\"fab-badge\">{{ unreadNotifications.length }}</span>\n }\n </button>\n }\n\n <!-- App Configuration Dialog -->\n <mj-user-app-config\n #appConfigDialog\n [(ShowDialog)]=\"showConfigDialog\"\n (ConfigSaved)=\"onConfigSaved()\">\n </mj-user-app-config>\n</div>\n", styles: [".home-dashboard {\n display: flex;\n height: 100%;\n background: var(--mj-bg-page);\n overflow: hidden;\n position: relative;\n}\n\n/* Main Content Area */\n.main-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: 32px;\n overflow-y: auto;\n transition: margin-right var(--mj-transition-slow);\n}\n\n/* Sidebar open state adjusts main content on desktop */\n.home-dashboard.sidebar-open .main-content {\n margin-right: 320px;\n}\n\n/* Header */\n.home-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 32px;\n}\n\n.greeting-section h1 {\n margin: 0 0 8px 0;\n font-size: var(--mj-text-4xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.greeting-section .date {\n margin: 0;\n font-size: var(--mj-text-base);\n color: var(--mj-text-muted);\n}\n\n/* FAB Toggle Button for Quick Access - top-right on desktop */\n.sidebar-fab-toggle {\n position: fixed;\n top: 80px; /* Below shell header with some spacing */\n right: 24px;\n width: 56px;\n height: 56px;\n border: none;\n border-radius: var(--mj-radius-full);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: var(--mj-text-xl);\n cursor: pointer;\n box-shadow: var(--mj-shadow-brand-md);\n transition: all var(--mj-transition-base);\n z-index: 100;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sidebar-fab-toggle:hover {\n background: var(--mj-brand-primary-hover);\n transform: scale(1.05);\n box-shadow: 0 6px 16px color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n}\n\n.fab-badge {\n position: absolute;\n top: -4px;\n right: -4px;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n border-radius: var(--mj-radius-full);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Loading State */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1;\n gap: 16px;\n color: var(--mj-text-muted);\n}\n\n.loading-spinner {\n font-size: var(--mj-text-4xl);\n color: var(--mj-brand-primary);\n}\n\n/* Apps Section */\n.apps-section {\n flex: 0 0 auto;\n}\n\n.section-title {\n display: flex;\n align-items: center;\n gap: 12px;\n margin: 0 0 24px 0;\n font-size: var(--mj-text-xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n}\n\n.section-title i {\n color: var(--mj-text-muted);\n}\n\n/* Apps Grid */\n.apps-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 20px;\n}\n\n/* App Card */\n.app-card {\n --app-color: var(--mj-text-muted);\n display: flex;\n align-items: flex-start;\n gap: 16px;\n padding: 20px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n cursor: pointer;\n transition: all 0.25s ease;\n position: relative;\n overflow: hidden;\n}\n\n.app-card::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n width: 4px;\n height: 100%;\n background: var(--app-color);\n opacity: 0;\n transition: opacity 0.25s ease;\n}\n\n.app-card:hover {\n border-color: var(--app-color);\n box-shadow: var(--mj-shadow-lg);\n transform: translateY(-3px);\n}\n\n.app-card:hover::before {\n opacity: 1;\n}\n\n/* App Icon */\n.app-icon-wrapper {\n flex-shrink: 0;\n}\n\n.app-icon {\n width: 52px;\n height: 52px;\n border-radius: var(--mj-radius-lg);\n background: color-mix(in srgb, var(--app-color) 12%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.25s ease;\n}\n\n.app-icon i {\n font-size: var(--mj-text-xl);\n color: var(--app-color);\n transition: transform 0.25s ease;\n}\n\n.app-card:hover .app-icon {\n background: var(--app-color);\n}\n\n.app-card:hover .app-icon i {\n color: var(--mj-text-inverse);\n transform: scale(1.1);\n}\n\n/* App Info */\n.app-info {\n flex: 1;\n min-width: 0;\n}\n\n.app-name {\n margin: 0 0 4px 0;\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.app-description {\n margin: 0 0 10px 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n line-height: var(--mj-leading-snug);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n/* Nav Items Preview */\n.nav-preview {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n align-items: center;\n}\n\n.nav-item-chip {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 3px 8px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n}\n\n.nav-item-chip i {\n font-size: 9px;\n color: var(--mj-text-muted);\n}\n\n.more-items {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n/* App Arrow */\n.app-arrow {\n position: absolute;\n right: 14px;\n top: 50%;\n transform: translateY(-50%) translateX(10px);\n opacity: 0;\n transition: all 0.25s ease;\n color: var(--app-color);\n font-size: var(--mj-text-base);\n}\n\n.app-card:hover .app-arrow {\n opacity: 1;\n transform: translateY(-50%) translateX(0);\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 24px;\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n border: 2px dashed var(--mj-border-default);\n text-align: center;\n}\n\n.empty-icon {\n width: 80px;\n height: 80px;\n border-radius: var(--mj-radius-full);\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 24px;\n}\n\n.empty-icon i {\n font-size: var(--mj-text-4xl);\n color: var(--mj-text-disabled);\n}\n\n.empty-state h3 {\n margin: 0 0 8px 0;\n font-size: var(--mj-text-xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n}\n\n.empty-state p {\n margin: 0 0 20px 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n max-width: 400px;\n}\n\n.empty-state button i {\n margin-right: 8px;\n}\n\n/* ========================================\n RIGHT SIDEBAR\n ======================================== */\n.quick-access-sidebar {\n position: fixed;\n top: 60px; /* Below shell header */\n right: 0;\n bottom: 0;\n width: 320px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform var(--mj-transition-slow);\n overflow: hidden;\n z-index: 100;\n box-shadow: -2px 0 8px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n.home-dashboard.sidebar-open .quick-access-sidebar {\n transform: translateX(0);\n}\n\n.sidebar-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.sidebar-header h3 {\n margin: 0;\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.sidebar-header h3 i {\n color: var(--mj-brand-primary);\n font-size: var(--mj-text-sm);\n}\n\n.sidebar-close-btn {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all var(--mj-transition-base);\n}\n\n.sidebar-close-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.sidebar-content {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n}\n\n/* Sidebar Sections */\n.sidebar-section {\n margin-bottom: 20px;\n}\n\n.sidebar-section:last-child {\n margin-bottom: 0;\n}\n\n.sidebar-section-title {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 12px 0;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.sidebar-section-title i {\n font-size: var(--mj-text-xs);\n}\n\n.notifications-section .sidebar-section-title i {\n color: var(--mj-color-warning-600);\n}\n\n.favorites-section .sidebar-section-title i {\n color: var(--mj-status-warning);\n}\n\n.recents-section .sidebar-section-title i {\n color: var(--mj-brand-primary);\n}\n\n.section-badge {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: var(--mj-font-semibold);\n padding: 2px 6px;\n border-radius: var(--mj-radius-md);\n margin-left: auto;\n}\n\n/* Sidebar Items */\n.sidebar-items {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sidebar-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n cursor: pointer;\n transition: all var(--mj-transition-base);\n}\n\n.sidebar-item:hover {\n background: var(--mj-bg-surface-hover);\n transform: translateX(4px);\n}\n\n.sidebar-item-icon {\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.sidebar-item-icon i {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n}\n\n.notification-item .sidebar-item-icon {\n background: var(--mj-color-warning-50);\n}\n\n.notification-item .sidebar-item-icon i {\n color: var(--mj-color-warning-600);\n}\n\n.favorite-item .sidebar-item-icon {\n background: var(--mj-color-warning-50);\n}\n\n.favorite-item .sidebar-item-icon i {\n color: var(--mj-color-warning-500);\n}\n\n.recent-item .sidebar-item-icon {\n background: var(--mj-color-info-50);\n}\n\n.recent-item .sidebar-item-icon i {\n color: var(--mj-brand-primary);\n}\n\n.sidebar-item-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n flex: 1;\n}\n\n.sidebar-item-title {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-item-subtitle {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-loading {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n padding: 8px 0;\n}\n\n.sidebar-loading i {\n color: var(--mj-brand-primary);\n}\n\n.sidebar-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n color: var(--mj-text-disabled);\n}\n\n.sidebar-empty i {\n font-size: var(--mj-text-4xl);\n margin-bottom: 12px;\n}\n\n.sidebar-empty p {\n margin: 0;\n font-size: var(--mj-text-sm);\n}\n\n\n/* ========================================\n RESPONSIVE DESIGN\n ======================================== */\n\n/* Tablet and smaller desktop */\n@media (max-width: 1200px) {\n .quick-access-sidebar {\n width: 280px;\n }\n\n .home-dashboard.sidebar-open .main-content {\n margin-right: 280px;\n }\n\n .apps-grid {\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n }\n}\n\n/* Tablet */\n@media (max-width: 992px) {\n .main-content {\n padding: 24px;\n }\n\n .greeting-section h1 {\n font-size: var(--mj-text-3xl);\n }\n\n /* Make sidebar an overlay on tablet */\n .quick-access-sidebar {\n position: fixed;\n top: 60px; /* Below shell header */\n right: 0;\n bottom: 0;\n width: 320px;\n z-index: 1000;\n box-shadow: -4px 0 20px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n }\n\n .home-dashboard.sidebar-open .main-content {\n margin-right: 0;\n }\n\n /* Show backdrop when sidebar is open on tablet */\n .home-dashboard.sidebar-open::after {\n content: '';\n position: fixed;\n top: 60px;\n left: 0;\n right: 320px;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n }\n}\n\n/* Mobile */\n@media (max-width: 768px) {\n .home-dashboard {\n height: auto;\n min-height: 100%;\n overflow: visible;\n }\n\n .main-content {\n padding: 20px;\n padding-bottom: 100px; /* Space for FAB button */\n overflow: visible;\n }\n\n .home-header {\n flex-direction: column;\n gap: 16px;\n margin-bottom: 24px;\n }\n\n .greeting-section h1 {\n font-size: var(--mj-text-2xl);\n }\n\n /* Full-width sidebar on mobile - positioned below top nav */\n .quick-access-sidebar {\n position: fixed;\n top: 60px; /* Below the shell header */\n right: 0;\n bottom: 0;\n width: 100%;\n max-width: 100%;\n z-index: 100; /* Below shell header */\n border-left: none;\n border-top: 1px solid var(--mj-border-default);\n }\n\n /* Add backdrop on mobile when sidebar is open */\n .home-dashboard.sidebar-open::before {\n content: '';\n position: fixed;\n top: 60px;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 99;\n }\n\n /* No ::after backdrop needed on mobile */\n .home-dashboard.sidebar-open::after {\n display: none;\n }\n\n .apps-grid {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .app-card {\n padding: 16px;\n }\n\n .app-icon {\n width: 44px;\n height: 44px;\n }\n\n .app-icon i {\n font-size: var(--mj-text-lg);\n }\n\n .app-name {\n font-size: var(--mj-text-sm);\n }\n\n .nav-preview {\n display: none;\n }\n\n /* Move FAB to bottom-right on mobile */\n .sidebar-fab-toggle {\n top: auto;\n bottom: 20px;\n right: 20px;\n width: 48px;\n height: 48px;\n font-size: var(--mj-text-lg);\n }\n}\n\n@media (max-width: 480px) {\n .main-content {\n padding: 16px;\n padding-bottom: 80px;\n }\n\n .greeting-section h1 {\n font-size: var(--mj-text-xl);\n }\n\n .greeting-section .date {\n font-size: var(--mj-text-sm);\n }\n\n .section-title {\n font-size: var(--mj-text-base);\n margin-bottom: 16px;\n }\n\n .sidebar-fab-toggle {\n bottom: 16px;\n right: 16px;\n width: 44px;\n height: 44px;\n font-size: var(--mj-text-base);\n }\n}\n"] }]
|
|
836
836
|
}], () => [{ type: i1.ApplicationManager }, { type: i2.NavigationService }, { type: i2.RecentAccessService }, { type: i0.ChangeDetectorRef }], { appConfigDialog: [{
|
|
837
837
|
type: ViewChild,
|
|
838
838
|
args: ['appConfigDialog']
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"activity.component.d.ts","sourceRoot":"","sources":["../../../../src/Integration/components/activity/activity.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,MAAM,EAAU,MAAM,eAAe,CAAC;AAE7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,OAAO,EAGL,iBAAiB,EACjB,YAAY,EAEb,MAAM,yCAAyC,CAAC;;AAEjD,KAAK,gBAAgB,GAAG,KAAK,GAAG,SAAS,GAAG,QAAQ,GAAG,aAAa,GAAG,SAAS,CAAC;AACjF,KAAK,cAAc,GAAG,OAAO,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,CAAC;AAErD,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,
|
|
1
|
+
{"version":3,"file":"activity.component.d.ts","sourceRoot":"","sources":["../../../../src/Integration/components/activity/activity.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,MAAM,EAAU,MAAM,eAAe,CAAC;AAE7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,OAAO,EAGL,iBAAiB,EACjB,YAAY,EAEb,MAAM,yCAAyC,CAAC;;AAEjD,KAAK,gBAAgB,GAAG,KAAK,GAAG,SAAS,GAAG,QAAQ,GAAG,aAAa,GAAG,SAAS,CAAC;AACjF,KAAK,cAAc,GAAG,OAAO,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,CAAC;AAErD,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,iBAAiB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qBAOa,iBAAkB,SAAQ,qBAAsB,YAAW,MAAM;IAG5E,OAAO,EAAE,iBAAiB,EAAE,CAAM;IAClC,YAAY,EAAE,iBAAiB,EAAE,CAAM;IACvC,YAAY,EAAE,iBAAiB,EAAE,CAAM;IACvC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAQ;IACpC,kBAAkB,EAAE,YAAY,EAAE,CAAM;IACxC,aAAa,EAAE,YAAY,EAAE,CAAM;IACnC,SAAS,UAAQ;IACjB,eAAe,UAAS;IAGxB,YAAY,EAAE,gBAAgB,CAAS;IACvC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACxC,UAAU,EAAE,cAAc,CAAQ;IAClC,WAAW,SAAM;IACjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAQ;IAGpC,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,iBAAiB,CAAS;IAGlC,eAAe,EAAE,UAAU,GAAG,YAAY,CAAc;IACxD,mBAAmB,UAAS;IAE5B,aAAa,EAAE,gBAAgB,EAAE,CAA0D;IAC3F,WAAW,EAAE;QAAE,KAAK,EAAE,cAAc,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAKrD;IAEF,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,GAAG,CAA6B;IAElC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAMzB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;YAoBjB,WAAW;IAczB,OAAO,CAAC,uBAAuB;IAOzB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAStD,cAAc,CAAC,oBAAoB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAanD,iBAAiB;IAiB/B,OAAO,CAAC,6BAA6B;IAarC,YAAY,IAAI,IAAI;IASpB,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,aAAa;IAcrB,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI;IAK/C,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAK1C,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAK7C,cAAc,IAAI,IAAI;IAIhB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAMxB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBvC,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBhD,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIlC,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIrC,kBAAkB,IAAI,YAAY,EAAE;IAIpC,wBAAwB,IAAI,OAAO;IAInC,cAAc,IAAI,iBAAiB,GAAG,IAAI;IAI1C,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,YAAY,GAAG,IAAI;IAIlD,OAAO,CAAC,WAAW;IAOnB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM;IAMxE,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM;IAI/C,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM;IAQlD,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM;IAM7C,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM;IAQ1C,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAOrC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAOtC,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAIzC,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAIvC,aAAa,CAAC,GAAG,EAAE,iBAAiB,GAAG,MAAM;IAM7C,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,IAAI,qBAAqB,IAAI,MAAM,CAElC;IAID,mBAAmB,CAAC,GAAG,EAAE,iBAAiB,GAAG,MAAM;IAKnD,mBAAmB,CAAC,GAAG,EAAE,iBAAiB,GAAG,MAAM;IAM7C,sBAAsB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAI5D,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;yCAvXrD,iBAAiB;2CAAjB,iBAAiB;CA0X7B;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C"}
|
|
@@ -463,7 +463,7 @@ function ActivityComponent_Conditional_21_Conditional_4_Conditional_22_Condition
|
|
|
463
463
|
i0.ɵɵadvance(2);
|
|
464
464
|
i0.ɵɵtextInterpolate(ctx_r2.FormatWatermark(wm_r13.WatermarkValue));
|
|
465
465
|
i0.ɵɵadvance(2);
|
|
466
|
-
i0.ɵɵtextInterpolate(ctx_r2.FormatDate(wm_r13.
|
|
466
|
+
i0.ɵɵtextInterpolate(ctx_r2.FormatDate(wm_r13.LastSyncAt));
|
|
467
467
|
} }
|
|
468
468
|
function ActivityComponent_Conditional_21_Conditional_4_Conditional_22_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
469
469
|
i0.ɵɵelementStart(0, "table", 75)(1, "thead")(2, "tr")(3, "th");
|
|
@@ -666,8 +666,8 @@ let ActivityComponent = class ActivityComponent extends BaseResourceComponent {
|
|
|
666
666
|
const result = await rv.RunView({
|
|
667
667
|
EntityName: 'MJ: Company Integration Sync Watermarks',
|
|
668
668
|
ExtraFilter: `EntityMapID IN (${entityMapIDs})`,
|
|
669
|
-
OrderBy: '
|
|
670
|
-
Fields: ['ID', 'EntityMapID', 'WatermarkType', 'WatermarkValue', '
|
|
669
|
+
OrderBy: 'LastSyncAt DESC',
|
|
670
|
+
Fields: ['ID', 'EntityMapID', 'WatermarkType', 'WatermarkValue', 'LastSyncAt'],
|
|
671
671
|
ResultType: 'simple'
|
|
672
672
|
});
|
|
673
673
|
return this.mergeWatermarksWithEntityMaps(result.Results, entityMaps);
|
|
@@ -943,7 +943,7 @@ let ActivityComponent = class ActivityComponent extends BaseResourceComponent {
|
|
|
943
943
|
i0.ɵɵconditional(!ctx.IsLoading && ctx.FilteredRuns.length === 0 ? 20 : -1);
|
|
944
944
|
i0.ɵɵadvance();
|
|
945
945
|
i0.ɵɵconditional(!ctx.IsLoading && ctx.FilteredRuns.length > 0 ? 21 : -1);
|
|
946
|
-
} }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.LoadingComponent, i3.DecimalPipe], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n}\n\n.activity-container[_ngcontent-%COMP%] {\n padding: 20px;\n height: 100%;\n display: flex;\n flex-direction: column;\n gap: 14px;\n overflow: auto;\n}\n\n\n\n\n.filter-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.filter-group[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.filter-pills[_ngcontent-%COMP%] {\n gap: 0;\n}\n\n.pill-btn[_ngcontent-%COMP%] {\n height: 32px;\n padding: 0 14px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-muted);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s, color 0.15s, border-color 0.15s;\n white-space: nowrap;\n}\n\n.pill-btn[_ngcontent-%COMP%]:first-child {\n border-radius: 9999px 0 0 9999px;\n}\n\n.pill-btn[_ngcontent-%COMP%]:last-child {\n border-radius: 0 9999px 9999px 0;\n}\n\n.pill-btn[_ngcontent-%COMP%]:not(:first-child) {\n margin-left: -1px;\n}\n\n.pill-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-info-bg);\n border-color: var(--mj-border-strong);\n z-index: 1;\n}\n\n.pill-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n z-index: 2;\n}\n\n.filter-select[_ngcontent-%COMP%] {\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n cursor: pointer;\n min-width: 180px;\n height: 32px;\n}\n\n.filter-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n.search-input[_ngcontent-%COMP%] {\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n min-width: 180px;\n height: 32px;\n}\n\n.search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n.refresh-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n transition: background 0.15s, color 0.15s;\n}\n\n.refresh-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-info-bg);\n color: var(--mj-brand-primary);\n}\n\n\n\n\n.summary-strip[_ngcontent-%COMP%] {\n display: inline-flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.summary-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--mj-text-muted);\n}\n\n.badge-dot[_ngcontent-%COMP%] {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.dot-blue[_ngcontent-%COMP%] { background: var(--mj-color-info-500); }\n.dot-green[_ngcontent-%COMP%] { background: var(--mj-color-success-600); }\n.dot-red[_ngcontent-%COMP%] { background: var(--mj-status-error); }\n.dot-amber[_ngcontent-%COMP%] { background: var(--mj-status-warning); }\n.dot-gray[_ngcontent-%COMP%] { background: var(--mj-text-disabled); }\n\n.badge-count[_ngcontent-%COMP%] {\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.count-green[_ngcontent-%COMP%] { color: var(--mj-color-success-600); }\n.count-red[_ngcontent-%COMP%] { color: var(--mj-color-error-600); }\n\n.badge-label[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n\n\n\n.loading-area[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n padding: 48px;\n}\n\n.empty-state[_ngcontent-%COMP%] {\n text-align: center;\n padding: 48px;\n color: var(--mj-text-disabled);\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n margin-bottom: 12px;\n display: block;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n}\n\n\n\n\n.split-view[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n\n\n\n.run-list-panel[_ngcontent-%COMP%] {\n flex: 7;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n}\n\n.run-row[_ngcontent-%COMP%] {\n border-bottom: 1px solid var(--mj-border-subtle);\n cursor: pointer;\n transition: background 0.1s;\n}\n\n.run-row[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-page);\n}\n\n.run-row.selected[_ngcontent-%COMP%] {\n background: var(--mj-status-info-bg);\n}\n\n.run-row-main[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n}\n\n\n\n.status-dot[_ngcontent-%COMP%] {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.status-icon[_ngcontent-%COMP%] {\n font-size: 14px;\n width: 16px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.icon-green[_ngcontent-%COMP%] { color: var(--mj-color-success-600); }\n.icon-red[_ngcontent-%COMP%] { color: var(--mj-status-error); }\n.icon-amber[_ngcontent-%COMP%] { color: var(--mj-status-warning); }\n.icon-gray[_ngcontent-%COMP%] { color: var(--mj-text-disabled); }\n\n\n\n.run-info[_ngcontent-%COMP%] {\n flex: 2;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 1px;\n}\n\n.run-integration[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.run-company[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-disabled);\n}\n\n\n\n.run-meta[_ngcontent-%COMP%] {\n flex-shrink: 0;\n font-size: 12px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n min-width: 60px;\n text-align: right;\n}\n\n.run-duration[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n min-width: 56px;\n}\n\n.run-records[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n min-width: 48px;\n}\n\n.run-errors[_ngcontent-%COMP%] {\n min-width: 24px;\n text-align: center;\n}\n\n.run-errors.has-errors[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.run-user[_ngcontent-%COMP%] {\n min-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.expand-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-disabled);\n font-size: 11px;\n transition: background 0.15s, transform 0.2s;\n flex-shrink: 0;\n}\n\n.expand-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-secondary);\n}\n\n.expand-btn[_ngcontent-%COMP%] i.rotated[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n}\n\n\n\n\n.expanded-section[_ngcontent-%COMP%] {\n padding: 8px 14px 14px 48px;\n background: var(--mj-bg-page);\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.expanded-loading[_ngcontent-%COMP%], \n.expanded-empty[_ngcontent-%COMP%] {\n padding: 16px;\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.expanded-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 6px;\n}\n\n.entity-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 12px;\n}\n\n.entity-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n padding: 6px 8px;\n color: var(--mj-text-disabled);\n font-weight: 600;\n font-size: 11px;\n border-bottom: 1px solid var(--mj-border-default);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.entity-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 5px 8px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.entity-table[_ngcontent-%COMP%] .num-col[_ngcontent-%COMP%], \n.detail-table[_ngcontent-%COMP%] .num-col[_ngcontent-%COMP%] {\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n\n.entity-table[_ngcontent-%COMP%] .created-col[_ngcontent-%COMP%], \n.detail-table[_ngcontent-%COMP%] .created-col[_ngcontent-%COMP%] {\n color: var(--mj-color-success-600);\n font-weight: 600;\n}\n\n.entity-table[_ngcontent-%COMP%] .updated-col[_ngcontent-%COMP%], \n.detail-table[_ngcontent-%COMP%] .updated-col[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.entity-table[_ngcontent-%COMP%] .error-col[_ngcontent-%COMP%], \n.detail-table[_ngcontent-%COMP%] .error-col[_ngcontent-%COMP%] {\n color: var(--mj-color-error-600);\n font-weight: 600;\n}\n\n.error-row[_ngcontent-%COMP%] {\n background: var(--mj-status-error-bg);\n}\n\n\n\n\n.error-log-block[_ngcontent-%COMP%] {\n margin-top: 10px;\n}\n\n.error-log-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-color-error-600);\n margin-bottom: 6px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.error-log-content[_ngcontent-%COMP%] {\n margin: 0;\n padding: 10px 12px;\n background: var(--mj-text-primary);\n color: #f1f5f9;\n font-family: 'SF Mono', 'Menlo', 'Consolas', monospace;\n font-size: 11px;\n border-radius: 8px;\n white-space: pre-wrap;\n word-break: break-word;\n max-height: 200px;\n overflow-y: auto;\n line-height: 1.5;\n}\n\n.detail-error-log[_ngcontent-%COMP%] {\n padding: 12px 16px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n\n\n\n.detail-panel[_ngcontent-%COMP%] {\n flex: 3;\n min-width: 340px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.detail-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n padding: 14px 16px;\n border-bottom: 1px solid var(--mj-border-subtle);\n gap: 12px;\n}\n\n.detail-header-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n}\n\n.detail-header-info[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 15px;\n font-weight: 700;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.detail-time[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-disabled);\n}\n\n.close-detail-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n font-size: 16px;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.close-detail-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-secondary);\n}\n\n\n\n.duration-bar-container[_ngcontent-%COMP%] {\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.duration-bar-track[_ngcontent-%COMP%] {\n height: 6px;\n background: var(--mj-bg-surface-active);\n border-radius: 3px;\n overflow: hidden;\n}\n\n.duration-bar-fill[_ngcontent-%COMP%] {\n height: 100%;\n background: linear-gradient(90deg, var(--mj-brand-primary), var(--mj-color-accent-400));\n border-radius: 3px;\n transition: width 0.3s;\n}\n\n.duration-bar-labels[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-top: 4px;\n font-size: 10px;\n color: var(--mj-text-disabled);\n}\n\n.duration-bar-value[_ngcontent-%COMP%] {\n font-weight: 700;\n color: var(--mj-color-info-500);\n font-size: 12px;\n}\n\n\n\n.detail-tabs[_ngcontent-%COMP%] {\n display: flex;\n border-bottom: 1px solid var(--mj-border-subtle);\n padding: 0 16px;\n gap: 2px;\n}\n\n.tab-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n border-bottom: 2px solid transparent;\n cursor: pointer;\n padding: 10px 12px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n display: flex;\n align-items: center;\n gap: 5px;\n transition: color 0.15s, border-color 0.15s;\n}\n\n.tab-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-brand-primary);\n}\n\n.tab-btn.active[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n\n\n.detail-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n}\n\n.detail-loading[_ngcontent-%COMP%], \n.detail-empty[_ngcontent-%COMP%] {\n padding: 24px;\n text-align: center;\n color: var(--mj-text-disabled);\n}\n\n.detail-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n margin-bottom: 8px;\n display: block;\n}\n\n.detail-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n}\n\n.detail-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 12px;\n}\n\n.detail-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n padding: 8px 10px;\n color: var(--mj-text-disabled);\n font-weight: 600;\n border-bottom: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-page);\n font-size: 11px;\n}\n\n.detail-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 7px 10px;\n border-bottom: 1px solid var(--mj-bg-page);\n}\n\n.mono-cell[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n color: var(--mj-text-muted);\n}\n\n.watermark-value[_ngcontent-%COMP%] {\n font-family: 'SF Mono', 'Menlo', 'Consolas', monospace;\n font-size: 11px;\n}\n\n\n\n.chip[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n padding: 3px 8px;\n border-radius: 10px;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n white-space: nowrap;\n}\n\n.chip-green[_ngcontent-%COMP%] { background: var(--mj-color-success-100); color: var(--mj-color-success-600); }\n.chip-red[_ngcontent-%COMP%] { background: var(--mj-color-error-100); color: var(--mj-color-error-600); }\n.chip-amber[_ngcontent-%COMP%] { background: var(--mj-color-warning-100); color: var(--mj-color-warning-600); }\n.chip-gray[_ngcontent-%COMP%] { background: var(--mj-bg-surface-hover); color: var(--mj-text-muted); }\n\n\n\n.type-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n background: var(--mj-status-info-bg);\n color: var(--mj-brand-primary);\n}\n\n\n\n\n@media (max-width: 900px) {\n .split-view[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .detail-panel[_ngcontent-%COMP%] {\n min-width: 0;\n max-height: 50vh;\n }\n\n .run-user[_ngcontent-%COMP%] {\n display: none;\n }\n}"] });
|
|
946
|
+
} }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.LoadingComponent, i3.DecimalPipe], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n}\n\n.activity-container[_ngcontent-%COMP%] {\n padding: 20px;\n height: 100%;\n display: flex;\n flex-direction: column;\n gap: 14px;\n overflow: auto;\n}\n\n\n\n\n.filter-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.filter-group[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.filter-pills[_ngcontent-%COMP%] {\n gap: 0;\n}\n\n.pill-btn[_ngcontent-%COMP%] {\n height: 32px;\n padding: 0 14px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-muted);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s, color 0.15s, border-color 0.15s;\n white-space: nowrap;\n}\n\n.pill-btn[_ngcontent-%COMP%]:first-child {\n border-radius: 9999px 0 0 9999px;\n}\n\n.pill-btn[_ngcontent-%COMP%]:last-child {\n border-radius: 0 9999px 9999px 0;\n}\n\n.pill-btn[_ngcontent-%COMP%]:not(:first-child) {\n margin-left: -1px;\n}\n\n.pill-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-info-bg);\n border-color: var(--mj-border-strong);\n z-index: 1;\n}\n\n.pill-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n z-index: 2;\n}\n\n.filter-select[_ngcontent-%COMP%] {\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n cursor: pointer;\n min-width: 180px;\n height: 32px;\n}\n\n.filter-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n.search-input[_ngcontent-%COMP%] {\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n min-width: 180px;\n height: 32px;\n}\n\n.search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n.refresh-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n transition: background 0.15s, color 0.15s;\n}\n\n.refresh-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-info-bg);\n color: var(--mj-brand-primary);\n}\n\n\n\n\n.summary-strip[_ngcontent-%COMP%] {\n display: inline-flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.summary-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--mj-text-muted);\n}\n\n.badge-dot[_ngcontent-%COMP%] {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.dot-blue[_ngcontent-%COMP%] { background: var(--mj-brand-primary); }\n.dot-green[_ngcontent-%COMP%] { background: var(--mj-color-success-600); }\n.dot-red[_ngcontent-%COMP%] { background: var(--mj-status-error); }\n.dot-amber[_ngcontent-%COMP%] { background: var(--mj-status-warning); }\n.dot-gray[_ngcontent-%COMP%] { background: var(--mj-text-disabled); }\n\n.badge-count[_ngcontent-%COMP%] {\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.count-green[_ngcontent-%COMP%] { color: var(--mj-color-success-600); }\n.count-red[_ngcontent-%COMP%] { color: var(--mj-color-error-600); }\n\n.badge-label[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n\n\n\n.loading-area[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n padding: 48px;\n}\n\n.empty-state[_ngcontent-%COMP%] {\n text-align: center;\n padding: 48px;\n color: var(--mj-text-disabled);\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n margin-bottom: 12px;\n display: block;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n}\n\n\n\n\n.split-view[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n\n\n\n.run-list-panel[_ngcontent-%COMP%] {\n flex: 7;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n}\n\n.run-row[_ngcontent-%COMP%] {\n border-bottom: 1px solid var(--mj-border-subtle);\n cursor: pointer;\n transition: background 0.1s;\n}\n\n.run-row[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-page);\n}\n\n.run-row.selected[_ngcontent-%COMP%] {\n background: var(--mj-status-info-bg);\n}\n\n.run-row-main[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n}\n\n\n\n.status-dot[_ngcontent-%COMP%] {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.status-icon[_ngcontent-%COMP%] {\n font-size: 14px;\n width: 16px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.icon-green[_ngcontent-%COMP%] { color: var(--mj-color-success-600); }\n.icon-red[_ngcontent-%COMP%] { color: var(--mj-status-error); }\n.icon-amber[_ngcontent-%COMP%] { color: var(--mj-status-warning); }\n.icon-gray[_ngcontent-%COMP%] { color: var(--mj-text-disabled); }\n\n\n\n.run-info[_ngcontent-%COMP%] {\n flex: 2;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 1px;\n}\n\n.run-integration[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.run-company[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-disabled);\n}\n\n\n\n.run-meta[_ngcontent-%COMP%] {\n flex-shrink: 0;\n font-size: 12px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n min-width: 60px;\n text-align: right;\n}\n\n.run-duration[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n min-width: 56px;\n}\n\n.run-records[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n min-width: 48px;\n}\n\n.run-errors[_ngcontent-%COMP%] {\n min-width: 24px;\n text-align: center;\n}\n\n.run-errors.has-errors[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.run-user[_ngcontent-%COMP%] {\n min-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.expand-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-disabled);\n font-size: 11px;\n transition: background 0.15s, transform 0.2s;\n flex-shrink: 0;\n}\n\n.expand-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-secondary);\n}\n\n.expand-btn[_ngcontent-%COMP%] i.rotated[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n}\n\n\n\n\n.expanded-section[_ngcontent-%COMP%] {\n padding: 8px 14px 14px 48px;\n background: var(--mj-bg-page);\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.expanded-loading[_ngcontent-%COMP%], \n.expanded-empty[_ngcontent-%COMP%] {\n padding: 16px;\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.expanded-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 6px;\n}\n\n.entity-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 12px;\n}\n\n.entity-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n padding: 6px 8px;\n color: var(--mj-text-disabled);\n font-weight: 600;\n font-size: 11px;\n border-bottom: 1px solid var(--mj-border-default);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.entity-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 5px 8px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.entity-table[_ngcontent-%COMP%] .num-col[_ngcontent-%COMP%], \n.detail-table[_ngcontent-%COMP%] .num-col[_ngcontent-%COMP%] {\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n\n.entity-table[_ngcontent-%COMP%] .created-col[_ngcontent-%COMP%], \n.detail-table[_ngcontent-%COMP%] .created-col[_ngcontent-%COMP%] {\n color: var(--mj-color-success-600);\n font-weight: 600;\n}\n\n.entity-table[_ngcontent-%COMP%] .updated-col[_ngcontent-%COMP%], \n.detail-table[_ngcontent-%COMP%] .updated-col[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.entity-table[_ngcontent-%COMP%] .error-col[_ngcontent-%COMP%], \n.detail-table[_ngcontent-%COMP%] .error-col[_ngcontent-%COMP%] {\n color: var(--mj-color-error-600);\n font-weight: 600;\n}\n\n.error-row[_ngcontent-%COMP%] {\n background: var(--mj-status-error-bg);\n}\n\n\n\n\n.error-log-block[_ngcontent-%COMP%] {\n margin-top: 10px;\n}\n\n.error-log-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-color-error-600);\n margin-bottom: 6px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.error-log-content[_ngcontent-%COMP%] {\n margin: 0;\n padding: 10px 12px;\n background: var(--mj-text-primary);\n color: var(--mj-bg-surface-sunken);\n font-family: 'SF Mono', 'Menlo', 'Consolas', monospace;\n font-size: 11px;\n border-radius: 8px;\n white-space: pre-wrap;\n word-break: break-word;\n max-height: 200px;\n overflow-y: auto;\n line-height: 1.5;\n}\n\n.detail-error-log[_ngcontent-%COMP%] {\n padding: 12px 16px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n\n\n\n.detail-panel[_ngcontent-%COMP%] {\n flex: 3;\n min-width: 340px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.detail-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n padding: 14px 16px;\n border-bottom: 1px solid var(--mj-border-subtle);\n gap: 12px;\n}\n\n.detail-header-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n}\n\n.detail-header-info[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 15px;\n font-weight: 700;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.detail-time[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-disabled);\n}\n\n.close-detail-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n font-size: 16px;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.close-detail-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-secondary);\n}\n\n\n\n.duration-bar-container[_ngcontent-%COMP%] {\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.duration-bar-track[_ngcontent-%COMP%] {\n height: 6px;\n background: var(--mj-bg-surface-active);\n border-radius: 3px;\n overflow: hidden;\n}\n\n.duration-bar-fill[_ngcontent-%COMP%] {\n height: 100%;\n background: linear-gradient(90deg, var(--mj-brand-primary), var(--mj-color-accent-400));\n border-radius: 3px;\n transition: width 0.3s;\n}\n\n.duration-bar-labels[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-top: 4px;\n font-size: 10px;\n color: var(--mj-text-disabled);\n}\n\n.duration-bar-value[_ngcontent-%COMP%] {\n font-weight: 700;\n color: var(--mj-brand-primary);\n font-size: 12px;\n}\n\n\n\n.detail-tabs[_ngcontent-%COMP%] {\n display: flex;\n border-bottom: 1px solid var(--mj-border-subtle);\n padding: 0 16px;\n gap: 2px;\n}\n\n.tab-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n border-bottom: 2px solid transparent;\n cursor: pointer;\n padding: 10px 12px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n display: flex;\n align-items: center;\n gap: 5px;\n transition: color 0.15s, border-color 0.15s;\n}\n\n.tab-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-brand-primary);\n}\n\n.tab-btn.active[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n\n\n.detail-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n}\n\n.detail-loading[_ngcontent-%COMP%], \n.detail-empty[_ngcontent-%COMP%] {\n padding: 24px;\n text-align: center;\n color: var(--mj-text-disabled);\n}\n\n.detail-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n margin-bottom: 8px;\n display: block;\n}\n\n.detail-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n}\n\n.detail-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 12px;\n}\n\n.detail-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n padding: 8px 10px;\n color: var(--mj-text-disabled);\n font-weight: 600;\n border-bottom: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-page);\n font-size: 11px;\n}\n\n.detail-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 7px 10px;\n border-bottom: 1px solid var(--mj-bg-page);\n}\n\n.mono-cell[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n color: var(--mj-text-muted);\n}\n\n.watermark-value[_ngcontent-%COMP%] {\n font-family: 'SF Mono', 'Menlo', 'Consolas', monospace;\n font-size: 11px;\n}\n\n\n\n.chip[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n padding: 3px 8px;\n border-radius: 10px;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n white-space: nowrap;\n}\n\n.chip-green[_ngcontent-%COMP%] { background: var(--mj-color-success-100); color: var(--mj-color-success-600); }\n.chip-red[_ngcontent-%COMP%] { background: var(--mj-color-error-100); color: var(--mj-color-error-600); }\n.chip-amber[_ngcontent-%COMP%] { background: var(--mj-color-warning-100); color: var(--mj-color-warning-600); }\n.chip-gray[_ngcontent-%COMP%] { background: var(--mj-bg-surface-hover); color: var(--mj-text-muted); }\n\n\n\n.type-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n background: var(--mj-status-info-bg);\n color: var(--mj-brand-primary);\n}\n\n\n\n\n@media (max-width: 900px) {\n .split-view[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .detail-panel[_ngcontent-%COMP%] {\n min-width: 0;\n max-height: 50vh;\n }\n\n .run-user[_ngcontent-%COMP%] {\n display: none;\n }\n}"] });
|
|
947
947
|
};
|
|
948
948
|
ActivityComponent = __decorate([
|
|
949
949
|
RegisterClass(BaseResourceComponent, 'IntegrationActivity')
|
|
@@ -951,7 +951,7 @@ ActivityComponent = __decorate([
|
|
|
951
951
|
export { ActivityComponent };
|
|
952
952
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ActivityComponent, [{
|
|
953
953
|
type: Component,
|
|
954
|
-
args: [{ standalone: false, selector: 'app-integration-activity', template: "<div class=\"activity-container\">\n\n <!-- Filter Bar -->\n <div class=\"filter-bar\">\n <div class=\"filter-group filter-pills\">\n @for (status of StatusOptions; track status) {\n <button class=\"pill-btn\"\n [class.active]=\"StatusFilter === status\"\n (click)=\"SetStatusFilter(status)\">\n {{ status }}\n </button>\n }\n </div>\n\n <div class=\"filter-group\">\n <select class=\"filter-select\"\n [ngModel]=\"IntegrationFilter ?? ''\"\n (ngModelChange)=\"SetIntegrationFilter($event || null)\">\n <option value=\"\">All Integrations</option>\n @for (opt of Integrations; track opt.ID) {\n <option [value]=\"opt.ID\">{{ opt.Name }}</option>\n }\n </select>\n </div>\n\n <div class=\"filter-group filter-pills\">\n @for (d of DateOptions; track d.Value) {\n <button class=\"pill-btn\"\n [class.active]=\"DateFilter === d.Value\"\n (click)=\"SetDateFilter(d.Value)\">\n {{ d.Label }}\n </button>\n }\n </div>\n\n <div class=\"filter-group\">\n <input type=\"text\"\n class=\"search-input\"\n placeholder=\"Search integrations...\"\n [(ngModel)]=\"SearchQuery\"\n (input)=\"OnSearchChange()\" />\n </div>\n\n <button class=\"refresh-btn\" (click)=\"Refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-arrows-rotate\"></i>\n </button>\n </div>\n\n <!-- Summary Strip -->\n @if (!IsLoading && AllRuns.length > 0) {\n <div class=\"summary-strip\">\n <div class=\"summary-badge\">\n <span class=\"badge-dot dot-blue\"></span>\n <span class=\"badge-count\">{{ TotalRuns }}</span>\n <span class=\"badge-label\">Total Runs</span>\n </div>\n <div class=\"summary-badge\">\n <span class=\"badge-dot dot-green\"></span>\n <span class=\"badge-count count-green\">{{ SuccessfulRuns }}</span>\n <span class=\"badge-label\">Successful</span>\n </div>\n <div class=\"summary-badge\">\n <span class=\"badge-dot dot-red\"></span>\n <span class=\"badge-count count-red\">{{ FailedRuns }}</span>\n <span class=\"badge-label\">Failed</span>\n </div>\n <div class=\"summary-badge\">\n <span class=\"badge-dot dot-blue\"></span>\n <span class=\"badge-count\">{{ TotalRecordsProcessed | number }}</span>\n <span class=\"badge-label\">Records Processed</span>\n </div>\n </div>\n }\n\n <!-- Loading state -->\n @if (IsLoading) {\n <div class=\"loading-area\">\n <mj-loading text=\"Loading activity...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Empty state -->\n @if (!IsLoading && FilteredRuns.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-inbox\"></i>\n <p>No runs found for the selected filters.</p>\n </div>\n }\n\n <!-- Split View: Run List + Detail Panel -->\n @if (!IsLoading && FilteredRuns.length > 0) {\n <div class=\"split-view\">\n\n <!-- Left panel: Run list -->\n <div class=\"run-list-panel\">\n @for (run of FilteredRuns; track run.ID) {\n <!-- Run row -->\n <div class=\"run-row\"\n [class.selected]=\"IsSelectedRun(run.ID)\"\n (click)=\"SelectRun(run.ID)\">\n <div class=\"run-row-main\">\n <!-- Status indicator -->\n <span [class]=\"GetStatusDotClass(run.Status)\"></span>\n <i [class]=\"GetStatusIcon(run.Status)\"\n [class.icon-green]=\"run.Status === 'Success'\"\n [class.icon-red]=\"run.Status === 'Failed'\"\n [class.icon-amber]=\"run.Status === 'In Progress'\"\n [class.icon-gray]=\"run.Status === 'Pending'\"\n class=\"status-icon\"></i>\n\n <!-- Integration info -->\n <div class=\"run-info\">\n <span class=\"run-integration\">{{ run.Integration }}</span>\n <span class=\"run-company\">{{ run.Company }}</span>\n </div>\n\n <!-- Started time -->\n <div class=\"run-meta\" [title]=\"FormatAbsoluteDate(run.StartedAt)\">\n {{ GetRelativeTime(run.StartedAt) }}\n </div>\n\n <!-- Duration -->\n <div class=\"run-meta run-duration\">\n {{ FormatDuration(run.StartedAt, run.EndedAt) }}\n </div>\n\n <!-- Records -->\n <div class=\"run-meta run-records\">\n {{ run.TotalRecords | number }}\n </div>\n\n <!-- Errors -->\n <div class=\"run-meta run-errors\" [class.has-errors]=\"run.ErrorLog\">\n @if (run.ErrorLog) {\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n }\n </div>\n\n <!-- Triggered by -->\n <div class=\"run-meta run-user\">\n {{ run.RunByUser || 'Scheduled' }}\n </div>\n\n <!-- Expand chevron -->\n <button class=\"expand-btn\"\n (click)=\"ToggleExpand(run.ID); $event.stopPropagation()\"\n title=\"Show entity breakdown\">\n <i class=\"fa-solid fa-chevron-down\"\n [class.rotated]=\"IsExpanded(run.ID)\"></i>\n </button>\n </div>\n\n <!-- Expanded section: entity breakdown -->\n @if (IsExpanded(run.ID)) {\n <div class=\"expanded-section\" (click)=\"$event.stopPropagation()\">\n @if (IsLoadingExpandedDetails()) {\n <div class=\"expanded-loading\">\n <mj-loading text=\"Loading breakdown...\" size=\"small\"></mj-loading>\n </div>\n } @else if (GetExpandedDetails().length === 0) {\n <div class=\"expanded-empty\">\n <i class=\"fa-solid fa-circle-info\"></i>\n No entity details for this run.\n </div>\n } @else {\n <table class=\"entity-table\">\n <thead>\n <tr>\n <th>Entity</th>\n <th class=\"num-col\">Processed</th>\n <th class=\"num-col\">Created</th>\n <th class=\"num-col\">Updated</th>\n <th class=\"num-col\">Deleted</th>\n <th class=\"num-col\">Errored</th>\n <th class=\"num-col\">Skipped</th>\n </tr>\n </thead>\n <tbody>\n @for (detail of GetExpandedDetails(); track detail.EntityID) {\n <tr [class.error-row]=\"detail.RecordsErrored > 0\">\n <td>{{ detail.Entity }}</td>\n <td class=\"num-col\">{{ detail.RecordsProcessed | number }}</td>\n <td class=\"num-col created-col\">{{ detail.RecordsCreated | number }}</td>\n <td class=\"num-col updated-col\">{{ detail.RecordsUpdated | number }}</td>\n <td class=\"num-col\">{{ detail.RecordsDeleted | number }}</td>\n <td class=\"num-col error-col\">{{ detail.RecordsErrored | number }}</td>\n <td class=\"num-col\">{{ detail.RecordsSkipped | number }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n\n <!-- Error log in expanded view -->\n @if (run.ErrorLog) {\n <div class=\"error-log-block\">\n <div class=\"error-log-label\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i> Error Log\n </div>\n <pre class=\"error-log-content\">{{ run.ErrorLog }}</pre>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Right panel: Detail -->\n @if (SelectedRunID && GetSelectedRun()) {\n <div class=\"detail-panel\">\n <div class=\"detail-header\">\n <div class=\"detail-header-info\">\n <h3>{{ GetSelectedRun()!.Integration }}</h3>\n <span [class]=\"StatusChipClass(GetSelectedRun()!.Status)\">\n <i [class]=\"GetStatusIcon(GetSelectedRun()!.Status)\"></i>\n {{ GetSelectedRun()!.Status }}\n </span>\n <span class=\"detail-time\">{{ FormatDate(GetSelectedRun()!.StartedAt) }}</span>\n </div>\n <button class=\"close-detail-btn\" (click)=\"SelectRun(SelectedRunID!)\" title=\"Close\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <!-- Duration bar -->\n @if (GetSelectedRun()!.StartedAt && GetSelectedRun()!.EndedAt) {\n <div class=\"duration-bar-container\">\n <div class=\"duration-bar-track\">\n <div class=\"duration-bar-fill\"\n [style.width.%]=\"GetDurationBarWidth(GetSelectedRun()!)\"></div>\n </div>\n <div class=\"duration-bar-labels\">\n <span>{{ FormatDate(GetSelectedRun()!.StartedAt) }}</span>\n <span class=\"duration-bar-value\">{{ GetDurationBarLabel(GetSelectedRun()!) }}</span>\n <span>{{ FormatDate(GetSelectedRun()!.EndedAt) }}</span>\n </div>\n </div>\n }\n\n <!-- Tabs -->\n <div class=\"detail-tabs\">\n <button class=\"tab-btn\" [class.active]=\"ActiveDetailTab === 'entities'\"\n (click)=\"SetDetailTab('entities')\">\n <i class=\"fa-solid fa-table\"></i> Entity Breakdown\n </button>\n <button class=\"tab-btn\" [class.active]=\"ActiveDetailTab === 'watermarks'\"\n (click)=\"SetDetailTab('watermarks')\">\n <i class=\"fa-solid fa-droplet\"></i> Watermarks\n </button>\n </div>\n\n <div class=\"detail-content\">\n <!-- Entity breakdown tab -->\n @if (ActiveDetailTab === 'entities') {\n @if (IsLoadingDetail) {\n <div class=\"detail-loading\">\n <mj-loading text=\"Loading details...\" size=\"small\"></mj-loading>\n </div>\n } @else if (SelectedRunDetails.length === 0) {\n <div class=\"detail-empty\">\n <i class=\"fa-solid fa-circle-info\"></i>\n <p>No entity detail records for this run.</p>\n </div>\n } @else {\n <table class=\"detail-table\">\n <thead>\n <tr>\n <th>Entity</th>\n <th class=\"num-col\">Processed</th>\n <th class=\"num-col\">Created</th>\n <th class=\"num-col\">Updated</th>\n <th class=\"num-col\">Deleted</th>\n <th class=\"num-col\">Errors</th>\n <th class=\"num-col\">Skipped</th>\n </tr>\n </thead>\n <tbody>\n @for (detail of SelectedRunDetails; track detail.EntityID) {\n <tr [class.error-row]=\"detail.RecordsErrored > 0\">\n <td>{{ detail.Entity }}</td>\n <td class=\"num-col\">{{ detail.RecordsProcessed | number }}</td>\n <td class=\"num-col created-col\">{{ detail.RecordsCreated | number }}</td>\n <td class=\"num-col updated-col\">{{ detail.RecordsUpdated | number }}</td>\n <td class=\"num-col\">{{ detail.RecordsDeleted | number }}</td>\n <td class=\"num-col error-col\">{{ detail.RecordsErrored | number }}</td>\n <td class=\"num-col\">{{ detail.RecordsSkipped | number }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n\n <!-- Error log -->\n @if (GetSelectedRun()?.ErrorLog) {\n <div class=\"error-log-block detail-error-log\">\n <div class=\"error-log-label\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i> Error Log\n </div>\n <pre class=\"error-log-content\">{{ GetSelectedRun()!.ErrorLog }}</pre>\n </div>\n }\n }\n\n <!-- Watermarks tab -->\n @if (ActiveDetailTab === 'watermarks') {\n @if (IsLoadingWatermarks) {\n <div class=\"detail-loading\">\n <mj-loading text=\"Loading watermarks...\" size=\"small\"></mj-loading>\n </div>\n } @else if (WatermarkData.length === 0) {\n <div class=\"detail-empty\">\n <i class=\"fa-solid fa-droplet-slash\"></i>\n <p>No watermarks recorded for this integration.</p>\n </div>\n } @else {\n <table class=\"detail-table\">\n <thead>\n <tr>\n <th>Entity Map</th>\n <th>Type</th>\n <th>Current Value</th>\n <th>Last Applied</th>\n </tr>\n </thead>\n <tbody>\n @for (wm of WatermarkData; track wm.ID) {\n <tr>\n <td>{{ wm.EntityMap }}</td>\n <td><span class=\"type-badge\">{{ wm.WatermarkType }}</span></td>\n <td class=\"mono-cell watermark-value\">{{ FormatWatermark(wm.WatermarkValue) }}</td>\n <td>{{ FormatDate(wm.LastAppliedAt) }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n }\n </div>\n </div>\n }\n\n </div>\n }\n\n</div>\n", styles: [":host {\n display: block;\n height: 100%;\n}\n\n.activity-container {\n padding: 20px;\n height: 100%;\n display: flex;\n flex-direction: column;\n gap: 14px;\n overflow: auto;\n}\n\n/* \u2500\u2500 Filter Bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.filter-bar {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.filter-group {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.filter-pills {\n gap: 0;\n}\n\n.pill-btn {\n height: 32px;\n padding: 0 14px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-muted);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s, color 0.15s, border-color 0.15s;\n white-space: nowrap;\n}\n\n.pill-btn:first-child {\n border-radius: 9999px 0 0 9999px;\n}\n\n.pill-btn:last-child {\n border-radius: 0 9999px 9999px 0;\n}\n\n.pill-btn:not(:first-child) {\n margin-left: -1px;\n}\n\n.pill-btn:hover {\n background: var(--mj-status-info-bg);\n border-color: var(--mj-border-strong);\n z-index: 1;\n}\n\n.pill-btn.active {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n z-index: 2;\n}\n\n.filter-select {\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n cursor: pointer;\n min-width: 180px;\n height: 32px;\n}\n\n.filter-select:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n.search-input {\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n min-width: 180px;\n height: 32px;\n}\n\n.search-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.search-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n.refresh-btn {\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n transition: background 0.15s, color 0.15s;\n}\n\n.refresh-btn:hover {\n background: var(--mj-status-info-bg);\n color: var(--mj-brand-primary);\n}\n\n/* \u2500\u2500 Summary Strip \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.summary-strip {\n display: inline-flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.summary-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--mj-text-muted);\n}\n\n.badge-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.dot-blue { background: var(--mj-color-info-500); }\n.dot-green { background: var(--mj-color-success-600); }\n.dot-red { background: var(--mj-status-error); }\n.dot-amber { background: var(--mj-status-warning); }\n.dot-gray { background: var(--mj-text-disabled); }\n\n.badge-count {\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.count-green { color: var(--mj-color-success-600); }\n.count-red { color: var(--mj-color-error-600); }\n\n.badge-label {\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n/* \u2500\u2500 Loading / Empty \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.loading-area {\n display: flex;\n justify-content: center;\n padding: 48px;\n}\n\n.empty-state {\n text-align: center;\n padding: 48px;\n color: var(--mj-text-disabled);\n}\n\n.empty-state i {\n font-size: 32px;\n margin-bottom: 12px;\n display: block;\n}\n\n.empty-state p {\n margin: 0;\n font-size: 14px;\n}\n\n/* \u2500\u2500 Split View \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.split-view {\n display: flex;\n gap: 16px;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n/* \u2500\u2500 Run List Panel (left 70%) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.run-list-panel {\n flex: 7;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n}\n\n.run-row {\n border-bottom: 1px solid var(--mj-border-subtle);\n cursor: pointer;\n transition: background 0.1s;\n}\n\n.run-row:hover {\n background: var(--mj-bg-page);\n}\n\n.run-row.selected {\n background: var(--mj-status-info-bg);\n}\n\n.run-row-main {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n}\n\n/* Status indicator */\n.status-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.status-icon {\n font-size: 14px;\n width: 16px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.icon-green { color: var(--mj-color-success-600); }\n.icon-red { color: var(--mj-status-error); }\n.icon-amber { color: var(--mj-status-warning); }\n.icon-gray { color: var(--mj-text-disabled); }\n\n/* Run info */\n.run-info {\n flex: 2;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 1px;\n}\n\n.run-integration {\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.run-company {\n font-size: 11px;\n color: var(--mj-text-disabled);\n}\n\n/* Meta columns */\n.run-meta {\n flex-shrink: 0;\n font-size: 12px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n min-width: 60px;\n text-align: right;\n}\n\n.run-duration {\n font-variant-numeric: tabular-nums;\n min-width: 56px;\n}\n\n.run-records {\n font-variant-numeric: tabular-nums;\n min-width: 48px;\n}\n\n.run-errors {\n min-width: 24px;\n text-align: center;\n}\n\n.run-errors.has-errors {\n color: var(--mj-status-error);\n}\n\n.run-user {\n min-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.expand-btn {\n background: none;\n border: none;\n cursor: pointer;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-disabled);\n font-size: 11px;\n transition: background 0.15s, transform 0.2s;\n flex-shrink: 0;\n}\n\n.expand-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-secondary);\n}\n\n.expand-btn i.rotated {\n transform: rotate(180deg);\n}\n\n/* \u2500\u2500 Expanded Section \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.expanded-section {\n padding: 8px 14px 14px 48px;\n background: var(--mj-bg-page);\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.expanded-loading,\n.expanded-empty {\n padding: 16px;\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.expanded-empty i {\n margin-right: 6px;\n}\n\n.entity-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 12px;\n}\n\n.entity-table th {\n text-align: left;\n padding: 6px 8px;\n color: var(--mj-text-disabled);\n font-weight: 600;\n font-size: 11px;\n border-bottom: 1px solid var(--mj-border-default);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.entity-table td {\n padding: 5px 8px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.entity-table .num-col,\n.detail-table .num-col {\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n\n.entity-table .created-col,\n.detail-table .created-col {\n color: var(--mj-color-success-600);\n font-weight: 600;\n}\n\n.entity-table .updated-col,\n.detail-table .updated-col {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.entity-table .error-col,\n.detail-table .error-col {\n color: var(--mj-color-error-600);\n font-weight: 600;\n}\n\n.error-row {\n background: var(--mj-status-error-bg);\n}\n\n/* \u2500\u2500 Error Log Block \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.error-log-block {\n margin-top: 10px;\n}\n\n.error-log-label {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-color-error-600);\n margin-bottom: 6px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.error-log-content {\n margin: 0;\n padding: 10px 12px;\n background: var(--mj-text-primary);\n color: #f1f5f9;\n font-family: 'SF Mono', 'Menlo', 'Consolas', monospace;\n font-size: 11px;\n border-radius: 8px;\n white-space: pre-wrap;\n word-break: break-word;\n max-height: 200px;\n overflow-y: auto;\n line-height: 1.5;\n}\n\n.detail-error-log {\n padding: 12px 16px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n/* \u2500\u2500 Detail Panel (right 30%) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.detail-panel {\n flex: 3;\n min-width: 340px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.detail-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n padding: 14px 16px;\n border-bottom: 1px solid var(--mj-border-subtle);\n gap: 12px;\n}\n\n.detail-header-info {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n}\n\n.detail-header-info h3 {\n margin: 0;\n font-size: 15px;\n font-weight: 700;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.detail-time {\n font-size: 12px;\n color: var(--mj-text-disabled);\n}\n\n.close-detail-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n font-size: 16px;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.close-detail-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-secondary);\n}\n\n/* Duration bar */\n.duration-bar-container {\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.duration-bar-track {\n height: 6px;\n background: var(--mj-bg-surface-active);\n border-radius: 3px;\n overflow: hidden;\n}\n\n.duration-bar-fill {\n height: 100%;\n background: linear-gradient(90deg, var(--mj-brand-primary), var(--mj-color-accent-400));\n border-radius: 3px;\n transition: width 0.3s;\n}\n\n.duration-bar-labels {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-top: 4px;\n font-size: 10px;\n color: var(--mj-text-disabled);\n}\n\n.duration-bar-value {\n font-weight: 700;\n color: var(--mj-color-info-500);\n font-size: 12px;\n}\n\n/* Tabs */\n.detail-tabs {\n display: flex;\n border-bottom: 1px solid var(--mj-border-subtle);\n padding: 0 16px;\n gap: 2px;\n}\n\n.tab-btn {\n background: none;\n border: none;\n border-bottom: 2px solid transparent;\n cursor: pointer;\n padding: 10px 12px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n display: flex;\n align-items: center;\n gap: 5px;\n transition: color 0.15s, border-color 0.15s;\n}\n\n.tab-btn:hover {\n color: var(--mj-brand-primary);\n}\n\n.tab-btn.active {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n/* Detail content area */\n.detail-content {\n flex: 1;\n overflow-y: auto;\n}\n\n.detail-loading,\n.detail-empty {\n padding: 24px;\n text-align: center;\n color: var(--mj-text-disabled);\n}\n\n.detail-empty i {\n font-size: 24px;\n margin-bottom: 8px;\n display: block;\n}\n\n.detail-empty p {\n margin: 0;\n font-size: 13px;\n}\n\n.detail-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 12px;\n}\n\n.detail-table th {\n text-align: left;\n padding: 8px 10px;\n color: var(--mj-text-disabled);\n font-weight: 600;\n border-bottom: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-page);\n font-size: 11px;\n}\n\n.detail-table td {\n padding: 7px 10px;\n border-bottom: 1px solid var(--mj-bg-page);\n}\n\n.mono-cell {\n font-variant-numeric: tabular-nums;\n color: var(--mj-text-muted);\n}\n\n.watermark-value {\n font-family: 'SF Mono', 'Menlo', 'Consolas', monospace;\n font-size: 11px;\n}\n\n/* Status chips */\n.chip {\n font-size: 11px;\n font-weight: 600;\n padding: 3px 8px;\n border-radius: 10px;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n white-space: nowrap;\n}\n\n.chip-green { background: var(--mj-color-success-100); color: var(--mj-color-success-600); }\n.chip-red { background: var(--mj-color-error-100); color: var(--mj-color-error-600); }\n.chip-amber { background: var(--mj-color-warning-100); color: var(--mj-color-warning-600); }\n.chip-gray { background: var(--mj-bg-surface-hover); color: var(--mj-text-muted); }\n\n/* Watermark type badge */\n.type-badge {\n display: inline-flex;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n background: var(--mj-status-info-bg);\n color: var(--mj-brand-primary);\n}\n\n/* \u2500\u2500 Responsive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n@media (max-width: 900px) {\n .split-view {\n flex-direction: column;\n }\n\n .detail-panel {\n min-width: 0;\n max-height: 50vh;\n }\n\n .run-user {\n display: none;\n }\n}\n"] }]
|
|
954
|
+
args: [{ standalone: false, selector: 'app-integration-activity', template: "<div class=\"activity-container\">\n\n <!-- Filter Bar -->\n <div class=\"filter-bar\">\n <div class=\"filter-group filter-pills\">\n @for (status of StatusOptions; track status) {\n <button class=\"pill-btn\"\n [class.active]=\"StatusFilter === status\"\n (click)=\"SetStatusFilter(status)\">\n {{ status }}\n </button>\n }\n </div>\n\n <div class=\"filter-group\">\n <select class=\"filter-select\"\n [ngModel]=\"IntegrationFilter ?? ''\"\n (ngModelChange)=\"SetIntegrationFilter($event || null)\">\n <option value=\"\">All Integrations</option>\n @for (opt of Integrations; track opt.ID) {\n <option [value]=\"opt.ID\">{{ opt.Name }}</option>\n }\n </select>\n </div>\n\n <div class=\"filter-group filter-pills\">\n @for (d of DateOptions; track d.Value) {\n <button class=\"pill-btn\"\n [class.active]=\"DateFilter === d.Value\"\n (click)=\"SetDateFilter(d.Value)\">\n {{ d.Label }}\n </button>\n }\n </div>\n\n <div class=\"filter-group\">\n <input type=\"text\"\n class=\"search-input\"\n placeholder=\"Search integrations...\"\n [(ngModel)]=\"SearchQuery\"\n (input)=\"OnSearchChange()\" />\n </div>\n\n <button class=\"refresh-btn\" (click)=\"Refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-arrows-rotate\"></i>\n </button>\n </div>\n\n <!-- Summary Strip -->\n @if (!IsLoading && AllRuns.length > 0) {\n <div class=\"summary-strip\">\n <div class=\"summary-badge\">\n <span class=\"badge-dot dot-blue\"></span>\n <span class=\"badge-count\">{{ TotalRuns }}</span>\n <span class=\"badge-label\">Total Runs</span>\n </div>\n <div class=\"summary-badge\">\n <span class=\"badge-dot dot-green\"></span>\n <span class=\"badge-count count-green\">{{ SuccessfulRuns }}</span>\n <span class=\"badge-label\">Successful</span>\n </div>\n <div class=\"summary-badge\">\n <span class=\"badge-dot dot-red\"></span>\n <span class=\"badge-count count-red\">{{ FailedRuns }}</span>\n <span class=\"badge-label\">Failed</span>\n </div>\n <div class=\"summary-badge\">\n <span class=\"badge-dot dot-blue\"></span>\n <span class=\"badge-count\">{{ TotalRecordsProcessed | number }}</span>\n <span class=\"badge-label\">Records Processed</span>\n </div>\n </div>\n }\n\n <!-- Loading state -->\n @if (IsLoading) {\n <div class=\"loading-area\">\n <mj-loading text=\"Loading activity...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Empty state -->\n @if (!IsLoading && FilteredRuns.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-inbox\"></i>\n <p>No runs found for the selected filters.</p>\n </div>\n }\n\n <!-- Split View: Run List + Detail Panel -->\n @if (!IsLoading && FilteredRuns.length > 0) {\n <div class=\"split-view\">\n\n <!-- Left panel: Run list -->\n <div class=\"run-list-panel\">\n @for (run of FilteredRuns; track run.ID) {\n <!-- Run row -->\n <div class=\"run-row\"\n [class.selected]=\"IsSelectedRun(run.ID)\"\n (click)=\"SelectRun(run.ID)\">\n <div class=\"run-row-main\">\n <!-- Status indicator -->\n <span [class]=\"GetStatusDotClass(run.Status)\"></span>\n <i [class]=\"GetStatusIcon(run.Status)\"\n [class.icon-green]=\"run.Status === 'Success'\"\n [class.icon-red]=\"run.Status === 'Failed'\"\n [class.icon-amber]=\"run.Status === 'In Progress'\"\n [class.icon-gray]=\"run.Status === 'Pending'\"\n class=\"status-icon\"></i>\n\n <!-- Integration info -->\n <div class=\"run-info\">\n <span class=\"run-integration\">{{ run.Integration }}</span>\n <span class=\"run-company\">{{ run.Company }}</span>\n </div>\n\n <!-- Started time -->\n <div class=\"run-meta\" [title]=\"FormatAbsoluteDate(run.StartedAt)\">\n {{ GetRelativeTime(run.StartedAt) }}\n </div>\n\n <!-- Duration -->\n <div class=\"run-meta run-duration\">\n {{ FormatDuration(run.StartedAt, run.EndedAt) }}\n </div>\n\n <!-- Records -->\n <div class=\"run-meta run-records\">\n {{ run.TotalRecords | number }}\n </div>\n\n <!-- Errors -->\n <div class=\"run-meta run-errors\" [class.has-errors]=\"run.ErrorLog\">\n @if (run.ErrorLog) {\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n }\n </div>\n\n <!-- Triggered by -->\n <div class=\"run-meta run-user\">\n {{ run.RunByUser || 'Scheduled' }}\n </div>\n\n <!-- Expand chevron -->\n <button class=\"expand-btn\"\n (click)=\"ToggleExpand(run.ID); $event.stopPropagation()\"\n title=\"Show entity breakdown\">\n <i class=\"fa-solid fa-chevron-down\"\n [class.rotated]=\"IsExpanded(run.ID)\"></i>\n </button>\n </div>\n\n <!-- Expanded section: entity breakdown -->\n @if (IsExpanded(run.ID)) {\n <div class=\"expanded-section\" (click)=\"$event.stopPropagation()\">\n @if (IsLoadingExpandedDetails()) {\n <div class=\"expanded-loading\">\n <mj-loading text=\"Loading breakdown...\" size=\"small\"></mj-loading>\n </div>\n } @else if (GetExpandedDetails().length === 0) {\n <div class=\"expanded-empty\">\n <i class=\"fa-solid fa-circle-info\"></i>\n No entity details for this run.\n </div>\n } @else {\n <table class=\"entity-table\">\n <thead>\n <tr>\n <th>Entity</th>\n <th class=\"num-col\">Processed</th>\n <th class=\"num-col\">Created</th>\n <th class=\"num-col\">Updated</th>\n <th class=\"num-col\">Deleted</th>\n <th class=\"num-col\">Errored</th>\n <th class=\"num-col\">Skipped</th>\n </tr>\n </thead>\n <tbody>\n @for (detail of GetExpandedDetails(); track detail.EntityID) {\n <tr [class.error-row]=\"detail.RecordsErrored > 0\">\n <td>{{ detail.Entity }}</td>\n <td class=\"num-col\">{{ detail.RecordsProcessed | number }}</td>\n <td class=\"num-col created-col\">{{ detail.RecordsCreated | number }}</td>\n <td class=\"num-col updated-col\">{{ detail.RecordsUpdated | number }}</td>\n <td class=\"num-col\">{{ detail.RecordsDeleted | number }}</td>\n <td class=\"num-col error-col\">{{ detail.RecordsErrored | number }}</td>\n <td class=\"num-col\">{{ detail.RecordsSkipped | number }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n\n <!-- Error log in expanded view -->\n @if (run.ErrorLog) {\n <div class=\"error-log-block\">\n <div class=\"error-log-label\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i> Error Log\n </div>\n <pre class=\"error-log-content\">{{ run.ErrorLog }}</pre>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Right panel: Detail -->\n @if (SelectedRunID && GetSelectedRun()) {\n <div class=\"detail-panel\">\n <div class=\"detail-header\">\n <div class=\"detail-header-info\">\n <h3>{{ GetSelectedRun()!.Integration }}</h3>\n <span [class]=\"StatusChipClass(GetSelectedRun()!.Status)\">\n <i [class]=\"GetStatusIcon(GetSelectedRun()!.Status)\"></i>\n {{ GetSelectedRun()!.Status }}\n </span>\n <span class=\"detail-time\">{{ FormatDate(GetSelectedRun()!.StartedAt) }}</span>\n </div>\n <button class=\"close-detail-btn\" (click)=\"SelectRun(SelectedRunID!)\" title=\"Close\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <!-- Duration bar -->\n @if (GetSelectedRun()!.StartedAt && GetSelectedRun()!.EndedAt) {\n <div class=\"duration-bar-container\">\n <div class=\"duration-bar-track\">\n <div class=\"duration-bar-fill\"\n [style.width.%]=\"GetDurationBarWidth(GetSelectedRun()!)\"></div>\n </div>\n <div class=\"duration-bar-labels\">\n <span>{{ FormatDate(GetSelectedRun()!.StartedAt) }}</span>\n <span class=\"duration-bar-value\">{{ GetDurationBarLabel(GetSelectedRun()!) }}</span>\n <span>{{ FormatDate(GetSelectedRun()!.EndedAt) }}</span>\n </div>\n </div>\n }\n\n <!-- Tabs -->\n <div class=\"detail-tabs\">\n <button class=\"tab-btn\" [class.active]=\"ActiveDetailTab === 'entities'\"\n (click)=\"SetDetailTab('entities')\">\n <i class=\"fa-solid fa-table\"></i> Entity Breakdown\n </button>\n <button class=\"tab-btn\" [class.active]=\"ActiveDetailTab === 'watermarks'\"\n (click)=\"SetDetailTab('watermarks')\">\n <i class=\"fa-solid fa-droplet\"></i> Watermarks\n </button>\n </div>\n\n <div class=\"detail-content\">\n <!-- Entity breakdown tab -->\n @if (ActiveDetailTab === 'entities') {\n @if (IsLoadingDetail) {\n <div class=\"detail-loading\">\n <mj-loading text=\"Loading details...\" size=\"small\"></mj-loading>\n </div>\n } @else if (SelectedRunDetails.length === 0) {\n <div class=\"detail-empty\">\n <i class=\"fa-solid fa-circle-info\"></i>\n <p>No entity detail records for this run.</p>\n </div>\n } @else {\n <table class=\"detail-table\">\n <thead>\n <tr>\n <th>Entity</th>\n <th class=\"num-col\">Processed</th>\n <th class=\"num-col\">Created</th>\n <th class=\"num-col\">Updated</th>\n <th class=\"num-col\">Deleted</th>\n <th class=\"num-col\">Errors</th>\n <th class=\"num-col\">Skipped</th>\n </tr>\n </thead>\n <tbody>\n @for (detail of SelectedRunDetails; track detail.EntityID) {\n <tr [class.error-row]=\"detail.RecordsErrored > 0\">\n <td>{{ detail.Entity }}</td>\n <td class=\"num-col\">{{ detail.RecordsProcessed | number }}</td>\n <td class=\"num-col created-col\">{{ detail.RecordsCreated | number }}</td>\n <td class=\"num-col updated-col\">{{ detail.RecordsUpdated | number }}</td>\n <td class=\"num-col\">{{ detail.RecordsDeleted | number }}</td>\n <td class=\"num-col error-col\">{{ detail.RecordsErrored | number }}</td>\n <td class=\"num-col\">{{ detail.RecordsSkipped | number }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n\n <!-- Error log -->\n @if (GetSelectedRun()?.ErrorLog) {\n <div class=\"error-log-block detail-error-log\">\n <div class=\"error-log-label\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i> Error Log\n </div>\n <pre class=\"error-log-content\">{{ GetSelectedRun()!.ErrorLog }}</pre>\n </div>\n }\n }\n\n <!-- Watermarks tab -->\n @if (ActiveDetailTab === 'watermarks') {\n @if (IsLoadingWatermarks) {\n <div class=\"detail-loading\">\n <mj-loading text=\"Loading watermarks...\" size=\"small\"></mj-loading>\n </div>\n } @else if (WatermarkData.length === 0) {\n <div class=\"detail-empty\">\n <i class=\"fa-solid fa-droplet-slash\"></i>\n <p>No watermarks recorded for this integration.</p>\n </div>\n } @else {\n <table class=\"detail-table\">\n <thead>\n <tr>\n <th>Entity Map</th>\n <th>Type</th>\n <th>Current Value</th>\n <th>Last Applied</th>\n </tr>\n </thead>\n <tbody>\n @for (wm of WatermarkData; track wm.ID) {\n <tr>\n <td>{{ wm.EntityMap }}</td>\n <td><span class=\"type-badge\">{{ wm.WatermarkType }}</span></td>\n <td class=\"mono-cell watermark-value\">{{ FormatWatermark(wm.WatermarkValue) }}</td>\n <td>{{ FormatDate(wm.LastSyncAt) }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n }\n </div>\n </div>\n }\n\n </div>\n }\n\n</div>\n", styles: [":host {\n display: block;\n height: 100%;\n}\n\n.activity-container {\n padding: 20px;\n height: 100%;\n display: flex;\n flex-direction: column;\n gap: 14px;\n overflow: auto;\n}\n\n/* \u2500\u2500 Filter Bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.filter-bar {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.filter-group {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.filter-pills {\n gap: 0;\n}\n\n.pill-btn {\n height: 32px;\n padding: 0 14px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-muted);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s, color 0.15s, border-color 0.15s;\n white-space: nowrap;\n}\n\n.pill-btn:first-child {\n border-radius: 9999px 0 0 9999px;\n}\n\n.pill-btn:last-child {\n border-radius: 0 9999px 9999px 0;\n}\n\n.pill-btn:not(:first-child) {\n margin-left: -1px;\n}\n\n.pill-btn:hover {\n background: var(--mj-status-info-bg);\n border-color: var(--mj-border-strong);\n z-index: 1;\n}\n\n.pill-btn.active {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n z-index: 2;\n}\n\n.filter-select {\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n cursor: pointer;\n min-width: 180px;\n height: 32px;\n}\n\n.filter-select:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n.search-input {\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n min-width: 180px;\n height: 32px;\n}\n\n.search-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.search-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n.refresh-btn {\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n transition: background 0.15s, color 0.15s;\n}\n\n.refresh-btn:hover {\n background: var(--mj-status-info-bg);\n color: var(--mj-brand-primary);\n}\n\n/* \u2500\u2500 Summary Strip \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.summary-strip {\n display: inline-flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.summary-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--mj-text-muted);\n}\n\n.badge-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.dot-blue { background: var(--mj-brand-primary); }\n.dot-green { background: var(--mj-color-success-600); }\n.dot-red { background: var(--mj-status-error); }\n.dot-amber { background: var(--mj-status-warning); }\n.dot-gray { background: var(--mj-text-disabled); }\n\n.badge-count {\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.count-green { color: var(--mj-color-success-600); }\n.count-red { color: var(--mj-color-error-600); }\n\n.badge-label {\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n/* \u2500\u2500 Loading / Empty \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.loading-area {\n display: flex;\n justify-content: center;\n padding: 48px;\n}\n\n.empty-state {\n text-align: center;\n padding: 48px;\n color: var(--mj-text-disabled);\n}\n\n.empty-state i {\n font-size: 32px;\n margin-bottom: 12px;\n display: block;\n}\n\n.empty-state p {\n margin: 0;\n font-size: 14px;\n}\n\n/* \u2500\u2500 Split View \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.split-view {\n display: flex;\n gap: 16px;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n/* \u2500\u2500 Run List Panel (left 70%) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.run-list-panel {\n flex: 7;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n}\n\n.run-row {\n border-bottom: 1px solid var(--mj-border-subtle);\n cursor: pointer;\n transition: background 0.1s;\n}\n\n.run-row:hover {\n background: var(--mj-bg-page);\n}\n\n.run-row.selected {\n background: var(--mj-status-info-bg);\n}\n\n.run-row-main {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n}\n\n/* Status indicator */\n.status-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.status-icon {\n font-size: 14px;\n width: 16px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.icon-green { color: var(--mj-color-success-600); }\n.icon-red { color: var(--mj-status-error); }\n.icon-amber { color: var(--mj-status-warning); }\n.icon-gray { color: var(--mj-text-disabled); }\n\n/* Run info */\n.run-info {\n flex: 2;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 1px;\n}\n\n.run-integration {\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.run-company {\n font-size: 11px;\n color: var(--mj-text-disabled);\n}\n\n/* Meta columns */\n.run-meta {\n flex-shrink: 0;\n font-size: 12px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n min-width: 60px;\n text-align: right;\n}\n\n.run-duration {\n font-variant-numeric: tabular-nums;\n min-width: 56px;\n}\n\n.run-records {\n font-variant-numeric: tabular-nums;\n min-width: 48px;\n}\n\n.run-errors {\n min-width: 24px;\n text-align: center;\n}\n\n.run-errors.has-errors {\n color: var(--mj-status-error);\n}\n\n.run-user {\n min-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.expand-btn {\n background: none;\n border: none;\n cursor: pointer;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-disabled);\n font-size: 11px;\n transition: background 0.15s, transform 0.2s;\n flex-shrink: 0;\n}\n\n.expand-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-secondary);\n}\n\n.expand-btn i.rotated {\n transform: rotate(180deg);\n}\n\n/* \u2500\u2500 Expanded Section \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.expanded-section {\n padding: 8px 14px 14px 48px;\n background: var(--mj-bg-page);\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.expanded-loading,\n.expanded-empty {\n padding: 16px;\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.expanded-empty i {\n margin-right: 6px;\n}\n\n.entity-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 12px;\n}\n\n.entity-table th {\n text-align: left;\n padding: 6px 8px;\n color: var(--mj-text-disabled);\n font-weight: 600;\n font-size: 11px;\n border-bottom: 1px solid var(--mj-border-default);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.entity-table td {\n padding: 5px 8px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.entity-table .num-col,\n.detail-table .num-col {\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n\n.entity-table .created-col,\n.detail-table .created-col {\n color: var(--mj-color-success-600);\n font-weight: 600;\n}\n\n.entity-table .updated-col,\n.detail-table .updated-col {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.entity-table .error-col,\n.detail-table .error-col {\n color: var(--mj-color-error-600);\n font-weight: 600;\n}\n\n.error-row {\n background: var(--mj-status-error-bg);\n}\n\n/* \u2500\u2500 Error Log Block \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.error-log-block {\n margin-top: 10px;\n}\n\n.error-log-label {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-color-error-600);\n margin-bottom: 6px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.error-log-content {\n margin: 0;\n padding: 10px 12px;\n background: var(--mj-text-primary);\n color: var(--mj-bg-surface-sunken);\n font-family: 'SF Mono', 'Menlo', 'Consolas', monospace;\n font-size: 11px;\n border-radius: 8px;\n white-space: pre-wrap;\n word-break: break-word;\n max-height: 200px;\n overflow-y: auto;\n line-height: 1.5;\n}\n\n.detail-error-log {\n padding: 12px 16px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n/* \u2500\u2500 Detail Panel (right 30%) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.detail-panel {\n flex: 3;\n min-width: 340px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.detail-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n padding: 14px 16px;\n border-bottom: 1px solid var(--mj-border-subtle);\n gap: 12px;\n}\n\n.detail-header-info {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n}\n\n.detail-header-info h3 {\n margin: 0;\n font-size: 15px;\n font-weight: 700;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.detail-time {\n font-size: 12px;\n color: var(--mj-text-disabled);\n}\n\n.close-detail-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n font-size: 16px;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.close-detail-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-secondary);\n}\n\n/* Duration bar */\n.duration-bar-container {\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.duration-bar-track {\n height: 6px;\n background: var(--mj-bg-surface-active);\n border-radius: 3px;\n overflow: hidden;\n}\n\n.duration-bar-fill {\n height: 100%;\n background: linear-gradient(90deg, var(--mj-brand-primary), var(--mj-color-accent-400));\n border-radius: 3px;\n transition: width 0.3s;\n}\n\n.duration-bar-labels {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-top: 4px;\n font-size: 10px;\n color: var(--mj-text-disabled);\n}\n\n.duration-bar-value {\n font-weight: 700;\n color: var(--mj-brand-primary);\n font-size: 12px;\n}\n\n/* Tabs */\n.detail-tabs {\n display: flex;\n border-bottom: 1px solid var(--mj-border-subtle);\n padding: 0 16px;\n gap: 2px;\n}\n\n.tab-btn {\n background: none;\n border: none;\n border-bottom: 2px solid transparent;\n cursor: pointer;\n padding: 10px 12px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n display: flex;\n align-items: center;\n gap: 5px;\n transition: color 0.15s, border-color 0.15s;\n}\n\n.tab-btn:hover {\n color: var(--mj-brand-primary);\n}\n\n.tab-btn.active {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n/* Detail content area */\n.detail-content {\n flex: 1;\n overflow-y: auto;\n}\n\n.detail-loading,\n.detail-empty {\n padding: 24px;\n text-align: center;\n color: var(--mj-text-disabled);\n}\n\n.detail-empty i {\n font-size: 24px;\n margin-bottom: 8px;\n display: block;\n}\n\n.detail-empty p {\n margin: 0;\n font-size: 13px;\n}\n\n.detail-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 12px;\n}\n\n.detail-table th {\n text-align: left;\n padding: 8px 10px;\n color: var(--mj-text-disabled);\n font-weight: 600;\n border-bottom: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-page);\n font-size: 11px;\n}\n\n.detail-table td {\n padding: 7px 10px;\n border-bottom: 1px solid var(--mj-bg-page);\n}\n\n.mono-cell {\n font-variant-numeric: tabular-nums;\n color: var(--mj-text-muted);\n}\n\n.watermark-value {\n font-family: 'SF Mono', 'Menlo', 'Consolas', monospace;\n font-size: 11px;\n}\n\n/* Status chips */\n.chip {\n font-size: 11px;\n font-weight: 600;\n padding: 3px 8px;\n border-radius: 10px;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n white-space: nowrap;\n}\n\n.chip-green { background: var(--mj-color-success-100); color: var(--mj-color-success-600); }\n.chip-red { background: var(--mj-color-error-100); color: var(--mj-color-error-600); }\n.chip-amber { background: var(--mj-color-warning-100); color: var(--mj-color-warning-600); }\n.chip-gray { background: var(--mj-bg-surface-hover); color: var(--mj-text-muted); }\n\n/* Watermark type badge */\n.type-badge {\n display: inline-flex;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n background: var(--mj-status-info-bg);\n color: var(--mj-brand-primary);\n}\n\n/* \u2500\u2500 Responsive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n@media (max-width: 900px) {\n .split-view {\n flex-direction: column;\n }\n\n .detail-panel {\n min-width: 0;\n max-height: 50vh;\n }\n\n .run-user {\n display: none;\n }\n}\n"] }]
|
|
955
955
|
}], null, null); })();
|
|
956
956
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ActivityComponent, { className: "ActivityComponent", filePath: "src/Integration/components/activity/activity.component.ts", lineNumber: 38 }); })();
|
|
957
957
|
export function LoadActivityComponent() {
|