@memberjunction/ng-dashboards 5.10.1 → 5.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AI/components/agents/agent-configuration.component.d.ts +34 -2
- package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-configuration.component.js +586 -223
- package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.js +2 -2
- package/dist/AI/components/agents/agent-filter-panel.component.d.ts +8 -0
- package/dist/AI/components/agents/agent-filter-panel.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-filter-panel.component.js +85 -52
- package/dist/AI/components/agents/agent-filter-panel.component.js.map +1 -1
- package/dist/AI/components/charts/performance-heatmap.component.d.ts +1 -0
- package/dist/AI/components/charts/performance-heatmap.component.d.ts.map +1 -1
- package/dist/AI/components/charts/performance-heatmap.component.js +27 -5
- package/dist/AI/components/charts/performance-heatmap.component.js.map +1 -1
- package/dist/AI/components/charts/time-series-chart.component.d.ts +5 -0
- package/dist/AI/components/charts/time-series-chart.component.d.ts.map +1 -1
- package/dist/AI/components/charts/time-series-chart.component.js +23 -8
- package/dist/AI/components/charts/time-series-chart.component.js.map +1 -1
- package/dist/AI/components/execution-monitoring.component.js +2 -2
- package/dist/AI/components/execution-monitoring.component.js.map +1 -1
- package/dist/AI/components/models/model-management.component.js +2 -2
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +2 -2
- package/dist/AI/components/prompts/prompt-filter-panel.component.js +2 -2
- package/dist/AI/components/prompts/prompt-management.component.js +3 -3
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-version-control.component.js +2 -2
- package/dist/AI/components/requests/agent-requests-resource.component.d.ts +83 -0
- package/dist/AI/components/requests/agent-requests-resource.component.d.ts.map +1 -0
- package/dist/AI/components/requests/agent-requests-resource.component.js +547 -0
- package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -0
- package/dist/AI/components/system/system-config-filter-panel.component.js +2 -2
- package/dist/AI/components/system/system-configuration.component.js +2 -2
- package/dist/AI/components/widgets/kpi-card.component.js +7 -7
- package/dist/AI/components/widgets/kpi-card.component.js.map +1 -1
- package/dist/AI/components/widgets/live-execution-widget.component.d.ts.map +1 -1
- package/dist/AI/components/widgets/live-execution-widget.component.js +6 -6
- package/dist/AI/components/widgets/live-execution-widget.component.js.map +1 -1
- package/dist/AI/index.d.ts +1 -0
- package/dist/AI/index.d.ts.map +1 -1
- package/dist/AI/index.js +2 -0
- package/dist/AI/index.js.map +1 -1
- package/dist/APIKeys/api-applications-panel.component.js +3 -3
- package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
- package/dist/APIKeys/api-key-create-dialog.component.js +3 -3
- package/dist/APIKeys/api-key-create-dialog.component.js.map +1 -1
- package/dist/APIKeys/api-key-edit-panel.component.js +1 -1
- package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -1
- package/dist/APIKeys/api-key-list.component.js +3 -3
- package/dist/APIKeys/api-key-list.component.js.map +1 -1
- package/dist/APIKeys/api-keys-resource.component.js +1 -1
- package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
- package/dist/APIKeys/api-scopes-panel.component.js +2 -2
- package/dist/APIKeys/api-usage-panel.component.js +2 -2
- package/dist/Actions/components/actions-overview.component.js +2 -2
- package/dist/Actions/components/execution-monitoring.component.js +2 -2
- package/dist/Actions/components/explorer/action-breadcrumb.component.js +2 -2
- package/dist/Actions/components/explorer/action-card.component.js +2 -2
- package/dist/Actions/components/explorer/action-explorer.component.js +2 -2
- package/dist/Actions/components/explorer/action-list-item.component.js +2 -2
- package/dist/Actions/components/explorer/action-toolbar.component.js +2 -2
- package/dist/Actions/components/explorer/action-tree-panel.component.js +2 -2
- package/dist/Actions/components/explorer/new-action-panel.component.js +2 -2
- package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -1
- package/dist/Actions/components/explorer/new-category-panel.component.js +2 -2
- package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -1
- package/dist/Communication/communication-dashboard.component.js +2 -2
- package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-logs-resource.component.js +3 -3
- package/dist/Communication/communication-logs-resource.component.js.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.js +5 -5
- package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
- package/dist/Communication/communication-providers-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-providers-resource.component.js +3 -3
- package/dist/Communication/communication-providers-resource.component.js.map +1 -1
- package/dist/Communication/communication-runs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-runs-resource.component.js +3 -3
- package/dist/Communication/communication-runs-resource.component.js.map +1 -1
- package/dist/Communication/communication-templates-resource.component.js +2 -2
- package/dist/Communication/communication-templates-resource.component.js.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +2 -2
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +2 -2
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/browser/component-browser.component.js +2 -2
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js +2 -2
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +2 -2
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js +2 -2
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/spec-editor.component.js +2 -2
- package/dist/ComponentStudio/components/editors/spec-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/text-import-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/text-import-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/workspace/component-preview.component.js +2 -2
- package/dist/ComponentStudio/components/workspace/editor-tabs.component.js +2 -2
- package/dist/ComponentStudio/components/workspace/editor-tabs.component.js.map +1 -1
- package/dist/Credentials/components/credentials-audit-resource.component.js +9 -9
- package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.js +11 -3
- package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +2 -2
- package/dist/Credentials/components/credentials-overview-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-overview-resource.component.js +12 -11
- package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +9 -9
- package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
- package/dist/Credentials/credentials-dashboard.component.js +2 -2
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +2 -2
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js +2 -2
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +2 -2
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +2 -2
- package/dist/DataExplorer/components/view-selector/view-selector.component.js +2 -2
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +6 -2
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +26 -8
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/Home/home-dashboard.component.js +2 -2
- package/dist/Integration/components/activity/activity.component.d.ts +1 -1
- package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
- package/dist/Integration/components/activity/activity.component.js +5 -5
- package/dist/Integration/components/activity/activity.component.js.map +1 -1
- package/dist/Integration/components/connections/connections.component.d.ts +31 -2
- package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
- package/dist/Integration/components/connections/connections.component.js +753 -412
- package/dist/Integration/components/connections/connections.component.js.map +1 -1
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +3 -3
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
- package/dist/Integration/components/overview/overview.component.d.ts +0 -1
- package/dist/Integration/components/overview/overview.component.d.ts.map +1 -1
- package/dist/Integration/components/overview/overview.component.js +3 -6
- package/dist/Integration/components/overview/overview.component.js.map +1 -1
- package/dist/Integration/components/pipelines/pipelines.component.js +3 -3
- package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
- package/dist/Integration/components/schedules/schedules.component.d.ts +20 -0
- package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -1
- package/dist/Integration/components/schedules/schedules.component.js +97 -5
- package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
- package/dist/Integration/components/visual-editor/visual-editor.component.js +2 -2
- package/dist/Integration/components/widgets/integration-card.component.d.ts.map +1 -1
- package/dist/Integration/components/widgets/integration-card.component.js +5 -1
- package/dist/Integration/components/widgets/integration-card.component.js.map +1 -1
- package/dist/Integration/components/widgets/run-history-panel.component.js +2 -2
- package/dist/Integration/components/widgets/run-history-panel.component.js.map +1 -1
- package/dist/Integration/integration.module.d.ts +2 -1
- package/dist/Integration/integration.module.d.ts.map +1 -1
- package/dist/Integration/integration.module.js +7 -3
- package/dist/Integration/integration.module.js.map +1 -1
- package/dist/Integration/services/integration-data.service.d.ts +27 -2
- package/dist/Integration/services/integration-data.service.d.ts.map +1 -1
- package/dist/Integration/services/integration-data.service.js +107 -4
- package/dist/Integration/services/integration-data.service.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +2 -2
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-categories-resource.component.js +2 -2
- package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +2 -2
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-operations-resource.component.js +2 -2
- package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
- package/dist/Lists/components/venn-diagram/venn-diagram.component.js +3 -3
- package/dist/Lists/components/venn-diagram/venn-diagram.component.js.map +1 -1
- package/dist/MCP/components/mcp-connection-dialog.component.js +2 -2
- package/dist/MCP/components/mcp-log-detail-panel.component.js +2 -2
- package/dist/MCP/components/mcp-log-detail-panel.component.js.map +1 -1
- package/dist/MCP/components/mcp-server-dialog.component.js +2 -2
- package/dist/MCP/components/mcp-test-tool-dialog.component.js +2 -2
- package/dist/MCP/components/mcp-test-tool-dialog.component.js.map +1 -1
- package/dist/MCP/mcp-dashboard.component.js +2 -2
- package/dist/MCP/mcp-filter-panel.component.js +2 -2
- package/dist/QueryBrowser/query-browser-resource.component.d.ts +55 -1
- package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js +664 -199
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/Scheduling/components/index.d.ts +0 -1
- package/dist/Scheduling/components/index.d.ts.map +1 -1
- package/dist/Scheduling/components/index.js +0 -1
- package/dist/Scheduling/components/index.js.map +1 -1
- package/dist/Scheduling/components/scheduling-activity.component.js +2 -2
- package/dist/Scheduling/components/scheduling-jobs.component.d.ts +6 -9
- package/dist/Scheduling/components/scheduling-jobs.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs.component.js +118 -110
- package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-overview.component.js +3 -3
- package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
- package/dist/Scheduling/scheduling-dashboard.component.js +2 -2
- package/dist/SystemDiagnostics/system-diagnostics.component.js +4 -4
- package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
- package/dist/Testing/components/testing-analytics.component.js +2 -2
- package/dist/Testing/components/testing-analytics.component.js.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab.component.js +4 -4
- package/dist/Testing/components/testing-dashboard-tab.component.js.map +1 -1
- package/dist/Testing/components/testing-explorer.component.js +2 -2
- package/dist/Testing/components/testing-explorer.component.js.map +1 -1
- package/dist/Testing/components/testing-review.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-review.component.js +5 -5
- package/dist/Testing/components/testing-review.component.js.map +1 -1
- package/dist/Testing/components/testing-runs.component.js +2 -2
- package/dist/Testing/components/testing-runs.component.js.map +1 -1
- package/dist/Testing/components/widgets/oracle-breakdown-table.component.js +2 -2
- package/dist/Testing/components/widgets/oracle-breakdown-table.component.js.map +1 -1
- package/dist/Testing/components/widgets/suite-tree.component.js +4 -4
- package/dist/Testing/components/widgets/suite-tree.component.js.map +1 -1
- package/dist/Testing/components/widgets/test-run-detail-panel.component.js +2 -2
- package/dist/Testing/components/widgets/test-run-detail-panel.component.js.map +1 -1
- package/dist/Testing/testing-dashboard.component.js +2 -2
- package/dist/VersionHistory/components/diff-resource.component.js +2 -2
- package/dist/VersionHistory/components/graph-resource.component.js +2 -2
- package/dist/VersionHistory/components/labels-resource.component.js +3 -3
- package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/restore-resource.component.js +3 -3
- package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
- package/dist/__tests__/integration-data-service.test.js +1 -0
- package/dist/__tests__/integration-data-service.test.js.map +1 -1
- package/dist/module.d.ts +52 -49
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +25 -6
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +1 -1
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -1
- package/dist/public-api.js.map +1 -1
- package/package.json +42 -40
- package/dist/Scheduling/components/job-slideout.component.d.ts +0 -45
- package/dist/Scheduling/components/job-slideout.component.d.ts.map +0 -1
- package/dist/Scheduling/components/job-slideout.component.js +0 -459
- package/dist/Scheduling/components/job-slideout.component.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-key-create-dialog.component.js","sourceRoot":"","sources":["../../src/APIKeys/api-key-create-dialog.component.ts","../../src/APIKeys/api-key-create-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, EventEmitter, HostListener, Input, OnInit, Output } from '@angular/core';\nimport { Metadata } from '@memberjunction/core';\nimport { MJAPIScopeEntity } from '@memberjunction/core-entities';\nimport { GraphQLDataProvider, GraphQLEncryptionClient } from '@memberjunction/graphql-dataprovider';\nimport { APIKeysEngineBase, parseAPIScopeUIConfig } from '@memberjunction/api-keys-base';\n\n/** Scope selection item */\ninterface ScopeItem {\n scope: MJAPIScopeEntity;\n selected: boolean;\n}\n\n/** Grouped scopes by category */\ninterface ScopeCategory {\n name: string;\n icon: string;\n color: string;\n scopes: ScopeItem[];\n expanded: boolean;\n allSelected: boolean;\n}\n\n/** Result of key creation */\nexport interface APIKeyCreateResult {\n success: boolean;\n apiKeyId?: string;\n rawKey?: string;\n error?: string;\n}\n/**\n * Dialog for creating new API keys\n * Shows the raw key only once - it cannot be recovered after closing\n */\n@Component({\n standalone: false,\n selector: 'mj-api-key-create-dialog',\n templateUrl: './api-key-create-dialog.component.html',\n styleUrls: ['./api-key-create-dialog.component.css']\n})\nexport class APIKeyCreateDialogComponent implements OnInit {\n @Input() Visible = false;\n @Output() VisibleChange = new EventEmitter<boolean>();\n @Output() Created = new EventEmitter<APIKeyCreateResult>();\n @Output() Closed = new EventEmitter<void>();\n\n // Form fields\n public Label = '';\n public Description = '';\n public ExpiresAt: Date | null = null;\n public NeverExpires = true;\n\n // Expiration presets\n public ExpirationPresets = [\n { label: '30 days', days: 30 },\n { label: '90 days', days: 90 },\n { label: '1 year', days: 365 },\n { label: 'Custom', days: -1 }\n ];\n public SelectedPreset: { label: string; days: number } | null = null;\n\n // Scopes\n public ScopeCategories: ScopeCategory[] = [];\n public IsLoadingScopes = true;\n\n // State\n public IsCreating = false;\n public Step: 'configure' | 'scopes' | 'success' = 'configure';\n public RawApiKey = '';\n public KeyCopied = false;\n public Error = '';\n\n // Default UI config for categories without explicit configuration\n private readonly defaultUIConfig = {\n icon: 'fa-solid fa-ellipsis',\n color: '#6b7280'\n };\n\n ngOnInit(): void {\n this.loadScopes();\n }\n\n /**\n * Handle escape key to close dialog\n */\n @HostListener('document:keydown.escape')\n public onEscapeKey(): void {\n if (this.Visible && !this.IsCreating) {\n this.close();\n }\n }\n\n /**\n * Load available scopes from cached data.\n * Uses UIConfig from root scopes for category icons/colors.\n */\n private loadScopes(): void {\n this.IsLoadingScopes = true;\n try {\n const base = APIKeysEngineBase.Instance;\n const scopes = base.Scopes;\n\n // Build a map of category -> root scope UIConfig\n // Root scopes (ParentID is null) define the UI appearance for their category\n const categoryUIConfigs = new Map<string, { icon: string; color: string }>();\n for (const scope of scopes) {\n if (!scope.ParentID) {\n // This is a root scope - use its UIConfig for the category\n const uiConfig = parseAPIScopeUIConfig(scope);\n categoryUIConfigs.set(scope.Category, {\n icon: uiConfig.icon || this.defaultUIConfig.icon,\n color: uiConfig.color || this.defaultUIConfig.color\n });\n }\n }\n\n // Group scopes by category\n const categoryMap = new Map<string, ScopeItem[]>();\n for (const scope of scopes) {\n const category = scope.Category || 'Other';\n if (!categoryMap.has(category)) {\n categoryMap.set(category, []);\n }\n categoryMap.get(category)!.push({\n scope,\n selected: false\n });\n }\n\n // Build categories with UI config from root scopes\n this.ScopeCategories = Array.from(categoryMap.entries())\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([name, scopeItems]) => {\n const config = categoryUIConfigs.get(name) || this.defaultUIConfig;\n return {\n name,\n icon: config.icon,\n color: config.color,\n scopes: scopeItems.sort((a, b) => a.scope.Name.localeCompare(b.scope.Name)),\n expanded: false,\n allSelected: false\n };\n });\n } catch (error) {\n console.error('Error loading scopes:', error);\n } finally {\n this.IsLoadingScopes = false;\n }\n }\n\n /**\n * Handle expiration preset selection\n */\n public onPresetSelect(preset: { label: string; days: number }): void {\n this.SelectedPreset = preset;\n this.NeverExpires = false;\n\n if (preset.days > 0) {\n const date = new Date();\n date.setDate(date.getDate() + preset.days);\n this.ExpiresAt = date;\n } else {\n this.ExpiresAt = null;\n }\n }\n\n /**\n * Handle never expires toggle\n */\n public onNeverExpiresChange(): void {\n if (this.NeverExpires) {\n this.ExpiresAt = null;\n this.SelectedPreset = null;\n }\n }\n\n /**\n * Toggle category expansion\n */\n public toggleCategory(category: ScopeCategory): void {\n category.expanded = !category.expanded;\n }\n\n /**\n * Toggle all scopes in a category\n */\n public toggleCategoryAll(category: ScopeCategory): void {\n category.allSelected = !category.allSelected;\n for (const item of category.scopes) {\n item.selected = category.allSelected;\n }\n }\n\n /**\n * Update category allSelected state\n */\n public updateCategoryState(category: ScopeCategory): void {\n category.allSelected = category.scopes.every(s => s.selected);\n }\n\n /**\n * Get selected scope count\n */\n public getSelectedScopeCount(): number {\n return this.ScopeCategories.reduce((sum, cat) =>\n sum + cat.scopes.filter(s => s.selected).length, 0);\n }\n\n /**\n * Proceed to scopes step\n */\n public goToScopes(): void {\n if (!this.Label.trim()) {\n this.Error = 'Please enter a label for the API key';\n return;\n }\n this.Error = '';\n this.Step = 'scopes';\n }\n\n /**\n * Go back to configure step\n */\n public goBack(): void {\n this.Step = 'configure';\n }\n\n /**\n * Create the API key using server-side cryptographic hashing\n */\n public async createKey(): Promise<void> {\n this.IsCreating = true;\n this.Error = '';\n\n try {\n // Get selected scope IDs\n const selectedScopeIds = this.ScopeCategories\n .flatMap(cat => cat.scopes)\n .filter(s => s.selected)\n .map(s => s.scope.ID);\n\n // Get the GraphQL provider and create the encryption client\n const provider = Metadata.Provider as GraphQLDataProvider;\n const encryptionClient = new GraphQLEncryptionClient(provider);\n\n // Call the server to create the API key with proper crypto hashing\n const result = await encryptionClient.CreateAPIKey({\n Label: this.Label.trim(),\n Description: this.Description.trim() || undefined,\n ExpiresAt: this.NeverExpires ? undefined : (this.ExpiresAt || undefined),\n ScopeIDs: selectedScopeIds.length > 0 ? selectedScopeIds : undefined\n });\n\n if (result.Success && result.RawKey) {\n this.RawApiKey = result.RawKey;\n this.Step = 'success';\n\n this.Created.emit({\n success: true,\n rawKey: result.RawKey\n });\n } else {\n this.Error = result.Error || 'Failed to create API key. Please try again.';\n }\n } catch (error) {\n console.error('Error creating API key:', error);\n this.Error = 'An error occurred while creating the API key.';\n } finally {\n this.IsCreating = false;\n }\n }\n\n /**\n * Copy the API key to clipboard\n */\n public async copyKey(): Promise<void> {\n try {\n await navigator.clipboard.writeText(this.RawApiKey);\n this.KeyCopied = true;\n setTimeout(() => this.KeyCopied = false, 3000);\n } catch (error) {\n console.error('Failed to copy key:', error);\n }\n }\n\n /**\n * Close the dialog\n */\n public close(): void {\n this.reset();\n this.Visible = false;\n this.VisibleChange.emit(false);\n this.Closed.emit();\n }\n\n /**\n * Reset form state\n */\n private reset(): void {\n this.Label = '';\n this.Description = '';\n this.ExpiresAt = null;\n this.NeverExpires = true;\n this.SelectedPreset = null;\n this.Step = 'configure';\n this.RawApiKey = '';\n this.KeyCopied = false;\n this.Error = '';\n\n // Reset scope selections\n for (const category of this.ScopeCategories) {\n category.expanded = false;\n category.allSelected = false;\n for (const scope of category.scopes) {\n scope.selected = false;\n }\n }\n }\n\n /**\n * Get minimum date for expiration (tomorrow)\n */\n public getMinDate(): Date {\n const tomorrow = new Date();\n tomorrow.setDate(tomorrow.getDate() + 1);\n return tomorrow;\n }\n}\n","<!-- Slide-out Backdrop -->\n@if (Visible) {\n <div class=\"slideout-backdrop\" (click)=\"Step !== 'success' ? close() : null\"></div>\n}\n\n<!-- Slide-out Panel -->\n<div class=\"slideout-panel\" [class.open]=\"Visible\">\n <!-- Header -->\n <div class=\"slideout-header\">\n <div class=\"slideout-title\">\n <i class=\"fa-solid fa-key\"></i>\n <span>Generate New API Key</span>\n </div>\n @if (Step !== 'success') {\n <button class=\"slideout-close\" (click)=\"close()\" title=\"Close (Esc)\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n\n <!-- Step Indicator -->\n @if (Step !== 'success') {\n <div class=\"step-indicator\">\n <div class=\"step\" [class.active]=\"Step === 'configure'\" [class.completed]=\"Step === 'scopes'\">\n <div class=\"step-number\">1</div>\n <div class=\"step-label\">Configure</div>\n </div>\n <div class=\"step-connector\" [class.active]=\"Step === 'scopes'\"></div>\n <div class=\"step\" [class.active]=\"Step === 'scopes'\">\n <div class=\"step-number\">2</div>\n <div class=\"step-label\">Permissions</div>\n </div>\n </div>\n }\n\n <div class=\"slideout-content\">\n <!-- Configure Step -->\n @if (Step === 'configure') {\n <div class=\"step-panel\">\n <div class=\"form-section\">\n <label class=\"form-label required\">Key Label</label>\n <input kendoTextBox [(ngModel)]=\"Label\"\n placeholder=\"e.g., ElevenLabs Integration, CI/CD Pipeline\"\n class=\"form-input\" />\n <div class=\"form-hint\">A memorable name to identify this key's purpose</div>\n </div>\n <div class=\"form-section\">\n <label class=\"form-label\">Description</label>\n <textarea kendoTextArea [(ngModel)]=\"Description\"\n placeholder=\"Optional notes about how this key will be used...\"\n [rows]=\"3\"\n class=\"form-textarea\"></textarea>\n </div>\n <div class=\"form-section\">\n <label class=\"form-label\">Expiration</label>\n <div class=\"expiration-options\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" kendoCheckBox\n [(ngModel)]=\"NeverExpires\"\n (change)=\"onNeverExpiresChange()\" />\n <span>Never expires</span>\n </label>\n @if (!NeverExpires) {\n <div class=\"preset-buttons\">\n @for (preset of ExpirationPresets; track preset) {\n <button\n class=\"preset-btn\"\n [class.active]=\"SelectedPreset === preset\"\n (click)=\"onPresetSelect(preset)\">\n {{preset.label}}\n </button>\n }\n </div>\n }\n @if (!NeverExpires && SelectedPreset?.days === -1) {\n <div class=\"custom-date\">\n <kendo-datepicker [(ngModel)]=\"ExpiresAt\"\n [min]=\"getMinDate()\"\n format=\"MMM d, yyyy\"\n placeholder=\"Select expiration date\">\n </kendo-datepicker>\n </div>\n }\n @if (!NeverExpires && ExpiresAt) {\n <div class=\"expiration-preview\">\n <i class=\"fa-solid fa-calendar-check\"></i>\n <span>Key will expire on {{ExpiresAt | date:'MMMM d, yyyy'}}</span>\n </div>\n }\n </div>\n </div>\n @if (Error) {\n <div class=\"error-message\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{Error}}\n </div>\n }\n </div>\n }\n\n <!-- Scopes Step -->\n @if (Step === 'scopes') {\n <div class=\"step-panel scopes-step\">\n <div class=\"scopes-header\">\n <div class=\"scopes-info\">\n <h4>Select Permission Scopes</h4>\n <p>Choose what this API key can access. You can always modify this later.</p>\n </div>\n @if (getSelectedScopeCount() > 0) {\n <div class=\"scopes-count\">\n <span class=\"count\">{{getSelectedScopeCount()}}</span> selected\n </div>\n }\n </div>\n @if (IsLoadingScopes) {\n <mj-loading text=\"Loading scopes...\"></mj-loading>\n }\n @if (!IsLoadingScopes) {\n <div class=\"scope-categories\">\n @for (category of ScopeCategories; track category) {\n <div class=\"scope-category\">\n <div class=\"category-header\" (click)=\"toggleCategory(category)\">\n <div class=\"category-left\">\n <i [class]=\"category.icon\" [style.color]=\"category.color\"></i>\n <span class=\"category-name\">{{category.name}}</span>\n <span class=\"category-badge\">{{category.scopes.length}}</span>\n </div>\n <div class=\"category-right\">\n <label class=\"select-all-label\" (click)=\"$event.stopPropagation()\">\n <input type=\"checkbox\" kendoCheckBox\n [checked]=\"category.allSelected\"\n (change)=\"toggleCategoryAll(category)\" />\n <span>All</span>\n </label>\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!category.expanded\"\n [class.fa-chevron-up]=\"category.expanded\"></i>\n </div>\n </div>\n @if (category.expanded) {\n <div class=\"category-scopes\">\n @for (item of category.scopes; track item) {\n <div class=\"scope-item\">\n <label class=\"scope-label\">\n <input type=\"checkbox\" kendoCheckBox\n [(ngModel)]=\"item.selected\"\n (change)=\"updateCategoryState(category)\" />\n <div class=\"scope-info\">\n <span class=\"scope-name\">{{item.scope.Name}}</span>\n @if (item.scope.Description) {\n <span class=\"scope-desc\">\n {{item.scope.Description}}\n </span>\n }\n </div>\n </label>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n <div class=\"scope-tip\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n <span>Tip: Use wildcards like <code>entities:*</code> for broad access within a category</span>\n </div>\n <!-- No Scopes Warning -->\n @if (!IsLoadingScopes && getSelectedScopeCount() === 0) {\n <div class=\"no-scopes-warning\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <div>\n <strong>Warning: No permissions selected</strong>\n <p>API keys without any assigned scopes will have <strong>no permissions</strong> and cannot perform any operations. This key will be rejected by all API endpoints until scopes are assigned.</p>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Success Step -->\n @if (Step === 'success') {\n <div class=\"step-panel success-step\">\n <div class=\"success-icon\">\n <i class=\"fa-solid fa-check-circle\"></i>\n </div>\n <h3 class=\"success-title\">API Key Created Successfully!</h3>\n <div class=\"key-display\">\n <div class=\"key-warning\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span>Copy this key now. It won't be shown again!</span>\n </div>\n <div class=\"key-value\">\n <code>{{RawApiKey}}</code>\n <button class=\"copy-btn\" (click)=\"copyKey()\" [class.copied]=\"KeyCopied\">\n <i class=\"fa-solid\" [class.fa-copy]=\"!KeyCopied\" [class.fa-check]=\"KeyCopied\"></i>\n <span>{{KeyCopied ? 'Copied!' : 'Copy'}}</span>\n </button>\n </div>\n </div>\n <div class=\"key-details\">\n <div class=\"detail-row\">\n <span class=\"detail-label\">Label:</span>\n <span class=\"detail-value\">{{Label}}</span>\n </div>\n @if (Description) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Description:</span>\n <span class=\"detail-value\">{{Description}}</span>\n </div>\n }\n <div class=\"detail-row\">\n <span class=\"detail-label\">Expires:</span>\n <span class=\"detail-value\">\n {{NeverExpires ? 'Never' : (ExpiresAt | date:'MMMM d, yyyy')}}\n </span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Scopes:</span>\n <span class=\"detail-value\">{{getSelectedScopeCount()}} permissions</span>\n </div>\n </div>\n <div class=\"security-note\">\n <i class=\"fa-solid fa-shield-check\"></i>\n <div>\n <strong>Security Note:</strong>\n Store this key securely. We only store a hash - the original key cannot be recovered.\n </div>\n </div>\n </div>\n }\n </div>\n\n <!-- Footer -->\n <div class=\"slideout-footer\">\n @if (Step === 'configure') {\n <button kendoButton [themeColor]=\"'primary'\" (click)=\"goToScopes()\">\n Next: Permissions\n <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n <button kendoButton (click)=\"close()\">Cancel</button>\n }\n\n @if (Step === 'scopes') {\n <button kendoButton [themeColor]=\"'primary'\"\n [disabled]=\"IsCreating\"\n (click)=\"createKey()\">\n @if (IsCreating) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n }\n @if (!IsCreating) {\n <span>\n <i class=\"fa-solid fa-key\"></i>\n Generate Key\n </span>\n }\n </button>\n <button kendoButton (click)=\"goBack()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n Back\n </button>\n }\n\n @if (Step === 'success') {\n <button kendoButton [themeColor]=\"'primary'\" (click)=\"close()\">\n <i class=\"fa-solid fa-check\"></i>\n Done\n </button>\n }\n </div>\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"api-key-create-dialog.component.js","sourceRoot":"","sources":["../../src/APIKeys/api-key-create-dialog.component.ts","../../src/APIKeys/api-key-create-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, EventEmitter, HostListener, Input, OnInit, Output } from '@angular/core';\nimport { Metadata } from '@memberjunction/core';\nimport { MJAPIScopeEntity } from '@memberjunction/core-entities';\nimport { GraphQLDataProvider, GraphQLEncryptionClient } from '@memberjunction/graphql-dataprovider';\nimport { APIKeysEngineBase, parseAPIScopeUIConfig } from '@memberjunction/api-keys-base';\n\n/** Scope selection item */\ninterface ScopeItem {\n scope: MJAPIScopeEntity;\n selected: boolean;\n}\n\n/** Grouped scopes by category */\ninterface ScopeCategory {\n name: string;\n icon: string;\n color: string;\n scopes: ScopeItem[];\n expanded: boolean;\n allSelected: boolean;\n}\n\n/** Result of key creation */\nexport interface APIKeyCreateResult {\n success: boolean;\n apiKeyId?: string;\n rawKey?: string;\n error?: string;\n}\n/**\n * Dialog for creating new API keys\n * Shows the raw key only once - it cannot be recovered after closing\n */\n@Component({\n standalone: false,\n selector: 'mj-api-key-create-dialog',\n templateUrl: './api-key-create-dialog.component.html',\n styleUrls: ['./api-key-create-dialog.component.css']\n})\nexport class APIKeyCreateDialogComponent implements OnInit {\n @Input() Visible = false;\n @Output() VisibleChange = new EventEmitter<boolean>();\n @Output() Created = new EventEmitter<APIKeyCreateResult>();\n @Output() Closed = new EventEmitter<void>();\n\n // Form fields\n public Label = '';\n public Description = '';\n public ExpiresAt: Date | null = null;\n public NeverExpires = true;\n\n // Expiration presets\n public ExpirationPresets = [\n { label: '30 days', days: 30 },\n { label: '90 days', days: 90 },\n { label: '1 year', days: 365 },\n { label: 'Custom', days: -1 }\n ];\n public SelectedPreset: { label: string; days: number } | null = null;\n\n // Scopes\n public ScopeCategories: ScopeCategory[] = [];\n public IsLoadingScopes = true;\n\n // State\n public IsCreating = false;\n public Step: 'configure' | 'scopes' | 'success' = 'configure';\n public RawApiKey = '';\n public KeyCopied = false;\n public Error = '';\n\n // Default UI config for categories without explicit configuration\n private readonly defaultUIConfig = {\n icon: 'fa-solid fa-ellipsis',\n color: 'var(--mj-text-muted)'\n };\n\n ngOnInit(): void {\n this.loadScopes();\n }\n\n /**\n * Handle escape key to close dialog\n */\n @HostListener('document:keydown.escape')\n public onEscapeKey(): void {\n if (this.Visible && !this.IsCreating) {\n this.close();\n }\n }\n\n /**\n * Load available scopes from cached data.\n * Uses UIConfig from root scopes for category icons/colors.\n */\n private loadScopes(): void {\n this.IsLoadingScopes = true;\n try {\n const base = APIKeysEngineBase.Instance;\n const scopes = base.Scopes;\n\n // Build a map of category -> root scope UIConfig\n // Root scopes (ParentID is null) define the UI appearance for their category\n const categoryUIConfigs = new Map<string, { icon: string; color: string }>();\n for (const scope of scopes) {\n if (!scope.ParentID) {\n // This is a root scope - use its UIConfig for the category\n const uiConfig = parseAPIScopeUIConfig(scope);\n categoryUIConfigs.set(scope.Category, {\n icon: uiConfig.icon || this.defaultUIConfig.icon,\n color: uiConfig.color || this.defaultUIConfig.color\n });\n }\n }\n\n // Group scopes by category\n const categoryMap = new Map<string, ScopeItem[]>();\n for (const scope of scopes) {\n const category = scope.Category || 'Other';\n if (!categoryMap.has(category)) {\n categoryMap.set(category, []);\n }\n categoryMap.get(category)!.push({\n scope,\n selected: false\n });\n }\n\n // Build categories with UI config from root scopes\n this.ScopeCategories = Array.from(categoryMap.entries())\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([name, scopeItems]) => {\n const config = categoryUIConfigs.get(name) || this.defaultUIConfig;\n return {\n name,\n icon: config.icon,\n color: config.color,\n scopes: scopeItems.sort((a, b) => a.scope.Name.localeCompare(b.scope.Name)),\n expanded: false,\n allSelected: false\n };\n });\n } catch (error) {\n console.error('Error loading scopes:', error);\n } finally {\n this.IsLoadingScopes = false;\n }\n }\n\n /**\n * Handle expiration preset selection\n */\n public onPresetSelect(preset: { label: string; days: number }): void {\n this.SelectedPreset = preset;\n this.NeverExpires = false;\n\n if (preset.days > 0) {\n const date = new Date();\n date.setDate(date.getDate() + preset.days);\n this.ExpiresAt = date;\n } else {\n this.ExpiresAt = null;\n }\n }\n\n /**\n * Handle never expires toggle\n */\n public onNeverExpiresChange(): void {\n if (this.NeverExpires) {\n this.ExpiresAt = null;\n this.SelectedPreset = null;\n }\n }\n\n /**\n * Toggle category expansion\n */\n public toggleCategory(category: ScopeCategory): void {\n category.expanded = !category.expanded;\n }\n\n /**\n * Toggle all scopes in a category\n */\n public toggleCategoryAll(category: ScopeCategory): void {\n category.allSelected = !category.allSelected;\n for (const item of category.scopes) {\n item.selected = category.allSelected;\n }\n }\n\n /**\n * Update category allSelected state\n */\n public updateCategoryState(category: ScopeCategory): void {\n category.allSelected = category.scopes.every(s => s.selected);\n }\n\n /**\n * Get selected scope count\n */\n public getSelectedScopeCount(): number {\n return this.ScopeCategories.reduce((sum, cat) =>\n sum + cat.scopes.filter(s => s.selected).length, 0);\n }\n\n /**\n * Proceed to scopes step\n */\n public goToScopes(): void {\n if (!this.Label.trim()) {\n this.Error = 'Please enter a label for the API key';\n return;\n }\n this.Error = '';\n this.Step = 'scopes';\n }\n\n /**\n * Go back to configure step\n */\n public goBack(): void {\n this.Step = 'configure';\n }\n\n /**\n * Create the API key using server-side cryptographic hashing\n */\n public async createKey(): Promise<void> {\n this.IsCreating = true;\n this.Error = '';\n\n try {\n // Get selected scope IDs\n const selectedScopeIds = this.ScopeCategories\n .flatMap(cat => cat.scopes)\n .filter(s => s.selected)\n .map(s => s.scope.ID);\n\n // Get the GraphQL provider and create the encryption client\n const provider = Metadata.Provider as GraphQLDataProvider;\n const encryptionClient = new GraphQLEncryptionClient(provider);\n\n // Call the server to create the API key with proper crypto hashing\n const result = await encryptionClient.CreateAPIKey({\n Label: this.Label.trim(),\n Description: this.Description.trim() || undefined,\n ExpiresAt: this.NeverExpires ? undefined : (this.ExpiresAt || undefined),\n ScopeIDs: selectedScopeIds.length > 0 ? selectedScopeIds : undefined\n });\n\n if (result.Success && result.RawKey) {\n this.RawApiKey = result.RawKey;\n this.Step = 'success';\n\n this.Created.emit({\n success: true,\n rawKey: result.RawKey\n });\n } else {\n this.Error = result.Error || 'Failed to create API key. Please try again.';\n }\n } catch (error) {\n console.error('Error creating API key:', error);\n this.Error = 'An error occurred while creating the API key.';\n } finally {\n this.IsCreating = false;\n }\n }\n\n /**\n * Copy the API key to clipboard\n */\n public async copyKey(): Promise<void> {\n try {\n await navigator.clipboard.writeText(this.RawApiKey);\n this.KeyCopied = true;\n setTimeout(() => this.KeyCopied = false, 3000);\n } catch (error) {\n console.error('Failed to copy key:', error);\n }\n }\n\n /**\n * Close the dialog\n */\n public close(): void {\n this.reset();\n this.Visible = false;\n this.VisibleChange.emit(false);\n this.Closed.emit();\n }\n\n /**\n * Reset form state\n */\n private reset(): void {\n this.Label = '';\n this.Description = '';\n this.ExpiresAt = null;\n this.NeverExpires = true;\n this.SelectedPreset = null;\n this.Step = 'configure';\n this.RawApiKey = '';\n this.KeyCopied = false;\n this.Error = '';\n\n // Reset scope selections\n for (const category of this.ScopeCategories) {\n category.expanded = false;\n category.allSelected = false;\n for (const scope of category.scopes) {\n scope.selected = false;\n }\n }\n }\n\n /**\n * Get minimum date for expiration (tomorrow)\n */\n public getMinDate(): Date {\n const tomorrow = new Date();\n tomorrow.setDate(tomorrow.getDate() + 1);\n return tomorrow;\n }\n}\n","<!-- Slide-out Backdrop -->\n@if (Visible) {\n <div class=\"slideout-backdrop\" (click)=\"Step !== 'success' ? close() : null\"></div>\n}\n\n<!-- Slide-out Panel -->\n<div class=\"slideout-panel\" [class.open]=\"Visible\">\n <!-- Header -->\n <div class=\"slideout-header\">\n <div class=\"slideout-title\">\n <i class=\"fa-solid fa-key\"></i>\n <span>Generate New API Key</span>\n </div>\n @if (Step !== 'success') {\n <button class=\"slideout-close\" (click)=\"close()\" title=\"Close (Esc)\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n\n <!-- Step Indicator -->\n @if (Step !== 'success') {\n <div class=\"step-indicator\">\n <div class=\"step\" [class.active]=\"Step === 'configure'\" [class.completed]=\"Step === 'scopes'\">\n <div class=\"step-number\">1</div>\n <div class=\"step-label\">Configure</div>\n </div>\n <div class=\"step-connector\" [class.active]=\"Step === 'scopes'\"></div>\n <div class=\"step\" [class.active]=\"Step === 'scopes'\">\n <div class=\"step-number\">2</div>\n <div class=\"step-label\">Permissions</div>\n </div>\n </div>\n }\n\n <div class=\"slideout-content\">\n <!-- Configure Step -->\n @if (Step === 'configure') {\n <div class=\"step-panel\">\n <div class=\"form-section\">\n <label class=\"form-label required\">Key Label</label>\n <input kendoTextBox [(ngModel)]=\"Label\"\n placeholder=\"e.g., ElevenLabs Integration, CI/CD Pipeline\"\n class=\"form-input\" />\n <div class=\"form-hint\">A memorable name to identify this key's purpose</div>\n </div>\n <div class=\"form-section\">\n <label class=\"form-label\">Description</label>\n <textarea kendoTextArea [(ngModel)]=\"Description\"\n placeholder=\"Optional notes about how this key will be used...\"\n [rows]=\"3\"\n class=\"form-textarea\"></textarea>\n </div>\n <div class=\"form-section\">\n <label class=\"form-label\">Expiration</label>\n <div class=\"expiration-options\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" kendoCheckBox\n [(ngModel)]=\"NeverExpires\"\n (change)=\"onNeverExpiresChange()\" />\n <span>Never expires</span>\n </label>\n @if (!NeverExpires) {\n <div class=\"preset-buttons\">\n @for (preset of ExpirationPresets; track preset) {\n <button\n class=\"preset-btn\"\n [class.active]=\"SelectedPreset === preset\"\n (click)=\"onPresetSelect(preset)\">\n {{preset.label}}\n </button>\n }\n </div>\n }\n @if (!NeverExpires && SelectedPreset?.days === -1) {\n <div class=\"custom-date\">\n <kendo-datepicker [(ngModel)]=\"ExpiresAt\"\n [min]=\"getMinDate()\"\n format=\"MMM d, yyyy\"\n placeholder=\"Select expiration date\">\n </kendo-datepicker>\n </div>\n }\n @if (!NeverExpires && ExpiresAt) {\n <div class=\"expiration-preview\">\n <i class=\"fa-solid fa-calendar-check\"></i>\n <span>Key will expire on {{ExpiresAt | date:'MMMM d, yyyy'}}</span>\n </div>\n }\n </div>\n </div>\n @if (Error) {\n <div class=\"error-message\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{Error}}\n </div>\n }\n </div>\n }\n\n <!-- Scopes Step -->\n @if (Step === 'scopes') {\n <div class=\"step-panel scopes-step\">\n <div class=\"scopes-header\">\n <div class=\"scopes-info\">\n <h4>Select Permission Scopes</h4>\n <p>Choose what this API key can access. You can always modify this later.</p>\n </div>\n @if (getSelectedScopeCount() > 0) {\n <div class=\"scopes-count\">\n <span class=\"count\">{{getSelectedScopeCount()}}</span> selected\n </div>\n }\n </div>\n @if (IsLoadingScopes) {\n <mj-loading text=\"Loading scopes...\"></mj-loading>\n }\n @if (!IsLoadingScopes) {\n <div class=\"scope-categories\">\n @for (category of ScopeCategories; track category) {\n <div class=\"scope-category\">\n <div class=\"category-header\" (click)=\"toggleCategory(category)\">\n <div class=\"category-left\">\n <i [class]=\"category.icon\" [style.color]=\"category.color\"></i>\n <span class=\"category-name\">{{category.name}}</span>\n <span class=\"category-badge\">{{category.scopes.length}}</span>\n </div>\n <div class=\"category-right\">\n <label class=\"select-all-label\" (click)=\"$event.stopPropagation()\">\n <input type=\"checkbox\" kendoCheckBox\n [checked]=\"category.allSelected\"\n (change)=\"toggleCategoryAll(category)\" />\n <span>All</span>\n </label>\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!category.expanded\"\n [class.fa-chevron-up]=\"category.expanded\"></i>\n </div>\n </div>\n @if (category.expanded) {\n <div class=\"category-scopes\">\n @for (item of category.scopes; track item) {\n <div class=\"scope-item\">\n <label class=\"scope-label\">\n <input type=\"checkbox\" kendoCheckBox\n [(ngModel)]=\"item.selected\"\n (change)=\"updateCategoryState(category)\" />\n <div class=\"scope-info\">\n <span class=\"scope-name\">{{item.scope.Name}}</span>\n @if (item.scope.Description) {\n <span class=\"scope-desc\">\n {{item.scope.Description}}\n </span>\n }\n </div>\n </label>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n <div class=\"scope-tip\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n <span>Tip: Use wildcards like <code>entities:*</code> for broad access within a category</span>\n </div>\n <!-- No Scopes Warning -->\n @if (!IsLoadingScopes && getSelectedScopeCount() === 0) {\n <div class=\"no-scopes-warning\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <div>\n <strong>Warning: No permissions selected</strong>\n <p>API keys without any assigned scopes will have <strong>no permissions</strong> and cannot perform any operations. This key will be rejected by all API endpoints until scopes are assigned.</p>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Success Step -->\n @if (Step === 'success') {\n <div class=\"step-panel success-step\">\n <div class=\"success-icon\">\n <i class=\"fa-solid fa-check-circle\"></i>\n </div>\n <h3 class=\"success-title\">API Key Created Successfully!</h3>\n <div class=\"key-display\">\n <div class=\"key-warning\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span>Copy this key now. It won't be shown again!</span>\n </div>\n <div class=\"key-value\">\n <code>{{RawApiKey}}</code>\n <button class=\"copy-btn\" (click)=\"copyKey()\" [class.copied]=\"KeyCopied\">\n <i class=\"fa-solid\" [class.fa-copy]=\"!KeyCopied\" [class.fa-check]=\"KeyCopied\"></i>\n <span>{{KeyCopied ? 'Copied!' : 'Copy'}}</span>\n </button>\n </div>\n </div>\n <div class=\"key-details\">\n <div class=\"detail-row\">\n <span class=\"detail-label\">Label:</span>\n <span class=\"detail-value\">{{Label}}</span>\n </div>\n @if (Description) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Description:</span>\n <span class=\"detail-value\">{{Description}}</span>\n </div>\n }\n <div class=\"detail-row\">\n <span class=\"detail-label\">Expires:</span>\n <span class=\"detail-value\">\n {{NeverExpires ? 'Never' : (ExpiresAt | date:'MMMM d, yyyy')}}\n </span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Scopes:</span>\n <span class=\"detail-value\">{{getSelectedScopeCount()}} permissions</span>\n </div>\n </div>\n <div class=\"security-note\">\n <i class=\"fa-solid fa-shield-check\"></i>\n <div>\n <strong>Security Note:</strong>\n Store this key securely. We only store a hash - the original key cannot be recovered.\n </div>\n </div>\n </div>\n }\n </div>\n\n <!-- Footer -->\n <div class=\"slideout-footer\">\n @if (Step === 'configure') {\n <button kendoButton [themeColor]=\"'primary'\" (click)=\"goToScopes()\">\n Next: Permissions\n <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n <button kendoButton (click)=\"close()\">Cancel</button>\n }\n\n @if (Step === 'scopes') {\n <button kendoButton [themeColor]=\"'primary'\"\n [disabled]=\"IsCreating\"\n (click)=\"createKey()\">\n @if (IsCreating) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n }\n @if (!IsCreating) {\n <span>\n <i class=\"fa-solid fa-key\"></i>\n Generate Key\n </span>\n }\n </button>\n <button kendoButton (click)=\"goBack()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n Back\n </button>\n }\n\n @if (Step === 'success') {\n <button kendoButton [themeColor]=\"'primary'\" (click)=\"close()\">\n <i class=\"fa-solid fa-check\"></i>\n Done\n </button>\n }\n </div>\n</div>\n"]}
|
|
@@ -635,7 +635,7 @@ export class APIKeyEditPanelComponent {
|
|
|
635
635
|
// Default UI config for categories without explicit configuration
|
|
636
636
|
defaultUIConfig = {
|
|
637
637
|
icon: 'fa-solid fa-ellipsis',
|
|
638
|
-
color: '
|
|
638
|
+
color: 'var(--mj-text-muted)'
|
|
639
639
|
};
|
|
640
640
|
async ngOnChanges(changes) {
|
|
641
641
|
if (changes['KeyId'] && this.KeyId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-key-edit-panel.component.js","sourceRoot":"","sources":["../../src/APIKeys/api-key-edit-panel.component.ts","../../src/APIKeys/api-key-edit-panel.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, EventEmitter, HostListener, Input, OnChanges, Output, SimpleChanges } from '@angular/core';\nimport { Metadata, RunView } from '@memberjunction/core';\nimport { MJAPIKeyEntity, MJAPIScopeEntity, MJAPIKeyScopeEntity, MJAPIKeyUsageLogEntity } from '@memberjunction/core-entities';\nimport { GraphQLDataProvider, GraphQLEncryptionClient } from '@memberjunction/graphql-dataprovider';\nimport { APIKeysEngineBase, parseAPIScopeUIConfig } from '@memberjunction/api-keys-base';\n/** Scope with selection state */\ninterface ScopeItem {\n scope: MJAPIScopeEntity;\n selected: boolean;\n originallySelected: boolean;\n}\n\n/** Grouped scopes by category */\ninterface ScopeCategory {\n name: string;\n icon: string;\n color: string;\n scopes: ScopeItem[];\n expanded: boolean;\n allSelected: boolean;\n}\n\n/** Usage log display item */\ninterface UsageLogItem {\n timestamp: Date;\n endpoint: string;\n method: string;\n statusCode: number;\n responseTime: number;\n ipAddress: string;\n}\n\n/**\n * Panel for viewing and editing existing API keys\n */\n@Component({\n standalone: false,\n selector: 'mj-api-key-edit-panel',\n templateUrl: './api-key-edit-panel.component.html',\n styleUrls: ['./api-key-edit-panel.component.css']\n})\nexport class APIKeyEditPanelComponent implements OnChanges {\n @Input() Visible = false;\n @Input() KeyId: string | null = null;\n @Output() VisibleChange = new EventEmitter<boolean>();\n @Output() Updated = new EventEmitter<MJAPIKeyEntity>();\n @Output() Revoked = new EventEmitter<MJAPIKeyEntity>();\n @Output() Closed = new EventEmitter<void>();\n\n private md = new Metadata();\n\n // Current key\n public APIKey: MJAPIKeyEntity | null = null;\n public IsLoading = true;\n public IsSaving = false;\n public IsRevoking = false;\n\n // Edit mode\n public IsEditing = false;\n public EditLabel = '';\n public EditDescription = '';\n public EditExpiresAt: Date | null = null;\n\n // Scopes\n public ScopeCategories: ScopeCategory[] = [];\n public IsLoadingScopes = true;\n public HasScopeChanges = false;\n\n // Usage logs\n public UsageLogs: UsageLogItem[] = [];\n public IsLoadingLogs = true;\n\n // Tabs\n public ActiveTab: 'details' | 'scopes' | 'usage' = 'details';\n\n // Revoke confirmation\n public ShowRevokeConfirm = false;\n public RevokeConfirmText = '';\n\n // Messages\n public SuccessMessage = '';\n public ErrorMessage = '';\n\n // Default UI config for categories without explicit configuration\n private readonly defaultUIConfig = {\n icon: 'fa-solid fa-ellipsis',\n color: '#6b7280'\n };\n\n async ngOnChanges(changes: SimpleChanges): Promise<void> {\n if (changes['KeyId'] && this.KeyId) {\n await this.loadKey();\n }\n }\n\n /**\n * Handle escape key to close panel\n */\n @HostListener('document:keydown.escape')\n public onEscapeKey(): void {\n if (this.Visible && !this.IsSaving && !this.IsRevoking) {\n this.close();\n }\n }\n\n /**\n * Load the API key and related data\n */\n private async loadKey(): Promise<void> {\n this.IsLoading = true;\n this.resetState();\n\n try {\n const key = await this.md.GetEntityObject<MJAPIKeyEntity>('MJ: API Keys');\n if (await key.Load(this.KeyId!)) {\n this.APIKey = key;\n this.EditLabel = key.Label;\n this.EditDescription = key.Description || '';\n this.EditExpiresAt = key.ExpiresAt;\n\n // Load scopes and usage in parallel\n await Promise.all([\n this.loadScopes(),\n this.loadUsageLogs()\n ]);\n }\n } catch (error) {\n console.error('Error loading API key:', error);\n this.ErrorMessage = 'Failed to load API key details';\n } finally {\n this.IsLoading = false;\n }\n }\n\n /**\n * Load all scopes and mark assigned ones\n */\n private async loadScopes(): Promise<void> {\n this.IsLoadingScopes = true;\n try {\n const rv = new RunView();\n const base = APIKeysEngineBase.Instance;\n\n // Get all scopes from cache, load assigned scopes from DB\n const allScopes = base.Scopes;\n const assignedScopesResult = await rv.RunView<MJAPIKeyScopeEntity>({\n EntityName: 'MJ: API Key Scopes',\n ExtraFilter: `APIKeyID='${this.KeyId}'`,\n ResultType: 'entity_object'\n });\n\n if (assignedScopesResult.Success) {\n const assignedScopeIds = new Set(\n assignedScopesResult.Results.map(ks => ks.ScopeID)\n );\n\n // Build category UI config from root scopes\n const categoryUIConfigs = new Map<string, { icon: string; color: string }>();\n for (const scope of allScopes) {\n if (!scope.ParentID) {\n const uiConfig = parseAPIScopeUIConfig(scope);\n categoryUIConfigs.set(scope.Category, {\n icon: uiConfig.icon || this.defaultUIConfig.icon,\n color: uiConfig.color || this.defaultUIConfig.color\n });\n }\n }\n\n const categoryMap = new Map<string, ScopeItem[]>();\n\n for (const scope of allScopes) {\n const category = scope.Category || 'Other';\n if (!categoryMap.has(category)) {\n categoryMap.set(category, []);\n }\n const isSelected = assignedScopeIds.has(scope.ID);\n categoryMap.get(category)!.push({\n scope,\n selected: isSelected,\n originallySelected: isSelected\n });\n }\n\n this.ScopeCategories = Array.from(categoryMap.entries()).map(([name, scopes]) => {\n const config = categoryUIConfigs.get(name) || this.defaultUIConfig;\n return {\n name,\n icon: config.icon,\n color: config.color,\n scopes: scopes.sort((a, b) => a.scope.Name.localeCompare(b.scope.Name)),\n expanded: scopes.some(s => s.selected),\n allSelected: scopes.length > 0 && scopes.every(s => s.selected)\n };\n }).sort((a, b) => a.name.localeCompare(b.name));\n }\n } catch (error) {\n console.error('Error loading scopes:', error);\n } finally {\n this.IsLoadingScopes = false;\n }\n }\n\n /**\n * Load usage logs for this key\n */\n private async loadUsageLogs(): Promise<void> {\n this.IsLoadingLogs = true;\n try {\n const rv = new RunView();\n const result = await rv.RunView<MJAPIKeyUsageLogEntity>({\n EntityName: 'MJ: API Key Usage Logs',\n ExtraFilter: `APIKeyID='${this.KeyId}'`,\n OrderBy: '__mj_CreatedAt DESC',\n MaxRows: 100,\n ResultType: 'entity_object'\n });\n\n if (result.Success) {\n this.UsageLogs = result.Results.map(log => ({\n timestamp: log.__mj_CreatedAt,\n endpoint: log.Endpoint || '/unknown',\n method: log.Method || 'GET',\n statusCode: log.StatusCode || 200,\n responseTime: log.ResponseTimeMs || 0,\n ipAddress: log.IPAddress || 'Unknown'\n }));\n }\n } catch (error) {\n console.error('Error loading usage logs:', error);\n } finally {\n this.IsLoadingLogs = false;\n }\n }\n\n /**\n * Reset component state\n */\n private resetState(): void {\n this.IsEditing = false;\n this.ShowRevokeConfirm = false;\n this.RevokeConfirmText = '';\n this.SuccessMessage = '';\n this.ErrorMessage = '';\n this.HasScopeChanges = false;\n this.ActiveTab = 'details';\n }\n\n /**\n * Toggle edit mode\n */\n public toggleEdit(): void {\n if (this.IsEditing) {\n // Cancel edit\n this.EditLabel = this.APIKey!.Label;\n this.EditDescription = this.APIKey!.Description || '';\n this.EditExpiresAt = this.APIKey!.ExpiresAt;\n }\n this.IsEditing = !this.IsEditing;\n }\n\n /**\n * Save changes to the key\n */\n public async saveChanges(): Promise<void> {\n if (!this.APIKey) return;\n\n this.IsSaving = true;\n this.ErrorMessage = '';\n\n try {\n this.APIKey.Label = this.EditLabel.trim();\n this.APIKey.Description = this.EditDescription.trim() || null;\n this.APIKey.ExpiresAt = this.EditExpiresAt;\n\n const result = await this.APIKey.Save();\n if (result) {\n this.IsEditing = false;\n this.SuccessMessage = 'API key updated successfully';\n this.Updated.emit(this.APIKey);\n setTimeout(() => this.SuccessMessage = '', 3000);\n } else {\n this.ErrorMessage = 'Failed to save changes';\n }\n } catch (error) {\n console.error('Error saving key:', error);\n this.ErrorMessage = 'An error occurred while saving';\n } finally {\n this.IsSaving = false;\n }\n }\n\n /**\n * Save scope changes\n */\n public async saveScopeChanges(): Promise<void> {\n if (!this.APIKey) return;\n\n this.IsSaving = true;\n this.ErrorMessage = '';\n\n try {\n const allScopes = this.ScopeCategories.flatMap(cat => cat.scopes);\n\n // Find scopes to add and remove\n const toAdd = allScopes.filter(s => s.selected && !s.originallySelected);\n const toRemove = allScopes.filter(s => !s.selected && s.originallySelected);\n\n // Add new scope assignments\n for (const item of toAdd) {\n const keyScope = await this.md.GetEntityObject<MJAPIKeyScopeEntity>('MJ: API Key Scopes');\n keyScope.NewRecord();\n keyScope.APIKeyID = this.APIKey.ID;\n keyScope.ScopeID = item.scope.ID;\n await keyScope.Save();\n item.originallySelected = true;\n }\n\n // Remove scope assignments\n const rv = new RunView();\n for (const item of toRemove) {\n const result = await rv.RunView<MJAPIKeyScopeEntity>({\n EntityName: 'MJ: API Key Scopes',\n ExtraFilter: `APIKeyID='${this.APIKey.ID}' AND ScopeID='${item.scope.ID}'`,\n ResultType: 'entity_object'\n });\n if (result.Success && result.Results.length > 0) {\n await result.Results[0].Delete();\n }\n item.originallySelected = false;\n }\n\n this.HasScopeChanges = false;\n this.SuccessMessage = 'Permissions updated successfully';\n setTimeout(() => this.SuccessMessage = '', 3000);\n } catch (error) {\n console.error('Error saving scopes:', error);\n this.ErrorMessage = 'Failed to update permissions';\n } finally {\n this.IsSaving = false;\n }\n }\n\n /**\n * Check for scope changes and update category allSelected states\n */\n public onScopeChange(): void {\n // Update allSelected state for each category\n for (const category of this.ScopeCategories) {\n category.allSelected = category.scopes.length > 0 && category.scopes.every(s => s.selected);\n }\n\n // Track overall changes\n const allScopes = this.ScopeCategories.flatMap(cat => cat.scopes);\n this.HasScopeChanges = allScopes.some(s => s.selected !== s.originallySelected);\n }\n\n /**\n * Toggle category expansion\n */\n public toggleCategory(category: ScopeCategory): void {\n category.expanded = !category.expanded;\n }\n\n /**\n * Toggle all scopes in a category on/off\n */\n public toggleCategoryAll(category: ScopeCategory): void {\n // Toggle to opposite of current allSelected state\n const newState = !category.allSelected;\n category.allSelected = newState;\n\n // Apply to all scopes in category\n for (const item of category.scopes) {\n item.selected = newState;\n }\n\n // Update change tracking\n this.onScopeChange();\n }\n\n /**\n * Start revoke flow\n */\n public startRevoke(): void {\n this.ShowRevokeConfirm = true;\n this.RevokeConfirmText = '';\n }\n\n /**\n * Cancel revoke\n */\n public cancelRevoke(): void {\n this.ShowRevokeConfirm = false;\n this.RevokeConfirmText = '';\n }\n\n /**\n * Confirm and execute revoke using GraphQL client\n */\n public async confirmRevoke(): Promise<void> {\n if (!this.APIKey || this.RevokeConfirmText !== 'REVOKE') return;\n\n this.IsRevoking = true;\n this.ErrorMessage = '';\n\n try {\n const provider = Metadata.Provider as GraphQLDataProvider;\n const encryptionClient = new GraphQLEncryptionClient(provider);\n\n const result = await encryptionClient.RevokeAPIKey(this.APIKey.ID);\n\n if (result.Success) {\n // Update local state to reflect the change\n this.APIKey.Status = 'Revoked';\n this.ShowRevokeConfirm = false;\n this.SuccessMessage = 'API key has been revoked';\n this.Revoked.emit(this.APIKey);\n } else {\n this.ErrorMessage = result.Error || 'Failed to revoke key';\n }\n } catch (error) {\n console.error('Error revoking key:', error);\n this.ErrorMessage = 'An error occurred while revoking';\n } finally {\n this.IsRevoking = false;\n }\n }\n\n /**\n * Format date for display\n */\n public formatDate(date: Date | null): string {\n if (!date) return 'Never';\n return new Date(date).toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n });\n }\n\n /**\n * Format relative time\n */\n public formatRelativeTime(date: Date): string {\n const now = new Date();\n const diff = now.getTime() - new Date(date).getTime();\n const minutes = Math.floor(diff / 60000);\n const hours = Math.floor(diff / 3600000);\n const days = Math.floor(diff / 86400000);\n\n if (minutes < 1) return 'Just now';\n if (minutes < 60) return `${minutes}m ago`;\n if (hours < 24) return `${hours}h ago`;\n if (days < 7) return `${days}d ago`;\n\n return new Date(date).toLocaleDateString();\n }\n\n /**\n * Get status class for HTTP status code\n */\n public getStatusClass(statusCode: number): string {\n if (statusCode >= 200 && statusCode < 300) return 'status-success';\n if (statusCode >= 400 && statusCode < 500) return 'status-warning';\n if (statusCode >= 500) return 'status-error';\n return '';\n }\n\n /**\n * Get assigned scope count\n */\n public getAssignedScopeCount(): number {\n return this.ScopeCategories.reduce((sum, cat) =>\n sum + cat.scopes.filter(s => s.selected).length, 0);\n }\n\n /**\n * Get selected scope count for a category (for template use)\n */\n public getSelectedCount(category: ScopeCategory): number {\n return category.scopes.filter(s => s.selected).length;\n }\n\n /**\n * Get minimum date for expiration (tomorrow)\n */\n public getMinDate(): Date {\n const tomorrow = new Date();\n tomorrow.setDate(tomorrow.getDate() + 1);\n return tomorrow;\n }\n\n /**\n * Close the panel\n */\n public close(): void {\n this.Visible = false;\n this.VisibleChange.emit(false);\n this.Closed.emit();\n }\n}\n","<!-- Slide-out Backdrop -->\n@if (Visible) {\n <div class=\"slideout-backdrop\" (click)=\"close()\"></div>\n}\n\n<!-- Slide-out Panel -->\n<div class=\"slideout-panel\" [class.open]=\"Visible\">\n <!-- Header -->\n <div class=\"slideout-header\">\n <div class=\"slideout-title\">\n <i class=\"fa-solid fa-key\"></i>\n <span>API Key Details</span>\n <span class=\"key-status\" [class.active]=\"APIKey?.Status === 'Active'\"\n [class.revoked]=\"APIKey?.Status === 'Revoked'\">\n {{APIKey?.Status}}\n </span>\n </div>\n <button class=\"slideout-close\" (click)=\"close()\" title=\"Close (Esc)\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n @if (IsLoading) {\n <mj-loading text=\"Loading key details...\"></mj-loading>\n }\n\n @if (!IsLoading && APIKey) {\n <!-- Success/Error Messages -->\n @if (SuccessMessage) {\n <div class=\"message success\">\n <i class=\"fa-solid fa-check-circle\"></i>\n {{SuccessMessage}}\n </div>\n }\n @if (ErrorMessage) {\n <div class=\"message error\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{ErrorMessage}}\n </div>\n }\n <!-- Tabs -->\n <div class=\"slideout-tabs\">\n <button class=\"slideout-tab\" [class.active]=\"ActiveTab === 'details'\"\n (click)=\"ActiveTab = 'details'\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Details\n </button>\n <button class=\"slideout-tab\" [class.active]=\"ActiveTab === 'scopes'\"\n (click)=\"ActiveTab = 'scopes'\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n Permissions\n @if (HasScopeChanges) {\n <span class=\"tab-badge unsaved\">!</span>\n }\n </button>\n <button class=\"slideout-tab\" [class.active]=\"ActiveTab === 'usage'\"\n (click)=\"ActiveTab = 'usage'\">\n <i class=\"fa-solid fa-chart-line\"></i>\n Usage\n </button>\n </div>\n <div class=\"slideout-content\">\n <!-- Details Tab -->\n @if (ActiveTab === 'details') {\n <div class=\"tab-panel\">\n <div class=\"key-info-card\">\n <div class=\"info-header\">\n <div class=\"info-row\">\n <span class=\"info-label\">Key Hash</span>\n <code class=\"hash-value\">{{APIKey.Hash}}</code>\n </div>\n </div>\n <div class=\"info-grid\">\n <div class=\"info-item\">\n <span class=\"info-label\">Created</span>\n <span class=\"info-value\">{{formatDate(APIKey.__mj_CreatedAt)}}</span>\n </div>\n <div class=\"info-item\">\n <span class=\"info-label\">Created By</span>\n <span class=\"info-value\">{{APIKey.CreatedByUser}}</span>\n </div>\n <div class=\"info-item\">\n <span class=\"info-label\">Owner</span>\n <span class=\"info-value\">{{APIKey.User}}</span>\n </div>\n <div class=\"info-item\">\n <span class=\"info-label\">Last Used</span>\n <span class=\"info-value\" [class.never-used]=\"!APIKey.LastUsedAt\">\n {{APIKey.LastUsedAt ? formatDate(APIKey.LastUsedAt) : 'Never'}}\n </span>\n </div>\n </div>\n </div>\n <!-- Editable Fields -->\n <div class=\"edit-section\">\n <div class=\"section-header\">\n <h4>Key Configuration</h4>\n @if (APIKey.Status === 'Active') {\n <button class=\"edit-toggle\"\n (click)=\"toggleEdit()\">\n <i class=\"fa-solid\" [class.fa-pencil]=\"!IsEditing\" [class.fa-times]=\"IsEditing\"></i>\n {{IsEditing ? 'Cancel' : 'Edit'}}\n </button>\n }\n </div>\n <div class=\"form-field\">\n <label>Label</label>\n <input kendoTextBox [(ngModel)]=\"EditLabel\"\n [disabled]=\"!IsEditing\"\n class=\"form-input\" />\n </div>\n <div class=\"form-field\">\n <label>Description</label>\n <textarea kendoTextArea [(ngModel)]=\"EditDescription\"\n [disabled]=\"!IsEditing\"\n [rows]=\"3\"\n class=\"form-textarea\"></textarea>\n </div>\n <div class=\"form-field\">\n <label>Expiration</label>\n <div class=\"expiration-field\">\n <kendo-datepicker [(ngModel)]=\"EditExpiresAt\"\n [disabled]=\"!IsEditing\"\n [min]=\"getMinDate()\"\n format=\"MMM d, yyyy\"\n placeholder=\"Never expires\">\n </kendo-datepicker>\n @if (IsEditing && EditExpiresAt) {\n <button class=\"clear-btn\"\n (click)=\"EditExpiresAt = null\">\n <i class=\"fa-solid fa-times\"></i>\n Never expires\n </button>\n }\n </div>\n </div>\n @if (IsEditing) {\n <div class=\"edit-actions\">\n <button kendoButton [themeColor]=\"'primary'\"\n [disabled]=\"IsSaving\"\n (click)=\"saveChanges()\">\n @if (IsSaving) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n }\n @if (!IsSaving) {\n <span>\n <i class=\"fa-solid fa-save\"></i>\n Save Changes\n </span>\n }\n </button>\n </div>\n }\n </div>\n <!-- Revoke Section -->\n @if (APIKey.Status === 'Active') {\n <div class=\"danger-zone\">\n <h4>Danger Zone</h4>\n @if (!ShowRevokeConfirm) {\n <div class=\"revoke-section\">\n <div class=\"revoke-info\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <div>\n <strong>Revoke this API key</strong>\n <p>Once revoked, this key will immediately stop working. This action cannot be undone.</p>\n </div>\n </div>\n <button class=\"revoke-btn\" (click)=\"startRevoke()\">\n <i class=\"fa-solid fa-ban\"></i>\n Revoke Key\n </button>\n </div>\n }\n @if (ShowRevokeConfirm) {\n <div class=\"revoke-confirm\">\n <div class=\"confirm-warning\">\n <i class=\"fa-solid fa-skull-crossbones\"></i>\n <div>\n <strong>Are you absolutely sure?</strong>\n <p>This will permanently revoke the API key. Any applications using this key will immediately lose access.</p>\n </div>\n </div>\n <div class=\"confirm-input\">\n <label>Type <code>REVOKE</code> to confirm:</label>\n <input kendoTextBox [(ngModel)]=\"RevokeConfirmText\"\n placeholder=\"REVOKE\" />\n </div>\n <div class=\"confirm-actions\">\n <button kendoButton (click)=\"cancelRevoke()\">Cancel</button>\n <button class=\"confirm-revoke-btn\"\n [disabled]=\"RevokeConfirmText !== 'REVOKE' || IsRevoking\"\n (click)=\"confirmRevoke()\">\n @if (IsRevoking) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n }\n @if (!IsRevoking) {\n <span>\n <i class=\"fa-solid fa-ban\"></i>\n Revoke Key\n </span>\n }\n </button>\n </div>\n </div>\n }\n </div>\n }\n <!-- Revoked Notice -->\n @if (APIKey.Status === 'Revoked') {\n <div class=\"revoked-notice\">\n <i class=\"fa-solid fa-ban\"></i>\n <div>\n <strong>This API key has been revoked</strong>\n <p>It can no longer be used for authentication. Consider deleting this record if no longer needed.</p>\n </div>\n </div>\n }\n </div>\n }\n <!-- Scopes Tab -->\n @if (ActiveTab === 'scopes') {\n <div class=\"tab-panel scopes-panel\">\n <div class=\"scopes-header\">\n <div class=\"scopes-info\">\n <span class=\"scope-count\">{{getAssignedScopeCount()}} permissions assigned</span>\n </div>\n @if (HasScopeChanges && APIKey.Status === 'Active') {\n <button kendoButton [themeColor]=\"'primary'\"\n [disabled]=\"IsSaving\"\n (click)=\"saveScopeChanges()\">\n @if (IsSaving) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n }\n @if (!IsSaving) {\n <span>\n <i class=\"fa-solid fa-save\"></i>\n Save Changes\n </span>\n }\n </button>\n }\n </div>\n <!-- No Scopes Warning -->\n @if (!IsLoadingScopes && getAssignedScopeCount() === 0 && APIKey.Status === 'Active') {\n <div class=\"no-scopes-warning\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <div>\n <strong>Warning: No permissions assigned</strong>\n <p>This API key has no assigned scopes and cannot perform any operations. All API requests using this key will be rejected until scopes are assigned.</p>\n </div>\n </div>\n }\n @if (IsLoadingScopes) {\n <mj-loading text=\"Loading permissions...\"></mj-loading>\n }\n @if (!IsLoadingScopes) {\n <div class=\"scope-categories\">\n @for (category of ScopeCategories; track category) {\n <div class=\"scope-category\">\n <div class=\"category-header\" (click)=\"toggleCategory(category)\">\n <div class=\"category-left\">\n <i [class]=\"category.icon\" [style.color]=\"category.color\"></i>\n <span class=\"category-name\">{{category.name}}</span>\n <span class=\"category-count\">\n {{getSelectedCount(category)}}/{{category.scopes.length}}\n </span>\n </div>\n <div class=\"category-right\">\n @if (APIKey.Status === 'Active') {\n <label class=\"category-all-toggle\"\n (click)=\"$event.stopPropagation()\"\n >\n <input type=\"checkbox\" kendoCheckBox\n [checked]=\"category.allSelected\"\n (change)=\"toggleCategoryAll(category)\" />\n <span>All</span>\n </label>\n }\n <i class=\"fa-solid expand-icon\" [class.fa-chevron-down]=\"!category.expanded\"\n [class.fa-chevron-up]=\"category.expanded\"></i>\n </div>\n </div>\n @if (category.expanded) {\n <div class=\"category-scopes\">\n @for (item of category.scopes; track item) {\n <div class=\"scope-item\">\n <label class=\"scope-label\">\n <input type=\"checkbox\" kendoCheckBox\n [(ngModel)]=\"item.selected\"\n [disabled]=\"APIKey.Status === 'Revoked'\"\n (change)=\"onScopeChange()\" />\n <div class=\"scope-info\">\n <span class=\"scope-name\">{{item.scope.Name}}</span>\n @if (item.scope.Description) {\n <span class=\"scope-desc\">\n {{item.scope.Description}}\n </span>\n }\n </div>\n </label>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n <!-- Usage Tab -->\n @if (ActiveTab === 'usage') {\n <div class=\"tab-panel usage-panel\">\n @if (IsLoadingLogs) {\n <mj-loading text=\"Loading usage logs...\"></mj-loading>\n }\n @if (!IsLoadingLogs) {\n <div class=\"usage-content\">\n <div class=\"usage-stats\">\n <div class=\"stat-card\">\n <i class=\"fa-solid fa-chart-line\"></i>\n <div class=\"stat-value\">{{UsageLogs.length}}</div>\n <div class=\"stat-label\">Total Requests</div>\n </div>\n <div class=\"stat-card\">\n <i class=\"fa-solid fa-clock\"></i>\n <div class=\"stat-value\">\n {{UsageLogs.length > 0 ? formatRelativeTime(UsageLogs[0].timestamp) : 'Never'}}\n </div>\n <div class=\"stat-label\">Last Used</div>\n </div>\n </div>\n @if (UsageLogs.length > 0) {\n <div class=\"usage-logs\">\n <div class=\"log-header\">\n <span class=\"col-time\">Time</span>\n <span class=\"col-endpoint\">Endpoint</span>\n <span class=\"col-status\">Status</span>\n <span class=\"col-duration\">Duration</span>\n </div>\n @for (log of UsageLogs; track log) {\n <div class=\"log-item\">\n <span class=\"col-time\">{{formatRelativeTime(log.timestamp)}}</span>\n <span class=\"col-endpoint\">\n <span class=\"method-badge\">{{log.method}}</span>\n {{log.endpoint}}\n </span>\n <span class=\"col-status\" [ngClass]=\"getStatusClass(log.statusCode)\">\n {{log.statusCode}}\n </span>\n <span class=\"col-duration\">{{log.responseTime}}ms</span>\n </div>\n }\n </div>\n }\n @if (UsageLogs.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-chart-area\"></i>\n <span>No usage logs yet</span>\n <p>Usage will be recorded when this API key is used for authentication</p>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n <!-- Footer -->\n <div class=\"slideout-footer\">\n <button kendoButton (click)=\"close()\">Close</button>\n </div>\n }\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"api-key-edit-panel.component.js","sourceRoot":"","sources":["../../src/APIKeys/api-key-edit-panel.component.ts","../../src/APIKeys/api-key-edit-panel.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,EAAa,MAAM,EAAiB,MAAM,eAAe,CAAC;AAC/G,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,EAAuB,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AACpG,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;;;;;;;;;;ICFvF,8BAAiD;IAAlB,yLAAS,cAAO,KAAC;IAAC,iBAAM;;;IAqBrD,gCAAuD;;;IAMrD,+BAA6B;IAC3B,wBAAwC;IACxC,YACF;IAAA,iBAAM;;;IADJ,eACF;IADE,sDACF;;;IAGA,+BAA2B;IACzB,wBAA8C;IAC9C,YACF;IAAA,iBAAM;;;IADJ,eACF;IADE,oDACF;;;IAcI,gCAAgC;IAAA,iBAAC;IAAA,iBAAO;;;;IA8ClC,kCACyB;IAAvB,4NAAS,mBAAY,KAAC;IACtB,wBAAoF;IACpF,YACF;IAAA,iBAAS;;;IAFa,cAA8B;IAAC,AAA/B,8CAA8B,8BAA6B;IAC/E,cACF;IADE,qEACF;;;;IA0BE,kCACiC;IAA/B,mPAAyB,IAAI,KAAC;IAC9B,uBAAiC;IACjC,+BACF;IAAA,iBAAS;;;IAUP,iCAAyD;;IAA7C,gCAAkB;;;IAG9B,4BAAM;IACJ,wBAAgC;IAChC,8BACF;IAAA,iBAAO;;;;IAVX,AADF,+BAA0B,iBAGE;IAAxB,4NAAS,oBAAa,KAAC;IACvB,+IAAgB;IAGhB,qIAAiB;IAOrB,AADE,iBAAS,EACL;;;IAbgB,cAAwB;IAC1C,AADkB,sCAAwB,6BACrB;IAErB,cAEC;IAFD,0CAEC;IACD,cAKC;IALD,2CAKC;;;;IAWD,AADF,+BAA4B,cACD;IACvB,wBAAgD;IAE9C,AADF,2BAAK,aACK;IAAA,mCAAmB;IAAA,iBAAS;IACpC,yBAAG;IAAA,mGAAmF;IAE1F,AADE,AADwF,iBAAI,EACtF,EACF;IACN,kCAAmD;IAAxB,0OAAS,oBAAa,KAAC;IAChD,wBAA+B;IAC/B,6BACF;IACF,AADE,iBAAS,EACL;;;IAsBE,iCAAyD;;IAA7C,gCAAkB;;;IAG9B,4BAAM;IACJ,wBAA+B;IAC/B,4BACF;IAAA,iBAAO;;;;IAxBb,AADF,+BAA4B,cACG;IAC3B,wBAA4C;IAE1C,AADF,2BAAK,aACK;IAAA,wCAAwB;IAAA,iBAAS;IACzC,yBAAG;IAAA,uHAAuG;IAE9G,AADE,AAD4G,iBAAI,EAC1G,EACF;IAEJ,AADF,+BAA2B,YAClB;IAAA,sBAAK;IAAA,6BAAM;IAAA,uBAAM;IAAA,iBAAO;IAAC,6BAAW;IAAA,iBAAQ;IACnD,kCACyB;IADL,iXAA+B;IAErD,AAFE,iBACyB,EACrB;IAEJ,AADF,gCAA6B,kBACkB;IAAzB,2OAAS,qBAAc,KAAC;IAAC,uBAAM;IAAA,iBAAS;IAC5D,mCAE4B;IAA1B,2OAAS,sBAAe,KAAC;IACzB,+JAAkB;IAGlB,qJAAmB;IAQzB,AADE,AADE,iBAAS,EACL,EACF;;;IAnBkB,gBAA+B;IAA/B,wDAA+B;IAMjD,eAAyD;IAAzD,qFAAyD;IAEzD,cAEC;IAFD,6CAEC;IACD,cAKC;IALD,8CAKC;;;IA3CT,AADF,+BAAyB,SACnB;IAAA,2BAAW;IAAA,iBAAK;IACpB,yIAA0B;IAe1B,yIAAyB;IAgC3B,iBAAM;;;IA/CJ,eAcC;IAdD,oDAcC;IACD,cA+BC;IA/BD,mDA+BC;;;IAKH,+BAA4B;IAC1B,wBAA+B;IAE7B,AADF,2BAAK,aACK;IAAA,6CAA6B;IAAA,iBAAS;IAC9C,yBAAG;IAAA,+GAA+F;IAEtG,AADE,AADoG,iBAAI,EAClG,EACF;;;;IAnJF,AADF,AADF,AADF,AADF,+BAAuB,cACM,cACA,cACD,eACK;IAAA,wBAAQ;IAAA,iBAAO;IACxC,gCAAyB;IAAA,YAAe;IAE5C,AADE,AAD0C,iBAAO,EAC3C,EACF;IAGF,AADF,AADF,+BAAuB,cACE,gBACI;IAAA,wBAAO;IAAA,iBAAO;IACvC,iCAAyB;IAAA,aAAqC;IAChE,AADgE,iBAAO,EACjE;IAEJ,AADF,gCAAuB,gBACI;IAAA,2BAAU;IAAA,iBAAO;IAC1C,iCAAyB;IAAA,aAAwB;IACnD,AADmD,iBAAO,EACpD;IAEJ,AADF,gCAAuB,gBACI;IAAA,sBAAK;IAAA,iBAAO;IACrC,iCAAyB;IAAA,aAAe;IAC1C,AAD0C,iBAAO,EAC3C;IAEJ,AADF,gCAAuB,gBACI;IAAA,0BAAS;IAAA,iBAAO;IACzC,iCAAiE;IAC/D,aACF;IAGN,AADE,AADE,AADE,iBAAO,EACH,EACF,EACF;IAIF,AADF,AADF,gCAA0B,eACI,UACtB;IAAA,kCAAiB;IAAA,iBAAK;IAC1B,8HAAkC;IAOpC,iBAAM;IAEJ,AADF,gCAAwB,aACf;IAAA,sBAAK;IAAA,iBAAQ;IACpB,kCAEuB;IAFH,oUAAuB;IAG7C,AAHE,iBAEuB,EACnB;IAEJ,AADF,gCAAwB,aACf;IAAA,4BAAW;IAAA,iBAAQ;IAC1B,qCAGsB;IAHE,mVAA6B;IAIvD,AADwB,iBAAW,EAC7B;IAEJ,AADF,gCAAwB,aACf;IAAA,2BAAU;IAAA,iBAAQ;IAEvB,AADF,gCAA8B,4BAKE;IAJZ,uVAA2B;IAK7C,iBAAmB;IACnB,8HAAkC;IAQtC,AADE,iBAAM,EACF;IACN,2HAAiB;IAiBnB,iBAAM;IAEN,2HAAkC;IAqDlC,2HAAmC;IASrC,iBAAM;;;IApJ2B,eAAe;IAAf,wCAAe;IAMf,eAAqC;IAArC,qEAAqC;IAIrC,eAAwB;IAAxB,iDAAwB;IAIxB,eAAe;IAAf,wCAAe;IAIf,eAAuC;IAAvC,uDAAuC;IAC9D,cACF;IADE,iHACF;IAQF,eAMC;IAND,6DAMC;IAImB,eAAuB;IAAvB,gDAAuB;IACzC,4CAAuB;IAKD,eAA6B;IAA7B,sDAA6B;IAEnD,AADA,4CAAuB,WACb;IAMQ,eAA2B;IAA3B,oDAA2B;IAE3C,AADA,4CAAuB,4BACH;IAItB,cAMC;IAND,oEAMC;IAGL,cAgBC;IAhBD,4CAgBC;IAGH,cAmDC;IAnDD,6DAmDC;IAED,cAQC;IARD,8DAQC;;;IAeO,iCAAyD;;IAA7C,gCAAkB;;;IAG9B,4BAAM;IACJ,wBAAgC;IAChC,8BACF;IAAA,iBAAO;;;;IAVX,kCAE+B;IAA7B,4NAAS,yBAAkB,KAAC;IAC5B,8IAAgB;IAGhB,oIAAiB;IAMnB,iBAAS;;;IAXP,AADkB,sCAAwB,6BACrB;IAErB,cAEC;IAFD,0CAEC;IACD,cAKC;IALD,2CAKC;;;IAML,+BAA+B;IAC7B,wBAAgD;IAE9C,AADF,2BAAK,aACK;IAAA,gDAAgC;IAAA,iBAAS;IACjD,yBAAG;IAAA,kKAAkJ;IAEzJ,AADE,AADuJ,iBAAI,EACrJ,EACF;;;IAGN,iCAAuD;;;;IAgB3C,iCAEG;IADD,iNAAS,wBAAwB,KAAC;IAElC,iCAE2C;IAAzC,oSAAU,sCAA2B,KAAC;IAFxC,iBAE2C;IAC3C,4BAAM;IAAA,mBAAG;IACX,AADW,iBAAO,EACV;;;IAHJ,cAAgC;IAAhC,kDAAgC;;;IAqB5B,gCAAyB;IACvB,YACF;IAAA,iBAAO;;;IADL,cACF;IADE,2DACF;;;;IATJ,AADF,AADF,+BAAwB,gBACK,gBAIM;IAF7B,sWAA2B;IAE3B,wPAAU,sBAAe,KAAC;IAH5B,iBAG+B;IAE7B,AADF,+BAAwB,eACG;IAAA,YAAmB;IAAA,iBAAO;IACnD,mKAA8B;IAOpC,AADE,AADE,iBAAM,EACA,EACJ;;;;IAZA,eAA2B;IAA3B,iDAA2B;IAC3B,6DAAwC;IAGf,eAAmB;IAAnB,yCAAmB;IAC5C,cAIC;IAJD,qDAIC;;;IAdX,+BAA6B;IAC3B,+KAiBC;IACH,iBAAM;;;IAlBJ,cAiBC;IAjBD,kCAiBC;;;;IA1CL,AADF,+BAA4B,cACsC;IAAnC,8PAAS,mCAAwB,KAAC;IAC7D,+BAA2B;IACzB,oBAA8D;IAC9D,gCAA4B;IAAA,YAAiB;IAAA,iBAAO;IACpD,gCAA6B;IAC3B,YACF;IACF,AADE,iBAAO,EACH;IACN,+BAA4B;IAC1B,+IAAkC;IAUlC,yBAC8C;IAElD,AADE,iBAAM,EACF;IACN,+IAAyB;IAsB3B,iBAAM;;;;IA3CG,eAAuB;IAAvB,gCAAuB;IAAC,2CAA8B;IAC7B,eAAiB;IAAjB,uCAAiB;IAE3C,eACF;IADE,uGACF;IAGA,eASC;IATD,4DASC;IAC+B,cAA4C;IAC5E,AADgC,yDAA4C,wCACnC;IAG7C,cAqBC;IArBD,iDAqBC;;;IA/CP,+BAA8B;IAC5B,4JAgDC;IACH,iBAAM;;;IAjDJ,cAgDC;IAhDD,qCAgDC;;;IAjFD,AADF,AADF,AADF,+BAAoC,cACP,cACA,eACG;IAAA,YAAgD;IAC5E,AAD4E,iBAAO,EAC7E;IACN,4HAAqD;IAevD,iBAAM;IAEN,yHAAuF;IASvF,gIAAuB;IAGvB,yHAAwB;IAqD1B,iBAAM;;;IApF0B,eAAgD;IAAhD,kFAAgD;IAE5E,cAcC;IAdD,sFAcC;IAGH,cAQC;IARD,+HAQC;IACD,cAEC;IAFD,iDAEC;IACD,cAoDC;IApDD,kDAoDC;;;IAOC,iCAAsD;;;IA4B5C,AADF,gCAAsB,eACG;IAAA,YAAqC;IAAA,iBAAO;IAEjE,AADF,gCAA2B,gBACE;IAAA,YAAc;IAAA,iBAAO;IAChD,YACF;IAAA,iBAAO;IACP,iCAAoE;IAClE,YACF;IAAA,iBAAO;IACP,iCAA2B;IAAA,aAAsB;IACnD,AADmD,iBAAO,EACpD;;;;IATmB,eAAqC;IAArC,kEAAqC;IAE/B,eAAc;IAAd,oCAAc;IACzC,cACF;IADE,iDACF;IACyB,cAA0C;IAA1C,mEAA0C;IACjE,cACF;IADE,mDACF;IAC2B,eAAsB;IAAtB,qDAAsB;;;IAfnD,AADF,AADF,+BAAwB,cACE,eACC;IAAA,oBAAI;IAAA,iBAAO;IAClC,gCAA2B;IAAA,wBAAQ;IAAA,iBAAO;IAC1C,iCAAyB;IAAA,sBAAM;IAAA,iBAAO;IACtC,iCAA2B;IAAA,wBAAQ;IACrC,AADqC,iBAAO,EACtC;IACN,6KAYC;IACH,iBAAM;;;IAbJ,gBAYC;IAZD,+BAYC;;;IAIH,+BAAyB;IACvB,yBAAsC;IACtC,4BAAM;IAAA,iCAAiB;IAAA,iBAAO;IAC9B,yBAAG;IAAA,mFAAmE;IACxE,AADwE,iBAAI,EACtE;;;IAzCN,AADF,AADF,+BAA2B,cACA,cACA;IACrB,wBAAsC;IACtC,+BAAwB;IAAA,YAAoB;IAAA,iBAAM;IAClD,+BAAwB;IAAA,8BAAc;IACxC,AADwC,iBAAM,EACxC;IACN,+BAAuB;IACrB,wBAAiC;IACjC,gCAAwB;IACtB,aACF;IAAA,iBAAM;IACN,gCAAwB;IAAA,0BAAS;IAErC,AADE,AADmC,iBAAM,EACnC,EACF;IACN,0IAA4B;IAuB5B,yIAA8B;IAOhC,iBAAM;;;IAzCwB,eAAoB;IAApB,6CAAoB;IAM1C,eACF;IADE,iIACF;IAIJ,eAsBC;IAtBD,uDAsBC;IACD,cAMC;IAND,yDAMC;;;IAjDP,+BAAmC;IACjC,gIAAqB;IAGrB,0HAAsB;IAgDxB,iBAAM;;;IAnDJ,cAEC;IAFD,+CAEC;IACD,cA+CC;IA/CD,gDA+CC;;;;IA/UP,0GAAsB;IAMtB,0GAAoB;IAQlB,AADF,+BAA2B,iBAES;IAAhC,gNAAqB,SAAS,KAAC;IAC/B,wBAAuC;IACvC,yBACF;IAAA,iBAAS;IACT,kCACiC;IAA/B,gNAAqB,QAAQ,KAAC;IAC9B,wBAAyC;IACzC,6BACA;IAAA,2GAAuB;IAGzB,iBAAS;IACT,mCACgC;IAA9B,iNAAqB,OAAO,KAAC;IAC7B,yBAAsC;IACtC,wBACF;IACF,AADE,iBAAS,EACL;IACN,gCAA8B;IAE5B,8GAA+B;IA6J/B,4GAA8B;IA2F9B,4GAA6B;IAuD/B,iBAAM;IAGJ,AADF,gCAA6B,kBACW;IAAlB,8LAAS,cAAO,KAAC;IAAC,sBAAK;IAC7C,AAD6C,iBAAS,EAChD;;;IAtVN,gDAKC;IACD,cAKC;IALD,8CAKC;IAG8B,eAAwC;IAAxC,wDAAwC;IAKxC,eAAuC;IAAvC,uDAAuC;IAIlE,eAEC;IAFD,iDAEC;IAE0B,cAAsC;IAAtC,sDAAsC;IAQnE,eA2JC;IA3JD,0DA2JC;IAED,cAyFC;IAzFD,yDAyFC;IAED,cAsDC;IAtDD,wDAsDC;;AD7UP;;GAEG;AAOH,MAAM,OAAO,wBAAwB;IACxB,OAAO,GAAG,KAAK,CAAC;IAChB,KAAK,GAAkB,IAAI,CAAC;IAC3B,aAAa,GAAG,IAAI,YAAY,EAAW,CAAC;IAC5C,OAAO,GAAG,IAAI,YAAY,EAAkB,CAAC;IAC7C,OAAO,GAAG,IAAI,YAAY,EAAkB,CAAC;IAC7C,MAAM,GAAG,IAAI,YAAY,EAAQ,CAAC;IAEpC,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;IAE5B,cAAc;IACP,MAAM,GAA0B,IAAI,CAAC;IACrC,SAAS,GAAG,IAAI,CAAC;IACjB,QAAQ,GAAG,KAAK,CAAC;IACjB,UAAU,GAAG,KAAK,CAAC;IAE1B,YAAY;IACL,SAAS,GAAG,KAAK,CAAC;IAClB,SAAS,GAAG,EAAE,CAAC;IACf,eAAe,GAAG,EAAE,CAAC;IACrB,aAAa,GAAgB,IAAI,CAAC;IAEzC,SAAS;IACF,eAAe,GAAoB,EAAE,CAAC;IACtC,eAAe,GAAG,IAAI,CAAC;IACvB,eAAe,GAAG,KAAK,CAAC;IAE/B,aAAa;IACN,SAAS,GAAmB,EAAE,CAAC;IAC/B,aAAa,GAAG,IAAI,CAAC;IAE5B,OAAO;IACA,SAAS,GAAmC,SAAS,CAAC;IAE7D,sBAAsB;IACf,iBAAiB,GAAG,KAAK,CAAC;IAC1B,iBAAiB,GAAG,EAAE,CAAC;IAE9B,WAAW;IACJ,cAAc,GAAG,EAAE,CAAC;IACpB,YAAY,GAAG,EAAE,CAAC;IAEzB,kEAAkE;IACjD,eAAe,GAAG;QAC/B,IAAI,EAAE,sBAAsB;QAC5B,KAAK,EAAE,sBAAsB;KAChC,CAAC;IAEF,KAAK,CAAC,WAAW,CAAC,OAAsB;QACpC,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACjC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACzB,CAAC;IACL,CAAC;IAED;;OAEG;IAEI,WAAW;QACd,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrD,IAAI,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC;IACL,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,OAAO;QACjB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,UAAU,EAAE,CAAC;QAElB,IAAI,CAAC;YACD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,eAAe,CAAiB,cAAc,CAAC,CAAC;YAC1E,IAAI,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAM,CAAC,EAAE,CAAC;gBAC9B,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;gBAClB,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC;gBAC3B,IAAI,CAAC,eAAe,GAAG,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;gBAC7C,IAAI,CAAC,aAAa,GAAG,GAAG,CAAC,SAAS,CAAC;gBAEnC,oCAAoC;gBACpC,MAAM,OAAO,CAAC,GAAG,CAAC;oBACd,IAAI,CAAC,UAAU,EAAE;oBACjB,IAAI,CAAC,aAAa,EAAE;iBACvB,CAAC,CAAC;YACP,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;YAC/C,IAAI,CAAC,YAAY,GAAG,gCAAgC,CAAC;QACzD,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QAC3B,CAAC;IACL,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,UAAU;QACpB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,IAAI,CAAC;YACD,MAAM,EAAE,GAAG,IAAI,OAAO,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,iBAAiB,CAAC,QAAQ,CAAC;YAExC,0DAA0D;YAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC;YAC9B,MAAM,oBAAoB,GAAG,MAAM,EAAE,CAAC,OAAO,CAAsB;gBAC/D,UAAU,EAAE,oBAAoB;gBAChC,WAAW,EAAE,aAAa,IAAI,CAAC,KAAK,GAAG;gBACvC,UAAU,EAAE,eAAe;aAC9B,CAAC,CAAC;YAEH,IAAI,oBAAoB,CAAC,OAAO,EAAE,CAAC;gBAC/B,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAC5B,oBAAoB,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CACrD,CAAC;gBAEF,4CAA4C;gBAC5C,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAA2C,CAAC;gBAC7E,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;oBAC5B,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;wBAClB,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;wBAC9C,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE;4BAClC,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI;4BAChD,KAAK,EAAE,QAAQ,CAAC,KAAK,IAAI,IAAI,CAAC,eAAe,CAAC,KAAK;yBACtD,CAAC,CAAC;oBACP,CAAC;gBACL,CAAC;gBAED,MAAM,WAAW,GAAG,IAAI,GAAG,EAAuB,CAAC;gBAEnD,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;oBAC5B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,OAAO,CAAC;oBAC3C,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;wBAC7B,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;oBAClC,CAAC;oBACD,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;oBAClD,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC,IAAI,CAAC;wBAC5B,KAAK;wBACL,QAAQ,EAAE,UAAU;wBACpB,kBAAkB,EAAE,UAAU;qBACjC,CAAC,CAAC;gBACP,CAAC;gBAED,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE;oBAC5E,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC;oBACnE,OAAO;wBACH,IAAI;wBACJ,IAAI,EAAE,MAAM,CAAC,IAAI;wBACjB,KAAK,EAAE,MAAM,CAAC,KAAK;wBACnB,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wBACvE,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;wBACtC,WAAW,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;qBAClE,CAAC;gBACN,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACpD,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;QAClD,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QACjC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,aAAa;QACvB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC;YACD,MAAM,EAAE,GAAG,IAAI,OAAO,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAyB;gBACpD,UAAU,EAAE,wBAAwB;gBACpC,WAAW,EAAE,aAAa,IAAI,CAAC,KAAK,GAAG;gBACvC,OAAO,EAAE,qBAAqB;gBAC9B,OAAO,EAAE,GAAG;gBACZ,UAAU,EAAE,eAAe;aAC9B,CAAC,CAAC;YAEH,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACjB,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBACxC,SAAS,EAAE,GAAG,CAAC,cAAc;oBAC7B,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,UAAU;oBACpC,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,KAAK;oBAC3B,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,GAAG;oBACjC,YAAY,EAAE,GAAG,CAAC,cAAc,IAAI,CAAC;oBACrC,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,SAAS;iBACxC,CAAC,CAAC,CAAC;YACR,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;QACtD,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC/B,CAAC;IACL,CAAC;IAED;;OAEG;IACK,UAAU;QACd,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;QAC/B,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC/B,CAAC;IAED;;OAEG;IACI,UAAU;QACb,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,cAAc;YACd,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,MAAO,CAAC,KAAK,CAAC;YACpC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,MAAO,CAAC,WAAW,IAAI,EAAE,CAAC;YACtD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,MAAO,CAAC,SAAS,CAAC;QAChD,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;IACrC,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,WAAW;QACpB,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QAEzB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QAEvB,IAAI,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;YAC1C,IAAI,CAAC,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;YAC9D,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC;YAE3C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACxC,IAAI,MAAM,EAAE,CAAC;gBACT,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;gBACvB,IAAI,CAAC,cAAc,GAAG,8BAA8B,CAAC;gBACrD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAC/B,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;YACrD,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,YAAY,GAAG,wBAAwB,CAAC;YACjD,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;YAC1C,IAAI,CAAC,YAAY,GAAG,gCAAgC,CAAC;QACzD,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QAC1B,CAAC;IACL,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,gBAAgB;QACzB,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QAEzB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QAEvB,IAAI,CAAC;YACD,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAElE,gCAAgC;YAChC,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;YACzE,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,kBAAkB,CAAC,CAAC;YAE5E,4BAA4B;YAC5B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACvB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,eAAe,CAAsB,oBAAoB,CAAC,CAAC;gBAC1F,QAAQ,CAAC,SAAS,EAAE,CAAC;gBACrB,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBACnC,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACtB,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;YACnC,CAAC;YAED,2BAA2B;YAC3B,MAAM,EAAE,GAAG,IAAI,OAAO,EAAE,CAAC;YACzB,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;gBAC1B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAsB;oBACjD,UAAU,EAAE,oBAAoB;oBAChC,WAAW,EAAE,aAAa,IAAI,CAAC,MAAM,CAAC,EAAE,kBAAkB,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG;oBAC1E,UAAU,EAAE,eAAe;iBAC9B,CAAC,CAAC;gBACH,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC9C,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;gBACrC,CAAC;gBACD,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;YACpC,CAAC;YAED,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;YAC7B,IAAI,CAAC,cAAc,GAAG,kCAAkC,CAAC;YACzD,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;QACrD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;YAC7C,IAAI,CAAC,YAAY,GAAG,8BAA8B,CAAC;QACvD,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QAC1B,CAAC;IACL,CAAC;IAED;;OAEG;IACI,aAAa;QAChB,6CAA6C;QAC7C,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YAC1C,QAAQ,CAAC,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAChG,CAAC;QAED,wBAAwB;QACxB,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAClE,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,kBAAkB,CAAC,CAAC;IACpF,CAAC;IAED;;OAEG;IACI,cAAc,CAAC,QAAuB;QACzC,QAAQ,CAAC,QAAQ,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAC3C,CAAC;IAED;;OAEG;IACI,iBAAiB,CAAC,QAAuB;QAC5C,kDAAkD;QAClD,MAAM,QAAQ,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC;QACvC,QAAQ,CAAC,WAAW,GAAG,QAAQ,CAAC;QAEhC,kCAAkC;QAClC,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;YACjC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC7B,CAAC;QAED,yBAAyB;QACzB,IAAI,CAAC,aAAa,EAAE,CAAC;IACzB,CAAC;IAED;;OAEG;IACI,WAAW;QACd,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;IAChC,CAAC;IAED;;OAEG;IACI,YAAY;QACf,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;QAC/B,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;IAChC,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,aAAa;QACtB,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,iBAAiB,KAAK,QAAQ;YAAE,OAAO;QAEhE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QAEvB,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAA+B,CAAC;YAC1D,MAAM,gBAAgB,GAAG,IAAI,uBAAuB,CAAC,QAAQ,CAAC,CAAC;YAE/D,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAEnE,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACjB,2CAA2C;gBAC3C,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC;gBAC/B,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;gBAC/B,IAAI,CAAC,cAAc,GAAG,0BAA0B,CAAC;gBACjD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACnC,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,KAAK,IAAI,sBAAsB,CAAC;YAC/D,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;YAC5C,IAAI,CAAC,YAAY,GAAG,kCAAkC,CAAC;QAC3D,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QAC5B,CAAC;IACL,CAAC;IAED;;OAEG;IACI,UAAU,CAAC,IAAiB;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO,OAAO,CAAC;QAC1B,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,kBAAkB,CAAC,OAAO,EAAE;YAC9C,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,MAAM;YACb,GAAG,EAAE,SAAS;YACd,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,SAAS;SACpB,CAAC,CAAC;IACP,CAAC;IAED;;OAEG;IACI,kBAAkB,CAAC,IAAU;QAChC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QACtD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC,CAAC;QAEzC,IAAI,OAAO,GAAG,CAAC;YAAE,OAAO,UAAU,CAAC;QACnC,IAAI,OAAO,GAAG,EAAE;YAAE,OAAO,GAAG,OAAO,OAAO,CAAC;QAC3C,IAAI,KAAK,GAAG,EAAE;YAAE,OAAO,GAAG,KAAK,OAAO,CAAC;QACvC,IAAI,IAAI,GAAG,CAAC;YAAE,OAAO,GAAG,IAAI,OAAO,CAAC;QAEpC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,kBAAkB,EAAE,CAAC;IAC/C,CAAC;IAED;;OAEG;IACI,cAAc,CAAC,UAAkB;QACpC,IAAI,UAAU,IAAI,GAAG,IAAI,UAAU,GAAG,GAAG;YAAE,OAAO,gBAAgB,CAAC;QACnE,IAAI,UAAU,IAAI,GAAG,IAAI,UAAU,GAAG,GAAG;YAAE,OAAO,gBAAgB,CAAC;QACnE,IAAI,UAAU,IAAI,GAAG;YAAE,OAAO,cAAc,CAAC;QAC7C,OAAO,EAAE,CAAC;IACd,CAAC;IAED;;OAEG;IACI,qBAAqB;QACxB,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAC5C,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED;;OAEG;IACI,gBAAgB,CAAC,QAAuB;QAC3C,OAAO,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;IAC1D,CAAC;IAED;;OAEG;IACI,UAAU;QACb,MAAM,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC;QAC5B,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QACzC,OAAO,QAAQ,CAAC;IACpB,CAAC;IAED;;OAEG;IACI,KAAK;QACR,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;kHA5cQ,wBAAwB;6DAAxB,wBAAwB;YAAxB,+GAAA,iBAAa,0BAAW;;YCxCrC,0FAAe;YAQX,AADF,AAFF,8BAAmD,aAEpB,aACC;YAC1B,uBAA+B;YAC/B,4BAAM;YAAA,+BAAe;YAAA,iBAAO;YAC5B,+BACiD;YAC/C,YACF;YACF,AADE,iBAAO,EACH;YACN,iCAAqE;YAAtC,qGAAS,WAAO,IAAC;YAC9C,wBAAiC;YAErC,AADE,iBAAS,EACL;YAEN,mGAAiB;YAIjB,oFAA4B;YA0V9B,iBAAM;;YAnXN,sCAEC;YAG2B,cAAsB;YAAtB,mCAAsB;YAMnB,eAA4C;YACnE,AADuB,sFAA4C,0EACrB;YAC9C,cACF;YADE,8EACF;YAOJ,eAEC;YAFD,yCAEC;YAED,cAyVC;YAzVD,wDAyVC;;;iFD1UU,wBAAwB;cANpC,SAAS;6BACI,KAAK,YACL,uBAAuB;;kBAKhC,KAAK;;kBACL,KAAK;;kBACL,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBAmDN,YAAY;mBAAC,yBAAyB;;kFAzD9B,wBAAwB","sourcesContent":["import { Component, EventEmitter, HostListener, Input, OnChanges, Output, SimpleChanges } from '@angular/core';\nimport { Metadata, RunView } from '@memberjunction/core';\nimport { MJAPIKeyEntity, MJAPIScopeEntity, MJAPIKeyScopeEntity, MJAPIKeyUsageLogEntity } from '@memberjunction/core-entities';\nimport { GraphQLDataProvider, GraphQLEncryptionClient } from '@memberjunction/graphql-dataprovider';\nimport { APIKeysEngineBase, parseAPIScopeUIConfig } from '@memberjunction/api-keys-base';\n/** Scope with selection state */\ninterface ScopeItem {\n scope: MJAPIScopeEntity;\n selected: boolean;\n originallySelected: boolean;\n}\n\n/** Grouped scopes by category */\ninterface ScopeCategory {\n name: string;\n icon: string;\n color: string;\n scopes: ScopeItem[];\n expanded: boolean;\n allSelected: boolean;\n}\n\n/** Usage log display item */\ninterface UsageLogItem {\n timestamp: Date;\n endpoint: string;\n method: string;\n statusCode: number;\n responseTime: number;\n ipAddress: string;\n}\n\n/**\n * Panel for viewing and editing existing API keys\n */\n@Component({\n standalone: false,\n selector: 'mj-api-key-edit-panel',\n templateUrl: './api-key-edit-panel.component.html',\n styleUrls: ['./api-key-edit-panel.component.css']\n})\nexport class APIKeyEditPanelComponent implements OnChanges {\n @Input() Visible = false;\n @Input() KeyId: string | null = null;\n @Output() VisibleChange = new EventEmitter<boolean>();\n @Output() Updated = new EventEmitter<MJAPIKeyEntity>();\n @Output() Revoked = new EventEmitter<MJAPIKeyEntity>();\n @Output() Closed = new EventEmitter<void>();\n\n private md = new Metadata();\n\n // Current key\n public APIKey: MJAPIKeyEntity | null = null;\n public IsLoading = true;\n public IsSaving = false;\n public IsRevoking = false;\n\n // Edit mode\n public IsEditing = false;\n public EditLabel = '';\n public EditDescription = '';\n public EditExpiresAt: Date | null = null;\n\n // Scopes\n public ScopeCategories: ScopeCategory[] = [];\n public IsLoadingScopes = true;\n public HasScopeChanges = false;\n\n // Usage logs\n public UsageLogs: UsageLogItem[] = [];\n public IsLoadingLogs = true;\n\n // Tabs\n public ActiveTab: 'details' | 'scopes' | 'usage' = 'details';\n\n // Revoke confirmation\n public ShowRevokeConfirm = false;\n public RevokeConfirmText = '';\n\n // Messages\n public SuccessMessage = '';\n public ErrorMessage = '';\n\n // Default UI config for categories without explicit configuration\n private readonly defaultUIConfig = {\n icon: 'fa-solid fa-ellipsis',\n color: 'var(--mj-text-muted)'\n };\n\n async ngOnChanges(changes: SimpleChanges): Promise<void> {\n if (changes['KeyId'] && this.KeyId) {\n await this.loadKey();\n }\n }\n\n /**\n * Handle escape key to close panel\n */\n @HostListener('document:keydown.escape')\n public onEscapeKey(): void {\n if (this.Visible && !this.IsSaving && !this.IsRevoking) {\n this.close();\n }\n }\n\n /**\n * Load the API key and related data\n */\n private async loadKey(): Promise<void> {\n this.IsLoading = true;\n this.resetState();\n\n try {\n const key = await this.md.GetEntityObject<MJAPIKeyEntity>('MJ: API Keys');\n if (await key.Load(this.KeyId!)) {\n this.APIKey = key;\n this.EditLabel = key.Label;\n this.EditDescription = key.Description || '';\n this.EditExpiresAt = key.ExpiresAt;\n\n // Load scopes and usage in parallel\n await Promise.all([\n this.loadScopes(),\n this.loadUsageLogs()\n ]);\n }\n } catch (error) {\n console.error('Error loading API key:', error);\n this.ErrorMessage = 'Failed to load API key details';\n } finally {\n this.IsLoading = false;\n }\n }\n\n /**\n * Load all scopes and mark assigned ones\n */\n private async loadScopes(): Promise<void> {\n this.IsLoadingScopes = true;\n try {\n const rv = new RunView();\n const base = APIKeysEngineBase.Instance;\n\n // Get all scopes from cache, load assigned scopes from DB\n const allScopes = base.Scopes;\n const assignedScopesResult = await rv.RunView<MJAPIKeyScopeEntity>({\n EntityName: 'MJ: API Key Scopes',\n ExtraFilter: `APIKeyID='${this.KeyId}'`,\n ResultType: 'entity_object'\n });\n\n if (assignedScopesResult.Success) {\n const assignedScopeIds = new Set(\n assignedScopesResult.Results.map(ks => ks.ScopeID)\n );\n\n // Build category UI config from root scopes\n const categoryUIConfigs = new Map<string, { icon: string; color: string }>();\n for (const scope of allScopes) {\n if (!scope.ParentID) {\n const uiConfig = parseAPIScopeUIConfig(scope);\n categoryUIConfigs.set(scope.Category, {\n icon: uiConfig.icon || this.defaultUIConfig.icon,\n color: uiConfig.color || this.defaultUIConfig.color\n });\n }\n }\n\n const categoryMap = new Map<string, ScopeItem[]>();\n\n for (const scope of allScopes) {\n const category = scope.Category || 'Other';\n if (!categoryMap.has(category)) {\n categoryMap.set(category, []);\n }\n const isSelected = assignedScopeIds.has(scope.ID);\n categoryMap.get(category)!.push({\n scope,\n selected: isSelected,\n originallySelected: isSelected\n });\n }\n\n this.ScopeCategories = Array.from(categoryMap.entries()).map(([name, scopes]) => {\n const config = categoryUIConfigs.get(name) || this.defaultUIConfig;\n return {\n name,\n icon: config.icon,\n color: config.color,\n scopes: scopes.sort((a, b) => a.scope.Name.localeCompare(b.scope.Name)),\n expanded: scopes.some(s => s.selected),\n allSelected: scopes.length > 0 && scopes.every(s => s.selected)\n };\n }).sort((a, b) => a.name.localeCompare(b.name));\n }\n } catch (error) {\n console.error('Error loading scopes:', error);\n } finally {\n this.IsLoadingScopes = false;\n }\n }\n\n /**\n * Load usage logs for this key\n */\n private async loadUsageLogs(): Promise<void> {\n this.IsLoadingLogs = true;\n try {\n const rv = new RunView();\n const result = await rv.RunView<MJAPIKeyUsageLogEntity>({\n EntityName: 'MJ: API Key Usage Logs',\n ExtraFilter: `APIKeyID='${this.KeyId}'`,\n OrderBy: '__mj_CreatedAt DESC',\n MaxRows: 100,\n ResultType: 'entity_object'\n });\n\n if (result.Success) {\n this.UsageLogs = result.Results.map(log => ({\n timestamp: log.__mj_CreatedAt,\n endpoint: log.Endpoint || '/unknown',\n method: log.Method || 'GET',\n statusCode: log.StatusCode || 200,\n responseTime: log.ResponseTimeMs || 0,\n ipAddress: log.IPAddress || 'Unknown'\n }));\n }\n } catch (error) {\n console.error('Error loading usage logs:', error);\n } finally {\n this.IsLoadingLogs = false;\n }\n }\n\n /**\n * Reset component state\n */\n private resetState(): void {\n this.IsEditing = false;\n this.ShowRevokeConfirm = false;\n this.RevokeConfirmText = '';\n this.SuccessMessage = '';\n this.ErrorMessage = '';\n this.HasScopeChanges = false;\n this.ActiveTab = 'details';\n }\n\n /**\n * Toggle edit mode\n */\n public toggleEdit(): void {\n if (this.IsEditing) {\n // Cancel edit\n this.EditLabel = this.APIKey!.Label;\n this.EditDescription = this.APIKey!.Description || '';\n this.EditExpiresAt = this.APIKey!.ExpiresAt;\n }\n this.IsEditing = !this.IsEditing;\n }\n\n /**\n * Save changes to the key\n */\n public async saveChanges(): Promise<void> {\n if (!this.APIKey) return;\n\n this.IsSaving = true;\n this.ErrorMessage = '';\n\n try {\n this.APIKey.Label = this.EditLabel.trim();\n this.APIKey.Description = this.EditDescription.trim() || null;\n this.APIKey.ExpiresAt = this.EditExpiresAt;\n\n const result = await this.APIKey.Save();\n if (result) {\n this.IsEditing = false;\n this.SuccessMessage = 'API key updated successfully';\n this.Updated.emit(this.APIKey);\n setTimeout(() => this.SuccessMessage = '', 3000);\n } else {\n this.ErrorMessage = 'Failed to save changes';\n }\n } catch (error) {\n console.error('Error saving key:', error);\n this.ErrorMessage = 'An error occurred while saving';\n } finally {\n this.IsSaving = false;\n }\n }\n\n /**\n * Save scope changes\n */\n public async saveScopeChanges(): Promise<void> {\n if (!this.APIKey) return;\n\n this.IsSaving = true;\n this.ErrorMessage = '';\n\n try {\n const allScopes = this.ScopeCategories.flatMap(cat => cat.scopes);\n\n // Find scopes to add and remove\n const toAdd = allScopes.filter(s => s.selected && !s.originallySelected);\n const toRemove = allScopes.filter(s => !s.selected && s.originallySelected);\n\n // Add new scope assignments\n for (const item of toAdd) {\n const keyScope = await this.md.GetEntityObject<MJAPIKeyScopeEntity>('MJ: API Key Scopes');\n keyScope.NewRecord();\n keyScope.APIKeyID = this.APIKey.ID;\n keyScope.ScopeID = item.scope.ID;\n await keyScope.Save();\n item.originallySelected = true;\n }\n\n // Remove scope assignments\n const rv = new RunView();\n for (const item of toRemove) {\n const result = await rv.RunView<MJAPIKeyScopeEntity>({\n EntityName: 'MJ: API Key Scopes',\n ExtraFilter: `APIKeyID='${this.APIKey.ID}' AND ScopeID='${item.scope.ID}'`,\n ResultType: 'entity_object'\n });\n if (result.Success && result.Results.length > 0) {\n await result.Results[0].Delete();\n }\n item.originallySelected = false;\n }\n\n this.HasScopeChanges = false;\n this.SuccessMessage = 'Permissions updated successfully';\n setTimeout(() => this.SuccessMessage = '', 3000);\n } catch (error) {\n console.error('Error saving scopes:', error);\n this.ErrorMessage = 'Failed to update permissions';\n } finally {\n this.IsSaving = false;\n }\n }\n\n /**\n * Check for scope changes and update category allSelected states\n */\n public onScopeChange(): void {\n // Update allSelected state for each category\n for (const category of this.ScopeCategories) {\n category.allSelected = category.scopes.length > 0 && category.scopes.every(s => s.selected);\n }\n\n // Track overall changes\n const allScopes = this.ScopeCategories.flatMap(cat => cat.scopes);\n this.HasScopeChanges = allScopes.some(s => s.selected !== s.originallySelected);\n }\n\n /**\n * Toggle category expansion\n */\n public toggleCategory(category: ScopeCategory): void {\n category.expanded = !category.expanded;\n }\n\n /**\n * Toggle all scopes in a category on/off\n */\n public toggleCategoryAll(category: ScopeCategory): void {\n // Toggle to opposite of current allSelected state\n const newState = !category.allSelected;\n category.allSelected = newState;\n\n // Apply to all scopes in category\n for (const item of category.scopes) {\n item.selected = newState;\n }\n\n // Update change tracking\n this.onScopeChange();\n }\n\n /**\n * Start revoke flow\n */\n public startRevoke(): void {\n this.ShowRevokeConfirm = true;\n this.RevokeConfirmText = '';\n }\n\n /**\n * Cancel revoke\n */\n public cancelRevoke(): void {\n this.ShowRevokeConfirm = false;\n this.RevokeConfirmText = '';\n }\n\n /**\n * Confirm and execute revoke using GraphQL client\n */\n public async confirmRevoke(): Promise<void> {\n if (!this.APIKey || this.RevokeConfirmText !== 'REVOKE') return;\n\n this.IsRevoking = true;\n this.ErrorMessage = '';\n\n try {\n const provider = Metadata.Provider as GraphQLDataProvider;\n const encryptionClient = new GraphQLEncryptionClient(provider);\n\n const result = await encryptionClient.RevokeAPIKey(this.APIKey.ID);\n\n if (result.Success) {\n // Update local state to reflect the change\n this.APIKey.Status = 'Revoked';\n this.ShowRevokeConfirm = false;\n this.SuccessMessage = 'API key has been revoked';\n this.Revoked.emit(this.APIKey);\n } else {\n this.ErrorMessage = result.Error || 'Failed to revoke key';\n }\n } catch (error) {\n console.error('Error revoking key:', error);\n this.ErrorMessage = 'An error occurred while revoking';\n } finally {\n this.IsRevoking = false;\n }\n }\n\n /**\n * Format date for display\n */\n public formatDate(date: Date | null): string {\n if (!date) return 'Never';\n return new Date(date).toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n });\n }\n\n /**\n * Format relative time\n */\n public formatRelativeTime(date: Date): string {\n const now = new Date();\n const diff = now.getTime() - new Date(date).getTime();\n const minutes = Math.floor(diff / 60000);\n const hours = Math.floor(diff / 3600000);\n const days = Math.floor(diff / 86400000);\n\n if (minutes < 1) return 'Just now';\n if (minutes < 60) return `${minutes}m ago`;\n if (hours < 24) return `${hours}h ago`;\n if (days < 7) return `${days}d ago`;\n\n return new Date(date).toLocaleDateString();\n }\n\n /**\n * Get status class for HTTP status code\n */\n public getStatusClass(statusCode: number): string {\n if (statusCode >= 200 && statusCode < 300) return 'status-success';\n if (statusCode >= 400 && statusCode < 500) return 'status-warning';\n if (statusCode >= 500) return 'status-error';\n return '';\n }\n\n /**\n * Get assigned scope count\n */\n public getAssignedScopeCount(): number {\n return this.ScopeCategories.reduce((sum, cat) =>\n sum + cat.scopes.filter(s => s.selected).length, 0);\n }\n\n /**\n * Get selected scope count for a category (for template use)\n */\n public getSelectedCount(category: ScopeCategory): number {\n return category.scopes.filter(s => s.selected).length;\n }\n\n /**\n * Get minimum date for expiration (tomorrow)\n */\n public getMinDate(): Date {\n const tomorrow = new Date();\n tomorrow.setDate(tomorrow.getDate() + 1);\n return tomorrow;\n }\n\n /**\n * Close the panel\n */\n public close(): void {\n this.Visible = false;\n this.VisibleChange.emit(false);\n this.Closed.emit();\n }\n}\n","<!-- Slide-out Backdrop -->\n@if (Visible) {\n <div class=\"slideout-backdrop\" (click)=\"close()\"></div>\n}\n\n<!-- Slide-out Panel -->\n<div class=\"slideout-panel\" [class.open]=\"Visible\">\n <!-- Header -->\n <div class=\"slideout-header\">\n <div class=\"slideout-title\">\n <i class=\"fa-solid fa-key\"></i>\n <span>API Key Details</span>\n <span class=\"key-status\" [class.active]=\"APIKey?.Status === 'Active'\"\n [class.revoked]=\"APIKey?.Status === 'Revoked'\">\n {{APIKey?.Status}}\n </span>\n </div>\n <button class=\"slideout-close\" (click)=\"close()\" title=\"Close (Esc)\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n @if (IsLoading) {\n <mj-loading text=\"Loading key details...\"></mj-loading>\n }\n\n @if (!IsLoading && APIKey) {\n <!-- Success/Error Messages -->\n @if (SuccessMessage) {\n <div class=\"message success\">\n <i class=\"fa-solid fa-check-circle\"></i>\n {{SuccessMessage}}\n </div>\n }\n @if (ErrorMessage) {\n <div class=\"message error\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{ErrorMessage}}\n </div>\n }\n <!-- Tabs -->\n <div class=\"slideout-tabs\">\n <button class=\"slideout-tab\" [class.active]=\"ActiveTab === 'details'\"\n (click)=\"ActiveTab = 'details'\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Details\n </button>\n <button class=\"slideout-tab\" [class.active]=\"ActiveTab === 'scopes'\"\n (click)=\"ActiveTab = 'scopes'\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n Permissions\n @if (HasScopeChanges) {\n <span class=\"tab-badge unsaved\">!</span>\n }\n </button>\n <button class=\"slideout-tab\" [class.active]=\"ActiveTab === 'usage'\"\n (click)=\"ActiveTab = 'usage'\">\n <i class=\"fa-solid fa-chart-line\"></i>\n Usage\n </button>\n </div>\n <div class=\"slideout-content\">\n <!-- Details Tab -->\n @if (ActiveTab === 'details') {\n <div class=\"tab-panel\">\n <div class=\"key-info-card\">\n <div class=\"info-header\">\n <div class=\"info-row\">\n <span class=\"info-label\">Key Hash</span>\n <code class=\"hash-value\">{{APIKey.Hash}}</code>\n </div>\n </div>\n <div class=\"info-grid\">\n <div class=\"info-item\">\n <span class=\"info-label\">Created</span>\n <span class=\"info-value\">{{formatDate(APIKey.__mj_CreatedAt)}}</span>\n </div>\n <div class=\"info-item\">\n <span class=\"info-label\">Created By</span>\n <span class=\"info-value\">{{APIKey.CreatedByUser}}</span>\n </div>\n <div class=\"info-item\">\n <span class=\"info-label\">Owner</span>\n <span class=\"info-value\">{{APIKey.User}}</span>\n </div>\n <div class=\"info-item\">\n <span class=\"info-label\">Last Used</span>\n <span class=\"info-value\" [class.never-used]=\"!APIKey.LastUsedAt\">\n {{APIKey.LastUsedAt ? formatDate(APIKey.LastUsedAt) : 'Never'}}\n </span>\n </div>\n </div>\n </div>\n <!-- Editable Fields -->\n <div class=\"edit-section\">\n <div class=\"section-header\">\n <h4>Key Configuration</h4>\n @if (APIKey.Status === 'Active') {\n <button class=\"edit-toggle\"\n (click)=\"toggleEdit()\">\n <i class=\"fa-solid\" [class.fa-pencil]=\"!IsEditing\" [class.fa-times]=\"IsEditing\"></i>\n {{IsEditing ? 'Cancel' : 'Edit'}}\n </button>\n }\n </div>\n <div class=\"form-field\">\n <label>Label</label>\n <input kendoTextBox [(ngModel)]=\"EditLabel\"\n [disabled]=\"!IsEditing\"\n class=\"form-input\" />\n </div>\n <div class=\"form-field\">\n <label>Description</label>\n <textarea kendoTextArea [(ngModel)]=\"EditDescription\"\n [disabled]=\"!IsEditing\"\n [rows]=\"3\"\n class=\"form-textarea\"></textarea>\n </div>\n <div class=\"form-field\">\n <label>Expiration</label>\n <div class=\"expiration-field\">\n <kendo-datepicker [(ngModel)]=\"EditExpiresAt\"\n [disabled]=\"!IsEditing\"\n [min]=\"getMinDate()\"\n format=\"MMM d, yyyy\"\n placeholder=\"Never expires\">\n </kendo-datepicker>\n @if (IsEditing && EditExpiresAt) {\n <button class=\"clear-btn\"\n (click)=\"EditExpiresAt = null\">\n <i class=\"fa-solid fa-times\"></i>\n Never expires\n </button>\n }\n </div>\n </div>\n @if (IsEditing) {\n <div class=\"edit-actions\">\n <button kendoButton [themeColor]=\"'primary'\"\n [disabled]=\"IsSaving\"\n (click)=\"saveChanges()\">\n @if (IsSaving) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n }\n @if (!IsSaving) {\n <span>\n <i class=\"fa-solid fa-save\"></i>\n Save Changes\n </span>\n }\n </button>\n </div>\n }\n </div>\n <!-- Revoke Section -->\n @if (APIKey.Status === 'Active') {\n <div class=\"danger-zone\">\n <h4>Danger Zone</h4>\n @if (!ShowRevokeConfirm) {\n <div class=\"revoke-section\">\n <div class=\"revoke-info\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <div>\n <strong>Revoke this API key</strong>\n <p>Once revoked, this key will immediately stop working. This action cannot be undone.</p>\n </div>\n </div>\n <button class=\"revoke-btn\" (click)=\"startRevoke()\">\n <i class=\"fa-solid fa-ban\"></i>\n Revoke Key\n </button>\n </div>\n }\n @if (ShowRevokeConfirm) {\n <div class=\"revoke-confirm\">\n <div class=\"confirm-warning\">\n <i class=\"fa-solid fa-skull-crossbones\"></i>\n <div>\n <strong>Are you absolutely sure?</strong>\n <p>This will permanently revoke the API key. Any applications using this key will immediately lose access.</p>\n </div>\n </div>\n <div class=\"confirm-input\">\n <label>Type <code>REVOKE</code> to confirm:</label>\n <input kendoTextBox [(ngModel)]=\"RevokeConfirmText\"\n placeholder=\"REVOKE\" />\n </div>\n <div class=\"confirm-actions\">\n <button kendoButton (click)=\"cancelRevoke()\">Cancel</button>\n <button class=\"confirm-revoke-btn\"\n [disabled]=\"RevokeConfirmText !== 'REVOKE' || IsRevoking\"\n (click)=\"confirmRevoke()\">\n @if (IsRevoking) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n }\n @if (!IsRevoking) {\n <span>\n <i class=\"fa-solid fa-ban\"></i>\n Revoke Key\n </span>\n }\n </button>\n </div>\n </div>\n }\n </div>\n }\n <!-- Revoked Notice -->\n @if (APIKey.Status === 'Revoked') {\n <div class=\"revoked-notice\">\n <i class=\"fa-solid fa-ban\"></i>\n <div>\n <strong>This API key has been revoked</strong>\n <p>It can no longer be used for authentication. Consider deleting this record if no longer needed.</p>\n </div>\n </div>\n }\n </div>\n }\n <!-- Scopes Tab -->\n @if (ActiveTab === 'scopes') {\n <div class=\"tab-panel scopes-panel\">\n <div class=\"scopes-header\">\n <div class=\"scopes-info\">\n <span class=\"scope-count\">{{getAssignedScopeCount()}} permissions assigned</span>\n </div>\n @if (HasScopeChanges && APIKey.Status === 'Active') {\n <button kendoButton [themeColor]=\"'primary'\"\n [disabled]=\"IsSaving\"\n (click)=\"saveScopeChanges()\">\n @if (IsSaving) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n }\n @if (!IsSaving) {\n <span>\n <i class=\"fa-solid fa-save\"></i>\n Save Changes\n </span>\n }\n </button>\n }\n </div>\n <!-- No Scopes Warning -->\n @if (!IsLoadingScopes && getAssignedScopeCount() === 0 && APIKey.Status === 'Active') {\n <div class=\"no-scopes-warning\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <div>\n <strong>Warning: No permissions assigned</strong>\n <p>This API key has no assigned scopes and cannot perform any operations. All API requests using this key will be rejected until scopes are assigned.</p>\n </div>\n </div>\n }\n @if (IsLoadingScopes) {\n <mj-loading text=\"Loading permissions...\"></mj-loading>\n }\n @if (!IsLoadingScopes) {\n <div class=\"scope-categories\">\n @for (category of ScopeCategories; track category) {\n <div class=\"scope-category\">\n <div class=\"category-header\" (click)=\"toggleCategory(category)\">\n <div class=\"category-left\">\n <i [class]=\"category.icon\" [style.color]=\"category.color\"></i>\n <span class=\"category-name\">{{category.name}}</span>\n <span class=\"category-count\">\n {{getSelectedCount(category)}}/{{category.scopes.length}}\n </span>\n </div>\n <div class=\"category-right\">\n @if (APIKey.Status === 'Active') {\n <label class=\"category-all-toggle\"\n (click)=\"$event.stopPropagation()\"\n >\n <input type=\"checkbox\" kendoCheckBox\n [checked]=\"category.allSelected\"\n (change)=\"toggleCategoryAll(category)\" />\n <span>All</span>\n </label>\n }\n <i class=\"fa-solid expand-icon\" [class.fa-chevron-down]=\"!category.expanded\"\n [class.fa-chevron-up]=\"category.expanded\"></i>\n </div>\n </div>\n @if (category.expanded) {\n <div class=\"category-scopes\">\n @for (item of category.scopes; track item) {\n <div class=\"scope-item\">\n <label class=\"scope-label\">\n <input type=\"checkbox\" kendoCheckBox\n [(ngModel)]=\"item.selected\"\n [disabled]=\"APIKey.Status === 'Revoked'\"\n (change)=\"onScopeChange()\" />\n <div class=\"scope-info\">\n <span class=\"scope-name\">{{item.scope.Name}}</span>\n @if (item.scope.Description) {\n <span class=\"scope-desc\">\n {{item.scope.Description}}\n </span>\n }\n </div>\n </label>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n <!-- Usage Tab -->\n @if (ActiveTab === 'usage') {\n <div class=\"tab-panel usage-panel\">\n @if (IsLoadingLogs) {\n <mj-loading text=\"Loading usage logs...\"></mj-loading>\n }\n @if (!IsLoadingLogs) {\n <div class=\"usage-content\">\n <div class=\"usage-stats\">\n <div class=\"stat-card\">\n <i class=\"fa-solid fa-chart-line\"></i>\n <div class=\"stat-value\">{{UsageLogs.length}}</div>\n <div class=\"stat-label\">Total Requests</div>\n </div>\n <div class=\"stat-card\">\n <i class=\"fa-solid fa-clock\"></i>\n <div class=\"stat-value\">\n {{UsageLogs.length > 0 ? formatRelativeTime(UsageLogs[0].timestamp) : 'Never'}}\n </div>\n <div class=\"stat-label\">Last Used</div>\n </div>\n </div>\n @if (UsageLogs.length > 0) {\n <div class=\"usage-logs\">\n <div class=\"log-header\">\n <span class=\"col-time\">Time</span>\n <span class=\"col-endpoint\">Endpoint</span>\n <span class=\"col-status\">Status</span>\n <span class=\"col-duration\">Duration</span>\n </div>\n @for (log of UsageLogs; track log) {\n <div class=\"log-item\">\n <span class=\"col-time\">{{formatRelativeTime(log.timestamp)}}</span>\n <span class=\"col-endpoint\">\n <span class=\"method-badge\">{{log.method}}</span>\n {{log.endpoint}}\n </span>\n <span class=\"col-status\" [ngClass]=\"getStatusClass(log.statusCode)\">\n {{log.statusCode}}\n </span>\n <span class=\"col-duration\">{{log.responseTime}}ms</span>\n </div>\n }\n </div>\n }\n @if (UsageLogs.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-chart-area\"></i>\n <span>No usage logs yet</span>\n <p>Usage will be recorded when this API key is used for authentication</p>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n <!-- Footer -->\n <div class=\"slideout-footer\">\n <button kendoButton (click)=\"close()\">Close</button>\n </div>\n }\n</div>\n"]}
|