@memberjunction/ng-dashboards 4.0.0 → 4.2.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/README.md +102 -339
- package/dist/AI/components/agents/agent-configuration.component.js +1 -1
- package/dist/AI/components/agents/agent-editor.component.js +1 -1
- package/dist/AI/components/agents/agent-filter-panel.component.js +1 -1
- package/dist/AI/components/charts/performance-heatmap.component.js +1 -1
- package/dist/AI/components/charts/time-series-chart.component.js +1 -1
- package/dist/AI/components/execution-monitoring.component.js +1 -1
- package/dist/AI/components/models/model-management.component.js +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +1 -1
- package/dist/AI/components/prompts/prompt-filter-panel.component.js +1 -1
- package/dist/AI/components/prompts/prompt-management.component.js +1 -1
- package/dist/AI/components/prompts/prompt-version-control.component.js +1 -1
- package/dist/AI/components/system/system-config-filter-panel.component.js +1 -1
- package/dist/AI/components/system/system-configuration.component.js +1 -1
- package/dist/AI/components/widgets/kpi-card.component.js +1 -1
- package/dist/AI/components/widgets/live-execution-widget.component.js +1 -1
- package/dist/APIKeys/api-applications-panel.component.js +1 -1
- package/dist/APIKeys/api-key-create-dialog.component.js +1 -1
- package/dist/APIKeys/api-key-edit-panel.component.js +1 -1
- package/dist/APIKeys/api-key-list.component.js +1 -1
- package/dist/APIKeys/api-keys-resource.component.js +1 -1
- package/dist/APIKeys/api-scopes-panel.component.js +1 -1
- package/dist/APIKeys/api-usage-panel.component.js +1 -1
- package/dist/Actions/components/actions-list-view.component.js +1 -1
- package/dist/Actions/components/actions-overview.component.js +1 -1
- package/dist/Actions/components/categories-list-view.component.js +1 -1
- package/dist/Actions/components/code-management.component.js +1 -1
- package/dist/Actions/components/entity-integration.component.js +1 -1
- package/dist/Actions/components/execution-monitoring.component.js +1 -1
- package/dist/Actions/components/executions-list-view.component.js +1 -1
- package/dist/Actions/components/explorer/action-breadcrumb.component.js +1 -1
- package/dist/Actions/components/explorer/action-card.component.js +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.js +1 -1
- package/dist/Actions/components/explorer/action-list-item.component.js +1 -1
- package/dist/Actions/components/explorer/action-toolbar.component.js +1 -1
- package/dist/Actions/components/explorer/action-tree-panel.component.js +1 -1
- package/dist/Actions/components/explorer/new-action-panel.component.js +1 -1
- package/dist/Actions/components/explorer/new-category-panel.component.js +1 -1
- package/dist/Actions/components/scheduled-actions.component.js +1 -1
- package/dist/Actions/components/security-permissions.component.js +1 -1
- package/dist/Communication/communication-dashboard.component.js +1 -1
- package/dist/Communication/communication-logs-resource.component.js +1 -1
- package/dist/Communication/communication-monitor-resource.component.js +1 -1
- package/dist/Communication/communication-providers-resource.component.js +1 -1
- package/dist/Communication/communication-runs-resource.component.js +1 -1
- package/dist/Communication/communication-templates-resource.component.js +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +1 -1
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +1 -1
- package/dist/ComponentStudio/components/browser/component-browser.component.js +1 -1
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js +1 -1
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +1 -1
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js +1 -1
- package/dist/ComponentStudio/components/editors/spec-editor.component.js +1 -1
- package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js +1 -1
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js +1 -1
- package/dist/ComponentStudio/components/text-import-dialog.component.js +1 -1
- package/dist/ComponentStudio/components/workspace/component-preview.component.js +1 -1
- package/dist/ComponentStudio/components/workspace/editor-tabs.component.js +1 -1
- package/dist/Credentials/components/credentials-audit-resource.component.js +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.js +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +1 -1
- package/dist/Credentials/components/credentials-overview-resource.component.js +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +1 -1
- package/dist/Credentials/credentials-dashboard.component.js +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +1 -1
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js +1 -1
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +1 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.js +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +2 -0
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +35 -11
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.js +1 -1
- package/dist/EntityAdmin/entity-admin-dashboard.component.js +1 -1
- package/dist/Home/home-application.d.ts +109 -22
- package/dist/Home/home-application.d.ts.map +1 -1
- package/dist/Home/home-application.js +351 -66
- package/dist/Home/home-application.js.map +1 -1
- package/dist/Home/home-dashboard.component.d.ts +48 -8
- package/dist/Home/home-dashboard.component.d.ts.map +1 -1
- package/dist/Home/home-dashboard.component.js +140 -62
- package/dist/Home/home-dashboard.component.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +1 -1
- package/dist/Lists/components/lists-categories-resource.component.js +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +1 -1
- package/dist/Lists/components/lists-operations-resource.component.js +1 -1
- package/dist/Lists/components/venn-diagram/venn-diagram.component.js +1 -1
- package/dist/MCP/components/mcp-connection-dialog.component.js +1 -1
- package/dist/MCP/components/mcp-log-detail-panel.component.js +1 -1
- package/dist/MCP/components/mcp-server-dialog.component.js +1 -1
- package/dist/MCP/components/mcp-test-tool-dialog.component.js +1 -1
- package/dist/MCP/mcp-dashboard.component.js +1 -1
- package/dist/MCP/mcp-filter-panel.component.js +1 -1
- package/dist/MCP/mcp-resource.component.js +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js +1 -1
- package/dist/Scheduling/components/job-slideout.component.js +1 -1
- package/dist/Scheduling/components/scheduling-activity-resource.component.js +1 -1
- package/dist/Scheduling/components/scheduling-activity.component.js +1 -1
- package/dist/Scheduling/components/scheduling-jobs-resource.component.js +1 -1
- package/dist/Scheduling/components/scheduling-jobs.component.js +1 -1
- package/dist/Scheduling/components/scheduling-overview-resource.component.js +1 -1
- package/dist/Scheduling/components/scheduling-overview.component.js +1 -1
- package/dist/Scheduling/scheduling-dashboard.component.js +1 -1
- package/dist/SystemDiagnostics/system-diagnostics.component.js +1 -1
- package/dist/Testing/components/testing-analytics-resource.component.js +1 -1
- package/dist/Testing/components/testing-analytics.component.js +1 -1
- package/dist/Testing/components/testing-dashboard-tab-resource.component.js +1 -1
- package/dist/Testing/components/testing-dashboard-tab.component.js +1 -1
- package/dist/Testing/components/testing-explorer-resource.component.js +1 -1
- package/dist/Testing/components/testing-explorer.component.js +1 -1
- package/dist/Testing/components/testing-review-resource.component.js +1 -1
- package/dist/Testing/components/testing-review.component.js +1 -1
- package/dist/Testing/components/testing-runs-resource.component.js +1 -1
- package/dist/Testing/components/testing-runs.component.js +1 -1
- package/dist/Testing/components/widgets/oracle-breakdown-table.component.js +1 -1
- package/dist/Testing/components/widgets/suite-tree.component.js +2 -2
- package/dist/Testing/components/widgets/test-run-detail-panel.component.js +1 -1
- package/dist/Testing/testing-dashboard.component.js +1 -1
- package/dist/VersionHistory/components/diff-resource.component.js +1 -1
- package/dist/VersionHistory/components/graph-resource.component.js +1 -1
- package/dist/VersionHistory/components/labels-resource.component.js +1 -1
- package/dist/VersionHistory/components/restore-resource.component.js +1 -1
- package/package.json +38 -38
- package/dist/AI/ai-dashboard.component.d.ts +0 -62
- package/dist/AI/ai-dashboard.component.d.ts.map +0 -1
- package/dist/AI/ai-dashboard.component.js +0 -338
- package/dist/AI/ai-dashboard.component.js.map +0 -1
- package/dist/AI/components/models/model-management-v2.component.d.ts +0 -96
- package/dist/AI/components/models/model-management-v2.component.d.ts.map +0 -1
- package/dist/AI/components/models/model-management-v2.component.js +0 -981
- package/dist/AI/components/models/model-management-v2.component.js.map +0 -1
- package/dist/AI/components/prompts/prompt-management-v2.component.d.ts +0 -97
- package/dist/AI/components/prompts/prompt-management-v2.component.d.ts.map +0 -1
- package/dist/AI/components/prompts/prompt-management-v2.component.js +0 -811
- package/dist/AI/components/prompts/prompt-management-v2.component.js.map +0 -1
- package/dist/Actions/actions-management-dashboard.component.d.ts +0 -52
- package/dist/Actions/actions-management-dashboard.component.d.ts.map +0 -1
- package/dist/Actions/actions-management-dashboard.component.js +0 -308
- package/dist/Actions/actions-management-dashboard.component.js.map +0 -1
- package/dist/Credentials/components/credential-category-edit-panel.component.d.ts +0 -44
- package/dist/Credentials/components/credential-category-edit-panel.component.d.ts.map +0 -1
- package/dist/Credentials/components/credential-category-edit-panel.component.js +0 -456
- package/dist/Credentials/components/credential-category-edit-panel.component.js.map +0 -1
- package/dist/Credentials/components/credential-edit-panel.component.d.ts +0 -70
- package/dist/Credentials/components/credential-edit-panel.component.d.ts.map +0 -1
- package/dist/Credentials/components/credential-edit-panel.component.js +0 -694
- package/dist/Credentials/components/credential-edit-panel.component.js.map +0 -1
- package/dist/Credentials/components/credential-type-edit-panel.component.d.ts +0 -56
- package/dist/Credentials/components/credential-type-edit-panel.component.d.ts.map +0 -1
- package/dist/Credentials/components/credential-type-edit-panel.component.js +0 -563
- package/dist/Credentials/components/credential-type-edit-panel.component.js.map +0 -1
- package/dist/DataExplorer/components/view-config-panel/view-config-panel.component.d.ts +0 -245
- package/dist/DataExplorer/components/view-config-panel/view-config-panel.component.d.ts.map +0 -1
- package/dist/DataExplorer/components/view-config-panel/view-config-panel.component.js +0 -1143
- package/dist/DataExplorer/components/view-config-panel/view-config-panel.component.js.map +0 -1
- package/dist/EntityAdmin/components/entity-details.component.d.ts +0 -50
- package/dist/EntityAdmin/components/entity-details.component.d.ts.map +0 -1
- package/dist/EntityAdmin/components/entity-details.component.js +0 -680
- package/dist/EntityAdmin/components/entity-details.component.js.map +0 -1
- package/dist/EntityAdmin/components/entity-filter-panel.component.d.ts +0 -31
- package/dist/EntityAdmin/components/entity-filter-panel.component.d.ts.map +0 -1
- package/dist/EntityAdmin/components/entity-filter-panel.component.js +0 -160
- package/dist/EntityAdmin/components/entity-filter-panel.component.js.map +0 -1
- package/dist/EntityAdmin/components/erd-composite.component.d.ts +0 -73
- package/dist/EntityAdmin/components/erd-composite.component.d.ts.map +0 -1
- package/dist/EntityAdmin/components/erd-composite.component.js +0 -271
- package/dist/EntityAdmin/components/erd-composite.component.js.map +0 -1
- package/dist/EntityAdmin/components/erd-diagram.component.d.ts +0 -47
- package/dist/EntityAdmin/components/erd-diagram.component.d.ts.map +0 -1
- package/dist/EntityAdmin/components/erd-diagram.component.js +0 -618
- package/dist/EntityAdmin/components/erd-diagram.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-health-resource.component.d.ts +0 -20
- package/dist/Scheduling/components/scheduling-health-resource.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-health-resource.component.js +0 -55
- package/dist/Scheduling/components/scheduling-health-resource.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-health.component.d.ts +0 -30
- package/dist/Scheduling/components/scheduling-health.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-health.component.js +0 -315
- package/dist/Scheduling/components/scheduling-health.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-history-resource.component.d.ts +0 -20
- package/dist/Scheduling/components/scheduling-history-resource.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-history-resource.component.js +0 -55
- package/dist/Scheduling/components/scheduling-history-resource.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-history.component.d.ts +0 -48
- package/dist/Scheduling/components/scheduling-history.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-history.component.js +0 -377
- package/dist/Scheduling/components/scheduling-history.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-monitor-resource.component.d.ts +0 -20
- package/dist/Scheduling/components/scheduling-monitor-resource.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-monitor-resource.component.js +0 -55
- package/dist/Scheduling/components/scheduling-monitor-resource.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-monitoring.component.d.ts +0 -37
- package/dist/Scheduling/components/scheduling-monitoring.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-monitoring.component.js +0 -488
- package/dist/Scheduling/components/scheduling-monitoring.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-types-resource.component.d.ts +0 -20
- package/dist/Scheduling/components/scheduling-types-resource.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-types-resource.component.js +0 -55
- package/dist/Scheduling/components/scheduling-types-resource.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-types.component.d.ts +0 -22
- package/dist/Scheduling/components/scheduling-types.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-types.component.js +0 -165
- package/dist/Scheduling/components/scheduling-types.component.js.map +0 -1
- package/dist/Testing/components/testing-execution-resource.component.d.ts +0 -20
- package/dist/Testing/components/testing-execution-resource.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-execution-resource.component.js +0 -55
- package/dist/Testing/components/testing-execution-resource.component.js.map +0 -1
- package/dist/Testing/components/testing-execution.component.d.ts +0 -71
- package/dist/Testing/components/testing-execution.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-execution.component.js +0 -845
- package/dist/Testing/components/testing-execution.component.js.map +0 -1
- package/dist/Testing/components/testing-feedback-resource.component.d.ts +0 -20
- package/dist/Testing/components/testing-feedback-resource.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-feedback-resource.component.js +0 -55
- package/dist/Testing/components/testing-feedback-resource.component.js.map +0 -1
- package/dist/Testing/components/testing-feedback.component.d.ts +0 -111
- package/dist/Testing/components/testing-feedback.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-feedback.component.js +0 -1486
- package/dist/Testing/components/testing-feedback.component.js.map +0 -1
- package/dist/Testing/components/testing-overview-resource.component.d.ts +0 -20
- package/dist/Testing/components/testing-overview-resource.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-overview-resource.component.js +0 -55
- package/dist/Testing/components/testing-overview-resource.component.js.map +0 -1
- package/dist/Testing/components/testing-overview.component.d.ts +0 -30
- package/dist/Testing/components/testing-overview.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-overview.component.js +0 -361
- package/dist/Testing/components/testing-overview.component.js.map +0 -1
- package/dist/Testing/components/testing-version-comparison.component.d.ts +0 -62
- package/dist/Testing/components/testing-version-comparison.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-version-comparison.component.js +0 -815
- package/dist/Testing/components/testing-version-comparison.component.js.map +0 -1
- package/dist/Testing/components/testing-version-resource.component.d.ts +0 -20
- package/dist/Testing/components/testing-version-resource.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-version-resource.component.js +0 -55
- package/dist/Testing/components/testing-version-resource.component.js.map +0 -1
- package/dist/generic/base-dashboard.d.ts +0 -65
- package/dist/generic/base-dashboard.d.ts.map +0 -1
- package/dist/generic/base-dashboard.js +0 -74
- package/dist/generic/base-dashboard.js.map +0 -1
|
@@ -2021,5 +2021,5 @@ export { ExecutionMonitoringComponent };
|
|
|
2021
2021
|
</div>
|
|
2022
2022
|
`, styles: ["\n .execution-monitoring {\n padding: 0;\n background: linear-gradient(135deg, #f5f7fa 0%, #e4e8ed 100%);\n width: 100%;\n height: 100%;\n position: relative;\n overflow: auto;\n display: flex;\n flex-direction: column;\n }\n\n .execution-monitoring.loading {\n overflow: hidden;\n }\n\n /* Loading Overlay */\n .loading-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(255, 255, 255, 0.7);\n z-index: 999;\n display: flex;\n align-items: center;\n justify-content: center;\n backdrop-filter: blur(4px);\n }\n\n /* === Dashboard Header - Clean White Style === */\n .monitoring-header {\n background: white;\n padding: 16px 24px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n border-bottom: 1px solid #e0e6ed;\n position: relative;\n z-index: 10;\n }\n\n .monitoring-title {\n margin: 0;\n font-size: 20px;\n font-weight: 700;\n color: #1e293b;\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .monitoring-title i {\n color: #6366f1;\n font-size: 22px;\n }\n\n .monitoring-controls {\n display: flex;\n gap: 12px;\n align-items: center;\n flex-wrap: wrap;\n }\n\n .time-range-control {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n }\n\n .time-range-control label {\n color: #64748b;\n font-weight: 500;\n }\n\n .time-range-control select {\n padding: 8px 14px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 13px;\n background: #f8fafc;\n color: #1e293b;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .time-range-control select:hover:not(:disabled) {\n background: #f1f5f9;\n border-color: #cbd5e1;\n }\n\n .time-range-control select:focus {\n outline: none;\n border-color: #6366f1;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n }\n\n .time-range-control select:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .time-range-control select option {\n background: white;\n color: #1e293b;\n }\n\n .refresh-btn {\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: 8px;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 8px;\n transition: all 0.2s ease;\n box-shadow: 0 2px 8px rgba(99, 102, 241, 0.25);\n }\n\n .refresh-btn:hover:not(:disabled) {\n background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.35);\n }\n\n .refresh-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n }\n\n .refresh-btn i.spinning {\n animation: spin 1s linear infinite;\n }\n\n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n\n .kpi-dashboard {\n padding: 20px;\n }\n\n .kpi-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n }\n\n .dashboard-splitter {\n flex: 1;\n min-height: 500px;\n margin: 0 20px 20px 20px;\n }\n\n .dashboard-section {\n background: white;\n border-radius: 12px;\n box-shadow: 0 4px 16px rgba(99, 102, 241, 0.08);\n overflow: hidden;\n height: 100%;\n display: flex;\n flex-direction: column;\n border: 1px solid rgba(99, 102, 241, 0.08);\n transition: box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .dashboard-section:hover {\n box-shadow: 0 8px 24px rgba(99, 102, 241, 0.12);\n }\n\n /* Ensure splitter panes take full height */\n :host ::ng-deep .k-splitter-pane {\n overflow: hidden;\n }\n\n :host ::ng-deep .k-splitter .k-splitter-pane {\n padding: 10px;\n }\n\n :host ::ng-deep .k-splitter-horizontal > .k-splitter-pane {\n padding: 10px 5px;\n }\n\n :host ::ng-deep .k-splitter-vertical > .k-splitter-pane {\n padding: 5px 10px;\n }\n\n /* Cost Analysis Styles */\n .cost-chart-container, .efficiency-chart-container, .status-container {\n padding: 20px;\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n\n .chart-header {\n margin-bottom: 16px;\n }\n\n .chart-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #1e293b;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .chart-title i {\n color: #6366f1;\n }\n\n .cost-bars, .efficiency-items {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n\n .cost-bar-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 8px 0;\n border-bottom: 1px solid #f0f0f0;\n }\n\n .cost-bar-item:last-child {\n border-bottom: none;\n }\n\n .cost-bar-info {\n min-width: 120px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n\n .model-name {\n font-size: 12px;\n font-weight: 500;\n color: #333;\n }\n\n .cost-value {\n font-size: 11px;\n color: #8b5cf6;\n font-weight: 600;\n }\n\n .cost-bar-container {\n flex: 1;\n height: 8px;\n background: linear-gradient(90deg, rgba(99, 102, 241, 0.1) 0%, rgba(139, 92, 246, 0.1) 100%);\n border-radius: 4px;\n overflow: hidden;\n }\n\n .cost-bar {\n height: 100%;\n background: linear-gradient(90deg, #6366f1 0%, #8b5cf6 50%, #a78bfa 100%);\n border-radius: 4px;\n transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .token-info {\n font-size: 10px;\n color: #666;\n min-width: 80px;\n text-align: right;\n }\n\n /* Token Efficiency Styles */\n .efficiency-item {\n padding: 12px 0;\n border-bottom: 1px solid #f0f0f0;\n }\n\n .efficiency-item:last-child {\n border-bottom: none;\n }\n\n .efficiency-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n }\n\n .efficiency-ratio {\n font-size: 11px;\n color: #6366f1;\n font-weight: 600;\n }\n\n .token-breakdown {\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n\n .token-bar {\n height: 8px;\n background: rgba(99, 102, 241, 0.1);\n border-radius: 4px;\n overflow: hidden;\n display: flex;\n }\n\n .token-segment {\n height: 100%;\n transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .token-segment--input {\n background: linear-gradient(90deg, #6366f1 0%, #818cf8 100%);\n }\n\n .token-segment--output {\n background: linear-gradient(90deg, #8b5cf6 0%, #a78bfa 100%);\n }\n\n .token-labels {\n display: flex;\n justify-content: space-between;\n font-size: 10px;\n color: #666;\n }\n\n .input-label {\n color: #6366f1;\n font-weight: 500;\n }\n\n .output-label {\n color: #8b5cf6;\n font-weight: 500;\n }\n\n .cost-per-token {\n font-size: 10px;\n color: #999;\n margin-top: 4px;\n }\n\n /* System Status Styles */\n .status-metrics {\n display: flex;\n flex-direction: column;\n gap: 16px;\n flex: 1;\n }\n\n .status-metric {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px;\n background: #f8f9fa;\n border-radius: 6px;\n }\n\n .status-icon {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n }\n\n .status-icon--success {\n background: linear-gradient(135deg, rgba(16, 185, 129, 0.15) 0%, rgba(5, 150, 105, 0.15) 100%);\n color: #10b981;\n }\n\n .status-icon--warning {\n background: linear-gradient(135deg, rgba(245, 158, 11, 0.15) 0%, rgba(217, 119, 6, 0.15) 100%);\n color: #f59e0b;\n }\n\n .status-icon--info {\n background: linear-gradient(135deg, rgba(99, 102, 241, 0.15) 0%, rgba(139, 92, 246, 0.15) 100%);\n color: #6366f1;\n }\n\n .status-icon--primary {\n background: linear-gradient(135deg, rgba(139, 92, 246, 0.15) 0%, rgba(167, 139, 250, 0.15) 100%);\n color: #8b5cf6;\n }\n\n .status-info {\n flex: 1;\n }\n\n .status-label {\n font-size: 12px;\n color: #666;\n font-weight: 500;\n }\n\n .status-value {\n font-size: 18px;\n font-weight: 700;\n color: #333;\n margin: 2px 0;\n }\n\n .status-subtitle {\n font-size: 10px;\n color: #999;\n }\n\n /* Execution Modal Styles */\n .execution-modal {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n padding: 20px;\n }\n\n .execution-modal-content {\n background: white;\n border-radius: 8px;\n max-width: 800px;\n width: 100%;\n max-height: 80vh;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .execution-modal-header {\n padding: 20px;\n border-bottom: 1px solid #f0f0f0;\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n\n .execution-modal-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n color: #333;\n }\n\n .modal-header-actions {\n display: flex;\n gap: 12px;\n align-items: center;\n }\n\n .open-record-btn {\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: 8px;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: 0 2px 8px rgba(99, 102, 241, 0.25);\n }\n\n .open-record-btn:hover {\n background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.35);\n }\n\n .open-record-btn i {\n font-size: 12px;\n }\n\n .close-btn {\n background: none;\n border: none;\n font-size: 16px;\n color: #999;\n cursor: pointer;\n padding: 4px;\n }\n\n .close-btn:hover {\n color: #333;\n }\n\n .execution-modal-body {\n padding: 20px;\n overflow-y: auto;\n flex: 1;\n }\n\n .execution-details {\n display: flex;\n flex-direction: column;\n gap: 20px;\n }\n\n .detail-section h4 {\n margin: 0 0 12px 0;\n font-size: 14px;\n font-weight: 600;\n color: #333;\n border-bottom: 1px solid #f0f0f0;\n padding-bottom: 6px;\n }\n\n .detail-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 12px;\n }\n\n .detail-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n\n .detail-item label {\n font-size: 11px;\n color: #666;\n font-weight: 500;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .detail-item span {\n font-size: 13px;\n color: #333;\n }\n\n .status-badge {\n display: inline-block;\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 10px;\n font-weight: 500;\n text-transform: uppercase;\n }\n\n .status-badge--completed {\n background: linear-gradient(135deg, rgba(16, 185, 129, 0.15) 0%, rgba(5, 150, 105, 0.15) 100%);\n color: #10b981;\n }\n\n .status-badge--running {\n background: linear-gradient(135deg, rgba(99, 102, 241, 0.15) 0%, rgba(139, 92, 246, 0.15) 100%);\n color: #6366f1;\n }\n\n .status-badge--failed {\n background: linear-gradient(135deg, rgba(239, 68, 68, 0.15) 0%, rgba(220, 38, 38, 0.15) 100%);\n color: #ef4444;\n }\n\n .error-message {\n background: #fff3e0;\n border: 1px solid #ffcc02;\n border-radius: 4px;\n padding: 12px;\n font-size: 12px;\n color: #e65100;\n font-family: monospace;\n }\n\n .child-executions {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .child-execution {\n background: #f8f9fa;\n border-radius: 4px;\n padding: 12px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n\n .child-info {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .child-name {\n font-size: 12px;\n font-weight: 500;\n color: #333;\n }\n\n .child-type {\n font-size: 10px;\n background: #e0e0e0;\n padding: 2px 6px;\n border-radius: 3px;\n color: #666;\n }\n\n .child-status {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 3px;\n }\n\n .child-metrics {\n display: flex;\n gap: 12px;\n font-size: 11px;\n color: #666;\n }\n\n .loading-details {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n gap: 12px;\n }\n\n /* Drill-down Tab Styles */\n .drill-down-container {\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n\n .drill-down-tabs {\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n\n .tab-header {\n display: flex;\n border-bottom: 1px solid rgba(99, 102, 241, 0.1);\n background: linear-gradient(180deg, #f8f9ff 0%, #f3f4f6 100%);\n min-height: 44px;\n overflow-x: auto;\n }\n\n .tab-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 18px;\n background: transparent;\n border: none;\n border-bottom: 2px solid transparent;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: #64748b;\n white-space: nowrap;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 120px;\n justify-content: space-between;\n }\n\n .tab-item:hover {\n background: rgba(99, 102, 241, 0.05);\n color: #6366f1;\n }\n\n .tab-item.active {\n background: white;\n color: #6366f1;\n border-bottom-color: #6366f1;\n font-weight: 600;\n }\n\n .tab-title {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .tab-close {\n background: none;\n border: none;\n color: #999;\n cursor: pointer;\n padding: 2px;\n border-radius: 2px;\n font-size: 10px;\n width: 16px;\n height: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n }\n\n .tab-close:hover {\n background: rgba(0, 0, 0, 0.1);\n color: #333;\n }\n\n .tab-content {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .tab-pane {\n height: 100%;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .trends-chart {\n padding: 0;\n }\n\n .trends-chart app-time-series-chart {\n height: 100%;\n display: block;\n overflow: hidden;\n }\n\n /* Ensure chart fits within tab pane */\n .tab-pane.trends-chart {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n /* Drill-down specific styles */\n .executions-drill-down {\n padding: 20px;\n overflow-y: auto;\n }\n\n .drill-down-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n padding-bottom: 12px;\n border-bottom: 1px solid #e0e0e0;\n }\n\n .drill-down-header h4 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .drill-down-meta {\n display: flex;\n gap: 12px;\n align-items: center;\n font-size: 12px;\n }\n\n .timestamp {\n color: #666;\n background: #f0f0f0;\n padding: 4px 8px;\n border-radius: 4px;\n }\n\n .metric-badge {\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n color: white;\n padding: 4px 10px;\n border-radius: 6px;\n font-weight: 600;\n box-shadow: 0 2px 4px rgba(99, 102, 241, 0.25);\n }\n\n .loading-spinner {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n color: #666;\n gap: 12px;\n }\n\n .executions-table {\n display: flex;\n flex-direction: column;\n gap: 0;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n overflow: hidden;\n }\n\n .table-header {\n display: grid;\n grid-template-columns: 80px 1fr 120px 100px 100px 80px 100px 120px;\n gap: 12px;\n background: #f8f9fa;\n padding: 12px 16px;\n font-size: 11px;\n font-weight: 600;\n color: #666;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .table-row {\n display: grid;\n grid-template-columns: 80px 1fr 120px 100px 100px 80px 100px 120px;\n gap: 12px;\n padding: 12px 16px;\n border-top: 1px solid #f0f0f0;\n cursor: pointer;\n transition: background 0.2s ease;\n align-items: center;\n }\n\n .table-row:hover {\n background: #f8f9fa;\n }\n\n .table-cell {\n font-size: 12px;\n color: #333;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .type-badge {\n background: linear-gradient(135deg, rgba(100, 116, 139, 0.1) 0%, rgba(71, 85, 105, 0.1) 100%);\n color: #64748b;\n padding: 3px 8px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n }\n\n .type-badge--prompt {\n background: linear-gradient(135deg, rgba(99, 102, 241, 0.15) 0%, rgba(139, 92, 246, 0.15) 100%);\n color: #6366f1;\n }\n\n .type-badge--agent {\n background: linear-gradient(135deg, rgba(16, 185, 129, 0.15) 0%, rgba(5, 150, 105, 0.15) 100%);\n color: #10b981;\n }\n\n .no-data {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n color: #999;\n gap: 16px;\n }\n\n .no-data i {\n font-size: 48px;\n color: #ddd;\n }\n\n .no-data p {\n margin: 0;\n font-size: 14px;\n }\n\n /* Model detail styles */\n .model-detail {\n padding: 20px;\n overflow-y: auto;\n }\n\n .model-details {\n display: flex;\n flex-direction: column;\n gap: 24px;\n }\n\n .model-info-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 16px;\n }\n\n .info-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 16px;\n background: #f8f9fa;\n border-radius: 6px;\n }\n\n .info-item label {\n font-size: 11px;\n color: #666;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin: 0;\n }\n\n .info-item span {\n font-size: 14px;\n color: #333;\n font-weight: 500;\n }\n\n .status-indicator {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n }\n\n .status-indicator.active {\n color: #4caf50;\n }\n\n .status-indicator.active::before {\n content: '';\n width: 6px;\n height: 6px;\n background: #4caf50;\n border-radius: 50%;\n }\n\n .model-description {\n padding: 20px;\n background: #f8f9fa;\n border-radius: 8px;\n }\n\n .model-description h5 {\n margin: 0 0 12px 0;\n font-size: 14px;\n font-weight: 600;\n color: #333;\n }\n\n .model-description p {\n margin: 0;\n font-size: 13px;\n color: #666;\n line-height: 1.5;\n }\n\n /* Clickable KPI cards */\n .clickable {\n cursor: pointer;\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n }\n\n .clickable:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n }\n\n /* Collapsible Panel Styles */\n .analysis-panels {\n padding: 12px;\n height: 100%;\n overflow-y: auto;\n background: linear-gradient(180deg, #f8f9ff 0%, #f3f4f6 100%);\n }\n\n .analysis-panel {\n margin-bottom: 12px;\n border-radius: 10px;\n box-shadow: 0 2px 8px rgba(99, 102, 241, 0.08);\n background: white;\n overflow: hidden;\n border: 1px solid rgba(99, 102, 241, 0.08);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .analysis-panel:hover {\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.12);\n }\n\n .analysis-panel:last-child {\n margin-bottom: 0;\n }\n\n .panel-header {\n padding: 14px 18px;\n background: linear-gradient(180deg, #fafbff 0%, #f8f9fc 100%);\n border-bottom: 1px solid rgba(99, 102, 241, 0.08);\n cursor: pointer;\n display: flex;\n justify-content: space-between;\n align-items: center;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .panel-header:hover {\n background: linear-gradient(180deg, #f0f1ff 0%, #e8e9ff 100%);\n }\n\n .panel-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-weight: 600;\n color: #1e293b;\n font-size: 14px;\n }\n\n .panel-title i {\n color: #6366f1;\n width: 18px;\n }\n\n .panel-toggle-icon {\n color: #6366f1;\n font-size: 12px;\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .panel-content {\n padding: 18px;\n border-top: 1px solid rgba(99, 102, 241, 0.05);\n animation: slideDown 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n @keyframes slideDown {\n from {\n opacity: 0;\n max-height: 0;\n }\n to {\n opacity: 1;\n max-height: 500px;\n }\n }\n\n .live-executions-panel {\n padding: 0;\n }\n\n .live-executions-panel app-live-execution-widget {\n height: 300px;\n display: block;\n }\n\n /* Responsive Design */\n @media (max-width: 1200px) {\n .dashboard-splitter {\n min-height: 400px;\n }\n \n .table-header,\n .table-row {\n grid-template-columns: 60px 1fr 100px 80px 80px 60px 80px 100px;\n gap: 8px;\n }\n \n .model-info-grid {\n grid-template-columns: 1fr;\n }\n \n .analysis-panels {\n padding: 8px;\n }\n \n .analysis-panel {\n margin-bottom: 8px;\n }\n }\n\n @media (max-width: 768px) {\n .execution-monitoring {\n padding: 12px;\n }\n \n .monitoring-header {\n flex-direction: column;\n align-items: flex-start;\n }\n \n .monitoring-controls {\n width: 100%;\n justify-content: flex-start;\n }\n \n .dashboard-splitter {\n min-height: 350px;\n }\n \n .kpi-grid {\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n }\n\n /* Reduce padding on smaller screens */\n :host ::ng-deep .k-splitter .k-splitter-pane {\n padding: 5px;\n }\n\n :host ::ng-deep .k-splitter-horizontal > .k-splitter-pane {\n padding: 5px 2px;\n }\n\n :host ::ng-deep .k-splitter-vertical > .k-splitter-pane {\n padding: 2px 5px;\n }\n \n .tab-header {\n overflow-x: auto;\n }\n \n .tab-item {\n min-width: 100px;\n padding: 6px 12px;\n }\n \n .table-header,\n .table-row {\n grid-template-columns: 1fr;\n gap: 4px;\n text-align: left;\n }\n \n .table-row {\n display: block;\n padding: 16px;\n }\n \n .table-cell {\n display: block;\n margin-bottom: 8px;\n }\n \n .table-cell:before {\n content: attr(data-label) ': ';\n font-weight: 600;\n color: #666;\n font-size: 11px;\n text-transform: uppercase;\n }\n \n .executions-drill-down,\n .model-detail {\n padding: 12px;\n }\n \n .panel-content {\n padding: 12px;\n }\n \n .panel-header {\n padding: 10px 12px;\n }\n \n .panel-title {\n font-size: 13px;\n }\n }\n "] }]
|
|
2023
2023
|
}], () => [{ type: i1.AIInstrumentationService }, { type: i2.NavigationService }, { type: i0.ChangeDetectorRef }], null); })();
|
|
2024
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ExecutionMonitoringComponent, { className: "ExecutionMonitoringComponent", filePath: "src/
|
|
2024
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ExecutionMonitoringComponent, { className: "ExecutionMonitoringComponent", filePath: "src/AI/components/execution-monitoring.component.ts", lineNumber: 1786 }); })();
|
|
2025
2025
|
//# sourceMappingURL=execution-monitoring.component.js.map
|
|
@@ -1392,5 +1392,5 @@ export { ModelManagementComponent };
|
|
|
1392
1392
|
type: Component,
|
|
1393
1393
|
args: [{ standalone: false, selector: 'app-model-management', template: "<div class=\"model-management-v2\">\n @if (isLoading) {\n <div class=\"loading-container\">\n <mj-loading [text]=\"currentLoadingMessage\" size=\"large\"></mj-loading>\n </div>\n } @else {\n <div class=\"dashboard-header\">\n <div class=\"header-info\">\n <h2 class=\"dashboard-title\">\n <i class=\"fa-solid fa-microchip\"></i>\n AI Models\n </h2>\n <button\n type=\"button\"\n class=\"filter-toggle-btn\"\n (click)=\"toggleFilters()\"\n title=\"Toggle Filters\">\n <i class=\"fa-solid fa-filter\"></i>\n @if (showFilters) {\n Hide Filters\n } @else {\n Show Filters\n }\n </button>\n <span class=\"item-count\">{{ filteredModels.length }} models</span>\n </div>\n\n <div class=\"header-controls\">\n <div class=\"view-toggle\">\n <button\n type=\"button\"\n class=\"view-btn\"\n [class.active]=\"viewMode === 'grid'\"\n (click)=\"setViewMode('grid')\"\n title=\"Grid View\">\n <i class=\"fa-solid fa-grip\"></i>\n </button>\n <button\n type=\"button\"\n class=\"view-btn\"\n [class.active]=\"viewMode === 'list'\"\n (click)=\"setViewMode('list')\"\n title=\"List View\">\n <i class=\"fa-solid fa-list\"></i>\n </button>\n </div>\n\n <button\n type=\"button\"\n class=\"control-btn primary\"\n (click)=\"createNewModel()\"\n title=\"Create New Model\">\n <i class=\"fa-solid fa-plus\"></i>\n New Model\n </button>\n </div>\n </div>\n\n <kendo-splitter orientation=\"horizontal\">\n @if (showFilters) {\n <kendo-splitter-pane size=\"320\" min=\"250\" max=\"400\">\n <div class=\"filter-panel\">\n <div class=\"filter-panel-header\">\n <h3>Model Filters</h3>\n <div class=\"filter-summary-inline\">\n <span class=\"summary-value\">{{ filteredModels.length }}</span>\n <span class=\"summary-label\">of {{ models.length }}</span>\n </div>\n <button class=\"close-btn\" (click)=\"toggleFilterPanel()\">\n <span class=\"fa-solid fa-times\"></span>\n </button>\n </div>\n \n <div class=\"filter-content\">\n <!-- Search Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <span class=\"fa-solid fa-search\"></span>\n Name\n </label>\n <input \n type=\"text\"\n class=\"filter-input\"\n placeholder=\"Search models...\"\n [value]=\"searchTerm\"\n (input)=\"onSearchChange($any($event.target).value)\"\n />\n </div>\n\n <!-- Sort By Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <span class=\"fa-solid fa-sort\"></span>\n Sort By\n </label>\n <select class=\"filter-select\" [value]=\"sortBy\" (change)=\"onSortChange($any($event.target).value)\">\n @for (option of sortOptions; track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n </div>\n\n <!-- Vendor Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <span class=\"fa-solid fa-building\"></span>\n Vendor\n </label>\n <select class=\"filter-select\" [value]=\"selectedVendor\" (change)=\"onVendorChange($any($event.target).value)\">\n <option value=\"all\">All Vendors</option>\n @for (vendor of vendors; track vendor.ID) {\n <option [value]=\"vendor.ID\">{{ vendor.Name }}</option>\n }\n </select>\n </div>\n\n <!-- Type Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <span class=\"fa-solid fa-microchip\"></span>\n Type\n </label>\n <select class=\"filter-select\" [value]=\"selectedType\" (change)=\"onTypeChange($any($event.target).value)\">\n <option value=\"all\">All Types</option>\n @for (type of modelTypes; track type.ID) {\n <option [value]=\"type.ID\">{{ type.Name }}</option>\n }\n </select>\n </div>\n\n <!-- Status Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <span class=\"fa-solid fa-toggle-on\"></span>\n Status\n </label>\n <select class=\"filter-select\" [value]=\"selectedStatus\" (change)=\"onStatusChange($any($event.target).value)\">\n <option value=\"all\">All Statuses</option>\n <option value=\"active\">Active</option>\n <option value=\"inactive\">Inactive</option>\n </select>\n </div>\n\n <!-- Power Rank Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <span class=\"fa-solid fa-bolt\"></span>\n Power Rank\n </label>\n <div class=\"rank-filter-inputs\">\n <input \n type=\"number\" \n min=\"0\" \n [max]=\"maxPowerRank\" \n [(ngModel)]=\"powerRankRange.min\"\n (change)=\"validateAndApplyRankFilters('power')\"\n class=\"rank-input\"\n placeholder=\"Min\"\n />\n <span class=\"rank-separator\">-</span>\n <input \n type=\"number\" \n min=\"0\" \n [max]=\"maxPowerRank\" \n [(ngModel)]=\"powerRankRange.max\"\n (change)=\"validateAndApplyRankFilters('power')\"\n class=\"rank-input\"\n placeholder=\"Max\"\n />\n </div>\n </div>\n\n <!-- Reset Button -->\n <div class=\"filter-actions\">\n <button class=\"reset-btn\" (click)=\"clearFilters()\" title=\"Reset all filters\">\n <span class=\"fa-solid fa-undo\"></span>\n Reset Filters\n </button>\n </div>\n </div>\n </div>\n </kendo-splitter-pane>\n }\n\n <kendo-splitter-pane>\n <div class=\"content-area\">\n @if (filteredModels.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-microchip fa-4x\"></i>\n <h3>No models found</h3>\n <p>{{ hasActiveFilters ? 'Try adjusting your filters' : 'Create your first AI model to get started' }}</p>\n @if (!hasActiveFilters) {\n <button class=\"primary-action\" (click)=\"createNewModel()\">\n <i class=\"fa-solid fa-plus\"></i>\n Create First Model\n </button>\n }\n </div>\n } @else {\n @switch (viewMode) {\n @case ('grid') {\n <div class=\"model-grid\">\n @for (model of filteredModels; track model.ID) {\n <div class=\"model-card\" [class.expanded]=\"expandedModelId === model.ID\">\n <!-- Card Header -->\n <div class=\"card-header\" (click)=\"toggleModelExpansion(model.ID)\">\n <div class=\"model-info\">\n <div class=\"model-icon\">\n <i [class]=\"getModelIcon(model)\"></i>\n </div>\n <div class=\"model-details\">\n <h4 class=\"model-name\" [innerHTML]=\"(model.Name || 'Unnamed Model') | highlightSearch:searchTerm\"></h4>\n <div class=\"model-meta\">\n @if (model.Vendor) {\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-building\"></i>\n {{ model.Vendor }}\n </span>\n }\n @if (model.AIModelType) {\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-microchip\"></i>\n {{ model.AIModelType }}\n </span>\n }\n @if (model.IsActive) {\n <span class=\"meta-item status-active\">\n <i class=\"fa-solid fa-circle\" style=\"font-size: 8px;\"></i>\n Active\n </span>\n } @else {\n <span class=\"meta-item status-inactive\">\n <i class=\"fa-solid fa-circle\" style=\"font-size: 8px;\"></i>\n Inactive\n </span>\n }\n </div>\n </div>\n </div>\n\n <i class=\"fa-solid fa-chevron-down expand-icon\"\n [class.rotated]=\"expandedModelId === model.ID\"></i>\n </div>\n\n <!-- Card Body -->\n <div class=\"card-body\">\n @if (model.Description) {\n <p class=\"model-description\" [innerHTML]=\"model.Description | highlightSearch:searchTerm\"></p>\n } @else {\n <p class=\"model-description text-muted\">No description provided</p>\n }\n\n <!-- Expandable Content -->\n @if (expandedModelId === model.ID) {\n <div class=\"expanded-content\">\n <div class=\"model-stats\">\n <div class=\"stat-item\">\n <span class=\"stat-label\">Power Rank</span>\n <span class=\"stat-value\">{{ formatRank(model.PowerRank, 'power') }}</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-label\">Speed Rank</span>\n <span class=\"stat-value\">{{ formatRank(model.SpeedRank, 'speed') }}</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-label\">Cost Rank</span>\n <span class=\"stat-value\">{{ formatRank(model.CostRank, 'cost') }}</span>\n </div>\n @if (model.InputTokenLimit) {\n <div class=\"stat-item\">\n <span class=\"stat-label\">Token Limit</span>\n <span class=\"stat-value\">{{ formatTokenLimit(model.InputTokenLimit) }}</span>\n </div>\n }\n @if (model.APIName) {\n <div class=\"stat-item\">\n <span class=\"stat-label\">API Name</span>\n <span class=\"stat-value\">{{ model.APIName }}</span>\n </div>\n }\n @if (model.DriverClass) {\n <div class=\"stat-item\">\n <span class=\"stat-label\">Driver</span>\n <span class=\"stat-value\">{{ model.DriverClass }}</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Card Actions -->\n <div class=\"card-actions\">\n <button\n type=\"button\"\n class=\"action-btn\"\n (click)=\"showModelDetails(model, $event)\"\n title=\"View Details\">\n <i class=\"fa-solid fa-eye\"></i>\n Details\n </button>\n </div>\n </div>\n }\n </div>\n }\n \n @case ('list') {\n <div class=\"model-list\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th (click)=\"onSortChange('name')\"\n [class.sorted]=\"sortBy === 'name'\"\n [class.desc]=\"sortBy === 'name' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Name\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"onSortChange('vendor')\"\n [class.sorted]=\"sortBy === 'vendor'\"\n [class.desc]=\"sortBy === 'vendor' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Vendor\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"onSortChange('type')\"\n [class.sorted]=\"sortBy === 'type'\"\n [class.desc]=\"sortBy === 'type' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Type\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"onSortChange('powerRank')\"\n [class.sorted]=\"sortBy === 'powerRank'\"\n [class.desc]=\"sortBy === 'powerRank' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Power\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"onSortChange('speedRank')\"\n [class.sorted]=\"sortBy === 'speedRank'\"\n [class.desc]=\"sortBy === 'speedRank' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Speed\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"onSortChange('costRank')\"\n [class.sorted]=\"sortBy === 'costRank'\"\n [class.desc]=\"sortBy === 'costRank' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Cost\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th>Status</th>\n <th>Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (model of filteredModels; track model.ID) {\n <tr>\n <td>\n <div class=\"name-cell\">\n <i [class]=\"getModelIcon(model)\"></i>\n <span [innerHTML]=\"(model.Name || 'Unnamed Model') | highlightSearch:searchTerm\"></span>\n </div>\n </td>\n <td>{{ model.Vendor || '-' }}</td>\n <td>{{ model.AIModelType }}</td>\n <td>\n <span class=\"rank-badge\" [class]=\"getRankClass(model.PowerRank, 'power')\">\n {{ formatRank(model.PowerRank, 'power') }}\n </span>\n </td>\n <td>\n <span class=\"rank-badge\" [class]=\"getRankClass(model.SpeedRank, 'speed')\">\n {{ formatRank(model.SpeedRank, 'speed') }}\n </span>\n </td>\n <td>\n <span class=\"rank-badge\" [class]=\"getRankClass(model.CostRank, 'cost')\">\n {{ formatRank(model.CostRank, 'cost') }}\n </span>\n </td>\n <td>\n <span class=\"status-badge\" [class.active]=\"model.IsActive\" [class.inactive]=\"!model.IsActive\">\n {{ model.IsActive ? 'Active' : 'Inactive' }}\n </span>\n </td>\n <td>\n <button class=\"action-button small\" (click)=\"showModelDetails(model)\" title=\"View Details\">\n <i class=\"fa-solid fa-eye\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n }\n }\n </div>\n </kendo-splitter-pane>\n </kendo-splitter>\n\n <!-- Detail Panel Overlay -->\n @if (detailPanelVisible) {\n <div class=\"detail-panel-overlay\" (click)=\"closeDetailPanel()\"></div>\n }\n\n <!-- Detail Panel -->\n <div class=\"detail-panel\" [class.visible]=\"detailPanelVisible\">\n @if (selectedModel) {\n <!-- Panel Header -->\n <div class=\"detail-panel-header\">\n <div class=\"detail-panel-title\">\n <div class=\"detail-icon\">\n <i [class]=\"getModelIcon(selectedModel)\"></i>\n </div>\n <div class=\"detail-title-info\">\n <h3>{{ selectedModel.Name }}</h3>\n <span class=\"detail-subtitle\">{{ selectedModel.Vendor || 'AI Model' }}</span>\n </div>\n </div>\n <button class=\"detail-panel-close\" (click)=\"closeDetailPanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Panel Content -->\n <div class=\"detail-panel-content\">\n <!-- Status Section -->\n <div class=\"detail-section\">\n <div class=\"detail-badges\">\n @if (selectedModel.IsActive) {\n <span class=\"status-badge status-active\">\n <i class=\"fa-solid fa-circle\" style=\"font-size: 8px;\"></i>\n Active\n </span>\n } @else {\n <span class=\"status-badge status-inactive\">\n <i class=\"fa-solid fa-circle\" style=\"font-size: 8px;\"></i>\n Inactive\n </span>\n }\n @if (selectedModel.AIModelType) {\n <span class=\"feature-badge\">\n <i class=\"fa-solid fa-microchip\"></i>\n {{ selectedModel.AIModelType }}\n </span>\n }\n </div>\n </div>\n\n <!-- Description -->\n @if (selectedModel.Description) {\n <div class=\"detail-section\">\n <h4 class=\"detail-section-title\">\n <i class=\"fa-solid fa-align-left\"></i>\n Description\n </h4>\n <p class=\"detail-description\">{{ selectedModel.Description }}</p>\n </div>\n }\n\n <!-- Ranking Details -->\n <div class=\"detail-section\">\n <h4 class=\"detail-section-title\">\n <i class=\"fa-solid fa-chart-bar\"></i>\n Rankings\n </h4>\n <div class=\"detail-grid\">\n <div class=\"detail-item\">\n <span class=\"detail-label\">Power Rank</span>\n <span class=\"detail-value rank-badge\" [class]=\"getRankClass(selectedModel.PowerRank, 'power')\">\n {{ formatRank(selectedModel.PowerRank, 'power') }}\n </span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Speed Rank</span>\n <span class=\"detail-value rank-badge\" [class]=\"getRankClass(selectedModel.SpeedRank, 'speed')\">\n {{ formatRank(selectedModel.SpeedRank, 'speed') }}\n </span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Cost Rank</span>\n <span class=\"detail-value rank-badge\" [class]=\"getRankClass(selectedModel.CostRank, 'cost')\">\n {{ formatRank(selectedModel.CostRank, 'cost') }}\n </span>\n </div>\n </div>\n </div>\n\n <!-- Configuration Details -->\n <div class=\"detail-section\">\n <h4 class=\"detail-section-title\">\n <i class=\"fa-solid fa-cog\"></i>\n Configuration\n </h4>\n <div class=\"detail-grid\">\n <div class=\"detail-item\">\n <span class=\"detail-label\">Vendor</span>\n <span class=\"detail-value\">{{ selectedModel.Vendor || 'Unknown' }}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Model Type</span>\n <span class=\"detail-value\">{{ selectedModel.AIModelType || 'Unknown' }}</span>\n </div>\n @if (selectedModel.APIName) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">API Name</span>\n <span class=\"detail-value\">{{ selectedModel.APIName }}</span>\n </div>\n }\n @if (selectedModel.InputTokenLimit) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">Input Token Limit</span>\n <span class=\"detail-value\">{{ formatTokenLimit(selectedModel.InputTokenLimit) }}</span>\n </div>\n }\n @if (selectedModel.SupportedResponseFormats) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">Response Formats</span>\n <span class=\"detail-value\">{{ selectedModel.SupportedResponseFormats }}</span>\n </div>\n }\n @if (selectedModel.SupportsEffortLevel) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">Supports Effort Level</span>\n <span class=\"detail-value\">Yes</span>\n </div>\n }\n @if (selectedModel.DriverClass) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">Driver Class</span>\n <span class=\"detail-value\">{{ selectedModel.DriverClass }}</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Timestamps -->\n <div class=\"detail-section\">\n <h4 class=\"detail-section-title\">\n <i class=\"fa-solid fa-clock\"></i>\n Timestamps\n </h4>\n <div class=\"detail-grid\">\n <div class=\"detail-item\">\n <span class=\"detail-label\">Created</span>\n <span class=\"detail-value\">{{ selectedModel.__mj_CreatedAt | date:'medium' }}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Updated</span>\n <span class=\"detail-value\">{{ selectedModel.__mj_UpdatedAt | date:'medium' }}</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Panel Actions -->\n <div class=\"detail-panel-actions\">\n <button\n type=\"button\"\n class=\"detail-action-btn primary\"\n (click)=\"openModelFromPanel()\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n Open Full Record\n </button>\n </div>\n }\n </div>\n }\n</div>", styles: ["/* ============================================\n AI Models Dashboard - World-Class Design\n Clean white header with indigo/purple accents\n ============================================ */\n\n/* Container */\n.model-management-v2 {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: linear-gradient(135deg, #f5f7fa 0%, #e4e8ed 100%);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\n}\n\n/* Loading State */\n.loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n background: linear-gradient(135deg, #f5f7fa 0%, #e4e8ed 100%);\n}\n\n/* Dashboard Header - Clean White Style */\n.dashboard-header {\n background: white;\n padding: 16px 24px;\n border-bottom: 1px solid #e0e6ed;\n display: flex;\n justify-content: space-between;\n align-items: center;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n position: relative;\n z-index: 10;\n}\n\n.header-info {\n display: flex;\n align-items: center;\n gap: 20px;\n}\n\n.dashboard-title {\n margin: 0;\n font-size: 20px;\n font-weight: 700;\n color: #1e293b;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.dashboard-title i {\n color: #6366f1;\n font-size: 22px;\n}\n\n.filter-toggle-btn {\n background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);\n border: 1px solid #dee2e6;\n padding: 10px 18px;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: #495057;\n cursor: pointer;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.filter-toggle-btn:hover {\n background: linear-gradient(135deg, #e9ecef 0%, #dee2e6 100%);\n border-color: #ced4da;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n\n.filter-toggle-btn i {\n color: #6366f1;\n font-size: 14px;\n}\n\n.item-count {\n color: #6c757d;\n font-size: 14px;\n font-weight: 500;\n padding: 6px 12px;\n background: #f8f9fa;\n border-radius: 20px;\n border: 1px solid #e9ecef;\n}\n\n.header-controls {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n/* View Toggle */\n.view-toggle {\n display: flex;\n background: #f8f9fa;\n border-radius: 8px;\n padding: 3px;\n border: 1px solid #dee2e6;\n}\n\n.view-btn {\n background: transparent;\n border: none;\n padding: 8px 14px;\n border-radius: 6px;\n color: #6c757d;\n cursor: pointer;\n transition: all 0.2s ease;\n font-size: 15px;\n}\n\n.view-btn:hover {\n color: #495057;\n}\n\n.view-btn.active {\n background: white;\n color: #6366f1;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);\n}\n\n.control-btn {\n background: white;\n border: 1px solid #dee2e6;\n padding: 10px 18px;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: #495057;\n cursor: pointer;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.control-btn:hover {\n background: #f8f9fa;\n border-color: #ced4da;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.control-btn i {\n font-size: 14px;\n}\n\n.control-btn.primary {\n background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);\n border-color: #4f46e5;\n color: white;\n}\n\n.control-btn.primary:hover {\n background: linear-gradient(135deg, #4f46e5 0%, #4338ca 100%);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.35);\n}\n\n/* Splitter */\nkendo-splitter {\n flex: 1;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 50%, #e8f0fe 100%);\n margin-top: 0;\n}\n\n:host ::ng-deep .k-splitter {\n border: none;\n background: transparent;\n}\n\n:host ::ng-deep .k-splitbar {\n background: #e2e8f0;\n width: 6px;\n}\n\n:host ::ng-deep .k-splitbar:hover {\n background: #c7d2fe;\n}\n\n:host ::ng-deep .k-pane {\n overflow: hidden;\n}\n\n/* Filter Panel */\n.filter-panel {\n height: 100%;\n background: white;\n border-right: 1px solid #e5e7eb;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n/* Header */\n.filter-panel-header {\n padding: 20px;\n border-bottom: 1px solid #f1f5f9;\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-shrink: 0;\n background: linear-gradient(135deg, #fafbfc 0%, #f8fafc 100%);\n}\n\n.filter-panel-header h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n color: #1e293b;\n flex: 1;\n letter-spacing: -0.02em;\n}\n\n.filter-panel-header .filter-summary-inline {\n display: flex;\n align-items: baseline;\n gap: 4px;\n margin-right: 16px;\n font-size: 13px;\n padding: 6px 12px;\n background: linear-gradient(135deg, #ede9fe 0%, #ddd6fe 100%);\n border-radius: 20px;\n border: 1px solid #c4b5fd;\n}\n\n.filter-panel-header .filter-summary-inline .summary-value {\n font-weight: 700;\n color: #6366f1;\n}\n\n.filter-panel-header .filter-summary-inline .summary-label {\n color: #7c3aed;\n font-weight: 500;\n}\n\n.filter-panel-header .close-btn {\n background: transparent;\n border: none;\n padding: 8px;\n cursor: pointer;\n color: #94a3b8;\n border-radius: 8px;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.filter-panel-header .close-btn:hover {\n background: #f1f5f9;\n color: #475569;\n}\n\n.filter-panel-header .close-btn .fa-solid {\n font-size: 14px;\n}\n\n/* Content Area */\n.filter-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 20px;\n}\n\n/* Filter Groups */\n.filter-group {\n margin-bottom: 24px;\n}\n\n.filter-group .filter-label {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 10px;\n font-size: 12px;\n font-weight: 700;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.75px;\n}\n\n.filter-group .filter-label .fa-solid {\n font-size: 13px;\n color: #6366f1;\n width: 16px;\n}\n\n.filter-group .filter-input,\n.filter-group .filter-select {\n width: 100%;\n padding: 12px 14px;\n border: 1px solid #e2e8f0;\n border-radius: 10px;\n font-size: 14px;\n background: white;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n box-sizing: border-box;\n color: #334155;\n}\n\n.filter-group .filter-input:focus,\n.filter-group .filter-select:focus {\n outline: none;\n border-color: #6366f1;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);\n}\n\n.filter-group .filter-input::placeholder {\n color: #94a3b8;\n}\n\n.filter-group .filter-select {\n cursor: pointer;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M2.5 4.5L6 8l3.5-3.5'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n padding-right: 36px;\n}\n\n/* Legacy support for non-scoped selectors */\n.filter-input,\n.filter-select {\n width: 100%;\n padding: 12px 14px;\n border: 1px solid #e2e8f0;\n border-radius: 10px;\n font-size: 14px;\n background: white;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n box-sizing: border-box;\n color: #334155;\n}\n\n.filter-input:focus,\n.filter-select:focus {\n outline: none;\n border-color: #6366f1;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);\n}\n\n.filter-input::placeholder {\n color: #94a3b8;\n}\n\n.filter-select {\n cursor: pointer;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M2.5 4.5L6 8l3.5-3.5'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n padding-right: 36px;\n}\n\n/* Rank Filter */\n.rank-filter-inputs {\n display: flex;\n gap: 10px;\n align-items: center;\n margin-top: 8px;\n}\n\n.rank-input {\n width: 70px;\n padding: 10px 12px;\n border: 2px solid #e2e8f0;\n border-radius: 8px;\n font-size: 14px;\n text-align: center;\n background: white;\n transition: all 0.3s;\n box-sizing: border-box;\n -moz-appearance: textfield;\n}\n\n.rank-input:focus {\n outline: none;\n border-color: #6366f1;\n box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.1);\n}\n\n.rank-input::placeholder {\n color: #94a3b8;\n font-size: 12px;\n}\n\n.rank-input::-webkit-inner-spin-button,\n.rank-input::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin: 0;\n}\n\n.rank-separator {\n color: #64748b;\n font-size: 13px;\n font-weight: 600;\n}\n\n/* Filter Actions */\n.filter-actions {\n margin-top: 28px;\n padding-top: 20px;\n border-top: 1px solid #f1f5f9;\n}\n\n.filter-actions .reset-btn {\n width: 100%;\n padding: 12px 16px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border: 1px solid #e2e8f0;\n border-radius: 10px;\n color: #64748b;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n box-sizing: border-box;\n}\n\n.filter-actions .reset-btn:hover {\n background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%);\n border-color: #cbd5e1;\n color: #475569;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.filter-actions .reset-btn .fa-solid {\n font-size: 13px;\n}\n\n/* Scrollbar Styling */\n.filter-content::-webkit-scrollbar {\n width: 6px;\n}\n\n.filter-content::-webkit-scrollbar-track {\n background: #f8fafc;\n border-radius: 3px;\n}\n\n.filter-content::-webkit-scrollbar-thumb {\n background: #cbd5e1;\n border-radius: 3px;\n}\n\n.filter-content::-webkit-scrollbar-thumb:hover {\n background: #94a3b8;\n}\n\n/* Content Area */\n.content-area {\n height: 100%;\n padding: 28px;\n overflow-y: auto;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 50%, #e8f0fe 100%);\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n text-align: center;\n color: #64748b;\n padding: 60px 32px;\n}\n\n.empty-state i {\n font-size: 80px;\n background: linear-gradient(135deg, #c7d2fe 0%, #ddd6fe 100%);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n margin-bottom: 28px;\n opacity: 1;\n}\n\n.empty-state h3 {\n margin: 0 0 12px 0;\n font-size: 24px;\n font-weight: 700;\n color: #1e293b;\n}\n\n.empty-state p {\n margin: 0 0 32px 0;\n font-size: 16px;\n line-height: 1.6;\n max-width: 420px;\n}\n\n/* Grid View */\n.model-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));\n gap: 24px;\n}\n\n.model-card {\n background: white;\n border-radius: 16px;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);\n border: 1px solid #e2e8f0;\n transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n position: relative;\n}\n\n.model-card::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 4px;\n background: linear-gradient(90deg, #6366f1 0%, #8b5cf6 50%, #a78bfa 100%);\n opacity: 0;\n transition: opacity 0.3s ease;\n}\n\n.model-card:hover {\n box-shadow: 0 20px 40px -15px rgba(99, 102, 241, 0.25);\n transform: translateY(-4px);\n border-color: #c7d2fe;\n}\n\n.model-card:hover::before {\n opacity: 1;\n}\n\n.model-card.expanded {\n box-shadow: 0 25px 50px -12px rgba(99, 102, 241, 0.3);\n border-color: #a5b4fc;\n}\n\n.model-card.expanded::before {\n opacity: 1;\n}\n\n.card-header {\n padding: 24px;\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n cursor: pointer;\n user-select: none;\n border-bottom: 1px solid #f1f5f9;\n transition: background-color 0.2s;\n}\n\n.card-header:hover {\n background-color: #fafbfc;\n}\n\n.model-info {\n display: flex;\n gap: 18px;\n flex: 1;\n}\n\n.model-icon {\n width: 56px;\n height: 56px;\n border-radius: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.model-icon i {\n color: white;\n font-size: 24px;\n}\n\n.model-details {\n flex: 1;\n min-width: 0;\n}\n\n.model-name {\n margin: 0;\n font-size: 18px;\n font-weight: 700;\n color: #1e293b;\n margin-bottom: 8px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.model-meta {\n display: flex;\n gap: 14px;\n flex-wrap: wrap;\n}\n\n.meta-item {\n font-size: 13px;\n color: #64748b;\n display: flex;\n align-items: center;\n gap: 6px;\n background: #f1f5f9;\n padding: 4px 10px;\n border-radius: 6px;\n}\n\n.meta-item i {\n font-size: 11px;\n color: #6366f1;\n}\n\n.meta-item.status-active {\n color: #059669;\n background: #d1fae5;\n}\n\n.meta-item.status-active i {\n color: #059669;\n}\n\n.meta-item.status-inactive {\n color: #64748b;\n background: #e2e8f0;\n}\n\n.meta-item.status-inactive i {\n color: #64748b;\n}\n\n.expand-icon {\n font-size: 16px;\n color: #94a3b8;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n padding: 8px;\n border-radius: 8px;\n}\n\n.expand-icon:hover {\n color: #6366f1;\n background: #f1f5f9;\n}\n\n.expand-icon.rotated {\n transform: rotate(180deg);\n color: #6366f1;\n}\n\n.card-body {\n padding: 0 24px 24px 24px;\n}\n\n.model-description {\n margin: 18px 0 0 0;\n font-size: 14px;\n line-height: 1.7;\n color: #64748b;\n}\n\n.model-description.text-muted {\n font-style: italic;\n color: #94a3b8;\n}\n\n/* Expanded Content */\n.expanded-content {\n margin-top: 20px;\n padding-top: 20px;\n border-top: 1px solid #e2e8f0;\n animation: slideDown 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n@keyframes slideDown {\n from {\n opacity: 0;\n transform: translateY(-12px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.model-stats {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 18px;\n}\n\n.stat-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 16px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-radius: 12px;\n border: 1px solid #e2e8f0;\n}\n\n.stat-label {\n font-size: 11px;\n font-weight: 700;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.stat-value {\n font-size: 15px;\n color: #1e293b;\n font-weight: 600;\n}\n\n/* Card Actions */\n.card-actions {\n padding: 18px 24px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-top: 1px solid #e2e8f0;\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n}\n\n.action-btn {\n background: white;\n border: 2px solid #e2e8f0;\n padding: 10px 20px;\n border-radius: 10px;\n font-size: 13px;\n font-weight: 600;\n color: #475569;\n cursor: pointer;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.action-btn:hover {\n background: #f8fafc;\n border-color: #6366f1;\n color: #6366f1;\n transform: translateY(-1px);\n}\n\n.action-btn-primary {\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n border-color: transparent;\n color: white;\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.action-btn-primary:hover {\n background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);\n transform: translateY(-2px);\n box-shadow: 0 6px 16px rgba(99, 102, 241, 0.4);\n}\n\n/* List View */\n.model-list {\n background: white;\n border-radius: 16px;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);\n border: 1px solid #e2e8f0;\n overflow: hidden;\n}\n\n.data-table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.data-table thead {\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n}\n\n.data-table thead tr {\n border-bottom: 2px solid #e2e8f0;\n}\n\n.data-table thead th {\n padding: 16px 20px;\n text-align: left;\n font-size: 12px;\n font-weight: 700;\n color: #475569;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n cursor: pointer;\n user-select: none;\n transition: all 0.2s ease;\n}\n\n.data-table thead th:hover {\n background: #e2e8f0;\n color: #6366f1;\n}\n\n.data-table thead th:last-child,\n.data-table thead th:nth-last-child(2) {\n cursor: default;\n}\n\n.data-table thead th:last-child:hover,\n.data-table thead th:nth-last-child(2):hover {\n background: transparent;\n color: #475569;\n}\n\n.data-table thead th.sorted {\n color: #6366f1;\n background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 100%);\n}\n\n.data-table thead th.sorted.desc .sort-icon {\n transform: rotate(180deg);\n}\n\n.data-table .sort-header {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.data-table .sort-icon {\n font-size: 10px;\n opacity: 0;\n transition: all 0.2s ease;\n}\n\n.data-table thead th:hover .sort-icon {\n opacity: 0.5;\n}\n\n.data-table thead th.sorted .sort-icon {\n opacity: 1;\n color: #6366f1;\n}\n\n.data-table tbody tr {\n border-bottom: 1px solid #f1f5f9;\n transition: background-color 0.2s ease;\n}\n\n.data-table tbody tr:last-child {\n border-bottom: none;\n}\n\n.data-table tbody tr:hover {\n background: linear-gradient(135deg, #fafbfc 0%, #f8fafc 100%);\n}\n\n.data-table tbody td {\n padding: 18px 20px;\n font-size: 14px;\n color: #475569;\n}\n\n.name-cell {\n display: flex;\n align-items: center;\n gap: 12px;\n font-weight: 600;\n color: #1e293b;\n}\n\n.name-cell i {\n color: #6366f1;\n font-size: 18px;\n}\n\n/* Rank Badge */\n.rank-badge {\n display: inline-flex;\n align-items: center;\n padding: 6px 12px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.rank-badge.rank-high {\n background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);\n color: #047857;\n}\n\n.rank-badge.rank-medium {\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n color: #b45309;\n}\n\n.rank-badge.rank-low {\n background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);\n color: #b91c1c;\n}\n\n.rank-badge.rank-none {\n background: linear-gradient(135deg, #e2e8f0 0%, #cbd5e1 100%);\n color: #475569;\n}\n\n/* Status Badge */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.status-badge.active {\n background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);\n color: #047857;\n}\n\n.status-badge.inactive {\n background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);\n color: #b91c1c;\n}\n\n/* Responsive Design */\n@media (max-width: 768px) {\n .dashboard-header {\n flex-direction: column;\n gap: 16px;\n align-items: stretch;\n padding: 16px 20px;\n }\n\n .header-info {\n flex-wrap: wrap;\n justify-content: center;\n }\n\n .header-controls {\n justify-content: center;\n }\n\n .content-area {\n padding: 16px;\n }\n\n .model-grid {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .model-stats {\n grid-template-columns: 1fr;\n }\n\n .card-header {\n padding: 18px;\n }\n\n .card-body {\n padding: 0 18px 18px 18px;\n }\n\n .card-actions {\n padding: 14px 18px;\n flex-wrap: wrap;\n }\n}\n\n/* ============================================\n Detail Panel - Slide-in Panel\n ============================================ */\n\n/* Detail Panel Overlay */\n.detail-panel-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(15, 23, 42, 0.5);\n backdrop-filter: blur(4px);\n z-index: 1000;\n opacity: 0;\n animation: fadeIn 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n@keyframes fadeIn {\n to {\n opacity: 1;\n }\n}\n\n/* Detail Panel */\n.detail-panel {\n position: fixed;\n top: 0;\n right: -480px;\n width: 480px;\n max-width: 90vw;\n height: 100vh;\n background: white;\n box-shadow: -8px 0 32px rgba(0, 0, 0, 0.15);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n transition: right 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.detail-panel.visible {\n right: 0;\n}\n\n/* Detail Panel Header */\n.detail-panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 24px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-bottom: 1px solid #e2e8f0;\n flex-shrink: 0;\n}\n\n.detail-panel-title {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.detail-icon {\n width: 56px;\n height: 56px;\n border-radius: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.detail-icon i {\n color: white;\n font-size: 24px;\n}\n\n.detail-title-info h3 {\n margin: 0 0 4px 0;\n font-size: 20px;\n font-weight: 700;\n color: #1e293b;\n}\n\n.detail-subtitle {\n font-size: 13px;\n color: #64748b;\n font-weight: 500;\n}\n\n.detail-panel-close {\n background: white;\n border: 1px solid #e2e8f0;\n width: 40px;\n height: 40px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.2s ease;\n color: #64748b;\n}\n\n.detail-panel-close:hover {\n background: #f8fafc;\n border-color: #cbd5e1;\n color: #1e293b;\n}\n\n/* Detail Panel Content */\n.detail-panel-content {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n}\n\n/* Detail Section */\n.detail-section {\n margin-bottom: 28px;\n}\n\n.detail-section:last-child {\n margin-bottom: 0;\n}\n\n.detail-badges {\n display: flex;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.status-badge.status-active {\n background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);\n color: #047857;\n}\n\n.status-badge.status-inactive {\n background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);\n color: #b91c1c;\n}\n\n.feature-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 100%);\n color: #4f46e5;\n}\n\n.feature-badge i {\n font-size: 11px;\n}\n\n.detail-description {\n margin: 0;\n font-size: 14px;\n line-height: 1.7;\n color: #475569;\n}\n\n.detail-section-title {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 700;\n color: #475569;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.detail-section-title i {\n color: #6366f1;\n font-size: 14px;\n}\n\n/* Detail Grid */\n.detail-grid {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 16px;\n}\n\n.detail-grid.single-column {\n grid-template-columns: 1fr;\n}\n\n.detail-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 14px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-radius: 12px;\n border: 1px solid #e2e8f0;\n}\n\n.detail-item.full-width {\n grid-column: 1 / -1;\n}\n\n.detail-label {\n font-size: 11px;\n font-weight: 700;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.detail-value {\n font-size: 14px;\n color: #1e293b;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.detail-value i {\n font-size: 13px;\n}\n\n.detail-value.muted {\n color: #94a3b8;\n font-style: italic;\n}\n\n/* Status Badges in Detail Panel */\n.detail-section .status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border-radius: 20px;\n font-size: 13px;\n font-weight: 600;\n}\n\n.detail-section .status-badge.active {\n background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);\n color: #047857;\n}\n\n.detail-section .status-badge.inactive {\n background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);\n color: #b91c1c;\n}\n\n/* Detail Panel Actions */\n.detail-panel-actions {\n padding: 20px 24px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-top: 1px solid #e2e8f0;\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n flex-shrink: 0;\n}\n\n.detail-action-btn {\n padding: 12px 24px;\n border-radius: 10px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.detail-action-btn.primary {\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n border: none;\n color: white;\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.detail-action-btn.primary:hover {\n background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);\n transform: translateY(-2px);\n box-shadow: 0 6px 16px rgba(99, 102, 241, 0.4);\n}\n\n.detail-action-btn.secondary {\n background: white;\n border: 2px solid #e2e8f0;\n color: #475569;\n}\n\n.detail-action-btn.secondary:hover {\n background: #f8fafc;\n border-color: #6366f1;\n color: #6366f1;\n}\n\n/* Responsive adjustments for detail panel */\n@media (max-width: 520px) {\n .detail-panel {\n width: 100%;\n right: -100%;\n }\n\n .detail-panel.visible {\n right: 0;\n }\n\n .detail-grid {\n grid-template-columns: 1fr;\n }\n}\n\n/* Search Highlight */\n:host ::ng-deep .search-highlight,\n.search-highlight {\n background-color: #fef08a;\n padding: 1px 2px;\n border-radius: 2px;\n font-weight: inherit;\n}\n"] }]
|
|
1394
1394
|
}], () => [{ type: i1.SharedService }, { type: i1.NavigationService }, { type: i0.ChangeDetectorRef }], null); })();
|
|
1395
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ModelManagementComponent, { className: "ModelManagementComponent", filePath: "src/
|
|
1395
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ModelManagementComponent, { className: "ModelManagementComponent", filePath: "src/AI/components/models/model-management.component.ts", lineNumber: 45 }); })();
|
|
1396
1396
|
//# sourceMappingURL=model-management.component.js.map
|
|
@@ -935,5 +935,5 @@ export class ModelPromptPriorityMatrixComponent {
|
|
|
935
935
|
}], promptSelected: [{
|
|
936
936
|
type: Output
|
|
937
937
|
}] }); })();
|
|
938
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ModelPromptPriorityMatrixComponent, { className: "ModelPromptPriorityMatrixComponent", filePath: "src/
|
|
938
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ModelPromptPriorityMatrixComponent, { className: "ModelPromptPriorityMatrixComponent", filePath: "src/AI/components/prompts/model-prompt-priority-matrix.component.ts", lineNumber: 33 }); })();
|
|
939
939
|
//# sourceMappingURL=model-prompt-priority-matrix.component.js.map
|
|
@@ -180,5 +180,5 @@ export class PromptFilterPanelComponent {
|
|
|
180
180
|
}], closePanel: [{
|
|
181
181
|
type: Output
|
|
182
182
|
}] }); })();
|
|
183
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PromptFilterPanelComponent, { className: "PromptFilterPanelComponent", filePath: "src/
|
|
183
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PromptFilterPanelComponent, { className: "PromptFilterPanelComponent", filePath: "src/AI/components/prompts/prompt-filter-panel.component.ts", lineNumber: 25 }); })();
|
|
184
184
|
//# sourceMappingURL=prompt-filter-panel.component.js.map
|
|
@@ -1182,5 +1182,5 @@ export { PromptManagementComponent };
|
|
|
1182
1182
|
type: Component,
|
|
1183
1183
|
args: [{ standalone: false, selector: 'app-prompt-management', template: "<div class=\"prompt-management-container\">\n <!-- Header -->\n <div class=\"dashboard-header\">\n <div class=\"header-info\">\n <h2 class=\"dashboard-title\">\n <i class=\"fa-solid fa-message\"></i>\n AI Prompts\n </h2>\n <button\n type=\"button\"\n class=\"filter-toggle-btn\"\n (click)=\"toggleFilters()\"\n title=\"Toggle Filters\">\n <i class=\"fa-solid fa-filter\"></i>\n @if (showFilters) {\n Hide Filters\n } @else {\n Show Filters\n }\n </button>\n <span class=\"item-count\">{{ filteredPrompts.length }} prompts</span>\n </div>\n\n <div class=\"header-controls\">\n <div class=\"view-toggle\">\n <button\n type=\"button\"\n class=\"view-btn\"\n [class.active]=\"viewMode === 'grid'\"\n (click)=\"setViewMode('grid')\"\n title=\"Grid View\">\n <i class=\"fa-solid fa-grip\"></i>\n </button>\n <button\n type=\"button\"\n class=\"view-btn\"\n [class.active]=\"viewMode === 'list'\"\n (click)=\"setViewMode('list')\"\n title=\"List View\">\n <i class=\"fa-solid fa-list\"></i>\n </button>\n </div>\n\n @if (UserCanCreatePrompts) {\n <button\n type=\"button\"\n class=\"control-btn primary\"\n (click)=\"createNewPrompt()\"\n title=\"Create New Prompt\">\n <i class=\"fa-solid fa-plus\"></i>\n New Prompt\n </button>\n }\n </div>\n </div>\n\n <!-- Main Content with Splitter -->\n <div class=\"main-content\">\n <kendo-splitter\n class=\"main-splitter\"\n orientation=\"horizontal\">\n\n <!-- Filter Panel (Left) -->\n <kendo-splitter-pane\n [size]=\"showFilters ? '320px' : '0px'\"\n [collapsible]=\"false\"\n [resizable]=\"showFilters\"\n [scrollable]=\"false\"\n [hidden]=\"!showFilters\">\n <div class=\"filter-panel\">\n <div class=\"filter-panel-header\">\n <h3>Prompt Filters</h3>\n <div class=\"filter-summary-inline\">\n <span class=\"summary-value\">{{ filteredPrompts.length }}</span>\n <span class=\"summary-label\">of {{ prompts.length }}</span>\n </div>\n <button class=\"close-btn\" (click)=\"toggleFilterPanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <div class=\"filter-content\">\n <!-- Search Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <i class=\"fa-solid fa-search\"></i>\n Name\n </label>\n <input\n type=\"text\"\n class=\"filter-input\"\n placeholder=\"Search prompts...\"\n [value]=\"searchTerm\"\n (input)=\"onSearchChange($any($event.target).value)\"\n />\n </div>\n\n <!-- Category Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <i class=\"fa-solid fa-folder\"></i>\n Category\n </label>\n <select class=\"filter-select\" [value]=\"selectedCategory\" (change)=\"onCategoryChange($any($event.target).value)\">\n <option value=\"all\">All Categories</option>\n @for (category of categories; track category.ID) {\n <option [value]=\"category.ID\">{{ category.Name }}</option>\n }\n </select>\n </div>\n\n <!-- Type Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <i class=\"fa-solid fa-tag\"></i>\n Type\n </label>\n <select class=\"filter-select\" [value]=\"selectedType\" (change)=\"onTypeChange($any($event.target).value)\">\n <option value=\"all\">All Types</option>\n @for (type of types; track type.ID) {\n <option [value]=\"type.ID\">{{ type.Name }}</option>\n }\n </select>\n </div>\n\n <!-- Status Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <i class=\"fa-solid fa-toggle-on\"></i>\n Status\n </label>\n <select class=\"filter-select\" [value]=\"selectedStatus\" (change)=\"onStatusChange($any($event.target).value)\">\n <option value=\"all\">All Statuses</option>\n <option value=\"active\">Active</option>\n <option value=\"inactive\">Inactive</option>\n </select>\n </div>\n\n <!-- Reset Button -->\n <div class=\"filter-actions\">\n <button class=\"reset-btn\" (click)=\"clearFilters()\" title=\"Reset all filters\">\n <i class=\"fa-solid fa-undo\"></i>\n Reset Filters\n </button>\n </div>\n </div>\n </div>\n </kendo-splitter-pane>\n\n <!-- Prompts List Panel -->\n <kendo-splitter-pane\n [resizable]=\"true\"\n [scrollable]=\"true\">\n <div class=\"prompts-content\">\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\">\n <mj-loading [text]=\"currentLoadingMessage\" size=\"large\"></mj-loading>\n </div>\n }\n\n <!-- Prompts Display -->\n @if (!isLoading) {\n @if (filteredPrompts.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-message\"></i>\n <h3>No prompts found</h3>\n <p>{{ hasActiveFilters ? 'Try adjusting your filters' : 'Create your first AI prompt to get started' }}</p>\n @if (!hasActiveFilters && UserCanCreatePrompts) {\n <button\n type=\"button\"\n class=\"empty-state-btn\"\n (click)=\"createNewPrompt()\">\n <i class=\"fa-solid fa-plus\"></i>\n Create New Prompt\n </button>\n }\n </div>\n } @else {\n <!-- Grid View -->\n @if (viewMode === 'grid') {\n <div class=\"prompts-grid\">\n @for (prompt of filteredPrompts; track prompt.ID) {\n <div class=\"prompt-card\" [class.expanded]=\"expandedPromptId === prompt.ID\">\n <!-- Card Header -->\n <div class=\"card-header\" (click)=\"togglePromptExpansion(prompt.ID)\">\n <div class=\"prompt-info\">\n <div class=\"prompt-icon\">\n <i [class]=\"getPromptIcon(prompt)\"></i>\n </div>\n <div class=\"prompt-details\">\n <h4 class=\"prompt-name\" [innerHTML]=\"prompt.Name | highlightSearch:searchTerm\"></h4>\n <div class=\"prompt-meta\">\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-folder\"></i>\n {{ prompt.CategoryName }}\n </span>\n @if (prompt.Status) {\n <span class=\"meta-item\" [class]=\"'status-' + prompt.Status.toLowerCase()\">\n <i class=\"fa-solid fa-circle\" style=\"font-size: 8px;\"></i>\n {{ prompt.Status }}\n </span>\n }\n </div>\n </div>\n </div>\n\n <i class=\"fa-solid fa-chevron-down expand-icon\"\n [class.rotated]=\"expandedPromptId === prompt.ID\"></i>\n </div>\n\n <!-- Card Body -->\n <div class=\"card-body\">\n @if (prompt.Description) {\n <p class=\"prompt-description\" [innerHTML]=\"prompt.Description | highlightSearch:searchTerm\"></p>\n } @else {\n <p class=\"prompt-description text-muted\">No description provided</p>\n }\n\n <!-- Expandable Content -->\n @if (expandedPromptId === prompt.ID) {\n <div class=\"expanded-content\">\n <div class=\"prompt-stats\">\n <div class=\"stat-item\">\n <span class=\"stat-label\">Type</span>\n <span class=\"stat-value\">{{ prompt.TypeName }}</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-label\">Template</span>\n <span class=\"stat-value\">\n @if (prompt.TemplateEntity) {\n <i class=\"fa-solid fa-check\" style=\"color: #28a745;\"></i> Yes\n } @else {\n <i class=\"fa-solid fa-times\" style=\"color: #dc3545;\"></i> No\n }\n </span>\n </div>\n </div>\n </div>\n }\n </div>\n\n <!-- Card Actions -->\n <div class=\"card-actions\">\n @if (UserCanReadPrompts) {\n <button\n type=\"button\"\n class=\"action-btn\"\n (click)=\"showPromptDetails(prompt, $event)\"\n title=\"View Details\">\n <i class=\"fa-solid fa-eye\"></i>\n Details\n </button>\n }\n\n @if (prompt.Status === 'Active' && UserCanReadPrompts) {\n <button\n type=\"button\"\n class=\"action-btn action-btn-primary\"\n (click)=\"testPrompt(prompt.ID, $event)\"\n title=\"Run Prompt\">\n <i class=\"fa-solid fa-play\"></i>\n Run\n </button>\n }\n </div>\n </div>\n }\n </div>\n }\n\n <!-- List View -->\n @if (viewMode === 'list') {\n <div class=\"prompts-list\">\n <table class=\"prompts-table\">\n <thead>\n <tr>\n <th (click)=\"sortBy('Name')\"\n [class.sorted]=\"sortColumn === 'Name'\"\n [class.desc]=\"sortColumn === 'Name' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Name\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"sortBy('Category')\"\n [class.sorted]=\"sortColumn === 'Category'\"\n [class.desc]=\"sortColumn === 'Category' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Category\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"sortBy('Type')\"\n [class.sorted]=\"sortColumn === 'Type'\"\n [class.desc]=\"sortColumn === 'Type' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Type\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"sortBy('Status')\"\n [class.sorted]=\"sortColumn === 'Status'\"\n [class.desc]=\"sortColumn === 'Status' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Status\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th>Template</th>\n <th>Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (prompt of filteredPrompts; track prompt.ID) {\n <tr>\n <td>\n <div class=\"prompt-name-cell\">\n <div class=\"prompt-icon-small\">\n <i [class]=\"getPromptIcon(prompt)\"></i>\n </div>\n <div>\n <div class=\"prompt-name\" [innerHTML]=\"prompt.Name | highlightSearch:searchTerm\"></div>\n @if (prompt.Description) {\n <div class=\"prompt-description-small\" [innerHTML]=\"prompt.Description | highlightSearch:searchTerm\"></div>\n }\n </div>\n </div>\n </td>\n <td>{{ prompt.CategoryName }}</td>\n <td>{{ prompt.TypeName }}</td>\n <td>\n <span class=\"status-badge\" [class]=\"'status-' + (prompt.Status || 'unknown').toLowerCase()\">\n {{ prompt.Status || 'Unknown' }}\n </span>\n </td>\n <td>\n @if (prompt.TemplateEntity) {\n <i class=\"fa-solid fa-check-circle\" style=\"color: #28a745;\"></i>\n } @else {\n <i class=\"fa-solid fa-times-circle\" style=\"color: #6c757d;\"></i>\n }\n </td>\n <td>\n <div class=\"table-actions\">\n @if (UserCanReadPrompts) {\n <button\n type=\"button\"\n class=\"action-btn-small\"\n (click)=\"showPromptDetails(prompt)\"\n title=\"View Details\">\n <i class=\"fa-solid fa-eye\"></i>\n </button>\n }\n @if (prompt.Status === 'Active' && UserCanReadPrompts) {\n <button\n type=\"button\"\n class=\"action-btn-small primary\"\n (click)=\"testPrompt(prompt.ID, $event)\"\n title=\"Run Prompt\">\n <i class=\"fa-solid fa-play\"></i>\n </button>\n }\n </div>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n }\n }\n </div>\n </kendo-splitter-pane>\n </kendo-splitter>\n </div>\n\n <!-- Detail Panel Overlay -->\n @if (detailPanelVisible) {\n <div class=\"detail-panel-overlay\" (click)=\"closeDetailPanel()\"></div>\n }\n\n <!-- Detail Panel -->\n <div class=\"detail-panel\" [class.visible]=\"detailPanelVisible\">\n @if (selectedPrompt) {\n <!-- Panel Header -->\n <div class=\"detail-panel-header\">\n <div class=\"detail-panel-title\">\n <div class=\"detail-icon\">\n <i [class]=\"getPromptIcon(selectedPrompt)\"></i>\n </div>\n <div class=\"detail-title-info\">\n <h3>{{ selectedPrompt.Name }}</h3>\n <span class=\"detail-subtitle\">{{ selectedPrompt.TypeName || 'Prompt' }}</span>\n </div>\n </div>\n <button class=\"detail-panel-close\" (click)=\"closeDetailPanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Panel Content -->\n <div class=\"detail-panel-content\">\n <!-- Status Section -->\n <div class=\"detail-section\">\n <div class=\"detail-badges\">\n <span class=\"status-badge\" [class]=\"'status-' + (selectedPrompt.Status || 'unknown').toLowerCase()\">\n <i class=\"fa-solid fa-circle\" style=\"font-size: 8px;\"></i>\n {{ selectedPrompt.Status || 'Unknown' }}\n </span>\n @if (selectedPrompt.TemplateEntity) {\n <span class=\"feature-badge\">\n <i class=\"fa-solid fa-file-code\"></i>\n Has Template\n </span>\n }\n </div>\n </div>\n\n <!-- Description -->\n @if (selectedPrompt.Description) {\n <div class=\"detail-section\">\n <h4 class=\"detail-section-title\">\n <i class=\"fa-solid fa-align-left\"></i>\n Description\n </h4>\n <p class=\"detail-description\">{{ selectedPrompt.Description }}</p>\n </div>\n }\n\n <!-- Configuration Details -->\n <div class=\"detail-section\">\n <h4 class=\"detail-section-title\">\n <i class=\"fa-solid fa-cog\"></i>\n Configuration\n </h4>\n <div class=\"detail-grid\">\n <div class=\"detail-item\">\n <span class=\"detail-label\">Category</span>\n <span class=\"detail-value\">{{ selectedPrompt.CategoryName || 'Uncategorized' }}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Type</span>\n <span class=\"detail-value\">{{ selectedPrompt.TypeName || 'Unknown' }}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Response Format</span>\n <span class=\"detail-value\">{{ selectedPrompt.ResponseFormat }}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Selection Strategy</span>\n <span class=\"detail-value\">{{ selectedPrompt.SelectionStrategy }}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Power Preference</span>\n <span class=\"detail-value\">{{ selectedPrompt.PowerPreference }}</span>\n </div>\n @if (selectedPrompt.MinPowerRank) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">Min Power Rank</span>\n <span class=\"detail-value\">{{ selectedPrompt.MinPowerRank }}</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Timestamps -->\n <div class=\"detail-section\">\n <h4 class=\"detail-section-title\">\n <i class=\"fa-solid fa-clock\"></i>\n Timestamps\n </h4>\n <div class=\"detail-grid\">\n <div class=\"detail-item\">\n <span class=\"detail-label\">Created</span>\n <span class=\"detail-value\">{{ selectedPrompt.__mj_CreatedAt | date:'medium' }}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Updated</span>\n <span class=\"detail-value\">{{ selectedPrompt.__mj_UpdatedAt | date:'medium' }}</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Panel Actions -->\n <div class=\"detail-panel-actions\">\n @if (selectedPrompt.Status === 'Active') {\n <button\n type=\"button\"\n class=\"detail-action-btn secondary\"\n (click)=\"testPrompt(selectedPrompt.ID)\">\n <i class=\"fa-solid fa-play\"></i>\n Run Prompt\n </button>\n }\n <button\n type=\"button\"\n class=\"detail-action-btn primary\"\n (click)=\"openPromptFromPanel()\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n Open Full Record\n </button>\n </div>\n }\n </div>\n</div>\n", styles: ["/* ============================================\n AI Prompts Dashboard - World-Class Design\n Modern gradient-based interface with indigo/purple theme\n ============================================ */\n\n/* Container */\n.prompt-management-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 50%, #e8f0fe 100%);\n}\n\n/* Dashboard Header - Clean White Style */\n.dashboard-header {\n background: white;\n padding: 16px 24px;\n border-bottom: 1px solid #e0e6ed;\n display: flex;\n justify-content: space-between;\n align-items: center;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n position: relative;\n z-index: 10;\n}\n\n.header-info {\n display: flex;\n align-items: center;\n gap: 20px;\n}\n\n.dashboard-title {\n margin: 0;\n font-size: 20px;\n font-weight: 700;\n color: #1e293b;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.dashboard-title i {\n color: #6366f1;\n font-size: 22px;\n}\n\n.filter-toggle-btn {\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n padding: 8px 16px;\n border-radius: 8px;\n font-size: 13px;\n font-weight: 500;\n color: #475569;\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.filter-toggle-btn:hover {\n background: #f1f5f9;\n border-color: #cbd5e1;\n color: #1e293b;\n}\n\n.filter-toggle-btn i {\n font-size: 13px;\n color: #6366f1;\n}\n\n.item-count {\n color: #64748b;\n font-size: 13px;\n font-weight: 500;\n background: #f1f5f9;\n padding: 6px 12px;\n border-radius: 16px;\n}\n\n.header-controls {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n/* View Toggle */\n.view-toggle {\n display: flex;\n background: #f1f5f9;\n border-radius: 8px;\n padding: 3px;\n border: 1px solid #e2e8f0;\n}\n\n.view-btn {\n background: transparent;\n border: none;\n padding: 8px 12px;\n border-radius: 6px;\n color: #64748b;\n cursor: pointer;\n transition: all 0.2s ease;\n font-size: 14px;\n}\n\n.view-btn:hover {\n color: #1e293b;\n background: rgba(99, 102, 241, 0.08);\n}\n\n.view-btn.active {\n background: white;\n color: #6366f1;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n.control-btn {\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n padding: 8px 16px;\n border-radius: 8px;\n font-size: 13px;\n font-weight: 600;\n color: #475569;\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.control-btn:hover {\n background: #f1f5f9;\n border-color: #cbd5e1;\n color: #1e293b;\n}\n\n.control-btn.primary {\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n border-color: transparent;\n color: white;\n box-shadow: 0 2px 8px rgba(99, 102, 241, 0.25);\n}\n\n.control-btn.primary:hover {\n background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.35);\n}\n\n/* Main Content */\n.main-content {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n\n.main-splitter {\n flex: 1;\n min-height: 0;\n}\n\n/* Splitter Styling */\nkendo-splitter {\n background: transparent;\n}\n\n:host ::ng-deep .k-splitter {\n border: none;\n background: transparent;\n}\n\n:host ::ng-deep .k-splitbar {\n background: #e5e7eb;\n width: 6px;\n}\n\n:host ::ng-deep .k-splitbar:hover {\n background: #c7d2fe;\n}\n\n:host ::ng-deep .k-pane {\n overflow: hidden;\n}\n\n/* Filter Panel */\n.filter-panel {\n height: 100%;\n background: white;\n border-right: 1px solid #e5e7eb;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n/* Header */\n.filter-panel-header {\n padding: 20px;\n border-bottom: 1px solid #f1f5f9;\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-shrink: 0;\n background: linear-gradient(135deg, #fafbfc 0%, #f8fafc 100%);\n}\n\n.filter-panel-header h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n color: #1e293b;\n flex: 1;\n letter-spacing: -0.02em;\n}\n\n.filter-panel-header .filter-summary-inline {\n display: flex;\n align-items: baseline;\n gap: 4px;\n margin-right: 16px;\n font-size: 13px;\n padding: 6px 12px;\n background: linear-gradient(135deg, #ede9fe 0%, #ddd6fe 100%);\n border-radius: 20px;\n border: 1px solid #c4b5fd;\n}\n\n.filter-panel-header .filter-summary-inline .summary-value {\n font-weight: 700;\n color: #6366f1;\n}\n\n.filter-panel-header .filter-summary-inline .summary-label {\n color: #7c3aed;\n font-weight: 500;\n}\n\n.filter-panel-header .close-btn {\n background: transparent;\n border: none;\n padding: 8px;\n cursor: pointer;\n color: #94a3b8;\n border-radius: 8px;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.filter-panel-header .close-btn:hover {\n background: #f1f5f9;\n color: #475569;\n}\n\n.filter-panel-header .close-btn .fa-solid {\n font-size: 14px;\n}\n\n/* Content Area */\n.filter-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 20px;\n}\n\n/* Filter Groups */\n.filter-group {\n margin-bottom: 24px;\n}\n\n.filter-group .filter-label {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 10px;\n font-size: 12px;\n font-weight: 700;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.75px;\n}\n\n.filter-group .filter-label .fa-solid {\n font-size: 13px;\n color: #6366f1;\n width: 16px;\n}\n\n.filter-group .filter-input,\n.filter-group .filter-select {\n width: 100%;\n padding: 12px 14px;\n border: 1px solid #e2e8f0;\n border-radius: 10px;\n font-size: 14px;\n background: white;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n box-sizing: border-box;\n color: #334155;\n}\n\n.filter-group .filter-input:focus,\n.filter-group .filter-select:focus {\n outline: none;\n border-color: #6366f1;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);\n}\n\n.filter-group .filter-input::placeholder {\n color: #94a3b8;\n}\n\n.filter-group .filter-select {\n cursor: pointer;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M2.5 4.5L6 8l3.5-3.5'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n padding-right: 36px;\n}\n\n/* Legacy support for non-scoped selectors */\n.filter-input,\n.filter-select {\n width: 100%;\n padding: 12px 14px;\n border: 1px solid #e2e8f0;\n border-radius: 10px;\n font-size: 14px;\n background: white;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n box-sizing: border-box;\n color: #334155;\n}\n\n.filter-input:focus,\n.filter-select:focus {\n outline: none;\n border-color: #6366f1;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);\n}\n\n.filter-input::placeholder {\n color: #94a3b8;\n}\n\n.filter-select {\n cursor: pointer;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M2.5 4.5L6 8l3.5-3.5'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n padding-right: 36px;\n}\n\n/* Filter Actions */\n.filter-actions {\n margin-top: 28px;\n padding-top: 20px;\n border-top: 1px solid #f1f5f9;\n}\n\n.filter-actions .reset-btn {\n width: 100%;\n padding: 12px 16px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border: 1px solid #e2e8f0;\n border-radius: 10px;\n color: #64748b;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n box-sizing: border-box;\n}\n\n.filter-actions .reset-btn:hover {\n background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%);\n border-color: #cbd5e1;\n color: #475569;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.filter-actions .reset-btn .fa-solid {\n font-size: 13px;\n}\n\n/* Scrollbar Styling */\n.filter-content::-webkit-scrollbar {\n width: 6px;\n}\n\n.filter-content::-webkit-scrollbar-track {\n background: #f8fafc;\n border-radius: 3px;\n}\n\n.filter-content::-webkit-scrollbar-thumb {\n background: #cbd5e1;\n border-radius: 3px;\n}\n\n.filter-content::-webkit-scrollbar-thumb:hover {\n background: #94a3b8;\n}\n\n/* Prompts Content */\n.prompts-content {\n height: 100%;\n overflow-y: auto;\n padding: 28px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 50%, #e8f0fe 100%);\n}\n\n/* Grid View */\n.prompts-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));\n gap: 24px;\n}\n\n.prompt-card {\n background: white;\n border-radius: 16px;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);\n border: 1px solid #e2e8f0;\n transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n position: relative;\n}\n\n.prompt-card::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 4px;\n background: linear-gradient(90deg, #6366f1 0%, #8b5cf6 50%, #a78bfa 100%);\n opacity: 0;\n transition: opacity 0.3s ease;\n}\n\n.prompt-card:hover {\n box-shadow: 0 20px 40px -15px rgba(99, 102, 241, 0.25);\n transform: translateY(-4px);\n border-color: #c7d2fe;\n}\n\n.prompt-card:hover::before {\n opacity: 1;\n}\n\n.prompt-card.expanded {\n box-shadow: 0 25px 50px -12px rgba(99, 102, 241, 0.3);\n border-color: #a5b4fc;\n}\n\n.prompt-card.expanded::before {\n opacity: 1;\n}\n\n.card-header {\n padding: 24px;\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n cursor: pointer;\n user-select: none;\n border-bottom: 1px solid #f1f5f9;\n transition: background-color 0.2s;\n}\n\n.card-header:hover {\n background-color: #fafbfc;\n}\n\n.prompt-info {\n display: flex;\n gap: 18px;\n flex: 1;\n}\n\n.prompt-icon {\n width: 56px;\n height: 56px;\n border-radius: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.prompt-icon i {\n color: white;\n font-size: 24px;\n}\n\n.prompt-details {\n flex: 1;\n min-width: 0;\n}\n\n.prompt-name {\n margin: 0;\n font-size: 18px;\n font-weight: 700;\n color: #1e293b;\n margin-bottom: 8px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.prompt-meta {\n display: flex;\n gap: 14px;\n flex-wrap: wrap;\n}\n\n.meta-item {\n font-size: 13px;\n color: #64748b;\n display: flex;\n align-items: center;\n gap: 6px;\n background: #f1f5f9;\n padding: 4px 10px;\n border-radius: 6px;\n}\n\n.meta-item i {\n font-size: 11px;\n color: #6366f1;\n}\n\n.meta-item.status-active {\n color: #059669;\n background: #d1fae5;\n}\n\n.meta-item.status-active i {\n color: #059669;\n}\n\n.meta-item.status-pending {\n color: #d97706;\n background: #fef3c7;\n}\n\n.meta-item.status-pending i {\n color: #d97706;\n}\n\n.meta-item.status-inactive {\n color: #64748b;\n background: #e2e8f0;\n}\n\n.meta-item.status-inactive i {\n color: #64748b;\n}\n\n.expand-icon {\n font-size: 16px;\n color: #94a3b8;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n padding: 8px;\n border-radius: 8px;\n}\n\n.expand-icon:hover {\n color: #6366f1;\n background: #f1f5f9;\n}\n\n.expand-icon.rotated {\n transform: rotate(180deg);\n color: #6366f1;\n}\n\n.card-body {\n padding: 0 24px 24px 24px;\n}\n\n.prompt-description {\n margin: 18px 0 0 0;\n font-size: 14px;\n line-height: 1.7;\n color: #64748b;\n}\n\n.prompt-description.text-muted {\n font-style: italic;\n color: #94a3b8;\n}\n\n/* Expanded Content */\n.expanded-content {\n margin-top: 20px;\n padding-top: 20px;\n border-top: 1px solid #e2e8f0;\n animation: slideDown 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n@keyframes slideDown {\n from {\n opacity: 0;\n transform: translateY(-12px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.prompt-stats {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 18px;\n}\n\n.stat-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 16px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-radius: 12px;\n border: 1px solid #e2e8f0;\n}\n\n.stat-label {\n font-size: 11px;\n font-weight: 700;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.stat-value {\n font-size: 15px;\n color: #1e293b;\n font-weight: 600;\n}\n\n/* Card Actions */\n.card-actions {\n padding: 18px 24px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-top: 1px solid #e2e8f0;\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n}\n\n.action-btn {\n background: white;\n border: 2px solid #e2e8f0;\n padding: 10px 20px;\n border-radius: 10px;\n font-size: 13px;\n font-weight: 600;\n color: #475569;\n cursor: pointer;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.action-btn:hover {\n background: #f8fafc;\n border-color: #6366f1;\n color: #6366f1;\n transform: translateY(-1px);\n}\n\n.action-btn-primary {\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n border-color: transparent;\n color: white;\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.action-btn-primary:hover {\n background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);\n transform: translateY(-2px);\n box-shadow: 0 6px 16px rgba(99, 102, 241, 0.4);\n}\n\n/* List View */\n.prompts-list {\n background: white;\n border-radius: 16px;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);\n border: 1px solid #e2e8f0;\n overflow: hidden;\n}\n\n.prompts-table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.prompts-table thead {\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-bottom: 2px solid #e2e8f0;\n}\n\n.prompts-table th {\n padding: 16px 20px;\n text-align: left;\n font-size: 12px;\n font-weight: 700;\n color: #475569;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n cursor: pointer;\n user-select: none;\n transition: all 0.2s ease;\n}\n\n.prompts-table th:hover {\n background: #e2e8f0;\n color: #6366f1;\n}\n\n.prompts-table th:last-child {\n cursor: default;\n}\n\n.prompts-table th:last-child:hover {\n background: transparent;\n color: #475569;\n}\n\n.prompts-table th.sorted {\n color: #6366f1;\n background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 100%);\n}\n\n.prompts-table th.sorted.desc .sort-icon {\n transform: rotate(180deg);\n}\n\n.prompts-table .sort-header {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.prompts-table .sort-icon {\n font-size: 10px;\n opacity: 0;\n transition: all 0.2s ease;\n}\n\n.prompts-table th:hover .sort-icon {\n opacity: 0.5;\n}\n\n.prompts-table th.sorted .sort-icon {\n opacity: 1;\n color: #6366f1;\n}\n\n.prompts-table tbody tr {\n border-bottom: 1px solid #f1f5f9;\n transition: background-color 0.2s;\n}\n\n.prompts-table tbody tr:last-child {\n border-bottom: none;\n}\n\n.prompts-table tbody tr:hover {\n background: linear-gradient(135deg, #fafbfc 0%, #f8fafc 100%);\n}\n\n.prompts-table td {\n padding: 18px 20px;\n font-size: 14px;\n color: #475569;\n}\n\n.prompt-name-cell {\n display: flex;\n align-items: center;\n gap: 14px;\n}\n\n.prompt-icon-small {\n width: 42px;\n height: 42px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n box-shadow: 0 2px 8px rgba(99, 102, 241, 0.25);\n}\n\n.prompt-icon-small i {\n color: white;\n font-size: 18px;\n}\n\n.prompt-name-cell .prompt-name {\n font-weight: 600;\n color: #1e293b;\n margin-bottom: 0;\n white-space: normal;\n}\n\n.prompt-description-small {\n font-size: 13px;\n color: #64748b;\n margin-top: 4px;\n line-height: 1.4;\n}\n\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.status-badge i {\n font-size: 8px;\n}\n\n.status-badge.status-active {\n background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);\n color: #047857;\n}\n\n.status-badge.status-pending {\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n color: #b45309;\n}\n\n.status-badge.status-inactive {\n background: linear-gradient(135deg, #e2e8f0 0%, #cbd5e1 100%);\n color: #475569;\n}\n\n.status-badge.status-unknown {\n background: #f1f5f9;\n color: #64748b;\n}\n\n.table-actions {\n display: flex;\n gap: 10px;\n}\n\n.action-btn-small {\n background: white;\n border: 2px solid #e2e8f0;\n padding: 8px 12px;\n border-radius: 8px;\n font-size: 13px;\n color: #475569;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.action-btn-small:hover {\n background: #f8fafc;\n border-color: #6366f1;\n color: #6366f1;\n}\n\n.action-btn-small.primary {\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n border-color: transparent;\n color: white;\n box-shadow: 0 2px 8px rgba(99, 102, 241, 0.25);\n}\n\n.action-btn-small.primary:hover {\n background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.35);\n}\n\n/* Empty State */\n.empty-state {\n text-align: center;\n padding: 100px 32px;\n color: #64748b;\n}\n\n.empty-state i {\n font-size: 80px;\n background: linear-gradient(135deg, #c7d2fe 0%, #ddd6fe 100%);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n margin-bottom: 28px;\n display: block;\n}\n\n.empty-state h3 {\n color: #1e293b;\n font-size: 24px;\n font-weight: 700;\n margin: 0 0 12px 0;\n}\n\n.empty-state p {\n font-size: 16px;\n line-height: 1.6;\n max-width: 420px;\n margin: 0 auto 32px;\n color: #64748b;\n}\n\n.empty-state-btn {\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n color: white;\n border: none;\n padding: 14px 28px;\n border-radius: 12px;\n font-size: 15px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: inline-flex;\n align-items: center;\n gap: 10px;\n box-shadow: 0 4px 15px rgba(99, 102, 241, 0.3);\n}\n\n.empty-state-btn:hover {\n transform: translateY(-2px);\n box-shadow: 0 8px 25px rgba(99, 102, 241, 0.4);\n}\n\n/* Loading State */\n.loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 400px;\n}\n\n/* Responsive Design */\n@media (max-width: 768px) {\n .dashboard-header {\n flex-direction: column;\n gap: 16px;\n align-items: stretch;\n padding: 16px 20px;\n }\n\n .header-info {\n flex-wrap: wrap;\n justify-content: center;\n }\n\n .header-controls {\n justify-content: center;\n }\n\n .prompts-content {\n padding: 16px;\n }\n\n .prompts-grid {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .prompt-stats {\n grid-template-columns: 1fr;\n }\n\n .card-header {\n padding: 18px;\n }\n\n .card-body {\n padding: 0 18px 18px 18px;\n }\n\n .card-actions {\n padding: 14px 18px;\n flex-wrap: wrap;\n }\n}\n\n/* =============================================\n Detail Panel - Slide-in Overlay\n ============================================= */\n\n.detail-panel-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(15, 23, 42, 0.4);\n backdrop-filter: blur(4px);\n z-index: 1000;\n animation: fadeIn 0.25s ease-out;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.detail-panel {\n position: fixed;\n top: 0;\n right: -480px;\n width: 480px;\n height: 100vh;\n background: white;\n box-shadow: -8px 0 32px rgba(0, 0, 0, 0.15);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n transition: right 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.detail-panel.visible {\n right: 0;\n}\n\n/* Detail Panel Header */\n.detail-panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 24px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-bottom: 1px solid #e2e8f0;\n flex-shrink: 0;\n}\n\n.detail-panel-title {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.detail-icon {\n width: 56px;\n height: 56px;\n border-radius: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.detail-icon i {\n color: white;\n font-size: 24px;\n}\n\n.detail-title-info h3 {\n margin: 0 0 4px 0;\n font-size: 20px;\n font-weight: 700;\n color: #1e293b;\n}\n\n.detail-subtitle {\n font-size: 13px;\n color: #64748b;\n font-weight: 500;\n}\n\n.detail-panel-close {\n background: white;\n border: 1px solid #e2e8f0;\n width: 40px;\n height: 40px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.2s ease;\n color: #64748b;\n}\n\n.detail-panel-close:hover {\n background: #f8fafc;\n border-color: #cbd5e1;\n color: #1e293b;\n}\n\n/* Detail Panel Content */\n.detail-panel-content {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n}\n\n.detail-section {\n margin-bottom: 28px;\n}\n\n.detail-section:last-child {\n margin-bottom: 0;\n}\n\n.detail-badges {\n display: flex;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.feature-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 100%);\n color: #4f46e5;\n}\n\n.feature-badge i {\n font-size: 11px;\n}\n\n.detail-section-title {\n margin: 0 0 16px 0;\n font-size: 12px;\n font-weight: 700;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.detail-section-title i {\n color: #6366f1;\n font-size: 14px;\n}\n\n.detail-description {\n margin: 0;\n font-size: 14px;\n line-height: 1.7;\n color: #475569;\n}\n\n.detail-grid {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 16px;\n}\n\n.detail-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 14px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-radius: 12px;\n border: 1px solid #e2e8f0;\n}\n\n.detail-label {\n font-size: 11px;\n font-weight: 700;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.detail-value {\n font-size: 14px;\n color: #1e293b;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.detail-value i {\n font-size: 13px;\n}\n\n/* Detail Panel Actions */\n.detail-panel-actions {\n padding: 20px 24px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-top: 1px solid #e2e8f0;\n display: flex;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.detail-action-btn {\n flex: 1;\n padding: 14px 20px;\n border-radius: 12px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n}\n\n.detail-action-btn.secondary {\n background: white;\n border: 2px solid #e2e8f0;\n color: #475569;\n}\n\n.detail-action-btn.secondary:hover {\n border-color: #6366f1;\n color: #6366f1;\n background: #fafbff;\n}\n\n.detail-action-btn.primary {\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n border: 2px solid transparent;\n color: white;\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.detail-action-btn.primary:hover {\n background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);\n transform: translateY(-1px);\n box-shadow: 0 6px 16px rgba(99, 102, 241, 0.4);\n}\n\n/* Detail Panel Responsive */\n@media (max-width: 520px) {\n .detail-panel {\n width: 100%;\n right: -100%;\n }\n\n .detail-grid {\n grid-template-columns: 1fr;\n }\n}\n\n/* Search Highlight */\n:host ::ng-deep .search-highlight,\n.search-highlight {\n background-color: #fef08a;\n padding: 1px 2px;\n border-radius: 2px;\n font-weight: inherit;\n}\n"] }]
|
|
1184
1184
|
}], () => [{ type: i1.SharedService }, { type: i2.AITestHarnessDialogService }, { type: i1.NavigationService }, { type: i0.ChangeDetectorRef }], null); })();
|
|
1185
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PromptManagementComponent, { className: "PromptManagementComponent", filePath: "src/
|
|
1185
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PromptManagementComponent, { className: "PromptManagementComponent", filePath: "src/AI/components/prompts/prompt-management.component.ts", lineNumber: 46 }); })();
|
|
1186
1186
|
//# sourceMappingURL=prompt-management.component.js.map
|
|
@@ -1186,5 +1186,5 @@ export class PromptVersionControlComponent {
|
|
|
1186
1186
|
}], versionCompared: [{
|
|
1187
1187
|
type: Output
|
|
1188
1188
|
}] }); })();
|
|
1189
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PromptVersionControlComponent, { className: "PromptVersionControlComponent", filePath: "src/
|
|
1189
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PromptVersionControlComponent, { className: "PromptVersionControlComponent", filePath: "src/AI/components/prompts/prompt-version-control.component.ts", lineNumber: 45 }); })();
|
|
1190
1190
|
//# sourceMappingURL=prompt-version-control.component.js.map
|
|
@@ -140,5 +140,5 @@ export class SystemConfigFilterPanelComponent {
|
|
|
140
140
|
}], closePanel: [{
|
|
141
141
|
type: Output
|
|
142
142
|
}] }); })();
|
|
143
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SystemConfigFilterPanelComponent, { className: "SystemConfigFilterPanelComponent", filePath: "src/
|
|
143
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SystemConfigFilterPanelComponent, { className: "SystemConfigFilterPanelComponent", filePath: "src/AI/components/system/system-config-filter-panel.component.ts", lineNumber: 16 }); })();
|
|
144
144
|
//# sourceMappingURL=system-config-filter-panel.component.js.map
|
|
@@ -967,5 +967,5 @@ export { SystemConfigurationComponent };
|
|
|
967
967
|
type: Component,
|
|
968
968
|
args: [{ standalone: false, selector: 'app-system-configuration', template: "<div class=\"system-configuration-container\">\n <!-- Header -->\n <div class=\"dashboard-header\">\n <div class=\"header-info\">\n <h2 class=\"dashboard-title\">\n <i class=\"fa-solid fa-sliders\"></i>\n AI Configuration\n </h2>\n <button\n type=\"button\"\n class=\"filter-toggle-btn\"\n (click)=\"toggleFilterPanel()\"\n title=\"Toggle Filters\">\n <i class=\"fa-solid fa-filter\"></i>\n @if (filterPanelVisible) {\n Hide Filters\n } @else {\n Show Filters\n }\n </button>\n <span class=\"config-count\">\n {{ filteredConfigurations.length }} of {{ configurations.length }} configurations\n </span>\n </div>\n\n <div class=\"header-controls\">\n <!-- View Toggle -->\n <div class=\"view-toggle\">\n <button\n type=\"button\"\n class=\"view-btn\"\n [class.active]=\"viewMode === 'grid'\"\n (click)=\"setViewMode('grid')\"\n title=\"Grid View\">\n <i class=\"fa-solid fa-grid-2\"></i>\n </button>\n <button\n type=\"button\"\n class=\"view-btn\"\n [class.active]=\"viewMode === 'list'\"\n (click)=\"setViewMode('list')\"\n title=\"List View\">\n <i class=\"fa-solid fa-list\"></i>\n </button>\n </div>\n\n <button\n type=\"button\"\n class=\"control-btn\"\n (click)=\"loadData()\"\n [disabled]=\"isLoading\"\n title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\" [class.fa-spin]=\"isLoading\"></i>\n Refresh\n </button>\n </div>\n </div>\n\n <!-- Main Content with Splitter -->\n <div class=\"main-content\">\n <kendo-splitter\n class=\"main-splitter\"\n orientation=\"horizontal\">\n\n <!-- Filter Panel (Left) -->\n <kendo-splitter-pane\n [size]=\"filterPanelVisible ? '320px' : '0px'\"\n [collapsible]=\"false\"\n [resizable]=\"filterPanelVisible\"\n [scrollable]=\"false\"\n [hidden]=\"!filterPanelVisible\">\n <mj-system-config-filter-panel\n [configurations]=\"configurations\"\n [filteredConfigurations]=\"filteredConfigurations\"\n [filters]=\"currentFilters\"\n (filtersChange)=\"onFiltersChange($event)\"\n (filterChange)=\"onFilterChange()\"\n (resetFilters)=\"onResetFilters()\"\n (closePanel)=\"toggleFilterPanel()\">\n </mj-system-config-filter-panel>\n </kendo-splitter-pane>\n\n <!-- Configurations List Panel -->\n <kendo-splitter-pane\n [resizable]=\"true\"\n [scrollable]=\"false\">\n <div class=\"configurations-content\">\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading AI configurations...\" size=\"large\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <div class=\"error-container\">\n <p class=\"error-message\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n {{ error }}\n </p>\n </div>\n }\n\n <!-- Configurations Content -->\n @if (!isLoading && !error) {\n @if (filteredConfigurations.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-sliders\"></i>\n <h3>No configurations found</h3>\n <p>No AI configurations match your current filters. Try adjusting your search criteria or create a new configuration.</p>\n </div>\n } @else {\n <!-- Grid View -->\n @if (viewMode === 'grid') {\n <div class=\"configurations-grid\">\n @for (config of filteredConfigurations; track config.ID) {\n <div class=\"config-card\" [class.expanded]=\"config.isExpanded\">\n <!-- Card Header -->\n <div class=\"card-header\" (click)=\"toggleExpanded(config)\">\n <div class=\"config-info\">\n <div class=\"config-icon\">\n <i class=\"fa-solid fa-sliders\"></i>\n </div>\n <div class=\"config-details\">\n <h4 class=\"config-name\">{{ config.Name }}</h4>\n <div class=\"config-meta\">\n @if (config.IsDefault) {\n <span class=\"default-badge\">\n <i class=\"fa-solid fa-star\"></i>\n Default\n </span>\n }\n <span class=\"status-badge\" [ngClass]=\"getStatusClass(config.Status)\">\n <i [class]=\"getStatusIcon(config.Status)\"></i>\n {{ config.Status }}\n </span>\n </div>\n </div>\n </div>\n\n <i class=\"fa-solid fa-chevron-down expand-icon\"\n [class.rotated]=\"config.isExpanded\"></i>\n </div>\n\n <!-- Card Body -->\n <div class=\"card-body\">\n @if (config.Description) {\n <p class=\"config-description\">{{ config.Description }}</p>\n } @else {\n <p class=\"config-description text-muted\">No description provided</p>\n }\n\n <!-- Expanded Content -->\n @if (config.isExpanded) {\n <div class=\"expanded-content\">\n <!-- Stats Grid -->\n <div class=\"config-stats\">\n <div class=\"stat-item\">\n <span class=\"stat-label\">Parameters</span>\n <span class=\"stat-value\">{{ config.params?.length || 0 }}</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-label\">Created</span>\n <span class=\"stat-value\">{{ formatDate(config.__mj_CreatedAt) }}</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-label\">Updated</span>\n <span class=\"stat-value\">{{ formatDate(config.__mj_UpdatedAt) }}</span>\n </div>\n </div>\n\n <!-- Linked Prompts -->\n <div class=\"prompts-section\">\n <h5 class=\"section-title\">\n <i class=\"fa-solid fa-message-lines\"></i>\n Linked Prompts\n </h5>\n <div class=\"prompt-links\">\n @if (config.compressionPrompt) {\n <div class=\"prompt-link\" (click)=\"onOpenPrompt(config.DefaultPromptForContextCompressionID!); $event.stopPropagation()\">\n <div class=\"prompt-link-info\">\n <div class=\"prompt-link-icon\">\n <i class=\"fa-solid fa-compress\"></i>\n </div>\n <div class=\"prompt-link-details\">\n <span class=\"prompt-link-label\">Context Compression</span>\n <span class=\"prompt-link-name\">{{ config.compressionPrompt.Name }}</span>\n </div>\n </div>\n <i class=\"fa-solid fa-arrow-right prompt-link-arrow\"></i>\n </div>\n } @else {\n <div class=\"no-prompt\">No compression prompt configured</div>\n }\n\n @if (config.summarizationPrompt) {\n <div class=\"prompt-link\" (click)=\"onOpenPrompt(config.DefaultPromptForContextSummarizationID!); $event.stopPropagation()\">\n <div class=\"prompt-link-info\">\n <div class=\"prompt-link-icon\">\n <i class=\"fa-solid fa-file-lines\"></i>\n </div>\n <div class=\"prompt-link-details\">\n <span class=\"prompt-link-label\">Context Summarization</span>\n <span class=\"prompt-link-name\">{{ config.summarizationPrompt.Name }}</span>\n </div>\n </div>\n <i class=\"fa-solid fa-arrow-right prompt-link-arrow\"></i>\n </div>\n } @else {\n <div class=\"no-prompt\">No summarization prompt configured</div>\n }\n </div>\n </div>\n\n <!-- Configuration Parameters -->\n @if (config.params && config.params.length > 0) {\n <div class=\"params-section\">\n <h5 class=\"section-title\">\n <i class=\"fa-solid fa-gear\"></i>\n Configuration Parameters\n </h5>\n <div class=\"params-grid\">\n @for (param of config.params; track param.ID) {\n <div class=\"param-item\" (click)=\"onOpenParam(param); $event.stopPropagation()\">\n <div class=\"param-info\">\n <div class=\"param-type-icon\">\n <i [class]=\"getParamTypeIcon(param.Type)\"></i>\n </div>\n <div class=\"param-details\">\n <span class=\"param-name\">{{ param.Name }}</span>\n <span class=\"param-type\">{{ param.Type }}</span>\n </div>\n </div>\n <span class=\"param-value\">{{ formatParamValue(param) }}</span>\n </div>\n }\n </div>\n </div>\n } @else {\n <div class=\"params-section\">\n <h5 class=\"section-title\">\n <i class=\"fa-solid fa-gear\"></i>\n Configuration Parameters\n </h5>\n <div class=\"no-params\">No parameters configured</div>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Card Actions -->\n <div class=\"card-actions\" (click)=\"$event.stopPropagation()\">\n <button\n type=\"button\"\n class=\"action-btn\"\n (click)=\"showConfigDetails(config, $event)\"\n title=\"View Details\">\n <i class=\"fa-solid fa-eye\"></i>\n Details\n </button>\n\n <button\n type=\"button\"\n class=\"action-btn action-btn-primary\"\n (click)=\"onOpenConfiguration(config)\">\n <i class=\"fa-solid fa-edit\"></i>\n Configure\n </button>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- List View -->\n @if (viewMode === 'list') {\n <div class=\"configurations-list\">\n <table class=\"configurations-table\">\n <thead>\n <tr>\n <th (click)=\"sortBy('Name')\"\n [class.sorted]=\"sortColumn === 'Name'\"\n [class.desc]=\"sortColumn === 'Name' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Configuration\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"sortBy('Status')\"\n [class.sorted]=\"sortColumn === 'Status'\"\n [class.desc]=\"sortColumn === 'Status' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Status\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"sortBy('Parameters')\"\n [class.sorted]=\"sortColumn === 'Parameters'\"\n [class.desc]=\"sortColumn === 'Parameters' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Parameters\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"sortBy('Updated')\"\n [class.sorted]=\"sortColumn === 'Updated'\"\n [class.desc]=\"sortColumn === 'Updated' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Updated\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th>Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (config of filteredConfigurations; track config.ID) {\n <tr>\n <td>\n <div class=\"config-name-cell\">\n <div class=\"config-icon-small\">\n <i class=\"fa-solid fa-sliders\"></i>\n </div>\n <div>\n <div class=\"config-name-text\">\n {{ config.Name }}\n @if (config.IsDefault) {\n <span class=\"default-badge\" style=\"margin-left: 8px;\">\n <i class=\"fa-solid fa-star\"></i>\n Default\n </span>\n }\n </div>\n @if (config.Description) {\n <div class=\"config-description-small\">{{ config.Description }}</div>\n }\n </div>\n </div>\n </td>\n <td>\n <span class=\"status-badge\" [ngClass]=\"getStatusClass(config.Status)\">\n <i [class]=\"getStatusIcon(config.Status)\"></i>\n {{ config.Status }}\n </span>\n </td>\n <td>{{ config.params?.length || 0 }}</td>\n <td>{{ formatDate(config.__mj_UpdatedAt) }}</td>\n <td>\n <div class=\"table-actions\">\n <button\n type=\"button\"\n class=\"action-btn-small\"\n (click)=\"showConfigDetails(config)\"\n title=\"View Details\">\n <i class=\"fa-solid fa-eye\"></i>\n </button>\n <button\n type=\"button\"\n class=\"action-btn-small primary\"\n (click)=\"onOpenConfiguration(config)\">\n <i class=\"fa-solid fa-edit\"></i>\n </button>\n </div>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n }\n }\n </div>\n </kendo-splitter-pane>\n </kendo-splitter>\n </div>\n\n <!-- Detail Panel Overlay -->\n @if (detailPanelVisible) {\n <div class=\"detail-panel-overlay\" (click)=\"closeDetailPanel()\"></div>\n }\n\n <!-- Detail Panel -->\n <div class=\"detail-panel\" [class.visible]=\"detailPanelVisible\">\n @if (selectedConfig) {\n <!-- Panel Header -->\n <div class=\"detail-panel-header\">\n <div class=\"detail-panel-title\">\n <div class=\"detail-icon\">\n <i class=\"fa-solid fa-sliders\"></i>\n </div>\n <div class=\"detail-title-info\">\n <h3>{{ selectedConfig.Name }}</h3>\n <span class=\"detail-subtitle\">AI Configuration</span>\n </div>\n </div>\n <button class=\"detail-panel-close\" (click)=\"closeDetailPanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Panel Content -->\n <div class=\"detail-panel-content\">\n <!-- Status Section -->\n <div class=\"detail-section\">\n <div class=\"detail-badges\">\n <span class=\"status-badge\" [ngClass]=\"getStatusClass(selectedConfig.Status)\">\n <i [class]=\"getStatusIcon(selectedConfig.Status)\"></i>\n {{ selectedConfig.Status }}\n </span>\n @if (selectedConfig.IsDefault) {\n <span class=\"feature-badge default\">\n <i class=\"fa-solid fa-star\"></i>\n Default Configuration\n </span>\n }\n </div>\n </div>\n\n <!-- Description -->\n @if (selectedConfig.Description) {\n <div class=\"detail-section\">\n <h4 class=\"detail-section-title\">\n <i class=\"fa-solid fa-align-left\"></i>\n Description\n </h4>\n <p class=\"detail-description\">{{ selectedConfig.Description }}</p>\n </div>\n }\n\n <!-- Configuration Stats -->\n <div class=\"detail-section\">\n <h4 class=\"detail-section-title\">\n <i class=\"fa-solid fa-chart-bar\"></i>\n Overview\n </h4>\n <div class=\"detail-grid\">\n <div class=\"detail-item\">\n <span class=\"detail-label\">Parameters</span>\n <span class=\"detail-value\">{{ selectedConfig.params?.length || 0 }}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Status</span>\n <span class=\"detail-value\">{{ selectedConfig.Status }}</span>\n </div>\n </div>\n </div>\n\n <!-- Linked Prompts -->\n <div class=\"detail-section\">\n <h4 class=\"detail-section-title\">\n <i class=\"fa-solid fa-message-lines\"></i>\n Linked Prompts\n </h4>\n <div class=\"detail-grid single-column\">\n <div class=\"detail-item\">\n <span class=\"detail-label\">Context Compression</span>\n <span class=\"detail-value\">\n @if (selectedConfig.compressionPrompt) {\n {{ selectedConfig.compressionPrompt.Name }}\n } @else {\n <span class=\"muted\">Not configured</span>\n }\n </span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Context Summarization</span>\n <span class=\"detail-value\">\n @if (selectedConfig.summarizationPrompt) {\n {{ selectedConfig.summarizationPrompt.Name }}\n } @else {\n <span class=\"muted\">Not configured</span>\n }\n </span>\n </div>\n </div>\n </div>\n\n <!-- Parameters Preview -->\n @if (selectedConfig.params && selectedConfig.params.length > 0) {\n <div class=\"detail-section\">\n <h4 class=\"detail-section-title\">\n <i class=\"fa-solid fa-gear\"></i>\n Parameters ({{ selectedConfig.params.length }})\n </h4>\n <div class=\"detail-params-list\">\n @for (param of selectedConfig.params.slice(0, 5); track param.ID) {\n <div class=\"detail-param-item\">\n <div class=\"param-info\">\n <i [class]=\"getParamTypeIcon(param.Type)\"></i>\n <span class=\"param-name\">{{ param.Name }}</span>\n </div>\n <span class=\"param-value\">{{ formatParamValue(param) }}</span>\n </div>\n }\n @if (selectedConfig.params.length > 5) {\n <div class=\"params-more\">\n +{{ selectedConfig.params.length - 5 }} more parameters\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Timestamps -->\n <div class=\"detail-section\">\n <h4 class=\"detail-section-title\">\n <i class=\"fa-solid fa-clock\"></i>\n Timestamps\n </h4>\n <div class=\"detail-grid\">\n <div class=\"detail-item\">\n <span class=\"detail-label\">Created</span>\n <span class=\"detail-value\">{{ formatDate(selectedConfig.__mj_CreatedAt) }}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Updated</span>\n <span class=\"detail-value\">{{ formatDate(selectedConfig.__mj_UpdatedAt) }}</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Panel Actions -->\n <div class=\"detail-panel-actions\">\n <button\n type=\"button\"\n class=\"detail-action-btn primary\"\n (click)=\"openConfigFromPanel()\">\n <i class=\"fa-solid fa-edit\"></i>\n Open Full Record\n </button>\n </div>\n }\n </div>\n</div>\n", styles: ["/* AI Configuration Dashboard - World-Class Design */\n\n/* ============================================================================\n CONTAINER & LAYOUT\n ============================================================================ */\n.system-configuration-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: linear-gradient(135deg, #f5f7fa 0%, #e4e8ed 100%);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\n}\n\n/* ============================================================================\n HEADER\n ============================================================================ */\n.dashboard-header {\n background: white;\n padding: 16px 24px;\n border-bottom: 1px solid #e0e6ed;\n display: flex;\n justify-content: space-between;\n align-items: center;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n position: relative;\n z-index: 10;\n}\n\n.header-info {\n display: flex;\n align-items: center;\n gap: 20px;\n}\n\n.dashboard-title {\n margin: 0;\n font-size: 20px;\n font-weight: 700;\n color: #1e293b;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.dashboard-title i {\n color: #6366f1;\n font-size: 22px;\n}\n\n.filter-toggle-btn {\n background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);\n border: 1px solid #dee2e6;\n padding: 10px 18px;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: #495057;\n cursor: pointer;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.filter-toggle-btn:hover {\n background: linear-gradient(135deg, #e9ecef 0%, #dee2e6 100%);\n border-color: #ced4da;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n\n.filter-toggle-btn i {\n color: #6366f1;\n font-size: 14px;\n}\n\n.config-count {\n color: #6c757d;\n font-size: 14px;\n font-weight: 500;\n padding: 6px 12px;\n background: #f8f9fa;\n border-radius: 20px;\n border: 1px solid #e9ecef;\n}\n\n.header-controls {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n/* View Toggle */\n.view-toggle {\n display: flex;\n background: #f8f9fa;\n border-radius: 8px;\n padding: 3px;\n border: 1px solid #dee2e6;\n}\n\n.view-btn {\n background: transparent;\n border: none;\n padding: 8px 14px;\n border-radius: 6px;\n color: #6c757d;\n cursor: pointer;\n transition: all 0.2s ease;\n font-size: 15px;\n}\n\n.view-btn:hover {\n color: #495057;\n}\n\n.view-btn.active {\n background: white;\n color: #6366f1;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);\n}\n\n.control-btn {\n background: white;\n border: 1px solid #dee2e6;\n padding: 10px 18px;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: #495057;\n cursor: pointer;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.control-btn:hover {\n background: #f8f9fa;\n border-color: #ced4da;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.control-btn i {\n font-size: 14px;\n}\n\n.control-btn.primary {\n background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);\n border-color: #4f46e5;\n color: white;\n}\n\n.control-btn.primary:hover {\n background: linear-gradient(135deg, #4f46e5 0%, #4338ca 100%);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.35);\n}\n\n/* ============================================================================\n MAIN CONTENT AREA\n ============================================================================ */\n.main-content {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n\n.main-splitter {\n flex: 1;\n min-height: 0;\n}\n\n.configurations-content {\n height: 100%;\n overflow-y: auto;\n padding: 24px;\n background: transparent;\n}\n\n/* ============================================================================\n LOADING STATE\n ============================================================================ */\n.loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n min-height: 400px;\n}\n\n/* ============================================================================\n ERROR STATE\n ============================================================================ */\n.error-container {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n}\n\n.error-message {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%);\n border: 1px solid #fecaca;\n border-radius: 12px;\n color: #dc2626;\n font-size: 15px;\n font-weight: 500;\n}\n\n.error-message i {\n font-size: 20px;\n}\n\n/* ============================================================================\n EMPTY STATE\n ============================================================================ */\n.empty-state {\n text-align: center;\n padding: 80px 20px;\n color: #6c757d;\n}\n\n.empty-state i {\n font-size: 72px;\n color: #d1d5db;\n margin-bottom: 24px;\n display: block;\n opacity: 0.8;\n}\n\n.empty-state h3 {\n color: #374151;\n font-size: 22px;\n font-weight: 600;\n margin: 0 0 12px 0;\n}\n\n.empty-state p {\n font-size: 15px;\n line-height: 1.6;\n max-width: 400px;\n margin: 0 auto 28px;\n color: #6b7280;\n}\n\n/* ============================================================================\n CONFIGURATION GRID\n ============================================================================ */\n.configurations-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(420px, 1fr));\n gap: 24px;\n}\n\n/* ============================================================================\n CONFIGURATION CARD\n ============================================================================ */\n.config-card {\n background: white;\n border-radius: 16px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06);\n border: 1px solid #e5e7eb;\n transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n position: relative;\n}\n\n.config-card::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 4px;\n background: linear-gradient(90deg, #6366f1, #8b5cf6, #a855f7);\n opacity: 0;\n transition: opacity 0.3s ease;\n}\n\n.config-card:hover {\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);\n transform: translateY(-4px);\n border-color: #c7d2fe;\n}\n\n.config-card:hover::before {\n opacity: 1;\n}\n\n.config-card.expanded {\n box-shadow: 0 12px 40px rgba(99, 102, 241, 0.15);\n}\n\n.config-card.expanded::before {\n opacity: 1;\n}\n\n/* Card Header */\n.card-header {\n padding: 24px;\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n cursor: pointer;\n user-select: none;\n border-bottom: 1px solid #f3f4f6;\n transition: background 0.2s ease;\n}\n\n.card-header:hover {\n background: #fafbfc;\n}\n\n.config-info {\n display: flex;\n gap: 18px;\n flex: 1;\n}\n\n.config-icon {\n width: 56px;\n height: 56px;\n border-radius: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.config-icon i {\n color: white;\n font-size: 24px;\n}\n\n.config-details {\n flex: 1;\n min-width: 0;\n}\n\n.config-name {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 700;\n color: #1f2937;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n letter-spacing: -0.02em;\n}\n\n.config-meta {\n display: flex;\n gap: 10px;\n flex-wrap: wrap;\n align-items: center;\n}\n\n/* Status Badge */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n transition: all 0.2s ease;\n}\n\n.status-badge i {\n font-size: 11px;\n}\n\n.status-badge.status-active {\n background: linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%);\n color: #166534;\n border: 1px solid #86efac;\n}\n\n.status-badge.status-preview {\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n color: #92400e;\n border: 1px solid #fcd34d;\n}\n\n.status-badge.status-inactive {\n background: linear-gradient(135deg, #f3f4f6 0%, #e5e7eb 100%);\n color: #4b5563;\n border: 1px solid #d1d5db;\n}\n\n.status-badge.status-deprecated {\n background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);\n color: #991b1b;\n border: 1px solid #fca5a5;\n}\n\n/* Default Badge */\n.default-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n background: linear-gradient(135deg, #ede9fe 0%, #ddd6fe 100%);\n color: #5b21b6;\n border: 1px solid #c4b5fd;\n}\n\n.default-badge i {\n font-size: 11px;\n color: #7c3aed;\n}\n\n/* Expand Icon */\n.expand-icon {\n font-size: 16px;\n color: #9ca3af;\n transition: all 0.3s ease;\n padding: 8px;\n border-radius: 8px;\n}\n\n.expand-icon:hover {\n color: #6366f1;\n background: #f3f4f6;\n}\n\n.expand-icon.rotated {\n transform: rotate(180deg);\n color: #6366f1;\n}\n\n/* Card Body */\n.card-body {\n padding: 0 24px 20px 24px;\n}\n\n.config-description {\n margin: 0;\n font-size: 14px;\n line-height: 1.7;\n color: #6b7280;\n}\n\n.config-description.text-muted {\n font-style: italic;\n color: #9ca3af;\n}\n\n/* ============================================================================\n EXPANDED CONTENT\n ============================================================================ */\n.expanded-content {\n margin-top: 20px;\n padding-top: 20px;\n border-top: 1px solid #f3f4f6;\n animation: slideDown 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n@keyframes slideDown {\n from {\n opacity: 0;\n transform: translateY(-12px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Stats Grid */\n.config-stats {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 16px;\n margin-bottom: 20px;\n}\n\n.stat-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 14px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-radius: 12px;\n border: 1px solid #e2e8f0;\n}\n\n.stat-label {\n font-size: 11px;\n font-weight: 700;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.75px;\n}\n\n.stat-value {\n font-size: 14px;\n color: #334155;\n font-weight: 600;\n}\n\n/* Prompts Section */\n.prompts-section {\n margin-top: 20px;\n}\n\n.section-title {\n font-size: 13px;\n font-weight: 700;\n color: #475569;\n text-transform: uppercase;\n letter-spacing: 0.75px;\n margin: 0 0 12px 0;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.section-title i {\n color: #6366f1;\n font-size: 14px;\n}\n\n.prompt-links {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.prompt-link {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.prompt-link:hover {\n background: #f8fafc;\n border-color: #c7d2fe;\n transform: translateX(4px);\n}\n\n.prompt-link-info {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n.prompt-link-icon {\n width: 36px;\n height: 36px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);\n color: #2563eb;\n flex-shrink: 0;\n}\n\n.prompt-link-icon i {\n font-size: 14px;\n}\n\n.prompt-link-details {\n flex: 1;\n min-width: 0;\n}\n\n.prompt-link-label {\n font-size: 11px;\n font-weight: 600;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 2px;\n}\n\n.prompt-link-name {\n font-size: 14px;\n font-weight: 600;\n color: #1e293b;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.prompt-link-arrow {\n color: #94a3b8;\n font-size: 14px;\n transition: all 0.2s ease;\n}\n\n.prompt-link:hover .prompt-link-arrow {\n color: #6366f1;\n transform: translateX(4px);\n}\n\n.no-prompt {\n font-size: 13px;\n color: #94a3b8;\n font-style: italic;\n padding: 12px 16px;\n background: #f8fafc;\n border-radius: 10px;\n border: 1px dashed #e2e8f0;\n}\n\n/* Parameters Section */\n.params-section {\n margin-top: 20px;\n}\n\n.params-grid {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.param-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.param-item:hover {\n background: #f8fafc;\n border-color: #c7d2fe;\n}\n\n.param-info {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n.param-type-icon {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #f3e8ff 0%, #e9d5ff 100%);\n color: #7c3aed;\n flex-shrink: 0;\n}\n\n.param-type-icon i {\n font-size: 13px;\n}\n\n.param-details {\n flex: 1;\n min-width: 0;\n}\n\n.param-name {\n font-size: 14px;\n font-weight: 600;\n color: #1e293b;\n}\n\n.param-type {\n font-size: 12px;\n color: #64748b;\n margin-top: 2px;\n}\n\n.param-value {\n font-size: 13px;\n color: #475569;\n font-family: 'SF Mono', Monaco, 'Consolas', monospace;\n background: #f1f5f9;\n padding: 4px 10px;\n border-radius: 6px;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.no-params {\n font-size: 13px;\n color: #94a3b8;\n font-style: italic;\n padding: 12px 16px;\n background: #f8fafc;\n border-radius: 10px;\n border: 1px dashed #e2e8f0;\n text-align: center;\n}\n\n/* ============================================================================\n CARD ACTIONS\n ============================================================================ */\n.card-actions {\n padding: 16px 24px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-top: 1px solid #e5e7eb;\n display: flex;\n gap: 10px;\n justify-content: flex-end;\n}\n\n.action-btn {\n background: white;\n border: 1px solid #e5e7eb;\n padding: 8px 16px;\n border-radius: 8px;\n font-size: 13px;\n font-weight: 500;\n color: #475569;\n cursor: pointer;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.action-btn:hover {\n background: #f8fafc;\n border-color: #cbd5e1;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.action-btn i {\n font-size: 12px;\n}\n\n.action-btn-primary {\n background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);\n border-color: #4f46e5;\n color: white;\n}\n\n.action-btn-primary:hover {\n background: linear-gradient(135deg, #4f46e5 0%, #4338ca 100%);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.35);\n}\n\n.action-btn-warning {\n background: linear-gradient(135deg, #fbbf24 0%, #f59e0b 100%);\n border-color: #f59e0b;\n color: #78350f;\n}\n\n.action-btn-warning:hover {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n box-shadow: 0 4px 12px rgba(245, 158, 11, 0.35);\n}\n\n.action-btn-danger {\n color: #dc2626;\n border-color: #fecaca;\n}\n\n.action-btn-danger:hover {\n background: #fef2f2;\n border-color: #dc2626;\n}\n\n/* ============================================================================\n LIST VIEW\n ============================================================================ */\n.configurations-list {\n background: white;\n border-radius: 16px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06);\n border: 1px solid #e5e7eb;\n overflow: hidden;\n}\n\n.configurations-table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.configurations-table thead {\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-bottom: 2px solid #e5e7eb;\n}\n\n.configurations-table th {\n padding: 14px 20px;\n text-align: left;\n font-size: 12px;\n font-weight: 700;\n color: #475569;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n cursor: pointer;\n user-select: none;\n transition: all 0.2s ease;\n}\n\n.configurations-table th:hover {\n background: #e2e8f0;\n color: #6366f1;\n}\n\n.configurations-table th:last-child {\n cursor: default;\n}\n\n.configurations-table th:last-child:hover {\n background: transparent;\n color: #475569;\n}\n\n.configurations-table th.sorted {\n color: #6366f1;\n background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 100%);\n}\n\n.configurations-table th.sorted.desc .sort-icon {\n transform: rotate(180deg);\n}\n\n.configurations-table .sort-header {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.configurations-table .sort-icon {\n font-size: 10px;\n opacity: 0;\n transition: all 0.2s ease;\n}\n\n.configurations-table th:hover .sort-icon {\n opacity: 0.5;\n}\n\n.configurations-table th.sorted .sort-icon {\n opacity: 1;\n color: #6366f1;\n}\n\n.configurations-table tbody tr {\n border-bottom: 1px solid #f1f5f9;\n transition: background 0.2s ease;\n}\n\n.configurations-table tbody tr:hover {\n background: #fafbfc;\n}\n\n.configurations-table tbody tr:last-child {\n border-bottom: none;\n}\n\n.configurations-table td {\n padding: 18px 20px;\n font-size: 14px;\n color: #475569;\n}\n\n.config-name-cell {\n display: flex;\n align-items: center;\n gap: 14px;\n}\n\n.config-icon-small {\n width: 42px;\n height: 42px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n flex-shrink: 0;\n}\n\n.config-icon-small i {\n color: white;\n font-size: 16px;\n}\n\n.config-name-text {\n font-weight: 600;\n color: #1e293b;\n}\n\n.config-description-small {\n font-size: 13px;\n color: #64748b;\n margin-top: 4px;\n max-width: 300px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.table-actions {\n display: flex;\n gap: 8px;\n}\n\n.action-btn-small {\n background: white;\n border: 1px solid #e5e7eb;\n padding: 6px 12px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n color: #475569;\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 5px;\n}\n\n.action-btn-small:hover {\n background: #f8fafc;\n border-color: #cbd5e1;\n}\n\n.action-btn-small.primary {\n background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);\n border-color: #4f46e5;\n color: white;\n}\n\n.action-btn-small.primary:hover {\n background: linear-gradient(135deg, #4f46e5 0%, #4338ca 100%);\n}\n\n/* ============================================================================\n RESPONSIVE DESIGN\n ============================================================================ */\n@media (max-width: 1024px) {\n .configurations-grid {\n grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));\n }\n}\n\n@media (max-width: 768px) {\n .dashboard-header {\n flex-direction: column;\n gap: 16px;\n align-items: stretch;\n }\n\n .header-info {\n justify-content: space-between;\n flex-wrap: wrap;\n }\n\n .header-controls {\n justify-content: space-between;\n }\n\n .configurations-grid {\n grid-template-columns: 1fr;\n }\n\n .config-stats {\n grid-template-columns: 1fr;\n }\n\n .card-header {\n padding: 20px;\n }\n\n .config-icon {\n width: 48px;\n height: 48px;\n }\n\n .config-icon i {\n font-size: 20px;\n }\n\n .card-actions {\n flex-wrap: wrap;\n }\n}\n\n/* ============================================================================\n SPLITTER CUSTOMIZATION\n ============================================================================ */\nkendo-splitter {\n background: transparent;\n}\n\n:host ::ng-deep .k-splitter {\n border: none;\n background: transparent;\n}\n\n:host ::ng-deep .k-splitbar {\n background: #e5e7eb;\n width: 6px;\n}\n\n:host ::ng-deep .k-splitbar:hover {\n background: #c7d2fe;\n}\n\n:host ::ng-deep .k-pane {\n overflow: hidden;\n}\n\n/* ============================================================================\n DETAIL PANEL - SLIDE-IN OVERLAY\n ============================================================================ */\n\n.detail-panel-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(15, 23, 42, 0.4);\n backdrop-filter: blur(4px);\n z-index: 1000;\n animation: fadeIn 0.25s ease-out;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.detail-panel {\n position: fixed;\n top: 0;\n right: -480px;\n width: 480px;\n height: 100vh;\n background: white;\n box-shadow: -8px 0 32px rgba(0, 0, 0, 0.15);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n transition: right 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.detail-panel.visible {\n right: 0;\n}\n\n/* Detail Panel Header */\n.detail-panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 24px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-bottom: 1px solid #e2e8f0;\n flex-shrink: 0;\n}\n\n.detail-panel-title {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.detail-icon {\n width: 56px;\n height: 56px;\n border-radius: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.detail-icon i {\n color: white;\n font-size: 24px;\n}\n\n.detail-title-info h3 {\n margin: 0 0 4px 0;\n font-size: 20px;\n font-weight: 700;\n color: #1e293b;\n}\n\n.detail-subtitle {\n font-size: 13px;\n color: #64748b;\n font-weight: 500;\n}\n\n.detail-panel-close {\n background: white;\n border: 1px solid #e2e8f0;\n width: 40px;\n height: 40px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.2s ease;\n color: #64748b;\n}\n\n.detail-panel-close:hover {\n background: #f8fafc;\n border-color: #cbd5e1;\n color: #1e293b;\n}\n\n/* Detail Panel Content */\n.detail-panel-content {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n}\n\n.detail-section {\n margin-bottom: 28px;\n}\n\n.detail-section:last-child {\n margin-bottom: 0;\n}\n\n.detail-badges {\n display: flex;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.feature-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 100%);\n color: #4f46e5;\n}\n\n.feature-badge.default {\n background: linear-gradient(135deg, #ede9fe 0%, #ddd6fe 100%);\n color: #5b21b6;\n}\n\n.feature-badge i {\n font-size: 11px;\n}\n\n.detail-section-title {\n margin: 0 0 16px 0;\n font-size: 12px;\n font-weight: 700;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.detail-section-title i {\n color: #6366f1;\n font-size: 14px;\n}\n\n.detail-description {\n margin: 0;\n font-size: 14px;\n line-height: 1.7;\n color: #475569;\n}\n\n.detail-grid {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 16px;\n}\n\n.detail-grid.single-column {\n grid-template-columns: 1fr;\n}\n\n.detail-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 14px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-radius: 12px;\n border: 1px solid #e2e8f0;\n}\n\n.detail-label {\n font-size: 11px;\n font-weight: 700;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.detail-value {\n font-size: 14px;\n color: #1e293b;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.detail-value .muted {\n color: #94a3b8;\n font-style: italic;\n font-weight: 500;\n}\n\n.detail-value i {\n font-size: 13px;\n}\n\n/* Detail Params List */\n.detail-params-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.detail-param-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 14px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-radius: 10px;\n border: 1px solid #e2e8f0;\n}\n\n.detail-param-item .param-info {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.detail-param-item .param-info i {\n color: #7c3aed;\n font-size: 14px;\n}\n\n.detail-param-item .param-name {\n font-size: 13px;\n font-weight: 600;\n color: #1e293b;\n}\n\n.detail-param-item .param-value {\n font-size: 12px;\n color: #475569;\n font-family: 'SF Mono', Monaco, 'Consolas', monospace;\n background: white;\n padding: 4px 10px;\n border-radius: 6px;\n border: 1px solid #e2e8f0;\n max-width: 150px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.params-more {\n font-size: 12px;\n color: #6366f1;\n font-weight: 600;\n text-align: center;\n padding: 10px;\n background: #eef2ff;\n border-radius: 8px;\n}\n\n/* Detail Panel Actions */\n.detail-panel-actions {\n padding: 20px 24px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-top: 1px solid #e2e8f0;\n display: flex;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.detail-action-btn {\n flex: 1;\n padding: 14px 20px;\n border-radius: 12px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n}\n\n.detail-action-btn.secondary {\n background: white;\n border: 2px solid #e2e8f0;\n color: #475569;\n}\n\n.detail-action-btn.secondary:hover {\n border-color: #6366f1;\n color: #6366f1;\n background: #fafbff;\n}\n\n.detail-action-btn.primary {\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n border: 2px solid transparent;\n color: white;\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.detail-action-btn.primary:hover {\n background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);\n transform: translateY(-1px);\n box-shadow: 0 6px 16px rgba(99, 102, 241, 0.4);\n}\n\n/* Detail Panel Responsive */\n@media (max-width: 520px) {\n .detail-panel {\n width: 100%;\n right: -100%;\n }\n\n .detail-panel.visible {\n right: 0;\n }\n\n .detail-grid {\n grid-template-columns: 1fr;\n }\n}\n"] }]
|
|
969
969
|
}], () => [{ type: i1.NavigationService }, { type: i0.ChangeDetectorRef }], null); })();
|
|
970
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SystemConfigurationComponent, { className: "SystemConfigurationComponent", filePath: "src/
|
|
970
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SystemConfigurationComponent, { className: "SystemConfigurationComponent", filePath: "src/AI/components/system/system-configuration.component.ts", lineNumber: 32 }); })();
|
|
971
971
|
//# sourceMappingURL=system-configuration.component.js.map
|
|
@@ -173,5 +173,5 @@ export class KPICardComponent {
|
|
|
173
173
|
}], null, { data: [{
|
|
174
174
|
type: Input
|
|
175
175
|
}] }); })();
|
|
176
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(KPICardComponent, { className: "KPICardComponent", filePath: "src/
|
|
176
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(KPICardComponent, { className: "KPICardComponent", filePath: "src/AI/components/widgets/kpi-card.component.ts", lineNumber: 194 }); })();
|
|
177
177
|
//# sourceMappingURL=kpi-card.component.js.map
|
|
@@ -294,5 +294,5 @@ export class LiveExecutionWidgetComponent {
|
|
|
294
294
|
}], executionClick: [{
|
|
295
295
|
type: Output
|
|
296
296
|
}] }); })();
|
|
297
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(LiveExecutionWidgetComponent, { className: "LiveExecutionWidgetComponent", filePath: "src/
|
|
297
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(LiveExecutionWidgetComponent, { className: "LiveExecutionWidgetComponent", filePath: "src/AI/components/widgets/live-execution-widget.component.ts", lineNumber: 383 }); })();
|
|
298
298
|
//# sourceMappingURL=live-execution-widget.component.js.map
|
|
@@ -1058,5 +1058,5 @@ export class APIApplicationsPanelComponent {
|
|
|
1058
1058
|
type: HostListener,
|
|
1059
1059
|
args: ['document:mouseup']
|
|
1060
1060
|
}] }); })();
|
|
1061
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(APIApplicationsPanelComponent, { className: "APIApplicationsPanelComponent", filePath: "src/
|
|
1061
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(APIApplicationsPanelComponent, { className: "APIApplicationsPanelComponent", filePath: "src/APIKeys/api-applications-panel.component.ts", lineNumber: 49 }); })();
|
|
1062
1062
|
//# sourceMappingURL=api-applications-panel.component.js.map
|
|
@@ -759,5 +759,5 @@ export class APIKeyCreateDialogComponent {
|
|
|
759
759
|
type: HostListener,
|
|
760
760
|
args: ['document:keydown.escape']
|
|
761
761
|
}] }); })();
|
|
762
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(APIKeyCreateDialogComponent, { className: "APIKeyCreateDialogComponent", filePath: "src/
|
|
762
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(APIKeyCreateDialogComponent, { className: "APIKeyCreateDialogComponent", filePath: "src/APIKeys/api-key-create-dialog.component.ts", lineNumber: 40 }); })();
|
|
763
763
|
//# sourceMappingURL=api-key-create-dialog.component.js.map
|
|
@@ -1076,5 +1076,5 @@ export class APIKeyEditPanelComponent {
|
|
|
1076
1076
|
type: HostListener,
|
|
1077
1077
|
args: ['document:keydown.escape']
|
|
1078
1078
|
}] }); })();
|
|
1079
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(APIKeyEditPanelComponent, { className: "APIKeyEditPanelComponent", filePath: "src/
|
|
1079
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(APIKeyEditPanelComponent, { className: "APIKeyEditPanelComponent", filePath: "src/APIKeys/api-key-edit-panel.component.ts", lineNumber: 42 }); })();
|
|
1080
1080
|
//# sourceMappingURL=api-key-edit-panel.component.js.map
|
|
@@ -813,5 +813,5 @@ export class APIKeyListComponent {
|
|
|
813
813
|
}], CreateRequested: [{
|
|
814
814
|
type: Output
|
|
815
815
|
}] }); })();
|
|
816
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(APIKeyListComponent, { className: "APIKeyListComponent", filePath: "src/
|
|
816
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(APIKeyListComponent, { className: "APIKeyListComponent", filePath: "src/APIKeys/api-key-list.component.ts", lineNumber: 32 }); })();
|
|
817
817
|
//# sourceMappingURL=api-key-list.component.js.map
|
|
@@ -1138,5 +1138,5 @@ export { APIKeysResourceComponent };
|
|
|
1138
1138
|
type: ViewChild,
|
|
1139
1139
|
args: ['keyList']
|
|
1140
1140
|
}] }); })();
|
|
1141
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(APIKeysResourceComponent, { className: "APIKeysResourceComponent", filePath: "src/
|
|
1141
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(APIKeysResourceComponent, { className: "APIKeysResourceComponent", filePath: "src/APIKeys/api-keys-resource.component.ts", lineNumber: 52 }); })();
|
|
1142
1142
|
//# sourceMappingURL=api-keys-resource.component.js.map
|