@memberjunction/ng-dashboards 5.22.0 → 5.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -0
- package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-configuration.component.js +364 -362
- package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.js +2 -2
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +947 -64
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +7645 -430
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +285 -6
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +2454 -277
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
- package/dist/AI/components/execution-monitoring.component.d.ts.map +1 -1
- package/dist/AI/components/execution-monitoring.component.js +191 -197
- package/dist/AI/components/execution-monitoring.component.js.map +1 -1
- package/dist/AI/components/models/model-management.component.js +9 -8
- package/dist/AI/components/models/model-management.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-management.component.js +305 -299
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/AI/components/system/system-configuration.component.js +319 -313
- package/dist/AI/components/system/system-configuration.component.js.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts +20 -2
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.js +419 -232
- package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
- package/dist/APIKeys/api-applications-panel.component.js +10 -12
- package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
- package/dist/APIKeys/api-key-create-dialog.component.js +13 -19
- package/dist/APIKeys/api-key-create-dialog.component.js.map +1 -1
- package/dist/APIKeys/api-key-edit-panel.component.js +12 -14
- package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -1
- package/dist/APIKeys/api-scopes-panel.component.js +61 -68
- package/dist/APIKeys/api-scopes-panel.component.js.map +1 -1
- package/dist/APIKeys/api-usage-panel.component.js +10 -11
- package/dist/APIKeys/api-usage-panel.component.js.map +1 -1
- package/dist/Actions/components/actions-list-view.component.js +82 -96
- package/dist/Actions/components/actions-list-view.component.js.map +1 -1
- package/dist/Actions/components/actions-overview.component.js +130 -134
- package/dist/Actions/components/actions-overview.component.js.map +1 -1
- package/dist/Actions/components/categories-list-view.component.d.ts.map +1 -1
- package/dist/Actions/components/categories-list-view.component.js +40 -46
- package/dist/Actions/components/categories-list-view.component.js.map +1 -1
- package/dist/Actions/components/code-management.component.js +2 -2
- package/dist/Actions/components/code-management.component.js.map +1 -1
- package/dist/Actions/components/entity-integration.component.js +2 -2
- package/dist/Actions/components/entity-integration.component.js.map +1 -1
- package/dist/Actions/components/execution-monitoring.component.js +127 -132
- package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
- package/dist/Actions/components/executions-list-view.component.js +2 -2
- package/dist/Actions/components/executions-list-view.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-card.component.js +11 -17
- package/dist/Actions/components/explorer/action-card.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.js +5 -11
- package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-list-item.component.js +8 -10
- package/dist/Actions/components/explorer/action-list-item.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-toolbar.component.js +112 -133
- package/dist/Actions/components/explorer/action-toolbar.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-tree-panel.component.js +63 -83
- package/dist/Actions/components/explorer/action-tree-panel.component.js.map +1 -1
- package/dist/Actions/components/explorer/new-action-panel.component.js +17 -21
- package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -1
- package/dist/Actions/components/explorer/new-category-panel.component.js +17 -21
- package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -1
- package/dist/Actions/components/scheduled-actions.component.js +2 -2
- package/dist/Actions/components/scheduled-actions.component.js.map +1 -1
- package/dist/Actions/components/security-permissions.component.js +2 -2
- package/dist/Actions/components/security-permissions.component.js.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts +13 -5
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +168 -145
- package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts +4 -5
- package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js +197 -200
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts +5 -7
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +142 -148
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/browser/component-browser.component.js +153 -166
- package/dist/ComponentStudio/components/browser/component-browser.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js +15 -20
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +16 -21
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js +18 -23
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/spec-editor.component.js +25 -30
- package/dist/ComponentStudio/components/editors/spec-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js +10 -11
- package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js +24 -35
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/text-import-dialog.component.js +15 -17
- package/dist/ComponentStudio/components/text-import-dialog.component.js.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.js +7 -6
- package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +6 -5
- package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +7 -6
- package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js +9 -9
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +17 -17
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/Home/home-dashboard.component.js +4 -4
- package/dist/Home/home-dashboard.component.js.map +1 -1
- package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
- package/dist/Integration/components/activity/activity.component.js +1 -0
- package/dist/Integration/components/activity/activity.component.js.map +1 -1
- package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
- package/dist/Integration/components/connections/connections.component.js +5 -4
- package/dist/Integration/components/connections/connections.component.js.map +1 -1
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.d.ts.map +1 -1
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +247 -259
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
- package/dist/Integration/components/overview/overview.component.d.ts.map +1 -1
- package/dist/Integration/components/overview/overview.component.js +1 -0
- package/dist/Integration/components/overview/overview.component.js.map +1 -1
- package/dist/Integration/components/pipelines/pipelines.component.d.ts.map +1 -1
- package/dist/Integration/components/pipelines/pipelines.component.js +1 -0
- package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
- package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -1
- package/dist/Integration/components/schedules/schedules.component.js +1 -0
- package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
- package/dist/Integration/components/widgets/integration-card.component.js +7 -9
- package/dist/Integration/components/widgets/integration-card.component.js.map +1 -1
- package/dist/Integration/integration.module.d.ts +6 -10
- package/dist/Integration/integration.module.d.ts.map +1 -1
- package/dist/Integration/integration.module.js +12 -20
- package/dist/Integration/integration.module.js.map +1 -1
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts +411 -0
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +4266 -0
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -0
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +140 -0
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +780 -0
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -0
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts +8 -2
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +246 -195
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts +75 -0
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +601 -0
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -0
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts +93 -12
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js +637 -107
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/index.d.ts +3 -0
- package/dist/KnowledgeHub/index.d.ts.map +1 -1
- package/dist/KnowledgeHub/index.js +3 -0
- package/dist/KnowledgeHub/index.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +9 -7
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +5 -4
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-operations-resource.component.js +10 -9
- package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
- package/dist/MCP/components/mcp-connection-dialog.component.js +141 -132
- package/dist/MCP/components/mcp-connection-dialog.component.js.map +1 -1
- package/dist/MCP/components/mcp-log-detail-panel.component.js +4 -4
- package/dist/MCP/components/mcp-log-detail-panel.component.js.map +1 -1
- package/dist/MCP/components/mcp-server-dialog.component.js +141 -128
- package/dist/MCP/components/mcp-server-dialog.component.js.map +1 -1
- package/dist/MCP/components/mcp-test-tool-dialog.component.js +210 -218
- package/dist/MCP/components/mcp-test-tool-dialog.component.js.map +1 -1
- package/dist/MCP/mcp-dashboard.component.js +2 -2
- package/dist/MCP/mcp-dashboard.component.js.map +1 -1
- package/dist/MCP/mcp.module.d.ts +6 -9
- package/dist/MCP/mcp.module.d.ts.map +1 -1
- package/dist/MCP/mcp.module.js +20 -22
- package/dist/MCP/mcp.module.js.map +1 -1
- package/dist/Scheduling/components/scheduling-activity.component.js +5 -4
- package/dist/Scheduling/components/scheduling-activity.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs.component.js +6 -5
- package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-overview.component.js +93 -92
- package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
- package/dist/Testing/testing-dashboard.component.js +9 -10
- package/dist/Testing/testing-dashboard.component.js.map +1 -1
- package/dist/__tests__/analytics-resource.test.d.ts +2 -0
- package/dist/__tests__/analytics-resource.test.d.ts.map +1 -0
- package/dist/__tests__/analytics-resource.test.js +181 -0
- package/dist/__tests__/analytics-resource.test.js.map +1 -0
- package/dist/__tests__/scheduling.test.d.ts +2 -0
- package/dist/__tests__/scheduling.test.d.ts.map +1 -0
- package/dist/__tests__/scheduling.test.js +205 -0
- package/dist/__tests__/scheduling.test.js.map +1 -0
- package/dist/actions-dashboards.module.d.ts +8 -13
- package/dist/actions-dashboards.module.d.ts.map +1 -1
- package/dist/actions-dashboards.module.js +6 -27
- package/dist/actions-dashboards.module.js.map +1 -1
- package/dist/ai-dashboards.module.d.ts +20 -20
- package/dist/ai-dashboards.module.d.ts.map +1 -1
- package/dist/ai-dashboards.module.js +43 -44
- package/dist/ai-dashboards.module.js.map +1 -1
- package/dist/communication-dashboards.module.d.ts +4 -8
- package/dist/communication-dashboards.module.d.ts.map +1 -1
- package/dist/communication-dashboards.module.js +0 -19
- package/dist/communication-dashboards.module.js.map +1 -1
- package/dist/component-studio-dashboards.module.d.ts +7 -11
- package/dist/component-studio-dashboards.module.d.ts.map +1 -1
- package/dist/component-studio-dashboards.module.js +22 -34
- package/dist/component-studio-dashboards.module.js.map +1 -1
- package/dist/core-dashboards.module.d.ts +12 -18
- package/dist/core-dashboards.module.d.ts.map +1 -1
- package/dist/core-dashboards.module.js +15 -31
- package/dist/core-dashboards.module.js.map +1 -1
- package/dist/credentials-dashboards.module.d.ts +5 -8
- package/dist/credentials-dashboards.module.d.ts.map +1 -1
- package/dist/credentials-dashboards.module.js +3 -19
- package/dist/credentials-dashboards.module.js.map +1 -1
- package/dist/data-explorer-dashboards.module.d.ts +7 -13
- package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
- package/dist/data-explorer-dashboards.module.js +0 -27
- package/dist/data-explorer-dashboards.module.js.map +1 -1
- package/dist/lists-dashboards.module.d.ts +5 -8
- package/dist/lists-dashboards.module.d.ts.map +1 -1
- package/dist/lists-dashboards.module.js +3 -19
- package/dist/lists-dashboards.module.js.map +1 -1
- package/dist/public-api.d.ts +2 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +2 -0
- package/dist/public-api.js.map +1 -1
- package/dist/scheduling-dashboards.module.d.ts +6 -10
- package/dist/scheduling-dashboards.module.d.ts.map +1 -1
- package/dist/scheduling-dashboards.module.js +3 -23
- package/dist/scheduling-dashboards.module.js.map +1 -1
- package/dist/shared/entity-field-display.d.ts +44 -0
- package/dist/shared/entity-field-display.d.ts.map +1 -0
- package/dist/shared/entity-field-display.js +118 -0
- package/dist/shared/entity-field-display.js.map +1 -0
- package/dist/testing-dashboards.module.d.ts +7 -13
- package/dist/testing-dashboards.module.d.ts.map +1 -1
- package/dist/testing-dashboards.module.js +0 -27
- package/dist/testing-dashboards.module.js.map +1 -1
- package/package.json +48 -55
|
@@ -4,11 +4,9 @@ import { GraphQLEncryptionClient } from '@memberjunction/graphql-dataprovider';
|
|
|
4
4
|
import { APIKeysEngineBase, parseAPIScopeUIConfig } from '@memberjunction/api-keys-base';
|
|
5
5
|
import * as i0 from "@angular/core";
|
|
6
6
|
import * as i1 from "@angular/forms";
|
|
7
|
-
import * as i2 from "@
|
|
8
|
-
import * as i3 from "@
|
|
9
|
-
import * as i4 from "@
|
|
10
|
-
import * as i5 from "@memberjunction/ng-shared-generic";
|
|
11
|
-
import * as i6 from "@angular/common";
|
|
7
|
+
import * as i2 from "@memberjunction/ng-ui-components";
|
|
8
|
+
import * as i3 from "@memberjunction/ng-shared-generic";
|
|
9
|
+
import * as i4 from "@angular/common";
|
|
12
10
|
function APIKeyCreateDialogComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
13
11
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
14
12
|
i0.ɵɵelementStart(0, "div", 13);
|
|
@@ -69,14 +67,14 @@ function APIKeyCreateDialogComponent_Conditional_10_Conditional_19_Template(rf,
|
|
|
69
67
|
} }
|
|
70
68
|
function APIKeyCreateDialogComponent_Conditional_10_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
71
69
|
const _r7 = i0.ɵɵgetCurrentView();
|
|
72
|
-
i0.ɵɵelementStart(0, "div", 30)(1, "
|
|
73
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
70
|
+
i0.ɵɵelementStart(0, "div", 30)(1, "mj-datepicker", 35);
|
|
71
|
+
i0.ɵɵtwoWayListener("ngModelChange", function APIKeyCreateDialogComponent_Conditional_10_Conditional_20_Template_mj_datepicker_ngModelChange_1_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.ExpiresAt, $event) || (ctx_r1.ExpiresAt = $event); return i0.ɵɵresetView($event); });
|
|
74
72
|
i0.ɵɵelementEnd()();
|
|
75
73
|
} if (rf & 2) {
|
|
76
74
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
77
75
|
i0.ɵɵadvance();
|
|
78
76
|
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.ExpiresAt);
|
|
79
|
-
i0.ɵɵproperty("
|
|
77
|
+
i0.ɵɵproperty("Min", ctx_r1.getMinDate());
|
|
80
78
|
} }
|
|
81
79
|
function APIKeyCreateDialogComponent_Conditional_10_Conditional_21_Template(rf, ctx) { if (rf & 1) {
|
|
82
80
|
i0.ɵɵelementStart(0, "div", 31);
|
|
@@ -390,8 +388,6 @@ function APIKeyCreateDialogComponent_Conditional_14_Template(rf, ctx) { if (rf &
|
|
|
390
388
|
i0.ɵɵlistener("click", function APIKeyCreateDialogComponent_Conditional_14_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.close()); });
|
|
391
389
|
i0.ɵɵtext(4, "Cancel");
|
|
392
390
|
i0.ɵɵelementEnd();
|
|
393
|
-
} if (rf & 2) {
|
|
394
|
-
i0.ɵɵproperty("themeColor", "primary");
|
|
395
391
|
} }
|
|
396
392
|
function APIKeyCreateDialogComponent_Conditional_15_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
397
393
|
i0.ɵɵelement(0, "mj-loading", 80);
|
|
@@ -418,7 +414,7 @@ function APIKeyCreateDialogComponent_Conditional_15_Template(rf, ctx) { if (rf &
|
|
|
418
414
|
i0.ɵɵelementEnd();
|
|
419
415
|
} if (rf & 2) {
|
|
420
416
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
421
|
-
i0.ɵɵproperty("
|
|
417
|
+
i0.ɵɵproperty("disabled", ctx_r1.IsCreating);
|
|
422
418
|
i0.ɵɵadvance();
|
|
423
419
|
i0.ɵɵconditional(ctx_r1.IsCreating ? 1 : -1);
|
|
424
420
|
i0.ɵɵadvance();
|
|
@@ -431,8 +427,6 @@ function APIKeyCreateDialogComponent_Conditional_16_Template(rf, ctx) { if (rf &
|
|
|
431
427
|
i0.ɵɵelement(1, "i", 82);
|
|
432
428
|
i0.ɵɵtext(2, " Done ");
|
|
433
429
|
i0.ɵɵelementEnd();
|
|
434
|
-
} if (rf & 2) {
|
|
435
|
-
i0.ɵɵproperty("themeColor", "primary");
|
|
436
430
|
} }
|
|
437
431
|
/**
|
|
438
432
|
* Dialog for creating new API keys
|
|
@@ -702,7 +696,7 @@ export class APIKeyCreateDialogComponent {
|
|
|
702
696
|
static ɵfac = function APIKeyCreateDialogComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || APIKeyCreateDialogComponent)(); };
|
|
703
697
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: APIKeyCreateDialogComponent, selectors: [["mj-api-key-create-dialog"]], hostBindings: function APIKeyCreateDialogComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
704
698
|
i0.ɵɵlistener("keydown.escape", function APIKeyCreateDialogComponent_keydown_escape_HostBindingHandler() { return ctx.onEscapeKey(); }, i0.ɵɵresolveDocument);
|
|
705
|
-
} }, inputs: { Visible: "Visible" }, outputs: { VisibleChange: "VisibleChange", Created: "Created", Closed: "Closed" }, standalone: false, decls: 17, vars: 11, consts: [[1, "slideout-backdrop"], [1, "slideout-panel"], [1, "slideout-header"], [1, "slideout-title"], [1, "fa-solid", "fa-key"], ["title", "Close (Esc)", 1, "slideout-close"], [1, "step-indicator"], [1, "slideout-content"], [1, "step-panel"], [1, "step-panel", "scopes-step"], [1, "step-panel", "success-step"], [1, "slideout-footer"], ["
|
|
699
|
+
} }, inputs: { Visible: "Visible" }, outputs: { VisibleChange: "VisibleChange", Created: "Created", Closed: "Closed" }, standalone: false, decls: 17, vars: 11, consts: [[1, "slideout-backdrop"], [1, "slideout-panel"], [1, "slideout-header"], [1, "slideout-title"], [1, "fa-solid", "fa-key"], ["title", "Close (Esc)", 1, "slideout-close"], [1, "step-indicator"], [1, "slideout-content"], [1, "step-panel"], [1, "step-panel", "scopes-step"], [1, "step-panel", "success-step"], [1, "slideout-footer"], ["mjButton", "", "variant", "primary"], [1, "slideout-backdrop", 3, "click"], ["title", "Close (Esc)", 1, "slideout-close", 3, "click"], [1, "fa-solid", "fa-times"], [1, "step"], [1, "step-number"], [1, "step-label"], [1, "step-connector"], [1, "form-section"], [1, "form-label", "required"], ["placeholder", "e.g., ElevenLabs Integration, CI/CD Pipeline", 1, "mj-input", "form-input", 3, "ngModelChange", "ngModel"], [1, "form-hint"], [1, "form-label"], ["placeholder", "Optional notes about how this key will be used...", 1, "mj-textarea", "form-textarea", 3, "ngModelChange", "ngModel", "rows"], [1, "expiration-options"], [1, "checkbox-label"], ["type", "checkbox", 1, "mj-checkbox", 3, "ngModelChange", "change", "ngModel"], [1, "preset-buttons"], [1, "custom-date"], [1, "expiration-preview"], [1, "error-message"], [1, "preset-btn", 3, "active"], [1, "preset-btn", 3, "click"], ["Format", "MMM d, yyyy", "Placeholder", "Select expiration date", 3, "ngModelChange", "ngModel", "Min"], [1, "fa-solid", "fa-calendar-check"], [1, "fa-solid", "fa-circle-exclamation"], [1, "scopes-header"], [1, "scopes-info"], [1, "scopes-count"], ["text", "Loading scopes..."], [1, "scope-categories"], [1, "scope-tip"], [1, "fa-solid", "fa-lightbulb"], [1, "no-scopes-warning"], [1, "count"], [1, "scope-category"], [1, "category-header", 3, "click"], [1, "category-left"], [1, "category-name"], [1, "category-badge"], [1, "category-right"], [1, "select-all-label", 3, "click"], ["type", "checkbox", 1, "mj-checkbox", 3, "change", "checked"], [1, "fa-solid"], [1, "category-scopes"], [1, "scope-item"], [1, "scope-label"], [1, "scope-info"], [1, "scope-name"], [1, "scope-desc"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "success-icon"], [1, "fa-solid", "fa-check-circle"], [1, "success-title"], [1, "key-display"], [1, "key-warning"], [1, "key-value"], [1, "copy-btn", 3, "click"], [1, "key-details"], [1, "detail-row"], [1, "detail-label"], [1, "detail-value"], [1, "security-note"], [1, "fa-solid", "fa-shield-check"], ["mjButton", "", "variant", "primary", 3, "click"], [1, "fa-solid", "fa-arrow-right"], ["mjButton", "", 3, "click"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], ["size", "small", 3, "showText"], [1, "fa-solid", "fa-arrow-left"], [1, "fa-solid", "fa-check"]], template: function APIKeyCreateDialogComponent_Template(rf, ctx) { if (rf & 1) {
|
|
706
700
|
i0.ɵɵconditionalCreate(0, APIKeyCreateDialogComponent_Conditional_0_Template, 1, 0, "div", 0);
|
|
707
701
|
i0.ɵɵelementStart(1, "div", 1)(2, "div", 2)(3, "div", 3);
|
|
708
702
|
i0.ɵɵelement(4, "i", 4);
|
|
@@ -718,9 +712,9 @@ export class APIKeyCreateDialogComponent {
|
|
|
718
712
|
i0.ɵɵconditionalCreate(12, APIKeyCreateDialogComponent_Conditional_12_Template, 41, 15, "div", 10);
|
|
719
713
|
i0.ɵɵelementEnd();
|
|
720
714
|
i0.ɵɵelementStart(13, "div", 11);
|
|
721
|
-
i0.ɵɵconditionalCreate(14, APIKeyCreateDialogComponent_Conditional_14_Template, 5,
|
|
722
|
-
i0.ɵɵconditionalCreate(15, APIKeyCreateDialogComponent_Conditional_15_Template, 6,
|
|
723
|
-
i0.ɵɵconditionalCreate(16, APIKeyCreateDialogComponent_Conditional_16_Template, 3,
|
|
715
|
+
i0.ɵɵconditionalCreate(14, APIKeyCreateDialogComponent_Conditional_14_Template, 5, 0);
|
|
716
|
+
i0.ɵɵconditionalCreate(15, APIKeyCreateDialogComponent_Conditional_15_Template, 6, 3);
|
|
717
|
+
i0.ɵɵconditionalCreate(16, APIKeyCreateDialogComponent_Conditional_16_Template, 3, 0, "button", 12);
|
|
724
718
|
i0.ɵɵelementEnd()();
|
|
725
719
|
} if (rf & 2) {
|
|
726
720
|
i0.ɵɵconditional(ctx.Visible ? 0 : -1);
|
|
@@ -742,11 +736,11 @@ export class APIKeyCreateDialogComponent {
|
|
|
742
736
|
i0.ɵɵconditional(ctx.Step === "scopes" ? 15 : -1);
|
|
743
737
|
i0.ɵɵadvance();
|
|
744
738
|
i0.ɵɵconditional(ctx.Step === "success" ? 16 : -1);
|
|
745
|
-
} }, dependencies: [i1.DefaultValueAccessor, i1.CheckboxControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.ButtonComponent, i3.TextBoxDirective, i3.TextAreaDirective, i3.CheckBoxDirective, i4.DatePickerComponent, i5.LoadingComponent, i6.DatePipe], 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: var(--mj-bg-overlay);\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(--mj-bg-surface);\n box-shadow: -8px 0 32px var(--mj-bg-overlay);\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: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\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: var(--mj-text-primary);\n flex: 1;\n min-width: 0;\n}\n\n.slideout-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 18px;\n flex-shrink: 0;\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: transparent;\n border: none;\n border-radius: 8px;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.slideout-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-secondary);\n}\n\n\n\n.slideout-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n}\n\n.step-panel[_ngcontent-%COMP%] {\n padding: 24px;\n}\n\n\n\n.slideout-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding: 16px 24px;\n background: var(--mj-bg-page);\n border-top: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n[_nghost-%COMP%] .slideout-footer .k-button {\n min-width: 100px;\n padding: 10px 20px;\n font-weight: 600;\n border-radius: 8px;\n transition: all 0.2s ease;\n}\n\n[_nghost-%COMP%] .slideout-footer .k-button-solid-primary {\n background: var(--mj-brand-primary);\n border: none;\n box-shadow: var(--mj-shadow-brand-sm);\n}\n\n[_nghost-%COMP%] .slideout-footer .k-button-solid-primary:hover {\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-brand-md);\n}\n\n[_nghost-%COMP%] .slideout-footer .k-button i {\n margin: 0 5px;\n}\n\n\n\n.step-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px 24px;\n background: linear-gradient(135deg, var(--mj-color-brand-100) 0%, var(--mj-color-brand-200) 100%);\n border-bottom: 1px solid var(--mj-color-accent-300);\n}\n\n.step[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n}\n\n.step-number[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-surface);\n border: 2px solid var(--mj-color-neutral-300);\n border-radius: 50%;\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.step.active[_ngcontent-%COMP%] .step-number[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.step.completed[_ngcontent-%COMP%] .step-number[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n border-color: var(--mj-status-success);\n color: var(--mj-text-inverse);\n}\n\n.step-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.step.active[_ngcontent-%COMP%] .step-label[_ngcontent-%COMP%] {\n color: var(--mj-color-brand-800);\n font-weight: 600;\n}\n\n.step-connector[_ngcontent-%COMP%] {\n width: 80px;\n height: 2px;\n background: var(--mj-color-neutral-300);\n margin: 0 16px;\n margin-bottom: 20px;\n transition: background 0.2s ease;\n}\n\n.step-connector.active[_ngcontent-%COMP%] {\n background: linear-gradient(90deg, var(--mj-status-success), var(--mj-brand-primary));\n}\n\n\n\n.dialog-content[_ngcontent-%COMP%] {\n padding: 24px;\n max-height: 400px;\n overflow-y: auto;\n}\n\n.scopes-content[_ngcontent-%COMP%] {\n max-height: 450px;\n}\n\n\n\n.form-section[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n\n.form-label[_ngcontent-%COMP%] {\n display: block;\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin-bottom: 8px;\n}\n\n.form-label.required[_ngcontent-%COMP%]::after {\n content: ' *';\n color: var(--mj-status-error);\n}\n\n.form-input[_ngcontent-%COMP%], \n.form-textarea[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.form-hint[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 6px;\n}\n\n\n\n.expiration-options[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.checkbox-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.preset-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.preset-btn[_ngcontent-%COMP%] {\n padding: 8px 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.preset-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-color-brand-50);\n}\n\n.preset-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.custom-date[_ngcontent-%COMP%] {\n margin-top: 4px;\n}\n\n.expiration-preview[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n background: var(--mj-color-success-50);\n border-radius: 8px;\n font-size: 13px;\n color: var(--mj-color-success-600);\n}\n\n.expiration-preview[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n\n\n.error-message[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n background: var(--mj-color-error-50);\n border: 1px solid var(--mj-status-error-border);\n border-radius: 8px;\n color: var(--mj-color-error-600);\n font-size: 14px;\n}\n\n\n\n.scopes-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 20px;\n}\n\n.scopes-info[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.scopes-info[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.scopes-count[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-brand-primary);\n border-radius: 20px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-inverse);\n}\n\n.scopes-count[_ngcontent-%COMP%] .count[_ngcontent-%COMP%] {\n font-weight: 700;\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: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\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: var(--mj-bg-surface-sunken);\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: var(--mj-text-primary);\n}\n\n.category-badge[_ngcontent-%COMP%] {\n padding: 2px 8px;\n background: var(--mj-border-default);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.category-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.select-all-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n}\n\n.category-right[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.category-scopes[_ngcontent-%COMP%] {\n padding: 8px 16px 16px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n\n.scope-item[_ngcontent-%COMP%] {\n padding: 10px 0;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\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: var(--mj-text-secondary);\n font-family: monospace;\n}\n\n.scope-desc[_ngcontent-%COMP%] {\n display: block;\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n}\n\n.scope-tip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n background: var(--mj-status-info-bg);\n border-radius: 8px;\n margin-top: 16px;\n font-size: 13px;\n color: var(--mj-status-info-text);\n}\n\n.scope-tip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-info);\n}\n\n.scope-tip[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: var(--mj-color-info-100);\n padding: 2px 6px;\n border-radius: 4px;\n font-family: monospace;\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, var(--mj-color-error-50) 0%, var(--mj-color-error-100) 100%);\n border: 1px solid var(--mj-status-error-border);\n border-radius: 10px;\n margin-top: 16px;\n font-size: 13px;\n color: var(--mj-status-error);\n}\n\n.no-scopes-warning[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--mj-color-error-600);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.no-scopes-warning[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n display: block;\n color: var(--mj-status-error);\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}\n\n\n\n.success-content[_ngcontent-%COMP%] {\n text-align: center;\n}\n\n.success-icon[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.success-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 64px;\n color: var(--mj-status-success);\n}\n\n.success-title[_ngcontent-%COMP%] {\n margin: 0 0 24px 0;\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n\n\n.key-display[_ngcontent-%COMP%] {\n background: var(--mj-color-neutral-800);\n border-radius: 12px;\n padding: 20px;\n margin-bottom: 24px;\n}\n\n.key-warning[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px 16px;\n background: color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n border-radius: 8px;\n margin-bottom: 16px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-color-accent-300);\n}\n\n.key-value[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 12px 16px;\n}\n\n.key-value[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n flex: 1;\n font-family: 'Fira Code', 'Consolas', monospace;\n font-size: 14px;\n color: var(--mj-status-success);\n word-break: break-all;\n text-align: left;\n}\n\n.copy-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-color-neutral-600);\n border: none;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-inverse);\n cursor: pointer;\n transition: all 0.2s ease;\n white-space: nowrap;\n}\n\n.copy-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-text-secondary);\n}\n\n.copy-btn.copied[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n}\n\n\n\n.key-details[_ngcontent-%COMP%] {\n text-align: left;\n background: var(--mj-bg-page);\n border-radius: 10px;\n padding: 16px 20px;\n margin-bottom: 20px;\n}\n\n.detail-row[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n padding: 8px 0;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.detail-row[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.detail-label[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.detail-value[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n\n\n.security-note[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n text-align: left;\n padding: 16px;\n background: linear-gradient(135deg, var(--mj-color-success-50) 0%, var(--mj-color-success-100) 100%);\n border-radius: 10px;\n font-size: 13px;\n color: var(--mj-color-success-800);\n}\n\n.security-note[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--mj-status-success);\n margin-top: 2px;\n}\n\n.security-note[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 4px;\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: var(--mj-border-default);\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: var(--mj-focus-ring);\n}"] });
|
|
739
|
+
} }, dependencies: [i1.DefaultValueAccessor, i1.CheckboxControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.MJButtonDirective, i2.MJDatepickerComponent, i3.LoadingComponent, i4.DatePipe], 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: var(--mj-bg-overlay);\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(--mj-bg-surface);\n box-shadow: -8px 0 32px var(--mj-bg-overlay);\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: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\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: var(--mj-text-primary);\n flex: 1;\n min-width: 0;\n}\n\n.slideout-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 18px;\n flex-shrink: 0;\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: transparent;\n border: none;\n border-radius: 8px;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.slideout-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-secondary);\n}\n\n\n\n.slideout-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n}\n\n.step-panel[_ngcontent-%COMP%] {\n padding: 24px;\n}\n\n\n\n.slideout-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding: 16px 24px;\n background: var(--mj-bg-page);\n border-top: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n[_nghost-%COMP%] .slideout-footer .k-button {\n min-width: 100px;\n padding: 10px 20px;\n font-weight: 600;\n border-radius: 8px;\n transition: all 0.2s ease;\n}\n\n[_nghost-%COMP%] .slideout-footer .k-button-solid-primary {\n background: var(--mj-brand-primary);\n border: none;\n box-shadow: var(--mj-shadow-brand-sm);\n}\n\n[_nghost-%COMP%] .slideout-footer .k-button-solid-primary:hover {\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-brand-md);\n}\n\n[_nghost-%COMP%] .slideout-footer .k-button i {\n margin: 0 5px;\n}\n\n\n\n.step-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px 24px;\n background: linear-gradient(135deg, var(--mj-color-brand-100) 0%, var(--mj-color-brand-200) 100%);\n border-bottom: 1px solid var(--mj-color-accent-300);\n}\n\n.step[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n}\n\n.step-number[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-surface);\n border: 2px solid var(--mj-color-neutral-300);\n border-radius: 50%;\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.step.active[_ngcontent-%COMP%] .step-number[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.step.completed[_ngcontent-%COMP%] .step-number[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n border-color: var(--mj-status-success);\n color: var(--mj-text-inverse);\n}\n\n.step-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.step.active[_ngcontent-%COMP%] .step-label[_ngcontent-%COMP%] {\n color: var(--mj-color-brand-800);\n font-weight: 600;\n}\n\n.step-connector[_ngcontent-%COMP%] {\n width: 80px;\n height: 2px;\n background: var(--mj-color-neutral-300);\n margin: 0 16px;\n margin-bottom: 20px;\n transition: background 0.2s ease;\n}\n\n.step-connector.active[_ngcontent-%COMP%] {\n background: linear-gradient(90deg, var(--mj-status-success), var(--mj-brand-primary));\n}\n\n\n\n.dialog-content[_ngcontent-%COMP%] {\n padding: 24px;\n max-height: 400px;\n overflow-y: auto;\n}\n\n.scopes-content[_ngcontent-%COMP%] {\n max-height: 450px;\n}\n\n\n\n.form-section[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n\n.form-label[_ngcontent-%COMP%] {\n display: block;\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin-bottom: 8px;\n}\n\n.form-label.required[_ngcontent-%COMP%]::after {\n content: ' *';\n color: var(--mj-status-error);\n}\n\n.form-input[_ngcontent-%COMP%], \n.form-textarea[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.form-hint[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 6px;\n}\n\n\n\n.expiration-options[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.checkbox-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.preset-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.preset-btn[_ngcontent-%COMP%] {\n padding: 8px 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.preset-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-color-brand-50);\n}\n\n.preset-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.custom-date[_ngcontent-%COMP%] {\n margin-top: 4px;\n}\n\n.expiration-preview[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n background: var(--mj-color-success-50);\n border-radius: 8px;\n font-size: 13px;\n color: var(--mj-color-success-600);\n}\n\n.expiration-preview[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n\n\n.error-message[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n background: var(--mj-color-error-50);\n border: 1px solid var(--mj-status-error-border);\n border-radius: 8px;\n color: var(--mj-color-error-600);\n font-size: 14px;\n}\n\n\n\n.scopes-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 20px;\n}\n\n.scopes-info[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.scopes-info[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.scopes-count[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-brand-primary);\n border-radius: 20px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-inverse);\n}\n\n.scopes-count[_ngcontent-%COMP%] .count[_ngcontent-%COMP%] {\n font-weight: 700;\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: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\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: var(--mj-bg-surface-sunken);\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: var(--mj-text-primary);\n}\n\n.category-badge[_ngcontent-%COMP%] {\n padding: 2px 8px;\n background: var(--mj-border-default);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.category-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.select-all-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n}\n\n.category-right[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.category-scopes[_ngcontent-%COMP%] {\n padding: 8px 16px 16px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n\n.scope-item[_ngcontent-%COMP%] {\n padding: 10px 0;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\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: var(--mj-text-secondary);\n font-family: monospace;\n}\n\n.scope-desc[_ngcontent-%COMP%] {\n display: block;\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n}\n\n.scope-tip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n background: var(--mj-status-info-bg);\n border-radius: 8px;\n margin-top: 16px;\n font-size: 13px;\n color: var(--mj-status-info-text);\n}\n\n.scope-tip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-info);\n}\n\n.scope-tip[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: var(--mj-color-info-100);\n padding: 2px 6px;\n border-radius: 4px;\n font-family: monospace;\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, var(--mj-color-error-50) 0%, var(--mj-color-error-100) 100%);\n border: 1px solid var(--mj-status-error-border);\n border-radius: 10px;\n margin-top: 16px;\n font-size: 13px;\n color: var(--mj-status-error);\n}\n\n.no-scopes-warning[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--mj-color-error-600);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.no-scopes-warning[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n display: block;\n color: var(--mj-status-error);\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}\n\n\n\n.success-content[_ngcontent-%COMP%] {\n text-align: center;\n}\n\n.success-icon[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.success-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 64px;\n color: var(--mj-status-success);\n}\n\n.success-title[_ngcontent-%COMP%] {\n margin: 0 0 24px 0;\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n\n\n.key-display[_ngcontent-%COMP%] {\n background: var(--mj-color-neutral-800);\n border-radius: 12px;\n padding: 20px;\n margin-bottom: 24px;\n}\n\n.key-warning[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px 16px;\n background: color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n border-radius: 8px;\n margin-bottom: 16px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-color-accent-300);\n}\n\n.key-value[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 12px 16px;\n}\n\n.key-value[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n flex: 1;\n font-family: 'Fira Code', 'Consolas', monospace;\n font-size: 14px;\n color: var(--mj-status-success);\n word-break: break-all;\n text-align: left;\n}\n\n.copy-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-color-neutral-600);\n border: none;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-inverse);\n cursor: pointer;\n transition: all 0.2s ease;\n white-space: nowrap;\n}\n\n.copy-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-text-secondary);\n}\n\n.copy-btn.copied[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n}\n\n\n\n.key-details[_ngcontent-%COMP%] {\n text-align: left;\n background: var(--mj-bg-page);\n border-radius: 10px;\n padding: 16px 20px;\n margin-bottom: 20px;\n}\n\n.detail-row[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n padding: 8px 0;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.detail-row[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.detail-label[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.detail-value[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n\n\n.security-note[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n text-align: left;\n padding: 16px;\n background: linear-gradient(135deg, var(--mj-color-success-50) 0%, var(--mj-color-success-100) 100%);\n border-radius: 10px;\n font-size: 13px;\n color: var(--mj-color-success-800);\n}\n\n.security-note[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--mj-status-success);\n margin-top: 2px;\n}\n\n.security-note[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 4px;\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: var(--mj-border-default);\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: var(--mj-focus-ring);\n}"] });
|
|
746
740
|
}
|
|
747
741
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(APIKeyCreateDialogComponent, [{
|
|
748
742
|
type: Component,
|
|
749
|
-
args: [{ standalone: false, selector: 'mj-api-key-create-dialog', template: "<!-- Slide-out Backdrop -->\n@if (Visible) {\n <div class=\"slideout-backdrop\" (click)=\"Step !== 'success' ? close() : null\"></div>\n}\n\n<!-- Slide-out Panel -->\n<div class=\"slideout-panel\" [class.open]=\"Visible\">\n <!-- Header -->\n <div class=\"slideout-header\">\n <div class=\"slideout-title\">\n <i class=\"fa-solid fa-key\"></i>\n <span>Generate New API Key</span>\n </div>\n @if (Step !== 'success') {\n <button class=\"slideout-close\" (click)=\"close()\" title=\"Close (Esc)\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n\n <!-- Step Indicator -->\n @if (Step !== 'success') {\n <div class=\"step-indicator\">\n <div class=\"step\" [class.active]=\"Step === 'configure'\" [class.completed]=\"Step === 'scopes'\">\n <div class=\"step-number\">1</div>\n <div class=\"step-label\">Configure</div>\n </div>\n <div class=\"step-connector\" [class.active]=\"Step === 'scopes'\"></div>\n <div class=\"step\" [class.active]=\"Step === 'scopes'\">\n <div class=\"step-number\">2</div>\n <div class=\"step-label\">Permissions</div>\n </div>\n </div>\n }\n\n <div class=\"slideout-content\">\n <!-- Configure Step -->\n @if (Step === 'configure') {\n <div class=\"step-panel\">\n <div class=\"form-section\">\n <label class=\"form-label required\">Key Label</label>\n <input kendoTextBox [(ngModel)]=\"Label\"\n placeholder=\"e.g., ElevenLabs Integration, CI/CD Pipeline\"\n class=\"form-input\" />\n <div class=\"form-hint\">A memorable name to identify this key's purpose</div>\n </div>\n <div class=\"form-section\">\n <label class=\"form-label\">Description</label>\n <textarea kendoTextArea [(ngModel)]=\"Description\"\n placeholder=\"Optional notes about how this key will be used...\"\n [rows]=\"3\"\n class=\"form-textarea\"></textarea>\n </div>\n <div class=\"form-section\">\n <label class=\"form-label\">Expiration</label>\n <div class=\"expiration-options\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" kendoCheckBox\n [(ngModel)]=\"NeverExpires\"\n (change)=\"onNeverExpiresChange()\" />\n <span>Never expires</span>\n </label>\n @if (!NeverExpires) {\n <div class=\"preset-buttons\">\n @for (preset of ExpirationPresets; track preset) {\n <button\n class=\"preset-btn\"\n [class.active]=\"SelectedPreset === preset\"\n (click)=\"onPresetSelect(preset)\">\n {{preset.label}}\n </button>\n }\n </div>\n }\n @if (!NeverExpires && SelectedPreset?.days === -1) {\n <div class=\"custom-date\">\n <kendo-datepicker [(ngModel)]=\"ExpiresAt\"\n [min]=\"getMinDate()\"\n format=\"MMM d, yyyy\"\n placeholder=\"Select expiration date\">\n </kendo-datepicker>\n </div>\n }\n @if (!NeverExpires && ExpiresAt) {\n <div class=\"expiration-preview\">\n <i class=\"fa-solid fa-calendar-check\"></i>\n <span>Key will expire on {{ExpiresAt | date:'MMMM d, yyyy'}}</span>\n </div>\n }\n </div>\n </div>\n @if (Error) {\n <div class=\"error-message\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{Error}}\n </div>\n }\n </div>\n }\n\n <!-- Scopes Step -->\n @if (Step === 'scopes') {\n <div class=\"step-panel scopes-step\">\n <div class=\"scopes-header\">\n <div class=\"scopes-info\">\n <h4>Select Permission Scopes</h4>\n <p>Choose what this API key can access. You can always modify this later.</p>\n </div>\n @if (getSelectedScopeCount() > 0) {\n <div class=\"scopes-count\">\n <span class=\"count\">{{getSelectedScopeCount()}}</span> selected\n </div>\n }\n </div>\n @if (IsLoadingScopes) {\n <mj-loading text=\"Loading scopes...\"></mj-loading>\n }\n @if (!IsLoadingScopes) {\n <div class=\"scope-categories\">\n @for (category of ScopeCategories; track category) {\n <div class=\"scope-category\">\n <div class=\"category-header\" (click)=\"toggleCategory(category)\">\n <div class=\"category-left\">\n <i [class]=\"category.icon\" [style.color]=\"category.color\"></i>\n <span class=\"category-name\">{{category.name}}</span>\n <span class=\"category-badge\">{{category.scopes.length}}</span>\n </div>\n <div class=\"category-right\">\n <label class=\"select-all-label\" (click)=\"$event.stopPropagation()\">\n <input type=\"checkbox\" kendoCheckBox\n [checked]=\"category.allSelected\"\n (change)=\"toggleCategoryAll(category)\" />\n <span>All</span>\n </label>\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!category.expanded\"\n [class.fa-chevron-up]=\"category.expanded\"></i>\n </div>\n </div>\n @if (category.expanded) {\n <div class=\"category-scopes\">\n @for (item of category.scopes; track item) {\n <div class=\"scope-item\">\n <label class=\"scope-label\">\n <input type=\"checkbox\" kendoCheckBox\n [(ngModel)]=\"item.selected\"\n (change)=\"updateCategoryState(category)\" />\n <div class=\"scope-info\">\n <span class=\"scope-name\">{{item.scope.Name}}</span>\n @if (item.scope.Description) {\n <span class=\"scope-desc\">\n {{item.scope.Description}}\n </span>\n }\n </div>\n </label>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n <div class=\"scope-tip\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n <span>Tip: Use wildcards like <code>entities:*</code> for broad access within a category</span>\n </div>\n <!-- No Scopes Warning -->\n @if (!IsLoadingScopes && getSelectedScopeCount() === 0) {\n <div class=\"no-scopes-warning\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <div>\n <strong>Warning: No permissions selected</strong>\n <p>API keys without any assigned scopes will have <strong>no permissions</strong> and cannot perform any operations. This key will be rejected by all API endpoints until scopes are assigned.</p>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Success Step -->\n @if (Step === 'success') {\n <div class=\"step-panel success-step\">\n <div class=\"success-icon\">\n <i class=\"fa-solid fa-check-circle\"></i>\n </div>\n <h3 class=\"success-title\">API Key Created Successfully!</h3>\n <div class=\"key-display\">\n <div class=\"key-warning\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span>Copy this key now. It won't be shown again!</span>\n </div>\n <div class=\"key-value\">\n <code>{{RawApiKey}}</code>\n <button class=\"copy-btn\" (click)=\"copyKey()\" [class.copied]=\"KeyCopied\">\n <i class=\"fa-solid\" [class.fa-copy]=\"!KeyCopied\" [class.fa-check]=\"KeyCopied\"></i>\n <span>{{KeyCopied ? 'Copied!' : 'Copy'}}</span>\n </button>\n </div>\n </div>\n <div class=\"key-details\">\n <div class=\"detail-row\">\n <span class=\"detail-label\">Label:</span>\n <span class=\"detail-value\">{{Label}}</span>\n </div>\n @if (Description) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Description:</span>\n <span class=\"detail-value\">{{Description}}</span>\n </div>\n }\n <div class=\"detail-row\">\n <span class=\"detail-label\">Expires:</span>\n <span class=\"detail-value\">\n {{NeverExpires ? 'Never' : (ExpiresAt | date:'MMMM d, yyyy')}}\n </span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Scopes:</span>\n <span class=\"detail-value\">{{getSelectedScopeCount()}} permissions</span>\n </div>\n </div>\n <div class=\"security-note\">\n <i class=\"fa-solid fa-shield-check\"></i>\n <div>\n <strong>Security Note:</strong>\n Store this key securely. We only store a hash - the original key cannot be recovered.\n </div>\n </div>\n </div>\n }\n </div>\n\n <!-- Footer -->\n <div class=\"slideout-footer\">\n @if (Step === 'configure') {\n <button kendoButton [themeColor]=\"'primary'\" (click)=\"goToScopes()\">\n Next: Permissions\n <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n <button kendoButton (click)=\"close()\">Cancel</button>\n }\n\n @if (Step === 'scopes') {\n <button kendoButton [themeColor]=\"'primary'\"\n [disabled]=\"IsCreating\"\n (click)=\"createKey()\">\n @if (IsCreating) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n }\n @if (!IsCreating) {\n <span>\n <i class=\"fa-solid fa-key\"></i>\n Generate Key\n </span>\n }\n </button>\n <button kendoButton (click)=\"goBack()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n Back\n </button>\n }\n\n @if (Step === 'success') {\n <button kendoButton [themeColor]=\"'primary'\" (click)=\"close()\">\n <i class=\"fa-solid fa-check\"></i>\n Done\n </button>\n }\n </div>\n</div>\n", 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: var(--mj-bg-overlay);\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(--mj-bg-surface);\n box-shadow: -8px 0 32px var(--mj-bg-overlay);\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: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\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: var(--mj-text-primary);\n flex: 1;\n min-width: 0;\n}\n\n.slideout-title i {\n color: var(--mj-brand-primary);\n font-size: 18px;\n flex-shrink: 0;\n}\n\n.slideout-close {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n border-radius: 8px;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.slideout-close:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-secondary);\n}\n\n/* Panel Content */\n.slideout-content {\n flex: 1;\n overflow-y: auto;\n}\n\n.step-panel {\n padding: 24px;\n}\n\n/* Panel Footer */\n.slideout-footer {\n display: flex;\n gap: 12px;\n padding: 16px 24px;\n background: var(--mj-bg-page);\n border-top: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n:host ::ng-deep .slideout-footer .k-button {\n min-width: 100px;\n padding: 10px 20px;\n font-weight: 600;\n border-radius: 8px;\n transition: all 0.2s ease;\n}\n\n:host ::ng-deep .slideout-footer .k-button-solid-primary {\n background: var(--mj-brand-primary);\n border: none;\n box-shadow: var(--mj-shadow-brand-sm);\n}\n\n:host ::ng-deep .slideout-footer .k-button-solid-primary:hover {\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-brand-md);\n}\n\n:host ::ng-deep .slideout-footer .k-button i {\n margin: 0 5px;\n}\n\n/* Step Indicator */\n.step-indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px 24px;\n background: linear-gradient(135deg, var(--mj-color-brand-100) 0%, var(--mj-color-brand-200) 100%);\n border-bottom: 1px solid var(--mj-color-accent-300);\n}\n\n.step {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n}\n\n.step-number {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-surface);\n border: 2px solid var(--mj-color-neutral-300);\n border-radius: 50%;\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.step.active .step-number {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.step.completed .step-number {\n background: var(--mj-status-success);\n border-color: var(--mj-status-success);\n color: var(--mj-text-inverse);\n}\n\n.step-label {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.step.active .step-label {\n color: var(--mj-color-brand-800);\n font-weight: 600;\n}\n\n.step-connector {\n width: 80px;\n height: 2px;\n background: var(--mj-color-neutral-300);\n margin: 0 16px;\n margin-bottom: 20px;\n transition: background 0.2s ease;\n}\n\n.step-connector.active {\n background: linear-gradient(90deg, var(--mj-status-success), var(--mj-brand-primary));\n}\n\n/* Dialog Content */\n.dialog-content {\n padding: 24px;\n max-height: 400px;\n overflow-y: auto;\n}\n\n.scopes-content {\n max-height: 450px;\n}\n\n/* Form Sections */\n.form-section {\n margin-bottom: 24px;\n}\n\n.form-label {\n display: block;\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin-bottom: 8px;\n}\n\n.form-label.required::after {\n content: ' *';\n color: var(--mj-status-error);\n}\n\n.form-input,\n.form-textarea {\n width: 100%;\n}\n\n.form-hint {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 6px;\n}\n\n/* Expiration Options */\n.expiration-options {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.checkbox-label {\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.preset-buttons {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.preset-btn {\n padding: 8px 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.preset-btn:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-color-brand-50);\n}\n\n.preset-btn.active {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.custom-date {\n margin-top: 4px;\n}\n\n.expiration-preview {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n background: var(--mj-color-success-50);\n border-radius: 8px;\n font-size: 13px;\n color: var(--mj-color-success-600);\n}\n\n.expiration-preview i {\n color: var(--mj-status-success);\n}\n\n/* Error Message */\n.error-message {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n background: var(--mj-color-error-50);\n border: 1px solid var(--mj-status-error-border);\n border-radius: 8px;\n color: var(--mj-color-error-600);\n font-size: 14px;\n}\n\n/* Scopes */\n.scopes-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 20px;\n}\n\n.scopes-info h4 {\n margin: 0 0 4px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.scopes-info p {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.scopes-count {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-brand-primary);\n border-radius: 20px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-inverse);\n}\n\n.scopes-count .count {\n font-weight: 700;\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: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\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: var(--mj-bg-surface-sunken);\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: var(--mj-text-primary);\n}\n\n.category-badge {\n padding: 2px 8px;\n background: var(--mj-border-default);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.category-right {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.select-all-label {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n}\n\n.category-right > i {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.category-scopes {\n padding: 8px 16px 16px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n\n.scope-item {\n padding: 10px 0;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\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: var(--mj-text-secondary);\n font-family: monospace;\n}\n\n.scope-desc {\n display: block;\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n}\n\n.scope-tip {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n background: var(--mj-status-info-bg);\n border-radius: 8px;\n margin-top: 16px;\n font-size: 13px;\n color: var(--mj-status-info-text);\n}\n\n.scope-tip i {\n color: var(--mj-status-info);\n}\n\n.scope-tip code {\n background: var(--mj-color-info-100);\n padding: 2px 6px;\n border-radius: 4px;\n font-family: monospace;\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, var(--mj-color-error-50) 0%, var(--mj-color-error-100) 100%);\n border: 1px solid var(--mj-status-error-border);\n border-radius: 10px;\n margin-top: 16px;\n font-size: 13px;\n color: var(--mj-status-error);\n}\n\n.no-scopes-warning i {\n font-size: 20px;\n color: var(--mj-color-error-600);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.no-scopes-warning strong {\n display: block;\n color: var(--mj-status-error);\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\n/* Success Content */\n.success-content {\n text-align: center;\n}\n\n.success-icon {\n margin-bottom: 16px;\n}\n\n.success-icon i {\n font-size: 64px;\n color: var(--mj-status-success);\n}\n\n.success-title {\n margin: 0 0 24px 0;\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n/* Key Display */\n.key-display {\n background: var(--mj-color-neutral-800);\n border-radius: 12px;\n padding: 20px;\n margin-bottom: 24px;\n}\n\n.key-warning {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px 16px;\n background: color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n border-radius: 8px;\n margin-bottom: 16px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-color-accent-300);\n}\n\n.key-value {\n display: flex;\n align-items: center;\n gap: 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 12px 16px;\n}\n\n.key-value code {\n flex: 1;\n font-family: 'Fira Code', 'Consolas', monospace;\n font-size: 14px;\n color: var(--mj-status-success);\n word-break: break-all;\n text-align: left;\n}\n\n.copy-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-color-neutral-600);\n border: none;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-inverse);\n cursor: pointer;\n transition: all 0.2s ease;\n white-space: nowrap;\n}\n\n.copy-btn:hover {\n background: var(--mj-text-secondary);\n}\n\n.copy-btn.copied {\n background: var(--mj-status-success);\n}\n\n/* Key Details */\n.key-details {\n text-align: left;\n background: var(--mj-bg-page);\n border-radius: 10px;\n padding: 16px 20px;\n margin-bottom: 20px;\n}\n\n.detail-row {\n display: flex;\n justify-content: space-between;\n padding: 8px 0;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.detail-row:last-child {\n border-bottom: none;\n}\n\n.detail-label {\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.detail-value {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n/* Security Note */\n.security-note {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n text-align: left;\n padding: 16px;\n background: linear-gradient(135deg, var(--mj-color-success-50) 0%, var(--mj-color-success-100) 100%);\n border-radius: 10px;\n font-size: 13px;\n color: var(--mj-color-success-800);\n}\n\n.security-note i {\n font-size: 20px;\n color: var(--mj-status-success);\n margin-top: 2px;\n}\n\n.security-note strong {\n display: block;\n margin-bottom: 4px;\n}\n\n/* Form input 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: var(--mj-border-default);\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: var(--mj-focus-ring);\n}\n"] }]
|
|
743
|
+
args: [{ standalone: false, selector: 'mj-api-key-create-dialog', template: "<!-- Slide-out Backdrop -->\n@if (Visible) {\n <div class=\"slideout-backdrop\" (click)=\"Step !== 'success' ? close() : null\"></div>\n}\n\n<!-- Slide-out Panel -->\n<div class=\"slideout-panel\" [class.open]=\"Visible\">\n <!-- Header -->\n <div class=\"slideout-header\">\n <div class=\"slideout-title\">\n <i class=\"fa-solid fa-key\"></i>\n <span>Generate New API Key</span>\n </div>\n @if (Step !== 'success') {\n <button class=\"slideout-close\" (click)=\"close()\" title=\"Close (Esc)\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n\n <!-- Step Indicator -->\n @if (Step !== 'success') {\n <div class=\"step-indicator\">\n <div class=\"step\" [class.active]=\"Step === 'configure'\" [class.completed]=\"Step === 'scopes'\">\n <div class=\"step-number\">1</div>\n <div class=\"step-label\">Configure</div>\n </div>\n <div class=\"step-connector\" [class.active]=\"Step === 'scopes'\"></div>\n <div class=\"step\" [class.active]=\"Step === 'scopes'\">\n <div class=\"step-number\">2</div>\n <div class=\"step-label\">Permissions</div>\n </div>\n </div>\n }\n\n <div class=\"slideout-content\">\n <!-- Configure Step -->\n @if (Step === 'configure') {\n <div class=\"step-panel\">\n <div class=\"form-section\">\n <label class=\"form-label required\">Key Label</label>\n <input class=\"mj-input form-input\" [(ngModel)]=\"Label\"\n placeholder=\"e.g., ElevenLabs Integration, CI/CD Pipeline\" />\n <div class=\"form-hint\">A memorable name to identify this key's purpose</div>\n </div>\n <div class=\"form-section\">\n <label class=\"form-label\">Description</label>\n <textarea class=\"mj-textarea form-textarea\" [(ngModel)]=\"Description\"\n placeholder=\"Optional notes about how this key will be used...\"\n [rows]=\"3\"></textarea>\n </div>\n <div class=\"form-section\">\n <label class=\"form-label\">Expiration</label>\n <div class=\"expiration-options\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" class=\"mj-checkbox\"\n [(ngModel)]=\"NeverExpires\"\n (change)=\"onNeverExpiresChange()\" />\n <span>Never expires</span>\n </label>\n @if (!NeverExpires) {\n <div class=\"preset-buttons\">\n @for (preset of ExpirationPresets; track preset) {\n <button\n class=\"preset-btn\"\n [class.active]=\"SelectedPreset === preset\"\n (click)=\"onPresetSelect(preset)\">\n {{preset.label}}\n </button>\n }\n </div>\n }\n @if (!NeverExpires && SelectedPreset?.days === -1) {\n <div class=\"custom-date\">\n <mj-datepicker [(ngModel)]=\"ExpiresAt\"\n [Min]=\"getMinDate()\"\n Format=\"MMM d, yyyy\"\n Placeholder=\"Select expiration date\">\n </mj-datepicker>\n </div>\n }\n @if (!NeverExpires && ExpiresAt) {\n <div class=\"expiration-preview\">\n <i class=\"fa-solid fa-calendar-check\"></i>\n <span>Key will expire on {{ExpiresAt | date:'MMMM d, yyyy'}}</span>\n </div>\n }\n </div>\n </div>\n @if (Error) {\n <div class=\"error-message\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{Error}}\n </div>\n }\n </div>\n }\n\n <!-- Scopes Step -->\n @if (Step === 'scopes') {\n <div class=\"step-panel scopes-step\">\n <div class=\"scopes-header\">\n <div class=\"scopes-info\">\n <h4>Select Permission Scopes</h4>\n <p>Choose what this API key can access. You can always modify this later.</p>\n </div>\n @if (getSelectedScopeCount() > 0) {\n <div class=\"scopes-count\">\n <span class=\"count\">{{getSelectedScopeCount()}}</span> selected\n </div>\n }\n </div>\n @if (IsLoadingScopes) {\n <mj-loading text=\"Loading scopes...\"></mj-loading>\n }\n @if (!IsLoadingScopes) {\n <div class=\"scope-categories\">\n @for (category of ScopeCategories; track category) {\n <div class=\"scope-category\">\n <div class=\"category-header\" (click)=\"toggleCategory(category)\">\n <div class=\"category-left\">\n <i [class]=\"category.icon\" [style.color]=\"category.color\"></i>\n <span class=\"category-name\">{{category.name}}</span>\n <span class=\"category-badge\">{{category.scopes.length}}</span>\n </div>\n <div class=\"category-right\">\n <label class=\"select-all-label\" (click)=\"$event.stopPropagation()\">\n <input type=\"checkbox\" class=\"mj-checkbox\"\n [checked]=\"category.allSelected\"\n (change)=\"toggleCategoryAll(category)\" />\n <span>All</span>\n </label>\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!category.expanded\"\n [class.fa-chevron-up]=\"category.expanded\"></i>\n </div>\n </div>\n @if (category.expanded) {\n <div class=\"category-scopes\">\n @for (item of category.scopes; track item) {\n <div class=\"scope-item\">\n <label class=\"scope-label\">\n <input type=\"checkbox\" class=\"mj-checkbox\"\n [(ngModel)]=\"item.selected\"\n (change)=\"updateCategoryState(category)\" />\n <div class=\"scope-info\">\n <span class=\"scope-name\">{{item.scope.Name}}</span>\n @if (item.scope.Description) {\n <span class=\"scope-desc\">\n {{item.scope.Description}}\n </span>\n }\n </div>\n </label>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n <div class=\"scope-tip\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n <span>Tip: Use wildcards like <code>entities:*</code> for broad access within a category</span>\n </div>\n <!-- No Scopes Warning -->\n @if (!IsLoadingScopes && getSelectedScopeCount() === 0) {\n <div class=\"no-scopes-warning\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <div>\n <strong>Warning: No permissions selected</strong>\n <p>API keys without any assigned scopes will have <strong>no permissions</strong> and cannot perform any operations. This key will be rejected by all API endpoints until scopes are assigned.</p>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Success Step -->\n @if (Step === 'success') {\n <div class=\"step-panel success-step\">\n <div class=\"success-icon\">\n <i class=\"fa-solid fa-check-circle\"></i>\n </div>\n <h3 class=\"success-title\">API Key Created Successfully!</h3>\n <div class=\"key-display\">\n <div class=\"key-warning\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span>Copy this key now. It won't be shown again!</span>\n </div>\n <div class=\"key-value\">\n <code>{{RawApiKey}}</code>\n <button class=\"copy-btn\" (click)=\"copyKey()\" [class.copied]=\"KeyCopied\">\n <i class=\"fa-solid\" [class.fa-copy]=\"!KeyCopied\" [class.fa-check]=\"KeyCopied\"></i>\n <span>{{KeyCopied ? 'Copied!' : 'Copy'}}</span>\n </button>\n </div>\n </div>\n <div class=\"key-details\">\n <div class=\"detail-row\">\n <span class=\"detail-label\">Label:</span>\n <span class=\"detail-value\">{{Label}}</span>\n </div>\n @if (Description) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Description:</span>\n <span class=\"detail-value\">{{Description}}</span>\n </div>\n }\n <div class=\"detail-row\">\n <span class=\"detail-label\">Expires:</span>\n <span class=\"detail-value\">\n {{NeverExpires ? 'Never' : (ExpiresAt | date:'MMMM d, yyyy')}}\n </span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Scopes:</span>\n <span class=\"detail-value\">{{getSelectedScopeCount()}} permissions</span>\n </div>\n </div>\n <div class=\"security-note\">\n <i class=\"fa-solid fa-shield-check\"></i>\n <div>\n <strong>Security Note:</strong>\n Store this key securely. We only store a hash - the original key cannot be recovered.\n </div>\n </div>\n </div>\n }\n </div>\n\n <!-- Footer -->\n <div class=\"slideout-footer\">\n @if (Step === 'configure') {\n <button mjButton variant=\"primary\" (click)=\"goToScopes()\">\n Next: Permissions\n <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n <button mjButton (click)=\"close()\">Cancel</button>\n }\n\n @if (Step === 'scopes') {\n <button mjButton variant=\"primary\"\n [disabled]=\"IsCreating\"\n (click)=\"createKey()\">\n @if (IsCreating) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n }\n @if (!IsCreating) {\n <span>\n <i class=\"fa-solid fa-key\"></i>\n Generate Key\n </span>\n }\n </button>\n <button mjButton (click)=\"goBack()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n Back\n </button>\n }\n\n @if (Step === 'success') {\n <button mjButton variant=\"primary\" (click)=\"close()\">\n <i class=\"fa-solid fa-check\"></i>\n Done\n </button>\n }\n </div>\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: var(--mj-bg-overlay);\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(--mj-bg-surface);\n box-shadow: -8px 0 32px var(--mj-bg-overlay);\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: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\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: var(--mj-text-primary);\n flex: 1;\n min-width: 0;\n}\n\n.slideout-title i {\n color: var(--mj-brand-primary);\n font-size: 18px;\n flex-shrink: 0;\n}\n\n.slideout-close {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n border-radius: 8px;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.slideout-close:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-secondary);\n}\n\n/* Panel Content */\n.slideout-content {\n flex: 1;\n overflow-y: auto;\n}\n\n.step-panel {\n padding: 24px;\n}\n\n/* Panel Footer */\n.slideout-footer {\n display: flex;\n gap: 12px;\n padding: 16px 24px;\n background: var(--mj-bg-page);\n border-top: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n:host ::ng-deep .slideout-footer .k-button {\n min-width: 100px;\n padding: 10px 20px;\n font-weight: 600;\n border-radius: 8px;\n transition: all 0.2s ease;\n}\n\n:host ::ng-deep .slideout-footer .k-button-solid-primary {\n background: var(--mj-brand-primary);\n border: none;\n box-shadow: var(--mj-shadow-brand-sm);\n}\n\n:host ::ng-deep .slideout-footer .k-button-solid-primary:hover {\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-brand-md);\n}\n\n:host ::ng-deep .slideout-footer .k-button i {\n margin: 0 5px;\n}\n\n/* Step Indicator */\n.step-indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px 24px;\n background: linear-gradient(135deg, var(--mj-color-brand-100) 0%, var(--mj-color-brand-200) 100%);\n border-bottom: 1px solid var(--mj-color-accent-300);\n}\n\n.step {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n}\n\n.step-number {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-surface);\n border: 2px solid var(--mj-color-neutral-300);\n border-radius: 50%;\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.step.active .step-number {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.step.completed .step-number {\n background: var(--mj-status-success);\n border-color: var(--mj-status-success);\n color: var(--mj-text-inverse);\n}\n\n.step-label {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.step.active .step-label {\n color: var(--mj-color-brand-800);\n font-weight: 600;\n}\n\n.step-connector {\n width: 80px;\n height: 2px;\n background: var(--mj-color-neutral-300);\n margin: 0 16px;\n margin-bottom: 20px;\n transition: background 0.2s ease;\n}\n\n.step-connector.active {\n background: linear-gradient(90deg, var(--mj-status-success), var(--mj-brand-primary));\n}\n\n/* Dialog Content */\n.dialog-content {\n padding: 24px;\n max-height: 400px;\n overflow-y: auto;\n}\n\n.scopes-content {\n max-height: 450px;\n}\n\n/* Form Sections */\n.form-section {\n margin-bottom: 24px;\n}\n\n.form-label {\n display: block;\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin-bottom: 8px;\n}\n\n.form-label.required::after {\n content: ' *';\n color: var(--mj-status-error);\n}\n\n.form-input,\n.form-textarea {\n width: 100%;\n}\n\n.form-hint {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 6px;\n}\n\n/* Expiration Options */\n.expiration-options {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.checkbox-label {\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.preset-buttons {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.preset-btn {\n padding: 8px 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.preset-btn:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-color-brand-50);\n}\n\n.preset-btn.active {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.custom-date {\n margin-top: 4px;\n}\n\n.expiration-preview {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n background: var(--mj-color-success-50);\n border-radius: 8px;\n font-size: 13px;\n color: var(--mj-color-success-600);\n}\n\n.expiration-preview i {\n color: var(--mj-status-success);\n}\n\n/* Error Message */\n.error-message {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n background: var(--mj-color-error-50);\n border: 1px solid var(--mj-status-error-border);\n border-radius: 8px;\n color: var(--mj-color-error-600);\n font-size: 14px;\n}\n\n/* Scopes */\n.scopes-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 20px;\n}\n\n.scopes-info h4 {\n margin: 0 0 4px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.scopes-info p {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.scopes-count {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-brand-primary);\n border-radius: 20px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-inverse);\n}\n\n.scopes-count .count {\n font-weight: 700;\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: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\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: var(--mj-bg-surface-sunken);\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: var(--mj-text-primary);\n}\n\n.category-badge {\n padding: 2px 8px;\n background: var(--mj-border-default);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.category-right {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.select-all-label {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n}\n\n.category-right > i {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.category-scopes {\n padding: 8px 16px 16px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n\n.scope-item {\n padding: 10px 0;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\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: var(--mj-text-secondary);\n font-family: monospace;\n}\n\n.scope-desc {\n display: block;\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n}\n\n.scope-tip {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n background: var(--mj-status-info-bg);\n border-radius: 8px;\n margin-top: 16px;\n font-size: 13px;\n color: var(--mj-status-info-text);\n}\n\n.scope-tip i {\n color: var(--mj-status-info);\n}\n\n.scope-tip code {\n background: var(--mj-color-info-100);\n padding: 2px 6px;\n border-radius: 4px;\n font-family: monospace;\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, var(--mj-color-error-50) 0%, var(--mj-color-error-100) 100%);\n border: 1px solid var(--mj-status-error-border);\n border-radius: 10px;\n margin-top: 16px;\n font-size: 13px;\n color: var(--mj-status-error);\n}\n\n.no-scopes-warning i {\n font-size: 20px;\n color: var(--mj-color-error-600);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.no-scopes-warning strong {\n display: block;\n color: var(--mj-status-error);\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\n/* Success Content */\n.success-content {\n text-align: center;\n}\n\n.success-icon {\n margin-bottom: 16px;\n}\n\n.success-icon i {\n font-size: 64px;\n color: var(--mj-status-success);\n}\n\n.success-title {\n margin: 0 0 24px 0;\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n/* Key Display */\n.key-display {\n background: var(--mj-color-neutral-800);\n border-radius: 12px;\n padding: 20px;\n margin-bottom: 24px;\n}\n\n.key-warning {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px 16px;\n background: color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n border-radius: 8px;\n margin-bottom: 16px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-color-accent-300);\n}\n\n.key-value {\n display: flex;\n align-items: center;\n gap: 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 12px 16px;\n}\n\n.key-value code {\n flex: 1;\n font-family: 'Fira Code', 'Consolas', monospace;\n font-size: 14px;\n color: var(--mj-status-success);\n word-break: break-all;\n text-align: left;\n}\n\n.copy-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-color-neutral-600);\n border: none;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-inverse);\n cursor: pointer;\n transition: all 0.2s ease;\n white-space: nowrap;\n}\n\n.copy-btn:hover {\n background: var(--mj-text-secondary);\n}\n\n.copy-btn.copied {\n background: var(--mj-status-success);\n}\n\n/* Key Details */\n.key-details {\n text-align: left;\n background: var(--mj-bg-page);\n border-radius: 10px;\n padding: 16px 20px;\n margin-bottom: 20px;\n}\n\n.detail-row {\n display: flex;\n justify-content: space-between;\n padding: 8px 0;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.detail-row:last-child {\n border-bottom: none;\n}\n\n.detail-label {\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.detail-value {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n/* Security Note */\n.security-note {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n text-align: left;\n padding: 16px;\n background: linear-gradient(135deg, var(--mj-color-success-50) 0%, var(--mj-color-success-100) 100%);\n border-radius: 10px;\n font-size: 13px;\n color: var(--mj-color-success-800);\n}\n\n.security-note i {\n font-size: 20px;\n color: var(--mj-status-success);\n margin-top: 2px;\n}\n\n.security-note strong {\n display: block;\n margin-bottom: 4px;\n}\n\n/* Form input 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: var(--mj-border-default);\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: var(--mj-focus-ring);\n}\n"] }]
|
|
750
744
|
}], null, { Visible: [{
|
|
751
745
|
type: Input
|
|
752
746
|
}], VisibleChange: [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-key-create-dialog.component.js","sourceRoot":"","sources":["../../src/APIKeys/api-key-create-dialog.component.ts","../../src/APIKeys/api-key-create-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, EventEmitter, HostListener, Input, OnInit, Output } from '@angular/core';\nimport { Metadata } from '@memberjunction/core';\nimport { MJAPIScopeEntity } from '@memberjunction/core-entities';\nimport { GraphQLDataProvider, GraphQLEncryptionClient } from '@memberjunction/graphql-dataprovider';\nimport { APIKeysEngineBase, parseAPIScopeUIConfig } from '@memberjunction/api-keys-base';\n\n/** Scope selection item */\ninterface ScopeItem {\n scope: MJAPIScopeEntity;\n selected: boolean;\n}\n\n/** Grouped scopes by category */\ninterface ScopeCategory {\n name: string;\n icon: string;\n color: string;\n scopes: ScopeItem[];\n expanded: boolean;\n allSelected: boolean;\n}\n\n/** Result of key creation */\nexport interface APIKeyCreateResult {\n success: boolean;\n apiKeyId?: string;\n rawKey?: string;\n error?: string;\n}\n/**\n * Dialog for creating new API keys\n * Shows the raw key only once - it cannot be recovered after closing\n */\n@Component({\n standalone: false,\n selector: 'mj-api-key-create-dialog',\n templateUrl: './api-key-create-dialog.component.html',\n styleUrls: ['./api-key-create-dialog.component.css']\n})\nexport class APIKeyCreateDialogComponent implements OnInit {\n @Input() Visible = false;\n @Output() VisibleChange = new EventEmitter<boolean>();\n @Output() Created = new EventEmitter<APIKeyCreateResult>();\n @Output() Closed = new EventEmitter<void>();\n\n // Form fields\n public Label = '';\n public Description = '';\n public ExpiresAt: Date | null = null;\n public NeverExpires = true;\n\n // Expiration presets\n public ExpirationPresets = [\n { label: '30 days', days: 30 },\n { label: '90 days', days: 90 },\n { label: '1 year', days: 365 },\n { label: 'Custom', days: -1 }\n ];\n public SelectedPreset: { label: string; days: number } | null = null;\n\n // Scopes\n public ScopeCategories: ScopeCategory[] = [];\n public IsLoadingScopes = true;\n\n // State\n public IsCreating = false;\n public Step: 'configure' | 'scopes' | 'success' = 'configure';\n public RawApiKey = '';\n public KeyCopied = false;\n public Error = '';\n\n // Default UI config for categories without explicit configuration\n private readonly defaultUIConfig = {\n icon: 'fa-solid fa-ellipsis',\n color: 'var(--mj-text-muted)'\n };\n\n ngOnInit(): void {\n this.loadScopes();\n }\n\n /**\n * Handle escape key to close dialog\n */\n @HostListener('document:keydown.escape')\n public onEscapeKey(): void {\n if (this.Visible && !this.IsCreating) {\n this.close();\n }\n }\n\n /**\n * Load available scopes from cached data.\n * Uses UIConfig from root scopes for category icons/colors.\n */\n private loadScopes(): void {\n this.IsLoadingScopes = true;\n try {\n const base = APIKeysEngineBase.Instance;\n const scopes = base.Scopes;\n\n // Build a map of category -> root scope UIConfig\n // Root scopes (ParentID is null) define the UI appearance for their category\n const categoryUIConfigs = new Map<string, { icon: string; color: string }>();\n for (const scope of scopes) {\n if (!scope.ParentID) {\n // This is a root scope - use its UIConfig for the category\n const uiConfig = parseAPIScopeUIConfig(scope);\n categoryUIConfigs.set(scope.Category, {\n icon: uiConfig.icon || this.defaultUIConfig.icon,\n color: uiConfig.color || this.defaultUIConfig.color\n });\n }\n }\n\n // Group scopes by category\n const categoryMap = new Map<string, ScopeItem[]>();\n for (const scope of scopes) {\n const category = scope.Category || 'Other';\n if (!categoryMap.has(category)) {\n categoryMap.set(category, []);\n }\n categoryMap.get(category)!.push({\n scope,\n selected: false\n });\n }\n\n // Build categories with UI config from root scopes\n this.ScopeCategories = Array.from(categoryMap.entries())\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([name, scopeItems]) => {\n const config = categoryUIConfigs.get(name) || this.defaultUIConfig;\n return {\n name,\n icon: config.icon,\n color: config.color,\n scopes: scopeItems.sort((a, b) => a.scope.Name.localeCompare(b.scope.Name)),\n expanded: false,\n allSelected: false\n };\n });\n } catch (error) {\n console.error('Error loading scopes:', error);\n } finally {\n this.IsLoadingScopes = false;\n }\n }\n\n /**\n * Handle expiration preset selection\n */\n public onPresetSelect(preset: { label: string; days: number }): void {\n this.SelectedPreset = preset;\n this.NeverExpires = false;\n\n if (preset.days > 0) {\n const date = new Date();\n date.setDate(date.getDate() + preset.days);\n this.ExpiresAt = date;\n } else {\n this.ExpiresAt = null;\n }\n }\n\n /**\n * Handle never expires toggle\n */\n public onNeverExpiresChange(): void {\n if (this.NeverExpires) {\n this.ExpiresAt = null;\n this.SelectedPreset = null;\n }\n }\n\n /**\n * Toggle category expansion\n */\n public toggleCategory(category: ScopeCategory): void {\n category.expanded = !category.expanded;\n }\n\n /**\n * Toggle all scopes in a category\n */\n public toggleCategoryAll(category: ScopeCategory): void {\n category.allSelected = !category.allSelected;\n for (const item of category.scopes) {\n item.selected = category.allSelected;\n }\n }\n\n /**\n * Update category allSelected state\n */\n public updateCategoryState(category: ScopeCategory): void {\n category.allSelected = category.scopes.every(s => s.selected);\n }\n\n /**\n * Get selected scope count\n */\n public getSelectedScopeCount(): number {\n return this.ScopeCategories.reduce((sum, cat) =>\n sum + cat.scopes.filter(s => s.selected).length, 0);\n }\n\n /**\n * Proceed to scopes step\n */\n public goToScopes(): void {\n if (!this.Label.trim()) {\n this.Error = 'Please enter a label for the API key';\n return;\n }\n this.Error = '';\n this.Step = 'scopes';\n }\n\n /**\n * Go back to configure step\n */\n public goBack(): void {\n this.Step = 'configure';\n }\n\n /**\n * Create the API key using server-side cryptographic hashing\n */\n public async createKey(): Promise<void> {\n this.IsCreating = true;\n this.Error = '';\n\n try {\n // Get selected scope IDs\n const selectedScopeIds = this.ScopeCategories\n .flatMap(cat => cat.scopes)\n .filter(s => s.selected)\n .map(s => s.scope.ID);\n\n // Get the GraphQL provider and create the encryption client\n const provider = Metadata.Provider as GraphQLDataProvider;\n const encryptionClient = new GraphQLEncryptionClient(provider);\n\n // Call the server to create the API key with proper crypto hashing\n const result = await encryptionClient.CreateAPIKey({\n Label: this.Label.trim(),\n Description: this.Description.trim() || undefined,\n ExpiresAt: this.NeverExpires ? undefined : (this.ExpiresAt || undefined),\n ScopeIDs: selectedScopeIds.length > 0 ? selectedScopeIds : undefined\n });\n\n if (result.Success && result.RawKey) {\n this.RawApiKey = result.RawKey;\n this.Step = 'success';\n\n this.Created.emit({\n success: true,\n rawKey: result.RawKey\n });\n } else {\n this.Error = result.Error || 'Failed to create API key. Please try again.';\n }\n } catch (error) {\n console.error('Error creating API key:', error);\n this.Error = 'An error occurred while creating the API key.';\n } finally {\n this.IsCreating = false;\n }\n }\n\n /**\n * Copy the API key to clipboard\n */\n public async copyKey(): Promise<void> {\n try {\n await navigator.clipboard.writeText(this.RawApiKey);\n this.KeyCopied = true;\n setTimeout(() => this.KeyCopied = false, 3000);\n } catch (error) {\n console.error('Failed to copy key:', error);\n }\n }\n\n /**\n * Close the dialog\n */\n public close(): void {\n this.reset();\n this.Visible = false;\n this.VisibleChange.emit(false);\n this.Closed.emit();\n }\n\n /**\n * Reset form state\n */\n private reset(): void {\n this.Label = '';\n this.Description = '';\n this.ExpiresAt = null;\n this.NeverExpires = true;\n this.SelectedPreset = null;\n this.Step = 'configure';\n this.RawApiKey = '';\n this.KeyCopied = false;\n this.Error = '';\n\n // Reset scope selections\n for (const category of this.ScopeCategories) {\n category.expanded = false;\n category.allSelected = false;\n for (const scope of category.scopes) {\n scope.selected = false;\n }\n }\n }\n\n /**\n * Get minimum date for expiration (tomorrow)\n */\n public getMinDate(): Date {\n const tomorrow = new Date();\n tomorrow.setDate(tomorrow.getDate() + 1);\n return tomorrow;\n }\n}\n","<!-- Slide-out Backdrop -->\n@if (Visible) {\n <div class=\"slideout-backdrop\" (click)=\"Step !== 'success' ? close() : null\"></div>\n}\n\n<!-- Slide-out Panel -->\n<div class=\"slideout-panel\" [class.open]=\"Visible\">\n <!-- Header -->\n <div class=\"slideout-header\">\n <div class=\"slideout-title\">\n <i class=\"fa-solid fa-key\"></i>\n <span>Generate New API Key</span>\n </div>\n @if (Step !== 'success') {\n <button class=\"slideout-close\" (click)=\"close()\" title=\"Close (Esc)\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n\n <!-- Step Indicator -->\n @if (Step !== 'success') {\n <div class=\"step-indicator\">\n <div class=\"step\" [class.active]=\"Step === 'configure'\" [class.completed]=\"Step === 'scopes'\">\n <div class=\"step-number\">1</div>\n <div class=\"step-label\">Configure</div>\n </div>\n <div class=\"step-connector\" [class.active]=\"Step === 'scopes'\"></div>\n <div class=\"step\" [class.active]=\"Step === 'scopes'\">\n <div class=\"step-number\">2</div>\n <div class=\"step-label\">Permissions</div>\n </div>\n </div>\n }\n\n <div class=\"slideout-content\">\n <!-- Configure Step -->\n @if (Step === 'configure') {\n <div class=\"step-panel\">\n <div class=\"form-section\">\n <label class=\"form-label required\">Key Label</label>\n <input kendoTextBox [(ngModel)]=\"Label\"\n placeholder=\"e.g., ElevenLabs Integration, CI/CD Pipeline\"\n class=\"form-input\" />\n <div class=\"form-hint\">A memorable name to identify this key's purpose</div>\n </div>\n <div class=\"form-section\">\n <label class=\"form-label\">Description</label>\n <textarea kendoTextArea [(ngModel)]=\"Description\"\n placeholder=\"Optional notes about how this key will be used...\"\n [rows]=\"3\"\n class=\"form-textarea\"></textarea>\n </div>\n <div class=\"form-section\">\n <label class=\"form-label\">Expiration</label>\n <div class=\"expiration-options\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" kendoCheckBox\n [(ngModel)]=\"NeverExpires\"\n (change)=\"onNeverExpiresChange()\" />\n <span>Never expires</span>\n </label>\n @if (!NeverExpires) {\n <div class=\"preset-buttons\">\n @for (preset of ExpirationPresets; track preset) {\n <button\n class=\"preset-btn\"\n [class.active]=\"SelectedPreset === preset\"\n (click)=\"onPresetSelect(preset)\">\n {{preset.label}}\n </button>\n }\n </div>\n }\n @if (!NeverExpires && SelectedPreset?.days === -1) {\n <div class=\"custom-date\">\n <kendo-datepicker [(ngModel)]=\"ExpiresAt\"\n [min]=\"getMinDate()\"\n format=\"MMM d, yyyy\"\n placeholder=\"Select expiration date\">\n </kendo-datepicker>\n </div>\n }\n @if (!NeverExpires && ExpiresAt) {\n <div class=\"expiration-preview\">\n <i class=\"fa-solid fa-calendar-check\"></i>\n <span>Key will expire on {{ExpiresAt | date:'MMMM d, yyyy'}}</span>\n </div>\n }\n </div>\n </div>\n @if (Error) {\n <div class=\"error-message\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{Error}}\n </div>\n }\n </div>\n }\n\n <!-- Scopes Step -->\n @if (Step === 'scopes') {\n <div class=\"step-panel scopes-step\">\n <div class=\"scopes-header\">\n <div class=\"scopes-info\">\n <h4>Select Permission Scopes</h4>\n <p>Choose what this API key can access. You can always modify this later.</p>\n </div>\n @if (getSelectedScopeCount() > 0) {\n <div class=\"scopes-count\">\n <span class=\"count\">{{getSelectedScopeCount()}}</span> selected\n </div>\n }\n </div>\n @if (IsLoadingScopes) {\n <mj-loading text=\"Loading scopes...\"></mj-loading>\n }\n @if (!IsLoadingScopes) {\n <div class=\"scope-categories\">\n @for (category of ScopeCategories; track category) {\n <div class=\"scope-category\">\n <div class=\"category-header\" (click)=\"toggleCategory(category)\">\n <div class=\"category-left\">\n <i [class]=\"category.icon\" [style.color]=\"category.color\"></i>\n <span class=\"category-name\">{{category.name}}</span>\n <span class=\"category-badge\">{{category.scopes.length}}</span>\n </div>\n <div class=\"category-right\">\n <label class=\"select-all-label\" (click)=\"$event.stopPropagation()\">\n <input type=\"checkbox\" kendoCheckBox\n [checked]=\"category.allSelected\"\n (change)=\"toggleCategoryAll(category)\" />\n <span>All</span>\n </label>\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!category.expanded\"\n [class.fa-chevron-up]=\"category.expanded\"></i>\n </div>\n </div>\n @if (category.expanded) {\n <div class=\"category-scopes\">\n @for (item of category.scopes; track item) {\n <div class=\"scope-item\">\n <label class=\"scope-label\">\n <input type=\"checkbox\" kendoCheckBox\n [(ngModel)]=\"item.selected\"\n (change)=\"updateCategoryState(category)\" />\n <div class=\"scope-info\">\n <span class=\"scope-name\">{{item.scope.Name}}</span>\n @if (item.scope.Description) {\n <span class=\"scope-desc\">\n {{item.scope.Description}}\n </span>\n }\n </div>\n </label>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n <div class=\"scope-tip\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n <span>Tip: Use wildcards like <code>entities:*</code> for broad access within a category</span>\n </div>\n <!-- No Scopes Warning -->\n @if (!IsLoadingScopes && getSelectedScopeCount() === 0) {\n <div class=\"no-scopes-warning\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <div>\n <strong>Warning: No permissions selected</strong>\n <p>API keys without any assigned scopes will have <strong>no permissions</strong> and cannot perform any operations. This key will be rejected by all API endpoints until scopes are assigned.</p>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Success Step -->\n @if (Step === 'success') {\n <div class=\"step-panel success-step\">\n <div class=\"success-icon\">\n <i class=\"fa-solid fa-check-circle\"></i>\n </div>\n <h3 class=\"success-title\">API Key Created Successfully!</h3>\n <div class=\"key-display\">\n <div class=\"key-warning\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span>Copy this key now. It won't be shown again!</span>\n </div>\n <div class=\"key-value\">\n <code>{{RawApiKey}}</code>\n <button class=\"copy-btn\" (click)=\"copyKey()\" [class.copied]=\"KeyCopied\">\n <i class=\"fa-solid\" [class.fa-copy]=\"!KeyCopied\" [class.fa-check]=\"KeyCopied\"></i>\n <span>{{KeyCopied ? 'Copied!' : 'Copy'}}</span>\n </button>\n </div>\n </div>\n <div class=\"key-details\">\n <div class=\"detail-row\">\n <span class=\"detail-label\">Label:</span>\n <span class=\"detail-value\">{{Label}}</span>\n </div>\n @if (Description) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Description:</span>\n <span class=\"detail-value\">{{Description}}</span>\n </div>\n }\n <div class=\"detail-row\">\n <span class=\"detail-label\">Expires:</span>\n <span class=\"detail-value\">\n {{NeverExpires ? 'Never' : (ExpiresAt | date:'MMMM d, yyyy')}}\n </span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Scopes:</span>\n <span class=\"detail-value\">{{getSelectedScopeCount()}} permissions</span>\n </div>\n </div>\n <div class=\"security-note\">\n <i class=\"fa-solid fa-shield-check\"></i>\n <div>\n <strong>Security Note:</strong>\n Store this key securely. We only store a hash - the original key cannot be recovered.\n </div>\n </div>\n </div>\n }\n </div>\n\n <!-- Footer -->\n <div class=\"slideout-footer\">\n @if (Step === 'configure') {\n <button kendoButton [themeColor]=\"'primary'\" (click)=\"goToScopes()\">\n Next: Permissions\n <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n <button kendoButton (click)=\"close()\">Cancel</button>\n }\n\n @if (Step === 'scopes') {\n <button kendoButton [themeColor]=\"'primary'\"\n [disabled]=\"IsCreating\"\n (click)=\"createKey()\">\n @if (IsCreating) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n }\n @if (!IsCreating) {\n <span>\n <i class=\"fa-solid fa-key\"></i>\n Generate Key\n </span>\n }\n </button>\n <button kendoButton (click)=\"goBack()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n Back\n </button>\n }\n\n @if (Step === 'success') {\n <button kendoButton [themeColor]=\"'primary'\" (click)=\"close()\">\n <i class=\"fa-solid fa-check\"></i>\n Done\n </button>\n }\n </div>\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"api-key-create-dialog.component.js","sourceRoot":"","sources":["../../src/APIKeys/api-key-create-dialog.component.ts","../../src/APIKeys/api-key-create-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, EventEmitter, HostListener, Input, OnInit, Output } from '@angular/core';\nimport { Metadata } from '@memberjunction/core';\nimport { MJAPIScopeEntity } from '@memberjunction/core-entities';\nimport { GraphQLDataProvider, GraphQLEncryptionClient } from '@memberjunction/graphql-dataprovider';\nimport { APIKeysEngineBase, parseAPIScopeUIConfig } from '@memberjunction/api-keys-base';\n\n/** Scope selection item */\ninterface ScopeItem {\n scope: MJAPIScopeEntity;\n selected: boolean;\n}\n\n/** Grouped scopes by category */\ninterface ScopeCategory {\n name: string;\n icon: string;\n color: string;\n scopes: ScopeItem[];\n expanded: boolean;\n allSelected: boolean;\n}\n\n/** Result of key creation */\nexport interface APIKeyCreateResult {\n success: boolean;\n apiKeyId?: string;\n rawKey?: string;\n error?: string;\n}\n/**\n * Dialog for creating new API keys\n * Shows the raw key only once - it cannot be recovered after closing\n */\n@Component({\n standalone: false,\n selector: 'mj-api-key-create-dialog',\n templateUrl: './api-key-create-dialog.component.html',\n styleUrls: ['./api-key-create-dialog.component.css']\n})\nexport class APIKeyCreateDialogComponent implements OnInit {\n @Input() Visible = false;\n @Output() VisibleChange = new EventEmitter<boolean>();\n @Output() Created = new EventEmitter<APIKeyCreateResult>();\n @Output() Closed = new EventEmitter<void>();\n\n // Form fields\n public Label = '';\n public Description = '';\n public ExpiresAt: Date | null = null;\n public NeverExpires = true;\n\n // Expiration presets\n public ExpirationPresets = [\n { label: '30 days', days: 30 },\n { label: '90 days', days: 90 },\n { label: '1 year', days: 365 },\n { label: 'Custom', days: -1 }\n ];\n public SelectedPreset: { label: string; days: number } | null = null;\n\n // Scopes\n public ScopeCategories: ScopeCategory[] = [];\n public IsLoadingScopes = true;\n\n // State\n public IsCreating = false;\n public Step: 'configure' | 'scopes' | 'success' = 'configure';\n public RawApiKey = '';\n public KeyCopied = false;\n public Error = '';\n\n // Default UI config for categories without explicit configuration\n private readonly defaultUIConfig = {\n icon: 'fa-solid fa-ellipsis',\n color: 'var(--mj-text-muted)'\n };\n\n ngOnInit(): void {\n this.loadScopes();\n }\n\n /**\n * Handle escape key to close dialog\n */\n @HostListener('document:keydown.escape')\n public onEscapeKey(): void {\n if (this.Visible && !this.IsCreating) {\n this.close();\n }\n }\n\n /**\n * Load available scopes from cached data.\n * Uses UIConfig from root scopes for category icons/colors.\n */\n private loadScopes(): void {\n this.IsLoadingScopes = true;\n try {\n const base = APIKeysEngineBase.Instance;\n const scopes = base.Scopes;\n\n // Build a map of category -> root scope UIConfig\n // Root scopes (ParentID is null) define the UI appearance for their category\n const categoryUIConfigs = new Map<string, { icon: string; color: string }>();\n for (const scope of scopes) {\n if (!scope.ParentID) {\n // This is a root scope - use its UIConfig for the category\n const uiConfig = parseAPIScopeUIConfig(scope);\n categoryUIConfigs.set(scope.Category, {\n icon: uiConfig.icon || this.defaultUIConfig.icon,\n color: uiConfig.color || this.defaultUIConfig.color\n });\n }\n }\n\n // Group scopes by category\n const categoryMap = new Map<string, ScopeItem[]>();\n for (const scope of scopes) {\n const category = scope.Category || 'Other';\n if (!categoryMap.has(category)) {\n categoryMap.set(category, []);\n }\n categoryMap.get(category)!.push({\n scope,\n selected: false\n });\n }\n\n // Build categories with UI config from root scopes\n this.ScopeCategories = Array.from(categoryMap.entries())\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([name, scopeItems]) => {\n const config = categoryUIConfigs.get(name) || this.defaultUIConfig;\n return {\n name,\n icon: config.icon,\n color: config.color,\n scopes: scopeItems.sort((a, b) => a.scope.Name.localeCompare(b.scope.Name)),\n expanded: false,\n allSelected: false\n };\n });\n } catch (error) {\n console.error('Error loading scopes:', error);\n } finally {\n this.IsLoadingScopes = false;\n }\n }\n\n /**\n * Handle expiration preset selection\n */\n public onPresetSelect(preset: { label: string; days: number }): void {\n this.SelectedPreset = preset;\n this.NeverExpires = false;\n\n if (preset.days > 0) {\n const date = new Date();\n date.setDate(date.getDate() + preset.days);\n this.ExpiresAt = date;\n } else {\n this.ExpiresAt = null;\n }\n }\n\n /**\n * Handle never expires toggle\n */\n public onNeverExpiresChange(): void {\n if (this.NeverExpires) {\n this.ExpiresAt = null;\n this.SelectedPreset = null;\n }\n }\n\n /**\n * Toggle category expansion\n */\n public toggleCategory(category: ScopeCategory): void {\n category.expanded = !category.expanded;\n }\n\n /**\n * Toggle all scopes in a category\n */\n public toggleCategoryAll(category: ScopeCategory): void {\n category.allSelected = !category.allSelected;\n for (const item of category.scopes) {\n item.selected = category.allSelected;\n }\n }\n\n /**\n * Update category allSelected state\n */\n public updateCategoryState(category: ScopeCategory): void {\n category.allSelected = category.scopes.every(s => s.selected);\n }\n\n /**\n * Get selected scope count\n */\n public getSelectedScopeCount(): number {\n return this.ScopeCategories.reduce((sum, cat) =>\n sum + cat.scopes.filter(s => s.selected).length, 0);\n }\n\n /**\n * Proceed to scopes step\n */\n public goToScopes(): void {\n if (!this.Label.trim()) {\n this.Error = 'Please enter a label for the API key';\n return;\n }\n this.Error = '';\n this.Step = 'scopes';\n }\n\n /**\n * Go back to configure step\n */\n public goBack(): void {\n this.Step = 'configure';\n }\n\n /**\n * Create the API key using server-side cryptographic hashing\n */\n public async createKey(): Promise<void> {\n this.IsCreating = true;\n this.Error = '';\n\n try {\n // Get selected scope IDs\n const selectedScopeIds = this.ScopeCategories\n .flatMap(cat => cat.scopes)\n .filter(s => s.selected)\n .map(s => s.scope.ID);\n\n // Get the GraphQL provider and create the encryption client\n const provider = Metadata.Provider as GraphQLDataProvider;\n const encryptionClient = new GraphQLEncryptionClient(provider);\n\n // Call the server to create the API key with proper crypto hashing\n const result = await encryptionClient.CreateAPIKey({\n Label: this.Label.trim(),\n Description: this.Description.trim() || undefined,\n ExpiresAt: this.NeverExpires ? undefined : (this.ExpiresAt || undefined),\n ScopeIDs: selectedScopeIds.length > 0 ? selectedScopeIds : undefined\n });\n\n if (result.Success && result.RawKey) {\n this.RawApiKey = result.RawKey;\n this.Step = 'success';\n\n this.Created.emit({\n success: true,\n rawKey: result.RawKey\n });\n } else {\n this.Error = result.Error || 'Failed to create API key. Please try again.';\n }\n } catch (error) {\n console.error('Error creating API key:', error);\n this.Error = 'An error occurred while creating the API key.';\n } finally {\n this.IsCreating = false;\n }\n }\n\n /**\n * Copy the API key to clipboard\n */\n public async copyKey(): Promise<void> {\n try {\n await navigator.clipboard.writeText(this.RawApiKey);\n this.KeyCopied = true;\n setTimeout(() => this.KeyCopied = false, 3000);\n } catch (error) {\n console.error('Failed to copy key:', error);\n }\n }\n\n /**\n * Close the dialog\n */\n public close(): void {\n this.reset();\n this.Visible = false;\n this.VisibleChange.emit(false);\n this.Closed.emit();\n }\n\n /**\n * Reset form state\n */\n private reset(): void {\n this.Label = '';\n this.Description = '';\n this.ExpiresAt = null;\n this.NeverExpires = true;\n this.SelectedPreset = null;\n this.Step = 'configure';\n this.RawApiKey = '';\n this.KeyCopied = false;\n this.Error = '';\n\n // Reset scope selections\n for (const category of this.ScopeCategories) {\n category.expanded = false;\n category.allSelected = false;\n for (const scope of category.scopes) {\n scope.selected = false;\n }\n }\n }\n\n /**\n * Get minimum date for expiration (tomorrow)\n */\n public getMinDate(): Date {\n const tomorrow = new Date();\n tomorrow.setDate(tomorrow.getDate() + 1);\n return tomorrow;\n }\n}\n","<!-- Slide-out Backdrop -->\n@if (Visible) {\n <div class=\"slideout-backdrop\" (click)=\"Step !== 'success' ? close() : null\"></div>\n}\n\n<!-- Slide-out Panel -->\n<div class=\"slideout-panel\" [class.open]=\"Visible\">\n <!-- Header -->\n <div class=\"slideout-header\">\n <div class=\"slideout-title\">\n <i class=\"fa-solid fa-key\"></i>\n <span>Generate New API Key</span>\n </div>\n @if (Step !== 'success') {\n <button class=\"slideout-close\" (click)=\"close()\" title=\"Close (Esc)\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n\n <!-- Step Indicator -->\n @if (Step !== 'success') {\n <div class=\"step-indicator\">\n <div class=\"step\" [class.active]=\"Step === 'configure'\" [class.completed]=\"Step === 'scopes'\">\n <div class=\"step-number\">1</div>\n <div class=\"step-label\">Configure</div>\n </div>\n <div class=\"step-connector\" [class.active]=\"Step === 'scopes'\"></div>\n <div class=\"step\" [class.active]=\"Step === 'scopes'\">\n <div class=\"step-number\">2</div>\n <div class=\"step-label\">Permissions</div>\n </div>\n </div>\n }\n\n <div class=\"slideout-content\">\n <!-- Configure Step -->\n @if (Step === 'configure') {\n <div class=\"step-panel\">\n <div class=\"form-section\">\n <label class=\"form-label required\">Key Label</label>\n <input class=\"mj-input form-input\" [(ngModel)]=\"Label\"\n placeholder=\"e.g., ElevenLabs Integration, CI/CD Pipeline\" />\n <div class=\"form-hint\">A memorable name to identify this key's purpose</div>\n </div>\n <div class=\"form-section\">\n <label class=\"form-label\">Description</label>\n <textarea class=\"mj-textarea form-textarea\" [(ngModel)]=\"Description\"\n placeholder=\"Optional notes about how this key will be used...\"\n [rows]=\"3\"></textarea>\n </div>\n <div class=\"form-section\">\n <label class=\"form-label\">Expiration</label>\n <div class=\"expiration-options\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" class=\"mj-checkbox\"\n [(ngModel)]=\"NeverExpires\"\n (change)=\"onNeverExpiresChange()\" />\n <span>Never expires</span>\n </label>\n @if (!NeverExpires) {\n <div class=\"preset-buttons\">\n @for (preset of ExpirationPresets; track preset) {\n <button\n class=\"preset-btn\"\n [class.active]=\"SelectedPreset === preset\"\n (click)=\"onPresetSelect(preset)\">\n {{preset.label}}\n </button>\n }\n </div>\n }\n @if (!NeverExpires && SelectedPreset?.days === -1) {\n <div class=\"custom-date\">\n <mj-datepicker [(ngModel)]=\"ExpiresAt\"\n [Min]=\"getMinDate()\"\n Format=\"MMM d, yyyy\"\n Placeholder=\"Select expiration date\">\n </mj-datepicker>\n </div>\n }\n @if (!NeverExpires && ExpiresAt) {\n <div class=\"expiration-preview\">\n <i class=\"fa-solid fa-calendar-check\"></i>\n <span>Key will expire on {{ExpiresAt | date:'MMMM d, yyyy'}}</span>\n </div>\n }\n </div>\n </div>\n @if (Error) {\n <div class=\"error-message\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{Error}}\n </div>\n }\n </div>\n }\n\n <!-- Scopes Step -->\n @if (Step === 'scopes') {\n <div class=\"step-panel scopes-step\">\n <div class=\"scopes-header\">\n <div class=\"scopes-info\">\n <h4>Select Permission Scopes</h4>\n <p>Choose what this API key can access. You can always modify this later.</p>\n </div>\n @if (getSelectedScopeCount() > 0) {\n <div class=\"scopes-count\">\n <span class=\"count\">{{getSelectedScopeCount()}}</span> selected\n </div>\n }\n </div>\n @if (IsLoadingScopes) {\n <mj-loading text=\"Loading scopes...\"></mj-loading>\n }\n @if (!IsLoadingScopes) {\n <div class=\"scope-categories\">\n @for (category of ScopeCategories; track category) {\n <div class=\"scope-category\">\n <div class=\"category-header\" (click)=\"toggleCategory(category)\">\n <div class=\"category-left\">\n <i [class]=\"category.icon\" [style.color]=\"category.color\"></i>\n <span class=\"category-name\">{{category.name}}</span>\n <span class=\"category-badge\">{{category.scopes.length}}</span>\n </div>\n <div class=\"category-right\">\n <label class=\"select-all-label\" (click)=\"$event.stopPropagation()\">\n <input type=\"checkbox\" class=\"mj-checkbox\"\n [checked]=\"category.allSelected\"\n (change)=\"toggleCategoryAll(category)\" />\n <span>All</span>\n </label>\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!category.expanded\"\n [class.fa-chevron-up]=\"category.expanded\"></i>\n </div>\n </div>\n @if (category.expanded) {\n <div class=\"category-scopes\">\n @for (item of category.scopes; track item) {\n <div class=\"scope-item\">\n <label class=\"scope-label\">\n <input type=\"checkbox\" class=\"mj-checkbox\"\n [(ngModel)]=\"item.selected\"\n (change)=\"updateCategoryState(category)\" />\n <div class=\"scope-info\">\n <span class=\"scope-name\">{{item.scope.Name}}</span>\n @if (item.scope.Description) {\n <span class=\"scope-desc\">\n {{item.scope.Description}}\n </span>\n }\n </div>\n </label>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n <div class=\"scope-tip\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n <span>Tip: Use wildcards like <code>entities:*</code> for broad access within a category</span>\n </div>\n <!-- No Scopes Warning -->\n @if (!IsLoadingScopes && getSelectedScopeCount() === 0) {\n <div class=\"no-scopes-warning\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <div>\n <strong>Warning: No permissions selected</strong>\n <p>API keys without any assigned scopes will have <strong>no permissions</strong> and cannot perform any operations. This key will be rejected by all API endpoints until scopes are assigned.</p>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Success Step -->\n @if (Step === 'success') {\n <div class=\"step-panel success-step\">\n <div class=\"success-icon\">\n <i class=\"fa-solid fa-check-circle\"></i>\n </div>\n <h3 class=\"success-title\">API Key Created Successfully!</h3>\n <div class=\"key-display\">\n <div class=\"key-warning\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span>Copy this key now. It won't be shown again!</span>\n </div>\n <div class=\"key-value\">\n <code>{{RawApiKey}}</code>\n <button class=\"copy-btn\" (click)=\"copyKey()\" [class.copied]=\"KeyCopied\">\n <i class=\"fa-solid\" [class.fa-copy]=\"!KeyCopied\" [class.fa-check]=\"KeyCopied\"></i>\n <span>{{KeyCopied ? 'Copied!' : 'Copy'}}</span>\n </button>\n </div>\n </div>\n <div class=\"key-details\">\n <div class=\"detail-row\">\n <span class=\"detail-label\">Label:</span>\n <span class=\"detail-value\">{{Label}}</span>\n </div>\n @if (Description) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Description:</span>\n <span class=\"detail-value\">{{Description}}</span>\n </div>\n }\n <div class=\"detail-row\">\n <span class=\"detail-label\">Expires:</span>\n <span class=\"detail-value\">\n {{NeverExpires ? 'Never' : (ExpiresAt | date:'MMMM d, yyyy')}}\n </span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Scopes:</span>\n <span class=\"detail-value\">{{getSelectedScopeCount()}} permissions</span>\n </div>\n </div>\n <div class=\"security-note\">\n <i class=\"fa-solid fa-shield-check\"></i>\n <div>\n <strong>Security Note:</strong>\n Store this key securely. We only store a hash - the original key cannot be recovered.\n </div>\n </div>\n </div>\n }\n </div>\n\n <!-- Footer -->\n <div class=\"slideout-footer\">\n @if (Step === 'configure') {\n <button mjButton variant=\"primary\" (click)=\"goToScopes()\">\n Next: Permissions\n <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n <button mjButton (click)=\"close()\">Cancel</button>\n }\n\n @if (Step === 'scopes') {\n <button mjButton variant=\"primary\"\n [disabled]=\"IsCreating\"\n (click)=\"createKey()\">\n @if (IsCreating) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n }\n @if (!IsCreating) {\n <span>\n <i class=\"fa-solid fa-key\"></i>\n Generate Key\n </span>\n }\n </button>\n <button mjButton (click)=\"goBack()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n Back\n </button>\n }\n\n @if (Step === 'success') {\n <button mjButton variant=\"primary\" (click)=\"close()\">\n <i class=\"fa-solid fa-check\"></i>\n Done\n </button>\n }\n </div>\n</div>\n"]}
|