@memberjunction/ng-dashboards 3.2.0 → 3.4.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 +24 -0
- package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-configuration.component.js +198 -111
- package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
- package/dist/AI/components/models/model-management.component.d.ts +23 -0
- package/dist/AI/components/models/model-management.component.d.ts.map +1 -1
- package/dist/AI/components/models/model-management.component.js +189 -83
- package/dist/AI/components/models/model-management.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-management.component.d.ts +23 -0
- package/dist/AI/components/prompts/prompt-management.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/prompt-management.component.js +135 -30
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/APIKeys/api-applications-panel.component.d.ts +169 -0
- package/dist/APIKeys/api-applications-panel.component.d.ts.map +1 -0
- package/dist/APIKeys/api-applications-panel.component.js +1058 -0
- package/dist/APIKeys/api-applications-panel.component.js.map +1 -0
- package/dist/APIKeys/api-key-create-dialog.component.d.ts +125 -0
- package/dist/APIKeys/api-key-create-dialog.component.d.ts.map +1 -0
- package/dist/APIKeys/api-key-create-dialog.component.js +768 -0
- package/dist/APIKeys/api-key-create-dialog.component.js.map +1 -0
- package/dist/APIKeys/api-key-edit-panel.component.d.ts +149 -0
- package/dist/APIKeys/api-key-edit-panel.component.d.ts.map +1 -0
- package/dist/APIKeys/api-key-edit-panel.component.js +1074 -0
- package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -0
- package/dist/APIKeys/api-key-list.component.d.ts +131 -0
- package/dist/APIKeys/api-key-list.component.d.ts.map +1 -0
- package/dist/APIKeys/api-key-list.component.js +818 -0
- package/dist/APIKeys/api-key-list.component.js.map +1 -0
- package/dist/APIKeys/api-keys-resource.component.d.ts +211 -0
- package/dist/APIKeys/api-keys-resource.component.d.ts.map +1 -0
- package/dist/APIKeys/api-keys-resource.component.js +1150 -0
- package/dist/APIKeys/api-keys-resource.component.js.map +1 -0
- package/dist/APIKeys/api-scopes-panel.component.d.ts +98 -0
- package/dist/APIKeys/api-scopes-panel.component.d.ts.map +1 -0
- package/dist/APIKeys/api-scopes-panel.component.js +652 -0
- package/dist/APIKeys/api-scopes-panel.component.js.map +1 -0
- package/dist/APIKeys/api-usage-panel.component.d.ts +174 -0
- package/dist/APIKeys/api-usage-panel.component.d.ts.map +1 -0
- package/dist/APIKeys/api-usage-panel.component.js +1013 -0
- package/dist/APIKeys/api-usage-panel.component.js.map +1 -0
- package/dist/APIKeys/index.d.ts +7 -0
- package/dist/APIKeys/index.d.ts.map +1 -0
- package/dist/APIKeys/index.js +8 -0
- package/dist/APIKeys/index.js.map +1 -0
- package/dist/Actions/components/explorer/action-breadcrumb.component.d.ts +22 -0
- package/dist/Actions/components/explorer/action-breadcrumb.component.d.ts.map +1 -0
- package/dist/Actions/components/explorer/action-breadcrumb.component.js +139 -0
- package/dist/Actions/components/explorer/action-breadcrumb.component.js.map +1 -0
- package/dist/Actions/components/explorer/action-card.component.d.ts +39 -0
- package/dist/Actions/components/explorer/action-card.component.d.ts.map +1 -0
- package/dist/Actions/components/explorer/action-card.component.js +410 -0
- package/dist/Actions/components/explorer/action-card.component.js.map +1 -0
- package/dist/Actions/components/explorer/action-explorer.component.d.ts +62 -0
- package/dist/Actions/components/explorer/action-explorer.component.d.ts.map +1 -0
- package/dist/Actions/components/explorer/action-explorer.component.js +527 -0
- package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -0
- package/dist/Actions/components/explorer/action-list-item.component.d.ts +24 -0
- package/dist/Actions/components/explorer/action-list-item.component.d.ts.map +1 -0
- package/dist/Actions/components/explorer/action-list-item.component.js +210 -0
- package/dist/Actions/components/explorer/action-list-item.component.js.map +1 -0
- package/dist/Actions/components/explorer/action-toolbar.component.d.ts +63 -0
- package/dist/Actions/components/explorer/action-toolbar.component.d.ts.map +1 -0
- package/dist/Actions/components/explorer/action-toolbar.component.js +483 -0
- package/dist/Actions/components/explorer/action-toolbar.component.js.map +1 -0
- package/dist/Actions/components/explorer/action-tree-panel.component.d.ts +57 -0
- package/dist/Actions/components/explorer/action-tree-panel.component.d.ts.map +1 -0
- package/dist/Actions/components/explorer/action-tree-panel.component.js +454 -0
- package/dist/Actions/components/explorer/action-tree-panel.component.js.map +1 -0
- package/dist/Actions/components/explorer/index.d.ts +10 -0
- package/dist/Actions/components/explorer/index.d.ts.map +1 -0
- package/dist/Actions/components/explorer/index.js +14 -0
- package/dist/Actions/components/explorer/index.js.map +1 -0
- package/dist/Actions/components/explorer/new-action-panel.component.d.ts +49 -0
- package/dist/Actions/components/explorer/new-action-panel.component.d.ts.map +1 -0
- package/dist/Actions/components/explorer/new-action-panel.component.js +359 -0
- package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -0
- package/dist/Actions/components/explorer/new-category-panel.component.d.ts +37 -0
- package/dist/Actions/components/explorer/new-category-panel.component.d.ts.map +1 -0
- package/dist/Actions/components/explorer/new-category-panel.component.js +282 -0
- package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -0
- package/dist/Actions/index.d.ts +3 -0
- package/dist/Actions/index.d.ts.map +1 -1
- package/dist/Actions/index.js +5 -0
- package/dist/Actions/index.js.map +1 -1
- package/dist/Actions/services/action-explorer-state.service.d.ts +104 -0
- package/dist/Actions/services/action-explorer-state.service.d.ts.map +1 -0
- package/dist/Actions/services/action-explorer-state.service.js +352 -0
- package/dist/Actions/services/action-explorer-state.service.js.map +1 -0
- package/dist/Communication/communication-dashboard.component.d.ts +2 -6
- package/dist/Communication/communication-dashboard.component.d.ts.map +1 -1
- package/dist/Communication/communication-dashboard.component.js +142 -93
- package/dist/Communication/communication-dashboard.component.js.map +1 -1
- package/dist/Communication/communication-logs-resource.component.d.ts +10 -4
- package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-logs-resource.component.js +253 -121
- package/dist/Communication/communication-logs-resource.component.js.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.d.ts +38 -3
- package/dist/Communication/communication-monitor-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.js +431 -157
- package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
- package/dist/Communication/communication-providers-resource.component.d.ts +16 -5
- package/dist/Communication/communication-providers-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-providers-resource.component.js +229 -118
- package/dist/Communication/communication-providers-resource.component.js.map +1 -1
- package/dist/Communication/communication-runs-resource.component.d.ts +4 -2
- package/dist/Communication/communication-runs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-runs-resource.component.js +155 -149
- package/dist/Communication/communication-runs-resource.component.js.map +1 -1
- package/dist/Communication/communication-templates-resource.component.d.ts +43 -0
- package/dist/Communication/communication-templates-resource.component.d.ts.map +1 -0
- package/dist/Communication/communication-templates-resource.component.js +371 -0
- package/dist/Communication/communication-templates-resource.component.js.map +1 -0
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts +69 -267
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +698 -1802
- package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts +68 -0
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts.map +1 -0
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +401 -0
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js.map +1 -0
- package/dist/ComponentStudio/components/browser/component-browser.component.d.ts +44 -0
- package/dist/ComponentStudio/components/browser/component-browser.component.d.ts.map +1 -0
- package/dist/ComponentStudio/components/browser/component-browser.component.js +636 -0
- package/dist/ComponentStudio/components/browser/component-browser.component.js.map +1 -0
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.d.ts +35 -0
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.d.ts.map +1 -0
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js +380 -0
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js.map +1 -0
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.d.ts +24 -0
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.d.ts.map +1 -0
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +221 -0
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js.map +1 -0
- package/dist/ComponentStudio/components/editors/requirements-editor.component.d.ts +28 -0
- package/dist/ComponentStudio/components/editors/requirements-editor.component.d.ts.map +1 -0
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js +263 -0
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js.map +1 -0
- package/dist/ComponentStudio/components/editors/spec-editor.component.d.ts +34 -0
- package/dist/ComponentStudio/components/editors/spec-editor.component.d.ts.map +1 -0
- package/dist/ComponentStudio/components/editors/spec-editor.component.js +307 -0
- package/dist/ComponentStudio/components/editors/spec-editor.component.js.map +1 -0
- package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.d.ts +29 -0
- package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.d.ts.map +1 -0
- package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js +159 -0
- package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js.map +1 -0
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.d.ts +20 -0
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.d.ts.map +1 -0
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js +192 -0
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js.map +1 -0
- package/dist/ComponentStudio/components/workspace/component-preview.component.d.ts +57 -0
- package/dist/ComponentStudio/components/workspace/component-preview.component.d.ts.map +1 -0
- package/dist/ComponentStudio/components/workspace/component-preview.component.js +342 -0
- package/dist/ComponentStudio/components/workspace/component-preview.component.js.map +1 -0
- package/dist/ComponentStudio/components/workspace/editor-tabs.component.d.ts +15 -0
- package/dist/ComponentStudio/components/workspace/editor-tabs.component.d.ts.map +1 -0
- package/dist/ComponentStudio/components/workspace/editor-tabs.component.js +144 -0
- package/dist/ComponentStudio/components/workspace/editor-tabs.component.js.map +1 -0
- package/dist/ComponentStudio/services/component-studio-state.service.d.ts +203 -0
- package/dist/ComponentStudio/services/component-studio-state.service.d.ts.map +1 -0
- package/dist/ComponentStudio/services/component-studio-state.service.js +651 -0
- package/dist/ComponentStudio/services/component-studio-state.service.js.map +1 -0
- package/dist/ComponentStudio/services/component-version.service.d.ts +120 -0
- package/dist/ComponentStudio/services/component-version.service.d.ts.map +1 -0
- package/dist/ComponentStudio/services/component-version.service.js +394 -0
- package/dist/ComponentStudio/services/component-version.service.js.map +1 -0
- package/dist/Credentials/components/credentials-categories-resource.component.d.ts +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.js +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.d.ts +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.d.ts +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +4 -2
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts +2 -2
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +3 -3
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +22 -6
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/EntityAdmin/entity-admin-dashboard.component.js +2 -2
- package/dist/MCP/components/mcp-connection-dialog.component.d.ts +72 -0
- package/dist/MCP/components/mcp-connection-dialog.component.d.ts.map +1 -0
- package/dist/MCP/components/mcp-connection-dialog.component.js +529 -0
- package/dist/MCP/components/mcp-connection-dialog.component.js.map +1 -0
- package/dist/MCP/components/mcp-log-detail-panel.component.d.ts +77 -0
- package/dist/MCP/components/mcp-log-detail-panel.component.d.ts.map +1 -0
- package/dist/MCP/components/mcp-log-detail-panel.component.js +535 -0
- package/dist/MCP/components/mcp-log-detail-panel.component.js.map +1 -0
- package/dist/MCP/components/mcp-server-dialog.component.d.ts +77 -0
- package/dist/MCP/components/mcp-server-dialog.component.d.ts.map +1 -0
- package/dist/MCP/components/mcp-server-dialog.component.js +437 -0
- package/dist/MCP/components/mcp-server-dialog.component.js.map +1 -0
- package/dist/MCP/components/mcp-test-tool-dialog.component.d.ts +271 -0
- package/dist/MCP/components/mcp-test-tool-dialog.component.d.ts.map +1 -0
- package/dist/MCP/components/mcp-test-tool-dialog.component.js +1300 -0
- package/dist/MCP/components/mcp-test-tool-dialog.component.js.map +1 -0
- package/dist/MCP/index.d.ts +11 -0
- package/dist/MCP/index.d.ts.map +1 -0
- package/dist/MCP/index.js +15 -0
- package/dist/MCP/index.js.map +1 -0
- package/dist/MCP/mcp-dashboard.component.d.ts +409 -0
- package/dist/MCP/mcp-dashboard.component.d.ts.map +1 -0
- package/dist/MCP/mcp-dashboard.component.js +2486 -0
- package/dist/MCP/mcp-dashboard.component.js.map +1 -0
- package/dist/MCP/mcp-resource.component.d.ts +20 -0
- package/dist/MCP/mcp-resource.component.d.ts.map +1 -0
- package/dist/MCP/mcp-resource.component.js +55 -0
- package/dist/MCP/mcp-resource.component.js.map +1 -0
- package/dist/MCP/mcp.module.d.ts +27 -0
- package/dist/MCP/mcp.module.d.ts.map +1 -0
- package/dist/MCP/mcp.module.js +122 -0
- package/dist/MCP/mcp.module.js.map +1 -0
- package/dist/MCP/services/mcp-tools.service.d.ts +109 -0
- package/dist/MCP/services/mcp-tools.service.d.ts.map +1 -0
- package/dist/MCP/services/mcp-tools.service.js +222 -0
- package/dist/MCP/services/mcp-tools.service.js.map +1 -0
- package/dist/Scheduling/components/index.d.ts +5 -8
- package/dist/Scheduling/components/index.d.ts.map +1 -1
- package/dist/Scheduling/components/index.js +6 -9
- package/dist/Scheduling/components/index.js.map +1 -1
- package/dist/Scheduling/components/job-slideout.component.d.ts +45 -0
- package/dist/Scheduling/components/job-slideout.component.d.ts.map +1 -0
- package/dist/Scheduling/components/job-slideout.component.js +458 -0
- package/dist/Scheduling/components/job-slideout.component.js.map +1 -0
- package/dist/Scheduling/components/scheduling-activity-resource.component.d.ts +19 -0
- package/dist/Scheduling/components/scheduling-activity-resource.component.d.ts.map +1 -0
- package/dist/Scheduling/components/scheduling-activity-resource.component.js +51 -0
- package/dist/Scheduling/components/scheduling-activity-resource.component.js.map +1 -0
- package/dist/Scheduling/components/scheduling-activity.component.d.ts +71 -0
- package/dist/Scheduling/components/scheduling-activity.component.d.ts.map +1 -0
- package/dist/Scheduling/components/scheduling-activity.component.js +714 -0
- package/dist/Scheduling/components/scheduling-activity.component.js.map +1 -0
- package/dist/Scheduling/components/scheduling-jobs-resource.component.d.ts +3 -4
- package/dist/Scheduling/components/scheduling-jobs-resource.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs-resource.component.js +3 -7
- package/dist/Scheduling/components/scheduling-jobs-resource.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs.component.d.ts +52 -34
- package/dist/Scheduling/components/scheduling-jobs.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs.component.js +446 -261
- package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-overview-resource.component.d.ts +19 -0
- package/dist/Scheduling/components/scheduling-overview-resource.component.d.ts.map +1 -0
- package/dist/Scheduling/components/scheduling-overview-resource.component.js +51 -0
- package/dist/Scheduling/components/scheduling-overview-resource.component.js.map +1 -0
- package/dist/Scheduling/components/scheduling-overview.component.d.ts +43 -0
- package/dist/Scheduling/components/scheduling-overview.component.d.ts.map +1 -0
- package/dist/Scheduling/components/scheduling-overview.component.js +595 -0
- package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -0
- package/dist/Scheduling/scheduling-dashboard.component.d.ts +22 -32
- package/dist/Scheduling/scheduling-dashboard.component.d.ts.map +1 -1
- package/dist/Scheduling/scheduling-dashboard.component.js +175 -169
- package/dist/Scheduling/scheduling-dashboard.component.js.map +1 -1
- package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts +49 -6
- package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts.map +1 -1
- package/dist/Scheduling/services/scheduling-instrumentation.service.js +218 -149
- package/dist/Scheduling/services/scheduling-instrumentation.service.js.map +1 -1
- package/dist/Testing/components/index.d.ts +7 -8
- package/dist/Testing/components/index.d.ts.map +1 -1
- package/dist/Testing/components/index.js +8 -9
- package/dist/Testing/components/index.js.map +1 -1
- package/dist/Testing/components/testing-analytics-resource.component.d.ts +0 -4
- package/dist/Testing/components/testing-analytics-resource.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-analytics-resource.component.js +1 -7
- package/dist/Testing/components/testing-analytics-resource.component.js.map +1 -1
- package/dist/Testing/components/testing-analytics.component.d.ts +52 -37
- package/dist/Testing/components/testing-analytics.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-analytics.component.js +1023 -569
- package/dist/Testing/components/testing-analytics.component.js.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts +16 -0
- package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts.map +1 -0
- package/dist/Testing/components/testing-dashboard-tab-resource.component.js +47 -0
- package/dist/Testing/components/testing-dashboard-tab-resource.component.js.map +1 -0
- package/dist/Testing/components/testing-dashboard-tab.component.d.ts +57 -0
- package/dist/Testing/components/testing-dashboard-tab.component.d.ts.map +1 -0
- package/dist/Testing/components/testing-dashboard-tab.component.js +649 -0
- package/dist/Testing/components/testing-dashboard-tab.component.js.map +1 -0
- package/dist/{Scheduling/components/scheduling-types-resource.component.d.ts → Testing/components/testing-explorer-resource.component.d.ts} +5 -9
- package/dist/Testing/components/testing-explorer-resource.component.d.ts.map +1 -0
- package/dist/Testing/components/testing-explorer-resource.component.js +47 -0
- package/dist/Testing/components/testing-explorer-resource.component.js.map +1 -0
- package/dist/Testing/components/testing-explorer.component.d.ts +193 -0
- package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -0
- package/dist/Testing/components/testing-explorer.component.js +2212 -0
- package/dist/Testing/components/testing-explorer.component.js.map +1 -0
- package/dist/Testing/components/testing-review-resource.component.d.ts +16 -0
- package/dist/Testing/components/testing-review-resource.component.d.ts.map +1 -0
- package/dist/Testing/components/testing-review-resource.component.js +47 -0
- package/dist/Testing/components/testing-review-resource.component.js.map +1 -0
- package/dist/Testing/components/testing-review.component.d.ts +60 -0
- package/dist/Testing/components/testing-review.component.d.ts.map +1 -0
- package/dist/Testing/components/testing-review.component.js +985 -0
- package/dist/Testing/components/testing-review.component.js.map +1 -0
- package/dist/Testing/components/testing-runs-resource.component.d.ts +16 -0
- package/dist/Testing/components/testing-runs-resource.component.d.ts.map +1 -0
- package/dist/Testing/components/testing-runs-resource.component.js +47 -0
- package/dist/Testing/components/testing-runs-resource.component.js.map +1 -0
- package/dist/Testing/components/testing-runs.component.d.ts +82 -0
- package/dist/Testing/components/testing-runs.component.d.ts.map +1 -0
- package/dist/Testing/components/testing-runs.component.js +1067 -0
- package/dist/Testing/components/testing-runs.component.js.map +1 -0
- package/dist/Testing/testing-dashboard.component.d.ts +12 -15
- package/dist/Testing/testing-dashboard.component.d.ts.map +1 -1
- package/dist/Testing/testing-dashboard.component.js +46 -68
- package/dist/Testing/testing-dashboard.component.js.map +1 -1
- package/dist/module.d.ts +121 -97
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +227 -95
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +12 -3
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +47 -16
- package/dist/public-api.js.map +1 -1
- package/dist/shared/pipes/highlight-search.pipe.d.ts +17 -0
- package/dist/shared/pipes/highlight-search.pipe.d.ts.map +1 -0
- package/dist/shared/pipes/highlight-search.pipe.js +40 -0
- package/dist/shared/pipes/highlight-search.pipe.js.map +1 -0
- package/dist/shared/pipes/index.d.ts +2 -0
- package/dist/shared/pipes/index.d.ts.map +1 -0
- package/dist/shared/pipes/index.js +2 -0
- package/dist/shared/pipes/index.js.map +1 -0
- package/dist/shared/shared-pipes.module.d.ts +11 -0
- package/dist/shared/shared-pipes.module.d.ts.map +1 -0
- package/dist/shared/shared-pipes.module.js +24 -0
- package/dist/shared/shared-pipes.module.js.map +1 -0
- package/package.json +39 -32
- package/dist/Credentials/components/credential-category-edit-panel.component.d.ts +0 -44
- package/dist/Credentials/components/credential-category-edit-panel.component.d.ts.map +0 -1
- package/dist/Credentials/components/credential-category-edit-panel.component.js +0 -456
- package/dist/Credentials/components/credential-category-edit-panel.component.js.map +0 -1
- package/dist/Credentials/components/credential-edit-panel.component.d.ts +0 -70
- package/dist/Credentials/components/credential-edit-panel.component.d.ts.map +0 -1
- package/dist/Credentials/components/credential-edit-panel.component.js +0 -694
- package/dist/Credentials/components/credential-edit-panel.component.js.map +0 -1
- package/dist/Credentials/components/credential-type-edit-panel.component.d.ts +0 -56
- package/dist/Credentials/components/credential-type-edit-panel.component.d.ts.map +0 -1
- package/dist/Credentials/components/credential-type-edit-panel.component.js +0 -563
- package/dist/Credentials/components/credential-type-edit-panel.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-health-resource.component.d.ts +0 -20
- package/dist/Scheduling/components/scheduling-health-resource.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-health-resource.component.js +0 -55
- package/dist/Scheduling/components/scheduling-health-resource.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-health.component.d.ts +0 -30
- package/dist/Scheduling/components/scheduling-health.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-health.component.js +0 -315
- package/dist/Scheduling/components/scheduling-health.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-history-resource.component.d.ts +0 -20
- package/dist/Scheduling/components/scheduling-history-resource.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-history-resource.component.js +0 -55
- package/dist/Scheduling/components/scheduling-history-resource.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-history.component.d.ts +0 -48
- package/dist/Scheduling/components/scheduling-history.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-history.component.js +0 -377
- package/dist/Scheduling/components/scheduling-history.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-monitor-resource.component.d.ts +0 -20
- package/dist/Scheduling/components/scheduling-monitor-resource.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-monitor-resource.component.js +0 -55
- package/dist/Scheduling/components/scheduling-monitor-resource.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-monitoring.component.d.ts +0 -37
- package/dist/Scheduling/components/scheduling-monitoring.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-monitoring.component.js +0 -488
- package/dist/Scheduling/components/scheduling-monitoring.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-types-resource.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-types-resource.component.js +0 -55
- package/dist/Scheduling/components/scheduling-types-resource.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-types.component.d.ts +0 -22
- package/dist/Scheduling/components/scheduling-types.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-types.component.js +0 -165
- package/dist/Scheduling/components/scheduling-types.component.js.map +0 -1
- package/dist/Testing/components/testing-execution-resource.component.d.ts +0 -20
- package/dist/Testing/components/testing-execution-resource.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-execution-resource.component.js +0 -55
- package/dist/Testing/components/testing-execution-resource.component.js.map +0 -1
- package/dist/Testing/components/testing-execution.component.d.ts +0 -71
- package/dist/Testing/components/testing-execution.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-execution.component.js +0 -845
- package/dist/Testing/components/testing-execution.component.js.map +0 -1
- package/dist/Testing/components/testing-feedback-resource.component.d.ts +0 -20
- package/dist/Testing/components/testing-feedback-resource.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-feedback-resource.component.js +0 -55
- package/dist/Testing/components/testing-feedback-resource.component.js.map +0 -1
- package/dist/Testing/components/testing-feedback.component.d.ts +0 -111
- package/dist/Testing/components/testing-feedback.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-feedback.component.js +0 -1486
- package/dist/Testing/components/testing-feedback.component.js.map +0 -1
- package/dist/Testing/components/testing-overview-resource.component.d.ts +0 -20
- package/dist/Testing/components/testing-overview-resource.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-overview-resource.component.js +0 -55
- package/dist/Testing/components/testing-overview-resource.component.js.map +0 -1
- package/dist/Testing/components/testing-overview.component.d.ts +0 -30
- package/dist/Testing/components/testing-overview.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-overview.component.js +0 -361
- package/dist/Testing/components/testing-overview.component.js.map +0 -1
- package/dist/Testing/components/testing-version-comparison.component.d.ts +0 -62
- package/dist/Testing/components/testing-version-comparison.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-version-comparison.component.js +0 -815
- package/dist/Testing/components/testing-version-comparison.component.js.map +0 -1
- package/dist/Testing/components/testing-version-resource.component.d.ts +0 -20
- package/dist/Testing/components/testing-version-resource.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-version-resource.component.js +0 -55
- package/dist/Testing/components/testing-version-resource.component.js.map +0 -1
|
@@ -0,0 +1,1074 @@
|
|
|
1
|
+
import { Component, EventEmitter, HostListener, Input, Output } from '@angular/core';
|
|
2
|
+
import { Metadata, RunView } from '@memberjunction/core';
|
|
3
|
+
import { GraphQLEncryptionClient } from '@memberjunction/graphql-dataprovider';
|
|
4
|
+
import { APIKeysEngineBase, parseAPIScopeUIConfig } from '@memberjunction/api-keys-base';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
import * as i1 from "@angular/common";
|
|
7
|
+
import * as i2 from "@angular/forms";
|
|
8
|
+
import * as i3 from "@progress/kendo-angular-inputs";
|
|
9
|
+
import * as i4 from "@progress/kendo-angular-dateinputs";
|
|
10
|
+
import * as i5 from "@progress/kendo-angular-buttons";
|
|
11
|
+
import * as i6 from "@memberjunction/ng-shared-generic";
|
|
12
|
+
function APIKeyEditPanelComponent_div_0_Template(rf, ctx) { if (rf & 1) {
|
|
13
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
14
|
+
i0.ɵɵelementStart(0, "div", 10);
|
|
15
|
+
i0.ɵɵlistener("click", function APIKeyEditPanelComponent_div_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.close()); });
|
|
16
|
+
i0.ɵɵelementEnd();
|
|
17
|
+
} }
|
|
18
|
+
function APIKeyEditPanelComponent_mj_loading_11_Template(rf, ctx) { if (rf & 1) {
|
|
19
|
+
i0.ɵɵelement(0, "mj-loading", 11);
|
|
20
|
+
} }
|
|
21
|
+
function APIKeyEditPanelComponent_ng_container_12_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
22
|
+
i0.ɵɵelementStart(0, "div", 26);
|
|
23
|
+
i0.ɵɵelement(1, "i", 27);
|
|
24
|
+
i0.ɵɵtext(2);
|
|
25
|
+
i0.ɵɵelementEnd();
|
|
26
|
+
} if (rf & 2) {
|
|
27
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
28
|
+
i0.ɵɵadvance(2);
|
|
29
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r1.SuccessMessage, " ");
|
|
30
|
+
} }
|
|
31
|
+
function APIKeyEditPanelComponent_ng_container_12_div_2_Template(rf, ctx) { if (rf & 1) {
|
|
32
|
+
i0.ɵɵelementStart(0, "div", 28);
|
|
33
|
+
i0.ɵɵelement(1, "i", 29);
|
|
34
|
+
i0.ɵɵtext(2);
|
|
35
|
+
i0.ɵɵelementEnd();
|
|
36
|
+
} if (rf & 2) {
|
|
37
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
38
|
+
i0.ɵɵadvance(2);
|
|
39
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r1.ErrorMessage, " ");
|
|
40
|
+
} }
|
|
41
|
+
function APIKeyEditPanelComponent_ng_container_12_span_10_Template(rf, ctx) { if (rf & 1) {
|
|
42
|
+
i0.ɵɵelementStart(0, "span", 30);
|
|
43
|
+
i0.ɵɵtext(1, "!");
|
|
44
|
+
i0.ɵɵelementEnd();
|
|
45
|
+
} }
|
|
46
|
+
function APIKeyEditPanelComponent_ng_container_12_div_15_button_33_Template(rf, ctx) { if (rf & 1) {
|
|
47
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
48
|
+
i0.ɵɵelementStart(0, "button", 52);
|
|
49
|
+
i0.ɵɵlistener("click", function APIKeyEditPanelComponent_ng_container_12_div_15_button_33_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.toggleEdit()); });
|
|
50
|
+
i0.ɵɵelement(1, "i", 53);
|
|
51
|
+
i0.ɵɵtext(2);
|
|
52
|
+
i0.ɵɵelementEnd();
|
|
53
|
+
} if (rf & 2) {
|
|
54
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
55
|
+
i0.ɵɵadvance();
|
|
56
|
+
i0.ɵɵclassProp("fa-pencil", !ctx_r1.IsEditing)("fa-times", ctx_r1.IsEditing);
|
|
57
|
+
i0.ɵɵadvance();
|
|
58
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r1.IsEditing ? "Cancel" : "Edit", " ");
|
|
59
|
+
} }
|
|
60
|
+
function APIKeyEditPanelComponent_ng_container_12_div_15_button_47_Template(rf, ctx) { if (rf & 1) {
|
|
61
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
62
|
+
i0.ɵɵelementStart(0, "button", 54);
|
|
63
|
+
i0.ɵɵlistener("click", function APIKeyEditPanelComponent_ng_container_12_div_15_button_47_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.EditExpiresAt = null); });
|
|
64
|
+
i0.ɵɵelement(1, "i", 7);
|
|
65
|
+
i0.ɵɵtext(2, " Never expires ");
|
|
66
|
+
i0.ɵɵelementEnd();
|
|
67
|
+
} }
|
|
68
|
+
function APIKeyEditPanelComponent_ng_container_12_div_15_div_48_mj_loading_2_Template(rf, ctx) { if (rf & 1) {
|
|
69
|
+
i0.ɵɵelement(0, "mj-loading", 58);
|
|
70
|
+
} if (rf & 2) {
|
|
71
|
+
i0.ɵɵproperty("showText", false);
|
|
72
|
+
} }
|
|
73
|
+
function APIKeyEditPanelComponent_ng_container_12_div_15_div_48_span_3_Template(rf, ctx) { if (rf & 1) {
|
|
74
|
+
i0.ɵɵelementStart(0, "span");
|
|
75
|
+
i0.ɵɵelement(1, "i", 59);
|
|
76
|
+
i0.ɵɵtext(2, " Save Changes ");
|
|
77
|
+
i0.ɵɵelementEnd();
|
|
78
|
+
} }
|
|
79
|
+
function APIKeyEditPanelComponent_ng_container_12_div_15_div_48_Template(rf, ctx) { if (rf & 1) {
|
|
80
|
+
const _r7 = i0.ɵɵgetCurrentView();
|
|
81
|
+
i0.ɵɵelementStart(0, "div", 55)(1, "button", 56);
|
|
82
|
+
i0.ɵɵlistener("click", function APIKeyEditPanelComponent_ng_container_12_div_15_div_48_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.saveChanges()); });
|
|
83
|
+
i0.ɵɵtemplate(2, APIKeyEditPanelComponent_ng_container_12_div_15_div_48_mj_loading_2_Template, 1, 1, "mj-loading", 57)(3, APIKeyEditPanelComponent_ng_container_12_div_15_div_48_span_3_Template, 3, 0, "span", 9);
|
|
84
|
+
i0.ɵɵelementEnd()();
|
|
85
|
+
} if (rf & 2) {
|
|
86
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
87
|
+
i0.ɵɵadvance();
|
|
88
|
+
i0.ɵɵproperty("themeColor", "primary")("disabled", ctx_r1.IsSaving);
|
|
89
|
+
i0.ɵɵadvance();
|
|
90
|
+
i0.ɵɵproperty("ngIf", ctx_r1.IsSaving);
|
|
91
|
+
i0.ɵɵadvance();
|
|
92
|
+
i0.ɵɵproperty("ngIf", !ctx_r1.IsSaving);
|
|
93
|
+
} }
|
|
94
|
+
function APIKeyEditPanelComponent_ng_container_12_div_15_div_49_div_3_Template(rf, ctx) { if (rf & 1) {
|
|
95
|
+
const _r8 = i0.ɵɵgetCurrentView();
|
|
96
|
+
i0.ɵɵelementStart(0, "div", 63)(1, "div", 64);
|
|
97
|
+
i0.ɵɵelement(2, "i", 65);
|
|
98
|
+
i0.ɵɵelementStart(3, "div")(4, "strong");
|
|
99
|
+
i0.ɵɵtext(5, "Revoke this API key");
|
|
100
|
+
i0.ɵɵelementEnd();
|
|
101
|
+
i0.ɵɵelementStart(6, "p");
|
|
102
|
+
i0.ɵɵtext(7, "Once revoked, this key will immediately stop working. This action cannot be undone.");
|
|
103
|
+
i0.ɵɵelementEnd()()();
|
|
104
|
+
i0.ɵɵelementStart(8, "button", 66);
|
|
105
|
+
i0.ɵɵlistener("click", function APIKeyEditPanelComponent_ng_container_12_div_15_div_49_div_3_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.startRevoke()); });
|
|
106
|
+
i0.ɵɵelement(9, "i", 67);
|
|
107
|
+
i0.ɵɵtext(10, " Revoke Key ");
|
|
108
|
+
i0.ɵɵelementEnd()();
|
|
109
|
+
} }
|
|
110
|
+
function APIKeyEditPanelComponent_ng_container_12_div_15_div_49_div_4_mj_loading_19_Template(rf, ctx) { if (rf & 1) {
|
|
111
|
+
i0.ɵɵelement(0, "mj-loading", 58);
|
|
112
|
+
} if (rf & 2) {
|
|
113
|
+
i0.ɵɵproperty("showText", false);
|
|
114
|
+
} }
|
|
115
|
+
function APIKeyEditPanelComponent_ng_container_12_div_15_div_49_div_4_span_20_Template(rf, ctx) { if (rf & 1) {
|
|
116
|
+
i0.ɵɵelementStart(0, "span");
|
|
117
|
+
i0.ɵɵelement(1, "i", 67);
|
|
118
|
+
i0.ɵɵtext(2, " Revoke Key ");
|
|
119
|
+
i0.ɵɵelementEnd();
|
|
120
|
+
} }
|
|
121
|
+
function APIKeyEditPanelComponent_ng_container_12_div_15_div_49_div_4_Template(rf, ctx) { if (rf & 1) {
|
|
122
|
+
const _r9 = i0.ɵɵgetCurrentView();
|
|
123
|
+
i0.ɵɵelementStart(0, "div", 68)(1, "div", 69);
|
|
124
|
+
i0.ɵɵelement(2, "i", 70);
|
|
125
|
+
i0.ɵɵelementStart(3, "div")(4, "strong");
|
|
126
|
+
i0.ɵɵtext(5, "Are you absolutely sure?");
|
|
127
|
+
i0.ɵɵelementEnd();
|
|
128
|
+
i0.ɵɵelementStart(6, "p");
|
|
129
|
+
i0.ɵɵtext(7, "This will permanently revoke the API key. Any applications using this key will immediately lose access.");
|
|
130
|
+
i0.ɵɵelementEnd()()();
|
|
131
|
+
i0.ɵɵelementStart(8, "div", 71)(9, "label");
|
|
132
|
+
i0.ɵɵtext(10, "Type ");
|
|
133
|
+
i0.ɵɵelementStart(11, "code");
|
|
134
|
+
i0.ɵɵtext(12, "REVOKE");
|
|
135
|
+
i0.ɵɵelementEnd();
|
|
136
|
+
i0.ɵɵtext(13, " to confirm:");
|
|
137
|
+
i0.ɵɵelementEnd();
|
|
138
|
+
i0.ɵɵelementStart(14, "input", 72);
|
|
139
|
+
i0.ɵɵtwoWayListener("ngModelChange", function APIKeyEditPanelComponent_ng_container_12_div_15_div_49_div_4_Template_input_ngModelChange_14_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r1.RevokeConfirmText, $event) || (ctx_r1.RevokeConfirmText = $event); return i0.ɵɵresetView($event); });
|
|
140
|
+
i0.ɵɵelementEnd()();
|
|
141
|
+
i0.ɵɵelementStart(15, "div", 73)(16, "button", 25);
|
|
142
|
+
i0.ɵɵlistener("click", function APIKeyEditPanelComponent_ng_container_12_div_15_div_49_div_4_Template_button_click_16_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.cancelRevoke()); });
|
|
143
|
+
i0.ɵɵtext(17, "Cancel");
|
|
144
|
+
i0.ɵɵelementEnd();
|
|
145
|
+
i0.ɵɵelementStart(18, "button", 74);
|
|
146
|
+
i0.ɵɵlistener("click", function APIKeyEditPanelComponent_ng_container_12_div_15_div_49_div_4_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.confirmRevoke()); });
|
|
147
|
+
i0.ɵɵtemplate(19, APIKeyEditPanelComponent_ng_container_12_div_15_div_49_div_4_mj_loading_19_Template, 1, 1, "mj-loading", 57)(20, APIKeyEditPanelComponent_ng_container_12_div_15_div_49_div_4_span_20_Template, 3, 0, "span", 9);
|
|
148
|
+
i0.ɵɵelementEnd()()();
|
|
149
|
+
} if (rf & 2) {
|
|
150
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
151
|
+
i0.ɵɵadvance(14);
|
|
152
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.RevokeConfirmText);
|
|
153
|
+
i0.ɵɵadvance(4);
|
|
154
|
+
i0.ɵɵproperty("disabled", ctx_r1.RevokeConfirmText !== "REVOKE" || ctx_r1.IsRevoking);
|
|
155
|
+
i0.ɵɵadvance();
|
|
156
|
+
i0.ɵɵproperty("ngIf", ctx_r1.IsRevoking);
|
|
157
|
+
i0.ɵɵadvance();
|
|
158
|
+
i0.ɵɵproperty("ngIf", !ctx_r1.IsRevoking);
|
|
159
|
+
} }
|
|
160
|
+
function APIKeyEditPanelComponent_ng_container_12_div_15_div_49_Template(rf, ctx) { if (rf & 1) {
|
|
161
|
+
i0.ɵɵelementStart(0, "div", 60)(1, "h4");
|
|
162
|
+
i0.ɵɵtext(2, "Danger Zone");
|
|
163
|
+
i0.ɵɵelementEnd();
|
|
164
|
+
i0.ɵɵtemplate(3, APIKeyEditPanelComponent_ng_container_12_div_15_div_49_div_3_Template, 11, 0, "div", 61)(4, APIKeyEditPanelComponent_ng_container_12_div_15_div_49_div_4_Template, 21, 4, "div", 62);
|
|
165
|
+
i0.ɵɵelementEnd();
|
|
166
|
+
} if (rf & 2) {
|
|
167
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
168
|
+
i0.ɵɵadvance(3);
|
|
169
|
+
i0.ɵɵproperty("ngIf", !ctx_r1.ShowRevokeConfirm);
|
|
170
|
+
i0.ɵɵadvance();
|
|
171
|
+
i0.ɵɵproperty("ngIf", ctx_r1.ShowRevokeConfirm);
|
|
172
|
+
} }
|
|
173
|
+
function APIKeyEditPanelComponent_ng_container_12_div_15_div_50_Template(rf, ctx) { if (rf & 1) {
|
|
174
|
+
i0.ɵɵelementStart(0, "div", 75);
|
|
175
|
+
i0.ɵɵelement(1, "i", 67);
|
|
176
|
+
i0.ɵɵelementStart(2, "div")(3, "strong");
|
|
177
|
+
i0.ɵɵtext(4, "This API key has been revoked");
|
|
178
|
+
i0.ɵɵelementEnd();
|
|
179
|
+
i0.ɵɵelementStart(5, "p");
|
|
180
|
+
i0.ɵɵtext(6, "It can no longer be used for authentication. Consider deleting this record if no longer needed.");
|
|
181
|
+
i0.ɵɵelementEnd()()();
|
|
182
|
+
} }
|
|
183
|
+
function APIKeyEditPanelComponent_ng_container_12_div_15_Template(rf, ctx) { if (rf & 1) {
|
|
184
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
185
|
+
i0.ɵɵelementStart(0, "div", 31)(1, "div", 32)(2, "div", 33)(3, "div", 34)(4, "span", 35);
|
|
186
|
+
i0.ɵɵtext(5, "Key Hash");
|
|
187
|
+
i0.ɵɵelementEnd();
|
|
188
|
+
i0.ɵɵelementStart(6, "code", 36);
|
|
189
|
+
i0.ɵɵtext(7);
|
|
190
|
+
i0.ɵɵelementEnd()()();
|
|
191
|
+
i0.ɵɵelementStart(8, "div", 37)(9, "div", 38)(10, "span", 35);
|
|
192
|
+
i0.ɵɵtext(11, "Created");
|
|
193
|
+
i0.ɵɵelementEnd();
|
|
194
|
+
i0.ɵɵelementStart(12, "span", 39);
|
|
195
|
+
i0.ɵɵtext(13);
|
|
196
|
+
i0.ɵɵelementEnd()();
|
|
197
|
+
i0.ɵɵelementStart(14, "div", 38)(15, "span", 35);
|
|
198
|
+
i0.ɵɵtext(16, "Created By");
|
|
199
|
+
i0.ɵɵelementEnd();
|
|
200
|
+
i0.ɵɵelementStart(17, "span", 39);
|
|
201
|
+
i0.ɵɵtext(18);
|
|
202
|
+
i0.ɵɵelementEnd()();
|
|
203
|
+
i0.ɵɵelementStart(19, "div", 38)(20, "span", 35);
|
|
204
|
+
i0.ɵɵtext(21, "Owner");
|
|
205
|
+
i0.ɵɵelementEnd();
|
|
206
|
+
i0.ɵɵelementStart(22, "span", 39);
|
|
207
|
+
i0.ɵɵtext(23);
|
|
208
|
+
i0.ɵɵelementEnd()();
|
|
209
|
+
i0.ɵɵelementStart(24, "div", 38)(25, "span", 35);
|
|
210
|
+
i0.ɵɵtext(26, "Last Used");
|
|
211
|
+
i0.ɵɵelementEnd();
|
|
212
|
+
i0.ɵɵelementStart(27, "span", 39);
|
|
213
|
+
i0.ɵɵtext(28);
|
|
214
|
+
i0.ɵɵelementEnd()()()();
|
|
215
|
+
i0.ɵɵelementStart(29, "div", 40)(30, "div", 41)(31, "h4");
|
|
216
|
+
i0.ɵɵtext(32, "Key Configuration");
|
|
217
|
+
i0.ɵɵelementEnd();
|
|
218
|
+
i0.ɵɵtemplate(33, APIKeyEditPanelComponent_ng_container_12_div_15_button_33_Template, 3, 5, "button", 42);
|
|
219
|
+
i0.ɵɵelementEnd();
|
|
220
|
+
i0.ɵɵelementStart(34, "div", 43)(35, "label");
|
|
221
|
+
i0.ɵɵtext(36, "Label");
|
|
222
|
+
i0.ɵɵelementEnd();
|
|
223
|
+
i0.ɵɵelementStart(37, "input", 44);
|
|
224
|
+
i0.ɵɵtwoWayListener("ngModelChange", function APIKeyEditPanelComponent_ng_container_12_div_15_Template_input_ngModelChange_37_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.EditLabel, $event) || (ctx_r1.EditLabel = $event); return i0.ɵɵresetView($event); });
|
|
225
|
+
i0.ɵɵelementEnd()();
|
|
226
|
+
i0.ɵɵelementStart(38, "div", 43)(39, "label");
|
|
227
|
+
i0.ɵɵtext(40, "Description");
|
|
228
|
+
i0.ɵɵelementEnd();
|
|
229
|
+
i0.ɵɵelementStart(41, "textarea", 45);
|
|
230
|
+
i0.ɵɵtwoWayListener("ngModelChange", function APIKeyEditPanelComponent_ng_container_12_div_15_Template_textarea_ngModelChange_41_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.EditDescription, $event) || (ctx_r1.EditDescription = $event); return i0.ɵɵresetView($event); });
|
|
231
|
+
i0.ɵɵelementEnd()();
|
|
232
|
+
i0.ɵɵelementStart(42, "div", 43)(43, "label");
|
|
233
|
+
i0.ɵɵtext(44, "Expiration");
|
|
234
|
+
i0.ɵɵelementEnd();
|
|
235
|
+
i0.ɵɵelementStart(45, "div", 46)(46, "kendo-datepicker", 47);
|
|
236
|
+
i0.ɵɵtwoWayListener("ngModelChange", function APIKeyEditPanelComponent_ng_container_12_div_15_Template_kendo_datepicker_ngModelChange_46_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.EditExpiresAt, $event) || (ctx_r1.EditExpiresAt = $event); return i0.ɵɵresetView($event); });
|
|
237
|
+
i0.ɵɵelementEnd();
|
|
238
|
+
i0.ɵɵtemplate(47, APIKeyEditPanelComponent_ng_container_12_div_15_button_47_Template, 3, 0, "button", 48);
|
|
239
|
+
i0.ɵɵelementEnd()();
|
|
240
|
+
i0.ɵɵtemplate(48, APIKeyEditPanelComponent_ng_container_12_div_15_div_48_Template, 4, 4, "div", 49);
|
|
241
|
+
i0.ɵɵelementEnd();
|
|
242
|
+
i0.ɵɵtemplate(49, APIKeyEditPanelComponent_ng_container_12_div_15_div_49_Template, 5, 2, "div", 50)(50, APIKeyEditPanelComponent_ng_container_12_div_15_div_50_Template, 7, 0, "div", 51);
|
|
243
|
+
i0.ɵɵelementEnd();
|
|
244
|
+
} if (rf & 2) {
|
|
245
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
246
|
+
i0.ɵɵadvance(7);
|
|
247
|
+
i0.ɵɵtextInterpolate(ctx_r1.APIKey.Hash);
|
|
248
|
+
i0.ɵɵadvance(6);
|
|
249
|
+
i0.ɵɵtextInterpolate(ctx_r1.formatDate(ctx_r1.APIKey.__mj_CreatedAt));
|
|
250
|
+
i0.ɵɵadvance(5);
|
|
251
|
+
i0.ɵɵtextInterpolate(ctx_r1.APIKey.CreatedByUser);
|
|
252
|
+
i0.ɵɵadvance(5);
|
|
253
|
+
i0.ɵɵtextInterpolate(ctx_r1.APIKey.User);
|
|
254
|
+
i0.ɵɵadvance(4);
|
|
255
|
+
i0.ɵɵclassProp("never-used", !ctx_r1.APIKey.LastUsedAt);
|
|
256
|
+
i0.ɵɵadvance();
|
|
257
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r1.APIKey.LastUsedAt ? ctx_r1.formatDate(ctx_r1.APIKey.LastUsedAt) : "Never", " ");
|
|
258
|
+
i0.ɵɵadvance(5);
|
|
259
|
+
i0.ɵɵproperty("ngIf", ctx_r1.APIKey.Status === "Active");
|
|
260
|
+
i0.ɵɵadvance(4);
|
|
261
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.EditLabel);
|
|
262
|
+
i0.ɵɵproperty("disabled", !ctx_r1.IsEditing);
|
|
263
|
+
i0.ɵɵadvance(4);
|
|
264
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.EditDescription);
|
|
265
|
+
i0.ɵɵproperty("disabled", !ctx_r1.IsEditing)("rows", 3);
|
|
266
|
+
i0.ɵɵadvance(5);
|
|
267
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.EditExpiresAt);
|
|
268
|
+
i0.ɵɵproperty("disabled", !ctx_r1.IsEditing)("min", ctx_r1.getMinDate());
|
|
269
|
+
i0.ɵɵadvance();
|
|
270
|
+
i0.ɵɵproperty("ngIf", ctx_r1.IsEditing && ctx_r1.EditExpiresAt);
|
|
271
|
+
i0.ɵɵadvance();
|
|
272
|
+
i0.ɵɵproperty("ngIf", ctx_r1.IsEditing);
|
|
273
|
+
i0.ɵɵadvance();
|
|
274
|
+
i0.ɵɵproperty("ngIf", ctx_r1.APIKey.Status === "Active");
|
|
275
|
+
i0.ɵɵadvance();
|
|
276
|
+
i0.ɵɵproperty("ngIf", ctx_r1.APIKey.Status === "Revoked");
|
|
277
|
+
} }
|
|
278
|
+
function APIKeyEditPanelComponent_ng_container_12_div_16_button_5_mj_loading_1_Template(rf, ctx) { if (rf & 1) {
|
|
279
|
+
i0.ɵɵelement(0, "mj-loading", 58);
|
|
280
|
+
} if (rf & 2) {
|
|
281
|
+
i0.ɵɵproperty("showText", false);
|
|
282
|
+
} }
|
|
283
|
+
function APIKeyEditPanelComponent_ng_container_12_div_16_button_5_span_2_Template(rf, ctx) { if (rf & 1) {
|
|
284
|
+
i0.ɵɵelementStart(0, "span");
|
|
285
|
+
i0.ɵɵelement(1, "i", 59);
|
|
286
|
+
i0.ɵɵtext(2, " Save Changes ");
|
|
287
|
+
i0.ɵɵelementEnd();
|
|
288
|
+
} }
|
|
289
|
+
function APIKeyEditPanelComponent_ng_container_12_div_16_button_5_Template(rf, ctx) { if (rf & 1) {
|
|
290
|
+
const _r10 = i0.ɵɵgetCurrentView();
|
|
291
|
+
i0.ɵɵelementStart(0, "button", 56);
|
|
292
|
+
i0.ɵɵlistener("click", function APIKeyEditPanelComponent_ng_container_12_div_16_button_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.saveScopeChanges()); });
|
|
293
|
+
i0.ɵɵtemplate(1, APIKeyEditPanelComponent_ng_container_12_div_16_button_5_mj_loading_1_Template, 1, 1, "mj-loading", 57)(2, APIKeyEditPanelComponent_ng_container_12_div_16_button_5_span_2_Template, 3, 0, "span", 9);
|
|
294
|
+
i0.ɵɵelementEnd();
|
|
295
|
+
} if (rf & 2) {
|
|
296
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
297
|
+
i0.ɵɵproperty("themeColor", "primary")("disabled", ctx_r1.IsSaving);
|
|
298
|
+
i0.ɵɵadvance();
|
|
299
|
+
i0.ɵɵproperty("ngIf", ctx_r1.IsSaving);
|
|
300
|
+
i0.ɵɵadvance();
|
|
301
|
+
i0.ɵɵproperty("ngIf", !ctx_r1.IsSaving);
|
|
302
|
+
} }
|
|
303
|
+
function APIKeyEditPanelComponent_ng_container_12_div_16_div_6_Template(rf, ctx) { if (rf & 1) {
|
|
304
|
+
i0.ɵɵelementStart(0, "div", 84);
|
|
305
|
+
i0.ɵɵelement(1, "i", 65);
|
|
306
|
+
i0.ɵɵelementStart(2, "div")(3, "strong");
|
|
307
|
+
i0.ɵɵtext(4, "Warning: No permissions assigned");
|
|
308
|
+
i0.ɵɵelementEnd();
|
|
309
|
+
i0.ɵɵelementStart(5, "p");
|
|
310
|
+
i0.ɵɵtext(6, "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.");
|
|
311
|
+
i0.ɵɵelementEnd()()();
|
|
312
|
+
} }
|
|
313
|
+
function APIKeyEditPanelComponent_ng_container_12_div_16_mj_loading_7_Template(rf, ctx) { if (rf & 1) {
|
|
314
|
+
i0.ɵɵelement(0, "mj-loading", 85);
|
|
315
|
+
} }
|
|
316
|
+
function APIKeyEditPanelComponent_ng_container_12_div_16_div_8_div_1_label_9_Template(rf, ctx) { if (rf & 1) {
|
|
317
|
+
const _r13 = i0.ɵɵgetCurrentView();
|
|
318
|
+
i0.ɵɵelementStart(0, "label", 97);
|
|
319
|
+
i0.ɵɵlistener("click", function APIKeyEditPanelComponent_ng_container_12_div_16_div_8_div_1_label_9_Template_label_click_0_listener($event) { i0.ɵɵrestoreView(_r13); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
320
|
+
i0.ɵɵelementStart(1, "input", 98);
|
|
321
|
+
i0.ɵɵlistener("change", function APIKeyEditPanelComponent_ng_container_12_div_16_div_8_div_1_label_9_Template_input_change_1_listener() { i0.ɵɵrestoreView(_r13); const category_r12 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.toggleCategoryAll(category_r12)); });
|
|
322
|
+
i0.ɵɵelementEnd();
|
|
323
|
+
i0.ɵɵelementStart(2, "span");
|
|
324
|
+
i0.ɵɵtext(3, "All");
|
|
325
|
+
i0.ɵɵelementEnd()();
|
|
326
|
+
} if (rf & 2) {
|
|
327
|
+
const category_r12 = i0.ɵɵnextContext().$implicit;
|
|
328
|
+
i0.ɵɵadvance();
|
|
329
|
+
i0.ɵɵproperty("checked", category_r12.allSelected);
|
|
330
|
+
} }
|
|
331
|
+
function APIKeyEditPanelComponent_ng_container_12_div_16_div_8_div_1_div_11_div_1_span_6_Template(rf, ctx) { if (rf & 1) {
|
|
332
|
+
i0.ɵɵelementStart(0, "span", 107);
|
|
333
|
+
i0.ɵɵtext(1);
|
|
334
|
+
i0.ɵɵelementEnd();
|
|
335
|
+
} if (rf & 2) {
|
|
336
|
+
const item_r15 = i0.ɵɵnextContext().$implicit;
|
|
337
|
+
i0.ɵɵadvance();
|
|
338
|
+
i0.ɵɵtextInterpolate1(" ", item_r15.scope.Description, " ");
|
|
339
|
+
} }
|
|
340
|
+
function APIKeyEditPanelComponent_ng_container_12_div_16_div_8_div_1_div_11_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
341
|
+
const _r14 = i0.ɵɵgetCurrentView();
|
|
342
|
+
i0.ɵɵelementStart(0, "div", 101)(1, "label", 102)(2, "input", 103);
|
|
343
|
+
i0.ɵɵtwoWayListener("ngModelChange", function APIKeyEditPanelComponent_ng_container_12_div_16_div_8_div_1_div_11_div_1_Template_input_ngModelChange_2_listener($event) { const item_r15 = i0.ɵɵrestoreView(_r14).$implicit; i0.ɵɵtwoWayBindingSet(item_r15.selected, $event) || (item_r15.selected = $event); return i0.ɵɵresetView($event); });
|
|
344
|
+
i0.ɵɵlistener("change", function APIKeyEditPanelComponent_ng_container_12_div_16_div_8_div_1_div_11_div_1_Template_input_change_2_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(6); return i0.ɵɵresetView(ctx_r1.onScopeChange()); });
|
|
345
|
+
i0.ɵɵelementEnd();
|
|
346
|
+
i0.ɵɵelementStart(3, "div", 104)(4, "span", 105);
|
|
347
|
+
i0.ɵɵtext(5);
|
|
348
|
+
i0.ɵɵelementEnd();
|
|
349
|
+
i0.ɵɵtemplate(6, APIKeyEditPanelComponent_ng_container_12_div_16_div_8_div_1_div_11_div_1_span_6_Template, 2, 1, "span", 106);
|
|
350
|
+
i0.ɵɵelementEnd()()();
|
|
351
|
+
} if (rf & 2) {
|
|
352
|
+
const item_r15 = ctx.$implicit;
|
|
353
|
+
const ctx_r1 = i0.ɵɵnextContext(6);
|
|
354
|
+
i0.ɵɵadvance(2);
|
|
355
|
+
i0.ɵɵtwoWayProperty("ngModel", item_r15.selected);
|
|
356
|
+
i0.ɵɵproperty("disabled", ctx_r1.APIKey.Status === "Revoked");
|
|
357
|
+
i0.ɵɵadvance(3);
|
|
358
|
+
i0.ɵɵtextInterpolate(item_r15.scope.Name);
|
|
359
|
+
i0.ɵɵadvance();
|
|
360
|
+
i0.ɵɵproperty("ngIf", item_r15.scope.Description);
|
|
361
|
+
} }
|
|
362
|
+
function APIKeyEditPanelComponent_ng_container_12_div_16_div_8_div_1_div_11_Template(rf, ctx) { if (rf & 1) {
|
|
363
|
+
i0.ɵɵelementStart(0, "div", 99);
|
|
364
|
+
i0.ɵɵtemplate(1, APIKeyEditPanelComponent_ng_container_12_div_16_div_8_div_1_div_11_div_1_Template, 7, 4, "div", 100);
|
|
365
|
+
i0.ɵɵelementEnd();
|
|
366
|
+
} if (rf & 2) {
|
|
367
|
+
const category_r12 = i0.ɵɵnextContext().$implicit;
|
|
368
|
+
i0.ɵɵadvance();
|
|
369
|
+
i0.ɵɵproperty("ngForOf", category_r12.scopes);
|
|
370
|
+
} }
|
|
371
|
+
function APIKeyEditPanelComponent_ng_container_12_div_16_div_8_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
372
|
+
const _r11 = i0.ɵɵgetCurrentView();
|
|
373
|
+
i0.ɵɵelementStart(0, "div", 88)(1, "div", 89);
|
|
374
|
+
i0.ɵɵlistener("click", function APIKeyEditPanelComponent_ng_container_12_div_16_div_8_div_1_Template_div_click_1_listener() { const category_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.toggleCategory(category_r12)); });
|
|
375
|
+
i0.ɵɵelementStart(2, "div", 90);
|
|
376
|
+
i0.ɵɵelement(3, "i");
|
|
377
|
+
i0.ɵɵelementStart(4, "span", 91);
|
|
378
|
+
i0.ɵɵtext(5);
|
|
379
|
+
i0.ɵɵelementEnd();
|
|
380
|
+
i0.ɵɵelementStart(6, "span", 92);
|
|
381
|
+
i0.ɵɵtext(7);
|
|
382
|
+
i0.ɵɵelementEnd()();
|
|
383
|
+
i0.ɵɵelementStart(8, "div", 93);
|
|
384
|
+
i0.ɵɵtemplate(9, APIKeyEditPanelComponent_ng_container_12_div_16_div_8_div_1_label_9_Template, 4, 1, "label", 94);
|
|
385
|
+
i0.ɵɵelement(10, "i", 95);
|
|
386
|
+
i0.ɵɵelementEnd()();
|
|
387
|
+
i0.ɵɵtemplate(11, APIKeyEditPanelComponent_ng_container_12_div_16_div_8_div_1_div_11_Template, 2, 1, "div", 96);
|
|
388
|
+
i0.ɵɵelementEnd();
|
|
389
|
+
} if (rf & 2) {
|
|
390
|
+
const category_r12 = ctx.$implicit;
|
|
391
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
392
|
+
i0.ɵɵadvance(3);
|
|
393
|
+
i0.ɵɵclassMap(category_r12.icon);
|
|
394
|
+
i0.ɵɵstyleProp("color", category_r12.color);
|
|
395
|
+
i0.ɵɵadvance(2);
|
|
396
|
+
i0.ɵɵtextInterpolate(category_r12.name);
|
|
397
|
+
i0.ɵɵadvance(2);
|
|
398
|
+
i0.ɵɵtextInterpolate2(" ", ctx_r1.getSelectedCount(category_r12), "/", category_r12.scopes.length, " ");
|
|
399
|
+
i0.ɵɵadvance(2);
|
|
400
|
+
i0.ɵɵproperty("ngIf", ctx_r1.APIKey.Status === "Active");
|
|
401
|
+
i0.ɵɵadvance();
|
|
402
|
+
i0.ɵɵclassProp("fa-chevron-down", !category_r12.expanded)("fa-chevron-up", category_r12.expanded);
|
|
403
|
+
i0.ɵɵadvance();
|
|
404
|
+
i0.ɵɵproperty("ngIf", category_r12.expanded);
|
|
405
|
+
} }
|
|
406
|
+
function APIKeyEditPanelComponent_ng_container_12_div_16_div_8_Template(rf, ctx) { if (rf & 1) {
|
|
407
|
+
i0.ɵɵelementStart(0, "div", 86);
|
|
408
|
+
i0.ɵɵtemplate(1, APIKeyEditPanelComponent_ng_container_12_div_16_div_8_div_1_Template, 12, 13, "div", 87);
|
|
409
|
+
i0.ɵɵelementEnd();
|
|
410
|
+
} if (rf & 2) {
|
|
411
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
412
|
+
i0.ɵɵadvance();
|
|
413
|
+
i0.ɵɵproperty("ngForOf", ctx_r1.ScopeCategories);
|
|
414
|
+
} }
|
|
415
|
+
function APIKeyEditPanelComponent_ng_container_12_div_16_Template(rf, ctx) { if (rf & 1) {
|
|
416
|
+
i0.ɵɵelementStart(0, "div", 76)(1, "div", 77)(2, "div", 78)(3, "span", 79);
|
|
417
|
+
i0.ɵɵtext(4);
|
|
418
|
+
i0.ɵɵelementEnd()();
|
|
419
|
+
i0.ɵɵtemplate(5, APIKeyEditPanelComponent_ng_container_12_div_16_button_5_Template, 3, 4, "button", 80);
|
|
420
|
+
i0.ɵɵelementEnd();
|
|
421
|
+
i0.ɵɵtemplate(6, APIKeyEditPanelComponent_ng_container_12_div_16_div_6_Template, 7, 0, "div", 81)(7, APIKeyEditPanelComponent_ng_container_12_div_16_mj_loading_7_Template, 1, 0, "mj-loading", 82)(8, APIKeyEditPanelComponent_ng_container_12_div_16_div_8_Template, 2, 1, "div", 83);
|
|
422
|
+
i0.ɵɵelementEnd();
|
|
423
|
+
} if (rf & 2) {
|
|
424
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
425
|
+
i0.ɵɵadvance(4);
|
|
426
|
+
i0.ɵɵtextInterpolate1("", ctx_r1.getAssignedScopeCount(), " permissions assigned");
|
|
427
|
+
i0.ɵɵadvance();
|
|
428
|
+
i0.ɵɵproperty("ngIf", ctx_r1.HasScopeChanges && ctx_r1.APIKey.Status === "Active");
|
|
429
|
+
i0.ɵɵadvance();
|
|
430
|
+
i0.ɵɵproperty("ngIf", !ctx_r1.IsLoadingScopes && ctx_r1.getAssignedScopeCount() === 0 && ctx_r1.APIKey.Status === "Active");
|
|
431
|
+
i0.ɵɵadvance();
|
|
432
|
+
i0.ɵɵproperty("ngIf", ctx_r1.IsLoadingScopes);
|
|
433
|
+
i0.ɵɵadvance();
|
|
434
|
+
i0.ɵɵproperty("ngIf", !ctx_r1.IsLoadingScopes);
|
|
435
|
+
} }
|
|
436
|
+
function APIKeyEditPanelComponent_ng_container_12_div_17_mj_loading_1_Template(rf, ctx) { if (rf & 1) {
|
|
437
|
+
i0.ɵɵelement(0, "mj-loading", 111);
|
|
438
|
+
} }
|
|
439
|
+
function APIKeyEditPanelComponent_ng_container_12_div_17_div_2_div_14_div_10_Template(rf, ctx) { if (rf & 1) {
|
|
440
|
+
i0.ɵɵelementStart(0, "div", 127)(1, "span", 122);
|
|
441
|
+
i0.ɵɵtext(2);
|
|
442
|
+
i0.ɵɵelementEnd();
|
|
443
|
+
i0.ɵɵelementStart(3, "span", 123)(4, "span", 128);
|
|
444
|
+
i0.ɵɵtext(5);
|
|
445
|
+
i0.ɵɵelementEnd();
|
|
446
|
+
i0.ɵɵtext(6);
|
|
447
|
+
i0.ɵɵelementEnd();
|
|
448
|
+
i0.ɵɵelementStart(7, "span", 129);
|
|
449
|
+
i0.ɵɵtext(8);
|
|
450
|
+
i0.ɵɵelementEnd();
|
|
451
|
+
i0.ɵɵelementStart(9, "span", 125);
|
|
452
|
+
i0.ɵɵtext(10);
|
|
453
|
+
i0.ɵɵelementEnd()();
|
|
454
|
+
} if (rf & 2) {
|
|
455
|
+
const log_r16 = ctx.$implicit;
|
|
456
|
+
const ctx_r1 = i0.ɵɵnextContext(5);
|
|
457
|
+
i0.ɵɵadvance(2);
|
|
458
|
+
i0.ɵɵtextInterpolate(ctx_r1.formatRelativeTime(log_r16.timestamp));
|
|
459
|
+
i0.ɵɵadvance(3);
|
|
460
|
+
i0.ɵɵtextInterpolate(log_r16.method);
|
|
461
|
+
i0.ɵɵadvance();
|
|
462
|
+
i0.ɵɵtextInterpolate1(" ", log_r16.endpoint, " ");
|
|
463
|
+
i0.ɵɵadvance();
|
|
464
|
+
i0.ɵɵproperty("ngClass", ctx_r1.getStatusClass(log_r16.statusCode));
|
|
465
|
+
i0.ɵɵadvance();
|
|
466
|
+
i0.ɵɵtextInterpolate1(" ", log_r16.statusCode, " ");
|
|
467
|
+
i0.ɵɵadvance(2);
|
|
468
|
+
i0.ɵɵtextInterpolate1("", log_r16.responseTime, "ms");
|
|
469
|
+
} }
|
|
470
|
+
function APIKeyEditPanelComponent_ng_container_12_div_17_div_2_div_14_Template(rf, ctx) { if (rf & 1) {
|
|
471
|
+
i0.ɵɵelementStart(0, "div", 120)(1, "div", 121)(2, "span", 122);
|
|
472
|
+
i0.ɵɵtext(3, "Time");
|
|
473
|
+
i0.ɵɵelementEnd();
|
|
474
|
+
i0.ɵɵelementStart(4, "span", 123);
|
|
475
|
+
i0.ɵɵtext(5, "Endpoint");
|
|
476
|
+
i0.ɵɵelementEnd();
|
|
477
|
+
i0.ɵɵelementStart(6, "span", 124);
|
|
478
|
+
i0.ɵɵtext(7, "Status");
|
|
479
|
+
i0.ɵɵelementEnd();
|
|
480
|
+
i0.ɵɵelementStart(8, "span", 125);
|
|
481
|
+
i0.ɵɵtext(9, "Duration");
|
|
482
|
+
i0.ɵɵelementEnd()();
|
|
483
|
+
i0.ɵɵtemplate(10, APIKeyEditPanelComponent_ng_container_12_div_17_div_2_div_14_div_10_Template, 11, 6, "div", 126);
|
|
484
|
+
i0.ɵɵelementEnd();
|
|
485
|
+
} if (rf & 2) {
|
|
486
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
487
|
+
i0.ɵɵadvance(10);
|
|
488
|
+
i0.ɵɵproperty("ngForOf", ctx_r1.UsageLogs);
|
|
489
|
+
} }
|
|
490
|
+
function APIKeyEditPanelComponent_ng_container_12_div_17_div_2_div_15_Template(rf, ctx) { if (rf & 1) {
|
|
491
|
+
i0.ɵɵelementStart(0, "div", 130);
|
|
492
|
+
i0.ɵɵelement(1, "i", 131);
|
|
493
|
+
i0.ɵɵelementStart(2, "span");
|
|
494
|
+
i0.ɵɵtext(3, "No usage logs yet");
|
|
495
|
+
i0.ɵɵelementEnd();
|
|
496
|
+
i0.ɵɵelementStart(4, "p");
|
|
497
|
+
i0.ɵɵtext(5, "Usage will be recorded when this API key is used for authentication");
|
|
498
|
+
i0.ɵɵelementEnd()();
|
|
499
|
+
} }
|
|
500
|
+
function APIKeyEditPanelComponent_ng_container_12_div_17_div_2_Template(rf, ctx) { if (rf & 1) {
|
|
501
|
+
i0.ɵɵelementStart(0, "div", 112)(1, "div", 113)(2, "div", 114);
|
|
502
|
+
i0.ɵɵelement(3, "i", 19);
|
|
503
|
+
i0.ɵɵelementStart(4, "div", 115);
|
|
504
|
+
i0.ɵɵtext(5);
|
|
505
|
+
i0.ɵɵelementEnd();
|
|
506
|
+
i0.ɵɵelementStart(6, "div", 116);
|
|
507
|
+
i0.ɵɵtext(7, "Total Requests");
|
|
508
|
+
i0.ɵɵelementEnd()();
|
|
509
|
+
i0.ɵɵelementStart(8, "div", 114);
|
|
510
|
+
i0.ɵɵelement(9, "i", 117);
|
|
511
|
+
i0.ɵɵelementStart(10, "div", 115);
|
|
512
|
+
i0.ɵɵtext(11);
|
|
513
|
+
i0.ɵɵelementEnd();
|
|
514
|
+
i0.ɵɵelementStart(12, "div", 116);
|
|
515
|
+
i0.ɵɵtext(13, "Last Used");
|
|
516
|
+
i0.ɵɵelementEnd()()();
|
|
517
|
+
i0.ɵɵtemplate(14, APIKeyEditPanelComponent_ng_container_12_div_17_div_2_div_14_Template, 11, 1, "div", 118)(15, APIKeyEditPanelComponent_ng_container_12_div_17_div_2_div_15_Template, 6, 0, "div", 119);
|
|
518
|
+
i0.ɵɵelementEnd();
|
|
519
|
+
} if (rf & 2) {
|
|
520
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
521
|
+
i0.ɵɵadvance(5);
|
|
522
|
+
i0.ɵɵtextInterpolate(ctx_r1.UsageLogs.length);
|
|
523
|
+
i0.ɵɵadvance(6);
|
|
524
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r1.UsageLogs.length > 0 ? ctx_r1.formatRelativeTime(ctx_r1.UsageLogs[0].timestamp) : "Never", " ");
|
|
525
|
+
i0.ɵɵadvance(3);
|
|
526
|
+
i0.ɵɵproperty("ngIf", ctx_r1.UsageLogs.length > 0);
|
|
527
|
+
i0.ɵɵadvance();
|
|
528
|
+
i0.ɵɵproperty("ngIf", ctx_r1.UsageLogs.length === 0);
|
|
529
|
+
} }
|
|
530
|
+
function APIKeyEditPanelComponent_ng_container_12_div_17_Template(rf, ctx) { if (rf & 1) {
|
|
531
|
+
i0.ɵɵelementStart(0, "div", 108);
|
|
532
|
+
i0.ɵɵtemplate(1, APIKeyEditPanelComponent_ng_container_12_div_17_mj_loading_1_Template, 1, 0, "mj-loading", 109)(2, APIKeyEditPanelComponent_ng_container_12_div_17_div_2_Template, 16, 4, "div", 110);
|
|
533
|
+
i0.ɵɵelementEnd();
|
|
534
|
+
} if (rf & 2) {
|
|
535
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
536
|
+
i0.ɵɵadvance();
|
|
537
|
+
i0.ɵɵproperty("ngIf", ctx_r1.IsLoadingLogs);
|
|
538
|
+
i0.ɵɵadvance();
|
|
539
|
+
i0.ɵɵproperty("ngIf", !ctx_r1.IsLoadingLogs);
|
|
540
|
+
} }
|
|
541
|
+
function APIKeyEditPanelComponent_ng_container_12_Template(rf, ctx) { if (rf & 1) {
|
|
542
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
543
|
+
i0.ɵɵelementContainerStart(0);
|
|
544
|
+
i0.ɵɵtemplate(1, APIKeyEditPanelComponent_ng_container_12_div_1_Template, 3, 1, "div", 12)(2, APIKeyEditPanelComponent_ng_container_12_div_2_Template, 3, 1, "div", 13);
|
|
545
|
+
i0.ɵɵelementStart(3, "div", 14)(4, "button", 15);
|
|
546
|
+
i0.ɵɵlistener("click", function APIKeyEditPanelComponent_ng_container_12_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ActiveTab = "details"); });
|
|
547
|
+
i0.ɵɵelement(5, "i", 16);
|
|
548
|
+
i0.ɵɵtext(6, " Details ");
|
|
549
|
+
i0.ɵɵelementEnd();
|
|
550
|
+
i0.ɵɵelementStart(7, "button", 15);
|
|
551
|
+
i0.ɵɵlistener("click", function APIKeyEditPanelComponent_ng_container_12_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ActiveTab = "scopes"); });
|
|
552
|
+
i0.ɵɵelement(8, "i", 17);
|
|
553
|
+
i0.ɵɵtext(9, " Permissions ");
|
|
554
|
+
i0.ɵɵtemplate(10, APIKeyEditPanelComponent_ng_container_12_span_10_Template, 2, 0, "span", 18);
|
|
555
|
+
i0.ɵɵelementEnd();
|
|
556
|
+
i0.ɵɵelementStart(11, "button", 15);
|
|
557
|
+
i0.ɵɵlistener("click", function APIKeyEditPanelComponent_ng_container_12_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ActiveTab = "usage"); });
|
|
558
|
+
i0.ɵɵelement(12, "i", 19);
|
|
559
|
+
i0.ɵɵtext(13, " Usage ");
|
|
560
|
+
i0.ɵɵelementEnd()();
|
|
561
|
+
i0.ɵɵelementStart(14, "div", 20);
|
|
562
|
+
i0.ɵɵtemplate(15, APIKeyEditPanelComponent_ng_container_12_div_15_Template, 51, 20, "div", 21)(16, APIKeyEditPanelComponent_ng_container_12_div_16_Template, 9, 5, "div", 22)(17, APIKeyEditPanelComponent_ng_container_12_div_17_Template, 3, 2, "div", 23);
|
|
563
|
+
i0.ɵɵelementEnd();
|
|
564
|
+
i0.ɵɵelementStart(18, "div", 24)(19, "button", 25);
|
|
565
|
+
i0.ɵɵlistener("click", function APIKeyEditPanelComponent_ng_container_12_Template_button_click_19_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.close()); });
|
|
566
|
+
i0.ɵɵtext(20, "Close");
|
|
567
|
+
i0.ɵɵelementEnd()();
|
|
568
|
+
i0.ɵɵelementContainerEnd();
|
|
569
|
+
} if (rf & 2) {
|
|
570
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
571
|
+
i0.ɵɵadvance();
|
|
572
|
+
i0.ɵɵproperty("ngIf", ctx_r1.SuccessMessage);
|
|
573
|
+
i0.ɵɵadvance();
|
|
574
|
+
i0.ɵɵproperty("ngIf", ctx_r1.ErrorMessage);
|
|
575
|
+
i0.ɵɵadvance(2);
|
|
576
|
+
i0.ɵɵclassProp("active", ctx_r1.ActiveTab === "details");
|
|
577
|
+
i0.ɵɵadvance(3);
|
|
578
|
+
i0.ɵɵclassProp("active", ctx_r1.ActiveTab === "scopes");
|
|
579
|
+
i0.ɵɵadvance(3);
|
|
580
|
+
i0.ɵɵproperty("ngIf", ctx_r1.HasScopeChanges);
|
|
581
|
+
i0.ɵɵadvance();
|
|
582
|
+
i0.ɵɵclassProp("active", ctx_r1.ActiveTab === "usage");
|
|
583
|
+
i0.ɵɵadvance(4);
|
|
584
|
+
i0.ɵɵproperty("ngIf", ctx_r1.ActiveTab === "details");
|
|
585
|
+
i0.ɵɵadvance();
|
|
586
|
+
i0.ɵɵproperty("ngIf", ctx_r1.ActiveTab === "scopes");
|
|
587
|
+
i0.ɵɵadvance();
|
|
588
|
+
i0.ɵɵproperty("ngIf", ctx_r1.ActiveTab === "usage");
|
|
589
|
+
} }
|
|
590
|
+
/** Tree shaking prevention function */
|
|
591
|
+
export function LoadAPIKeyEditPanel() {
|
|
592
|
+
// This function prevents tree shaking
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* Panel for viewing and editing existing API keys
|
|
596
|
+
*/
|
|
597
|
+
export class APIKeyEditPanelComponent {
|
|
598
|
+
Visible = false;
|
|
599
|
+
KeyId = null;
|
|
600
|
+
VisibleChange = new EventEmitter();
|
|
601
|
+
Updated = new EventEmitter();
|
|
602
|
+
Revoked = new EventEmitter();
|
|
603
|
+
Closed = new EventEmitter();
|
|
604
|
+
md = new Metadata();
|
|
605
|
+
// Current key
|
|
606
|
+
APIKey = null;
|
|
607
|
+
IsLoading = true;
|
|
608
|
+
IsSaving = false;
|
|
609
|
+
IsRevoking = false;
|
|
610
|
+
// Edit mode
|
|
611
|
+
IsEditing = false;
|
|
612
|
+
EditLabel = '';
|
|
613
|
+
EditDescription = '';
|
|
614
|
+
EditExpiresAt = null;
|
|
615
|
+
// Scopes
|
|
616
|
+
ScopeCategories = [];
|
|
617
|
+
IsLoadingScopes = true;
|
|
618
|
+
HasScopeChanges = false;
|
|
619
|
+
// Usage logs
|
|
620
|
+
UsageLogs = [];
|
|
621
|
+
IsLoadingLogs = true;
|
|
622
|
+
// Tabs
|
|
623
|
+
ActiveTab = 'details';
|
|
624
|
+
// Revoke confirmation
|
|
625
|
+
ShowRevokeConfirm = false;
|
|
626
|
+
RevokeConfirmText = '';
|
|
627
|
+
// Messages
|
|
628
|
+
SuccessMessage = '';
|
|
629
|
+
ErrorMessage = '';
|
|
630
|
+
// Default UI config for categories without explicit configuration
|
|
631
|
+
defaultUIConfig = {
|
|
632
|
+
icon: 'fa-solid fa-ellipsis',
|
|
633
|
+
color: '#6b7280'
|
|
634
|
+
};
|
|
635
|
+
async ngOnChanges(changes) {
|
|
636
|
+
if (changes['KeyId'] && this.KeyId) {
|
|
637
|
+
await this.loadKey();
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Handle escape key to close panel
|
|
642
|
+
*/
|
|
643
|
+
onEscapeKey() {
|
|
644
|
+
if (this.Visible && !this.IsSaving && !this.IsRevoking) {
|
|
645
|
+
this.close();
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* Load the API key and related data
|
|
650
|
+
*/
|
|
651
|
+
async loadKey() {
|
|
652
|
+
this.IsLoading = true;
|
|
653
|
+
this.resetState();
|
|
654
|
+
try {
|
|
655
|
+
const key = await this.md.GetEntityObject('MJ: API Keys');
|
|
656
|
+
if (await key.Load(this.KeyId)) {
|
|
657
|
+
this.APIKey = key;
|
|
658
|
+
this.EditLabel = key.Label;
|
|
659
|
+
this.EditDescription = key.Description || '';
|
|
660
|
+
this.EditExpiresAt = key.ExpiresAt;
|
|
661
|
+
// Load scopes and usage in parallel
|
|
662
|
+
await Promise.all([
|
|
663
|
+
this.loadScopes(),
|
|
664
|
+
this.loadUsageLogs()
|
|
665
|
+
]);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
catch (error) {
|
|
669
|
+
console.error('Error loading API key:', error);
|
|
670
|
+
this.ErrorMessage = 'Failed to load API key details';
|
|
671
|
+
}
|
|
672
|
+
finally {
|
|
673
|
+
this.IsLoading = false;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* Load all scopes and mark assigned ones
|
|
678
|
+
*/
|
|
679
|
+
async loadScopes() {
|
|
680
|
+
this.IsLoadingScopes = true;
|
|
681
|
+
try {
|
|
682
|
+
const rv = new RunView();
|
|
683
|
+
const base = APIKeysEngineBase.Instance;
|
|
684
|
+
// Get all scopes from cache, load assigned scopes from DB
|
|
685
|
+
const allScopes = base.Scopes;
|
|
686
|
+
const assignedScopesResult = await rv.RunView({
|
|
687
|
+
EntityName: 'MJ: API Key Scopes',
|
|
688
|
+
ExtraFilter: `APIKeyID='${this.KeyId}'`,
|
|
689
|
+
ResultType: 'entity_object'
|
|
690
|
+
});
|
|
691
|
+
if (assignedScopesResult.Success) {
|
|
692
|
+
const assignedScopeIds = new Set(assignedScopesResult.Results.map(ks => ks.ScopeID));
|
|
693
|
+
// Build category UI config from root scopes
|
|
694
|
+
const categoryUIConfigs = new Map();
|
|
695
|
+
for (const scope of allScopes) {
|
|
696
|
+
if (!scope.ParentID) {
|
|
697
|
+
const uiConfig = parseAPIScopeUIConfig(scope);
|
|
698
|
+
categoryUIConfigs.set(scope.Category, {
|
|
699
|
+
icon: uiConfig.icon || this.defaultUIConfig.icon,
|
|
700
|
+
color: uiConfig.color || this.defaultUIConfig.color
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
const categoryMap = new Map();
|
|
705
|
+
for (const scope of allScopes) {
|
|
706
|
+
const category = scope.Category || 'Other';
|
|
707
|
+
if (!categoryMap.has(category)) {
|
|
708
|
+
categoryMap.set(category, []);
|
|
709
|
+
}
|
|
710
|
+
const isSelected = assignedScopeIds.has(scope.ID);
|
|
711
|
+
categoryMap.get(category).push({
|
|
712
|
+
scope,
|
|
713
|
+
selected: isSelected,
|
|
714
|
+
originallySelected: isSelected
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
this.ScopeCategories = Array.from(categoryMap.entries()).map(([name, scopes]) => {
|
|
718
|
+
const config = categoryUIConfigs.get(name) || this.defaultUIConfig;
|
|
719
|
+
return {
|
|
720
|
+
name,
|
|
721
|
+
icon: config.icon,
|
|
722
|
+
color: config.color,
|
|
723
|
+
scopes: scopes.sort((a, b) => a.scope.Name.localeCompare(b.scope.Name)),
|
|
724
|
+
expanded: scopes.some(s => s.selected),
|
|
725
|
+
allSelected: scopes.length > 0 && scopes.every(s => s.selected)
|
|
726
|
+
};
|
|
727
|
+
}).sort((a, b) => a.name.localeCompare(b.name));
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
catch (error) {
|
|
731
|
+
console.error('Error loading scopes:', error);
|
|
732
|
+
}
|
|
733
|
+
finally {
|
|
734
|
+
this.IsLoadingScopes = false;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
/**
|
|
738
|
+
* Load usage logs for this key
|
|
739
|
+
*/
|
|
740
|
+
async loadUsageLogs() {
|
|
741
|
+
this.IsLoadingLogs = true;
|
|
742
|
+
try {
|
|
743
|
+
const rv = new RunView();
|
|
744
|
+
const result = await rv.RunView({
|
|
745
|
+
EntityName: 'MJ: API Key Usage Logs',
|
|
746
|
+
ExtraFilter: `APIKeyID='${this.KeyId}'`,
|
|
747
|
+
OrderBy: '__mj_CreatedAt DESC',
|
|
748
|
+
MaxRows: 100,
|
|
749
|
+
ResultType: 'entity_object'
|
|
750
|
+
});
|
|
751
|
+
if (result.Success) {
|
|
752
|
+
this.UsageLogs = result.Results.map(log => ({
|
|
753
|
+
timestamp: log.__mj_CreatedAt,
|
|
754
|
+
endpoint: log.Endpoint || '/unknown',
|
|
755
|
+
method: log.Method || 'GET',
|
|
756
|
+
statusCode: log.StatusCode || 200,
|
|
757
|
+
responseTime: log.ResponseTimeMs || 0,
|
|
758
|
+
ipAddress: log.IPAddress || 'Unknown'
|
|
759
|
+
}));
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
catch (error) {
|
|
763
|
+
console.error('Error loading usage logs:', error);
|
|
764
|
+
}
|
|
765
|
+
finally {
|
|
766
|
+
this.IsLoadingLogs = false;
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
/**
|
|
770
|
+
* Reset component state
|
|
771
|
+
*/
|
|
772
|
+
resetState() {
|
|
773
|
+
this.IsEditing = false;
|
|
774
|
+
this.ShowRevokeConfirm = false;
|
|
775
|
+
this.RevokeConfirmText = '';
|
|
776
|
+
this.SuccessMessage = '';
|
|
777
|
+
this.ErrorMessage = '';
|
|
778
|
+
this.HasScopeChanges = false;
|
|
779
|
+
this.ActiveTab = 'details';
|
|
780
|
+
}
|
|
781
|
+
/**
|
|
782
|
+
* Toggle edit mode
|
|
783
|
+
*/
|
|
784
|
+
toggleEdit() {
|
|
785
|
+
if (this.IsEditing) {
|
|
786
|
+
// Cancel edit
|
|
787
|
+
this.EditLabel = this.APIKey.Label;
|
|
788
|
+
this.EditDescription = this.APIKey.Description || '';
|
|
789
|
+
this.EditExpiresAt = this.APIKey.ExpiresAt;
|
|
790
|
+
}
|
|
791
|
+
this.IsEditing = !this.IsEditing;
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Save changes to the key
|
|
795
|
+
*/
|
|
796
|
+
async saveChanges() {
|
|
797
|
+
if (!this.APIKey)
|
|
798
|
+
return;
|
|
799
|
+
this.IsSaving = true;
|
|
800
|
+
this.ErrorMessage = '';
|
|
801
|
+
try {
|
|
802
|
+
this.APIKey.Label = this.EditLabel.trim();
|
|
803
|
+
this.APIKey.Description = this.EditDescription.trim() || null;
|
|
804
|
+
this.APIKey.ExpiresAt = this.EditExpiresAt;
|
|
805
|
+
const result = await this.APIKey.Save();
|
|
806
|
+
if (result) {
|
|
807
|
+
this.IsEditing = false;
|
|
808
|
+
this.SuccessMessage = 'API key updated successfully';
|
|
809
|
+
this.Updated.emit(this.APIKey);
|
|
810
|
+
setTimeout(() => this.SuccessMessage = '', 3000);
|
|
811
|
+
}
|
|
812
|
+
else {
|
|
813
|
+
this.ErrorMessage = 'Failed to save changes';
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
catch (error) {
|
|
817
|
+
console.error('Error saving key:', error);
|
|
818
|
+
this.ErrorMessage = 'An error occurred while saving';
|
|
819
|
+
}
|
|
820
|
+
finally {
|
|
821
|
+
this.IsSaving = false;
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
/**
|
|
825
|
+
* Save scope changes
|
|
826
|
+
*/
|
|
827
|
+
async saveScopeChanges() {
|
|
828
|
+
if (!this.APIKey)
|
|
829
|
+
return;
|
|
830
|
+
this.IsSaving = true;
|
|
831
|
+
this.ErrorMessage = '';
|
|
832
|
+
try {
|
|
833
|
+
const allScopes = this.ScopeCategories.flatMap(cat => cat.scopes);
|
|
834
|
+
// Find scopes to add and remove
|
|
835
|
+
const toAdd = allScopes.filter(s => s.selected && !s.originallySelected);
|
|
836
|
+
const toRemove = allScopes.filter(s => !s.selected && s.originallySelected);
|
|
837
|
+
// Add new scope assignments
|
|
838
|
+
for (const item of toAdd) {
|
|
839
|
+
const keyScope = await this.md.GetEntityObject('MJ: API Key Scopes');
|
|
840
|
+
keyScope.NewRecord();
|
|
841
|
+
keyScope.APIKeyID = this.APIKey.ID;
|
|
842
|
+
keyScope.ScopeID = item.scope.ID;
|
|
843
|
+
await keyScope.Save();
|
|
844
|
+
item.originallySelected = true;
|
|
845
|
+
}
|
|
846
|
+
// Remove scope assignments
|
|
847
|
+
const rv = new RunView();
|
|
848
|
+
for (const item of toRemove) {
|
|
849
|
+
const result = await rv.RunView({
|
|
850
|
+
EntityName: 'MJ: API Key Scopes',
|
|
851
|
+
ExtraFilter: `APIKeyID='${this.APIKey.ID}' AND ScopeID='${item.scope.ID}'`,
|
|
852
|
+
ResultType: 'entity_object'
|
|
853
|
+
});
|
|
854
|
+
if (result.Success && result.Results.length > 0) {
|
|
855
|
+
await result.Results[0].Delete();
|
|
856
|
+
}
|
|
857
|
+
item.originallySelected = false;
|
|
858
|
+
}
|
|
859
|
+
this.HasScopeChanges = false;
|
|
860
|
+
this.SuccessMessage = 'Permissions updated successfully';
|
|
861
|
+
setTimeout(() => this.SuccessMessage = '', 3000);
|
|
862
|
+
}
|
|
863
|
+
catch (error) {
|
|
864
|
+
console.error('Error saving scopes:', error);
|
|
865
|
+
this.ErrorMessage = 'Failed to update permissions';
|
|
866
|
+
}
|
|
867
|
+
finally {
|
|
868
|
+
this.IsSaving = false;
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
/**
|
|
872
|
+
* Check for scope changes and update category allSelected states
|
|
873
|
+
*/
|
|
874
|
+
onScopeChange() {
|
|
875
|
+
// Update allSelected state for each category
|
|
876
|
+
for (const category of this.ScopeCategories) {
|
|
877
|
+
category.allSelected = category.scopes.length > 0 && category.scopes.every(s => s.selected);
|
|
878
|
+
}
|
|
879
|
+
// Track overall changes
|
|
880
|
+
const allScopes = this.ScopeCategories.flatMap(cat => cat.scopes);
|
|
881
|
+
this.HasScopeChanges = allScopes.some(s => s.selected !== s.originallySelected);
|
|
882
|
+
}
|
|
883
|
+
/**
|
|
884
|
+
* Toggle category expansion
|
|
885
|
+
*/
|
|
886
|
+
toggleCategory(category) {
|
|
887
|
+
category.expanded = !category.expanded;
|
|
888
|
+
}
|
|
889
|
+
/**
|
|
890
|
+
* Toggle all scopes in a category on/off
|
|
891
|
+
*/
|
|
892
|
+
toggleCategoryAll(category) {
|
|
893
|
+
// Toggle to opposite of current allSelected state
|
|
894
|
+
const newState = !category.allSelected;
|
|
895
|
+
category.allSelected = newState;
|
|
896
|
+
// Apply to all scopes in category
|
|
897
|
+
for (const item of category.scopes) {
|
|
898
|
+
item.selected = newState;
|
|
899
|
+
}
|
|
900
|
+
// Update change tracking
|
|
901
|
+
this.onScopeChange();
|
|
902
|
+
}
|
|
903
|
+
/**
|
|
904
|
+
* Start revoke flow
|
|
905
|
+
*/
|
|
906
|
+
startRevoke() {
|
|
907
|
+
this.ShowRevokeConfirm = true;
|
|
908
|
+
this.RevokeConfirmText = '';
|
|
909
|
+
}
|
|
910
|
+
/**
|
|
911
|
+
* Cancel revoke
|
|
912
|
+
*/
|
|
913
|
+
cancelRevoke() {
|
|
914
|
+
this.ShowRevokeConfirm = false;
|
|
915
|
+
this.RevokeConfirmText = '';
|
|
916
|
+
}
|
|
917
|
+
/**
|
|
918
|
+
* Confirm and execute revoke using GraphQL client
|
|
919
|
+
*/
|
|
920
|
+
async confirmRevoke() {
|
|
921
|
+
if (!this.APIKey || this.RevokeConfirmText !== 'REVOKE')
|
|
922
|
+
return;
|
|
923
|
+
this.IsRevoking = true;
|
|
924
|
+
this.ErrorMessage = '';
|
|
925
|
+
try {
|
|
926
|
+
const provider = Metadata.Provider;
|
|
927
|
+
const encryptionClient = new GraphQLEncryptionClient(provider);
|
|
928
|
+
const result = await encryptionClient.RevokeAPIKey(this.APIKey.ID);
|
|
929
|
+
if (result.Success) {
|
|
930
|
+
// Update local state to reflect the change
|
|
931
|
+
this.APIKey.Status = 'Revoked';
|
|
932
|
+
this.ShowRevokeConfirm = false;
|
|
933
|
+
this.SuccessMessage = 'API key has been revoked';
|
|
934
|
+
this.Revoked.emit(this.APIKey);
|
|
935
|
+
}
|
|
936
|
+
else {
|
|
937
|
+
this.ErrorMessage = result.Error || 'Failed to revoke key';
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
catch (error) {
|
|
941
|
+
console.error('Error revoking key:', error);
|
|
942
|
+
this.ErrorMessage = 'An error occurred while revoking';
|
|
943
|
+
}
|
|
944
|
+
finally {
|
|
945
|
+
this.IsRevoking = false;
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
/**
|
|
949
|
+
* Format date for display
|
|
950
|
+
*/
|
|
951
|
+
formatDate(date) {
|
|
952
|
+
if (!date)
|
|
953
|
+
return 'Never';
|
|
954
|
+
return new Date(date).toLocaleDateString('en-US', {
|
|
955
|
+
year: 'numeric',
|
|
956
|
+
month: 'long',
|
|
957
|
+
day: 'numeric',
|
|
958
|
+
hour: '2-digit',
|
|
959
|
+
minute: '2-digit'
|
|
960
|
+
});
|
|
961
|
+
}
|
|
962
|
+
/**
|
|
963
|
+
* Format relative time
|
|
964
|
+
*/
|
|
965
|
+
formatRelativeTime(date) {
|
|
966
|
+
const now = new Date();
|
|
967
|
+
const diff = now.getTime() - new Date(date).getTime();
|
|
968
|
+
const minutes = Math.floor(diff / 60000);
|
|
969
|
+
const hours = Math.floor(diff / 3600000);
|
|
970
|
+
const days = Math.floor(diff / 86400000);
|
|
971
|
+
if (minutes < 1)
|
|
972
|
+
return 'Just now';
|
|
973
|
+
if (minutes < 60)
|
|
974
|
+
return `${minutes}m ago`;
|
|
975
|
+
if (hours < 24)
|
|
976
|
+
return `${hours}h ago`;
|
|
977
|
+
if (days < 7)
|
|
978
|
+
return `${days}d ago`;
|
|
979
|
+
return new Date(date).toLocaleDateString();
|
|
980
|
+
}
|
|
981
|
+
/**
|
|
982
|
+
* Get status class for HTTP status code
|
|
983
|
+
*/
|
|
984
|
+
getStatusClass(statusCode) {
|
|
985
|
+
if (statusCode >= 200 && statusCode < 300)
|
|
986
|
+
return 'status-success';
|
|
987
|
+
if (statusCode >= 400 && statusCode < 500)
|
|
988
|
+
return 'status-warning';
|
|
989
|
+
if (statusCode >= 500)
|
|
990
|
+
return 'status-error';
|
|
991
|
+
return '';
|
|
992
|
+
}
|
|
993
|
+
/**
|
|
994
|
+
* Get assigned scope count
|
|
995
|
+
*/
|
|
996
|
+
getAssignedScopeCount() {
|
|
997
|
+
return this.ScopeCategories.reduce((sum, cat) => sum + cat.scopes.filter(s => s.selected).length, 0);
|
|
998
|
+
}
|
|
999
|
+
/**
|
|
1000
|
+
* Get selected scope count for a category (for template use)
|
|
1001
|
+
*/
|
|
1002
|
+
getSelectedCount(category) {
|
|
1003
|
+
return category.scopes.filter(s => s.selected).length;
|
|
1004
|
+
}
|
|
1005
|
+
/**
|
|
1006
|
+
* Get minimum date for expiration (tomorrow)
|
|
1007
|
+
*/
|
|
1008
|
+
getMinDate() {
|
|
1009
|
+
const tomorrow = new Date();
|
|
1010
|
+
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
1011
|
+
return tomorrow;
|
|
1012
|
+
}
|
|
1013
|
+
/**
|
|
1014
|
+
* Close the panel
|
|
1015
|
+
*/
|
|
1016
|
+
close() {
|
|
1017
|
+
this.Visible = false;
|
|
1018
|
+
this.VisibleChange.emit(false);
|
|
1019
|
+
this.Closed.emit();
|
|
1020
|
+
}
|
|
1021
|
+
static ɵfac = function APIKeyEditPanelComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || APIKeyEditPanelComponent)(); };
|
|
1022
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: APIKeyEditPanelComponent, selectors: [["mj-api-key-edit-panel"]], hostBindings: function APIKeyEditPanelComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
1023
|
+
i0.ɵɵlistener("keydown.escape", function APIKeyEditPanelComponent_keydown_escape_HostBindingHandler() { return ctx.onEscapeKey(); }, false, i0.ɵɵresolveDocument);
|
|
1024
|
+
} }, inputs: { Visible: "Visible", KeyId: "KeyId" }, outputs: { VisibleChange: "VisibleChange", Updated: "Updated", Revoked: "Revoked", Closed: "Closed" }, features: [i0.ɵɵNgOnChangesFeature], decls: 13, vars: 10, consts: [["class", "slideout-backdrop", 3, "click", 4, "ngIf"], [1, "slideout-panel"], [1, "slideout-header"], [1, "slideout-title"], [1, "fa-solid", "fa-key"], [1, "key-status"], ["title", "Close (Esc)", 1, "slideout-close", 3, "click"], [1, "fa-solid", "fa-times"], ["text", "Loading key details...", 4, "ngIf"], [4, "ngIf"], [1, "slideout-backdrop", 3, "click"], ["text", "Loading key details..."], ["class", "message success", 4, "ngIf"], ["class", "message error", 4, "ngIf"], [1, "slideout-tabs"], [1, "slideout-tab", 3, "click"], [1, "fa-solid", "fa-info-circle"], [1, "fa-solid", "fa-shield-halved"], ["class", "tab-badge unsaved", 4, "ngIf"], [1, "fa-solid", "fa-chart-line"], [1, "slideout-content"], ["class", "tab-panel", 4, "ngIf"], ["class", "tab-panel scopes-panel", 4, "ngIf"], ["class", "tab-panel usage-panel", 4, "ngIf"], [1, "slideout-footer"], ["kendoButton", "", 3, "click"], [1, "message", "success"], [1, "fa-solid", "fa-check-circle"], [1, "message", "error"], [1, "fa-solid", "fa-circle-exclamation"], [1, "tab-badge", "unsaved"], [1, "tab-panel"], [1, "key-info-card"], [1, "info-header"], [1, "info-row"], [1, "info-label"], [1, "hash-value"], [1, "info-grid"], [1, "info-item"], [1, "info-value"], [1, "edit-section"], [1, "section-header"], ["class", "edit-toggle", 3, "click", 4, "ngIf"], [1, "form-field"], ["kendoTextBox", "", 1, "form-input", 3, "ngModelChange", "ngModel", "disabled"], ["kendoTextArea", "", 1, "form-textarea", 3, "ngModelChange", "ngModel", "disabled", "rows"], [1, "expiration-field"], ["format", "MMM d, yyyy", "placeholder", "Never expires", 3, "ngModelChange", "ngModel", "disabled", "min"], ["class", "clear-btn", 3, "click", 4, "ngIf"], ["class", "edit-actions", 4, "ngIf"], ["class", "danger-zone", 4, "ngIf"], ["class", "revoked-notice", 4, "ngIf"], [1, "edit-toggle", 3, "click"], [1, "fa-solid"], [1, "clear-btn", 3, "click"], [1, "edit-actions"], ["kendoButton", "", 3, "click", "themeColor", "disabled"], ["size", "small", 3, "showText", 4, "ngIf"], ["size", "small", 3, "showText"], [1, "fa-solid", "fa-save"], [1, "danger-zone"], ["class", "revoke-section", 4, "ngIf"], ["class", "revoke-confirm", 4, "ngIf"], [1, "revoke-section"], [1, "revoke-info"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "revoke-btn", 3, "click"], [1, "fa-solid", "fa-ban"], [1, "revoke-confirm"], [1, "confirm-warning"], [1, "fa-solid", "fa-skull-crossbones"], [1, "confirm-input"], ["kendoTextBox", "", "placeholder", "REVOKE", 3, "ngModelChange", "ngModel"], [1, "confirm-actions"], [1, "confirm-revoke-btn", 3, "click", "disabled"], [1, "revoked-notice"], [1, "tab-panel", "scopes-panel"], [1, "scopes-header"], [1, "scopes-info"], [1, "scope-count"], ["kendoButton", "", 3, "themeColor", "disabled", "click", 4, "ngIf"], ["class", "no-scopes-warning", 4, "ngIf"], ["text", "Loading permissions...", 4, "ngIf"], ["class", "scope-categories", 4, "ngIf"], [1, "no-scopes-warning"], ["text", "Loading permissions..."], [1, "scope-categories"], ["class", "scope-category", 4, "ngFor", "ngForOf"], [1, "scope-category"], [1, "category-header", 3, "click"], [1, "category-left"], [1, "category-name"], [1, "category-count"], [1, "category-right"], ["class", "category-all-toggle", 3, "click", 4, "ngIf"], [1, "fa-solid", "expand-icon"], ["class", "category-scopes", 4, "ngIf"], [1, "category-all-toggle", 3, "click"], ["type", "checkbox", "kendoCheckBox", "", 3, "change", "checked"], [1, "category-scopes"], ["class", "scope-item", 4, "ngFor", "ngForOf"], [1, "scope-item"], [1, "scope-label"], ["type", "checkbox", "kendoCheckBox", "", 3, "ngModelChange", "change", "ngModel", "disabled"], [1, "scope-info"], [1, "scope-name"], ["class", "scope-desc", 4, "ngIf"], [1, "scope-desc"], [1, "tab-panel", "usage-panel"], ["text", "Loading usage logs...", 4, "ngIf"], ["class", "usage-content", 4, "ngIf"], ["text", "Loading usage logs..."], [1, "usage-content"], [1, "usage-stats"], [1, "stat-card"], [1, "stat-value"], [1, "stat-label"], [1, "fa-solid", "fa-clock"], ["class", "usage-logs", 4, "ngIf"], ["class", "empty-state", 4, "ngIf"], [1, "usage-logs"], [1, "log-header"], [1, "col-time"], [1, "col-endpoint"], [1, "col-status"], [1, "col-duration"], ["class", "log-item", 4, "ngFor", "ngForOf"], [1, "log-item"], [1, "method-badge"], [1, "col-status", 3, "ngClass"], [1, "empty-state"], [1, "fa-solid", "fa-chart-area"]], template: function APIKeyEditPanelComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1025
|
+
i0.ɵɵtemplate(0, APIKeyEditPanelComponent_div_0_Template, 1, 0, "div", 0);
|
|
1026
|
+
i0.ɵɵelementStart(1, "div", 1)(2, "div", 2)(3, "div", 3);
|
|
1027
|
+
i0.ɵɵelement(4, "i", 4);
|
|
1028
|
+
i0.ɵɵelementStart(5, "span");
|
|
1029
|
+
i0.ɵɵtext(6, "API Key Details");
|
|
1030
|
+
i0.ɵɵelementEnd();
|
|
1031
|
+
i0.ɵɵelementStart(7, "span", 5);
|
|
1032
|
+
i0.ɵɵtext(8);
|
|
1033
|
+
i0.ɵɵelementEnd()();
|
|
1034
|
+
i0.ɵɵelementStart(9, "button", 6);
|
|
1035
|
+
i0.ɵɵlistener("click", function APIKeyEditPanelComponent_Template_button_click_9_listener() { return ctx.close(); });
|
|
1036
|
+
i0.ɵɵelement(10, "i", 7);
|
|
1037
|
+
i0.ɵɵelementEnd()();
|
|
1038
|
+
i0.ɵɵtemplate(11, APIKeyEditPanelComponent_mj_loading_11_Template, 1, 0, "mj-loading", 8)(12, APIKeyEditPanelComponent_ng_container_12_Template, 21, 12, "ng-container", 9);
|
|
1039
|
+
i0.ɵɵelementEnd();
|
|
1040
|
+
} if (rf & 2) {
|
|
1041
|
+
i0.ɵɵproperty("ngIf", ctx.Visible);
|
|
1042
|
+
i0.ɵɵadvance();
|
|
1043
|
+
i0.ɵɵclassProp("open", ctx.Visible);
|
|
1044
|
+
i0.ɵɵadvance(6);
|
|
1045
|
+
i0.ɵɵclassProp("active", (ctx.APIKey == null ? null : ctx.APIKey.Status) === "Active")("revoked", (ctx.APIKey == null ? null : ctx.APIKey.Status) === "Revoked");
|
|
1046
|
+
i0.ɵɵadvance();
|
|
1047
|
+
i0.ɵɵtextInterpolate1(" ", ctx.APIKey == null ? null : ctx.APIKey.Status, " ");
|
|
1048
|
+
i0.ɵɵadvance(3);
|
|
1049
|
+
i0.ɵɵproperty("ngIf", ctx.IsLoading);
|
|
1050
|
+
i0.ɵɵadvance();
|
|
1051
|
+
i0.ɵɵproperty("ngIf", !ctx.IsLoading && ctx.APIKey);
|
|
1052
|
+
} }, dependencies: [i1.NgClass, i1.NgForOf, i1.NgIf, i2.DefaultValueAccessor, i2.CheckboxControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.TextAreaDirective, i3.TextBoxDirective, i3.CheckBoxDirective, i4.DatePickerComponent, i5.ButtonComponent, i6.LoadingComponent], styles: ["\n\n\n\n\n\n\n.slideout-backdrop[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 100;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n\n.slideout-panel[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n right: 0;\n width: 520px;\n height: 100%;\n max-height: 100%;\n background: var(--card-background, #ffffff);\n box-shadow: -8px 0 32px rgba(0, 0, 0, 0.15);\n z-index: 101;\n display: flex;\n flex-direction: column;\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n transform: translateX(100%);\n overflow: hidden;\n}\n\n.slideout-panel.open[_ngcontent-%COMP%] {\n transform: translateX(0);\n}\n\n\n\n.slideout-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n border-bottom: 1px solid #fcd34d;\n flex-shrink: 0;\n}\n\n.slideout-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n font-weight: 600;\n font-size: 17px;\n color: #78350f;\n flex: 1;\n min-width: 0;\n}\n\n.slideout-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #f59e0b;\n font-size: 18px;\n flex-shrink: 0;\n}\n\n.key-status[_ngcontent-%COMP%] {\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n flex-shrink: 0;\n}\n\n.key-status.active[_ngcontent-%COMP%] {\n background: rgba(16, 185, 129, 0.2);\n color: #059669;\n}\n\n.key-status.revoked[_ngcontent-%COMP%] {\n background: rgba(220, 38, 38, 0.2);\n color: #dc2626;\n}\n\n.slideout-close[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgba(255, 255, 255, 0.5);\n border: none;\n border-radius: 8px;\n color: #92400e;\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.slideout-close[_ngcontent-%COMP%]:hover {\n background: rgba(255, 255, 255, 0.8);\n color: #78350f;\n}\n\n\n\n.slideout-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n padding: 12px 24px;\n background: #f9fafb;\n border-bottom: 1px solid #e5e7eb;\n flex-shrink: 0;\n}\n\n.slideout-tab[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 18px;\n background: transparent;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: #6b7280;\n cursor: pointer;\n transition: all 0.2s ease;\n position: relative;\n}\n\n.slideout-tab[_ngcontent-%COMP%]:hover {\n background: #e5e7eb;\n color: #374151;\n}\n\n.slideout-tab.active[_ngcontent-%COMP%] {\n background: #f59e0b;\n color: white;\n}\n\n.slideout-tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.tab-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n background: rgba(255, 255, 255, 0.2);\n border-radius: 9px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.tab-badge.unsaved[_ngcontent-%COMP%] {\n background: #ef4444;\n color: white;\n}\n\n.slideout-tab[_ngcontent-%COMP%]:not(.active) .tab-badge[_ngcontent-%COMP%] {\n background: #e5e7eb;\n color: #374151;\n}\n\n\n\n.slideout-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 0;\n}\n\n.tab-panel[_ngcontent-%COMP%] {\n padding: 20px 24px;\n}\n\n\n\n.slideout-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n padding: 16px 24px;\n background: #f9fafb;\n border-top: 1px solid #e5e7eb;\n flex-shrink: 0;\n}\n\n[_nghost-%COMP%] .slideout-footer .k-button {\n min-width: 80px;\n padding: 8px 16px;\n font-weight: 500;\n border-radius: 6px;\n}\n\n\n\n.message[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n margin: 12px 16px;\n border-radius: 8px;\n font-size: 14px;\n}\n\n.message.success[_ngcontent-%COMP%] {\n background: #d1fae5;\n color: #059669;\n}\n\n.message.error[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #dc2626;\n}\n\n\n\n\n\n\n.key-info-card[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n border-radius: 10px;\n padding: 14px 16px;\n margin-bottom: 16px;\n}\n\n.info-header[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n padding-bottom: 12px;\n border-bottom: 1px solid rgba(245, 158, 11, 0.3);\n}\n\n.info-row[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.info-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: #92400e;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.hash-value[_ngcontent-%COMP%] {\n font-family: 'Fira Code', 'Consolas', monospace;\n font-size: 13px;\n color: #78350f;\n word-break: break-all;\n background: rgba(255, 255, 255, 0.5);\n padding: 8px 12px;\n border-radius: 6px;\n}\n\n.info-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 10px 16px;\n}\n\n.info-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.info-value[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: #78350f;\n}\n\n.info-value.never-used[_ngcontent-%COMP%] {\n color: #6b7280;\n font-style: italic;\n}\n\n\n\n.edit-section[_ngcontent-%COMP%] {\n background: #f9fafb;\n border-radius: 10px;\n padding: 16px;\n margin-bottom: 16px;\n}\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 14px;\n}\n\n.section-header[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #1f2937;\n}\n\n.edit-toggle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n color: #6b7280;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.edit-toggle[_ngcontent-%COMP%]:hover {\n border-color: #f59e0b;\n color: #f59e0b;\n}\n\n.form-field[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n.form-field[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: block;\n font-size: 12px;\n font-weight: 500;\n color: #374151;\n margin-bottom: 4px;\n}\n\n.form-input[_ngcontent-%COMP%], \n.form-textarea[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.expiration-field[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.clear-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px dashed #d1d5db;\n border-radius: 6px;\n font-size: 13px;\n color: #6b7280;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.clear-btn[_ngcontent-%COMP%]:hover {\n border-color: #f59e0b;\n color: #f59e0b;\n}\n\n.edit-actions[_ngcontent-%COMP%] {\n margin-top: 14px;\n padding-top: 14px;\n border-top: 1px solid #e5e7eb;\n}\n\n\n\n.danger-zone[_ngcontent-%COMP%] {\n background: #fef2f2;\n border: 1px solid #fecaca;\n border-radius: 10px;\n padding: 14px 16px;\n}\n\n.danger-zone[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: 12px;\n font-weight: 600;\n color: #dc2626;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.revoke-section[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 20px;\n}\n\n.revoke-info[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n flex: 1;\n}\n\n.revoke-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: #dc2626;\n margin-top: 2px;\n}\n\n.revoke-info[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n display: block;\n color: #991b1b;\n margin-bottom: 4px;\n}\n\n.revoke-info[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n color: #7f1d1d;\n}\n\n.revoke-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: white;\n border: 1px solid #dc2626;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 600;\n color: #dc2626;\n cursor: pointer;\n transition: all 0.2s ease;\n white-space: nowrap;\n}\n\n.revoke-btn[_ngcontent-%COMP%]:hover {\n background: #dc2626;\n color: white;\n}\n\n\n\n.revoke-confirm[_ngcontent-%COMP%] {\n background: #fef2f2;\n border-radius: 8px;\n}\n\n.confirm-warning[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.confirm-warning[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n color: #dc2626;\n}\n\n.confirm-warning[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n display: block;\n color: #991b1b;\n font-size: 16px;\n margin-bottom: 4px;\n}\n\n.confirm-warning[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n color: #7f1d1d;\n}\n\n.confirm-input[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.confirm-input[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: block;\n font-size: 14px;\n font-weight: 500;\n color: #7f1d1d;\n margin-bottom: 8px;\n}\n\n.confirm-input[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: #fee2e2;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n}\n\n.confirm-input[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.confirm-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n}\n\n.confirm-revoke-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: #dc2626;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 600;\n color: white;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.confirm-revoke-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #b91c1c;\n}\n\n.confirm-revoke-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n\n.revoked-notice[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding: 20px;\n background: #f3f4f6;\n border-radius: 12px;\n}\n\n.revoked-notice[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n color: #6b7280;\n}\n\n.revoked-notice[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n display: block;\n color: #374151;\n margin-bottom: 4px;\n}\n\n.revoked-notice[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n color: #6b7280;\n}\n\n\n\n.scopes-tab[_ngcontent-%COMP%] {\n padding: 16px;\n}\n\n.scopes-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding-bottom: 16px;\n border-bottom: 1px solid #e5e7eb;\n}\n\n.scope-count[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: #374151;\n}\n\n\n\n.scope-categories[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.scope-category[_ngcontent-%COMP%] {\n background: #f9fafb;\n border: 1px solid #e5e7eb;\n border-radius: 10px;\n overflow: hidden;\n}\n\n.category-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 14px 16px;\n cursor: pointer;\n transition: background 0.2s ease;\n}\n\n.category-header[_ngcontent-%COMP%]:hover {\n background: #f3f4f6;\n}\n\n.category-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.category-left[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.category-name[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 14px;\n color: #1f2937;\n}\n\n.category-count[_ngcontent-%COMP%] {\n padding: 2px 8px;\n background: #e5e7eb;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n color: #6b7280;\n}\n\n.category-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.category-all-toggle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n color: #6b7280;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.category-all-toggle[_ngcontent-%COMP%]:hover {\n border-color: #f59e0b;\n color: #f59e0b;\n}\n\n.category-all-toggle[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n margin: 0;\n}\n\n.expand-icon[_ngcontent-%COMP%] {\n color: #9ca3af;\n font-size: 12px;\n transition: transform 0.2s ease;\n}\n\n.category-scopes[_ngcontent-%COMP%] {\n padding: 8px 16px 16px;\n border-top: 1px solid #e5e7eb;\n background: white;\n}\n\n.scope-item[_ngcontent-%COMP%] {\n padding: 10px 0;\n border-bottom: 1px solid #f3f4f6;\n}\n\n.scope-item[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.scope-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n cursor: pointer;\n}\n\n.scope-info[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.scope-name[_ngcontent-%COMP%] {\n display: block;\n font-weight: 500;\n font-size: 13px;\n color: #374151;\n font-family: monospace;\n}\n\n.scope-desc[_ngcontent-%COMP%] {\n display: block;\n font-size: 12px;\n color: #6b7280;\n margin-top: 2px;\n}\n\n\n\n.usage-tab[_ngcontent-%COMP%] {\n padding: 16px;\n}\n\n.usage-stats[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.stat-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 20px;\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n border-radius: 12px;\n text-align: center;\n}\n\n.stat-card[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n color: #f59e0b;\n margin-bottom: 12px;\n}\n\n.stat-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: #78350f;\n}\n\n.stat-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #92400e;\n margin-top: 4px;\n}\n\n\n\n.usage-logs[_ngcontent-%COMP%] {\n background: #f9fafb;\n border-radius: 10px;\n overflow: hidden;\n}\n\n.log-header[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 100px 1fr 80px 80px;\n gap: 12px;\n padding: 12px 16px;\n background: #e5e7eb;\n font-size: 11px;\n font-weight: 600;\n color: #6b7280;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.log-item[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 100px 1fr 80px 80px;\n gap: 12px;\n padding: 12px 16px;\n border-bottom: 1px solid #e5e7eb;\n font-size: 13px;\n align-items: center;\n}\n\n.log-item[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.col-time[_ngcontent-%COMP%] {\n color: #6b7280;\n}\n\n.col-endpoint[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-family: monospace;\n color: #374151;\n}\n\n.method-badge[_ngcontent-%COMP%] {\n padding: 2px 6px;\n background: #dbeafe;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n color: #1d4ed8;\n}\n\n.col-status[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n\n.col-status.status-success[_ngcontent-%COMP%] {\n color: #10b981;\n}\n\n.col-status.status-warning[_ngcontent-%COMP%] {\n color: #f59e0b;\n}\n\n.col-status.status-error[_ngcontent-%COMP%] {\n color: #ef4444;\n}\n\n.col-duration[_ngcontent-%COMP%] {\n color: #6b7280;\n text-align: right;\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 24px;\n color: #6b7280;\n text-align: center;\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.5;\n}\n\n.empty-state[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 500;\n color: #374151;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 8px 0 0 0;\n font-size: 13px;\n}\n\n\n\n\n\n\n[_nghost-%COMP%] .form-input .k-input, \n[_nghost-%COMP%] .form-textarea .k-input-inner, \n[_nghost-%COMP%] .k-datepicker .k-input {\n padding: 10px 14px;\n border-radius: 8px;\n font-size: 14px;\n border-color: #e5e7eb;\n transition: all 0.2s ease;\n}\n\n[_nghost-%COMP%] .form-input:focus-within, \n[_nghost-%COMP%] .form-textarea:focus-within, \n[_nghost-%COMP%] .k-datepicker:focus-within {\n box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.1);\n}\n\n\n\n[_nghost-%COMP%] .edit-actions .k-button {\n min-width: 120px;\n padding: 10px 20px;\n font-weight: 600;\n border-radius: 8px;\n transition: all 0.2s ease;\n}\n\n[_nghost-%COMP%] .edit-actions .k-button-solid-primary {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n border: none;\n box-shadow: 0 2px 8px rgba(245, 158, 11, 0.3);\n}\n\n[_nghost-%COMP%] .edit-actions .k-button-solid-primary:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(245, 158, 11, 0.4);\n}\n\n\n\n[_nghost-%COMP%] .scopes-header .k-button {\n min-width: 120px;\n padding: 10px 20px;\n font-weight: 600;\n border-radius: 8px;\n transition: all 0.2s ease;\n}\n\n[_nghost-%COMP%] .scopes-header .k-button-solid-primary {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n border: none;\n box-shadow: 0 2px 8px rgba(245, 158, 11, 0.3);\n}\n\n[_nghost-%COMP%] .scopes-header .k-button-solid-primary:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(245, 158, 11, 0.4);\n}\n\n\n\n.no-scopes-warning[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 16px;\n background: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%);\n border: 1px solid #fecaca;\n border-radius: 10px;\n margin-bottom: 16px;\n font-size: 13px;\n color: #991b1b;\n}\n\n.no-scopes-warning[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: #dc2626;\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.no-scopes-warning[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n display: block;\n color: #991b1b;\n font-size: 14px;\n margin-bottom: 4px;\n}\n\n.no-scopes-warning[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n line-height: 1.5;\n}"] });
|
|
1053
|
+
}
|
|
1054
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(APIKeyEditPanelComponent, [{
|
|
1055
|
+
type: Component,
|
|
1056
|
+
args: [{ selector: 'mj-api-key-edit-panel', template: "<!-- Slide-out Backdrop -->\n<div class=\"slideout-backdrop\" *ngIf=\"Visible\" (click)=\"close()\"></div>\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 <mj-loading *ngIf=\"IsLoading\" text=\"Loading key details...\"></mj-loading>\n\n <ng-container *ngIf=\"!IsLoading && APIKey\">\n <!-- Success/Error Messages -->\n <div class=\"message success\" *ngIf=\"SuccessMessage\">\n <i class=\"fa-solid fa-check-circle\"></i>\n {{SuccessMessage}}\n </div>\n <div class=\"message error\" *ngIf=\"ErrorMessage\">\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 <span class=\"tab-badge unsaved\" *ngIf=\"HasScopeChanges\">!</span>\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\n <div class=\"slideout-content\">\n <!-- Details Tab -->\n <div class=\"tab-panel\" *ngIf=\"ActiveTab === 'details'\">\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\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\n <!-- Editable Fields -->\n <div class=\"edit-section\">\n <div class=\"section-header\">\n <h4>Key Configuration</h4>\n <button class=\"edit-toggle\" *ngIf=\"APIKey.Status === 'Active'\"\n (click)=\"toggleEdit()\">\n <i class=\"fa-solid\" [class.fa-pencil]=\"!IsEditing\" [class.fa-times]=\"IsEditing\"></i>\n {{IsEditing ? 'Cancel' : 'Edit'}}\n </button>\n </div>\n\n <div class=\"form-field\">\n <label>Label</label>\n <input kendoTextBox [(ngModel)]=\"EditLabel\"\n [disabled]=\"!IsEditing\"\n class=\"form-input\" />\n </div>\n\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\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 <button class=\"clear-btn\" *ngIf=\"IsEditing && EditExpiresAt\"\n (click)=\"EditExpiresAt = null\">\n <i class=\"fa-solid fa-times\"></i>\n Never expires\n </button>\n </div>\n </div>\n\n <div class=\"edit-actions\" *ngIf=\"IsEditing\">\n <button kendoButton [themeColor]=\"'primary'\"\n [disabled]=\"IsSaving\"\n (click)=\"saveChanges()\">\n <mj-loading *ngIf=\"IsSaving\" [showText]=\"false\" size=\"small\"></mj-loading>\n <span *ngIf=\"!IsSaving\">\n <i class=\"fa-solid fa-save\"></i>\n Save Changes\n </span>\n </button>\n </div>\n </div>\n\n <!-- Revoke Section -->\n <div class=\"danger-zone\" *ngIf=\"APIKey.Status === 'Active'\">\n <h4>Danger Zone</h4>\n <div class=\"revoke-section\" *ngIf=\"!ShowRevokeConfirm\">\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 <div class=\"revoke-confirm\" *ngIf=\"ShowRevokeConfirm\">\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 <mj-loading *ngIf=\"IsRevoking\" [showText]=\"false\" size=\"small\"></mj-loading>\n <span *ngIf=\"!IsRevoking\">\n <i class=\"fa-solid fa-ban\"></i>\n Revoke Key\n </span>\n </button>\n </div>\n </div>\n </div>\n\n <!-- Revoked Notice -->\n <div class=\"revoked-notice\" *ngIf=\"APIKey.Status === 'Revoked'\">\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 </div>\n\n <!-- Scopes Tab -->\n <div class=\"tab-panel scopes-panel\" *ngIf=\"ActiveTab === 'scopes'\">\n <div class=\"scopes-header\">\n <div class=\"scopes-info\">\n <span class=\"scope-count\">{{getAssignedScopeCount()}} permissions assigned</span>\n </div>\n <button kendoButton [themeColor]=\"'primary'\"\n *ngIf=\"HasScopeChanges && APIKey.Status === 'Active'\"\n [disabled]=\"IsSaving\"\n (click)=\"saveScopeChanges()\">\n <mj-loading *ngIf=\"IsSaving\" [showText]=\"false\" size=\"small\"></mj-loading>\n <span *ngIf=\"!IsSaving\">\n <i class=\"fa-solid fa-save\"></i>\n Save Changes\n </span>\n </button>\n </div>\n\n <!-- No Scopes Warning -->\n <div class=\"no-scopes-warning\" *ngIf=\"!IsLoadingScopes && getAssignedScopeCount() === 0 && APIKey.Status === 'Active'\">\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 <mj-loading *ngIf=\"IsLoadingScopes\" text=\"Loading permissions...\"></mj-loading>\n\n <div class=\"scope-categories\" *ngIf=\"!IsLoadingScopes\">\n <div class=\"scope-category\" *ngFor=\"let category of ScopeCategories\">\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 <label class=\"category-all-toggle\"\n (click)=\"$event.stopPropagation()\"\n *ngIf=\"APIKey.Status === 'Active'\">\n <input type=\"checkbox\" kendoCheckBox\n [checked]=\"category.allSelected\"\n (change)=\"toggleCategoryAll(category)\" />\n <span>All</span>\n </label>\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\n <div class=\"category-scopes\" *ngIf=\"category.expanded\">\n <div class=\"scope-item\" *ngFor=\"let item of category.scopes\">\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 <span class=\"scope-desc\" *ngIf=\"item.scope.Description\">\n {{item.scope.Description}}\n </span>\n </div>\n </label>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Usage Tab -->\n <div class=\"tab-panel usage-panel\" *ngIf=\"ActiveTab === 'usage'\">\n <mj-loading *ngIf=\"IsLoadingLogs\" text=\"Loading usage logs...\"></mj-loading>\n\n <div class=\"usage-content\" *ngIf=\"!IsLoadingLogs\">\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\n <div class=\"usage-logs\" *ngIf=\"UsageLogs.length > 0\">\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 <div class=\"log-item\" *ngFor=\"let log of UsageLogs\">\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 </div>\n\n <div class=\"empty-state\" *ngIf=\"UsageLogs.length === 0\">\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 </div>\n </div>\n </div>\n\n <!-- Footer -->\n <div class=\"slideout-footer\">\n <button kendoButton (click)=\"close()\">Close</button>\n </div>\n </ng-container>\n</div>\n", styles: ["/* ========================================\n Slide-out Panel Styles\n ======================================== */\n\n/* Backdrop */\n.slideout-backdrop {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 100;\n animation: fadeIn 0.2s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Slide-out Panel */\n.slideout-panel {\n position: absolute;\n top: 0;\n right: 0;\n width: 520px;\n height: 100%;\n max-height: 100%;\n background: var(--card-background, #ffffff);\n box-shadow: -8px 0 32px rgba(0, 0, 0, 0.15);\n z-index: 101;\n display: flex;\n flex-direction: column;\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n transform: translateX(100%);\n overflow: hidden;\n}\n\n.slideout-panel.open {\n transform: translateX(0);\n}\n\n/* Panel Header */\n.slideout-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n border-bottom: 1px solid #fcd34d;\n flex-shrink: 0;\n}\n\n.slideout-title {\n display: flex;\n align-items: center;\n gap: 12px;\n font-weight: 600;\n font-size: 17px;\n color: #78350f;\n flex: 1;\n min-width: 0;\n}\n\n.slideout-title i {\n color: #f59e0b;\n font-size: 18px;\n flex-shrink: 0;\n}\n\n.key-status {\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n flex-shrink: 0;\n}\n\n.key-status.active {\n background: rgba(16, 185, 129, 0.2);\n color: #059669;\n}\n\n.key-status.revoked {\n background: rgba(220, 38, 38, 0.2);\n color: #dc2626;\n}\n\n.slideout-close {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgba(255, 255, 255, 0.5);\n border: none;\n border-radius: 8px;\n color: #92400e;\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.slideout-close:hover {\n background: rgba(255, 255, 255, 0.8);\n color: #78350f;\n}\n\n/* Panel Tabs */\n.slideout-tabs {\n display: flex;\n gap: 4px;\n padding: 12px 24px;\n background: #f9fafb;\n border-bottom: 1px solid #e5e7eb;\n flex-shrink: 0;\n}\n\n.slideout-tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 18px;\n background: transparent;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: #6b7280;\n cursor: pointer;\n transition: all 0.2s ease;\n position: relative;\n}\n\n.slideout-tab:hover {\n background: #e5e7eb;\n color: #374151;\n}\n\n.slideout-tab.active {\n background: #f59e0b;\n color: white;\n}\n\n.slideout-tab i {\n font-size: 14px;\n}\n\n.tab-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n background: rgba(255, 255, 255, 0.2);\n border-radius: 9px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.tab-badge.unsaved {\n background: #ef4444;\n color: white;\n}\n\n.slideout-tab:not(.active) .tab-badge {\n background: #e5e7eb;\n color: #374151;\n}\n\n/* Panel Content */\n.slideout-content {\n flex: 1;\n overflow-y: auto;\n padding: 0;\n}\n\n.tab-panel {\n padding: 20px 24px;\n}\n\n/* Panel Footer */\n.slideout-footer {\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n padding: 16px 24px;\n background: #f9fafb;\n border-top: 1px solid #e5e7eb;\n flex-shrink: 0;\n}\n\n:host ::ng-deep .slideout-footer .k-button {\n min-width: 80px;\n padding: 8px 16px;\n font-weight: 500;\n border-radius: 6px;\n}\n\n/* Messages */\n.message {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n margin: 12px 16px;\n border-radius: 8px;\n font-size: 14px;\n}\n\n.message.success {\n background: #d1fae5;\n color: #059669;\n}\n\n.message.error {\n background: #fee2e2;\n color: #dc2626;\n}\n\n/* Legacy tab styles removed - now using slideout-tabs */\n\n/* Key Info Card */\n.key-info-card {\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n border-radius: 10px;\n padding: 14px 16px;\n margin-bottom: 16px;\n}\n\n.info-header {\n margin-bottom: 12px;\n padding-bottom: 12px;\n border-bottom: 1px solid rgba(245, 158, 11, 0.3);\n}\n\n.info-row {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.info-label {\n font-size: 12px;\n font-weight: 500;\n color: #92400e;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.hash-value {\n font-family: 'Fira Code', 'Consolas', monospace;\n font-size: 13px;\n color: #78350f;\n word-break: break-all;\n background: rgba(255, 255, 255, 0.5);\n padding: 8px 12px;\n border-radius: 6px;\n}\n\n.info-grid {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 10px 16px;\n}\n\n.info-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.info-value {\n font-size: 13px;\n font-weight: 500;\n color: #78350f;\n}\n\n.info-value.never-used {\n color: #6b7280;\n font-style: italic;\n}\n\n/* Edit Section */\n.edit-section {\n background: #f9fafb;\n border-radius: 10px;\n padding: 16px;\n margin-bottom: 16px;\n}\n\n.section-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 14px;\n}\n\n.section-header h4 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #1f2937;\n}\n\n.edit-toggle {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n color: #6b7280;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.edit-toggle:hover {\n border-color: #f59e0b;\n color: #f59e0b;\n}\n\n.form-field {\n margin-bottom: 12px;\n}\n\n.form-field label {\n display: block;\n font-size: 12px;\n font-weight: 500;\n color: #374151;\n margin-bottom: 4px;\n}\n\n.form-input,\n.form-textarea {\n width: 100%;\n}\n\n.expiration-field {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.clear-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px dashed #d1d5db;\n border-radius: 6px;\n font-size: 13px;\n color: #6b7280;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.clear-btn:hover {\n border-color: #f59e0b;\n color: #f59e0b;\n}\n\n.edit-actions {\n margin-top: 14px;\n padding-top: 14px;\n border-top: 1px solid #e5e7eb;\n}\n\n/* Danger Zone */\n.danger-zone {\n background: #fef2f2;\n border: 1px solid #fecaca;\n border-radius: 10px;\n padding: 14px 16px;\n}\n\n.danger-zone h4 {\n margin: 0 0 12px 0;\n font-size: 12px;\n font-weight: 600;\n color: #dc2626;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.revoke-section {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 20px;\n}\n\n.revoke-info {\n display: flex;\n gap: 12px;\n flex: 1;\n}\n\n.revoke-info i {\n font-size: 20px;\n color: #dc2626;\n margin-top: 2px;\n}\n\n.revoke-info strong {\n display: block;\n color: #991b1b;\n margin-bottom: 4px;\n}\n\n.revoke-info p {\n margin: 0;\n font-size: 13px;\n color: #7f1d1d;\n}\n\n.revoke-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: white;\n border: 1px solid #dc2626;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 600;\n color: #dc2626;\n cursor: pointer;\n transition: all 0.2s ease;\n white-space: nowrap;\n}\n\n.revoke-btn:hover {\n background: #dc2626;\n color: white;\n}\n\n/* Revoke Confirm */\n.revoke-confirm {\n background: #fef2f2;\n border-radius: 8px;\n}\n\n.confirm-warning {\n display: flex;\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.confirm-warning i {\n font-size: 24px;\n color: #dc2626;\n}\n\n.confirm-warning strong {\n display: block;\n color: #991b1b;\n font-size: 16px;\n margin-bottom: 4px;\n}\n\n.confirm-warning p {\n margin: 0;\n font-size: 13px;\n color: #7f1d1d;\n}\n\n.confirm-input {\n margin-bottom: 16px;\n}\n\n.confirm-input label {\n display: block;\n font-size: 14px;\n font-weight: 500;\n color: #7f1d1d;\n margin-bottom: 8px;\n}\n\n.confirm-input code {\n background: #fee2e2;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n}\n\n.confirm-input input {\n width: 100%;\n}\n\n.confirm-actions {\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n}\n\n.confirm-revoke-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: #dc2626;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 600;\n color: white;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.confirm-revoke-btn:hover:not(:disabled) {\n background: #b91c1c;\n}\n\n.confirm-revoke-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Revoked Notice */\n.revoked-notice {\n display: flex;\n gap: 12px;\n padding: 20px;\n background: #f3f4f6;\n border-radius: 12px;\n}\n\n.revoked-notice i {\n font-size: 24px;\n color: #6b7280;\n}\n\n.revoked-notice strong {\n display: block;\n color: #374151;\n margin-bottom: 4px;\n}\n\n.revoked-notice p {\n margin: 0;\n font-size: 13px;\n color: #6b7280;\n}\n\n/* Scopes Tab */\n.scopes-tab {\n padding: 16px;\n}\n\n.scopes-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding-bottom: 16px;\n border-bottom: 1px solid #e5e7eb;\n}\n\n.scope-count {\n font-size: 14px;\n font-weight: 500;\n color: #374151;\n}\n\n/* Scope Categories */\n.scope-categories {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.scope-category {\n background: #f9fafb;\n border: 1px solid #e5e7eb;\n border-radius: 10px;\n overflow: hidden;\n}\n\n.category-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 14px 16px;\n cursor: pointer;\n transition: background 0.2s ease;\n}\n\n.category-header:hover {\n background: #f3f4f6;\n}\n\n.category-left {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.category-left i {\n font-size: 16px;\n}\n\n.category-name {\n font-weight: 600;\n font-size: 14px;\n color: #1f2937;\n}\n\n.category-count {\n padding: 2px 8px;\n background: #e5e7eb;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n color: #6b7280;\n}\n\n.category-right {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.category-all-toggle {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n color: #6b7280;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.category-all-toggle:hover {\n border-color: #f59e0b;\n color: #f59e0b;\n}\n\n.category-all-toggle input {\n margin: 0;\n}\n\n.expand-icon {\n color: #9ca3af;\n font-size: 12px;\n transition: transform 0.2s ease;\n}\n\n.category-scopes {\n padding: 8px 16px 16px;\n border-top: 1px solid #e5e7eb;\n background: white;\n}\n\n.scope-item {\n padding: 10px 0;\n border-bottom: 1px solid #f3f4f6;\n}\n\n.scope-item:last-child {\n border-bottom: none;\n}\n\n.scope-label {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n cursor: pointer;\n}\n\n.scope-info {\n flex: 1;\n}\n\n.scope-name {\n display: block;\n font-weight: 500;\n font-size: 13px;\n color: #374151;\n font-family: monospace;\n}\n\n.scope-desc {\n display: block;\n font-size: 12px;\n color: #6b7280;\n margin-top: 2px;\n}\n\n/* Usage Tab */\n.usage-tab {\n padding: 16px;\n}\n\n.usage-stats {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.stat-card {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 20px;\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n border-radius: 12px;\n text-align: center;\n}\n\n.stat-card i {\n font-size: 24px;\n color: #f59e0b;\n margin-bottom: 12px;\n}\n\n.stat-value {\n font-size: 24px;\n font-weight: 700;\n color: #78350f;\n}\n\n.stat-label {\n font-size: 12px;\n color: #92400e;\n margin-top: 4px;\n}\n\n/* Usage Logs */\n.usage-logs {\n background: #f9fafb;\n border-radius: 10px;\n overflow: hidden;\n}\n\n.log-header {\n display: grid;\n grid-template-columns: 100px 1fr 80px 80px;\n gap: 12px;\n padding: 12px 16px;\n background: #e5e7eb;\n font-size: 11px;\n font-weight: 600;\n color: #6b7280;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.log-item {\n display: grid;\n grid-template-columns: 100px 1fr 80px 80px;\n gap: 12px;\n padding: 12px 16px;\n border-bottom: 1px solid #e5e7eb;\n font-size: 13px;\n align-items: center;\n}\n\n.log-item:last-child {\n border-bottom: none;\n}\n\n.col-time {\n color: #6b7280;\n}\n\n.col-endpoint {\n display: flex;\n align-items: center;\n gap: 8px;\n font-family: monospace;\n color: #374151;\n}\n\n.method-badge {\n padding: 2px 6px;\n background: #dbeafe;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n color: #1d4ed8;\n}\n\n.col-status {\n font-weight: 600;\n}\n\n.col-status.status-success {\n color: #10b981;\n}\n\n.col-status.status-warning {\n color: #f59e0b;\n}\n\n.col-status.status-error {\n color: #ef4444;\n}\n\n.col-duration {\n color: #6b7280;\n text-align: right;\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 24px;\n color: #6b7280;\n text-align: center;\n}\n\n.empty-state i {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.5;\n}\n\n.empty-state span {\n font-size: 16px;\n font-weight: 500;\n color: #374151;\n}\n\n.empty-state p {\n margin: 8px 0 0 0;\n font-size: 13px;\n}\n\n/* Legacy kendo-window styles removed - now using slideout-panel */\n\n/* Input and form field styling */\n:host ::ng-deep .form-input .k-input,\n:host ::ng-deep .form-textarea .k-input-inner,\n:host ::ng-deep .k-datepicker .k-input {\n padding: 10px 14px;\n border-radius: 8px;\n font-size: 14px;\n border-color: #e5e7eb;\n transition: all 0.2s ease;\n}\n\n:host ::ng-deep .form-input:focus-within,\n:host ::ng-deep .form-textarea:focus-within,\n:host ::ng-deep .k-datepicker:focus-within {\n box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.1);\n}\n\n/* Button styling in edit actions */\n:host ::ng-deep .edit-actions .k-button {\n min-width: 120px;\n padding: 10px 20px;\n font-weight: 600;\n border-radius: 8px;\n transition: all 0.2s ease;\n}\n\n:host ::ng-deep .edit-actions .k-button-solid-primary {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n border: none;\n box-shadow: 0 2px 8px rgba(245, 158, 11, 0.3);\n}\n\n:host ::ng-deep .edit-actions .k-button-solid-primary:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(245, 158, 11, 0.4);\n}\n\n/* Scopes header button styling */\n:host ::ng-deep .scopes-header .k-button {\n min-width: 120px;\n padding: 10px 20px;\n font-weight: 600;\n border-radius: 8px;\n transition: all 0.2s ease;\n}\n\n:host ::ng-deep .scopes-header .k-button-solid-primary {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n border: none;\n box-shadow: 0 2px 8px rgba(245, 158, 11, 0.3);\n}\n\n:host ::ng-deep .scopes-header .k-button-solid-primary:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(245, 158, 11, 0.4);\n}\n\n/* No Scopes Warning */\n.no-scopes-warning {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 16px;\n background: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%);\n border: 1px solid #fecaca;\n border-radius: 10px;\n margin-bottom: 16px;\n font-size: 13px;\n color: #991b1b;\n}\n\n.no-scopes-warning i {\n font-size: 20px;\n color: #dc2626;\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.no-scopes-warning strong {\n display: block;\n color: #991b1b;\n font-size: 14px;\n margin-bottom: 4px;\n}\n\n.no-scopes-warning p {\n margin: 0;\n line-height: 1.5;\n}\n"] }]
|
|
1057
|
+
}], null, { Visible: [{
|
|
1058
|
+
type: Input
|
|
1059
|
+
}], KeyId: [{
|
|
1060
|
+
type: Input
|
|
1061
|
+
}], VisibleChange: [{
|
|
1062
|
+
type: Output
|
|
1063
|
+
}], Updated: [{
|
|
1064
|
+
type: Output
|
|
1065
|
+
}], Revoked: [{
|
|
1066
|
+
type: Output
|
|
1067
|
+
}], Closed: [{
|
|
1068
|
+
type: Output
|
|
1069
|
+
}], onEscapeKey: [{
|
|
1070
|
+
type: HostListener,
|
|
1071
|
+
args: ['document:keydown.escape']
|
|
1072
|
+
}] }); })();
|
|
1073
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(APIKeyEditPanelComponent, { className: "APIKeyEditPanelComponent", filePath: "src/APIKeys/api-key-edit-panel.component.ts", lineNumber: 47 }); })();
|
|
1074
|
+
//# sourceMappingURL=api-key-edit-panel.component.js.map
|