@memberjunction/ng-dashboards 3.4.0 → 4.1.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.d.ts +12 -5
- package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-configuration.component.js +103 -44
- package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.d.ts +14 -5
- package/dist/AI/components/agents/agent-editor.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.js +149 -211
- package/dist/AI/components/agents/agent-editor.component.js.map +1 -1
- package/dist/AI/components/agents/agent-filter-panel.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-filter-panel.component.js +4 -4
- package/dist/AI/components/agents/agent-filter-panel.component.js.map +1 -1
- package/dist/AI/components/charts/performance-heatmap.component.d.ts.map +1 -1
- package/dist/AI/components/charts/performance-heatmap.component.js +4 -6
- package/dist/AI/components/charts/performance-heatmap.component.js.map +1 -1
- package/dist/AI/components/charts/time-series-chart.component.d.ts.map +1 -1
- package/dist/AI/components/charts/time-series-chart.component.js +6 -7
- package/dist/AI/components/charts/time-series-chart.component.js.map +1 -1
- package/dist/AI/components/execution-monitoring.component.d.ts +0 -4
- package/dist/AI/components/execution-monitoring.component.d.ts.map +1 -1
- package/dist/AI/components/execution-monitoring.component.js +33 -37
- package/dist/AI/components/execution-monitoring.component.js.map +1 -1
- package/dist/AI/components/models/model-management.component.d.ts +3 -6
- package/dist/AI/components/models/model-management.component.d.ts.map +1 -1
- package/dist/AI/components/models/model-management.component.js +34 -27
- package/dist/AI/components/models/model-management.component.js.map +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +22 -17
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-filter-panel.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/prompt-filter-panel.component.js +4 -4
- package/dist/AI/components/prompts/prompt-filter-panel.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-management.component.d.ts +3 -6
- package/dist/AI/components/prompts/prompt-management.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/prompt-management.component.js +34 -32
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-version-control.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/prompt-version-control.component.js +33 -28
- package/dist/AI/components/prompts/prompt-version-control.component.js.map +1 -1
- package/dist/AI/components/system/system-config-filter-panel.component.d.ts.map +1 -1
- package/dist/AI/components/system/system-config-filter-panel.component.js +4 -4
- package/dist/AI/components/system/system-config-filter-panel.component.js.map +1 -1
- package/dist/AI/components/system/system-configuration.component.d.ts +0 -4
- package/dist/AI/components/system/system-configuration.component.d.ts.map +1 -1
- package/dist/AI/components/system/system-configuration.component.js +26 -27
- package/dist/AI/components/system/system-configuration.component.js.map +1 -1
- package/dist/AI/components/widgets/kpi-card.component.d.ts.map +1 -1
- package/dist/AI/components/widgets/kpi-card.component.js +52 -42
- package/dist/AI/components/widgets/kpi-card.component.js.map +1 -1
- package/dist/AI/components/widgets/live-execution-widget.component.d.ts.map +1 -1
- package/dist/AI/components/widgets/live-execution-widget.component.js +7 -7
- package/dist/AI/components/widgets/live-execution-widget.component.js.map +1 -1
- package/dist/APIKeys/api-applications-panel.component.d.ts +0 -2
- package/dist/APIKeys/api-applications-panel.component.d.ts.map +1 -1
- package/dist/APIKeys/api-applications-panel.component.js +193 -189
- package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
- package/dist/APIKeys/api-key-create-dialog.component.d.ts +0 -2
- package/dist/APIKeys/api-key-create-dialog.component.d.ts.map +1 -1
- package/dist/APIKeys/api-key-create-dialog.component.js +175 -180
- package/dist/APIKeys/api-key-create-dialog.component.js.map +1 -1
- package/dist/APIKeys/api-key-edit-panel.component.d.ts +0 -2
- package/dist/APIKeys/api-key-edit-panel.component.d.ts.map +1 -1
- package/dist/APIKeys/api-key-edit-panel.component.js +231 -225
- package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -1
- package/dist/APIKeys/api-key-list.component.d.ts +0 -2
- package/dist/APIKeys/api-key-list.component.d.ts.map +1 -1
- package/dist/APIKeys/api-key-list.component.js +113 -114
- package/dist/APIKeys/api-key-list.component.js.map +1 -1
- package/dist/APIKeys/api-keys-resource.component.d.ts +0 -2
- package/dist/APIKeys/api-keys-resource.component.d.ts.map +1 -1
- package/dist/APIKeys/api-keys-resource.component.js +294 -302
- package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
- package/dist/APIKeys/api-scopes-panel.component.d.ts +0 -2
- package/dist/APIKeys/api-scopes-panel.component.d.ts.map +1 -1
- package/dist/APIKeys/api-scopes-panel.component.js +151 -155
- package/dist/APIKeys/api-scopes-panel.component.js.map +1 -1
- package/dist/APIKeys/api-usage-panel.component.d.ts +0 -2
- package/dist/APIKeys/api-usage-panel.component.d.ts.map +1 -1
- package/dist/APIKeys/api-usage-panel.component.js +237 -234
- package/dist/APIKeys/api-usage-panel.component.js.map +1 -1
- package/dist/Actions/components/actions-list-view.component.d.ts.map +1 -1
- package/dist/Actions/components/actions-list-view.component.js +15 -14
- package/dist/Actions/components/actions-list-view.component.js.map +1 -1
- package/dist/Actions/components/actions-overview.component.d.ts +3 -6
- package/dist/Actions/components/actions-overview.component.d.ts.map +1 -1
- package/dist/Actions/components/actions-overview.component.js +17 -19
- package/dist/Actions/components/actions-overview.component.js.map +1 -1
- package/dist/Actions/components/categories-list-view.component.d.ts.map +1 -1
- package/dist/Actions/components/categories-list-view.component.js +6 -6
- package/dist/Actions/components/categories-list-view.component.js.map +1 -1
- package/dist/Actions/components/code-management.component.d.ts +0 -4
- package/dist/Actions/components/code-management.component.d.ts.map +1 -1
- package/dist/Actions/components/code-management.component.js +3 -9
- package/dist/Actions/components/code-management.component.js.map +1 -1
- package/dist/Actions/components/entity-integration.component.d.ts +0 -4
- package/dist/Actions/components/entity-integration.component.d.ts.map +1 -1
- package/dist/Actions/components/entity-integration.component.js +3 -9
- package/dist/Actions/components/entity-integration.component.js.map +1 -1
- package/dist/Actions/components/execution-monitoring.component.d.ts +3 -6
- package/dist/Actions/components/execution-monitoring.component.d.ts.map +1 -1
- package/dist/Actions/components/execution-monitoring.component.js +13 -16
- package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
- package/dist/Actions/components/executions-list-view.component.d.ts.map +1 -1
- package/dist/Actions/components/executions-list-view.component.js +3 -3
- package/dist/Actions/components/executions-list-view.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-breadcrumb.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/action-breadcrumb.component.js +6 -6
- package/dist/Actions/components/explorer/action-breadcrumb.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-card.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/action-card.component.js +11 -10
- package/dist/Actions/components/explorer/action-card.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.d.ts +0 -4
- package/dist/Actions/components/explorer/action-explorer.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.js +10 -14
- package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-list-item.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/action-list-item.component.js +8 -8
- package/dist/Actions/components/explorer/action-list-item.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-toolbar.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/action-toolbar.component.js +15 -14
- package/dist/Actions/components/explorer/action-toolbar.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-tree-panel.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/action-tree-panel.component.js +11 -10
- package/dist/Actions/components/explorer/action-tree-panel.component.js.map +1 -1
- package/dist/Actions/components/explorer/index.d.ts +0 -1
- package/dist/Actions/components/explorer/index.d.ts.map +1 -1
- package/dist/Actions/components/explorer/index.js +0 -4
- package/dist/Actions/components/explorer/index.js.map +1 -1
- package/dist/Actions/components/explorer/new-action-panel.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/new-action-panel.component.js +10 -10
- package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -1
- package/dist/Actions/components/explorer/new-category-panel.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/new-category-panel.component.js +8 -8
- package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -1
- package/dist/Actions/components/scheduled-actions.component.d.ts +0 -4
- package/dist/Actions/components/scheduled-actions.component.d.ts.map +1 -1
- package/dist/Actions/components/scheduled-actions.component.js +3 -9
- package/dist/Actions/components/scheduled-actions.component.js.map +1 -1
- package/dist/Actions/components/security-permissions.component.d.ts +0 -4
- package/dist/Actions/components/security-permissions.component.d.ts.map +1 -1
- package/dist/Actions/components/security-permissions.component.js +3 -9
- package/dist/Actions/components/security-permissions.component.js.map +1 -1
- package/dist/Actions/index.d.ts +0 -7
- package/dist/Actions/index.d.ts.map +1 -1
- package/dist/Actions/index.js +0 -8
- package/dist/Actions/index.js.map +1 -1
- package/dist/Communication/communication-dashboard.component.d.ts +0 -1
- package/dist/Communication/communication-dashboard.component.d.ts.map +1 -1
- package/dist/Communication/communication-dashboard.component.js +38 -51
- package/dist/Communication/communication-dashboard.component.js.map +1 -1
- package/dist/Communication/communication-logs-resource.component.d.ts +0 -4
- package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-logs-resource.component.js +112 -108
- package/dist/Communication/communication-logs-resource.component.js.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.d.ts +0 -4
- package/dist/Communication/communication-monitor-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.js +210 -201
- package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
- package/dist/Communication/communication-providers-resource.component.d.ts +0 -4
- package/dist/Communication/communication-providers-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-providers-resource.component.js +136 -124
- package/dist/Communication/communication-providers-resource.component.js.map +1 -1
- package/dist/Communication/communication-runs-resource.component.d.ts +0 -4
- package/dist/Communication/communication-runs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-runs-resource.component.js +91 -88
- package/dist/Communication/communication-runs-resource.component.js.map +1 -1
- package/dist/Communication/communication-templates-resource.component.d.ts +0 -4
- package/dist/Communication/communication-templates-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-templates-resource.component.js +139 -122
- package/dist/Communication/communication-templates-resource.component.js.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts +0 -4
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +21 -20
- package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +11 -12
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js +25 -22
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +16 -16
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/browser/component-browser.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/browser/component-browser.component.js +23 -21
- package/dist/ComponentStudio/components/browser/component-browser.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js +10 -10
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +13 -13
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/requirements-editor.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js +7 -7
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/spec-editor.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/editors/spec-editor.component.js +5 -5
- package/dist/ComponentStudio/components/editors/spec-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js +4 -4
- package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js +9 -9
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/text-import-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/text-import-dialog.component.js +4 -4
- package/dist/ComponentStudio/components/text-import-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/workspace/component-preview.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/workspace/component-preview.component.js +10 -9
- package/dist/ComponentStudio/components/workspace/component-preview.component.js.map +1 -1
- package/dist/ComponentStudio/components/workspace/editor-tabs.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/workspace/editor-tabs.component.js +4 -4
- package/dist/ComponentStudio/components/workspace/editor-tabs.component.js.map +1 -1
- package/dist/Credentials/components/credentials-audit-resource.component.d.ts +0 -1
- package/dist/Credentials/components/credentials-audit-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-audit-resource.component.js +200 -196
- package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.d.ts +0 -1
- package/dist/Credentials/components/credentials-categories-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.js +195 -190
- package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.d.ts +0 -1
- package/dist/Credentials/components/credentials-list-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +251 -240
- package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-overview-resource.component.d.ts +0 -1
- package/dist/Credentials/components/credentials-overview-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-overview-resource.component.js +228 -226
- package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.d.ts +0 -1
- package/dist/Credentials/components/credentials-types-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +214 -210
- package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
- package/dist/Credentials/credentials-dashboard.component.d.ts +0 -1
- package/dist/Credentials/credentials-dashboard.component.d.ts.map +1 -1
- package/dist/Credentials/credentials-dashboard.component.js +31 -44
- package/dist/Credentials/credentials-dashboard.component.js.map +1 -1
- package/dist/Credentials/pipes/group-by.pipe.d.ts.map +1 -1
- package/dist/Credentials/pipes/group-by.pipe.js +2 -1
- package/dist/Credentials/pipes/group-by.pipe.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts +0 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +73 -80
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-share-dialog.component.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js +46 -45
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js.map +1 -1
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.d.ts.map +1 -1
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +7 -7
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js.map +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts.map +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +15 -15
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js.map +1 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts.map +1 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.js +17 -11
- package/dist/DataExplorer/components/view-selector/view-selector.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +2 -4
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +83 -64
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.d.ts +0 -1
- package/dist/DataExplorer/data-explorer-resource.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.js +3 -6
- package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -1
- package/dist/DataExplorer/index.d.ts +2 -2
- package/dist/DataExplorer/index.d.ts.map +1 -1
- package/dist/DataExplorer/index.js +2 -2
- package/dist/DataExplorer/index.js.map +1 -1
- package/dist/EntityAdmin/entity-admin-dashboard.component.d.ts +0 -1
- package/dist/EntityAdmin/entity-admin-dashboard.component.d.ts.map +1 -1
- package/dist/EntityAdmin/entity-admin-dashboard.component.js +6 -7
- package/dist/EntityAdmin/entity-admin-dashboard.component.js.map +1 -1
- package/dist/Home/home-application.d.ts +109 -27
- package/dist/Home/home-application.d.ts.map +1 -1
- package/dist/Home/home-application.js +351 -75
- package/dist/Home/home-application.js.map +1 -1
- package/dist/Home/home-dashboard.component.d.ts +48 -12
- package/dist/Home/home-dashboard.component.d.ts.map +1 -1
- package/dist/Home/home-dashboard.component.js +267 -187
- package/dist/Home/home-dashboard.component.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.d.ts +0 -1
- package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +761 -685
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-categories-resource.component.d.ts +0 -1
- package/dist/Lists/components/lists-categories-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-categories-resource.component.js +340 -316
- package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.d.ts +0 -1
- package/dist/Lists/components/lists-my-lists-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +530 -482
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-operations-resource.component.d.ts +0 -1
- package/dist/Lists/components/lists-operations-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-operations-resource.component.js +508 -455
- package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
- package/dist/Lists/components/venn-diagram/venn-diagram.component.d.ts.map +1 -1
- package/dist/Lists/components/venn-diagram/venn-diagram.component.js +44 -39
- package/dist/Lists/components/venn-diagram/venn-diagram.component.js.map +1 -1
- package/dist/Lists/index.d.ts +0 -1
- package/dist/Lists/index.d.ts.map +1 -1
- package/dist/Lists/index.js +0 -11
- package/dist/Lists/index.js.map +1 -1
- package/dist/MCP/components/mcp-connection-dialog.component.d.ts +0 -4
- package/dist/MCP/components/mcp-connection-dialog.component.d.ts.map +1 -1
- package/dist/MCP/components/mcp-connection-dialog.component.js +33 -39
- package/dist/MCP/components/mcp-connection-dialog.component.js.map +1 -1
- package/dist/MCP/components/mcp-log-detail-panel.component.d.ts +0 -4
- package/dist/MCP/components/mcp-log-detail-panel.component.d.ts.map +1 -1
- package/dist/MCP/components/mcp-log-detail-panel.component.js +42 -44
- package/dist/MCP/components/mcp-log-detail-panel.component.js.map +1 -1
- package/dist/MCP/components/mcp-server-dialog.component.d.ts +3 -4
- package/dist/MCP/components/mcp-server-dialog.component.d.ts.map +1 -1
- package/dist/MCP/components/mcp-server-dialog.component.js +186 -77
- package/dist/MCP/components/mcp-server-dialog.component.js.map +1 -1
- package/dist/MCP/components/mcp-test-tool-dialog.component.d.ts +0 -4
- package/dist/MCP/components/mcp-test-tool-dialog.component.d.ts.map +1 -1
- package/dist/MCP/components/mcp-test-tool-dialog.component.js +187 -187
- package/dist/MCP/components/mcp-test-tool-dialog.component.js.map +1 -1
- package/dist/MCP/index.d.ts +5 -5
- package/dist/MCP/index.d.ts.map +1 -1
- package/dist/MCP/index.js +5 -5
- package/dist/MCP/index.js.map +1 -1
- package/dist/MCP/mcp-dashboard.component.d.ts +65 -7
- package/dist/MCP/mcp-dashboard.component.d.ts.map +1 -1
- package/dist/MCP/mcp-dashboard.component.js +976 -697
- package/dist/MCP/mcp-dashboard.component.js.map +1 -1
- package/dist/MCP/mcp-filter-panel.component.d.ts +54 -0
- package/dist/MCP/mcp-filter-panel.component.d.ts.map +1 -0
- package/dist/MCP/mcp-filter-panel.component.js +288 -0
- package/dist/MCP/mcp-filter-panel.component.js.map +1 -0
- package/dist/MCP/mcp-resource.component.d.ts +11 -5
- package/dist/MCP/mcp-resource.component.d.ts.map +1 -1
- package/dist/MCP/mcp-resource.component.js +8 -9
- package/dist/MCP/mcp-resource.component.js.map +1 -1
- package/dist/MCP/mcp.module.d.ts +16 -19
- package/dist/MCP/mcp.module.d.ts.map +1 -1
- package/dist/MCP/mcp.module.js +17 -26
- package/dist/MCP/mcp.module.js.map +1 -1
- package/dist/MCP/services/mcp-tools.service.d.ts +10 -4
- package/dist/MCP/services/mcp-tools.service.d.ts.map +1 -1
- package/dist/MCP/services/mcp-tools.service.js +5 -6
- package/dist/MCP/services/mcp-tools.service.js.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.d.ts +0 -1
- package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js +79 -88
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/Scheduling/components/job-slideout.component.d.ts.map +1 -1
- package/dist/Scheduling/components/job-slideout.component.js +117 -116
- package/dist/Scheduling/components/job-slideout.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-activity-resource.component.d.ts +0 -4
- package/dist/Scheduling/components/scheduling-activity-resource.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-activity-resource.component.js +3 -9
- package/dist/Scheduling/components/scheduling-activity-resource.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-activity.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-activity.component.js +134 -134
- package/dist/Scheduling/components/scheduling-activity.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs-resource.component.d.ts +0 -4
- package/dist/Scheduling/components/scheduling-jobs-resource.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs-resource.component.js +3 -9
- package/dist/Scheduling/components/scheduling-jobs-resource.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs.component.js +102 -97
- package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-overview-resource.component.d.ts +0 -4
- package/dist/Scheduling/components/scheduling-overview-resource.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-overview-resource.component.js +3 -9
- package/dist/Scheduling/components/scheduling-overview-resource.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-overview.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-overview.component.js +127 -122
- package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
- package/dist/Scheduling/scheduling-dashboard.component.d.ts +0 -1
- package/dist/Scheduling/scheduling-dashboard.component.d.ts.map +1 -1
- package/dist/Scheduling/scheduling-dashboard.component.js +35 -43
- package/dist/Scheduling/scheduling-dashboard.component.js.map +1 -1
- package/dist/SystemDiagnostics/system-diagnostics.component.d.ts +0 -4
- package/dist/SystemDiagnostics/system-diagnostics.component.d.ts.map +1 -1
- package/dist/SystemDiagnostics/system-diagnostics.component.js +1552 -1534
- package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
- package/dist/Testing/components/testing-analytics-resource.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-analytics-resource.component.js +3 -3
- package/dist/Testing/components/testing-analytics-resource.component.js.map +1 -1
- package/dist/Testing/components/testing-analytics.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-analytics.component.js +30 -30
- package/dist/Testing/components/testing-analytics.component.js.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab-resource.component.js +3 -3
- package/dist/Testing/components/testing-dashboard-tab-resource.component.js.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab.component.js +7 -7
- package/dist/Testing/components/testing-dashboard-tab.component.js.map +1 -1
- package/dist/Testing/components/testing-explorer-resource.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-explorer-resource.component.js +3 -3
- package/dist/Testing/components/testing-explorer-resource.component.js.map +1 -1
- package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-explorer.component.js +42 -35
- package/dist/Testing/components/testing-explorer.component.js.map +1 -1
- package/dist/Testing/components/testing-review-resource.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-review-resource.component.js +3 -3
- package/dist/Testing/components/testing-review-resource.component.js.map +1 -1
- package/dist/Testing/components/testing-review.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-review.component.js +16 -16
- package/dist/Testing/components/testing-review.component.js.map +1 -1
- package/dist/Testing/components/testing-runs-resource.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-runs-resource.component.js +3 -3
- package/dist/Testing/components/testing-runs-resource.component.js.map +1 -1
- package/dist/Testing/components/testing-runs.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-runs.component.js +15 -15
- package/dist/Testing/components/testing-runs.component.js.map +1 -1
- package/dist/Testing/components/widgets/oracle-breakdown-table.component.d.ts.map +1 -1
- package/dist/Testing/components/widgets/oracle-breakdown-table.component.js +73 -61
- package/dist/Testing/components/widgets/oracle-breakdown-table.component.js.map +1 -1
- package/dist/Testing/components/widgets/suite-tree.component.d.ts.map +1 -1
- package/dist/Testing/components/widgets/suite-tree.component.js +34 -31
- package/dist/Testing/components/widgets/suite-tree.component.js.map +1 -1
- package/dist/Testing/components/widgets/test-run-detail-panel.component.d.ts.map +1 -1
- package/dist/Testing/components/widgets/test-run-detail-panel.component.js +180 -171
- package/dist/Testing/components/widgets/test-run-detail-panel.component.js.map +1 -1
- package/dist/Testing/testing-dashboard.component.d.ts +0 -1
- package/dist/Testing/testing-dashboard.component.d.ts.map +1 -1
- package/dist/Testing/testing-dashboard.component.js +9 -8
- package/dist/Testing/testing-dashboard.component.js.map +1 -1
- package/dist/VersionHistory/components/diff-resource.component.d.ts +119 -0
- package/dist/VersionHistory/components/diff-resource.component.d.ts.map +1 -0
- package/dist/VersionHistory/components/diff-resource.component.js +1162 -0
- package/dist/VersionHistory/components/diff-resource.component.js.map +1 -0
- package/dist/VersionHistory/components/graph-resource.component.d.ts +67 -0
- package/dist/VersionHistory/components/graph-resource.component.d.ts.map +1 -0
- package/dist/VersionHistory/components/graph-resource.component.js +521 -0
- package/dist/VersionHistory/components/graph-resource.component.js.map +1 -0
- package/dist/VersionHistory/components/index.d.ts +5 -0
- package/dist/VersionHistory/components/index.d.ts.map +1 -0
- package/dist/VersionHistory/components/index.js +5 -0
- package/dist/VersionHistory/components/index.js.map +1 -0
- package/dist/VersionHistory/components/labels-resource.component.d.ts +89 -0
- package/dist/VersionHistory/components/labels-resource.component.d.ts.map +1 -0
- package/dist/VersionHistory/components/labels-resource.component.js +968 -0
- package/dist/VersionHistory/components/labels-resource.component.js.map +1 -0
- package/dist/VersionHistory/components/restore-resource.component.d.ts +40 -0
- package/dist/VersionHistory/components/restore-resource.component.d.ts.map +1 -0
- package/dist/VersionHistory/components/restore-resource.component.js +472 -0
- package/dist/VersionHistory/components/restore-resource.component.js.map +1 -0
- package/dist/VersionHistory/index.d.ts +2 -0
- package/dist/VersionHistory/index.d.ts.map +1 -0
- package/dist/VersionHistory/index.js +2 -0
- package/dist/VersionHistory/index.js.map +1 -0
- package/dist/module.d.ts +42 -36
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +41 -7
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +20 -19
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +22 -120
- package/dist/public-api.js.map +1 -1
- package/dist/shared/pipes/highlight-search.pipe.d.ts.map +1 -1
- package/dist/shared/pipes/highlight-search.pipe.js +2 -1
- package/dist/shared/pipes/highlight-search.pipe.js.map +1 -1
- package/package.json +64 -62
|
@@ -20,23 +20,23 @@ import * as i6 from "./api-applications-panel.component";
|
|
|
20
20
|
import * as i7 from "./api-scopes-panel.component";
|
|
21
21
|
import * as i8 from "./api-usage-panel.component";
|
|
22
22
|
const _c0 = ["keyList"];
|
|
23
|
-
function
|
|
24
|
-
i0.ɵɵelement(0, "mj-loading",
|
|
23
|
+
function APIKeysResourceComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
24
|
+
i0.ɵɵelement(0, "mj-loading", 2);
|
|
25
25
|
} }
|
|
26
|
-
function
|
|
26
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
27
27
|
const _r4 = i0.ɵɵgetCurrentView();
|
|
28
|
-
i0.ɵɵelementStart(0, "button",
|
|
29
|
-
i0.ɵɵlistener("click", function
|
|
30
|
-
i0.ɵɵelement(1, "i",
|
|
28
|
+
i0.ɵɵelementStart(0, "button", 76);
|
|
29
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.openCreateDialog()); });
|
|
30
|
+
i0.ɵɵelement(1, "i", 77);
|
|
31
31
|
i0.ɵɵelementStart(2, "span");
|
|
32
32
|
i0.ɵɵtext(3, "Generate New Key");
|
|
33
33
|
i0.ɵɵelementEnd()();
|
|
34
34
|
} }
|
|
35
|
-
function
|
|
35
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_22_Template(rf, ctx) { if (rf & 1) {
|
|
36
36
|
const _r5 = i0.ɵɵgetCurrentView();
|
|
37
|
-
i0.ɵɵelementStart(0, "span",
|
|
38
|
-
i0.ɵɵlistener("click", function
|
|
39
|
-
i0.ɵɵelement(1, "i",
|
|
37
|
+
i0.ɵɵelementStart(0, "span", 78);
|
|
38
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_22_Template_span_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.showListView("expired")); });
|
|
39
|
+
i0.ɵɵelement(1, "i", 79);
|
|
40
40
|
i0.ɵɵtext(2);
|
|
41
41
|
i0.ɵɵelementEnd();
|
|
42
42
|
} if (rf & 2) {
|
|
@@ -44,11 +44,11 @@ function APIKeysResourceComponent_ng_container_2_ng_container_32_ng_container_1_
|
|
|
44
44
|
i0.ɵɵadvance(2);
|
|
45
45
|
i0.ɵɵtextInterpolate1(" ", ctx_r1.ExpiredKeys, " expired ");
|
|
46
46
|
} }
|
|
47
|
-
function
|
|
47
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_23_Template(rf, ctx) { if (rf & 1) {
|
|
48
48
|
const _r6 = i0.ɵɵgetCurrentView();
|
|
49
|
-
i0.ɵɵelementStart(0, "span",
|
|
50
|
-
i0.ɵɵlistener("click", function
|
|
51
|
-
i0.ɵɵelement(1, "i",
|
|
49
|
+
i0.ɵɵelementStart(0, "span", 80);
|
|
50
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_23_Template_span_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.showListView("expiring")); });
|
|
51
|
+
i0.ɵɵelement(1, "i", 55);
|
|
52
52
|
i0.ɵɵtext(2);
|
|
53
53
|
i0.ɵɵelementEnd();
|
|
54
54
|
} if (rf & 2) {
|
|
@@ -56,11 +56,11 @@ function APIKeysResourceComponent_ng_container_2_ng_container_32_ng_container_1_
|
|
|
56
56
|
i0.ɵɵadvance(2);
|
|
57
57
|
i0.ɵɵtextInterpolate1(" ", ctx_r1.ExpiringSoonCount, " expiring soon ");
|
|
58
58
|
} }
|
|
59
|
-
function
|
|
59
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_24_Template(rf, ctx) { if (rf & 1) {
|
|
60
60
|
const _r7 = i0.ɵɵgetCurrentView();
|
|
61
|
-
i0.ɵɵelementStart(0, "span",
|
|
62
|
-
i0.ɵɵlistener("click", function
|
|
63
|
-
i0.ɵɵelement(1, "i",
|
|
61
|
+
i0.ɵɵelementStart(0, "span", 81);
|
|
62
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_24_Template_span_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.showListView("never-used")); });
|
|
63
|
+
i0.ɵɵelement(1, "i", 82);
|
|
64
64
|
i0.ɵɵtext(2);
|
|
65
65
|
i0.ɵɵelementEnd();
|
|
66
66
|
} if (rf & 2) {
|
|
@@ -68,37 +68,37 @@ function APIKeysResourceComponent_ng_container_2_ng_container_32_ng_container_1_
|
|
|
68
68
|
i0.ɵɵadvance(2);
|
|
69
69
|
i0.ɵɵtextInterpolate1(" ", ctx_r1.NeverUsedKeys, " never used ");
|
|
70
70
|
} }
|
|
71
|
-
function
|
|
72
|
-
i0.ɵɵelementStart(0, "span",
|
|
73
|
-
i0.ɵɵelement(1, "i",
|
|
71
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_25_Template(rf, ctx) { if (rf & 1) {
|
|
72
|
+
i0.ɵɵelementStart(0, "span", 42);
|
|
73
|
+
i0.ɵɵelement(1, "i", 52);
|
|
74
74
|
i0.ɵɵtext(2, " All keys healthy ");
|
|
75
75
|
i0.ɵɵelementEnd();
|
|
76
76
|
} }
|
|
77
|
-
function
|
|
78
|
-
i0.ɵɵelementStart(0, "div",
|
|
79
|
-
i0.ɵɵelement(1, "i",
|
|
77
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_56_Template(rf, ctx) { if (rf & 1) {
|
|
78
|
+
i0.ɵɵelementStart(0, "div", 56);
|
|
79
|
+
i0.ɵɵelement(1, "i", 50);
|
|
80
80
|
i0.ɵɵelementEnd();
|
|
81
81
|
} }
|
|
82
|
-
function
|
|
82
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_84_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
83
83
|
const _r8 = i0.ɵɵgetCurrentView();
|
|
84
|
-
i0.ɵɵelementStart(0, "div",
|
|
85
|
-
i0.ɵɵlistener("click", function
|
|
86
|
-
i0.ɵɵelementStart(1, "div",
|
|
87
|
-
i0.ɵɵelement(2, "i",
|
|
84
|
+
i0.ɵɵelementStart(0, "div", 84);
|
|
85
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_84_For_2_Template_div_click_0_listener() { const key_r9 = i0.ɵɵrestoreView(_r8).$implicit; const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.openEditPanel(key_r9)); });
|
|
86
|
+
i0.ɵɵelementStart(1, "div", 85);
|
|
87
|
+
i0.ɵɵelement(2, "i", 8);
|
|
88
88
|
i0.ɵɵelementEnd();
|
|
89
|
-
i0.ɵɵelementStart(3, "div",
|
|
89
|
+
i0.ɵɵelementStart(3, "div", 86)(4, "div", 87);
|
|
90
90
|
i0.ɵɵtext(5);
|
|
91
91
|
i0.ɵɵelementEnd();
|
|
92
|
-
i0.ɵɵelementStart(6, "div",
|
|
92
|
+
i0.ɵɵelementStart(6, "div", 88)(7, "span", 89);
|
|
93
93
|
i0.ɵɵtext(8);
|
|
94
94
|
i0.ɵɵelementEnd();
|
|
95
|
-
i0.ɵɵelementStart(9, "span",
|
|
95
|
+
i0.ɵɵelementStart(9, "span", 90);
|
|
96
96
|
i0.ɵɵtext(10);
|
|
97
97
|
i0.ɵɵelementEnd()()();
|
|
98
|
-
i0.ɵɵelementStart(11, "div",
|
|
98
|
+
i0.ɵɵelementStart(11, "div", 91)(12, "div", 92);
|
|
99
99
|
i0.ɵɵtext(13);
|
|
100
100
|
i0.ɵɵelementEnd();
|
|
101
|
-
i0.ɵɵelementStart(14, "div",
|
|
101
|
+
i0.ɵɵelementStart(14, "div", 93);
|
|
102
102
|
i0.ɵɵtext(15);
|
|
103
103
|
i0.ɵɵelementEnd()()();
|
|
104
104
|
} if (rf & 2) {
|
|
@@ -111,7 +111,7 @@ function APIKeysResourceComponent_ng_container_2_ng_container_32_ng_container_1_
|
|
|
111
111
|
i0.ɵɵadvance(3);
|
|
112
112
|
i0.ɵɵtextInterpolate(key_r9.User);
|
|
113
113
|
i0.ɵɵadvance(2);
|
|
114
|
-
i0.ɵɵtextInterpolate1("...", key_r9.Hash.slice(-8)
|
|
114
|
+
i0.ɵɵtextInterpolate1("...", key_r9.Hash.slice(-8));
|
|
115
115
|
i0.ɵɵadvance(3);
|
|
116
116
|
i0.ɵɵtextInterpolate(ctx_r1.formatDate(key_r9.LastUsedAt));
|
|
117
117
|
i0.ɵɵadvance();
|
|
@@ -119,50 +119,50 @@ function APIKeysResourceComponent_ng_container_2_ng_container_32_ng_container_1_
|
|
|
119
119
|
i0.ɵɵadvance();
|
|
120
120
|
i0.ɵɵtextInterpolate1(" ", ctx_r1.formatExpiration(key_r9.ExpiresAt), " ");
|
|
121
121
|
} }
|
|
122
|
-
function
|
|
123
|
-
i0.ɵɵelementStart(0, "div",
|
|
124
|
-
i0.ɵɵ
|
|
122
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_84_Template(rf, ctx) { if (rf & 1) {
|
|
123
|
+
i0.ɵɵelementStart(0, "div", 64);
|
|
124
|
+
i0.ɵɵrepeaterCreate(1, APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_84_For_2_Template, 16, 8, "div", 83, i0.ɵɵrepeaterTrackByIdentity);
|
|
125
125
|
i0.ɵɵelementEnd();
|
|
126
126
|
} if (rf & 2) {
|
|
127
127
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
128
128
|
i0.ɵɵadvance();
|
|
129
|
-
i0.ɵɵ
|
|
129
|
+
i0.ɵɵrepeater(ctx_r1.TopUsedKeys);
|
|
130
130
|
} }
|
|
131
|
-
function
|
|
132
|
-
i0.ɵɵelementStart(0, "div",
|
|
133
|
-
i0.ɵɵelement(1, "i",
|
|
131
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_85_Template(rf, ctx) { if (rf & 1) {
|
|
132
|
+
i0.ɵɵelementStart(0, "div", 65);
|
|
133
|
+
i0.ɵɵelement(1, "i", 8);
|
|
134
134
|
i0.ɵɵelementStart(2, "span");
|
|
135
135
|
i0.ɵɵtext(3, "No active keys with recent usage");
|
|
136
136
|
i0.ɵɵelementEnd()();
|
|
137
137
|
} }
|
|
138
|
-
function
|
|
138
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_95_For_5_Template(rf, ctx) { if (rf & 1) {
|
|
139
139
|
const _r10 = i0.ɵɵgetCurrentView();
|
|
140
140
|
i0.ɵɵnamespaceSVG();
|
|
141
141
|
i0.ɵɵelementContainerStart(0);
|
|
142
|
-
i0.ɵɵelementStart(1, "circle",
|
|
143
|
-
i0.ɵɵlistener("click", function
|
|
142
|
+
i0.ɵɵelementStart(1, "circle", 102);
|
|
143
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_95_For_5_Template_circle_click_1_listener() { const stat_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.onScopeClick(stat_r11)); });
|
|
144
144
|
i0.ɵɵelementEnd();
|
|
145
145
|
i0.ɵɵelementContainerEnd();
|
|
146
146
|
} if (rf & 2) {
|
|
147
147
|
const stat_r11 = ctx.$implicit;
|
|
148
|
-
const
|
|
148
|
+
const ɵ$index_303_r12 = ctx.$index;
|
|
149
149
|
const ctx_r1 = i0.ɵɵnextContext(5);
|
|
150
150
|
i0.ɵɵadvance();
|
|
151
|
-
i0.ɵɵattribute("stroke", stat_r11.color)("stroke-dasharray", stat_r11.percentage * 2.51 + " " + (251 - stat_r11.percentage * 2.51))("stroke-dashoffset", ctx_r1.getDonutOffset(
|
|
151
|
+
i0.ɵɵattribute("stroke", stat_r11.color)("stroke-dasharray", stat_r11.percentage * 2.51 + " " + (251 - stat_r11.percentage * 2.51))("stroke-dashoffset", ctx_r1.getDonutOffset(ɵ$index_303_r12));
|
|
152
152
|
} }
|
|
153
|
-
function
|
|
153
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_95_For_13_Template(rf, ctx) { if (rf & 1) {
|
|
154
154
|
const _r13 = i0.ɵɵgetCurrentView();
|
|
155
|
-
i0.ɵɵelementStart(0, "div",
|
|
156
|
-
i0.ɵɵlistener("click", function
|
|
157
|
-
i0.ɵɵelement(1, "div",
|
|
158
|
-
i0.ɵɵelementStart(2, "div",
|
|
155
|
+
i0.ɵɵelementStart(0, "div", 103);
|
|
156
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_95_For_13_Template_div_click_0_listener() { const stat_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.onScopeClick(stat_r14)); });
|
|
157
|
+
i0.ɵɵelement(1, "div", 104);
|
|
158
|
+
i0.ɵɵelementStart(2, "div", 105)(3, "div", 106);
|
|
159
159
|
i0.ɵɵelement(4, "i");
|
|
160
160
|
i0.ɵɵtext(5);
|
|
161
161
|
i0.ɵɵelementEnd();
|
|
162
|
-
i0.ɵɵelementStart(6, "div",
|
|
162
|
+
i0.ɵɵelementStart(6, "div", 107);
|
|
163
163
|
i0.ɵɵtext(7);
|
|
164
164
|
i0.ɵɵelementEnd()();
|
|
165
|
-
i0.ɵɵelement(8, "i",
|
|
165
|
+
i0.ɵɵelement(8, "i", 108);
|
|
166
166
|
i0.ɵɵelementEnd();
|
|
167
167
|
} if (rf & 2) {
|
|
168
168
|
const stat_r14 = ctx.$implicit;
|
|
@@ -175,64 +175,64 @@ function APIKeysResourceComponent_ng_container_2_ng_container_32_ng_container_1_
|
|
|
175
175
|
i0.ɵɵadvance(2);
|
|
176
176
|
i0.ɵɵtextInterpolate1("", stat_r14.count, " scopes");
|
|
177
177
|
} }
|
|
178
|
-
function
|
|
179
|
-
i0.ɵɵelementStart(0, "div",
|
|
178
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_95_Template(rf, ctx) { if (rf & 1) {
|
|
179
|
+
i0.ɵɵelementStart(0, "div", 68)(1, "div", 94);
|
|
180
180
|
i0.ɵɵnamespaceSVG();
|
|
181
|
-
i0.ɵɵelementStart(2, "svg",
|
|
182
|
-
i0.ɵɵelement(3, "circle",
|
|
183
|
-
i0.ɵɵ
|
|
181
|
+
i0.ɵɵelementStart(2, "svg", 95);
|
|
182
|
+
i0.ɵɵelement(3, "circle", 96);
|
|
183
|
+
i0.ɵɵrepeaterCreate(4, APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_95_For_5_Template, 2, 3, ":svg:ng-container", null, i0.ɵɵrepeaterTrackByIdentity);
|
|
184
184
|
i0.ɵɵelementEnd();
|
|
185
185
|
i0.ɵɵnamespaceHTML();
|
|
186
|
-
i0.ɵɵelementStart(
|
|
187
|
-
i0.ɵɵtext(
|
|
186
|
+
i0.ɵɵelementStart(6, "div", 97)(7, "div", 98);
|
|
187
|
+
i0.ɵɵtext(8);
|
|
188
188
|
i0.ɵɵelementEnd();
|
|
189
|
-
i0.ɵɵelementStart(
|
|
190
|
-
i0.ɵɵtext(
|
|
189
|
+
i0.ɵɵelementStart(9, "div", 99);
|
|
190
|
+
i0.ɵɵtext(10, "Categories");
|
|
191
191
|
i0.ɵɵelementEnd()()();
|
|
192
|
-
i0.ɵɵelementStart(
|
|
193
|
-
i0.ɵɵ
|
|
192
|
+
i0.ɵɵelementStart(11, "div", 100);
|
|
193
|
+
i0.ɵɵrepeaterCreate(12, APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_95_For_13_Template, 9, 6, "div", 101, i0.ɵɵrepeaterTrackByIdentity);
|
|
194
194
|
i0.ɵɵelementEnd()();
|
|
195
195
|
} if (rf & 2) {
|
|
196
196
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
197
197
|
i0.ɵɵadvance(4);
|
|
198
|
-
i0.ɵɵ
|
|
199
|
-
i0.ɵɵadvance(
|
|
198
|
+
i0.ɵɵrepeater(ctx_r1.ScopeStats);
|
|
199
|
+
i0.ɵɵadvance(4);
|
|
200
200
|
i0.ɵɵtextInterpolate(ctx_r1.ScopeStats.length);
|
|
201
201
|
i0.ɵɵadvance(4);
|
|
202
|
-
i0.ɵɵ
|
|
202
|
+
i0.ɵɵrepeater(ctx_r1.ScopeStats);
|
|
203
203
|
} }
|
|
204
|
-
function
|
|
205
|
-
i0.ɵɵelementStart(0, "div",
|
|
206
|
-
i0.ɵɵelement(1, "i",
|
|
204
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_96_Template(rf, ctx) { if (rf & 1) {
|
|
205
|
+
i0.ɵɵelementStart(0, "div", 65);
|
|
206
|
+
i0.ɵɵelement(1, "i", 14);
|
|
207
207
|
i0.ɵɵelementStart(2, "span");
|
|
208
208
|
i0.ɵɵtext(3, "No scopes configured");
|
|
209
209
|
i0.ɵɵelementEnd()();
|
|
210
210
|
} }
|
|
211
|
-
function
|
|
212
|
-
i0.ɵɵelementStart(0, "span",
|
|
211
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_104_For_2_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
212
|
+
i0.ɵɵelementStart(0, "span", 116);
|
|
213
213
|
i0.ɵɵtext(1);
|
|
214
214
|
i0.ɵɵelementEnd();
|
|
215
215
|
} if (rf & 2) {
|
|
216
216
|
const activity_r16 = i0.ɵɵnextContext().$implicit;
|
|
217
217
|
i0.ɵɵadvance();
|
|
218
|
-
i0.ɵɵtextInterpolate1("by ", activity_r16.user
|
|
218
|
+
i0.ɵɵtextInterpolate1("by ", activity_r16.user);
|
|
219
219
|
} }
|
|
220
|
-
function
|
|
220
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_104_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
221
221
|
const _r15 = i0.ɵɵgetCurrentView();
|
|
222
|
-
i0.ɵɵelementStart(0, "div",
|
|
223
|
-
i0.ɵɵlistener("click", function
|
|
224
|
-
i0.ɵɵelementStart(1, "div",
|
|
222
|
+
i0.ɵɵelementStart(0, "div", 110);
|
|
223
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_104_For_2_Template_div_click_0_listener() { const activity_r16 = i0.ɵɵrestoreView(_r15).$implicit; const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.onActivityClick(activity_r16)); });
|
|
224
|
+
i0.ɵɵelementStart(1, "div", 111);
|
|
225
225
|
i0.ɵɵelement(2, "i");
|
|
226
226
|
i0.ɵɵelementEnd();
|
|
227
|
-
i0.ɵɵelementStart(3, "div",
|
|
227
|
+
i0.ɵɵelementStart(3, "div", 112)(4, "div", 113);
|
|
228
228
|
i0.ɵɵtext(5);
|
|
229
229
|
i0.ɵɵelementEnd();
|
|
230
|
-
i0.ɵɵelementStart(6, "div",
|
|
230
|
+
i0.ɵɵelementStart(6, "div", 114)(7, "span", 115);
|
|
231
231
|
i0.ɵɵtext(8);
|
|
232
232
|
i0.ɵɵelementEnd();
|
|
233
|
-
i0.ɵɵ
|
|
233
|
+
i0.ɵɵconditionalCreate(9, APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_104_For_2_Conditional_9_Template, 2, 1, "span", 116);
|
|
234
234
|
i0.ɵɵelementEnd()();
|
|
235
|
-
i0.ɵɵelementStart(10, "div",
|
|
235
|
+
i0.ɵɵelementStart(10, "div", 117);
|
|
236
236
|
i0.ɵɵtext(11);
|
|
237
237
|
i0.ɵɵelementEnd()();
|
|
238
238
|
} if (rf & 2) {
|
|
@@ -247,194 +247,198 @@ function APIKeysResourceComponent_ng_container_2_ng_container_32_ng_container_1_
|
|
|
247
247
|
i0.ɵɵadvance(3);
|
|
248
248
|
i0.ɵɵtextInterpolate(activity_r16.action);
|
|
249
249
|
i0.ɵɵadvance();
|
|
250
|
-
i0.ɵɵ
|
|
250
|
+
i0.ɵɵconditional(activity_r16.user ? 9 : -1);
|
|
251
251
|
i0.ɵɵadvance(2);
|
|
252
252
|
i0.ɵɵtextInterpolate1(" ", ctx_r1.formatDate(activity_r16.date), " ");
|
|
253
253
|
} }
|
|
254
|
-
function
|
|
255
|
-
i0.ɵɵelementStart(0, "div",
|
|
256
|
-
i0.ɵɵ
|
|
254
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_104_Template(rf, ctx) { if (rf & 1) {
|
|
255
|
+
i0.ɵɵelementStart(0, "div", 71);
|
|
256
|
+
i0.ɵɵrepeaterCreate(1, APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_104_For_2_Template, 12, 7, "div", 109, i0.ɵɵrepeaterTrackByIdentity);
|
|
257
257
|
i0.ɵɵelementEnd();
|
|
258
258
|
} if (rf & 2) {
|
|
259
259
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
260
260
|
i0.ɵɵadvance();
|
|
261
|
-
i0.ɵɵ
|
|
261
|
+
i0.ɵɵrepeater(ctx_r1.RecentActivity);
|
|
262
262
|
} }
|
|
263
|
-
function
|
|
264
|
-
i0.ɵɵelementStart(0, "div",
|
|
265
|
-
i0.ɵɵelement(1, "i",
|
|
263
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_105_Template(rf, ctx) { if (rf & 1) {
|
|
264
|
+
i0.ɵɵelementStart(0, "div", 65);
|
|
265
|
+
i0.ɵɵelement(1, "i", 118);
|
|
266
266
|
i0.ɵɵelementStart(2, "span");
|
|
267
267
|
i0.ɵɵtext(3, "No recent activity");
|
|
268
268
|
i0.ɵɵelementEnd()();
|
|
269
269
|
} }
|
|
270
|
-
function
|
|
270
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_106_Template(rf, ctx) { if (rf & 1) {
|
|
271
271
|
const _r17 = i0.ɵɵgetCurrentView();
|
|
272
|
-
i0.ɵɵelementStart(0, "div",
|
|
272
|
+
i0.ɵɵelementStart(0, "div", 72)(1, "div", 119);
|
|
273
273
|
i0.ɵɵtext(2, "Quick Actions");
|
|
274
274
|
i0.ɵɵelementEnd();
|
|
275
|
-
i0.ɵɵelementStart(3, "div",
|
|
276
|
-
i0.ɵɵlistener("click", function
|
|
277
|
-
i0.ɵɵelement(5, "i",
|
|
275
|
+
i0.ɵɵelementStart(3, "div", 120)(4, "button", 121);
|
|
276
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_106_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.openCreateDialog()); });
|
|
277
|
+
i0.ɵɵelement(5, "i", 77);
|
|
278
278
|
i0.ɵɵelementStart(6, "span");
|
|
279
279
|
i0.ɵɵtext(7, "Generate Key");
|
|
280
280
|
i0.ɵɵelementEnd()();
|
|
281
|
-
i0.ɵɵelementStart(8, "button",
|
|
282
|
-
i0.ɵɵlistener("click", function
|
|
283
|
-
i0.ɵɵelement(9, "i",
|
|
281
|
+
i0.ɵɵelementStart(8, "button", 121);
|
|
282
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_106_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.showListView("all")); });
|
|
283
|
+
i0.ɵɵelement(9, "i", 122);
|
|
284
284
|
i0.ɵɵelementStart(10, "span");
|
|
285
285
|
i0.ɵɵtext(11, "View All Keys");
|
|
286
286
|
i0.ɵɵelementEnd()();
|
|
287
|
-
i0.ɵɵelementStart(12, "button",
|
|
288
|
-
i0.ɵɵlistener("click", function
|
|
289
|
-
i0.ɵɵelement(13, "i",
|
|
287
|
+
i0.ɵɵelementStart(12, "button", 121);
|
|
288
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_106_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.showListView("expiring")); });
|
|
289
|
+
i0.ɵɵelement(13, "i", 55);
|
|
290
290
|
i0.ɵɵelementStart(14, "span");
|
|
291
291
|
i0.ɵɵtext(15, "Expiring Keys");
|
|
292
292
|
i0.ɵɵelementEnd()();
|
|
293
|
-
i0.ɵɵelementStart(16, "button",
|
|
294
|
-
i0.ɵɵlistener("click", function
|
|
295
|
-
i0.ɵɵelement(17, "i",
|
|
293
|
+
i0.ɵɵelementStart(16, "button", 121);
|
|
294
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_106_Template_button_click_16_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.showListView("never-used")); });
|
|
295
|
+
i0.ɵɵelement(17, "i", 82);
|
|
296
296
|
i0.ɵɵelementStart(18, "span");
|
|
297
297
|
i0.ɵɵtext(19, "Never Used");
|
|
298
298
|
i0.ɵɵelementEnd()()()();
|
|
299
299
|
} }
|
|
300
|
-
function
|
|
300
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
301
301
|
const _r3 = i0.ɵɵgetCurrentView();
|
|
302
|
-
i0.ɵɵ
|
|
303
|
-
i0.ɵɵ
|
|
304
|
-
i0.ɵɵtext(4, "API Keys Management");
|
|
302
|
+
i0.ɵɵelementStart(0, "div", 21)(1, "div", 22)(2, "h2", 23);
|
|
303
|
+
i0.ɵɵtext(3, "API Keys Management");
|
|
305
304
|
i0.ɵɵelementEnd();
|
|
306
|
-
i0.ɵɵelementStart(
|
|
307
|
-
i0.ɵɵtext(
|
|
305
|
+
i0.ɵɵelementStart(4, "p", 24);
|
|
306
|
+
i0.ɵɵtext(5, "Manage API keys for external integrations and services");
|
|
308
307
|
i0.ɵɵelementEnd()();
|
|
309
|
-
i0.ɵɵelementStart(
|
|
310
|
-
i0.ɵɵlistener("click", function
|
|
311
|
-
i0.ɵɵelement(
|
|
308
|
+
i0.ɵɵelementStart(6, "div", 25)(7, "button", 26);
|
|
309
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.refresh()); });
|
|
310
|
+
i0.ɵɵelement(8, "i", 27);
|
|
312
311
|
i0.ɵɵelementEnd();
|
|
313
|
-
i0.ɵɵ
|
|
312
|
+
i0.ɵɵconditionalCreate(9, APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_9_Template, 4, 0, "button", 28);
|
|
314
313
|
i0.ɵɵelementEnd()();
|
|
315
|
-
i0.ɵɵelementStart(
|
|
314
|
+
i0.ɵɵelementStart(10, "div", 29)(11, "div", 30)(12, "div", 31);
|
|
316
315
|
i0.ɵɵnamespaceSVG();
|
|
317
|
-
i0.ɵɵelementStart(
|
|
318
|
-
i0.ɵɵelement(
|
|
316
|
+
i0.ɵɵelementStart(13, "svg", 32);
|
|
317
|
+
i0.ɵɵelement(14, "path", 33)(15, "path", 34);
|
|
319
318
|
i0.ɵɵelementEnd();
|
|
320
319
|
i0.ɵɵnamespaceHTML();
|
|
321
|
-
i0.ɵɵelementStart(
|
|
322
|
-
i0.ɵɵtext(
|
|
320
|
+
i0.ɵɵelementStart(16, "div", 35);
|
|
321
|
+
i0.ɵɵtext(17);
|
|
323
322
|
i0.ɵɵelementEnd()()();
|
|
324
|
-
i0.ɵɵelementStart(
|
|
325
|
-
i0.ɵɵtext(
|
|
323
|
+
i0.ɵɵelementStart(18, "div", 36)(19, "div", 37);
|
|
324
|
+
i0.ɵɵtext(20);
|
|
326
325
|
i0.ɵɵelementEnd();
|
|
327
|
-
i0.ɵɵelementStart(
|
|
328
|
-
i0.ɵɵ
|
|
326
|
+
i0.ɵɵelementStart(21, "div", 38);
|
|
327
|
+
i0.ɵɵconditionalCreate(22, APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_22_Template, 3, 1, "span", 39);
|
|
328
|
+
i0.ɵɵconditionalCreate(23, APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_23_Template, 3, 1, "span", 40);
|
|
329
|
+
i0.ɵɵconditionalCreate(24, APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_24_Template, 3, 1, "span", 41);
|
|
330
|
+
i0.ɵɵconditionalCreate(25, APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_25_Template, 3, 0, "span", 42);
|
|
329
331
|
i0.ɵɵelementEnd()()();
|
|
330
|
-
i0.ɵɵelementStart(
|
|
331
|
-
i0.ɵɵlistener("click", function
|
|
332
|
-
i0.ɵɵelementStart(
|
|
333
|
-
i0.ɵɵelement(
|
|
332
|
+
i0.ɵɵelementStart(26, "div", 43)(27, "div", 44);
|
|
333
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Template_div_click_27_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.showListView("all")); });
|
|
334
|
+
i0.ɵɵelementStart(28, "div", 45);
|
|
335
|
+
i0.ɵɵelement(29, "i", 8);
|
|
334
336
|
i0.ɵɵelementEnd();
|
|
335
|
-
i0.ɵɵelementStart(
|
|
336
|
-
i0.ɵɵtext(
|
|
337
|
+
i0.ɵɵelementStart(30, "div", 46)(31, "div", 47);
|
|
338
|
+
i0.ɵɵtext(32);
|
|
337
339
|
i0.ɵɵelementEnd();
|
|
338
|
-
i0.ɵɵelementStart(
|
|
339
|
-
i0.ɵɵtext(
|
|
340
|
+
i0.ɵɵelementStart(33, "div", 48);
|
|
341
|
+
i0.ɵɵtext(34, "Total Keys");
|
|
340
342
|
i0.ɵɵelementEnd()();
|
|
341
|
-
i0.ɵɵelementStart(
|
|
342
|
-
i0.ɵɵelement(
|
|
343
|
+
i0.ɵɵelementStart(35, "div", 49);
|
|
344
|
+
i0.ɵɵelement(36, "i", 50);
|
|
343
345
|
i0.ɵɵelementEnd()();
|
|
344
|
-
i0.ɵɵelementStart(
|
|
345
|
-
i0.ɵɵlistener("click", function
|
|
346
|
-
i0.ɵɵelementStart(
|
|
347
|
-
i0.ɵɵelement(
|
|
346
|
+
i0.ɵɵelementStart(37, "div", 51);
|
|
347
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Template_div_click_37_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.showListView("active")); });
|
|
348
|
+
i0.ɵɵelementStart(38, "div", 45);
|
|
349
|
+
i0.ɵɵelement(39, "i", 52);
|
|
348
350
|
i0.ɵɵelementEnd();
|
|
349
|
-
i0.ɵɵelementStart(
|
|
350
|
-
i0.ɵɵtext(
|
|
351
|
+
i0.ɵɵelementStart(40, "div", 46)(41, "div", 47);
|
|
352
|
+
i0.ɵɵtext(42);
|
|
351
353
|
i0.ɵɵelementEnd();
|
|
352
|
-
i0.ɵɵelementStart(
|
|
353
|
-
i0.ɵɵtext(
|
|
354
|
+
i0.ɵɵelementStart(43, "div", 48);
|
|
355
|
+
i0.ɵɵtext(44, "Active");
|
|
354
356
|
i0.ɵɵelementEnd()();
|
|
355
|
-
i0.ɵɵelementStart(
|
|
356
|
-
i0.ɵɵtext(
|
|
357
|
+
i0.ɵɵelementStart(45, "div", 53)(46, "span", 54);
|
|
358
|
+
i0.ɵɵtext(47);
|
|
357
359
|
i0.ɵɵelementEnd()()();
|
|
358
|
-
i0.ɵɵelementStart(
|
|
359
|
-
i0.ɵɵlistener("click", function
|
|
360
|
-
i0.ɵɵelementStart(
|
|
361
|
-
i0.ɵɵelement(
|
|
360
|
+
i0.ɵɵelementStart(48, "div", 44);
|
|
361
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Template_div_click_48_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.showListView("expiring")); });
|
|
362
|
+
i0.ɵɵelementStart(49, "div", 45);
|
|
363
|
+
i0.ɵɵelement(50, "i", 55);
|
|
362
364
|
i0.ɵɵelementEnd();
|
|
363
|
-
i0.ɵɵelementStart(
|
|
364
|
-
i0.ɵɵtext(
|
|
365
|
+
i0.ɵɵelementStart(51, "div", 46)(52, "div", 47);
|
|
366
|
+
i0.ɵɵtext(53);
|
|
365
367
|
i0.ɵɵelementEnd();
|
|
366
|
-
i0.ɵɵelementStart(
|
|
367
|
-
i0.ɵɵtext(
|
|
368
|
+
i0.ɵɵelementStart(54, "div", 48);
|
|
369
|
+
i0.ɵɵtext(55, "Expiring Soon");
|
|
368
370
|
i0.ɵɵelementEnd()();
|
|
369
|
-
i0.ɵɵ
|
|
371
|
+
i0.ɵɵconditionalCreate(56, APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_56_Template, 2, 0, "div", 56);
|
|
370
372
|
i0.ɵɵelementEnd();
|
|
371
|
-
i0.ɵɵelementStart(
|
|
372
|
-
i0.ɵɵlistener("click", function
|
|
373
|
-
i0.ɵɵelementStart(
|
|
374
|
-
i0.ɵɵelement(
|
|
373
|
+
i0.ɵɵelementStart(57, "div", 44);
|
|
374
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Template_div_click_57_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.showListView("revoked")); });
|
|
375
|
+
i0.ɵɵelementStart(58, "div", 45);
|
|
376
|
+
i0.ɵɵelement(59, "i", 57);
|
|
375
377
|
i0.ɵɵelementEnd();
|
|
376
|
-
i0.ɵɵelementStart(
|
|
377
|
-
i0.ɵɵtext(
|
|
378
|
+
i0.ɵɵelementStart(60, "div", 46)(61, "div", 47);
|
|
379
|
+
i0.ɵɵtext(62);
|
|
378
380
|
i0.ɵɵelementEnd();
|
|
379
|
-
i0.ɵɵelementStart(
|
|
380
|
-
i0.ɵɵtext(
|
|
381
|
+
i0.ɵɵelementStart(63, "div", 48);
|
|
382
|
+
i0.ɵɵtext(64, "Revoked");
|
|
381
383
|
i0.ɵɵelementEnd()()();
|
|
382
|
-
i0.ɵɵelementStart(
|
|
383
|
-
i0.ɵɵlistener("click", function
|
|
384
|
-
i0.ɵɵelementStart(
|
|
385
|
-
i0.ɵɵelement(
|
|
384
|
+
i0.ɵɵelementStart(65, "div", 44);
|
|
385
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Template_div_click_65_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.switchTab("scopes")); });
|
|
386
|
+
i0.ɵɵelementStart(66, "div", 45);
|
|
387
|
+
i0.ɵɵelement(67, "i", 14);
|
|
386
388
|
i0.ɵɵelementEnd();
|
|
387
|
-
i0.ɵɵelementStart(
|
|
388
|
-
i0.ɵɵtext(
|
|
389
|
+
i0.ɵɵelementStart(68, "div", 46)(69, "div", 47);
|
|
390
|
+
i0.ɵɵtext(70);
|
|
389
391
|
i0.ɵɵelementEnd();
|
|
390
|
-
i0.ɵɵelementStart(
|
|
391
|
-
i0.ɵɵtext(
|
|
392
|
+
i0.ɵɵelementStart(71, "div", 48);
|
|
393
|
+
i0.ɵɵtext(72, "Scope Categories");
|
|
392
394
|
i0.ɵɵelementEnd()()()();
|
|
393
|
-
i0.ɵɵelementStart(
|
|
394
|
-
i0.ɵɵelement(
|
|
395
|
-
i0.ɵɵelementStart(
|
|
396
|
-
i0.ɵɵtext(
|
|
395
|
+
i0.ɵɵelementStart(73, "div", 58)(74, "div", 59)(75, "div", 60)(76, "div", 61);
|
|
396
|
+
i0.ɵɵelement(77, "i", 8);
|
|
397
|
+
i0.ɵɵelementStart(78, "span");
|
|
398
|
+
i0.ɵɵtext(79, "Recently Used Keys");
|
|
397
399
|
i0.ɵɵelementEnd()();
|
|
398
|
-
i0.ɵɵelementStart(
|
|
399
|
-
i0.ɵɵlistener("click", function
|
|
400
|
-
i0.ɵɵtext(
|
|
401
|
-
i0.ɵɵelement(
|
|
400
|
+
i0.ɵɵelementStart(80, "button", 62);
|
|
401
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Template_button_click_80_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.showListView("all")); });
|
|
402
|
+
i0.ɵɵtext(81, " View All ");
|
|
403
|
+
i0.ɵɵelement(82, "i", 50);
|
|
402
404
|
i0.ɵɵelementEnd()();
|
|
403
|
-
i0.ɵɵelementStart(
|
|
404
|
-
i0.ɵɵ
|
|
405
|
+
i0.ɵɵelementStart(83, "div", 63);
|
|
406
|
+
i0.ɵɵconditionalCreate(84, APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_84_Template, 3, 0, "div", 64);
|
|
407
|
+
i0.ɵɵconditionalCreate(85, APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_85_Template, 4, 0, "div", 65);
|
|
405
408
|
i0.ɵɵelementEnd()();
|
|
406
|
-
i0.ɵɵelementStart(
|
|
407
|
-
i0.ɵɵelement(
|
|
408
|
-
i0.ɵɵelementStart(
|
|
409
|
-
i0.ɵɵtext(
|
|
409
|
+
i0.ɵɵelementStart(86, "div", 66)(87, "div", 60)(88, "div", 61);
|
|
410
|
+
i0.ɵɵelement(89, "i", 14);
|
|
411
|
+
i0.ɵɵelementStart(90, "span");
|
|
412
|
+
i0.ɵɵtext(91, "Permission Scopes");
|
|
410
413
|
i0.ɵɵelementEnd()();
|
|
411
|
-
i0.ɵɵelementStart(
|
|
412
|
-
i0.ɵɵtext(
|
|
414
|
+
i0.ɵɵelementStart(92, "span", 67);
|
|
415
|
+
i0.ɵɵtext(93, "Available scope categories");
|
|
413
416
|
i0.ɵɵelementEnd()();
|
|
414
|
-
i0.ɵɵelementStart(
|
|
415
|
-
i0.ɵɵ
|
|
417
|
+
i0.ɵɵelementStart(94, "div", 63);
|
|
418
|
+
i0.ɵɵconditionalCreate(95, APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_95_Template, 14, 1, "div", 68);
|
|
419
|
+
i0.ɵɵconditionalCreate(96, APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_96_Template, 4, 0, "div", 65);
|
|
416
420
|
i0.ɵɵelementEnd()();
|
|
417
|
-
i0.ɵɵelementStart(
|
|
418
|
-
i0.ɵɵelement(
|
|
419
|
-
i0.ɵɵelementStart(
|
|
420
|
-
i0.ɵɵtext(
|
|
421
|
+
i0.ɵɵelementStart(97, "div", 69)(98, "div", 60)(99, "div", 61);
|
|
422
|
+
i0.ɵɵelement(100, "i", 70);
|
|
423
|
+
i0.ɵɵelementStart(101, "span");
|
|
424
|
+
i0.ɵɵtext(102, "Recent Activity");
|
|
421
425
|
i0.ɵɵelementEnd()()();
|
|
422
|
-
i0.ɵɵelementStart(
|
|
423
|
-
i0.ɵɵ
|
|
426
|
+
i0.ɵɵelementStart(103, "div", 63);
|
|
427
|
+
i0.ɵɵconditionalCreate(104, APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_104_Template, 3, 0, "div", 71);
|
|
428
|
+
i0.ɵɵconditionalCreate(105, APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_105_Template, 4, 0, "div", 65);
|
|
424
429
|
i0.ɵɵelementEnd()()();
|
|
425
|
-
i0.ɵɵ
|
|
426
|
-
i0.ɵɵelementStart(
|
|
427
|
-
i0.ɵɵelement(
|
|
428
|
-
i0.ɵɵelementStart(
|
|
429
|
-
i0.ɵɵtext(
|
|
430
|
+
i0.ɵɵconditionalCreate(106, APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Conditional_106_Template, 20, 0, "div", 72);
|
|
431
|
+
i0.ɵɵelementStart(107, "div", 73);
|
|
432
|
+
i0.ɵɵelement(108, "i", 74);
|
|
433
|
+
i0.ɵɵelementStart(109, "div", 75)(110, "strong");
|
|
434
|
+
i0.ɵɵtext(111, "Security Best Practices:");
|
|
430
435
|
i0.ɵɵelementEnd();
|
|
431
|
-
i0.ɵɵtext(
|
|
436
|
+
i0.ɵɵtext(112, " API keys should be rotated regularly and revoked when no longer needed. Keys are hashed and stored securely - the raw key is only shown once at creation time. All API key usage is logged for audit purposes. ");
|
|
432
437
|
i0.ɵɵelementEnd()();
|
|
433
|
-
i0.ɵɵelementContainerEnd();
|
|
434
438
|
} if (rf & 2) {
|
|
435
439
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
436
|
-
i0.ɵɵadvance(
|
|
437
|
-
i0.ɵɵ
|
|
440
|
+
i0.ɵɵadvance(9);
|
|
441
|
+
i0.ɵɵconditional(ctx_r1.UserCanCreateKeys ? 9 : -1);
|
|
438
442
|
i0.ɵɵadvance();
|
|
439
443
|
i0.ɵɵproperty("ngClass", ctx_r1.getHealthClass());
|
|
440
444
|
i0.ɵɵadvance(5);
|
|
@@ -444,13 +448,13 @@ function APIKeysResourceComponent_ng_container_2_ng_container_32_ng_container_1_
|
|
|
444
448
|
i0.ɵɵadvance(3);
|
|
445
449
|
i0.ɵɵtextInterpolate(ctx_r1.getHealthLabel());
|
|
446
450
|
i0.ɵɵadvance(2);
|
|
447
|
-
i0.ɵɵ
|
|
451
|
+
i0.ɵɵconditional(ctx_r1.ExpiredKeys > 0 ? 22 : -1);
|
|
448
452
|
i0.ɵɵadvance();
|
|
449
|
-
i0.ɵɵ
|
|
453
|
+
i0.ɵɵconditional(ctx_r1.ExpiringSoonCount > 0 ? 23 : -1);
|
|
450
454
|
i0.ɵɵadvance();
|
|
451
|
-
i0.ɵɵ
|
|
455
|
+
i0.ɵɵconditional(ctx_r1.NeverUsedKeys > 0 ? 24 : -1);
|
|
452
456
|
i0.ɵɵadvance();
|
|
453
|
-
i0.ɵɵ
|
|
457
|
+
i0.ɵɵconditional(ctx_r1.ExpiredKeys === 0 && ctx_r1.ExpiringSoonCount === 0 && ctx_r1.NeverUsedKeys === 0 ? 25 : -1);
|
|
454
458
|
i0.ɵɵadvance(7);
|
|
455
459
|
i0.ɵɵtextInterpolate(ctx_r1.TotalKeys);
|
|
456
460
|
i0.ɵɵadvance(10);
|
|
@@ -462,7 +466,7 @@ function APIKeysResourceComponent_ng_container_2_ng_container_32_ng_container_1_
|
|
|
462
466
|
i0.ɵɵadvance(5);
|
|
463
467
|
i0.ɵɵtextInterpolate(ctx_r1.ExpiringSoonCount);
|
|
464
468
|
i0.ɵɵadvance(3);
|
|
465
|
-
i0.ɵɵ
|
|
469
|
+
i0.ɵɵconditional(ctx_r1.ExpiringSoonCount > 0 ? 56 : -1);
|
|
466
470
|
i0.ɵɵadvance();
|
|
467
471
|
i0.ɵɵclassProp("danger", ctx_r1.RevokedKeys > 0);
|
|
468
472
|
i0.ɵɵadvance(5);
|
|
@@ -470,124 +474,115 @@ function APIKeysResourceComponent_ng_container_2_ng_container_32_ng_container_1_
|
|
|
470
474
|
i0.ɵɵadvance(8);
|
|
471
475
|
i0.ɵɵtextInterpolate(ctx_r1.ScopeStats.length);
|
|
472
476
|
i0.ɵɵadvance(14);
|
|
473
|
-
i0.ɵɵ
|
|
477
|
+
i0.ɵɵconditional(ctx_r1.TopUsedKeys.length > 0 ? 84 : -1);
|
|
474
478
|
i0.ɵɵadvance();
|
|
475
|
-
i0.ɵɵ
|
|
479
|
+
i0.ɵɵconditional(ctx_r1.TopUsedKeys.length === 0 ? 85 : -1);
|
|
476
480
|
i0.ɵɵadvance(10);
|
|
477
|
-
i0.ɵɵ
|
|
481
|
+
i0.ɵɵconditional(ctx_r1.ScopeStats.length > 0 ? 95 : -1);
|
|
478
482
|
i0.ɵɵadvance();
|
|
479
|
-
i0.ɵɵ
|
|
483
|
+
i0.ɵɵconditional(ctx_r1.ScopeStats.length === 0 ? 96 : -1);
|
|
480
484
|
i0.ɵɵadvance(8);
|
|
481
|
-
i0.ɵɵ
|
|
485
|
+
i0.ɵɵconditional(ctx_r1.RecentActivity.length > 0 ? 104 : -1);
|
|
482
486
|
i0.ɵɵadvance();
|
|
483
|
-
i0.ɵɵ
|
|
487
|
+
i0.ɵɵconditional(ctx_r1.RecentActivity.length === 0 ? 105 : -1);
|
|
484
488
|
i0.ɵɵadvance();
|
|
485
|
-
i0.ɵɵ
|
|
489
|
+
i0.ɵɵconditional(ctx_r1.UserCanCreateKeys ? 106 : -1);
|
|
486
490
|
} }
|
|
487
|
-
function
|
|
491
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
488
492
|
const _r18 = i0.ɵɵgetCurrentView();
|
|
489
|
-
i0.ɵɵ
|
|
490
|
-
i0.ɵɵ
|
|
491
|
-
i0.ɵɵ
|
|
492
|
-
i0.ɵɵ
|
|
493
|
-
i0.ɵɵtext(4, " Back to Overview ");
|
|
493
|
+
i0.ɵɵelementStart(0, "div", 123)(1, "button", 124);
|
|
494
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_1_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.showOverview()); });
|
|
495
|
+
i0.ɵɵelement(2, "i", 125);
|
|
496
|
+
i0.ɵɵtext(3, " Back to Overview ");
|
|
494
497
|
i0.ɵɵelementEnd()();
|
|
495
|
-
i0.ɵɵelementStart(
|
|
496
|
-
i0.ɵɵlistener("KeySelected", function
|
|
498
|
+
i0.ɵɵelementStart(4, "mj-api-key-list", 126, 0);
|
|
499
|
+
i0.ɵɵlistener("KeySelected", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_1_Template_mj_api_key_list_KeySelected_4_listener($event) { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onKeySelected($event)); })("CreateRequested", function APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_1_Template_mj_api_key_list_CreateRequested_4_listener() { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.openCreateDialog()); });
|
|
497
500
|
i0.ɵɵelementEnd();
|
|
498
|
-
i0.ɵɵelementContainerEnd();
|
|
499
501
|
} if (rf & 2) {
|
|
500
502
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
501
|
-
i0.ɵɵadvance(
|
|
503
|
+
i0.ɵɵadvance(4);
|
|
502
504
|
i0.ɵɵproperty("Filter", ctx_r1.ListFilter);
|
|
503
505
|
} }
|
|
504
|
-
function
|
|
505
|
-
i0.ɵɵ
|
|
506
|
-
i0.ɵɵ
|
|
507
|
-
i0.ɵɵelementContainerEnd();
|
|
506
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_31_Template(rf, ctx) { if (rf & 1) {
|
|
507
|
+
i0.ɵɵconditionalCreate(0, APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_0_Template, 113, 27);
|
|
508
|
+
i0.ɵɵconditionalCreate(1, APIKeysResourceComponent_Conditional_2_Conditional_31_Conditional_1_Template, 6, 1);
|
|
508
509
|
} if (rf & 2) {
|
|
509
510
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
511
|
+
i0.ɵɵconditional(ctx_r1.CurrentView === "overview" ? 0 : -1);
|
|
510
512
|
i0.ɵɵadvance();
|
|
511
|
-
i0.ɵɵ
|
|
512
|
-
i0.ɵɵadvance();
|
|
513
|
-
i0.ɵɵproperty("ngIf", ctx_r1.CurrentView === "list");
|
|
513
|
+
i0.ɵɵconditional(ctx_r1.CurrentView === "list" ? 1 : -1);
|
|
514
514
|
} }
|
|
515
|
-
function
|
|
515
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_32_Template(rf, ctx) { if (rf & 1) {
|
|
516
516
|
const _r19 = i0.ɵɵgetCurrentView();
|
|
517
|
-
i0.ɵɵ
|
|
518
|
-
i0.ɵɵ
|
|
519
|
-
i0.ɵɵlistener("ApplicationUpdated", function APIKeysResourceComponent_ng_container_2_ng_container_33_Template_mj_api_applications_panel_ApplicationUpdated_1_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onDataUpdated()); });
|
|
517
|
+
i0.ɵɵelementStart(0, "mj-api-applications-panel", 127);
|
|
518
|
+
i0.ɵɵlistener("ApplicationUpdated", function APIKeysResourceComponent_Conditional_2_Conditional_32_Template_mj_api_applications_panel_ApplicationUpdated_0_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onDataUpdated()); });
|
|
520
519
|
i0.ɵɵelementEnd();
|
|
521
|
-
i0.ɵɵelementContainerEnd();
|
|
522
520
|
} }
|
|
523
|
-
function
|
|
521
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_33_Template(rf, ctx) { if (rf & 1) {
|
|
524
522
|
const _r20 = i0.ɵɵgetCurrentView();
|
|
525
|
-
i0.ɵɵ
|
|
526
|
-
i0.ɵɵ
|
|
527
|
-
i0.ɵɵlistener("ScopeUpdated", function APIKeysResourceComponent_ng_container_2_ng_container_34_Template_mj_api_scopes_panel_ScopeUpdated_1_listener() { i0.ɵɵrestoreView(_r20); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onDataUpdated()); });
|
|
523
|
+
i0.ɵɵelementStart(0, "mj-api-scopes-panel", 128);
|
|
524
|
+
i0.ɵɵlistener("ScopeUpdated", function APIKeysResourceComponent_Conditional_2_Conditional_33_Template_mj_api_scopes_panel_ScopeUpdated_0_listener() { i0.ɵɵrestoreView(_r20); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onDataUpdated()); });
|
|
528
525
|
i0.ɵɵelementEnd();
|
|
529
|
-
i0.ɵɵelementContainerEnd();
|
|
530
526
|
} }
|
|
531
|
-
function
|
|
532
|
-
i0.ɵɵ
|
|
533
|
-
i0.ɵɵelement(1, "mj-api-usage-panel");
|
|
534
|
-
i0.ɵɵelementContainerEnd();
|
|
527
|
+
function APIKeysResourceComponent_Conditional_2_Conditional_34_Template(rf, ctx) { if (rf & 1) {
|
|
528
|
+
i0.ɵɵelement(0, "mj-api-usage-panel");
|
|
535
529
|
} }
|
|
536
|
-
function
|
|
530
|
+
function APIKeysResourceComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
537
531
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
538
|
-
i0.ɵɵ
|
|
539
|
-
i0.ɵɵ
|
|
540
|
-
i0.ɵɵ
|
|
541
|
-
i0.ɵɵ
|
|
542
|
-
i0.ɵɵtext(6, "API Keys");
|
|
532
|
+
i0.ɵɵelementStart(0, "div", 5)(1, "div", 6)(2, "div", 7);
|
|
533
|
+
i0.ɵɵelement(3, "i", 8);
|
|
534
|
+
i0.ɵɵelementStart(4, "span");
|
|
535
|
+
i0.ɵɵtext(5, "API Keys");
|
|
543
536
|
i0.ɵɵelementEnd()()();
|
|
544
|
-
i0.ɵɵelementStart(
|
|
545
|
-
i0.ɵɵlistener("click", function
|
|
546
|
-
i0.ɵɵelement(
|
|
547
|
-
i0.ɵɵelementStart(
|
|
548
|
-
i0.ɵɵtext(
|
|
537
|
+
i0.ɵɵelementStart(6, "div", 9)(7, "button", 10);
|
|
538
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); ctx_r1.switchTab("keys"); return i0.ɵɵresetView(ctx_r1.closeNav()); });
|
|
539
|
+
i0.ɵɵelement(8, "i", 8);
|
|
540
|
+
i0.ɵɵelementStart(9, "span", 11);
|
|
541
|
+
i0.ɵɵtext(10, "API Keys");
|
|
549
542
|
i0.ɵɵelementEnd();
|
|
550
|
-
i0.ɵɵelementStart(
|
|
551
|
-
i0.ɵɵtext(
|
|
543
|
+
i0.ɵɵelementStart(11, "span", 12);
|
|
544
|
+
i0.ɵɵtext(12);
|
|
552
545
|
i0.ɵɵelementEnd()();
|
|
553
|
-
i0.ɵɵelementStart(
|
|
554
|
-
i0.ɵɵlistener("click", function
|
|
555
|
-
i0.ɵɵelement(
|
|
556
|
-
i0.ɵɵelementStart(
|
|
557
|
-
i0.ɵɵtext(
|
|
546
|
+
i0.ɵɵelementStart(13, "button", 10);
|
|
547
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Template_button_click_13_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); ctx_r1.switchTab("applications"); return i0.ɵɵresetView(ctx_r1.closeNav()); });
|
|
548
|
+
i0.ɵɵelement(14, "i", 13);
|
|
549
|
+
i0.ɵɵelementStart(15, "span", 11);
|
|
550
|
+
i0.ɵɵtext(16, "Applications");
|
|
558
551
|
i0.ɵɵelementEnd();
|
|
559
|
-
i0.ɵɵelementStart(
|
|
560
|
-
i0.ɵɵtext(
|
|
552
|
+
i0.ɵɵelementStart(17, "span", 12);
|
|
553
|
+
i0.ɵɵtext(18);
|
|
561
554
|
i0.ɵɵelementEnd()();
|
|
562
|
-
i0.ɵɵelementStart(
|
|
563
|
-
i0.ɵɵlistener("click", function
|
|
564
|
-
i0.ɵɵelement(
|
|
565
|
-
i0.ɵɵelementStart(
|
|
566
|
-
i0.ɵɵtext(
|
|
555
|
+
i0.ɵɵelementStart(19, "button", 10);
|
|
556
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Template_button_click_19_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); ctx_r1.switchTab("scopes"); return i0.ɵɵresetView(ctx_r1.closeNav()); });
|
|
557
|
+
i0.ɵɵelement(20, "i", 14);
|
|
558
|
+
i0.ɵɵelementStart(21, "span", 11);
|
|
559
|
+
i0.ɵɵtext(22, "Scopes");
|
|
567
560
|
i0.ɵɵelementEnd();
|
|
568
|
-
i0.ɵɵelementStart(
|
|
569
|
-
i0.ɵɵtext(
|
|
561
|
+
i0.ɵɵelementStart(23, "span", 12);
|
|
562
|
+
i0.ɵɵtext(24);
|
|
570
563
|
i0.ɵɵelementEnd()();
|
|
571
|
-
i0.ɵɵelementStart(
|
|
572
|
-
i0.ɵɵlistener("click", function
|
|
573
|
-
i0.ɵɵelement(
|
|
574
|
-
i0.ɵɵelementStart(
|
|
575
|
-
i0.ɵɵtext(
|
|
564
|
+
i0.ɵɵelementStart(25, "button", 10);
|
|
565
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Template_button_click_25_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); ctx_r1.switchTab("usage"); return i0.ɵɵresetView(ctx_r1.closeNav()); });
|
|
566
|
+
i0.ɵɵelement(26, "i", 15);
|
|
567
|
+
i0.ɵɵelementStart(27, "span", 11);
|
|
568
|
+
i0.ɵɵtext(28, "Usage Analytics");
|
|
576
569
|
i0.ɵɵelementEnd()()()();
|
|
577
|
-
i0.ɵɵelementStart(
|
|
578
|
-
i0.ɵɵ
|
|
570
|
+
i0.ɵɵelementStart(29, "div", 16)(30, "div", 17);
|
|
571
|
+
i0.ɵɵconditionalCreate(31, APIKeysResourceComponent_Conditional_2_Conditional_31_Template, 2, 2);
|
|
572
|
+
i0.ɵɵconditionalCreate(32, APIKeysResourceComponent_Conditional_2_Conditional_32_Template, 1, 0, "mj-api-applications-panel");
|
|
573
|
+
i0.ɵɵconditionalCreate(33, APIKeysResourceComponent_Conditional_2_Conditional_33_Template, 1, 0, "mj-api-scopes-panel");
|
|
574
|
+
i0.ɵɵconditionalCreate(34, APIKeysResourceComponent_Conditional_2_Conditional_34_Template, 1, 0, "mj-api-usage-panel");
|
|
579
575
|
i0.ɵɵelementEnd()();
|
|
580
|
-
i0.ɵɵelementStart(
|
|
581
|
-
i0.ɵɵlistener("click", function
|
|
582
|
-
i0.ɵɵelement(
|
|
576
|
+
i0.ɵɵelementStart(35, "button", 18);
|
|
577
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Template_button_click_35_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleNav()); });
|
|
578
|
+
i0.ɵɵelement(36, "i", 19);
|
|
583
579
|
i0.ɵɵelementEnd();
|
|
584
|
-
i0.ɵɵelementStart(
|
|
585
|
-
i0.ɵɵlistener("click", function
|
|
580
|
+
i0.ɵɵelementStart(37, "div", 20);
|
|
581
|
+
i0.ɵɵlistener("click", function APIKeysResourceComponent_Conditional_2_Template_div_click_37_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.closeNav()); });
|
|
586
582
|
i0.ɵɵelementEnd();
|
|
587
|
-
i0.ɵɵelementContainerEnd();
|
|
588
583
|
} if (rf & 2) {
|
|
589
584
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
590
|
-
i0.ɵɵadvance(
|
|
585
|
+
i0.ɵɵadvance(7);
|
|
591
586
|
i0.ɵɵclassProp("active", ctx_r1.MainTab === "keys");
|
|
592
587
|
i0.ɵɵadvance(5);
|
|
593
588
|
i0.ɵɵtextInterpolate(ctx_r1.TotalKeys);
|
|
@@ -602,20 +597,16 @@ function APIKeysResourceComponent_ng_container_2_Template(rf, ctx) { if (rf & 1)
|
|
|
602
597
|
i0.ɵɵadvance();
|
|
603
598
|
i0.ɵɵclassProp("active", ctx_r1.MainTab === "usage");
|
|
604
599
|
i0.ɵɵadvance(6);
|
|
605
|
-
i0.ɵɵ
|
|
600
|
+
i0.ɵɵconditional(ctx_r1.MainTab === "keys" ? 31 : -1);
|
|
606
601
|
i0.ɵɵadvance();
|
|
607
|
-
i0.ɵɵ
|
|
602
|
+
i0.ɵɵconditional(ctx_r1.MainTab === "applications" ? 32 : -1);
|
|
608
603
|
i0.ɵɵadvance();
|
|
609
|
-
i0.ɵɵ
|
|
604
|
+
i0.ɵɵconditional(ctx_r1.MainTab === "scopes" ? 33 : -1);
|
|
610
605
|
i0.ɵɵadvance();
|
|
611
|
-
i0.ɵɵ
|
|
606
|
+
i0.ɵɵconditional(ctx_r1.MainTab === "usage" ? 34 : -1);
|
|
612
607
|
i0.ɵɵadvance(2);
|
|
613
608
|
i0.ɵɵclassProp("fa-bars", !ctx_r1.NavOpen)("fa-times", ctx_r1.NavOpen);
|
|
614
609
|
} }
|
|
615
|
-
/** Tree shaking prevention function */
|
|
616
|
-
export function LoadAPIKeysResource() {
|
|
617
|
-
// This function prevents tree shaking
|
|
618
|
-
}
|
|
619
610
|
/**
|
|
620
611
|
* API Keys Resource Component
|
|
621
612
|
* Provides management interface for MJ API Keys including:
|
|
@@ -1114,26 +1105,27 @@ let APIKeysResourceComponent = class APIKeysResourceComponent extends BaseResour
|
|
|
1114
1105
|
} if (rf & 2) {
|
|
1115
1106
|
let _t;
|
|
1116
1107
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.keyListComponent = _t.first);
|
|
1117
|
-
} }, features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 9, consts: [["keyList", ""], [1, "api-keys-dashboard"], ["text", "Loading API Keys..."
|
|
1108
|
+
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 9, consts: [["keyList", ""], [1, "api-keys-dashboard"], ["text", "Loading API Keys..."], [3, "Created", "Closed", "Visible"], [3, "Updated", "Revoked", "Closed", "Visible", "KeyId"], [1, "dashboard-nav"], [1, "nav-header"], [1, "nav-title"], [1, "fa-solid", "fa-key"], [1, "nav-items"], [1, "nav-item", 3, "click"], [1, "nav-label"], [1, "nav-badge"], [1, "fa-solid", "fa-cube"], [1, "fa-solid", "fa-shield-halved"], [1, "fa-solid", "fa-chart-line"], [1, "dashboard-content"], [1, "content-wrapper"], [1, "mobile-nav-toggle", 3, "click"], [1, "fa-solid"], [1, "mobile-nav-overlay", 3, "click"], [1, "overview-header"], [1, "header-left"], [1, "overview-title"], [1, "overview-subtitle"], [1, "header-actions"], ["title", "Refresh", 1, "btn-refresh", 3, "click"], [1, "fa-solid", "fa-refresh"], [1, "btn-primary"], [1, "health-banner", 3, "ngClass"], [1, "health-score-container"], [1, "health-score-ring"], ["viewBox", "0 0 36 36", 1, "circular-chart"], ["d", "M18 2.0845\n a 15.9155 15.9155 0 0 1 0 31.831\n a 15.9155 15.9155 0 0 1 0 -31.831", 1, "circle-bg"], ["d", "M18 2.0845\n a 15.9155 15.9155 0 0 1 0 31.831\n a 15.9155 15.9155 0 0 1 0 -31.831", 1, "circle"], [1, "health-score-value"], [1, "health-info"], [1, "health-label"], [1, "health-details"], [1, "health-alert"], [1, "health-warning-text"], [1, "health-info-text"], [1, "health-ok"], [1, "kpi-row"], [1, "kpi-card", "clickable", 3, "click"], [1, "kpi-icon"], [1, "kpi-content"], [1, "kpi-value"], [1, "kpi-label"], [1, "kpi-trend"], [1, "fa-solid", "fa-arrow-right"], [1, "kpi-card", "active", "clickable", 3, "click"], [1, "fa-solid", "fa-check-circle"], [1, "kpi-trend", "success"], [1, "percentage"], [1, "fa-solid", "fa-clock"], [1, "kpi-trend", "warning"], [1, "fa-solid", "fa-ban"], [1, "content-grid"], [1, "panel", "keys-panel"], [1, "panel-header"], [1, "panel-title"], [1, "panel-action", 3, "click"], [1, "panel-body"], [1, "key-list"], [1, "empty-state"], [1, "panel", "scope-panel"], [1, "panel-subtitle"], [1, "scope-chart"], [1, "panel", "activity-panel"], [1, "fa-solid", "fa-clock-rotate-left"], [1, "activity-list"], [1, "quick-actions"], [1, "security-notice"], [1, "fa-solid", "fa-shield-check"], [1, "notice-content"], [1, "btn-primary", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "health-alert", 3, "click"], [1, "fa-solid", "fa-circle-exclamation"], [1, "health-warning-text", 3, "click"], [1, "health-info-text", 3, "click"], [1, "fa-solid", "fa-question-circle"], [1, "key-item"], [1, "key-item", 3, "click"], [1, "key-icon"], [1, "key-info"], [1, "key-label"], [1, "key-meta"], [1, "key-user"], [1, "key-hash"], [1, "key-status"], [1, "last-used"], [1, "expiration", 3, "ngClass"], [1, "donut-chart-container"], ["viewBox", "0 0 100 100", 1, "donut-chart"], ["cx", "50", "cy", "50", "r", "40", "fill", "none", "stroke", "#e5e7eb", "stroke-width", "12"], [1, "donut-center"], [1, "donut-total"], [1, "donut-label"], [1, "scope-legend"], [1, "legend-item"], ["cx", "50", "cy", "50", "r", "40", "fill", "none", "stroke-width", "12", 1, "donut-segment", 3, "click"], [1, "legend-item", 3, "click"], [1, "legend-color"], [1, "legend-info"], [1, "legend-name"], [1, "legend-value"], [1, "fa-solid", "fa-chevron-right", "legend-arrow"], [1, "activity-item"], [1, "activity-item", 3, "click"], [1, "activity-icon", 3, "ngClass"], [1, "activity-info"], [1, "activity-name"], [1, "activity-meta"], [1, "activity-action"], [1, "activity-user"], [1, "activity-time"], [1, "fa-solid", "fa-inbox"], [1, "quick-actions-title"], [1, "quick-actions-grid"], [1, "quick-action", 3, "click"], [1, "fa-solid", "fa-list"], [1, "list-view-header"], [1, "back-btn", 3, "click"], [1, "fa-solid", "fa-arrow-left"], [3, "KeySelected", "CreateRequested", "Filter"], [3, "ApplicationUpdated"], [3, "ScopeUpdated"]], template: function APIKeysResourceComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1118
1109
|
i0.ɵɵelementStart(0, "div", 1);
|
|
1119
|
-
i0.ɵɵ
|
|
1120
|
-
i0.ɵɵ
|
|
1110
|
+
i0.ɵɵconditionalCreate(1, APIKeysResourceComponent_Conditional_1_Template, 1, 0, "mj-loading", 2);
|
|
1111
|
+
i0.ɵɵconditionalCreate(2, APIKeysResourceComponent_Conditional_2_Template, 38, 19);
|
|
1112
|
+
i0.ɵɵelementStart(3, "mj-api-key-create-dialog", 3);
|
|
1121
1113
|
i0.ɵɵlistener("Created", function APIKeysResourceComponent_Template_mj_api_key_create_dialog_Created_3_listener($event) { return ctx.onKeyCreated($event); })("Closed", function APIKeysResourceComponent_Template_mj_api_key_create_dialog_Closed_3_listener() { return ctx.onCreateDialogClosed(); });
|
|
1122
1114
|
i0.ɵɵelementEnd();
|
|
1123
|
-
i0.ɵɵelementStart(4, "mj-api-key-edit-panel",
|
|
1115
|
+
i0.ɵɵelementStart(4, "mj-api-key-edit-panel", 4);
|
|
1124
1116
|
i0.ɵɵlistener("Updated", function APIKeysResourceComponent_Template_mj_api_key_edit_panel_Updated_4_listener() { return ctx.onKeyUpdated(); })("Revoked", function APIKeysResourceComponent_Template_mj_api_key_edit_panel_Revoked_4_listener() { return ctx.onKeyRevoked(); })("Closed", function APIKeysResourceComponent_Template_mj_api_key_edit_panel_Closed_4_listener() { return ctx.onEditPanelClosed(); });
|
|
1125
1117
|
i0.ɵɵelementEnd()();
|
|
1126
1118
|
} if (rf & 2) {
|
|
1127
1119
|
i0.ɵɵclassProp("panel-open", ctx.ShowCreateDialog || ctx.ShowEditPanel)("nav-open", ctx.NavOpen);
|
|
1128
1120
|
i0.ɵɵadvance();
|
|
1129
|
-
i0.ɵɵ
|
|
1121
|
+
i0.ɵɵconditional(ctx.IsLoading ? 1 : -1);
|
|
1130
1122
|
i0.ɵɵadvance();
|
|
1131
|
-
i0.ɵɵ
|
|
1123
|
+
i0.ɵɵconditional(!ctx.IsLoading ? 2 : -1);
|
|
1132
1124
|
i0.ɵɵadvance();
|
|
1133
1125
|
i0.ɵɵproperty("Visible", ctx.ShowCreateDialog);
|
|
1134
1126
|
i0.ɵɵadvance();
|
|
1135
1127
|
i0.ɵɵproperty("Visible", ctx.ShowEditPanel)("KeyId", ctx.SelectedKeyId);
|
|
1136
|
-
} }, dependencies: [i1.NgClass, i1.NgForOf, i1.NgIf, i2.LoadingComponent, i3.APIKeyCreateDialogComponent, i4.APIKeyEditPanelComponent, i5.APIKeyListComponent, i6.APIApplicationsPanelComponent, i7.APIScopesPanelComponent, i8.APIUsagePanelComponent], styles: ["\n\n.api-keys-dashboard[_ngcontent-%COMP%] {\n display: flex;\n height: 100%;\n position: relative;\n overflow: hidden;\n}\n\n.api-keys-dashboard.panel-open[_ngcontent-%COMP%] .dashboard-content[_ngcontent-%COMP%] {\n overflow: hidden;\n}\n\n\n\n.dashboard-nav[_ngcontent-%COMP%] {\n width: 220px;\n background: var(--card-background, #ffffff);\n border-right: 1px solid var(--border-color, #e5e7eb);\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n}\n\n.nav-header[_ngcontent-%COMP%] {\n padding: 20px;\n border-bottom: 1px solid var(--border-color, #e5e7eb);\n}\n\n.nav-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-weight: 700;\n font-size: 16px;\n color: var(--text-primary, #1f2937);\n}\n\n.nav-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #f59e0b;\n font-size: 18px;\n}\n\n.nav-items[_ngcontent-%COMP%] {\n flex: 1;\n padding: 12px;\n overflow-y: auto;\n}\n\n.nav-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n margin-bottom: 4px;\n background: transparent;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.2s ease;\n width: 100%;\n text-align: left;\n}\n\n.nav-item[_ngcontent-%COMP%]:hover {\n background: var(--item-hover, #f3f4f6);\n color: var(--text-primary, #1f2937);\n}\n\n.nav-item.active[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n color: white;\n box-shadow: 0 2px 8px rgba(245, 158, 11, 0.3);\n}\n\n.nav-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n width: 20px;\n text-align: center;\n}\n\n.nav-item[_ngcontent-%COMP%] .nav-label[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.nav-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 22px;\n height: 20px;\n padding: 0 6px;\n background: rgba(0, 0, 0, 0.1);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.nav-item.active[_ngcontent-%COMP%] .nav-badge[_ngcontent-%COMP%] {\n background: rgba(255, 255, 255, 0.25);\n}\n\n\n\n.dashboard-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n min-width: 0;\n}\n\n.content-wrapper[_ngcontent-%COMP%] {\n flex: 1;\n padding: 24px;\n overflow-y: auto;\n}\n\n\n\n.list-view-header[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.back-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.back-btn[_ngcontent-%COMP%]:hover {\n background: var(--item-hover, #f3f4f6);\n color: var(--text-primary, #1f2937);\n}\n\n\n\n.overview-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.header-left[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.overview-title[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 4px 0;\n}\n\n.overview-subtitle[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n}\n\n.btn-refresh[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-refresh[_ngcontent-%COMP%]:hover {\n background: var(--item-hover, #f3f4f6);\n}\n\n.btn-refresh[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--text-secondary, #6b7280);\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n color: white;\n border: none;\n border-radius: 8px;\n font-weight: 600;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(245, 158, 11, 0.4);\n}\n\n\n\n.health-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 20px 24px;\n background: linear-gradient(135deg, #ecfdf5 0%, #d1fae5 100%);\n border: 1px solid #a7f3d0;\n border-radius: 16px;\n margin-bottom: 24px;\n}\n\n.health-banner.health-warning[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);\n border-color: #fcd34d;\n}\n\n.health-banner.health-critical[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%);\n border-color: #fca5a5;\n}\n\n.health-score-container[_ngcontent-%COMP%] {\n margin-right: 24px;\n}\n\n.health-score-ring[_ngcontent-%COMP%] {\n position: relative;\n width: 80px;\n height: 80px;\n}\n\n.circular-chart[_ngcontent-%COMP%] {\n display: block;\n margin: 0 auto;\n max-height: 80px;\n transform: rotate(-90deg);\n}\n\n.circle-bg[_ngcontent-%COMP%] {\n fill: none;\n stroke: #e5e7eb;\n stroke-width: 3.8;\n}\n\n.circle[_ngcontent-%COMP%] {\n fill: none;\n stroke-width: 3.8;\n stroke-linecap: round;\n stroke: #10b981;\n animation: _ngcontent-%COMP%_progress 1s ease-out forwards;\n}\n\n.health-banner.health-warning[_ngcontent-%COMP%] .circle[_ngcontent-%COMP%] {\n stroke: #f59e0b;\n}\n\n.health-banner.health-critical[_ngcontent-%COMP%] .circle[_ngcontent-%COMP%] {\n stroke: #ef4444;\n}\n\n@keyframes _ngcontent-%COMP%_progress {\n 0% {\n stroke-dasharray: 0 100;\n }\n}\n\n.health-score-value[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 20px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n}\n\n.health-info[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.health-label[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: #059669;\n margin-bottom: 4px;\n}\n\n.health-banner.health-warning[_ngcontent-%COMP%] .health-label[_ngcontent-%COMP%] {\n color: #d97706;\n}\n\n.health-banner.health-critical[_ngcontent-%COMP%] .health-label[_ngcontent-%COMP%] {\n color: #dc2626;\n}\n\n.health-details[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.health-alert[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #dc2626;\n font-weight: 500;\n font-size: 14px;\n cursor: pointer;\n}\n\n.health-alert[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n}\n\n.health-warning-text[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #d97706;\n font-weight: 500;\n font-size: 14px;\n cursor: pointer;\n}\n\n.health-warning-text[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n}\n\n.health-info-text[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #6b7280;\n font-weight: 500;\n font-size: 14px;\n cursor: pointer;\n}\n\n.health-info-text[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n}\n\n.health-ok[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #059669;\n font-weight: 500;\n font-size: 14px;\n}\n\n\n\n.kpi-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 16px 20px;\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.kpi-card.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.kpi-card.clickable[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n\n.kpi-card.active[_ngcontent-%COMP%] .kpi-icon[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n}\n\n.kpi-card.warning[_ngcontent-%COMP%] .kpi-icon[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n}\n\n.kpi-card.danger[_ngcontent-%COMP%] .kpi-icon[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);\n}\n\n.kpi-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n border-radius: 10px;\n margin-right: 14px;\n flex-shrink: 0;\n}\n\n.kpi-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: white;\n}\n\n.kpi-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n line-height: 1.2;\n}\n\n.kpi-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n margin-top: 2px;\n white-space: nowrap;\n}\n\n.kpi-trend[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n margin-left: 8px;\n color: var(--text-tertiary, #9ca3af);\n}\n\n.kpi-trend.success[_ngcontent-%COMP%] {\n color: #10b981;\n}\n\n.kpi-trend.warning[_ngcontent-%COMP%] {\n color: #f59e0b;\n}\n\n.kpi-trend[_ngcontent-%COMP%] .percentage[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n}\n\n\n\n.content-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 1fr;\n grid-template-rows: auto auto;\n gap: 20px;\n margin-bottom: 24px;\n}\n\n.keys-panel[_ngcontent-%COMP%] {\n grid-row: span 1;\n}\n\n.scope-panel[_ngcontent-%COMP%] {\n grid-row: span 1;\n}\n\n.activity-panel[_ngcontent-%COMP%] {\n grid-column: span 2;\n}\n\n.panel[_ngcontent-%COMP%] {\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: var(--header-background, #f9fafb);\n border-bottom: 1px solid var(--border-color, #e5e7eb);\n}\n\n.panel-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-weight: 600;\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n}\n\n.panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #f59e0b;\n}\n\n.panel-subtitle[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--text-tertiary, #9ca3af);\n}\n\n.panel-action[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: transparent;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.panel-action[_ngcontent-%COMP%]:hover {\n background: #f59e0b;\n border-color: #f59e0b;\n color: white;\n}\n\n.panel-body[_ngcontent-%COMP%] {\n padding: 20px;\n flex: 1;\n overflow-y: auto;\n}\n\n\n\n.key-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.key-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 14px 16px;\n background: var(--item-background, #f9fafb);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.key-item[_ngcontent-%COMP%]:hover {\n background: var(--item-hover, #f3f4f6);\n transform: translateX(4px);\n}\n\n.key-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #6b7280 0%, #4b5563 100%);\n border-radius: 8px;\n margin-right: 14px;\n flex-shrink: 0;\n}\n\n.key-icon.active[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n}\n\n.key-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n color: white;\n}\n\n.key-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.key-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.key-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 2px;\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n.key-hash[_ngcontent-%COMP%] {\n font-family: monospace;\n background: var(--tag-background, #e5e7eb);\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 11px;\n}\n\n.key-status[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 4px;\n margin-left: 16px;\n}\n\n.last-used[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n.expiration[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--text-tertiary, #9ca3af);\n}\n\n.expiration.expiring-soon[_ngcontent-%COMP%] {\n color: #f59e0b;\n font-weight: 500;\n}\n\n.expiration.expiring-critical[_ngcontent-%COMP%] {\n color: #ef4444;\n font-weight: 500;\n}\n\n.expiration.expired[_ngcontent-%COMP%] {\n color: #ef4444;\n font-weight: 600;\n}\n\n\n\n.scope-chart[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 24px;\n height: 100%;\n}\n\n.donut-chart-container[_ngcontent-%COMP%] {\n position: relative;\n width: 160px;\n height: 160px;\n margin: 0 auto;\n}\n\n.donut-chart[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n transform: rotate(-90deg);\n}\n\n.donut-segment[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: opacity 0.2s ease;\n}\n\n.donut-segment[_ngcontent-%COMP%]:hover {\n opacity: 0.8;\n}\n\n.donut-center[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n text-align: center;\n}\n\n.donut-total[_ngcontent-%COMP%] {\n font-size: 28px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n}\n\n.donut-label[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--text-secondary, #6b7280);\n}\n\n\n\n.scope-legend[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.legend-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n background: var(--item-background, #f9fafb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.legend-item[_ngcontent-%COMP%]:hover {\n background: var(--item-hover, #f3f4f6);\n transform: translateX(4px);\n}\n\n.legend-color[_ngcontent-%COMP%] {\n width: 12px;\n height: 12px;\n border-radius: 4px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.legend-info[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.legend-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--text-primary, #1f2937);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.legend-name[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n.legend-value[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n.legend-arrow[_ngcontent-%COMP%] {\n color: var(--text-tertiary, #9ca3af);\n font-size: 10px;\n}\n\n\n\n.activity-list[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 12px;\n}\n\n.activity-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px 14px;\n background: var(--item-background, #f9fafb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.activity-item[_ngcontent-%COMP%]:hover {\n background: var(--item-hover, #f3f4f6);\n}\n\n.activity-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--icon-background, #fef3c7);\n border-radius: 6px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.activity-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #f59e0b;\n}\n\n.activity-icon.action-created[_ngcontent-%COMP%] {\n background: #d1fae5;\n}\n\n.activity-icon.action-created[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #059669;\n}\n\n.activity-icon.action-updated[_ngcontent-%COMP%] {\n background: #e0e7ff;\n}\n\n.activity-icon.action-updated[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6366f1;\n}\n\n.activity-icon.action-revoked[_ngcontent-%COMP%] {\n background: #fee2e2;\n}\n\n.activity-icon.action-revoked[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #dc2626;\n}\n\n.activity-icon.action-used[_ngcontent-%COMP%] {\n background: #fef3c7;\n}\n\n.activity-icon.action-used[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #d97706;\n}\n\n.activity-icon.action-extended[_ngcontent-%COMP%] {\n background: #dbeafe;\n}\n\n.activity-icon.action-extended[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n.activity-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.activity-name[_ngcontent-%COMP%] {\n font-weight: 500;\n font-size: 13px;\n color: var(--text-primary, #1f2937);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.activity-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 2px;\n font-size: 11px;\n color: var(--text-secondary, #6b7280);\n}\n\n.activity-action[_ngcontent-%COMP%] {\n font-weight: 500;\n text-transform: capitalize;\n}\n\n.activity-time[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--text-tertiary, #9ca3af);\n white-space: nowrap;\n}\n\n\n\n.quick-actions[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n\n.quick-actions-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin-bottom: 12px;\n}\n\n.quick-actions-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 12px;\n}\n\n.quick-action[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 16px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.quick-action[_ngcontent-%COMP%]:hover {\n border-color: #f59e0b;\n background: #fffbeb;\n transform: translateY(-2px);\n}\n\n.quick-action[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: #f59e0b;\n}\n\n.quick-action[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 32px;\n color: var(--text-secondary, #6b7280);\n text-align: center;\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n margin-bottom: 12px;\n opacity: 0.5;\n}\n\n\n\n.security-notice[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n padding: 16px 20px;\n background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);\n border-radius: 12px;\n border: 1px solid #fcd34d;\n}\n\n.security-notice[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: #f59e0b;\n margin-right: 12px;\n margin-top: 2px;\n}\n\n.notice-content[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #92400e;\n line-height: 1.5;\n}\n\n.notice-content[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n\n\n\n.mobile-nav-toggle[_ngcontent-%COMP%] {\n display: none;\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 56px;\n height: 56px;\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n border: none;\n border-radius: 50%;\n color: white;\n font-size: 24px;\n box-shadow: 0 4px 16px rgba(245, 158, 11, 0.4);\n cursor: pointer;\n z-index: 50;\n transition: transform 0.2s ease;\n}\n\n.mobile-nav-toggle[_ngcontent-%COMP%]:hover {\n transform: scale(1.05);\n}\n\n\n\n.mobile-nav-overlay[_ngcontent-%COMP%] {\n display: none;\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n z-index: 90;\n}\n\n\n\n\n\n\n\n\n@media (max-width: 1024px) {\n .content-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .activity-panel[_ngcontent-%COMP%] {\n grid-column: span 1;\n }\n\n .scope-chart[_ngcontent-%COMP%] {\n flex-direction: row;\n align-items: center;\n }\n\n .donut-chart-container[_ngcontent-%COMP%] {\n width: 140px;\n height: 140px;\n }\n\n .scope-legend[_ngcontent-%COMP%] {\n flex: 1;\n }\n\n .dashboard-nav[_ngcontent-%COMP%] {\n width: 200px;\n }\n}\n\n\n\n@media (max-width: 768px) {\n .api-keys-dashboard[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .dashboard-nav[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: -280px;\n width: 280px;\n height: 100%;\n z-index: 100;\n transition: left 0.3s ease;\n box-shadow: 4px 0 20px rgba(0, 0, 0, 0.15);\n }\n\n .api-keys-dashboard.nav-open[_ngcontent-%COMP%] .dashboard-nav[_ngcontent-%COMP%] {\n left: 0;\n }\n\n .mobile-nav-toggle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .mobile-nav-overlay[_ngcontent-%COMP%] {\n display: block;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.3s ease;\n }\n\n .api-keys-dashboard.nav-open[_ngcontent-%COMP%] .mobile-nav-overlay[_ngcontent-%COMP%] {\n opacity: 1;\n pointer-events: auto;\n }\n\n .dashboard-content[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .content-wrapper[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .overview-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-actions[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: flex-end;\n }\n\n .health-banner[_ngcontent-%COMP%] {\n flex-direction: column;\n text-align: center;\n }\n\n .health-score-container[_ngcontent-%COMP%] {\n margin-right: 0;\n margin-bottom: 16px;\n }\n\n .kpi-row[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .scope-chart[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .quick-actions-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .activity-list[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .key-item[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n }\n\n .key-status[_ngcontent-%COMP%] {\n width: 100%;\n flex-direction: row;\n justify-content: flex-start;\n margin-left: 54px;\n margin-top: 8px;\n gap: 12px;\n }\n}\n\n\n\n@media (max-width: 480px) {\n .kpi-row[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .quick-actions-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .kpi-card[_ngcontent-%COMP%] {\n padding: 12px 16px;\n }\n\n .kpi-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n }\n\n .kpi-value[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .overview-title[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .btn-primary[_ngcontent-%COMP%] {\n padding: 8px 16px;\n font-size: 13px;\n }\n}"] });
|
|
1128
|
+
} }, dependencies: [i1.NgClass, i2.LoadingComponent, i3.APIKeyCreateDialogComponent, i4.APIKeyEditPanelComponent, i5.APIKeyListComponent, i6.APIApplicationsPanelComponent, i7.APIScopesPanelComponent, i8.APIUsagePanelComponent], styles: ["\n\n.api-keys-dashboard[_ngcontent-%COMP%] {\n display: flex;\n height: 100%;\n position: relative;\n overflow: hidden;\n}\n\n.api-keys-dashboard.panel-open[_ngcontent-%COMP%] .dashboard-content[_ngcontent-%COMP%] {\n overflow: hidden;\n}\n\n\n\n.dashboard-nav[_ngcontent-%COMP%] {\n width: 220px;\n background: var(--card-background, #ffffff);\n border-right: 1px solid var(--border-color, #e5e7eb);\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n}\n\n.nav-header[_ngcontent-%COMP%] {\n padding: 20px;\n border-bottom: 1px solid var(--border-color, #e5e7eb);\n}\n\n.nav-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-weight: 700;\n font-size: 16px;\n color: var(--text-primary, #1f2937);\n}\n\n.nav-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #f59e0b;\n font-size: 18px;\n}\n\n.nav-items[_ngcontent-%COMP%] {\n flex: 1;\n padding: 12px;\n overflow-y: auto;\n}\n\n.nav-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n margin-bottom: 4px;\n background: transparent;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.2s ease;\n width: 100%;\n text-align: left;\n}\n\n.nav-item[_ngcontent-%COMP%]:hover {\n background: var(--item-hover, #f3f4f6);\n color: var(--text-primary, #1f2937);\n}\n\n.nav-item.active[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n color: white;\n box-shadow: 0 2px 8px rgba(245, 158, 11, 0.3);\n}\n\n.nav-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n width: 20px;\n text-align: center;\n}\n\n.nav-item[_ngcontent-%COMP%] .nav-label[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.nav-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 22px;\n height: 20px;\n padding: 0 6px;\n background: rgba(0, 0, 0, 0.1);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.nav-item.active[_ngcontent-%COMP%] .nav-badge[_ngcontent-%COMP%] {\n background: rgba(255, 255, 255, 0.25);\n}\n\n\n\n.dashboard-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n min-width: 0;\n}\n\n.content-wrapper[_ngcontent-%COMP%] {\n flex: 1;\n padding: 24px;\n overflow-y: auto;\n}\n\n\n\n.list-view-header[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.back-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.back-btn[_ngcontent-%COMP%]:hover {\n background: var(--item-hover, #f3f4f6);\n color: var(--text-primary, #1f2937);\n}\n\n\n\n.overview-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.header-left[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.overview-title[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 4px 0;\n}\n\n.overview-subtitle[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n}\n\n.btn-refresh[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-refresh[_ngcontent-%COMP%]:hover {\n background: var(--item-hover, #f3f4f6);\n}\n\n.btn-refresh[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--text-secondary, #6b7280);\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n color: white;\n border: none;\n border-radius: 8px;\n font-weight: 600;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(245, 158, 11, 0.4);\n}\n\n\n\n.health-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 20px 24px;\n background: linear-gradient(135deg, #ecfdf5 0%, #d1fae5 100%);\n border: 1px solid #a7f3d0;\n border-radius: 16px;\n margin-bottom: 24px;\n}\n\n.health-banner.health-warning[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);\n border-color: #fcd34d;\n}\n\n.health-banner.health-critical[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%);\n border-color: #fca5a5;\n}\n\n.health-score-container[_ngcontent-%COMP%] {\n margin-right: 24px;\n}\n\n.health-score-ring[_ngcontent-%COMP%] {\n position: relative;\n width: 80px;\n height: 80px;\n}\n\n.circular-chart[_ngcontent-%COMP%] {\n display: block;\n margin: 0 auto;\n max-height: 80px;\n transform: rotate(-90deg);\n}\n\n.circle-bg[_ngcontent-%COMP%] {\n fill: none;\n stroke: #e5e7eb;\n stroke-width: 3.8;\n}\n\n.circle[_ngcontent-%COMP%] {\n fill: none;\n stroke-width: 3.8;\n stroke-linecap: round;\n stroke: #10b981;\n animation: _ngcontent-%COMP%_progress 1s ease-out forwards;\n}\n\n.health-banner.health-warning[_ngcontent-%COMP%] .circle[_ngcontent-%COMP%] {\n stroke: #f59e0b;\n}\n\n.health-banner.health-critical[_ngcontent-%COMP%] .circle[_ngcontent-%COMP%] {\n stroke: #ef4444;\n}\n\n@keyframes _ngcontent-%COMP%_progress {\n 0% {\n stroke-dasharray: 0 100;\n }\n}\n\n.health-score-value[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 20px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n}\n\n.health-info[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.health-label[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: #059669;\n margin-bottom: 4px;\n}\n\n.health-banner.health-warning[_ngcontent-%COMP%] .health-label[_ngcontent-%COMP%] {\n color: #d97706;\n}\n\n.health-banner.health-critical[_ngcontent-%COMP%] .health-label[_ngcontent-%COMP%] {\n color: #dc2626;\n}\n\n.health-details[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.health-alert[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #dc2626;\n font-weight: 500;\n font-size: 14px;\n cursor: pointer;\n}\n\n.health-alert[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n}\n\n.health-warning-text[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #d97706;\n font-weight: 500;\n font-size: 14px;\n cursor: pointer;\n}\n\n.health-warning-text[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n}\n\n.health-info-text[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #6b7280;\n font-weight: 500;\n font-size: 14px;\n cursor: pointer;\n}\n\n.health-info-text[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n}\n\n.health-ok[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #059669;\n font-weight: 500;\n font-size: 14px;\n}\n\n\n\n.kpi-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 16px 20px;\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.kpi-card.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.kpi-card.clickable[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n\n.kpi-card.active[_ngcontent-%COMP%] .kpi-icon[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n}\n\n.kpi-card.warning[_ngcontent-%COMP%] .kpi-icon[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n}\n\n.kpi-card.danger[_ngcontent-%COMP%] .kpi-icon[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);\n}\n\n.kpi-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n border-radius: 10px;\n margin-right: 14px;\n flex-shrink: 0;\n}\n\n.kpi-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: white;\n}\n\n.kpi-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n line-height: 1.2;\n}\n\n.kpi-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n margin-top: 2px;\n white-space: nowrap;\n}\n\n.kpi-trend[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n margin-left: 8px;\n color: var(--text-tertiary, #9ca3af);\n}\n\n.kpi-trend.success[_ngcontent-%COMP%] {\n color: #10b981;\n}\n\n.kpi-trend.warning[_ngcontent-%COMP%] {\n color: #f59e0b;\n}\n\n.kpi-trend[_ngcontent-%COMP%] .percentage[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n}\n\n\n\n.content-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 1fr;\n grid-template-rows: auto auto;\n gap: 20px;\n margin-bottom: 24px;\n}\n\n.keys-panel[_ngcontent-%COMP%] {\n grid-row: span 1;\n}\n\n.scope-panel[_ngcontent-%COMP%] {\n grid-row: span 1;\n}\n\n.activity-panel[_ngcontent-%COMP%] {\n grid-column: span 2;\n}\n\n.panel[_ngcontent-%COMP%] {\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: var(--header-background, #f9fafb);\n border-bottom: 1px solid var(--border-color, #e5e7eb);\n}\n\n.panel-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-weight: 600;\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n}\n\n.panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #f59e0b;\n}\n\n.panel-subtitle[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--text-tertiary, #9ca3af);\n}\n\n.panel-action[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: transparent;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.panel-action[_ngcontent-%COMP%]:hover {\n background: #f59e0b;\n border-color: #f59e0b;\n color: white;\n}\n\n.panel-body[_ngcontent-%COMP%] {\n padding: 20px;\n flex: 1;\n overflow-y: auto;\n}\n\n\n\n.key-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.key-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 14px 16px;\n background: var(--item-background, #f9fafb);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.key-item[_ngcontent-%COMP%]:hover {\n background: var(--item-hover, #f3f4f6);\n transform: translateX(4px);\n}\n\n.key-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #6b7280 0%, #4b5563 100%);\n border-radius: 8px;\n margin-right: 14px;\n flex-shrink: 0;\n}\n\n.key-icon.active[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n}\n\n.key-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n color: white;\n}\n\n.key-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.key-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.key-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 2px;\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n.key-hash[_ngcontent-%COMP%] {\n font-family: monospace;\n background: var(--tag-background, #e5e7eb);\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 11px;\n}\n\n.key-status[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 4px;\n margin-left: 16px;\n}\n\n.last-used[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n.expiration[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--text-tertiary, #9ca3af);\n}\n\n.expiration.expiring-soon[_ngcontent-%COMP%] {\n color: #f59e0b;\n font-weight: 500;\n}\n\n.expiration.expiring-critical[_ngcontent-%COMP%] {\n color: #ef4444;\n font-weight: 500;\n}\n\n.expiration.expired[_ngcontent-%COMP%] {\n color: #ef4444;\n font-weight: 600;\n}\n\n\n\n.scope-chart[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 24px;\n height: 100%;\n}\n\n.donut-chart-container[_ngcontent-%COMP%] {\n position: relative;\n width: 160px;\n height: 160px;\n margin: 0 auto;\n}\n\n.donut-chart[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n transform: rotate(-90deg);\n}\n\n.donut-segment[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: opacity 0.2s ease;\n}\n\n.donut-segment[_ngcontent-%COMP%]:hover {\n opacity: 0.8;\n}\n\n.donut-center[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n text-align: center;\n}\n\n.donut-total[_ngcontent-%COMP%] {\n font-size: 28px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n}\n\n.donut-label[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--text-secondary, #6b7280);\n}\n\n\n\n.scope-legend[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.legend-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n background: var(--item-background, #f9fafb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.legend-item[_ngcontent-%COMP%]:hover {\n background: var(--item-hover, #f3f4f6);\n transform: translateX(4px);\n}\n\n.legend-color[_ngcontent-%COMP%] {\n width: 12px;\n height: 12px;\n border-radius: 4px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.legend-info[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.legend-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--text-primary, #1f2937);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.legend-name[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n.legend-value[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n.legend-arrow[_ngcontent-%COMP%] {\n color: var(--text-tertiary, #9ca3af);\n font-size: 10px;\n}\n\n\n\n.activity-list[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 12px;\n}\n\n.activity-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px 14px;\n background: var(--item-background, #f9fafb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.activity-item[_ngcontent-%COMP%]:hover {\n background: var(--item-hover, #f3f4f6);\n}\n\n.activity-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--icon-background, #fef3c7);\n border-radius: 6px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.activity-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #f59e0b;\n}\n\n.activity-icon.action-created[_ngcontent-%COMP%] {\n background: #d1fae5;\n}\n\n.activity-icon.action-created[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #059669;\n}\n\n.activity-icon.action-updated[_ngcontent-%COMP%] {\n background: #e0e7ff;\n}\n\n.activity-icon.action-updated[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6366f1;\n}\n\n.activity-icon.action-revoked[_ngcontent-%COMP%] {\n background: #fee2e2;\n}\n\n.activity-icon.action-revoked[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #dc2626;\n}\n\n.activity-icon.action-used[_ngcontent-%COMP%] {\n background: #fef3c7;\n}\n\n.activity-icon.action-used[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #d97706;\n}\n\n.activity-icon.action-extended[_ngcontent-%COMP%] {\n background: #dbeafe;\n}\n\n.activity-icon.action-extended[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n.activity-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.activity-name[_ngcontent-%COMP%] {\n font-weight: 500;\n font-size: 13px;\n color: var(--text-primary, #1f2937);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.activity-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 2px;\n font-size: 11px;\n color: var(--text-secondary, #6b7280);\n}\n\n.activity-action[_ngcontent-%COMP%] {\n font-weight: 500;\n text-transform: capitalize;\n}\n\n.activity-time[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--text-tertiary, #9ca3af);\n white-space: nowrap;\n}\n\n\n\n.quick-actions[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n\n.quick-actions-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin-bottom: 12px;\n}\n\n.quick-actions-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 12px;\n}\n\n.quick-action[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 16px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.quick-action[_ngcontent-%COMP%]:hover {\n border-color: #f59e0b;\n background: #fffbeb;\n transform: translateY(-2px);\n}\n\n.quick-action[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: #f59e0b;\n}\n\n.quick-action[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 32px;\n color: var(--text-secondary, #6b7280);\n text-align: center;\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n margin-bottom: 12px;\n opacity: 0.5;\n}\n\n\n\n.security-notice[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n padding: 16px 20px;\n background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);\n border-radius: 12px;\n border: 1px solid #fcd34d;\n}\n\n.security-notice[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: #f59e0b;\n margin-right: 12px;\n margin-top: 2px;\n}\n\n.notice-content[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #92400e;\n line-height: 1.5;\n}\n\n.notice-content[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n\n\n\n.mobile-nav-toggle[_ngcontent-%COMP%] {\n display: none;\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 56px;\n height: 56px;\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n border: none;\n border-radius: 50%;\n color: white;\n font-size: 24px;\n box-shadow: 0 4px 16px rgba(245, 158, 11, 0.4);\n cursor: pointer;\n z-index: 50;\n transition: transform 0.2s ease;\n}\n\n.mobile-nav-toggle[_ngcontent-%COMP%]:hover {\n transform: scale(1.05);\n}\n\n\n\n.mobile-nav-overlay[_ngcontent-%COMP%] {\n display: none;\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n z-index: 90;\n}\n\n\n\n\n\n\n\n\n@media (max-width: 1024px) {\n .content-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .activity-panel[_ngcontent-%COMP%] {\n grid-column: span 1;\n }\n\n .scope-chart[_ngcontent-%COMP%] {\n flex-direction: row;\n align-items: center;\n }\n\n .donut-chart-container[_ngcontent-%COMP%] {\n width: 140px;\n height: 140px;\n }\n\n .scope-legend[_ngcontent-%COMP%] {\n flex: 1;\n }\n\n .dashboard-nav[_ngcontent-%COMP%] {\n width: 200px;\n }\n}\n\n\n\n@media (max-width: 768px) {\n .api-keys-dashboard[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .dashboard-nav[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: -280px;\n width: 280px;\n height: 100%;\n z-index: 100;\n transition: left 0.3s ease;\n box-shadow: 4px 0 20px rgba(0, 0, 0, 0.15);\n }\n\n .api-keys-dashboard.nav-open[_ngcontent-%COMP%] .dashboard-nav[_ngcontent-%COMP%] {\n left: 0;\n }\n\n .mobile-nav-toggle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .mobile-nav-overlay[_ngcontent-%COMP%] {\n display: block;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.3s ease;\n }\n\n .api-keys-dashboard.nav-open[_ngcontent-%COMP%] .mobile-nav-overlay[_ngcontent-%COMP%] {\n opacity: 1;\n pointer-events: auto;\n }\n\n .dashboard-content[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .content-wrapper[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .overview-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-actions[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: flex-end;\n }\n\n .health-banner[_ngcontent-%COMP%] {\n flex-direction: column;\n text-align: center;\n }\n\n .health-score-container[_ngcontent-%COMP%] {\n margin-right: 0;\n margin-bottom: 16px;\n }\n\n .kpi-row[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .scope-chart[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .quick-actions-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .activity-list[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .key-item[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n }\n\n .key-status[_ngcontent-%COMP%] {\n width: 100%;\n flex-direction: row;\n justify-content: flex-start;\n margin-left: 54px;\n margin-top: 8px;\n gap: 12px;\n }\n}\n\n\n\n@media (max-width: 480px) {\n .kpi-row[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .quick-actions-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .kpi-card[_ngcontent-%COMP%] {\n padding: 12px 16px;\n }\n\n .kpi-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n }\n\n .kpi-value[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .overview-title[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .btn-primary[_ngcontent-%COMP%] {\n padding: 8px 16px;\n font-size: 13px;\n }\n}"] });
|
|
1137
1129
|
};
|
|
1138
1130
|
APIKeysResourceComponent = __decorate([
|
|
1139
1131
|
RegisterClass(BaseResourceComponent, 'APIKeysResource')
|
|
@@ -1141,10 +1133,10 @@ APIKeysResourceComponent = __decorate([
|
|
|
1141
1133
|
export { APIKeysResourceComponent };
|
|
1142
1134
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(APIKeysResourceComponent, [{
|
|
1143
1135
|
type: Component,
|
|
1144
|
-
args: [{ selector: 'mj-api-keys-resource', template: "<div class=\"api-keys-dashboard\" [class.panel-open]=\"ShowCreateDialog || ShowEditPanel\" [class.nav-open]=\"NavOpen\">\n <mj-loading *ngIf=\"IsLoading\" text=\"Loading API Keys...\"></mj-loading>\n\n <ng-container *ngIf=\"!IsLoading\">\n <!-- Left Navigation Sidebar -->\n <div class=\"dashboard-nav\">\n <div class=\"nav-header\">\n <div class=\"nav-title\">\n <i class=\"fa-solid fa-key\"></i>\n <span>API Keys</span>\n </div>\n </div>\n <div class=\"nav-items\">\n <button class=\"nav-item\" [class.active]=\"MainTab === 'keys'\" (click)=\"switchTab('keys'); closeNav()\">\n <i class=\"fa-solid fa-key\"></i>\n <span class=\"nav-label\">API Keys</span>\n <span class=\"nav-badge\">{{TotalKeys}}</span>\n </button>\n <button class=\"nav-item\" [class.active]=\"MainTab === 'applications'\" (click)=\"switchTab('applications'); closeNav()\">\n <i class=\"fa-solid fa-cube\"></i>\n <span class=\"nav-label\">Applications</span>\n <span class=\"nav-badge\">{{ApplicationCount}}</span>\n </button>\n <button class=\"nav-item\" [class.active]=\"MainTab === 'scopes'\" (click)=\"switchTab('scopes'); closeNav()\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span class=\"nav-label\">Scopes</span>\n <span class=\"nav-badge\">{{ScopeCount}}</span>\n </button>\n <button class=\"nav-item\" [class.active]=\"MainTab === 'usage'\" (click)=\"switchTab('usage'); closeNav()\">\n <i class=\"fa-solid fa-chart-line\"></i>\n <span class=\"nav-label\">Usage Analytics</span>\n </button>\n </div>\n </div>\n\n <!-- Main Content Area -->\n <div class=\"dashboard-content\">\n <div class=\"content-wrapper\">\n <!-- Keys Tab Content -->\n <ng-container *ngIf=\"MainTab === 'keys'\">\n <!-- Overview View -->\n <ng-container *ngIf=\"CurrentView === 'overview'\">\n <!-- Header with Actions -->\n <div class=\"overview-header\">\n <div class=\"header-left\">\n <h2 class=\"overview-title\">API Keys Management</h2>\n <p class=\"overview-subtitle\">Manage API keys for external integrations and services</p>\n </div>\n <div class=\"header-actions\">\n <button class=\"btn-refresh\" (click)=\"refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n <button class=\"btn-primary\" *ngIf=\"UserCanCreateKeys\" (click)=\"openCreateDialog()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Generate New Key</span>\n </button>\n </div>\n </div>\n\n <!-- Health Score Banner -->\n <div class=\"health-banner\" [ngClass]=\"getHealthClass()\">\n <div class=\"health-score-container\">\n <div class=\"health-score-ring\">\n <svg viewBox=\"0 0 36 36\" class=\"circular-chart\">\n <path class=\"circle-bg\"\n d=\"M18 2.0845\n a 15.9155 15.9155 0 0 1 0 31.831\n a 15.9155 15.9155 0 0 1 0 -31.831\"\n />\n <path class=\"circle\"\n [attr.stroke-dasharray]=\"getHealthScore() + ', 100'\"\n d=\"M18 2.0845\n a 15.9155 15.9155 0 0 1 0 31.831\n a 15.9155 15.9155 0 0 1 0 -31.831\"\n />\n </svg>\n <div class=\"health-score-value\">{{getHealthScore()}}</div>\n </div>\n </div>\n <div class=\"health-info\">\n <div class=\"health-label\">{{getHealthLabel()}}</div>\n <div class=\"health-details\">\n <span *ngIf=\"ExpiredKeys > 0\" class=\"health-alert\" (click)=\"showListView('expired')\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{ExpiredKeys}} expired\n </span>\n <span *ngIf=\"ExpiringSoonCount > 0\" class=\"health-warning-text\" (click)=\"showListView('expiring')\">\n <i class=\"fa-solid fa-clock\"></i>\n {{ExpiringSoonCount}} expiring soon\n </span>\n <span *ngIf=\"NeverUsedKeys > 0\" class=\"health-info-text\" (click)=\"showListView('never-used')\">\n <i class=\"fa-solid fa-question-circle\"></i>\n {{NeverUsedKeys}} never used\n </span>\n <span *ngIf=\"ExpiredKeys === 0 && ExpiringSoonCount === 0 && NeverUsedKeys === 0\" class=\"health-ok\">\n <i class=\"fa-solid fa-check-circle\"></i>\n All keys healthy\n </span>\n </div>\n </div>\n </div>\n\n <!-- KPI Cards Row -->\n <div class=\"kpi-row\">\n <div class=\"kpi-card clickable\" (click)=\"showListView('all')\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-key\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{TotalKeys}}</div>\n <div class=\"kpi-label\">Total Keys</div>\n </div>\n <div class=\"kpi-trend\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n </div>\n\n <div class=\"kpi-card active clickable\" (click)=\"showListView('active')\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-check-circle\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ActiveKeys}}</div>\n <div class=\"kpi-label\">Active</div>\n </div>\n <div class=\"kpi-trend success\">\n <span class=\"percentage\">{{TotalKeys > 0 ? (ActiveKeys / TotalKeys * 100).toFixed(0) : 100}}%</span>\n </div>\n </div>\n\n <div class=\"kpi-card clickable\" [class.warning]=\"ExpiringSoonCount > 0\" (click)=\"showListView('expiring')\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-clock\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ExpiringSoonCount}}</div>\n <div class=\"kpi-label\">Expiring Soon</div>\n </div>\n <div class=\"kpi-trend warning\" *ngIf=\"ExpiringSoonCount > 0\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n </div>\n\n <div class=\"kpi-card clickable\" [class.danger]=\"RevokedKeys > 0\" (click)=\"showListView('revoked')\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-ban\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{RevokedKeys}}</div>\n <div class=\"kpi-label\">Revoked</div>\n </div>\n </div>\n\n <div class=\"kpi-card clickable\" (click)=\"switchTab('scopes')\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ScopeStats.length}}</div>\n <div class=\"kpi-label\">Scope Categories</div>\n </div>\n </div>\n </div>\n\n <!-- Content Grid -->\n <div class=\"content-grid\">\n <!-- Recently Used Keys -->\n <div class=\"panel keys-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-key\"></i>\n <span>Recently Used Keys</span>\n </div>\n <button class=\"panel-action\" (click)=\"showListView('all')\">\n View All <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n </div>\n <div class=\"panel-body\">\n <div class=\"key-list\" *ngIf=\"TopUsedKeys.length > 0\">\n <div class=\"key-item\" *ngFor=\"let key of TopUsedKeys\" (click)=\"openEditPanel(key)\">\n <div class=\"key-icon\" [class.active]=\"key.Status === 'Active'\">\n <i class=\"fa-solid fa-key\"></i>\n </div>\n <div class=\"key-info\">\n <div class=\"key-label\">{{key.Label}}</div>\n <div class=\"key-meta\">\n <span class=\"key-user\">{{key.User}}</span>\n <span class=\"key-hash\">...{{key.Hash.slice(-8)}}</span>\n </div>\n </div>\n <div class=\"key-status\">\n <div class=\"last-used\">{{formatDate(key.LastUsedAt)}}</div>\n <div class=\"expiration\" [ngClass]=\"getExpirationClass(key)\">\n {{formatExpiration(key.ExpiresAt)}}\n </div>\n </div>\n </div>\n </div>\n <div class=\"empty-state\" *ngIf=\"TopUsedKeys.length === 0\">\n <i class=\"fa-solid fa-key\"></i>\n <span>No active keys with recent usage</span>\n </div>\n </div>\n </div>\n\n <!-- Scope Categories -->\n <div class=\"panel scope-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span>Permission Scopes</span>\n </div>\n <span class=\"panel-subtitle\">Available scope categories</span>\n </div>\n <div class=\"panel-body\">\n <div class=\"scope-chart\" *ngIf=\"ScopeStats.length > 0\">\n <!-- Visual Donut Chart -->\n <div class=\"donut-chart-container\">\n <svg viewBox=\"0 0 100 100\" class=\"donut-chart\">\n <circle cx=\"50\" cy=\"50\" r=\"40\" fill=\"none\" stroke=\"#e5e7eb\" stroke-width=\"12\"/>\n <ng-container *ngFor=\"let stat of ScopeStats; let i = index\">\n <circle\n cx=\"50\" cy=\"50\" r=\"40\"\n fill=\"none\"\n [attr.stroke]=\"stat.color\"\n stroke-width=\"12\"\n [attr.stroke-dasharray]=\"stat.percentage * 2.51 + ' ' + (251 - stat.percentage * 2.51)\"\n [attr.stroke-dashoffset]=\"getDonutOffset(i)\"\n class=\"donut-segment\"\n (click)=\"onScopeClick(stat)\"\n />\n </ng-container>\n </svg>\n <div class=\"donut-center\">\n <div class=\"donut-total\">{{ScopeStats.length}}</div>\n <div class=\"donut-label\">Categories</div>\n </div>\n </div>\n <!-- Legend -->\n <div class=\"scope-legend\">\n <div class=\"legend-item\" *ngFor=\"let stat of ScopeStats\" (click)=\"onScopeClick(stat)\">\n <div class=\"legend-color\" [style.backgroundColor]=\"stat.color\"></div>\n <div class=\"legend-info\">\n <div class=\"legend-name\">\n <i [class]=\"stat.iconClass\"></i>\n {{stat.category}}\n </div>\n <div class=\"legend-value\">{{stat.count}} scopes</div>\n </div>\n <i class=\"fa-solid fa-chevron-right legend-arrow\"></i>\n </div>\n </div>\n </div>\n <div class=\"empty-state\" *ngIf=\"ScopeStats.length === 0\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span>No scopes configured</span>\n </div>\n </div>\n </div>\n\n <!-- Recent Activity -->\n <div class=\"panel activity-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n <span>Recent Activity</span>\n </div>\n </div>\n <div class=\"panel-body\">\n <div class=\"activity-list\" *ngIf=\"RecentActivity.length > 0\">\n <div class=\"activity-item\" *ngFor=\"let activity of RecentActivity\" (click)=\"onActivityClick(activity)\">\n <div class=\"activity-icon\" [ngClass]=\"getActionClass(activity.action)\">\n <i [class]=\"getActionIcon(activity.action)\"></i>\n </div>\n <div class=\"activity-info\">\n <div class=\"activity-name\">{{activity.keyLabel}}</div>\n <div class=\"activity-meta\">\n <span class=\"activity-action\">{{activity.action}}</span>\n <span class=\"activity-user\" *ngIf=\"activity.user\">by {{activity.user}}</span>\n </div>\n </div>\n <div class=\"activity-time\">\n {{formatDate(activity.date)}}\n </div>\n </div>\n </div>\n <div class=\"empty-state\" *ngIf=\"RecentActivity.length === 0\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No recent activity</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Quick Actions -->\n <div class=\"quick-actions\" *ngIf=\"UserCanCreateKeys\">\n <div class=\"quick-actions-title\">Quick Actions</div>\n <div class=\"quick-actions-grid\">\n <button class=\"quick-action\" (click)=\"openCreateDialog()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Generate Key</span>\n </button>\n <button class=\"quick-action\" (click)=\"showListView('all')\">\n <i class=\"fa-solid fa-list\"></i>\n <span>View All Keys</span>\n </button>\n <button class=\"quick-action\" (click)=\"showListView('expiring')\">\n <i class=\"fa-solid fa-clock\"></i>\n <span>Expiring Keys</span>\n </button>\n <button class=\"quick-action\" (click)=\"showListView('never-used')\">\n <i class=\"fa-solid fa-question-circle\"></i>\n <span>Never Used</span>\n </button>\n </div>\n </div>\n\n <!-- Security Notice -->\n <div class=\"security-notice\">\n <i class=\"fa-solid fa-shield-check\"></i>\n <div class=\"notice-content\">\n <strong>Security Best Practices:</strong>\n API keys should be rotated regularly and revoked when no longer needed.\n Keys are hashed and stored securely - the raw key is only shown once at creation time.\n All API key usage is logged for audit purposes.\n </div>\n </div>\n </ng-container>\n\n <!-- List View -->\n <ng-container *ngIf=\"CurrentView === 'list'\">\n <div class=\"list-view-header\">\n <button class=\"back-btn\" (click)=\"showOverview()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n Back to Overview\n </button>\n </div>\n <mj-api-key-list #keyList\n [Filter]=\"ListFilter\"\n (KeySelected)=\"onKeySelected($event)\"\n (CreateRequested)=\"openCreateDialog()\">\n </mj-api-key-list>\n </ng-container>\n </ng-container>\n\n <!-- Applications Tab Content -->\n <ng-container *ngIf=\"MainTab === 'applications'\">\n <mj-api-applications-panel\n (ApplicationUpdated)=\"onDataUpdated()\">\n </mj-api-applications-panel>\n </ng-container>\n\n <!-- Scopes Tab Content -->\n <ng-container *ngIf=\"MainTab === 'scopes'\">\n <mj-api-scopes-panel\n (ScopeUpdated)=\"onDataUpdated()\">\n </mj-api-scopes-panel>\n </ng-container>\n\n <!-- Usage Tab Content -->\n <ng-container *ngIf=\"MainTab === 'usage'\">\n <mj-api-usage-panel></mj-api-usage-panel>\n </ng-container>\n </div><!-- /.content-wrapper -->\n </div><!-- /.dashboard-content -->\n\n <!-- Mobile Navigation Toggle -->\n <button class=\"mobile-nav-toggle\" (click)=\"toggleNav()\">\n <i class=\"fa-solid\" [class.fa-bars]=\"!NavOpen\" [class.fa-times]=\"NavOpen\"></i>\n </button>\n\n <!-- Mobile Navigation Overlay -->\n <div class=\"mobile-nav-overlay\" (click)=\"closeNav()\"></div>\n </ng-container>\n\n <!-- Create Dialog -->\n <mj-api-key-create-dialog\n [Visible]=\"ShowCreateDialog\"\n (Created)=\"onKeyCreated($event)\"\n (Closed)=\"onCreateDialogClosed()\">\n </mj-api-key-create-dialog>\n\n <!-- Edit Panel -->\n <mj-api-key-edit-panel\n [Visible]=\"ShowEditPanel\"\n [KeyId]=\"SelectedKeyId\"\n (Updated)=\"onKeyUpdated()\"\n (Revoked)=\"onKeyRevoked()\"\n (Closed)=\"onEditPanelClosed()\">\n </mj-api-key-edit-panel>\n</div>\n", styles: ["/* Main Dashboard Container */\n.api-keys-dashboard {\n display: flex;\n height: 100%;\n position: relative;\n overflow: hidden;\n}\n\n.api-keys-dashboard.panel-open .dashboard-content {\n overflow: hidden;\n}\n\n/* Left Navigation Sidebar */\n.dashboard-nav {\n width: 220px;\n background: var(--card-background, #ffffff);\n border-right: 1px solid var(--border-color, #e5e7eb);\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n}\n\n.nav-header {\n padding: 20px;\n border-bottom: 1px solid var(--border-color, #e5e7eb);\n}\n\n.nav-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-weight: 700;\n font-size: 16px;\n color: var(--text-primary, #1f2937);\n}\n\n.nav-title i {\n color: #f59e0b;\n font-size: 18px;\n}\n\n.nav-items {\n flex: 1;\n padding: 12px;\n overflow-y: auto;\n}\n\n.nav-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n margin-bottom: 4px;\n background: transparent;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.2s ease;\n width: 100%;\n text-align: left;\n}\n\n.nav-item:hover {\n background: var(--item-hover, #f3f4f6);\n color: var(--text-primary, #1f2937);\n}\n\n.nav-item.active {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n color: white;\n box-shadow: 0 2px 8px rgba(245, 158, 11, 0.3);\n}\n\n.nav-item i {\n font-size: 16px;\n width: 20px;\n text-align: center;\n}\n\n.nav-item .nav-label {\n flex: 1;\n}\n\n.nav-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 22px;\n height: 20px;\n padding: 0 6px;\n background: rgba(0, 0, 0, 0.1);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.nav-item.active .nav-badge {\n background: rgba(255, 255, 255, 0.25);\n}\n\n/* Dashboard Content Area */\n.dashboard-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n min-width: 0;\n}\n\n.content-wrapper {\n flex: 1;\n padding: 24px;\n overflow-y: auto;\n}\n\n/* List View Header */\n.list-view-header {\n margin-bottom: 16px;\n}\n\n.back-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.back-btn:hover {\n background: var(--item-hover, #f3f4f6);\n color: var(--text-primary, #1f2937);\n}\n\n/* Header */\n.overview-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.header-left {\n flex: 1;\n}\n\n.overview-title {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 4px 0;\n}\n\n.overview-subtitle {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n}\n\n.header-actions {\n display: flex;\n gap: 12px;\n}\n\n.btn-refresh {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-refresh:hover {\n background: var(--item-hover, #f3f4f6);\n}\n\n.btn-refresh i {\n color: var(--text-secondary, #6b7280);\n}\n\n.btn-primary {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n color: white;\n border: none;\n border-radius: 8px;\n font-weight: 600;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-primary:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(245, 158, 11, 0.4);\n}\n\n/* Health Banner */\n.health-banner {\n display: flex;\n align-items: center;\n padding: 20px 24px;\n background: linear-gradient(135deg, #ecfdf5 0%, #d1fae5 100%);\n border: 1px solid #a7f3d0;\n border-radius: 16px;\n margin-bottom: 24px;\n}\n\n.health-banner.health-warning {\n background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);\n border-color: #fcd34d;\n}\n\n.health-banner.health-critical {\n background: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%);\n border-color: #fca5a5;\n}\n\n.health-score-container {\n margin-right: 24px;\n}\n\n.health-score-ring {\n position: relative;\n width: 80px;\n height: 80px;\n}\n\n.circular-chart {\n display: block;\n margin: 0 auto;\n max-height: 80px;\n transform: rotate(-90deg);\n}\n\n.circle-bg {\n fill: none;\n stroke: #e5e7eb;\n stroke-width: 3.8;\n}\n\n.circle {\n fill: none;\n stroke-width: 3.8;\n stroke-linecap: round;\n stroke: #10b981;\n animation: progress 1s ease-out forwards;\n}\n\n.health-banner.health-warning .circle {\n stroke: #f59e0b;\n}\n\n.health-banner.health-critical .circle {\n stroke: #ef4444;\n}\n\n@keyframes progress {\n 0% {\n stroke-dasharray: 0 100;\n }\n}\n\n.health-score-value {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 20px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n}\n\n.health-info {\n flex: 1;\n}\n\n.health-label {\n font-size: 18px;\n font-weight: 700;\n color: #059669;\n margin-bottom: 4px;\n}\n\n.health-banner.health-warning .health-label {\n color: #d97706;\n}\n\n.health-banner.health-critical .health-label {\n color: #dc2626;\n}\n\n.health-details {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.health-alert {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #dc2626;\n font-weight: 500;\n font-size: 14px;\n cursor: pointer;\n}\n\n.health-alert:hover {\n text-decoration: underline;\n}\n\n.health-warning-text {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #d97706;\n font-weight: 500;\n font-size: 14px;\n cursor: pointer;\n}\n\n.health-warning-text:hover {\n text-decoration: underline;\n}\n\n.health-info-text {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #6b7280;\n font-weight: 500;\n font-size: 14px;\n cursor: pointer;\n}\n\n.health-info-text:hover {\n text-decoration: underline;\n}\n\n.health-ok {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #059669;\n font-weight: 500;\n font-size: 14px;\n}\n\n/* KPI Cards */\n.kpi-row {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card {\n display: flex;\n align-items: center;\n padding: 16px 20px;\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.kpi-card.clickable {\n cursor: pointer;\n}\n\n.kpi-card.clickable:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n\n.kpi-card.active .kpi-icon {\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n}\n\n.kpi-card.warning .kpi-icon {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n}\n\n.kpi-card.danger .kpi-icon {\n background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);\n}\n\n.kpi-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n border-radius: 10px;\n margin-right: 14px;\n flex-shrink: 0;\n}\n\n.kpi-icon i {\n font-size: 20px;\n color: white;\n}\n\n.kpi-content {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n line-height: 1.2;\n}\n\n.kpi-label {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n margin-top: 2px;\n white-space: nowrap;\n}\n\n.kpi-trend {\n display: flex;\n align-items: center;\n margin-left: 8px;\n color: var(--text-tertiary, #9ca3af);\n}\n\n.kpi-trend.success {\n color: #10b981;\n}\n\n.kpi-trend.warning {\n color: #f59e0b;\n}\n\n.kpi-trend .percentage {\n font-size: 12px;\n font-weight: 600;\n}\n\n/* Content Grid */\n.content-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n grid-template-rows: auto auto;\n gap: 20px;\n margin-bottom: 24px;\n}\n\n.keys-panel {\n grid-row: span 1;\n}\n\n.scope-panel {\n grid-row: span 1;\n}\n\n.activity-panel {\n grid-column: span 2;\n}\n\n.panel {\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: var(--header-background, #f9fafb);\n border-bottom: 1px solid var(--border-color, #e5e7eb);\n}\n\n.panel-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-weight: 600;\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n}\n\n.panel-title i {\n color: #f59e0b;\n}\n\n.panel-subtitle {\n font-size: 12px;\n color: var(--text-tertiary, #9ca3af);\n}\n\n.panel-action {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: transparent;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.panel-action:hover {\n background: #f59e0b;\n border-color: #f59e0b;\n color: white;\n}\n\n.panel-body {\n padding: 20px;\n flex: 1;\n overflow-y: auto;\n}\n\n/* Key List */\n.key-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.key-item {\n display: flex;\n align-items: center;\n padding: 14px 16px;\n background: var(--item-background, #f9fafb);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.key-item:hover {\n background: var(--item-hover, #f3f4f6);\n transform: translateX(4px);\n}\n\n.key-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #6b7280 0%, #4b5563 100%);\n border-radius: 8px;\n margin-right: 14px;\n flex-shrink: 0;\n}\n\n.key-icon.active {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n}\n\n.key-icon i {\n font-size: 16px;\n color: white;\n}\n\n.key-info {\n flex: 1;\n min-width: 0;\n}\n\n.key-label {\n font-size: 14px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.key-meta {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 2px;\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n.key-hash {\n font-family: monospace;\n background: var(--tag-background, #e5e7eb);\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 11px;\n}\n\n.key-status {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 4px;\n margin-left: 16px;\n}\n\n.last-used {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n.expiration {\n font-size: 11px;\n color: var(--text-tertiary, #9ca3af);\n}\n\n.expiration.expiring-soon {\n color: #f59e0b;\n font-weight: 500;\n}\n\n.expiration.expiring-critical {\n color: #ef4444;\n font-weight: 500;\n}\n\n.expiration.expired {\n color: #ef4444;\n font-weight: 600;\n}\n\n/* Scope Chart */\n.scope-chart {\n display: flex;\n flex-direction: column;\n gap: 24px;\n height: 100%;\n}\n\n.donut-chart-container {\n position: relative;\n width: 160px;\n height: 160px;\n margin: 0 auto;\n}\n\n.donut-chart {\n width: 100%;\n height: 100%;\n transform: rotate(-90deg);\n}\n\n.donut-segment {\n cursor: pointer;\n transition: opacity 0.2s ease;\n}\n\n.donut-segment:hover {\n opacity: 0.8;\n}\n\n.donut-center {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n text-align: center;\n}\n\n.donut-total {\n font-size: 28px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n}\n\n.donut-label {\n font-size: 11px;\n color: var(--text-secondary, #6b7280);\n}\n\n/* Scope Legend */\n.scope-legend {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.legend-item {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n background: var(--item-background, #f9fafb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.legend-item:hover {\n background: var(--item-hover, #f3f4f6);\n transform: translateX(4px);\n}\n\n.legend-color {\n width: 12px;\n height: 12px;\n border-radius: 4px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.legend-info {\n flex: 1;\n}\n\n.legend-name {\n font-size: 14px;\n font-weight: 500;\n color: var(--text-primary, #1f2937);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.legend-name i {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n.legend-value {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n.legend-arrow {\n color: var(--text-tertiary, #9ca3af);\n font-size: 10px;\n}\n\n/* Activity List */\n.activity-list {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 12px;\n}\n\n.activity-item {\n display: flex;\n align-items: center;\n padding: 12px 14px;\n background: var(--item-background, #f9fafb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.activity-item:hover {\n background: var(--item-hover, #f3f4f6);\n}\n\n.activity-icon {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--icon-background, #fef3c7);\n border-radius: 6px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.activity-icon i {\n font-size: 12px;\n color: #f59e0b;\n}\n\n.activity-icon.action-created {\n background: #d1fae5;\n}\n\n.activity-icon.action-created i {\n color: #059669;\n}\n\n.activity-icon.action-updated {\n background: #e0e7ff;\n}\n\n.activity-icon.action-updated i {\n color: #6366f1;\n}\n\n.activity-icon.action-revoked {\n background: #fee2e2;\n}\n\n.activity-icon.action-revoked i {\n color: #dc2626;\n}\n\n.activity-icon.action-used {\n background: #fef3c7;\n}\n\n.activity-icon.action-used i {\n color: #d97706;\n}\n\n.activity-icon.action-extended {\n background: #dbeafe;\n}\n\n.activity-icon.action-extended i {\n color: #3b82f6;\n}\n\n.activity-info {\n flex: 1;\n min-width: 0;\n}\n\n.activity-name {\n font-weight: 500;\n font-size: 13px;\n color: var(--text-primary, #1f2937);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.activity-meta {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 2px;\n font-size: 11px;\n color: var(--text-secondary, #6b7280);\n}\n\n.activity-action {\n font-weight: 500;\n text-transform: capitalize;\n}\n\n.activity-time {\n font-size: 11px;\n color: var(--text-tertiary, #9ca3af);\n white-space: nowrap;\n}\n\n/* Quick Actions */\n.quick-actions {\n margin-bottom: 24px;\n}\n\n.quick-actions-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin-bottom: 12px;\n}\n\n.quick-actions-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 12px;\n}\n\n.quick-action {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 16px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.quick-action:hover {\n border-color: #f59e0b;\n background: #fffbeb;\n transform: translateY(-2px);\n}\n\n.quick-action i {\n font-size: 20px;\n color: #f59e0b;\n}\n\n.quick-action span {\n font-size: 12px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 32px;\n color: var(--text-secondary, #6b7280);\n text-align: center;\n}\n\n.empty-state i {\n font-size: 32px;\n margin-bottom: 12px;\n opacity: 0.5;\n}\n\n/* Security Notice */\n.security-notice {\n display: flex;\n align-items: flex-start;\n padding: 16px 20px;\n background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);\n border-radius: 12px;\n border: 1px solid #fcd34d;\n}\n\n.security-notice i {\n font-size: 20px;\n color: #f59e0b;\n margin-right: 12px;\n margin-top: 2px;\n}\n\n.notice-content {\n font-size: 13px;\n color: #92400e;\n line-height: 1.5;\n}\n\n.notice-content strong {\n font-weight: 600;\n}\n\n/* Mobile Navigation Toggle */\n.mobile-nav-toggle {\n display: none;\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 56px;\n height: 56px;\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n border: none;\n border-radius: 50%;\n color: white;\n font-size: 24px;\n box-shadow: 0 4px 16px rgba(245, 158, 11, 0.4);\n cursor: pointer;\n z-index: 50;\n transition: transform 0.2s ease;\n}\n\n.mobile-nav-toggle:hover {\n transform: scale(1.05);\n}\n\n/* Mobile Nav Overlay */\n.mobile-nav-overlay {\n display: none;\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n z-index: 90;\n}\n\n/* ========================================\n Responsive Styles\n ======================================== */\n\n/* Tablet */\n@media (max-width: 1024px) {\n .content-grid {\n grid-template-columns: 1fr;\n }\n\n .activity-panel {\n grid-column: span 1;\n }\n\n .scope-chart {\n flex-direction: row;\n align-items: center;\n }\n\n .donut-chart-container {\n width: 140px;\n height: 140px;\n }\n\n .scope-legend {\n flex: 1;\n }\n\n .dashboard-nav {\n width: 200px;\n }\n}\n\n/* Mobile */\n@media (max-width: 768px) {\n .api-keys-dashboard {\n flex-direction: column;\n }\n\n .dashboard-nav {\n position: fixed;\n top: 0;\n left: -280px;\n width: 280px;\n height: 100%;\n z-index: 100;\n transition: left 0.3s ease;\n box-shadow: 4px 0 20px rgba(0, 0, 0, 0.15);\n }\n\n .api-keys-dashboard.nav-open .dashboard-nav {\n left: 0;\n }\n\n .mobile-nav-toggle {\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .mobile-nav-overlay {\n display: block;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.3s ease;\n }\n\n .api-keys-dashboard.nav-open .mobile-nav-overlay {\n opacity: 1;\n pointer-events: auto;\n }\n\n .dashboard-content {\n width: 100%;\n }\n\n .content-wrapper {\n padding: 16px;\n }\n\n .overview-header {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: flex-end;\n }\n\n .health-banner {\n flex-direction: column;\n text-align: center;\n }\n\n .health-score-container {\n margin-right: 0;\n margin-bottom: 16px;\n }\n\n .kpi-row {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .scope-chart {\n flex-direction: column;\n }\n\n .quick-actions-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .activity-list {\n grid-template-columns: 1fr;\n }\n\n .key-item {\n flex-wrap: wrap;\n }\n\n .key-status {\n width: 100%;\n flex-direction: row;\n justify-content: flex-start;\n margin-left: 54px;\n margin-top: 8px;\n gap: 12px;\n }\n}\n\n/* Small Mobile */\n@media (max-width: 480px) {\n .kpi-row {\n grid-template-columns: 1fr;\n }\n\n .quick-actions-grid {\n grid-template-columns: 1fr;\n }\n\n .kpi-card {\n padding: 12px 16px;\n }\n\n .kpi-icon {\n width: 40px;\n height: 40px;\n }\n\n .kpi-value {\n font-size: 20px;\n }\n\n .overview-title {\n font-size: 20px;\n }\n\n .btn-primary {\n padding: 8px 16px;\n font-size: 13px;\n }\n}\n"] }]
|
|
1136
|
+
args: [{ standalone: false, selector: 'mj-api-keys-resource', template: "<div class=\"api-keys-dashboard\" [class.panel-open]=\"ShowCreateDialog || ShowEditPanel\" [class.nav-open]=\"NavOpen\">\n @if (IsLoading) {\n <mj-loading text=\"Loading API Keys...\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <!-- Left Navigation Sidebar -->\n <div class=\"dashboard-nav\">\n <div class=\"nav-header\">\n <div class=\"nav-title\">\n <i class=\"fa-solid fa-key\"></i>\n <span>API Keys</span>\n </div>\n </div>\n <div class=\"nav-items\">\n <button class=\"nav-item\" [class.active]=\"MainTab === 'keys'\" (click)=\"switchTab('keys'); closeNav()\">\n <i class=\"fa-solid fa-key\"></i>\n <span class=\"nav-label\">API Keys</span>\n <span class=\"nav-badge\">{{TotalKeys}}</span>\n </button>\n <button class=\"nav-item\" [class.active]=\"MainTab === 'applications'\" (click)=\"switchTab('applications'); closeNav()\">\n <i class=\"fa-solid fa-cube\"></i>\n <span class=\"nav-label\">Applications</span>\n <span class=\"nav-badge\">{{ApplicationCount}}</span>\n </button>\n <button class=\"nav-item\" [class.active]=\"MainTab === 'scopes'\" (click)=\"switchTab('scopes'); closeNav()\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span class=\"nav-label\">Scopes</span>\n <span class=\"nav-badge\">{{ScopeCount}}</span>\n </button>\n <button class=\"nav-item\" [class.active]=\"MainTab === 'usage'\" (click)=\"switchTab('usage'); closeNav()\">\n <i class=\"fa-solid fa-chart-line\"></i>\n <span class=\"nav-label\">Usage Analytics</span>\n </button>\n </div>\n </div>\n <!-- Main Content Area -->\n <div class=\"dashboard-content\">\n <div class=\"content-wrapper\">\n <!-- Keys Tab Content -->\n @if (MainTab === 'keys') {\n <!-- Overview View -->\n @if (CurrentView === 'overview') {\n <!-- Header with Actions -->\n <div class=\"overview-header\">\n <div class=\"header-left\">\n <h2 class=\"overview-title\">API Keys Management</h2>\n <p class=\"overview-subtitle\">Manage API keys for external integrations and services</p>\n </div>\n <div class=\"header-actions\">\n <button class=\"btn-refresh\" (click)=\"refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n @if (UserCanCreateKeys) {\n <button class=\"btn-primary\" (click)=\"openCreateDialog()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Generate New Key</span>\n </button>\n }\n </div>\n </div>\n <!-- Health Score Banner -->\n <div class=\"health-banner\" [ngClass]=\"getHealthClass()\">\n <div class=\"health-score-container\">\n <div class=\"health-score-ring\">\n <svg viewBox=\"0 0 36 36\" class=\"circular-chart\">\n <path class=\"circle-bg\"\n d=\"M18 2.0845\n a 15.9155 15.9155 0 0 1 0 31.831\n a 15.9155 15.9155 0 0 1 0 -31.831\"\n />\n <path class=\"circle\"\n [attr.stroke-dasharray]=\"getHealthScore() + ', 100'\"\n d=\"M18 2.0845\n a 15.9155 15.9155 0 0 1 0 31.831\n a 15.9155 15.9155 0 0 1 0 -31.831\"\n />\n </svg>\n <div class=\"health-score-value\">{{getHealthScore()}}</div>\n </div>\n </div>\n <div class=\"health-info\">\n <div class=\"health-label\">{{getHealthLabel()}}</div>\n <div class=\"health-details\">\n @if (ExpiredKeys > 0) {\n <span class=\"health-alert\" (click)=\"showListView('expired')\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{ExpiredKeys}} expired\n </span>\n }\n @if (ExpiringSoonCount > 0) {\n <span class=\"health-warning-text\" (click)=\"showListView('expiring')\">\n <i class=\"fa-solid fa-clock\"></i>\n {{ExpiringSoonCount}} expiring soon\n </span>\n }\n @if (NeverUsedKeys > 0) {\n <span class=\"health-info-text\" (click)=\"showListView('never-used')\">\n <i class=\"fa-solid fa-question-circle\"></i>\n {{NeverUsedKeys}} never used\n </span>\n }\n @if (ExpiredKeys === 0 && ExpiringSoonCount === 0 && NeverUsedKeys === 0) {\n <span class=\"health-ok\">\n <i class=\"fa-solid fa-check-circle\"></i>\n All keys healthy\n </span>\n }\n </div>\n </div>\n </div>\n <!-- KPI Cards Row -->\n <div class=\"kpi-row\">\n <div class=\"kpi-card clickable\" (click)=\"showListView('all')\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-key\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{TotalKeys}}</div>\n <div class=\"kpi-label\">Total Keys</div>\n </div>\n <div class=\"kpi-trend\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n </div>\n <div class=\"kpi-card active clickable\" (click)=\"showListView('active')\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-check-circle\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ActiveKeys}}</div>\n <div class=\"kpi-label\">Active</div>\n </div>\n <div class=\"kpi-trend success\">\n <span class=\"percentage\">{{TotalKeys > 0 ? (ActiveKeys / TotalKeys * 100).toFixed(0) : 100}}%</span>\n </div>\n </div>\n <div class=\"kpi-card clickable\" [class.warning]=\"ExpiringSoonCount > 0\" (click)=\"showListView('expiring')\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-clock\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ExpiringSoonCount}}</div>\n <div class=\"kpi-label\">Expiring Soon</div>\n </div>\n @if (ExpiringSoonCount > 0) {\n <div class=\"kpi-trend warning\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n }\n </div>\n <div class=\"kpi-card clickable\" [class.danger]=\"RevokedKeys > 0\" (click)=\"showListView('revoked')\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-ban\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{RevokedKeys}}</div>\n <div class=\"kpi-label\">Revoked</div>\n </div>\n </div>\n <div class=\"kpi-card clickable\" (click)=\"switchTab('scopes')\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ScopeStats.length}}</div>\n <div class=\"kpi-label\">Scope Categories</div>\n </div>\n </div>\n </div>\n <!-- Content Grid -->\n <div class=\"content-grid\">\n <!-- Recently Used Keys -->\n <div class=\"panel keys-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-key\"></i>\n <span>Recently Used Keys</span>\n </div>\n <button class=\"panel-action\" (click)=\"showListView('all')\">\n View All <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n </div>\n <div class=\"panel-body\">\n @if (TopUsedKeys.length > 0) {\n <div class=\"key-list\">\n @for (key of TopUsedKeys; track key) {\n <div class=\"key-item\" (click)=\"openEditPanel(key)\">\n <div class=\"key-icon\" [class.active]=\"key.Status === 'Active'\">\n <i class=\"fa-solid fa-key\"></i>\n </div>\n <div class=\"key-info\">\n <div class=\"key-label\">{{key.Label}}</div>\n <div class=\"key-meta\">\n <span class=\"key-user\">{{key.User}}</span>\n <span class=\"key-hash\">...{{key.Hash.slice(-8)}}</span>\n </div>\n </div>\n <div class=\"key-status\">\n <div class=\"last-used\">{{formatDate(key.LastUsedAt)}}</div>\n <div class=\"expiration\" [ngClass]=\"getExpirationClass(key)\">\n {{formatExpiration(key.ExpiresAt)}}\n </div>\n </div>\n </div>\n }\n </div>\n }\n @if (TopUsedKeys.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-key\"></i>\n <span>No active keys with recent usage</span>\n </div>\n }\n </div>\n </div>\n <!-- Scope Categories -->\n <div class=\"panel scope-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span>Permission Scopes</span>\n </div>\n <span class=\"panel-subtitle\">Available scope categories</span>\n </div>\n <div class=\"panel-body\">\n @if (ScopeStats.length > 0) {\n <div class=\"scope-chart\">\n <!-- Visual Donut Chart -->\n <div class=\"donut-chart-container\">\n <svg viewBox=\"0 0 100 100\" class=\"donut-chart\">\n <circle cx=\"50\" cy=\"50\" r=\"40\" fill=\"none\" stroke=\"#e5e7eb\" stroke-width=\"12\"/>\n @for (stat of ScopeStats; track stat; let i = $index) {\n <ng-container>\n <circle\n cx=\"50\" cy=\"50\" r=\"40\"\n fill=\"none\"\n [attr.stroke]=\"stat.color\"\n stroke-width=\"12\"\n [attr.stroke-dasharray]=\"stat.percentage * 2.51 + ' ' + (251 - stat.percentage * 2.51)\"\n [attr.stroke-dashoffset]=\"getDonutOffset(i)\"\n class=\"donut-segment\"\n (click)=\"onScopeClick(stat)\"\n />\n </ng-container>\n }\n </svg>\n <div class=\"donut-center\">\n <div class=\"donut-total\">{{ScopeStats.length}}</div>\n <div class=\"donut-label\">Categories</div>\n </div>\n </div>\n <!-- Legend -->\n <div class=\"scope-legend\">\n @for (stat of ScopeStats; track stat) {\n <div class=\"legend-item\" (click)=\"onScopeClick(stat)\">\n <div class=\"legend-color\" [style.backgroundColor]=\"stat.color\"></div>\n <div class=\"legend-info\">\n <div class=\"legend-name\">\n <i [class]=\"stat.iconClass\"></i>\n {{stat.category}}\n </div>\n <div class=\"legend-value\">{{stat.count}} scopes</div>\n </div>\n <i class=\"fa-solid fa-chevron-right legend-arrow\"></i>\n </div>\n }\n </div>\n </div>\n }\n @if (ScopeStats.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span>No scopes configured</span>\n </div>\n }\n </div>\n </div>\n <!-- Recent Activity -->\n <div class=\"panel activity-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n <span>Recent Activity</span>\n </div>\n </div>\n <div class=\"panel-body\">\n @if (RecentActivity.length > 0) {\n <div class=\"activity-list\">\n @for (activity of RecentActivity; track activity) {\n <div class=\"activity-item\" (click)=\"onActivityClick(activity)\">\n <div class=\"activity-icon\" [ngClass]=\"getActionClass(activity.action)\">\n <i [class]=\"getActionIcon(activity.action)\"></i>\n </div>\n <div class=\"activity-info\">\n <div class=\"activity-name\">{{activity.keyLabel}}</div>\n <div class=\"activity-meta\">\n <span class=\"activity-action\">{{activity.action}}</span>\n @if (activity.user) {\n <span class=\"activity-user\">by {{activity.user}}</span>\n }\n </div>\n </div>\n <div class=\"activity-time\">\n {{formatDate(activity.date)}}\n </div>\n </div>\n }\n </div>\n }\n @if (RecentActivity.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No recent activity</span>\n </div>\n }\n </div>\n </div>\n </div>\n <!-- Quick Actions -->\n @if (UserCanCreateKeys) {\n <div class=\"quick-actions\">\n <div class=\"quick-actions-title\">Quick Actions</div>\n <div class=\"quick-actions-grid\">\n <button class=\"quick-action\" (click)=\"openCreateDialog()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Generate Key</span>\n </button>\n <button class=\"quick-action\" (click)=\"showListView('all')\">\n <i class=\"fa-solid fa-list\"></i>\n <span>View All Keys</span>\n </button>\n <button class=\"quick-action\" (click)=\"showListView('expiring')\">\n <i class=\"fa-solid fa-clock\"></i>\n <span>Expiring Keys</span>\n </button>\n <button class=\"quick-action\" (click)=\"showListView('never-used')\">\n <i class=\"fa-solid fa-question-circle\"></i>\n <span>Never Used</span>\n </button>\n </div>\n </div>\n }\n <!-- Security Notice -->\n <div class=\"security-notice\">\n <i class=\"fa-solid fa-shield-check\"></i>\n <div class=\"notice-content\">\n <strong>Security Best Practices:</strong>\n API keys should be rotated regularly and revoked when no longer needed.\n Keys are hashed and stored securely - the raw key is only shown once at creation time.\n All API key usage is logged for audit purposes.\n </div>\n </div>\n }\n <!-- List View -->\n @if (CurrentView === 'list') {\n <div class=\"list-view-header\">\n <button class=\"back-btn\" (click)=\"showOverview()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n Back to Overview\n </button>\n </div>\n <mj-api-key-list #keyList\n [Filter]=\"ListFilter\"\n (KeySelected)=\"onKeySelected($event)\"\n (CreateRequested)=\"openCreateDialog()\">\n </mj-api-key-list>\n }\n }\n <!-- Applications Tab Content -->\n @if (MainTab === 'applications') {\n <mj-api-applications-panel\n (ApplicationUpdated)=\"onDataUpdated()\">\n </mj-api-applications-panel>\n }\n <!-- Scopes Tab Content -->\n @if (MainTab === 'scopes') {\n <mj-api-scopes-panel\n (ScopeUpdated)=\"onDataUpdated()\">\n </mj-api-scopes-panel>\n }\n <!-- Usage Tab Content -->\n @if (MainTab === 'usage') {\n <mj-api-usage-panel></mj-api-usage-panel>\n }\n </div><!-- /.content-wrapper -->\n </div><!-- /.dashboard-content -->\n <!-- Mobile Navigation Toggle -->\n <button class=\"mobile-nav-toggle\" (click)=\"toggleNav()\">\n <i class=\"fa-solid\" [class.fa-bars]=\"!NavOpen\" [class.fa-times]=\"NavOpen\"></i>\n </button>\n <!-- Mobile Navigation Overlay -->\n <div class=\"mobile-nav-overlay\" (click)=\"closeNav()\"></div>\n }\n\n <!-- Create Dialog -->\n <mj-api-key-create-dialog\n [Visible]=\"ShowCreateDialog\"\n (Created)=\"onKeyCreated($event)\"\n (Closed)=\"onCreateDialogClosed()\">\n </mj-api-key-create-dialog>\n\n <!-- Edit Panel -->\n <mj-api-key-edit-panel\n [Visible]=\"ShowEditPanel\"\n [KeyId]=\"SelectedKeyId\"\n (Updated)=\"onKeyUpdated()\"\n (Revoked)=\"onKeyRevoked()\"\n (Closed)=\"onEditPanelClosed()\">\n </mj-api-key-edit-panel>\n</div>\n", styles: ["/* Main Dashboard Container */\n.api-keys-dashboard {\n display: flex;\n height: 100%;\n position: relative;\n overflow: hidden;\n}\n\n.api-keys-dashboard.panel-open .dashboard-content {\n overflow: hidden;\n}\n\n/* Left Navigation Sidebar */\n.dashboard-nav {\n width: 220px;\n background: var(--card-background, #ffffff);\n border-right: 1px solid var(--border-color, #e5e7eb);\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n}\n\n.nav-header {\n padding: 20px;\n border-bottom: 1px solid var(--border-color, #e5e7eb);\n}\n\n.nav-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-weight: 700;\n font-size: 16px;\n color: var(--text-primary, #1f2937);\n}\n\n.nav-title i {\n color: #f59e0b;\n font-size: 18px;\n}\n\n.nav-items {\n flex: 1;\n padding: 12px;\n overflow-y: auto;\n}\n\n.nav-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n margin-bottom: 4px;\n background: transparent;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.2s ease;\n width: 100%;\n text-align: left;\n}\n\n.nav-item:hover {\n background: var(--item-hover, #f3f4f6);\n color: var(--text-primary, #1f2937);\n}\n\n.nav-item.active {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n color: white;\n box-shadow: 0 2px 8px rgba(245, 158, 11, 0.3);\n}\n\n.nav-item i {\n font-size: 16px;\n width: 20px;\n text-align: center;\n}\n\n.nav-item .nav-label {\n flex: 1;\n}\n\n.nav-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 22px;\n height: 20px;\n padding: 0 6px;\n background: rgba(0, 0, 0, 0.1);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.nav-item.active .nav-badge {\n background: rgba(255, 255, 255, 0.25);\n}\n\n/* Dashboard Content Area */\n.dashboard-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n min-width: 0;\n}\n\n.content-wrapper {\n flex: 1;\n padding: 24px;\n overflow-y: auto;\n}\n\n/* List View Header */\n.list-view-header {\n margin-bottom: 16px;\n}\n\n.back-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.back-btn:hover {\n background: var(--item-hover, #f3f4f6);\n color: var(--text-primary, #1f2937);\n}\n\n/* Header */\n.overview-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.header-left {\n flex: 1;\n}\n\n.overview-title {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 4px 0;\n}\n\n.overview-subtitle {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n}\n\n.header-actions {\n display: flex;\n gap: 12px;\n}\n\n.btn-refresh {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-refresh:hover {\n background: var(--item-hover, #f3f4f6);\n}\n\n.btn-refresh i {\n color: var(--text-secondary, #6b7280);\n}\n\n.btn-primary {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n color: white;\n border: none;\n border-radius: 8px;\n font-weight: 600;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-primary:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(245, 158, 11, 0.4);\n}\n\n/* Health Banner */\n.health-banner {\n display: flex;\n align-items: center;\n padding: 20px 24px;\n background: linear-gradient(135deg, #ecfdf5 0%, #d1fae5 100%);\n border: 1px solid #a7f3d0;\n border-radius: 16px;\n margin-bottom: 24px;\n}\n\n.health-banner.health-warning {\n background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);\n border-color: #fcd34d;\n}\n\n.health-banner.health-critical {\n background: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%);\n border-color: #fca5a5;\n}\n\n.health-score-container {\n margin-right: 24px;\n}\n\n.health-score-ring {\n position: relative;\n width: 80px;\n height: 80px;\n}\n\n.circular-chart {\n display: block;\n margin: 0 auto;\n max-height: 80px;\n transform: rotate(-90deg);\n}\n\n.circle-bg {\n fill: none;\n stroke: #e5e7eb;\n stroke-width: 3.8;\n}\n\n.circle {\n fill: none;\n stroke-width: 3.8;\n stroke-linecap: round;\n stroke: #10b981;\n animation: progress 1s ease-out forwards;\n}\n\n.health-banner.health-warning .circle {\n stroke: #f59e0b;\n}\n\n.health-banner.health-critical .circle {\n stroke: #ef4444;\n}\n\n@keyframes progress {\n 0% {\n stroke-dasharray: 0 100;\n }\n}\n\n.health-score-value {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 20px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n}\n\n.health-info {\n flex: 1;\n}\n\n.health-label {\n font-size: 18px;\n font-weight: 700;\n color: #059669;\n margin-bottom: 4px;\n}\n\n.health-banner.health-warning .health-label {\n color: #d97706;\n}\n\n.health-banner.health-critical .health-label {\n color: #dc2626;\n}\n\n.health-details {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.health-alert {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #dc2626;\n font-weight: 500;\n font-size: 14px;\n cursor: pointer;\n}\n\n.health-alert:hover {\n text-decoration: underline;\n}\n\n.health-warning-text {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #d97706;\n font-weight: 500;\n font-size: 14px;\n cursor: pointer;\n}\n\n.health-warning-text:hover {\n text-decoration: underline;\n}\n\n.health-info-text {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #6b7280;\n font-weight: 500;\n font-size: 14px;\n cursor: pointer;\n}\n\n.health-info-text:hover {\n text-decoration: underline;\n}\n\n.health-ok {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #059669;\n font-weight: 500;\n font-size: 14px;\n}\n\n/* KPI Cards */\n.kpi-row {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card {\n display: flex;\n align-items: center;\n padding: 16px 20px;\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.kpi-card.clickable {\n cursor: pointer;\n}\n\n.kpi-card.clickable:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n\n.kpi-card.active .kpi-icon {\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n}\n\n.kpi-card.warning .kpi-icon {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n}\n\n.kpi-card.danger .kpi-icon {\n background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);\n}\n\n.kpi-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n border-radius: 10px;\n margin-right: 14px;\n flex-shrink: 0;\n}\n\n.kpi-icon i {\n font-size: 20px;\n color: white;\n}\n\n.kpi-content {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n line-height: 1.2;\n}\n\n.kpi-label {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n margin-top: 2px;\n white-space: nowrap;\n}\n\n.kpi-trend {\n display: flex;\n align-items: center;\n margin-left: 8px;\n color: var(--text-tertiary, #9ca3af);\n}\n\n.kpi-trend.success {\n color: #10b981;\n}\n\n.kpi-trend.warning {\n color: #f59e0b;\n}\n\n.kpi-trend .percentage {\n font-size: 12px;\n font-weight: 600;\n}\n\n/* Content Grid */\n.content-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n grid-template-rows: auto auto;\n gap: 20px;\n margin-bottom: 24px;\n}\n\n.keys-panel {\n grid-row: span 1;\n}\n\n.scope-panel {\n grid-row: span 1;\n}\n\n.activity-panel {\n grid-column: span 2;\n}\n\n.panel {\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: var(--header-background, #f9fafb);\n border-bottom: 1px solid var(--border-color, #e5e7eb);\n}\n\n.panel-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-weight: 600;\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n}\n\n.panel-title i {\n color: #f59e0b;\n}\n\n.panel-subtitle {\n font-size: 12px;\n color: var(--text-tertiary, #9ca3af);\n}\n\n.panel-action {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: transparent;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.panel-action:hover {\n background: #f59e0b;\n border-color: #f59e0b;\n color: white;\n}\n\n.panel-body {\n padding: 20px;\n flex: 1;\n overflow-y: auto;\n}\n\n/* Key List */\n.key-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.key-item {\n display: flex;\n align-items: center;\n padding: 14px 16px;\n background: var(--item-background, #f9fafb);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.key-item:hover {\n background: var(--item-hover, #f3f4f6);\n transform: translateX(4px);\n}\n\n.key-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #6b7280 0%, #4b5563 100%);\n border-radius: 8px;\n margin-right: 14px;\n flex-shrink: 0;\n}\n\n.key-icon.active {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n}\n\n.key-icon i {\n font-size: 16px;\n color: white;\n}\n\n.key-info {\n flex: 1;\n min-width: 0;\n}\n\n.key-label {\n font-size: 14px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.key-meta {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 2px;\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n.key-hash {\n font-family: monospace;\n background: var(--tag-background, #e5e7eb);\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 11px;\n}\n\n.key-status {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 4px;\n margin-left: 16px;\n}\n\n.last-used {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n.expiration {\n font-size: 11px;\n color: var(--text-tertiary, #9ca3af);\n}\n\n.expiration.expiring-soon {\n color: #f59e0b;\n font-weight: 500;\n}\n\n.expiration.expiring-critical {\n color: #ef4444;\n font-weight: 500;\n}\n\n.expiration.expired {\n color: #ef4444;\n font-weight: 600;\n}\n\n/* Scope Chart */\n.scope-chart {\n display: flex;\n flex-direction: column;\n gap: 24px;\n height: 100%;\n}\n\n.donut-chart-container {\n position: relative;\n width: 160px;\n height: 160px;\n margin: 0 auto;\n}\n\n.donut-chart {\n width: 100%;\n height: 100%;\n transform: rotate(-90deg);\n}\n\n.donut-segment {\n cursor: pointer;\n transition: opacity 0.2s ease;\n}\n\n.donut-segment:hover {\n opacity: 0.8;\n}\n\n.donut-center {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n text-align: center;\n}\n\n.donut-total {\n font-size: 28px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n}\n\n.donut-label {\n font-size: 11px;\n color: var(--text-secondary, #6b7280);\n}\n\n/* Scope Legend */\n.scope-legend {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.legend-item {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n background: var(--item-background, #f9fafb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.legend-item:hover {\n background: var(--item-hover, #f3f4f6);\n transform: translateX(4px);\n}\n\n.legend-color {\n width: 12px;\n height: 12px;\n border-radius: 4px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.legend-info {\n flex: 1;\n}\n\n.legend-name {\n font-size: 14px;\n font-weight: 500;\n color: var(--text-primary, #1f2937);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.legend-name i {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n.legend-value {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n.legend-arrow {\n color: var(--text-tertiary, #9ca3af);\n font-size: 10px;\n}\n\n/* Activity List */\n.activity-list {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 12px;\n}\n\n.activity-item {\n display: flex;\n align-items: center;\n padding: 12px 14px;\n background: var(--item-background, #f9fafb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.activity-item:hover {\n background: var(--item-hover, #f3f4f6);\n}\n\n.activity-icon {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--icon-background, #fef3c7);\n border-radius: 6px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.activity-icon i {\n font-size: 12px;\n color: #f59e0b;\n}\n\n.activity-icon.action-created {\n background: #d1fae5;\n}\n\n.activity-icon.action-created i {\n color: #059669;\n}\n\n.activity-icon.action-updated {\n background: #e0e7ff;\n}\n\n.activity-icon.action-updated i {\n color: #6366f1;\n}\n\n.activity-icon.action-revoked {\n background: #fee2e2;\n}\n\n.activity-icon.action-revoked i {\n color: #dc2626;\n}\n\n.activity-icon.action-used {\n background: #fef3c7;\n}\n\n.activity-icon.action-used i {\n color: #d97706;\n}\n\n.activity-icon.action-extended {\n background: #dbeafe;\n}\n\n.activity-icon.action-extended i {\n color: #3b82f6;\n}\n\n.activity-info {\n flex: 1;\n min-width: 0;\n}\n\n.activity-name {\n font-weight: 500;\n font-size: 13px;\n color: var(--text-primary, #1f2937);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.activity-meta {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 2px;\n font-size: 11px;\n color: var(--text-secondary, #6b7280);\n}\n\n.activity-action {\n font-weight: 500;\n text-transform: capitalize;\n}\n\n.activity-time {\n font-size: 11px;\n color: var(--text-tertiary, #9ca3af);\n white-space: nowrap;\n}\n\n/* Quick Actions */\n.quick-actions {\n margin-bottom: 24px;\n}\n\n.quick-actions-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin-bottom: 12px;\n}\n\n.quick-actions-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 12px;\n}\n\n.quick-action {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 16px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.quick-action:hover {\n border-color: #f59e0b;\n background: #fffbeb;\n transform: translateY(-2px);\n}\n\n.quick-action i {\n font-size: 20px;\n color: #f59e0b;\n}\n\n.quick-action span {\n font-size: 12px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 32px;\n color: var(--text-secondary, #6b7280);\n text-align: center;\n}\n\n.empty-state i {\n font-size: 32px;\n margin-bottom: 12px;\n opacity: 0.5;\n}\n\n/* Security Notice */\n.security-notice {\n display: flex;\n align-items: flex-start;\n padding: 16px 20px;\n background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);\n border-radius: 12px;\n border: 1px solid #fcd34d;\n}\n\n.security-notice i {\n font-size: 20px;\n color: #f59e0b;\n margin-right: 12px;\n margin-top: 2px;\n}\n\n.notice-content {\n font-size: 13px;\n color: #92400e;\n line-height: 1.5;\n}\n\n.notice-content strong {\n font-weight: 600;\n}\n\n/* Mobile Navigation Toggle */\n.mobile-nav-toggle {\n display: none;\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 56px;\n height: 56px;\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n border: none;\n border-radius: 50%;\n color: white;\n font-size: 24px;\n box-shadow: 0 4px 16px rgba(245, 158, 11, 0.4);\n cursor: pointer;\n z-index: 50;\n transition: transform 0.2s ease;\n}\n\n.mobile-nav-toggle:hover {\n transform: scale(1.05);\n}\n\n/* Mobile Nav Overlay */\n.mobile-nav-overlay {\n display: none;\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n z-index: 90;\n}\n\n/* ========================================\n Responsive Styles\n ======================================== */\n\n/* Tablet */\n@media (max-width: 1024px) {\n .content-grid {\n grid-template-columns: 1fr;\n }\n\n .activity-panel {\n grid-column: span 1;\n }\n\n .scope-chart {\n flex-direction: row;\n align-items: center;\n }\n\n .donut-chart-container {\n width: 140px;\n height: 140px;\n }\n\n .scope-legend {\n flex: 1;\n }\n\n .dashboard-nav {\n width: 200px;\n }\n}\n\n/* Mobile */\n@media (max-width: 768px) {\n .api-keys-dashboard {\n flex-direction: column;\n }\n\n .dashboard-nav {\n position: fixed;\n top: 0;\n left: -280px;\n width: 280px;\n height: 100%;\n z-index: 100;\n transition: left 0.3s ease;\n box-shadow: 4px 0 20px rgba(0, 0, 0, 0.15);\n }\n\n .api-keys-dashboard.nav-open .dashboard-nav {\n left: 0;\n }\n\n .mobile-nav-toggle {\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .mobile-nav-overlay {\n display: block;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.3s ease;\n }\n\n .api-keys-dashboard.nav-open .mobile-nav-overlay {\n opacity: 1;\n pointer-events: auto;\n }\n\n .dashboard-content {\n width: 100%;\n }\n\n .content-wrapper {\n padding: 16px;\n }\n\n .overview-header {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: flex-end;\n }\n\n .health-banner {\n flex-direction: column;\n text-align: center;\n }\n\n .health-score-container {\n margin-right: 0;\n margin-bottom: 16px;\n }\n\n .kpi-row {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .scope-chart {\n flex-direction: column;\n }\n\n .quick-actions-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .activity-list {\n grid-template-columns: 1fr;\n }\n\n .key-item {\n flex-wrap: wrap;\n }\n\n .key-status {\n width: 100%;\n flex-direction: row;\n justify-content: flex-start;\n margin-left: 54px;\n margin-top: 8px;\n gap: 12px;\n }\n}\n\n/* Small Mobile */\n@media (max-width: 480px) {\n .kpi-row {\n grid-template-columns: 1fr;\n }\n\n .quick-actions-grid {\n grid-template-columns: 1fr;\n }\n\n .kpi-card {\n padding: 12px 16px;\n }\n\n .kpi-icon {\n width: 40px;\n height: 40px;\n }\n\n .kpi-value {\n font-size: 20px;\n }\n\n .overview-title {\n font-size: 20px;\n }\n\n .btn-primary {\n padding: 8px 16px;\n font-size: 13px;\n }\n}\n"] }]
|
|
1145
1137
|
}], () => [{ type: i0.ChangeDetectorRef }], { keyListComponent: [{
|
|
1146
1138
|
type: ViewChild,
|
|
1147
1139
|
args: ['keyList']
|
|
1148
1140
|
}] }); })();
|
|
1149
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(APIKeysResourceComponent, { className: "APIKeysResourceComponent", filePath: "src/APIKeys/api-keys-resource.component.ts", lineNumber:
|
|
1141
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(APIKeysResourceComponent, { className: "APIKeysResourceComponent", filePath: "src/APIKeys/api-keys-resource.component.ts", lineNumber: 52 }); })();
|
|
1150
1142
|
//# sourceMappingURL=api-keys-resource.component.js.map
|