@memberjunction/ng-dashboards 5.24.0 → 5.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AI/components/agents/agent-configuration.component.d.ts +15 -33
- package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-configuration.component.js +233 -493
- package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.d.ts +2 -2
- package/dist/AI/components/agents/agent-editor.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.js +7 -7
- package/dist/AI/components/agents/agent-editor.component.js.map +1 -1
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +43 -6
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +1135 -864
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +4 -3
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +1 -0
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
- package/dist/AI/components/execution-monitoring.component.d.ts +4 -5
- package/dist/AI/components/execution-monitoring.component.d.ts.map +1 -1
- package/dist/AI/components/execution-monitoring.component.js +14 -15
- package/dist/AI/components/execution-monitoring.component.js.map +1 -1
- package/dist/AI/components/models/model-management.component.d.ts +4 -4
- package/dist/AI/components/models/model-management.component.d.ts.map +1 -1
- package/dist/AI/components/models/model-management.component.js +5 -5
- package/dist/AI/components/models/model-management.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-management.component.d.ts +4 -4
- package/dist/AI/components/prompts/prompt-management.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/prompt-management.component.js +5 -5
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/AI/components/requests/agent-requests-resource.component.d.ts +2 -1
- package/dist/AI/components/requests/agent-requests-resource.component.d.ts.map +1 -1
- package/dist/AI/components/requests/agent-requests-resource.component.js +1 -0
- package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -1
- package/dist/AI/components/system/system-configuration.component.d.ts +2 -3
- package/dist/AI/components/system/system-configuration.component.d.ts.map +1 -1
- package/dist/AI/components/system/system-configuration.component.js +9 -11
- package/dist/AI/components/system/system-configuration.component.js.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts +44 -8
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.js +648 -384
- package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
- package/dist/APIKeys/api-keys-resource.component.d.ts +2 -1
- package/dist/APIKeys/api-keys-resource.component.d.ts.map +1 -1
- package/dist/APIKeys/api-keys-resource.component.js +2 -0
- package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
- package/dist/Actions/components/actions-overview.component.d.ts +4 -5
- package/dist/Actions/components/actions-overview.component.d.ts.map +1 -1
- package/dist/Actions/components/actions-overview.component.js +11 -12
- package/dist/Actions/components/actions-overview.component.js.map +1 -1
- package/dist/Actions/components/code-management.component.d.ts +2 -3
- package/dist/Actions/components/code-management.component.d.ts.map +1 -1
- package/dist/Actions/components/code-management.component.js +4 -6
- package/dist/Actions/components/code-management.component.js.map +1 -1
- package/dist/Actions/components/entity-integration.component.d.ts +2 -3
- package/dist/Actions/components/entity-integration.component.d.ts.map +1 -1
- package/dist/Actions/components/entity-integration.component.js +4 -6
- package/dist/Actions/components/entity-integration.component.js.map +1 -1
- package/dist/Actions/components/execution-monitoring.component.d.ts +4 -5
- package/dist/Actions/components/execution-monitoring.component.d.ts.map +1 -1
- package/dist/Actions/components/execution-monitoring.component.js +10 -11
- package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.d.ts +13 -12
- package/dist/Actions/components/explorer/action-explorer.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.js +39 -66
- package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
- package/dist/Actions/components/scheduled-actions.component.d.ts +2 -3
- package/dist/Actions/components/scheduled-actions.component.d.ts.map +1 -1
- package/dist/Actions/components/scheduled-actions.component.js +4 -6
- package/dist/Actions/components/scheduled-actions.component.js.map +1 -1
- package/dist/Actions/components/security-permissions.component.d.ts +2 -3
- package/dist/Actions/components/security-permissions.component.d.ts.map +1 -1
- package/dist/Actions/components/security-permissions.component.js +4 -6
- package/dist/Actions/components/security-permissions.component.js.map +1 -1
- package/dist/ApplicationRoles/application-roles-resource.component.d.ts +112 -0
- package/dist/ApplicationRoles/application-roles-resource.component.d.ts.map +1 -0
- package/dist/ApplicationRoles/application-roles-resource.component.js +532 -0
- package/dist/ApplicationRoles/application-roles-resource.component.js.map +1 -0
- package/dist/Communication/communication-dashboard.component.d.ts.map +1 -1
- package/dist/Communication/communication-dashboard.component.js +1 -0
- package/dist/Communication/communication-dashboard.component.js.map +1 -1
- package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-logs-resource.component.js +4 -1
- package/dist/Communication/communication-logs-resource.component.js.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.js +4 -1
- package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
- package/dist/Communication/communication-providers-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-providers-resource.component.js +4 -1
- package/dist/Communication/communication-providers-resource.component.js.map +1 -1
- package/dist/Communication/communication-runs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-runs-resource.component.js +4 -1
- package/dist/Communication/communication-runs-resource.component.js.map +1 -1
- package/dist/Communication/communication-templates-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-templates-resource.component.js +4 -1
- package/dist/Communication/communication-templates-resource.component.js.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts +2 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +1 -0
- package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
- package/dist/Credentials/components/credentials-audit-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-audit-resource.component.js +2 -0
- package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.d.ts +2 -3
- package/dist/Credentials/components/credentials-categories-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.js +10 -11
- package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.d.ts +2 -1
- package/dist/Credentials/components/credentials-list-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +2 -0
- package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-overview-resource.component.d.ts +4 -4
- package/dist/Credentials/components/credentials-overview-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-overview-resource.component.js +8 -9
- package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.d.ts +2 -3
- package/dist/Credentials/components/credentials-types-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +11 -12
- package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
- package/dist/Credentials/credentials-dashboard.component.d.ts.map +1 -1
- package/dist/Credentials/credentials-dashboard.component.js +1 -0
- package/dist/Credentials/credentials-dashboard.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts +2 -3
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +9 -10
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +2 -2
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts +23 -15
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts.map +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +167 -213
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +68 -32
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +453 -420
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.d.ts +10 -3
- package/dist/DataExplorer/data-explorer-resource.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.js +35 -11
- package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -1
- package/dist/DataExplorer/models/explorer-state.interface.d.ts +12 -3
- package/dist/DataExplorer/models/explorer-state.interface.d.ts.map +1 -1
- package/dist/DataExplorer/models/explorer-state.interface.js +5 -1
- package/dist/DataExplorer/models/explorer-state.interface.js.map +1 -1
- package/dist/Home/home-dashboard.component.d.ts +4 -4
- package/dist/Home/home-dashboard.component.d.ts.map +1 -1
- package/dist/Home/home-dashboard.component.js +4 -5
- 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 +2 -0
- 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 +1 -0
- 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 +2 -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 +2 -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 +2 -0
- package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts +4 -3
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +1 -0
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +4 -3
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +1 -0
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts +13 -3
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +220 -138
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts +4 -3
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +1 -0
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/index.d.ts +0 -1
- package/dist/KnowledgeHub/index.d.ts.map +1 -1
- package/dist/KnowledgeHub/index.js +0 -1
- package/dist/KnowledgeHub/index.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.d.ts +2 -1
- package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +2 -0
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-categories-resource.component.d.ts +2 -1
- package/dist/Lists/components/lists-categories-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-categories-resource.component.js +2 -0
- package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.d.ts +2 -1
- package/dist/Lists/components/lists-my-lists-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +2 -0
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-operations-resource.component.d.ts +2 -1
- package/dist/Lists/components/lists-operations-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-operations-resource.component.js +2 -0
- package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
- package/dist/MCP/mcp-dashboard.component.d.ts +7 -28
- package/dist/MCP/mcp-dashboard.component.d.ts.map +1 -1
- package/dist/MCP/mcp-dashboard.component.js +25 -107
- package/dist/MCP/mcp-dashboard.component.js.map +1 -1
- package/dist/MCP/mcp-resource.component.d.ts.map +1 -1
- package/dist/MCP/mcp-resource.component.js +1 -0
- package/dist/MCP/mcp-resource.component.js.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.d.ts +10 -23
- package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js +41 -103
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-activity-resource.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-activity-resource.component.js +1 -0
- package/dist/Scheduling/components/scheduling-activity-resource.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs-resource.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs-resource.component.js +1 -0
- package/dist/Scheduling/components/scheduling-jobs-resource.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-overview-resource.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-overview-resource.component.js +1 -0
- package/dist/Scheduling/components/scheduling-overview-resource.component.js.map +1 -1
- package/dist/Scheduling/scheduling-dashboard.component.d.ts.map +1 -1
- package/dist/Scheduling/scheduling-dashboard.component.js +1 -0
- package/dist/Scheduling/scheduling-dashboard.component.js.map +1 -1
- package/dist/SystemDiagnostics/system-diagnostics.component.d.ts +4 -4
- package/dist/SystemDiagnostics/system-diagnostics.component.d.ts.map +1 -1
- package/dist/SystemDiagnostics/system-diagnostics.component.js +9 -10
- package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
- package/dist/Testing/components/testing-analytics-resource.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-analytics-resource.component.js +2 -0
- package/dist/Testing/components/testing-analytics-resource.component.js.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts +2 -1
- package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab-resource.component.js +2 -0
- package/dist/Testing/components/testing-dashboard-tab-resource.component.js.map +1 -1
- package/dist/Testing/components/testing-explorer-resource.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-explorer-resource.component.js +2 -0
- package/dist/Testing/components/testing-explorer-resource.component.js.map +1 -1
- package/dist/Testing/components/testing-review-resource.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-review-resource.component.js +2 -0
- package/dist/Testing/components/testing-review-resource.component.js.map +1 -1
- package/dist/Testing/components/testing-runs-resource.component.d.ts +2 -1
- package/dist/Testing/components/testing-runs-resource.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-runs-resource.component.js +2 -0
- package/dist/Testing/components/testing-runs-resource.component.js.map +1 -1
- package/dist/Testing/testing-dashboard.component.d.ts +2 -1
- package/dist/Testing/testing-dashboard.component.d.ts.map +1 -1
- package/dist/Testing/testing-dashboard.component.js +1 -0
- package/dist/Testing/testing-dashboard.component.js.map +1 -1
- package/dist/VersionHistory/components/diff-resource.component.d.ts +4 -4
- package/dist/VersionHistory/components/diff-resource.component.d.ts.map +1 -1
- package/dist/VersionHistory/components/diff-resource.component.js +9 -10
- package/dist/VersionHistory/components/diff-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/graph-resource.component.d.ts +2 -1
- package/dist/VersionHistory/components/graph-resource.component.d.ts.map +1 -1
- package/dist/VersionHistory/components/graph-resource.component.js +2 -0
- package/dist/VersionHistory/components/graph-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/labels-resource.component.d.ts +4 -4
- package/dist/VersionHistory/components/labels-resource.component.d.ts.map +1 -1
- package/dist/VersionHistory/components/labels-resource.component.js +10 -11
- package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/restore-resource.component.d.ts +2 -1
- package/dist/VersionHistory/components/restore-resource.component.d.ts.map +1 -1
- package/dist/VersionHistory/components/restore-resource.component.js +2 -0
- package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
- package/dist/ai-dashboards.module.d.ts +19 -19
- package/dist/ai-dashboards.module.d.ts.map +1 -1
- package/dist/ai-dashboards.module.js +4 -5
- package/dist/ai-dashboards.module.js.map +1 -1
- package/dist/core-dashboards.module.d.ts +19 -18
- package/dist/core-dashboards.module.d.ts.map +1 -1
- package/dist/core-dashboards.module.js +8 -0
- package/dist/core-dashboards.module.js.map +1 -1
- package/dist/data-explorer-dashboards.module.d.ts +2 -1
- package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
- package/dist/data-explorer-dashboards.module.js +7 -3
- package/dist/data-explorer-dashboards.module.js.map +1 -1
- package/dist/public-api.d.ts +1 -1
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +2 -1
- package/dist/public-api.js.map +1 -1
- package/package.json +47 -47
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts +0 -166
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts.map +0 -1
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js +0 -991
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js.map +0 -1
|
@@ -10,9 +10,8 @@ import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
|
|
|
10
10
|
import { BaseResourceComponent } from '@memberjunction/ng-shared';
|
|
11
11
|
import { RunView, Metadata, CompositeKey } from '@memberjunction/core';
|
|
12
12
|
import * as i0 from "@angular/core";
|
|
13
|
-
import * as i1 from "@
|
|
14
|
-
import * as i2 from "@
|
|
15
|
-
import * as i3 from "@memberjunction/ng-shared-generic";
|
|
13
|
+
import * as i1 from "@angular/common";
|
|
14
|
+
import * as i2 from "@memberjunction/ng-shared-generic";
|
|
16
15
|
function CredentialsOverviewResourceComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
17
16
|
i0.ɵɵelement(0, "mj-loading", 1);
|
|
18
17
|
} }
|
|
@@ -491,7 +490,6 @@ function CredentialsOverviewResourceComponent_Conditional_2_Template(rf, ctx) {
|
|
|
491
490
|
} }
|
|
492
491
|
let CredentialsOverviewResourceComponent = class CredentialsOverviewResourceComponent extends BaseResourceComponent {
|
|
493
492
|
cdr;
|
|
494
|
-
navigationService;
|
|
495
493
|
isLoading = true;
|
|
496
494
|
// Summary stats
|
|
497
495
|
totalCredentials = 0;
|
|
@@ -524,15 +522,16 @@ let CredentialsOverviewResourceComponent = class CredentialsOverviewResourceComp
|
|
|
524
522
|
'Integration': 'var(--mj-brand-primary)'
|
|
525
523
|
};
|
|
526
524
|
destroy$ = new Subject();
|
|
527
|
-
constructor(cdr
|
|
525
|
+
constructor(cdr) {
|
|
528
526
|
super();
|
|
529
527
|
this.cdr = cdr;
|
|
530
|
-
this.navigationService = navigationService;
|
|
531
528
|
}
|
|
532
529
|
ngOnInit() {
|
|
530
|
+
super.ngOnInit();
|
|
533
531
|
this.loadData();
|
|
534
532
|
}
|
|
535
533
|
ngOnDestroy() {
|
|
534
|
+
super.ngOnDestroy();
|
|
536
535
|
this.destroy$.next();
|
|
537
536
|
this.destroy$.complete();
|
|
538
537
|
}
|
|
@@ -914,7 +913,7 @@ let CredentialsOverviewResourceComponent = class CredentialsOverviewResourceComp
|
|
|
914
913
|
}
|
|
915
914
|
return offset;
|
|
916
915
|
}
|
|
917
|
-
static ɵfac = function CredentialsOverviewResourceComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CredentialsOverviewResourceComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)
|
|
916
|
+
static ɵfac = function CredentialsOverviewResourceComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CredentialsOverviewResourceComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
918
917
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: CredentialsOverviewResourceComponent, selectors: [["mj-credentials-overview-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 3, vars: 2, consts: [[1, "overview-container"], ["text", "Loading overview..."], [1, "overview-header"], [1, "header-left"], [1, "overview-title"], [1, "overview-subtitle"], [1, "header-actions"], ["title", "Refresh", 1, "btn-refresh", 3, "click"], [1, "fa-solid", "fa-refresh"], [1, "btn-primary"], [1, "health-banner", 3, "ngClass"], [1, "health-score-container"], [1, "health-score-ring"], ["viewBox", "0 0 36 36", 1, "circular-chart"], ["d", "M18 2.0845\n a 15.9155 15.9155 0 0 1 0 31.831\n a 15.9155 15.9155 0 0 1 0 -31.831", 1, "circle-bg"], ["d", "M18 2.0845\n a 15.9155 15.9155 0 0 1 0 31.831\n a 15.9155 15.9155 0 0 1 0 -31.831", 1, "circle"], [1, "health-score-value"], [1, "health-info"], [1, "health-label"], [1, "health-details"], [1, "health-alert"], [1, "health-warning-text"], [1, "health-ok"], [1, "kpi-row"], [1, "kpi-card", "clickable", 3, "click"], [1, "kpi-icon"], [1, "fa-solid", "fa-key"], [1, "kpi-content"], [1, "kpi-value"], [1, "kpi-label"], [1, "kpi-trend"], [1, "fa-solid", "fa-arrow-right"], [1, "kpi-card", "active", "clickable", 3, "click"], [1, "fa-solid", "fa-check-circle"], [1, "kpi-trend", "success"], [1, "percentage"], [1, "kpi-card"], [1, "fa-solid", "fa-cubes"], [1, "fa-solid", "fa-clock"], [1, "kpi-trend", "warning"], [1, "fa-solid", "fa-circle-xmark"], [1, "content-grid"], [1, "panel", "category-panel"], [1, "panel-header"], [1, "panel-title"], [1, "fa-solid", "fa-chart-pie"], [1, "panel-subtitle"], [1, "panel-body"], [1, "category-chart"], [1, "empty-state"], [1, "panel", "types-panel"], [1, "panel-action", 3, "click"], [1, "type-list"], [1, "panel", "activity-panel"], [1, "fa-solid", "fa-clock-rotate-left"], [1, "activity-list"], [1, "quick-actions"], [1, "security-notice"], [1, "fa-solid", "fa-shield-check"], [1, "notice-content"], [1, "btn-primary", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "fa-solid", "fa-circle-exclamation"], [1, "health-warning-text", 3, "click"], [1, "donut-chart-container"], ["viewBox", "0 0 100 100", 1, "donut-chart"], ["cx", "50", "cy", "50", "r", "40", "fill", "none", "stroke", "var(--mj-border-default)", "stroke-width", "12"], [1, "donut-center"], [1, "donut-total"], [1, "donut-label"], [1, "category-legend"], [1, "legend-item"], ["cx", "50", "cy", "50", "r", "40", "fill", "none", "stroke-width", "12", 1, "donut-segment", 3, "click"], [1, "legend-item", 3, "click"], [1, "legend-color"], [1, "legend-info"], [1, "legend-name"], [1, "legend-value"], [1, "fa-solid", "fa-chevron-right", "legend-arrow"], [1, "fa-solid", "fa-folder-open"], [1, "type-item"], [1, "type-item", 3, "click"], [1, "type-info"], [1, "type-name"], [1, "type-category"], [1, "type-stats"], [1, "type-count"], [1, "count-value"], [1, "count-label"], [1, "type-bar"], [1, "type-bar-fill"], [1, "type-indicators"], ["title", "Active", 1, "indicator", "active"], ["title", "Expiring Soon", 1, "indicator", "warning"], [1, "fa-solid", "fa-circle"], [1, "fa-solid", "fa-shapes"], [1, "activity-item"], [1, "activity-item", 3, "click"], [1, "activity-icon", 3, "ngClass"], [1, "activity-info"], [1, "activity-name"], [1, "activity-meta"], [1, "activity-type"], [1, "activity-action"], [1, "activity-user"], [1, "activity-time"], [1, "fa-solid", "fa-inbox"], [1, "quick-actions-title"], [1, "quick-actions-grid"], [1, "quick-action", 3, "click"], [1, "fa-solid", "fa-folder-tree"], [1, "fa-solid", "fa-clipboard-list"]], template: function CredentialsOverviewResourceComponent_Template(rf, ctx) { if (rf & 1) {
|
|
919
918
|
i0.ɵɵelementStart(0, "div", 0);
|
|
920
919
|
i0.ɵɵconditionalCreate(1, CredentialsOverviewResourceComponent_Conditional_1_Template, 1, 0, "mj-loading", 1);
|
|
@@ -925,7 +924,7 @@ let CredentialsOverviewResourceComponent = class CredentialsOverviewResourceComp
|
|
|
925
924
|
i0.ɵɵconditional(ctx.isLoading ? 1 : -1);
|
|
926
925
|
i0.ɵɵadvance();
|
|
927
926
|
i0.ɵɵconditional(!ctx.isLoading ? 2 : -1);
|
|
928
|
-
} }, dependencies: [i2.NgClass, i3.LoadingComponent], styles: [".overview-container[_ngcontent-%COMP%] {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n}\n\n\n\n.overview-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.header-left[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.overview-title[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 4px 0;\n}\n\n.overview-subtitle[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n}\n\n.btn-refresh[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-refresh[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.btn-refresh[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n font-weight: 600;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n\n\n.health-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 20px 24px;\n background: color-mix(in srgb, var(--mj-status-success) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n border-radius: 16px;\n margin-bottom: 24px;\n}\n\n.health-banner.health-warning[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n}\n\n.health-banner.health-critical[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n}\n\n.health-score-container[_ngcontent-%COMP%] {\n margin-right: 24px;\n}\n\n.health-score-ring[_ngcontent-%COMP%] {\n position: relative;\n width: 80px;\n height: 80px;\n}\n\n.circular-chart[_ngcontent-%COMP%] {\n display: block;\n margin: 0 auto;\n max-height: 80px;\n transform: rotate(-90deg);\n}\n\n.circle-bg[_ngcontent-%COMP%] {\n fill: none;\n stroke: var(--mj-border-default);\n stroke-width: 3.8;\n}\n\n.circle[_ngcontent-%COMP%] {\n fill: none;\n stroke-width: 3.8;\n stroke-linecap: round;\n stroke: var(--mj-status-success);\n animation: _ngcontent-%COMP%_progress 1s ease-out forwards;\n}\n\n.health-banner.health-warning[_ngcontent-%COMP%] .circle[_ngcontent-%COMP%] {\n stroke: var(--mj-status-warning);\n}\n\n.health-banner.health-critical[_ngcontent-%COMP%] .circle[_ngcontent-%COMP%] {\n stroke: var(--mj-status-error);\n}\n\n@keyframes _ngcontent-%COMP%_progress {\n 0% {\n stroke-dasharray: 0 100;\n }\n}\n\n.health-score-value[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.health-info[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.health-label[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-status-success);\n margin-bottom: 4px;\n}\n\n.health-banner.health-warning[_ngcontent-%COMP%] .health-label[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.health-banner.health-critical[_ngcontent-%COMP%] .health-label[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.health-details[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.health-alert[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--mj-status-error);\n font-weight: 500;\n font-size: 14px;\n}\n\n.health-warning-text[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--mj-status-warning);\n font-weight: 500;\n font-size: 14px;\n cursor: pointer;\n}\n\n.health-warning-text[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n}\n\n.health-ok[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--mj-status-success);\n font-weight: 500;\n font-size: 14px;\n}\n\n\n\n.kpi-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 16px 20px;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.kpi-card.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.kpi-card.clickable[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n\n.kpi-card.active[_ngcontent-%COMP%] .kpi-icon[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n}\n\n.kpi-card.warning[_ngcontent-%COMP%] .kpi-icon[_ngcontent-%COMP%] {\n background: var(--mj-status-warning);\n}\n\n.kpi-card.danger[_ngcontent-%COMP%] .kpi-icon[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n}\n\n.kpi-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n border-radius: 10px;\n margin-right: 14px;\n flex-shrink: 0;\n}\n\n.kpi-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--mj-text-inverse);\n}\n\n.kpi-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1.2;\n}\n\n.kpi-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n white-space: nowrap;\n}\n\n.kpi-trend[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n margin-left: 8px;\n color: var(--mj-text-disabled);\n}\n\n.kpi-trend.success[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.kpi-trend.warning[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.kpi-trend[_ngcontent-%COMP%] .percentage[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n}\n\n\n\n.content-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 1fr;\n grid-template-rows: auto auto;\n gap: 20px;\n margin-bottom: 24px;\n}\n\n.category-panel[_ngcontent-%COMP%] {\n grid-row: span 2;\n}\n\n.panel[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.panel-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.panel-subtitle[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-disabled);\n}\n\n.panel-action[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.panel-action[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.panel-body[_ngcontent-%COMP%] {\n padding: 20px;\n flex: 1;\n overflow-y: auto;\n}\n\n\n\n.category-chart[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 24px;\n height: 100%;\n}\n\n.donut-chart-container[_ngcontent-%COMP%] {\n position: relative;\n width: 200px;\n height: 200px;\n margin: 0 auto;\n}\n\n.donut-chart[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n transform: rotate(-90deg);\n}\n\n.donut-segment[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: opacity 0.2s ease;\n}\n\n.donut-segment[_ngcontent-%COMP%]:hover {\n opacity: 0.8;\n}\n\n.donut-center[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n text-align: center;\n}\n\n.donut-total[_ngcontent-%COMP%] {\n font-size: 32px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.donut-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n\n\n.category-legend[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.legend-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.legend-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n transform: translateX(4px);\n}\n\n.legend-color[_ngcontent-%COMP%] {\n width: 12px;\n height: 12px;\n border-radius: 4px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.legend-info[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.legend-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.legend-name[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.legend-value[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.legend-arrow[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n font-size: 10px;\n}\n\n\n\n.type-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.type-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.type-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.type-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.type-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.type-category[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-disabled);\n margin-top: 2px;\n}\n\n.type-stats[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 4px;\n flex-shrink: 0;\n margin-left: 16px;\n}\n\n.type-count[_ngcontent-%COMP%] {\n display: flex;\n align-items: baseline;\n gap: 4px;\n}\n\n.count-value[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.count-label[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-disabled);\n}\n\n.type-bar[_ngcontent-%COMP%] {\n width: 100px;\n height: 4px;\n background: var(--mj-border-default);\n border-radius: 2px;\n overflow: hidden;\n}\n\n.type-bar-fill[_ngcontent-%COMP%] {\n height: 100%;\n background: var(--mj-brand-primary);\n border-radius: 2px;\n transition: width 0.3s ease;\n}\n\n.type-indicators[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n}\n\n.indicator.active[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.indicator.warning[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 6px;\n}\n\n\n\n.activity-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.activity-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.activity-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.activity-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-radius: 6px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.activity-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-brand-primary);\n}\n\n.activity-icon.action-created[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n}\n\n.activity-icon.action-created[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.activity-icon.action-updated[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n.activity-icon.action-updated[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.activity-icon.action-accessed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n}\n\n.activity-icon.action-accessed[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.activity-icon.action-rotated[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n.activity-icon.action-rotated[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.activity-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.activity-name[_ngcontent-%COMP%] {\n font-weight: 500;\n font-size: 13px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.activity-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 2px;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.activity-type[_ngcontent-%COMP%] {\n background: var(--mj-border-default);\n padding: 1px 6px;\n border-radius: 4px;\n}\n\n.activity-action[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n.activity-time[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-disabled);\n white-space: nowrap;\n}\n\n\n\n.quick-actions[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n\n.quick-actions-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 12px;\n}\n\n.quick-actions-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 12px;\n}\n\n.quick-action[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.quick-action[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n transform: translateY(-2px);\n}\n\n.quick-action[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--mj-brand-primary);\n}\n\n.quick-action[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 32px;\n color: var(--mj-text-secondary);\n text-align: center;\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n margin-bottom: 12px;\n opacity: 0.5;\n}\n\n\n\n.security-notice[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n padding: 16px 20px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border-radius: 12px;\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.security-notice[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--mj-brand-primary);\n margin-right: 12px;\n margin-top: 2px;\n}\n\n.notice-content[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n}\n\n.notice-content[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n\n\n\n@media (max-width: 1024px) {\n .content-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .category-panel[_ngcontent-%COMP%] {\n grid-row: auto;\n }\n\n .category-chart[_ngcontent-%COMP%] {\n flex-direction: row;\n align-items: center;\n }\n\n .donut-chart-container[_ngcontent-%COMP%] {\n width: 160px;\n height: 160px;\n }\n\n .category-legend[_ngcontent-%COMP%] {\n flex: 1;\n }\n}\n\n@media (max-width: 768px) {\n .overview-container[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .overview-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-actions[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: flex-end;\n }\n\n .health-banner[_ngcontent-%COMP%] {\n flex-direction: column;\n text-align: center;\n }\n\n .health-score-container[_ngcontent-%COMP%] {\n margin-right: 0;\n margin-bottom: 16px;\n }\n\n .kpi-row[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .category-chart[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .quick-actions-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n}"], changeDetection: 0 });
|
|
927
|
+
} }, dependencies: [i1.NgClass, i2.LoadingComponent], styles: [".overview-container[_ngcontent-%COMP%] {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n}\n\n\n\n.overview-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.header-left[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.overview-title[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 4px 0;\n}\n\n.overview-subtitle[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n}\n\n.btn-refresh[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-refresh[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.btn-refresh[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n font-weight: 600;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n\n\n.health-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 20px 24px;\n background: color-mix(in srgb, var(--mj-status-success) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n border-radius: 16px;\n margin-bottom: 24px;\n}\n\n.health-banner.health-warning[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n}\n\n.health-banner.health-critical[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n}\n\n.health-score-container[_ngcontent-%COMP%] {\n margin-right: 24px;\n}\n\n.health-score-ring[_ngcontent-%COMP%] {\n position: relative;\n width: 80px;\n height: 80px;\n}\n\n.circular-chart[_ngcontent-%COMP%] {\n display: block;\n margin: 0 auto;\n max-height: 80px;\n transform: rotate(-90deg);\n}\n\n.circle-bg[_ngcontent-%COMP%] {\n fill: none;\n stroke: var(--mj-border-default);\n stroke-width: 3.8;\n}\n\n.circle[_ngcontent-%COMP%] {\n fill: none;\n stroke-width: 3.8;\n stroke-linecap: round;\n stroke: var(--mj-status-success);\n animation: _ngcontent-%COMP%_progress 1s ease-out forwards;\n}\n\n.health-banner.health-warning[_ngcontent-%COMP%] .circle[_ngcontent-%COMP%] {\n stroke: var(--mj-status-warning);\n}\n\n.health-banner.health-critical[_ngcontent-%COMP%] .circle[_ngcontent-%COMP%] {\n stroke: var(--mj-status-error);\n}\n\n@keyframes _ngcontent-%COMP%_progress {\n 0% {\n stroke-dasharray: 0 100;\n }\n}\n\n.health-score-value[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.health-info[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.health-label[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-status-success);\n margin-bottom: 4px;\n}\n\n.health-banner.health-warning[_ngcontent-%COMP%] .health-label[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.health-banner.health-critical[_ngcontent-%COMP%] .health-label[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.health-details[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.health-alert[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--mj-status-error);\n font-weight: 500;\n font-size: 14px;\n}\n\n.health-warning-text[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--mj-status-warning);\n font-weight: 500;\n font-size: 14px;\n cursor: pointer;\n}\n\n.health-warning-text[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n}\n\n.health-ok[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--mj-status-success);\n font-weight: 500;\n font-size: 14px;\n}\n\n\n\n.kpi-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 16px 20px;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.kpi-card.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.kpi-card.clickable[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n\n.kpi-card.active[_ngcontent-%COMP%] .kpi-icon[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n}\n\n.kpi-card.warning[_ngcontent-%COMP%] .kpi-icon[_ngcontent-%COMP%] {\n background: var(--mj-status-warning);\n}\n\n.kpi-card.danger[_ngcontent-%COMP%] .kpi-icon[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n}\n\n.kpi-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n border-radius: 10px;\n margin-right: 14px;\n flex-shrink: 0;\n}\n\n.kpi-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--mj-text-inverse);\n}\n\n.kpi-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1.2;\n}\n\n.kpi-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n white-space: nowrap;\n}\n\n.kpi-trend[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n margin-left: 8px;\n color: var(--mj-text-disabled);\n}\n\n.kpi-trend.success[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.kpi-trend.warning[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.kpi-trend[_ngcontent-%COMP%] .percentage[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n}\n\n\n\n.content-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 1fr;\n grid-template-rows: auto auto;\n gap: 20px;\n margin-bottom: 24px;\n}\n\n.category-panel[_ngcontent-%COMP%] {\n grid-row: span 2;\n}\n\n.panel[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.panel-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.panel-subtitle[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-disabled);\n}\n\n.panel-action[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.panel-action[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.panel-body[_ngcontent-%COMP%] {\n padding: 20px;\n flex: 1;\n overflow-y: auto;\n}\n\n\n\n.category-chart[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 24px;\n height: 100%;\n}\n\n.donut-chart-container[_ngcontent-%COMP%] {\n position: relative;\n width: 200px;\n height: 200px;\n margin: 0 auto;\n}\n\n.donut-chart[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n transform: rotate(-90deg);\n}\n\n.donut-segment[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: opacity 0.2s ease;\n}\n\n.donut-segment[_ngcontent-%COMP%]:hover {\n opacity: 0.8;\n}\n\n.donut-center[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n text-align: center;\n}\n\n.donut-total[_ngcontent-%COMP%] {\n font-size: 32px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.donut-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n\n\n.category-legend[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.legend-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.legend-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n transform: translateX(4px);\n}\n\n.legend-color[_ngcontent-%COMP%] {\n width: 12px;\n height: 12px;\n border-radius: 4px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.legend-info[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.legend-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.legend-name[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.legend-value[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.legend-arrow[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n font-size: 10px;\n}\n\n\n\n.type-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.type-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.type-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.type-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.type-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.type-category[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-disabled);\n margin-top: 2px;\n}\n\n.type-stats[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 4px;\n flex-shrink: 0;\n margin-left: 16px;\n}\n\n.type-count[_ngcontent-%COMP%] {\n display: flex;\n align-items: baseline;\n gap: 4px;\n}\n\n.count-value[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.count-label[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-disabled);\n}\n\n.type-bar[_ngcontent-%COMP%] {\n width: 100px;\n height: 4px;\n background: var(--mj-border-default);\n border-radius: 2px;\n overflow: hidden;\n}\n\n.type-bar-fill[_ngcontent-%COMP%] {\n height: 100%;\n background: var(--mj-brand-primary);\n border-radius: 2px;\n transition: width 0.3s ease;\n}\n\n.type-indicators[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n}\n\n.indicator.active[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.indicator.warning[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 6px;\n}\n\n\n\n.activity-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.activity-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.activity-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.activity-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-radius: 6px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.activity-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-brand-primary);\n}\n\n.activity-icon.action-created[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n}\n\n.activity-icon.action-created[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.activity-icon.action-updated[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n.activity-icon.action-updated[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.activity-icon.action-accessed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n}\n\n.activity-icon.action-accessed[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.activity-icon.action-rotated[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n.activity-icon.action-rotated[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.activity-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.activity-name[_ngcontent-%COMP%] {\n font-weight: 500;\n font-size: 13px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.activity-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 2px;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.activity-type[_ngcontent-%COMP%] {\n background: var(--mj-border-default);\n padding: 1px 6px;\n border-radius: 4px;\n}\n\n.activity-action[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n.activity-time[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-disabled);\n white-space: nowrap;\n}\n\n\n\n.quick-actions[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n\n.quick-actions-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 12px;\n}\n\n.quick-actions-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 12px;\n}\n\n.quick-action[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.quick-action[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n transform: translateY(-2px);\n}\n\n.quick-action[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--mj-brand-primary);\n}\n\n.quick-action[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 32px;\n color: var(--mj-text-secondary);\n text-align: center;\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n margin-bottom: 12px;\n opacity: 0.5;\n}\n\n\n\n.security-notice[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n padding: 16px 20px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border-radius: 12px;\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.security-notice[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--mj-brand-primary);\n margin-right: 12px;\n margin-top: 2px;\n}\n\n.notice-content[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n}\n\n.notice-content[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n\n\n\n@media (max-width: 1024px) {\n .content-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .category-panel[_ngcontent-%COMP%] {\n grid-row: auto;\n }\n\n .category-chart[_ngcontent-%COMP%] {\n flex-direction: row;\n align-items: center;\n }\n\n .donut-chart-container[_ngcontent-%COMP%] {\n width: 160px;\n height: 160px;\n }\n\n .category-legend[_ngcontent-%COMP%] {\n flex: 1;\n }\n}\n\n@media (max-width: 768px) {\n .overview-container[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .overview-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-actions[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: flex-end;\n }\n\n .health-banner[_ngcontent-%COMP%] {\n flex-direction: column;\n text-align: center;\n }\n\n .health-score-container[_ngcontent-%COMP%] {\n margin-right: 0;\n margin-bottom: 16px;\n }\n\n .kpi-row[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .category-chart[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .quick-actions-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n}"], changeDetection: 0 });
|
|
929
928
|
};
|
|
930
929
|
CredentialsOverviewResourceComponent = __decorate([
|
|
931
930
|
RegisterClass(BaseResourceComponent, 'CredentialsOverviewResource')
|
|
@@ -934,6 +933,6 @@ export { CredentialsOverviewResourceComponent };
|
|
|
934
933
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CredentialsOverviewResourceComponent, [{
|
|
935
934
|
type: Component,
|
|
936
935
|
args: [{ standalone: false, selector: 'mj-credentials-overview-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"overview-container\">\n @if (isLoading) {\n <mj-loading text=\"Loading overview...\"></mj-loading>\n }\n\n @if (!isLoading) {\n <!-- Header with Actions -->\n <div class=\"overview-header\">\n <div class=\"header-left\">\n <h2 class=\"overview-title\">Credential Overview</h2>\n <p class=\"overview-subtitle\">Monitor and manage your organization's credentials</p>\n </div>\n <div class=\"header-actions\">\n <button class=\"btn-refresh\" (click)=\"refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n @if (UserCanCreateCredentials) {\n <button class=\"btn-primary\" (click)=\"createNewCredential()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>New Credential</span>\n </button>\n }\n </div>\n </div>\n <!-- Health Score Banner -->\n <div class=\"health-banner\" [ngClass]=\"getHealthClass()\">\n <div class=\"health-score-container\">\n <div class=\"health-score-ring\">\n <svg viewBox=\"0 0 36 36\" class=\"circular-chart\">\n <path class=\"circle-bg\"\n d=\"M18 2.0845\n a 15.9155 15.9155 0 0 1 0 31.831\n a 15.9155 15.9155 0 0 1 0 -31.831\"\n />\n <path class=\"circle\"\n [attr.stroke-dasharray]=\"getHealthScore() + ', 100'\"\n d=\"M18 2.0845\n a 15.9155 15.9155 0 0 1 0 31.831\n a 15.9155 15.9155 0 0 1 0 -31.831\"\n />\n </svg>\n <div class=\"health-score-value\">{{getHealthScore()}}</div>\n </div>\n </div>\n <div class=\"health-info\">\n <div class=\"health-label\">{{getHealthLabel()}}</div>\n <div class=\"health-details\">\n @if (expiredCredentials > 0) {\n <span class=\"health-alert\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{expiredCredentials}} expired\n </span>\n }\n @if (expiringSoonCount > 0) {\n <span class=\"health-warning-text\" (click)=\"viewExpiringCredentials()\">\n <i class=\"fa-solid fa-clock\"></i>\n {{expiringSoonCount}} expiring soon\n </span>\n }\n @if (expiredCredentials === 0 && expiringSoonCount === 0) {\n <span class=\"health-ok\">\n <i class=\"fa-solid fa-check-circle\"></i>\n All credentials healthy\n </span>\n }\n </div>\n </div>\n </div>\n <!-- KPI Cards Row -->\n <div class=\"kpi-row\">\n <div class=\"kpi-card clickable\" (click)=\"viewAllCredentials()\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-key\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{totalCredentials}}</div>\n <div class=\"kpi-label\">Total Credentials</div>\n </div>\n <div class=\"kpi-trend\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n </div>\n <div class=\"kpi-card active clickable\" (click)=\"viewAllCredentials()\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-check-circle\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{activeCredentials}}</div>\n <div class=\"kpi-label\">Active</div>\n </div>\n <div class=\"kpi-trend success\">\n <span class=\"percentage\">{{totalCredentials > 0 ? (activeCredentials / totalCredentials * 100).toFixed(0) : 0}}%</span>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-cubes\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{credentialTypes}}</div>\n <div class=\"kpi-label\">Types</div>\n </div>\n </div>\n <div class=\"kpi-card clickable\" [class.warning]=\"expiringSoonCount > 0\" (click)=\"viewExpiringCredentials()\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-clock\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{expiringSoonCount}}</div>\n <div class=\"kpi-label\">Expiring Soon</div>\n </div>\n @if (expiringSoonCount > 0) {\n <div class=\"kpi-trend warning\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n }\n </div>\n <div class=\"kpi-card\" [class.danger]=\"expiredCredentials > 0\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-circle-xmark\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{expiredCredentials}}</div>\n <div class=\"kpi-label\">Expired</div>\n </div>\n </div>\n </div>\n <!-- Content Grid -->\n <div class=\"content-grid\">\n <!-- Category Distribution Chart -->\n <div class=\"panel category-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-chart-pie\"></i>\n <span>Credentials by Category</span>\n </div>\n <span class=\"panel-subtitle\">Click to filter by category</span>\n </div>\n <div class=\"panel-body\">\n @if (categoryStats.length > 0) {\n <div class=\"category-chart\">\n <!-- Visual Donut Chart -->\n <div class=\"donut-chart-container\">\n <svg viewBox=\"0 0 100 100\" class=\"donut-chart\">\n <circle cx=\"50\" cy=\"50\" r=\"40\" fill=\"none\" stroke=\"var(--mj-border-default)\" stroke-width=\"12\"/>\n @for (stat of categoryStats; track stat; let i = $index) {\n <ng-container>\n <circle\n cx=\"50\" cy=\"50\" r=\"40\"\n fill=\"none\"\n [attr.stroke]=\"stat.color\"\n stroke-width=\"12\"\n [attr.stroke-dasharray]=\"stat.percentage * 2.51 + ' ' + (251 - stat.percentage * 2.51)\"\n [attr.stroke-dashoffset]=\"getDonutOffset(i)\"\n class=\"donut-segment\"\n (click)=\"onCategoryClick(stat)\"\n />\n </ng-container>\n }\n </svg>\n <div class=\"donut-center\">\n <div class=\"donut-total\">{{totalCredentials}}</div>\n <div class=\"donut-label\">Total</div>\n </div>\n </div>\n <!-- Legend -->\n <div class=\"category-legend\">\n @for (stat of categoryStats; track stat) {\n <div class=\"legend-item\" (click)=\"onCategoryClick(stat)\">\n <div class=\"legend-color\" [style.backgroundColor]=\"stat.color\"></div>\n <div class=\"legend-info\">\n <div class=\"legend-name\">\n <i [class]=\"stat.iconClass\"></i>\n {{stat.category}}\n </div>\n <div class=\"legend-value\">{{stat.count}} ({{stat.percentage}}%)</div>\n </div>\n <i class=\"fa-solid fa-chevron-right legend-arrow\"></i>\n </div>\n }\n </div>\n </div>\n }\n @if (categoryStats.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-folder-open\"></i>\n <span>No credentials configured</span>\n </div>\n }\n </div>\n </div>\n <!-- Types Breakdown -->\n <div class=\"panel types-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-cubes\"></i>\n <span>Top Credential Types</span>\n </div>\n <button class=\"panel-action\" (click)=\"viewAllTypes()\">\n View All <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n </div>\n <div class=\"panel-body\">\n @if (typeStats.length > 0) {\n <div class=\"type-list\">\n @for (type of typeStats.slice(0, 6); track type) {\n <div class=\"type-item\" (click)=\"onTypeClick(type)\">\n <div class=\"type-info\">\n <div class=\"type-name\">{{type.typeName}}</div>\n <div class=\"type-category\">{{type.category}}</div>\n </div>\n <div class=\"type-stats\">\n <div class=\"type-count\">\n <span class=\"count-value\">{{type.credentialCount}}</span>\n <span class=\"count-label\">credentials</span>\n </div>\n <div class=\"type-bar\">\n <div class=\"type-bar-fill\"\n [style.width.%]=\"totalCredentials > 0 ? (type.credentialCount / totalCredentials * 100) : 0\">\n </div>\n </div>\n <div class=\"type-indicators\">\n @if (type.activeCount > 0) {\n <span class=\"indicator active\" title=\"Active\">\n <i class=\"fa-solid fa-circle\"></i> {{type.activeCount}}\n </span>\n }\n @if (type.expiringCount > 0) {\n <span class=\"indicator warning\" title=\"Expiring Soon\">\n <i class=\"fa-solid fa-clock\"></i> {{type.expiringCount}}\n </span>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n @if (typeStats.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-shapes\"></i>\n <span>No credential types configured</span>\n </div>\n }\n </div>\n </div>\n <!-- Recent Activity -->\n <div class=\"panel activity-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n <span>Recent Activity</span>\n </div>\n <button class=\"panel-action\" (click)=\"viewAuditLog()\">\n View All <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n </div>\n <div class=\"panel-body\">\n @if (recentActivity.length > 0) {\n <div class=\"activity-list\">\n @for (activity of recentActivity; track activity) {\n <div class=\"activity-item\" (click)=\"onActivityClick(activity)\">\n <div class=\"activity-icon\" [ngClass]=\"getActionClass(activity.action)\">\n <i [class]=\"getActionIcon(activity.action)\"></i>\n </div>\n <div class=\"activity-info\">\n <div class=\"activity-name\">{{activity.credentialName}}</div>\n <div class=\"activity-meta\">\n <span class=\"activity-type\">{{activity.typeName}}</span>\n <span class=\"activity-action\">{{activity.action}}</span>\n @if (activity.user) {\n <span class=\"activity-user\">by {{activity.user}}</span>\n }\n </div>\n </div>\n <div class=\"activity-time\">\n {{formatDate(activity.date)}}\n </div>\n </div>\n }\n </div>\n }\n @if (recentActivity.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No recent activity</span>\n </div>\n }\n </div>\n </div>\n </div>\n <!-- Quick Actions -->\n @if (UserCanCreateCredentials) {\n <div class=\"quick-actions\">\n <div class=\"quick-actions-title\">Quick Actions</div>\n <div class=\"quick-actions-grid\">\n <button class=\"quick-action\" (click)=\"createNewCredential()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Add Credential</span>\n </button>\n <button class=\"quick-action\" (click)=\"viewAllTypes()\">\n <i class=\"fa-solid fa-shapes\"></i>\n <span>Manage Types</span>\n </button>\n <button class=\"quick-action\" (click)=\"viewAllCategories()\">\n <i class=\"fa-solid fa-folder-tree\"></i>\n <span>Categories</span>\n </button>\n <button class=\"quick-action\" (click)=\"viewAuditLog()\">\n <i class=\"fa-solid fa-clipboard-list\"></i>\n <span>Audit Log</span>\n </button>\n </div>\n </div>\n }\n <!-- Security Notice -->\n <div class=\"security-notice\">\n <i class=\"fa-solid fa-shield-check\"></i>\n <div class=\"notice-content\">\n <strong>Security Note:</strong> All credential values are encrypted.\n Access to credentials is logged in the audit trail for compliance and security monitoring.\n </div>\n </div>\n }\n</div>\n", styles: [".overview-container {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n}\n\n/* Header */\n.overview-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.header-left {\n flex: 1;\n}\n\n.overview-title {\n font-size: 24px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 4px 0;\n}\n\n.overview-subtitle {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.header-actions {\n display: flex;\n gap: 12px;\n}\n\n.btn-refresh {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-refresh:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.btn-refresh i {\n color: var(--mj-text-secondary);\n}\n\n.btn-primary {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n font-weight: 600;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-primary:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n/* Health Banner */\n.health-banner {\n display: flex;\n align-items: center;\n padding: 20px 24px;\n background: color-mix(in srgb, var(--mj-status-success) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n border-radius: 16px;\n margin-bottom: 24px;\n}\n\n.health-banner.health-warning {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n}\n\n.health-banner.health-critical {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n}\n\n.health-score-container {\n margin-right: 24px;\n}\n\n.health-score-ring {\n position: relative;\n width: 80px;\n height: 80px;\n}\n\n.circular-chart {\n display: block;\n margin: 0 auto;\n max-height: 80px;\n transform: rotate(-90deg);\n}\n\n.circle-bg {\n fill: none;\n stroke: var(--mj-border-default);\n stroke-width: 3.8;\n}\n\n.circle {\n fill: none;\n stroke-width: 3.8;\n stroke-linecap: round;\n stroke: var(--mj-status-success);\n animation: progress 1s ease-out forwards;\n}\n\n.health-banner.health-warning .circle {\n stroke: var(--mj-status-warning);\n}\n\n.health-banner.health-critical .circle {\n stroke: var(--mj-status-error);\n}\n\n@keyframes progress {\n 0% {\n stroke-dasharray: 0 100;\n }\n}\n\n.health-score-value {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.health-info {\n flex: 1;\n}\n\n.health-label {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-status-success);\n margin-bottom: 4px;\n}\n\n.health-banner.health-warning .health-label {\n color: var(--mj-status-warning);\n}\n\n.health-banner.health-critical .health-label {\n color: var(--mj-status-error);\n}\n\n.health-details {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.health-alert {\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--mj-status-error);\n font-weight: 500;\n font-size: 14px;\n}\n\n.health-warning-text {\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--mj-status-warning);\n font-weight: 500;\n font-size: 14px;\n cursor: pointer;\n}\n\n.health-warning-text:hover {\n text-decoration: underline;\n}\n\n.health-ok {\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--mj-status-success);\n font-weight: 500;\n font-size: 14px;\n}\n\n/* KPI Cards */\n.kpi-row {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card {\n display: flex;\n align-items: center;\n padding: 16px 20px;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.kpi-card.clickable {\n cursor: pointer;\n}\n\n.kpi-card.clickable:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n\n.kpi-card.active .kpi-icon {\n background: var(--mj-status-success);\n}\n\n.kpi-card.warning .kpi-icon {\n background: var(--mj-status-warning);\n}\n\n.kpi-card.danger .kpi-icon {\n background: var(--mj-status-error);\n}\n\n.kpi-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n border-radius: 10px;\n margin-right: 14px;\n flex-shrink: 0;\n}\n\n.kpi-icon i {\n font-size: 20px;\n color: var(--mj-text-inverse);\n}\n\n.kpi-content {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1.2;\n}\n\n.kpi-label {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n white-space: nowrap;\n}\n\n.kpi-trend {\n display: flex;\n align-items: center;\n margin-left: 8px;\n color: var(--mj-text-disabled);\n}\n\n.kpi-trend.success {\n color: var(--mj-status-success);\n}\n\n.kpi-trend.warning {\n color: var(--mj-status-warning);\n}\n\n.kpi-trend .percentage {\n font-size: 12px;\n font-weight: 600;\n}\n\n/* Content Grid */\n.content-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n grid-template-rows: auto auto;\n gap: 20px;\n margin-bottom: 24px;\n}\n\n.category-panel {\n grid-row: span 2;\n}\n\n.panel {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.panel-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.panel-title i {\n color: var(--mj-brand-primary);\n}\n\n.panel-subtitle {\n font-size: 12px;\n color: var(--mj-text-disabled);\n}\n\n.panel-action {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.panel-action:hover {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.panel-body {\n padding: 20px;\n flex: 1;\n overflow-y: auto;\n}\n\n/* Category Chart */\n.category-chart {\n display: flex;\n flex-direction: column;\n gap: 24px;\n height: 100%;\n}\n\n.donut-chart-container {\n position: relative;\n width: 200px;\n height: 200px;\n margin: 0 auto;\n}\n\n.donut-chart {\n width: 100%;\n height: 100%;\n transform: rotate(-90deg);\n}\n\n.donut-segment {\n cursor: pointer;\n transition: opacity 0.2s ease;\n}\n\n.donut-segment:hover {\n opacity: 0.8;\n}\n\n.donut-center {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n text-align: center;\n}\n\n.donut-total {\n font-size: 32px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.donut-label {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n/* Category Legend */\n.category-legend {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.legend-item {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.legend-item:hover {\n background: var(--mj-bg-surface-sunken);\n transform: translateX(4px);\n}\n\n.legend-color {\n width: 12px;\n height: 12px;\n border-radius: 4px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.legend-info {\n flex: 1;\n}\n\n.legend-name {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.legend-name i {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.legend-value {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.legend-arrow {\n color: var(--mj-text-disabled);\n font-size: 10px;\n}\n\n/* Type List */\n.type-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.type-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.type-item:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.type-info {\n flex: 1;\n min-width: 0;\n}\n\n.type-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.type-category {\n font-size: 11px;\n color: var(--mj-text-disabled);\n margin-top: 2px;\n}\n\n.type-stats {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 4px;\n flex-shrink: 0;\n margin-left: 16px;\n}\n\n.type-count {\n display: flex;\n align-items: baseline;\n gap: 4px;\n}\n\n.count-value {\n font-size: 16px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.count-label {\n font-size: 11px;\n color: var(--mj-text-disabled);\n}\n\n.type-bar {\n width: 100px;\n height: 4px;\n background: var(--mj-border-default);\n border-radius: 2px;\n overflow: hidden;\n}\n\n.type-bar-fill {\n height: 100%;\n background: var(--mj-brand-primary);\n border-radius: 2px;\n transition: width 0.3s ease;\n}\n\n.type-indicators {\n display: flex;\n gap: 8px;\n}\n\n.indicator {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n}\n\n.indicator.active {\n color: var(--mj-status-success);\n}\n\n.indicator.warning {\n color: var(--mj-status-warning);\n}\n\n.indicator i {\n font-size: 6px;\n}\n\n/* Activity List */\n.activity-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.activity-item {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.activity-item:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.activity-icon {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-radius: 6px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.activity-icon i {\n font-size: 12px;\n color: var(--mj-brand-primary);\n}\n\n.activity-icon.action-created {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n}\n\n.activity-icon.action-created i {\n color: var(--mj-status-success);\n}\n\n.activity-icon.action-updated {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n.activity-icon.action-updated i {\n color: var(--mj-brand-primary);\n}\n\n.activity-icon.action-accessed {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n}\n\n.activity-icon.action-accessed i {\n color: var(--mj-status-warning);\n}\n\n.activity-icon.action-rotated {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n.activity-icon.action-rotated i {\n color: var(--mj-brand-primary);\n}\n\n.activity-info {\n flex: 1;\n min-width: 0;\n}\n\n.activity-name {\n font-weight: 500;\n font-size: 13px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.activity-meta {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 2px;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.activity-type {\n background: var(--mj-border-default);\n padding: 1px 6px;\n border-radius: 4px;\n}\n\n.activity-action {\n font-weight: 500;\n}\n\n.activity-time {\n font-size: 11px;\n color: var(--mj-text-disabled);\n white-space: nowrap;\n}\n\n/* Quick Actions */\n.quick-actions {\n margin-bottom: 24px;\n}\n\n.quick-actions-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 12px;\n}\n\n.quick-actions-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 12px;\n}\n\n.quick-action {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.quick-action:hover {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n transform: translateY(-2px);\n}\n\n.quick-action i {\n font-size: 20px;\n color: var(--mj-brand-primary);\n}\n\n.quick-action span {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 32px;\n color: var(--mj-text-secondary);\n text-align: center;\n}\n\n.empty-state i {\n font-size: 32px;\n margin-bottom: 12px;\n opacity: 0.5;\n}\n\n/* Security Notice */\n.security-notice {\n display: flex;\n align-items: flex-start;\n padding: 16px 20px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border-radius: 12px;\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.security-notice i {\n font-size: 20px;\n color: var(--mj-brand-primary);\n margin-right: 12px;\n margin-top: 2px;\n}\n\n.notice-content {\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n}\n\n.notice-content strong {\n font-weight: 600;\n}\n\n/* Responsive */\n@media (max-width: 1024px) {\n .content-grid {\n grid-template-columns: 1fr;\n }\n\n .category-panel {\n grid-row: auto;\n }\n\n .category-chart {\n flex-direction: row;\n align-items: center;\n }\n\n .donut-chart-container {\n width: 160px;\n height: 160px;\n }\n\n .category-legend {\n flex: 1;\n }\n}\n\n@media (max-width: 768px) {\n .overview-container {\n padding: 16px;\n }\n\n .overview-header {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: flex-end;\n }\n\n .health-banner {\n flex-direction: column;\n text-align: center;\n }\n\n .health-score-container {\n margin-right: 0;\n margin-bottom: 16px;\n }\n\n .kpi-row {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .category-chart {\n flex-direction: column;\n }\n\n .quick-actions-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n"] }]
|
|
937
|
-
}], () => [{ type: i0.ChangeDetectorRef }
|
|
936
|
+
}], () => [{ type: i0.ChangeDetectorRef }], null); })();
|
|
938
937
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialsOverviewResourceComponent, { className: "CredentialsOverviewResourceComponent", filePath: "src/Credentials/components/credentials-overview-resource.component.ts", lineNumber: 50 }); })();
|
|
939
938
|
//# sourceMappingURL=credentials-overview-resource.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials-overview-resource.component.js","sourceRoot":"","sources":["../../../src/Credentials/components/credentials-overview-resource.component.ts","../../../src/Credentials/components/credentials-overview-resource.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { ResourceData, MJCredentialEntity, MJCredentialTypeEntity, MJCredentialCategoryEntity, MJAuditLogEntity } from '@memberjunction/core-entities';\nimport { RegisterClass , UUIDsEqual } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { RunView, Metadata, CompositeKey } from '@memberjunction/core';\ninterface CategoryStat {\n category: string;\n categoryId: string;\n count: number;\n iconClass: string;\n color: string;\n percentage: number;\n}\n\ninterface TypeStat {\n typeId: string;\n typeName: string;\n category: string;\n credentialCount: number;\n activeCount: number;\n expiringCount: number;\n}\n\ninterface ActivityItem {\n id: string;\n credentialName: string;\n credentialId: string;\n typeName: string;\n action: 'Created' | 'Updated' | 'Accessed' | 'Rotated';\n date: Date;\n user?: string;\n}\n\ninterface UsageTrendPoint {\n timestamp: Date;\n accessCount: number;\n uniqueCredentials: number;\n successRate: number;\n}\n\n@RegisterClass(BaseResourceComponent, 'CredentialsOverviewResource')\n@Component({\n standalone: false,\n selector: 'mj-credentials-overview-resource',\n templateUrl: './credentials-overview-resource.component.html',\n styleUrls: ['./credentials-overview-resource.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class CredentialsOverviewResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public isLoading = true;\n\n // Summary stats\n public totalCredentials = 0;\n public activeCredentials = 0;\n public expiredCredentials = 0;\n public expiringSoonCount = 0;\n public credentialTypes = 0;\n public categories = 0;\n\n // Grouped data\n public categoryStats: CategoryStat[] = [];\n public typeStats: TypeStat[] = [];\n public recentActivity: ActivityItem[] = [];\n public usageTrend: UsageTrendPoint[] = [];\n\n // Raw data\n private credentials: MJCredentialEntity[] = [];\n private types: MJCredentialTypeEntity[] = [];\n private categoryList: MJCredentialCategoryEntity[] = [];\n private auditLogs: MJAuditLogEntity[] = [];\n\n // Permissions\n private _metadata = new Metadata();\n private _permissionCache = new Map<string, boolean>();\n\n // Category colors for charts - using CSS custom properties via getComputedStyle at runtime\n // These are semantic fallback values; the actual tokens are resolved from the theme\n private categoryColors: Record<string, string> = {\n 'AI': 'var(--mj-brand-primary)',\n 'Communication': 'var(--mj-brand-primary)',\n 'Storage': 'var(--mj-status-success)',\n 'Database': 'var(--mj-status-warning)',\n 'Authentication': 'var(--mj-status-error)',\n 'Integration': 'var(--mj-brand-primary)'\n };\n\n private destroy$ = new Subject<void>();\n\n constructor(\n private cdr: ChangeDetectorRef,\n private navigationService: NavigationService\n ) {\n super();\n }\n\n ngOnInit(): void {\n this.loadData();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Overview';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-chart-pie';\n }\n\n // === Permission Checks ===\n public get UserCanCreateCredentials(): boolean {\n return this.checkEntityPermission('MJ: Credentials', 'Create');\n }\n\n public get UserCanUpdateCredentials(): boolean {\n return this.checkEntityPermission('MJ: Credentials', 'Update');\n }\n\n private checkEntityPermission(entityName: string, permissionType: 'Create' | 'Read' | 'Update' | 'Delete'): boolean {\n const cacheKey = `${entityName}_${permissionType}`;\n\n if (this._permissionCache.has(cacheKey)) {\n return this._permissionCache.get(cacheKey)!;\n }\n\n try {\n const entityInfo = this._metadata.Entities.find(e => e.Name === entityName);\n if (!entityInfo) {\n this._permissionCache.set(cacheKey, false);\n return false;\n }\n\n const userPermissions = entityInfo.GetUserPermisions(this._metadata.CurrentUser);\n let hasPermission = false;\n\n switch (permissionType) {\n case 'Create': hasPermission = userPermissions.CanCreate; break;\n case 'Read': hasPermission = userPermissions.CanRead; break;\n case 'Update': hasPermission = userPermissions.CanUpdate; break;\n case 'Delete': hasPermission = userPermissions.CanDelete; break;\n }\n\n this._permissionCache.set(cacheKey, hasPermission);\n return hasPermission;\n } catch (error) {\n this._permissionCache.set(cacheKey, false);\n return false;\n }\n }\n\n private async loadData(): Promise<void> {\n try {\n this.isLoading = true;\n this.cdr.markForCheck();\n\n const rv = new RunView();\n\n // Calculate date range for audit logs (last 30 days)\n const thirtyDaysAgo = new Date();\n thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);\n const dateFilter = `__mj_CreatedAt >= '${thirtyDaysAgo.toISOString()}'`;\n\n // Load all data in parallel using RunViews\n const [credResult, typeResult, categoryResult, auditResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Credentials',\n ResultType: 'entity_object'\n },\n {\n EntityName: 'MJ: Credential Types',\n ResultType: 'entity_object'\n },\n {\n EntityName: 'MJ: Credential Categories',\n ResultType: 'entity_object'\n },\n {\n EntityName: 'MJ: Audit Logs',\n ExtraFilter: `AuditLogType LIKE '%Credential%' AND ${dateFilter}`,\n OrderBy: '__mj_CreatedAt DESC',\n MaxRows: 100,\n ResultType: 'entity_object'\n }\n ]);\n\n if (credResult.Success) {\n this.credentials = credResult.Results as MJCredentialEntity[];\n this.processCredentialStats();\n }\n\n if (typeResult.Success) {\n this.types = typeResult.Results as MJCredentialTypeEntity[];\n this.credentialTypes = this.types.length;\n this.processTypeStats();\n }\n\n if (categoryResult.Success) {\n this.categoryList = categoryResult.Results as MJCredentialCategoryEntity[];\n this.categories = this.categoryList.length;\n this.processCategoryStats();\n }\n\n if (auditResult.Success) {\n this.auditLogs = auditResult.Results as MJAuditLogEntity[];\n this.processActivityAndTrends();\n }\n\n // Build recent activity from credentials if no audit logs\n if (this.recentActivity.length === 0) {\n this.buildActivityFromCredentials();\n }\n\n } catch (error) {\n console.error('Error loading credentials overview:', error);\n } finally {\n this.isLoading = false;\n this.NotifyLoadComplete();\n this.cdr.markForCheck();\n }\n }\n\n private processCredentialStats(): void {\n this.totalCredentials = this.credentials.length;\n this.activeCredentials = this.credentials.filter(c => c.IsActive).length;\n\n const now = new Date();\n const thirtyDaysFromNow = new Date();\n thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30);\n\n this.expiredCredentials = this.credentials.filter(c =>\n c.ExpiresAt && new Date(c.ExpiresAt) < now\n ).length;\n\n this.expiringSoonCount = this.credentials.filter(c =>\n c.ExpiresAt &&\n new Date(c.ExpiresAt) >= now &&\n new Date(c.ExpiresAt) <= thirtyDaysFromNow &&\n c.IsActive\n ).length;\n }\n\n private processTypeStats(): void {\n const now = new Date();\n const thirtyDaysFromNow = new Date();\n thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30);\n\n this.typeStats = this.types.map(type => {\n const typeCredentials = this.credentials.filter(c => UUIDsEqual(c.CredentialTypeID, type.ID));\n\n return {\n typeId: type.ID,\n typeName: type.Name,\n category: type.Category,\n credentialCount: typeCredentials.length,\n activeCount: typeCredentials.filter(c => c.IsActive).length,\n expiringCount: typeCredentials.filter(c =>\n c.ExpiresAt &&\n new Date(c.ExpiresAt) >= now &&\n new Date(c.ExpiresAt) <= thirtyDaysFromNow\n ).length\n };\n }).sort((a, b) => b.credentialCount - a.credentialCount);\n }\n\n private processCategoryStats(): void {\n const categoryMap = new Map<string, CategoryStat>();\n\n // Initialize from credential types\n for (const type of this.types) {\n const category = type.Category;\n const existing = categoryMap.get(category);\n const categoryCredentials = this.credentials.filter(c => UUIDsEqual(c.CredentialTypeID, type.ID));\n\n if (existing) {\n existing.count += categoryCredentials.length;\n } else {\n categoryMap.set(category, {\n category: category,\n categoryId: category, // Use category name as ID for filtering\n count: categoryCredentials.length,\n iconClass: this.getCategoryIcon(category),\n color: this.categoryColors[category] || 'var(--mj-text-muted)',\n percentage: 0\n });\n }\n }\n\n // Calculate percentages\n const total = this.totalCredentials || 1;\n categoryMap.forEach(stat => {\n stat.percentage = Math.round((stat.count / total) * 100);\n });\n\n this.categoryStats = Array.from(categoryMap.values())\n .sort((a, b) => b.count - a.count);\n }\n\n private processActivityAndTrends(): void {\n // Process recent activity from audit logs\n this.recentActivity = this.auditLogs\n .slice(0, 10)\n .map(log => ({\n id: log.ID,\n credentialName: this.extractCredentialName(log.Description || ''),\n credentialId: '', // Would need to parse from log\n typeName: 'Credential',\n action: this.extractAction(log.Description || '') as ActivityItem['action'],\n date: new Date(log.__mj_CreatedAt),\n user: log.User\n }));\n\n // Build usage trend data (group by day)\n const trendMap = new Map<string, UsageTrendPoint>();\n const uniqueCredentialsPerDay = new Map<string, Set<string>>();\n\n for (const log of this.auditLogs) {\n const dateKey = new Date(log.__mj_CreatedAt).toISOString().split('T')[0];\n\n if (!trendMap.has(dateKey)) {\n trendMap.set(dateKey, {\n timestamp: new Date(dateKey),\n accessCount: 0,\n uniqueCredentials: 0,\n successRate: 100\n });\n uniqueCredentialsPerDay.set(dateKey, new Set());\n }\n\n const point = trendMap.get(dateKey)!;\n point.accessCount++;\n\n // Track unique credentials (would need proper parsing)\n const credId = this.extractCredentialId(log.Description || '');\n if (credId) {\n uniqueCredentialsPerDay.get(dateKey)!.add(credId);\n }\n }\n\n // Finalize unique counts\n trendMap.forEach((point, dateKey) => {\n point.uniqueCredentials = uniqueCredentialsPerDay.get(dateKey)?.size || 0;\n });\n\n this.usageTrend = Array.from(trendMap.values())\n .sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());\n }\n\n private buildActivityFromCredentials(): void {\n this.recentActivity = this.credentials\n .filter(c => c.__mj_UpdatedAt)\n .sort((a, b) => new Date(b.__mj_UpdatedAt).getTime() - new Date(a.__mj_UpdatedAt).getTime())\n .slice(0, 10)\n .map(c => ({\n id: c.ID,\n credentialName: c.Name,\n credentialId: c.ID,\n typeName: c.CredentialType || 'Unknown',\n action: 'Updated' as const,\n date: new Date(c.__mj_UpdatedAt),\n user: undefined\n }));\n }\n\n private extractCredentialName(description: string): string {\n // Try to extract credential name from audit log description\n const match = description.match(/credential[:\\s]+['\"]?([^'\"]+)['\"]?/i);\n return match ? match[1] : 'Unknown Credential';\n }\n\n private extractAction(description: string): string {\n if (description.toLowerCase().includes('creat')) return 'Created';\n if (description.toLowerCase().includes('rotat')) return 'Rotated';\n if (description.toLowerCase().includes('access')) return 'Accessed';\n return 'Updated';\n }\n\n private extractCredentialId(description: string): string {\n const match = description.match(/[a-f0-9-]{36}/i);\n return match ? match[0] : '';\n }\n\n private getCategoryIcon(category: string): string {\n const iconMap: Record<string, string> = {\n 'AI': 'fa-solid fa-brain',\n 'Communication': 'fa-solid fa-envelope',\n 'Storage': 'fa-solid fa-cloud',\n 'Database': 'fa-solid fa-database',\n 'Authentication': 'fa-solid fa-shield-halved',\n 'Integration': 'fa-solid fa-plug'\n };\n return iconMap[category] || 'fa-solid fa-key';\n }\n\n // === Navigation Actions ===\n\n public createNewCredential(): void {\n // Navigate to Credentials tab with openCreatePanel flag to show the slide-in editor\n this.navigationService.OpenNavItemByName('Credentials', {\n openCreatePanel: true\n });\n }\n\n public openCredential(credentialId: string): void {\n const key = new CompositeKey([{ FieldName: 'ID', Value: credentialId }]);\n this.navigationService.OpenEntityRecord('MJ: Credentials', key);\n }\n\n public onCategoryClick(category: CategoryStat): void {\n // Navigate to types nav item with category filter\n this.navigationService.OpenNavItemByName('Types', {\n categoryFilter: category.category\n });\n }\n\n public onTypeClick(typeStat: TypeStat): void {\n // Navigate to credentials nav item with type filter\n this.navigationService.OpenNavItemByName('Credentials', {\n typeId: typeStat.typeId\n });\n }\n\n public onActivityClick(activity: ActivityItem): void {\n if (activity.credentialId) {\n this.openCredential(activity.credentialId);\n }\n }\n\n public viewAllCredentials(): void {\n this.navigationService.OpenNavItemByName('Credentials');\n }\n\n public viewAuditLog(): void {\n this.navigationService.OpenNavItemByName('Audit Log');\n }\n\n public viewAllTypes(): void {\n this.navigationService.OpenNavItemByName('Types');\n }\n\n public viewAllCategories(): void {\n this.navigationService.OpenNavItemByName('Categories');\n }\n\n public viewExpiringCredentials(): void {\n this.navigationService.OpenNavItemByName('Credentials', {\n filter: 'expiring'\n });\n }\n\n // === Formatting Helpers ===\n\n public formatDate(date: Date): string {\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return 'Just now';\n if (diffMins < 60) return `${diffMins}m ago`;\n if (diffHours < 24) return `${diffHours}h ago`;\n if (diffDays < 7) return `${diffDays}d ago`;\n\n return date.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n });\n }\n\n public getActionIcon(action: string): string {\n const iconMap: Record<string, string> = {\n 'Created': 'fa-solid fa-plus',\n 'Updated': 'fa-solid fa-pen',\n 'Accessed': 'fa-solid fa-eye',\n 'Rotated': 'fa-solid fa-rotate'\n };\n return iconMap[action] || 'fa-solid fa-circle';\n }\n\n public getActionClass(action: string): string {\n const classMap: Record<string, string> = {\n 'Created': 'action-created',\n 'Updated': 'action-updated',\n 'Accessed': 'action-accessed',\n 'Rotated': 'action-rotated'\n };\n return classMap[action] || '';\n }\n\n public refresh(): void {\n this.loadData();\n }\n\n public getHealthScore(): number {\n if (this.totalCredentials === 0) return 100;\n\n const activeRatio = this.activeCredentials / this.totalCredentials;\n const expiredPenalty = (this.expiredCredentials / this.totalCredentials) * 30;\n const expiringPenalty = (this.expiringSoonCount / this.totalCredentials) * 15;\n\n return Math.max(0, Math.min(100, Math.round((activeRatio * 100) - expiredPenalty - expiringPenalty)));\n }\n\n public getHealthClass(): string {\n const score = this.getHealthScore();\n if (score >= 80) return 'health-good';\n if (score >= 60) return 'health-warning';\n return 'health-critical';\n }\n\n public getHealthLabel(): string {\n const score = this.getHealthScore();\n if (score >= 80) return 'Healthy';\n if (score >= 60) return 'Needs Attention';\n return 'Critical';\n }\n\n public getDonutOffset(index: number): number {\n // Calculate cumulative offset for donut chart segments\n // Each segment starts where the previous one ended\n // The circumference is 251 (2 * PI * 40)\n let offset = 63; // Start at top (25% of circumference = 90 degrees rotation)\n\n for (let i = 0; i < index; i++) {\n offset -= this.categoryStats[i].percentage * 2.51;\n }\n\n return offset;\n }\n}\n","<div class=\"overview-container\">\n @if (isLoading) {\n <mj-loading text=\"Loading overview...\"></mj-loading>\n }\n\n @if (!isLoading) {\n <!-- Header with Actions -->\n <div class=\"overview-header\">\n <div class=\"header-left\">\n <h2 class=\"overview-title\">Credential Overview</h2>\n <p class=\"overview-subtitle\">Monitor and manage your organization's credentials</p>\n </div>\n <div class=\"header-actions\">\n <button class=\"btn-refresh\" (click)=\"refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n @if (UserCanCreateCredentials) {\n <button class=\"btn-primary\" (click)=\"createNewCredential()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>New Credential</span>\n </button>\n }\n </div>\n </div>\n <!-- Health Score Banner -->\n <div class=\"health-banner\" [ngClass]=\"getHealthClass()\">\n <div class=\"health-score-container\">\n <div class=\"health-score-ring\">\n <svg viewBox=\"0 0 36 36\" class=\"circular-chart\">\n <path class=\"circle-bg\"\n d=\"M18 2.0845\n a 15.9155 15.9155 0 0 1 0 31.831\n a 15.9155 15.9155 0 0 1 0 -31.831\"\n />\n <path class=\"circle\"\n [attr.stroke-dasharray]=\"getHealthScore() + ', 100'\"\n d=\"M18 2.0845\n a 15.9155 15.9155 0 0 1 0 31.831\n a 15.9155 15.9155 0 0 1 0 -31.831\"\n />\n </svg>\n <div class=\"health-score-value\">{{getHealthScore()}}</div>\n </div>\n </div>\n <div class=\"health-info\">\n <div class=\"health-label\">{{getHealthLabel()}}</div>\n <div class=\"health-details\">\n @if (expiredCredentials > 0) {\n <span class=\"health-alert\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{expiredCredentials}} expired\n </span>\n }\n @if (expiringSoonCount > 0) {\n <span class=\"health-warning-text\" (click)=\"viewExpiringCredentials()\">\n <i class=\"fa-solid fa-clock\"></i>\n {{expiringSoonCount}} expiring soon\n </span>\n }\n @if (expiredCredentials === 0 && expiringSoonCount === 0) {\n <span class=\"health-ok\">\n <i class=\"fa-solid fa-check-circle\"></i>\n All credentials healthy\n </span>\n }\n </div>\n </div>\n </div>\n <!-- KPI Cards Row -->\n <div class=\"kpi-row\">\n <div class=\"kpi-card clickable\" (click)=\"viewAllCredentials()\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-key\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{totalCredentials}}</div>\n <div class=\"kpi-label\">Total Credentials</div>\n </div>\n <div class=\"kpi-trend\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n </div>\n <div class=\"kpi-card active clickable\" (click)=\"viewAllCredentials()\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-check-circle\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{activeCredentials}}</div>\n <div class=\"kpi-label\">Active</div>\n </div>\n <div class=\"kpi-trend success\">\n <span class=\"percentage\">{{totalCredentials > 0 ? (activeCredentials / totalCredentials * 100).toFixed(0) : 0}}%</span>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-cubes\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{credentialTypes}}</div>\n <div class=\"kpi-label\">Types</div>\n </div>\n </div>\n <div class=\"kpi-card clickable\" [class.warning]=\"expiringSoonCount > 0\" (click)=\"viewExpiringCredentials()\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-clock\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{expiringSoonCount}}</div>\n <div class=\"kpi-label\">Expiring Soon</div>\n </div>\n @if (expiringSoonCount > 0) {\n <div class=\"kpi-trend warning\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n }\n </div>\n <div class=\"kpi-card\" [class.danger]=\"expiredCredentials > 0\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-circle-xmark\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{expiredCredentials}}</div>\n <div class=\"kpi-label\">Expired</div>\n </div>\n </div>\n </div>\n <!-- Content Grid -->\n <div class=\"content-grid\">\n <!-- Category Distribution Chart -->\n <div class=\"panel category-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-chart-pie\"></i>\n <span>Credentials by Category</span>\n </div>\n <span class=\"panel-subtitle\">Click to filter by category</span>\n </div>\n <div class=\"panel-body\">\n @if (categoryStats.length > 0) {\n <div class=\"category-chart\">\n <!-- Visual Donut Chart -->\n <div class=\"donut-chart-container\">\n <svg viewBox=\"0 0 100 100\" class=\"donut-chart\">\n <circle cx=\"50\" cy=\"50\" r=\"40\" fill=\"none\" stroke=\"var(--mj-border-default)\" stroke-width=\"12\"/>\n @for (stat of categoryStats; track stat; let i = $index) {\n <ng-container>\n <circle\n cx=\"50\" cy=\"50\" r=\"40\"\n fill=\"none\"\n [attr.stroke]=\"stat.color\"\n stroke-width=\"12\"\n [attr.stroke-dasharray]=\"stat.percentage * 2.51 + ' ' + (251 - stat.percentage * 2.51)\"\n [attr.stroke-dashoffset]=\"getDonutOffset(i)\"\n class=\"donut-segment\"\n (click)=\"onCategoryClick(stat)\"\n />\n </ng-container>\n }\n </svg>\n <div class=\"donut-center\">\n <div class=\"donut-total\">{{totalCredentials}}</div>\n <div class=\"donut-label\">Total</div>\n </div>\n </div>\n <!-- Legend -->\n <div class=\"category-legend\">\n @for (stat of categoryStats; track stat) {\n <div class=\"legend-item\" (click)=\"onCategoryClick(stat)\">\n <div class=\"legend-color\" [style.backgroundColor]=\"stat.color\"></div>\n <div class=\"legend-info\">\n <div class=\"legend-name\">\n <i [class]=\"stat.iconClass\"></i>\n {{stat.category}}\n </div>\n <div class=\"legend-value\">{{stat.count}} ({{stat.percentage}}%)</div>\n </div>\n <i class=\"fa-solid fa-chevron-right legend-arrow\"></i>\n </div>\n }\n </div>\n </div>\n }\n @if (categoryStats.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-folder-open\"></i>\n <span>No credentials configured</span>\n </div>\n }\n </div>\n </div>\n <!-- Types Breakdown -->\n <div class=\"panel types-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-cubes\"></i>\n <span>Top Credential Types</span>\n </div>\n <button class=\"panel-action\" (click)=\"viewAllTypes()\">\n View All <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n </div>\n <div class=\"panel-body\">\n @if (typeStats.length > 0) {\n <div class=\"type-list\">\n @for (type of typeStats.slice(0, 6); track type) {\n <div class=\"type-item\" (click)=\"onTypeClick(type)\">\n <div class=\"type-info\">\n <div class=\"type-name\">{{type.typeName}}</div>\n <div class=\"type-category\">{{type.category}}</div>\n </div>\n <div class=\"type-stats\">\n <div class=\"type-count\">\n <span class=\"count-value\">{{type.credentialCount}}</span>\n <span class=\"count-label\">credentials</span>\n </div>\n <div class=\"type-bar\">\n <div class=\"type-bar-fill\"\n [style.width.%]=\"totalCredentials > 0 ? (type.credentialCount / totalCredentials * 100) : 0\">\n </div>\n </div>\n <div class=\"type-indicators\">\n @if (type.activeCount > 0) {\n <span class=\"indicator active\" title=\"Active\">\n <i class=\"fa-solid fa-circle\"></i> {{type.activeCount}}\n </span>\n }\n @if (type.expiringCount > 0) {\n <span class=\"indicator warning\" title=\"Expiring Soon\">\n <i class=\"fa-solid fa-clock\"></i> {{type.expiringCount}}\n </span>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n @if (typeStats.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-shapes\"></i>\n <span>No credential types configured</span>\n </div>\n }\n </div>\n </div>\n <!-- Recent Activity -->\n <div class=\"panel activity-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n <span>Recent Activity</span>\n </div>\n <button class=\"panel-action\" (click)=\"viewAuditLog()\">\n View All <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n </div>\n <div class=\"panel-body\">\n @if (recentActivity.length > 0) {\n <div class=\"activity-list\">\n @for (activity of recentActivity; track activity) {\n <div class=\"activity-item\" (click)=\"onActivityClick(activity)\">\n <div class=\"activity-icon\" [ngClass]=\"getActionClass(activity.action)\">\n <i [class]=\"getActionIcon(activity.action)\"></i>\n </div>\n <div class=\"activity-info\">\n <div class=\"activity-name\">{{activity.credentialName}}</div>\n <div class=\"activity-meta\">\n <span class=\"activity-type\">{{activity.typeName}}</span>\n <span class=\"activity-action\">{{activity.action}}</span>\n @if (activity.user) {\n <span class=\"activity-user\">by {{activity.user}}</span>\n }\n </div>\n </div>\n <div class=\"activity-time\">\n {{formatDate(activity.date)}}\n </div>\n </div>\n }\n </div>\n }\n @if (recentActivity.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No recent activity</span>\n </div>\n }\n </div>\n </div>\n </div>\n <!-- Quick Actions -->\n @if (UserCanCreateCredentials) {\n <div class=\"quick-actions\">\n <div class=\"quick-actions-title\">Quick Actions</div>\n <div class=\"quick-actions-grid\">\n <button class=\"quick-action\" (click)=\"createNewCredential()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Add Credential</span>\n </button>\n <button class=\"quick-action\" (click)=\"viewAllTypes()\">\n <i class=\"fa-solid fa-shapes\"></i>\n <span>Manage Types</span>\n </button>\n <button class=\"quick-action\" (click)=\"viewAllCategories()\">\n <i class=\"fa-solid fa-folder-tree\"></i>\n <span>Categories</span>\n </button>\n <button class=\"quick-action\" (click)=\"viewAuditLog()\">\n <i class=\"fa-solid fa-clipboard-list\"></i>\n <span>Audit Log</span>\n </button>\n </div>\n </div>\n }\n <!-- Security Notice -->\n <div class=\"security-notice\">\n <i class=\"fa-solid fa-shield-check\"></i>\n <div class=\"notice-content\">\n <strong>Security Note:</strong> All credential values are encrypted.\n Access to credentials is logged in the audit trail for compliance and security monitoring.\n </div>\n </div>\n }\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"credentials-overview-resource.component.js","sourceRoot":"","sources":["../../../src/Credentials/components/credentials-overview-resource.component.ts","../../../src/Credentials/components/credentials-overview-resource.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { ResourceData, MJCredentialEntity, MJCredentialTypeEntity, MJCredentialCategoryEntity, MJAuditLogEntity } from '@memberjunction/core-entities';\nimport { RegisterClass , UUIDsEqual } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { RunView, Metadata, CompositeKey } from '@memberjunction/core';\ninterface CategoryStat {\n category: string;\n categoryId: string;\n count: number;\n iconClass: string;\n color: string;\n percentage: number;\n}\n\ninterface TypeStat {\n typeId: string;\n typeName: string;\n category: string;\n credentialCount: number;\n activeCount: number;\n expiringCount: number;\n}\n\ninterface ActivityItem {\n id: string;\n credentialName: string;\n credentialId: string;\n typeName: string;\n action: 'Created' | 'Updated' | 'Accessed' | 'Rotated';\n date: Date;\n user?: string;\n}\n\ninterface UsageTrendPoint {\n timestamp: Date;\n accessCount: number;\n uniqueCredentials: number;\n successRate: number;\n}\n\n@RegisterClass(BaseResourceComponent, 'CredentialsOverviewResource')\n@Component({\n standalone: false,\n selector: 'mj-credentials-overview-resource',\n templateUrl: './credentials-overview-resource.component.html',\n styleUrls: ['./credentials-overview-resource.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class CredentialsOverviewResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public isLoading = true;\n\n // Summary stats\n public totalCredentials = 0;\n public activeCredentials = 0;\n public expiredCredentials = 0;\n public expiringSoonCount = 0;\n public credentialTypes = 0;\n public categories = 0;\n\n // Grouped data\n public categoryStats: CategoryStat[] = [];\n public typeStats: TypeStat[] = [];\n public recentActivity: ActivityItem[] = [];\n public usageTrend: UsageTrendPoint[] = [];\n\n // Raw data\n private credentials: MJCredentialEntity[] = [];\n private types: MJCredentialTypeEntity[] = [];\n private categoryList: MJCredentialCategoryEntity[] = [];\n private auditLogs: MJAuditLogEntity[] = [];\n\n // Permissions\n private _metadata = new Metadata();\n private _permissionCache = new Map<string, boolean>();\n\n // Category colors for charts - using CSS custom properties via getComputedStyle at runtime\n // These are semantic fallback values; the actual tokens are resolved from the theme\n private categoryColors: Record<string, string> = {\n 'AI': 'var(--mj-brand-primary)',\n 'Communication': 'var(--mj-brand-primary)',\n 'Storage': 'var(--mj-status-success)',\n 'Database': 'var(--mj-status-warning)',\n 'Authentication': 'var(--mj-status-error)',\n 'Integration': 'var(--mj-brand-primary)'\n };\n\n protected override destroy$ = new Subject<void>();\n\n constructor(\n private cdr: ChangeDetectorRef) {\n super();\n }\n\n ngOnInit(): void {\n super.ngOnInit();\n this.loadData();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Overview';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-chart-pie';\n }\n\n // === Permission Checks ===\n public get UserCanCreateCredentials(): boolean {\n return this.checkEntityPermission('MJ: Credentials', 'Create');\n }\n\n public get UserCanUpdateCredentials(): boolean {\n return this.checkEntityPermission('MJ: Credentials', 'Update');\n }\n\n private checkEntityPermission(entityName: string, permissionType: 'Create' | 'Read' | 'Update' | 'Delete'): boolean {\n const cacheKey = `${entityName}_${permissionType}`;\n\n if (this._permissionCache.has(cacheKey)) {\n return this._permissionCache.get(cacheKey)!;\n }\n\n try {\n const entityInfo = this._metadata.Entities.find(e => e.Name === entityName);\n if (!entityInfo) {\n this._permissionCache.set(cacheKey, false);\n return false;\n }\n\n const userPermissions = entityInfo.GetUserPermisions(this._metadata.CurrentUser);\n let hasPermission = false;\n\n switch (permissionType) {\n case 'Create': hasPermission = userPermissions.CanCreate; break;\n case 'Read': hasPermission = userPermissions.CanRead; break;\n case 'Update': hasPermission = userPermissions.CanUpdate; break;\n case 'Delete': hasPermission = userPermissions.CanDelete; break;\n }\n\n this._permissionCache.set(cacheKey, hasPermission);\n return hasPermission;\n } catch (error) {\n this._permissionCache.set(cacheKey, false);\n return false;\n }\n }\n\n private async loadData(): Promise<void> {\n try {\n this.isLoading = true;\n this.cdr.markForCheck();\n\n const rv = new RunView();\n\n // Calculate date range for audit logs (last 30 days)\n const thirtyDaysAgo = new Date();\n thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);\n const dateFilter = `__mj_CreatedAt >= '${thirtyDaysAgo.toISOString()}'`;\n\n // Load all data in parallel using RunViews\n const [credResult, typeResult, categoryResult, auditResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Credentials',\n ResultType: 'entity_object'\n },\n {\n EntityName: 'MJ: Credential Types',\n ResultType: 'entity_object'\n },\n {\n EntityName: 'MJ: Credential Categories',\n ResultType: 'entity_object'\n },\n {\n EntityName: 'MJ: Audit Logs',\n ExtraFilter: `AuditLogType LIKE '%Credential%' AND ${dateFilter}`,\n OrderBy: '__mj_CreatedAt DESC',\n MaxRows: 100,\n ResultType: 'entity_object'\n }\n ]);\n\n if (credResult.Success) {\n this.credentials = credResult.Results as MJCredentialEntity[];\n this.processCredentialStats();\n }\n\n if (typeResult.Success) {\n this.types = typeResult.Results as MJCredentialTypeEntity[];\n this.credentialTypes = this.types.length;\n this.processTypeStats();\n }\n\n if (categoryResult.Success) {\n this.categoryList = categoryResult.Results as MJCredentialCategoryEntity[];\n this.categories = this.categoryList.length;\n this.processCategoryStats();\n }\n\n if (auditResult.Success) {\n this.auditLogs = auditResult.Results as MJAuditLogEntity[];\n this.processActivityAndTrends();\n }\n\n // Build recent activity from credentials if no audit logs\n if (this.recentActivity.length === 0) {\n this.buildActivityFromCredentials();\n }\n\n } catch (error) {\n console.error('Error loading credentials overview:', error);\n } finally {\n this.isLoading = false;\n this.NotifyLoadComplete();\n this.cdr.markForCheck();\n }\n }\n\n private processCredentialStats(): void {\n this.totalCredentials = this.credentials.length;\n this.activeCredentials = this.credentials.filter(c => c.IsActive).length;\n\n const now = new Date();\n const thirtyDaysFromNow = new Date();\n thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30);\n\n this.expiredCredentials = this.credentials.filter(c =>\n c.ExpiresAt && new Date(c.ExpiresAt) < now\n ).length;\n\n this.expiringSoonCount = this.credentials.filter(c =>\n c.ExpiresAt &&\n new Date(c.ExpiresAt) >= now &&\n new Date(c.ExpiresAt) <= thirtyDaysFromNow &&\n c.IsActive\n ).length;\n }\n\n private processTypeStats(): void {\n const now = new Date();\n const thirtyDaysFromNow = new Date();\n thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30);\n\n this.typeStats = this.types.map(type => {\n const typeCredentials = this.credentials.filter(c => UUIDsEqual(c.CredentialTypeID, type.ID));\n\n return {\n typeId: type.ID,\n typeName: type.Name,\n category: type.Category,\n credentialCount: typeCredentials.length,\n activeCount: typeCredentials.filter(c => c.IsActive).length,\n expiringCount: typeCredentials.filter(c =>\n c.ExpiresAt &&\n new Date(c.ExpiresAt) >= now &&\n new Date(c.ExpiresAt) <= thirtyDaysFromNow\n ).length\n };\n }).sort((a, b) => b.credentialCount - a.credentialCount);\n }\n\n private processCategoryStats(): void {\n const categoryMap = new Map<string, CategoryStat>();\n\n // Initialize from credential types\n for (const type of this.types) {\n const category = type.Category;\n const existing = categoryMap.get(category);\n const categoryCredentials = this.credentials.filter(c => UUIDsEqual(c.CredentialTypeID, type.ID));\n\n if (existing) {\n existing.count += categoryCredentials.length;\n } else {\n categoryMap.set(category, {\n category: category,\n categoryId: category, // Use category name as ID for filtering\n count: categoryCredentials.length,\n iconClass: this.getCategoryIcon(category),\n color: this.categoryColors[category] || 'var(--mj-text-muted)',\n percentage: 0\n });\n }\n }\n\n // Calculate percentages\n const total = this.totalCredentials || 1;\n categoryMap.forEach(stat => {\n stat.percentage = Math.round((stat.count / total) * 100);\n });\n\n this.categoryStats = Array.from(categoryMap.values())\n .sort((a, b) => b.count - a.count);\n }\n\n private processActivityAndTrends(): void {\n // Process recent activity from audit logs\n this.recentActivity = this.auditLogs\n .slice(0, 10)\n .map(log => ({\n id: log.ID,\n credentialName: this.extractCredentialName(log.Description || ''),\n credentialId: '', // Would need to parse from log\n typeName: 'Credential',\n action: this.extractAction(log.Description || '') as ActivityItem['action'],\n date: new Date(log.__mj_CreatedAt),\n user: log.User\n }));\n\n // Build usage trend data (group by day)\n const trendMap = new Map<string, UsageTrendPoint>();\n const uniqueCredentialsPerDay = new Map<string, Set<string>>();\n\n for (const log of this.auditLogs) {\n const dateKey = new Date(log.__mj_CreatedAt).toISOString().split('T')[0];\n\n if (!trendMap.has(dateKey)) {\n trendMap.set(dateKey, {\n timestamp: new Date(dateKey),\n accessCount: 0,\n uniqueCredentials: 0,\n successRate: 100\n });\n uniqueCredentialsPerDay.set(dateKey, new Set());\n }\n\n const point = trendMap.get(dateKey)!;\n point.accessCount++;\n\n // Track unique credentials (would need proper parsing)\n const credId = this.extractCredentialId(log.Description || '');\n if (credId) {\n uniqueCredentialsPerDay.get(dateKey)!.add(credId);\n }\n }\n\n // Finalize unique counts\n trendMap.forEach((point, dateKey) => {\n point.uniqueCredentials = uniqueCredentialsPerDay.get(dateKey)?.size || 0;\n });\n\n this.usageTrend = Array.from(trendMap.values())\n .sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());\n }\n\n private buildActivityFromCredentials(): void {\n this.recentActivity = this.credentials\n .filter(c => c.__mj_UpdatedAt)\n .sort((a, b) => new Date(b.__mj_UpdatedAt).getTime() - new Date(a.__mj_UpdatedAt).getTime())\n .slice(0, 10)\n .map(c => ({\n id: c.ID,\n credentialName: c.Name,\n credentialId: c.ID,\n typeName: c.CredentialType || 'Unknown',\n action: 'Updated' as const,\n date: new Date(c.__mj_UpdatedAt),\n user: undefined\n }));\n }\n\n private extractCredentialName(description: string): string {\n // Try to extract credential name from audit log description\n const match = description.match(/credential[:\\s]+['\"]?([^'\"]+)['\"]?/i);\n return match ? match[1] : 'Unknown Credential';\n }\n\n private extractAction(description: string): string {\n if (description.toLowerCase().includes('creat')) return 'Created';\n if (description.toLowerCase().includes('rotat')) return 'Rotated';\n if (description.toLowerCase().includes('access')) return 'Accessed';\n return 'Updated';\n }\n\n private extractCredentialId(description: string): string {\n const match = description.match(/[a-f0-9-]{36}/i);\n return match ? match[0] : '';\n }\n\n private getCategoryIcon(category: string): string {\n const iconMap: Record<string, string> = {\n 'AI': 'fa-solid fa-brain',\n 'Communication': 'fa-solid fa-envelope',\n 'Storage': 'fa-solid fa-cloud',\n 'Database': 'fa-solid fa-database',\n 'Authentication': 'fa-solid fa-shield-halved',\n 'Integration': 'fa-solid fa-plug'\n };\n return iconMap[category] || 'fa-solid fa-key';\n }\n\n // === Navigation Actions ===\n\n public createNewCredential(): void {\n // Navigate to Credentials tab with openCreatePanel flag to show the slide-in editor\n this.navigationService.OpenNavItemByName('Credentials', {\n openCreatePanel: true\n });\n }\n\n public openCredential(credentialId: string): void {\n const key = new CompositeKey([{ FieldName: 'ID', Value: credentialId }]);\n this.navigationService.OpenEntityRecord('MJ: Credentials', key);\n }\n\n public onCategoryClick(category: CategoryStat): void {\n // Navigate to types nav item with category filter\n this.navigationService.OpenNavItemByName('Types', {\n categoryFilter: category.category\n });\n }\n\n public onTypeClick(typeStat: TypeStat): void {\n // Navigate to credentials nav item with type filter\n this.navigationService.OpenNavItemByName('Credentials', {\n typeId: typeStat.typeId\n });\n }\n\n public onActivityClick(activity: ActivityItem): void {\n if (activity.credentialId) {\n this.openCredential(activity.credentialId);\n }\n }\n\n public viewAllCredentials(): void {\n this.navigationService.OpenNavItemByName('Credentials');\n }\n\n public viewAuditLog(): void {\n this.navigationService.OpenNavItemByName('Audit Log');\n }\n\n public viewAllTypes(): void {\n this.navigationService.OpenNavItemByName('Types');\n }\n\n public viewAllCategories(): void {\n this.navigationService.OpenNavItemByName('Categories');\n }\n\n public viewExpiringCredentials(): void {\n this.navigationService.OpenNavItemByName('Credentials', {\n filter: 'expiring'\n });\n }\n\n // === Formatting Helpers ===\n\n public formatDate(date: Date): string {\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return 'Just now';\n if (diffMins < 60) return `${diffMins}m ago`;\n if (diffHours < 24) return `${diffHours}h ago`;\n if (diffDays < 7) return `${diffDays}d ago`;\n\n return date.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n });\n }\n\n public getActionIcon(action: string): string {\n const iconMap: Record<string, string> = {\n 'Created': 'fa-solid fa-plus',\n 'Updated': 'fa-solid fa-pen',\n 'Accessed': 'fa-solid fa-eye',\n 'Rotated': 'fa-solid fa-rotate'\n };\n return iconMap[action] || 'fa-solid fa-circle';\n }\n\n public getActionClass(action: string): string {\n const classMap: Record<string, string> = {\n 'Created': 'action-created',\n 'Updated': 'action-updated',\n 'Accessed': 'action-accessed',\n 'Rotated': 'action-rotated'\n };\n return classMap[action] || '';\n }\n\n public refresh(): void {\n this.loadData();\n }\n\n public getHealthScore(): number {\n if (this.totalCredentials === 0) return 100;\n\n const activeRatio = this.activeCredentials / this.totalCredentials;\n const expiredPenalty = (this.expiredCredentials / this.totalCredentials) * 30;\n const expiringPenalty = (this.expiringSoonCount / this.totalCredentials) * 15;\n\n return Math.max(0, Math.min(100, Math.round((activeRatio * 100) - expiredPenalty - expiringPenalty)));\n }\n\n public getHealthClass(): string {\n const score = this.getHealthScore();\n if (score >= 80) return 'health-good';\n if (score >= 60) return 'health-warning';\n return 'health-critical';\n }\n\n public getHealthLabel(): string {\n const score = this.getHealthScore();\n if (score >= 80) return 'Healthy';\n if (score >= 60) return 'Needs Attention';\n return 'Critical';\n }\n\n public getDonutOffset(index: number): number {\n // Calculate cumulative offset for donut chart segments\n // Each segment starts where the previous one ended\n // The circumference is 251 (2 * PI * 40)\n let offset = 63; // Start at top (25% of circumference = 90 degrees rotation)\n\n for (let i = 0; i < index; i++) {\n offset -= this.categoryStats[i].percentage * 2.51;\n }\n\n return offset;\n }\n}\n","<div class=\"overview-container\">\n @if (isLoading) {\n <mj-loading text=\"Loading overview...\"></mj-loading>\n }\n\n @if (!isLoading) {\n <!-- Header with Actions -->\n <div class=\"overview-header\">\n <div class=\"header-left\">\n <h2 class=\"overview-title\">Credential Overview</h2>\n <p class=\"overview-subtitle\">Monitor and manage your organization's credentials</p>\n </div>\n <div class=\"header-actions\">\n <button class=\"btn-refresh\" (click)=\"refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n @if (UserCanCreateCredentials) {\n <button class=\"btn-primary\" (click)=\"createNewCredential()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>New Credential</span>\n </button>\n }\n </div>\n </div>\n <!-- Health Score Banner -->\n <div class=\"health-banner\" [ngClass]=\"getHealthClass()\">\n <div class=\"health-score-container\">\n <div class=\"health-score-ring\">\n <svg viewBox=\"0 0 36 36\" class=\"circular-chart\">\n <path class=\"circle-bg\"\n d=\"M18 2.0845\n a 15.9155 15.9155 0 0 1 0 31.831\n a 15.9155 15.9155 0 0 1 0 -31.831\"\n />\n <path class=\"circle\"\n [attr.stroke-dasharray]=\"getHealthScore() + ', 100'\"\n d=\"M18 2.0845\n a 15.9155 15.9155 0 0 1 0 31.831\n a 15.9155 15.9155 0 0 1 0 -31.831\"\n />\n </svg>\n <div class=\"health-score-value\">{{getHealthScore()}}</div>\n </div>\n </div>\n <div class=\"health-info\">\n <div class=\"health-label\">{{getHealthLabel()}}</div>\n <div class=\"health-details\">\n @if (expiredCredentials > 0) {\n <span class=\"health-alert\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{expiredCredentials}} expired\n </span>\n }\n @if (expiringSoonCount > 0) {\n <span class=\"health-warning-text\" (click)=\"viewExpiringCredentials()\">\n <i class=\"fa-solid fa-clock\"></i>\n {{expiringSoonCount}} expiring soon\n </span>\n }\n @if (expiredCredentials === 0 && expiringSoonCount === 0) {\n <span class=\"health-ok\">\n <i class=\"fa-solid fa-check-circle\"></i>\n All credentials healthy\n </span>\n }\n </div>\n </div>\n </div>\n <!-- KPI Cards Row -->\n <div class=\"kpi-row\">\n <div class=\"kpi-card clickable\" (click)=\"viewAllCredentials()\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-key\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{totalCredentials}}</div>\n <div class=\"kpi-label\">Total Credentials</div>\n </div>\n <div class=\"kpi-trend\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n </div>\n <div class=\"kpi-card active clickable\" (click)=\"viewAllCredentials()\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-check-circle\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{activeCredentials}}</div>\n <div class=\"kpi-label\">Active</div>\n </div>\n <div class=\"kpi-trend success\">\n <span class=\"percentage\">{{totalCredentials > 0 ? (activeCredentials / totalCredentials * 100).toFixed(0) : 0}}%</span>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-cubes\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{credentialTypes}}</div>\n <div class=\"kpi-label\">Types</div>\n </div>\n </div>\n <div class=\"kpi-card clickable\" [class.warning]=\"expiringSoonCount > 0\" (click)=\"viewExpiringCredentials()\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-clock\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{expiringSoonCount}}</div>\n <div class=\"kpi-label\">Expiring Soon</div>\n </div>\n @if (expiringSoonCount > 0) {\n <div class=\"kpi-trend warning\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n }\n </div>\n <div class=\"kpi-card\" [class.danger]=\"expiredCredentials > 0\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-circle-xmark\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{expiredCredentials}}</div>\n <div class=\"kpi-label\">Expired</div>\n </div>\n </div>\n </div>\n <!-- Content Grid -->\n <div class=\"content-grid\">\n <!-- Category Distribution Chart -->\n <div class=\"panel category-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-chart-pie\"></i>\n <span>Credentials by Category</span>\n </div>\n <span class=\"panel-subtitle\">Click to filter by category</span>\n </div>\n <div class=\"panel-body\">\n @if (categoryStats.length > 0) {\n <div class=\"category-chart\">\n <!-- Visual Donut Chart -->\n <div class=\"donut-chart-container\">\n <svg viewBox=\"0 0 100 100\" class=\"donut-chart\">\n <circle cx=\"50\" cy=\"50\" r=\"40\" fill=\"none\" stroke=\"var(--mj-border-default)\" stroke-width=\"12\"/>\n @for (stat of categoryStats; track stat; let i = $index) {\n <ng-container>\n <circle\n cx=\"50\" cy=\"50\" r=\"40\"\n fill=\"none\"\n [attr.stroke]=\"stat.color\"\n stroke-width=\"12\"\n [attr.stroke-dasharray]=\"stat.percentage * 2.51 + ' ' + (251 - stat.percentage * 2.51)\"\n [attr.stroke-dashoffset]=\"getDonutOffset(i)\"\n class=\"donut-segment\"\n (click)=\"onCategoryClick(stat)\"\n />\n </ng-container>\n }\n </svg>\n <div class=\"donut-center\">\n <div class=\"donut-total\">{{totalCredentials}}</div>\n <div class=\"donut-label\">Total</div>\n </div>\n </div>\n <!-- Legend -->\n <div class=\"category-legend\">\n @for (stat of categoryStats; track stat) {\n <div class=\"legend-item\" (click)=\"onCategoryClick(stat)\">\n <div class=\"legend-color\" [style.backgroundColor]=\"stat.color\"></div>\n <div class=\"legend-info\">\n <div class=\"legend-name\">\n <i [class]=\"stat.iconClass\"></i>\n {{stat.category}}\n </div>\n <div class=\"legend-value\">{{stat.count}} ({{stat.percentage}}%)</div>\n </div>\n <i class=\"fa-solid fa-chevron-right legend-arrow\"></i>\n </div>\n }\n </div>\n </div>\n }\n @if (categoryStats.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-folder-open\"></i>\n <span>No credentials configured</span>\n </div>\n }\n </div>\n </div>\n <!-- Types Breakdown -->\n <div class=\"panel types-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-cubes\"></i>\n <span>Top Credential Types</span>\n </div>\n <button class=\"panel-action\" (click)=\"viewAllTypes()\">\n View All <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n </div>\n <div class=\"panel-body\">\n @if (typeStats.length > 0) {\n <div class=\"type-list\">\n @for (type of typeStats.slice(0, 6); track type) {\n <div class=\"type-item\" (click)=\"onTypeClick(type)\">\n <div class=\"type-info\">\n <div class=\"type-name\">{{type.typeName}}</div>\n <div class=\"type-category\">{{type.category}}</div>\n </div>\n <div class=\"type-stats\">\n <div class=\"type-count\">\n <span class=\"count-value\">{{type.credentialCount}}</span>\n <span class=\"count-label\">credentials</span>\n </div>\n <div class=\"type-bar\">\n <div class=\"type-bar-fill\"\n [style.width.%]=\"totalCredentials > 0 ? (type.credentialCount / totalCredentials * 100) : 0\">\n </div>\n </div>\n <div class=\"type-indicators\">\n @if (type.activeCount > 0) {\n <span class=\"indicator active\" title=\"Active\">\n <i class=\"fa-solid fa-circle\"></i> {{type.activeCount}}\n </span>\n }\n @if (type.expiringCount > 0) {\n <span class=\"indicator warning\" title=\"Expiring Soon\">\n <i class=\"fa-solid fa-clock\"></i> {{type.expiringCount}}\n </span>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n @if (typeStats.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-shapes\"></i>\n <span>No credential types configured</span>\n </div>\n }\n </div>\n </div>\n <!-- Recent Activity -->\n <div class=\"panel activity-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n <span>Recent Activity</span>\n </div>\n <button class=\"panel-action\" (click)=\"viewAuditLog()\">\n View All <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n </div>\n <div class=\"panel-body\">\n @if (recentActivity.length > 0) {\n <div class=\"activity-list\">\n @for (activity of recentActivity; track activity) {\n <div class=\"activity-item\" (click)=\"onActivityClick(activity)\">\n <div class=\"activity-icon\" [ngClass]=\"getActionClass(activity.action)\">\n <i [class]=\"getActionIcon(activity.action)\"></i>\n </div>\n <div class=\"activity-info\">\n <div class=\"activity-name\">{{activity.credentialName}}</div>\n <div class=\"activity-meta\">\n <span class=\"activity-type\">{{activity.typeName}}</span>\n <span class=\"activity-action\">{{activity.action}}</span>\n @if (activity.user) {\n <span class=\"activity-user\">by {{activity.user}}</span>\n }\n </div>\n </div>\n <div class=\"activity-time\">\n {{formatDate(activity.date)}}\n </div>\n </div>\n }\n </div>\n }\n @if (recentActivity.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No recent activity</span>\n </div>\n }\n </div>\n </div>\n </div>\n <!-- Quick Actions -->\n @if (UserCanCreateCredentials) {\n <div class=\"quick-actions\">\n <div class=\"quick-actions-title\">Quick Actions</div>\n <div class=\"quick-actions-grid\">\n <button class=\"quick-action\" (click)=\"createNewCredential()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Add Credential</span>\n </button>\n <button class=\"quick-action\" (click)=\"viewAllTypes()\">\n <i class=\"fa-solid fa-shapes\"></i>\n <span>Manage Types</span>\n </button>\n <button class=\"quick-action\" (click)=\"viewAllCategories()\">\n <i class=\"fa-solid fa-folder-tree\"></i>\n <span>Categories</span>\n </button>\n <button class=\"quick-action\" (click)=\"viewAuditLog()\">\n <i class=\"fa-solid fa-clipboard-list\"></i>\n <span>Audit Log</span>\n </button>\n </div>\n </div>\n }\n <!-- Security Notice -->\n <div class=\"security-notice\">\n <i class=\"fa-solid fa-shield-check\"></i>\n <div class=\"notice-content\">\n <strong>Security Note:</strong> All credential values are encrypted.\n Access to credentials is logged in the audit trail for compliance and security monitoring.\n </div>\n </div>\n }\n</div>\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
|
|
2
2
|
import { ResourceData, MJCredentialTypeEntity, MJCredentialEntity } from '@memberjunction/core-entities';
|
|
3
|
-
import { BaseResourceComponent
|
|
3
|
+
import { BaseResourceComponent } from '@memberjunction/ng-shared';
|
|
4
4
|
import { CredentialTypeEditPanelComponent } from '@memberjunction/ng-credentials';
|
|
5
5
|
import * as i0 from "@angular/core";
|
|
6
6
|
interface FieldSchemaProperty {
|
|
@@ -18,7 +18,6 @@ interface TypeWithStats extends MJCredentialTypeEntity {
|
|
|
18
18
|
}
|
|
19
19
|
export declare class CredentialsTypesResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {
|
|
20
20
|
private cdr;
|
|
21
|
-
private navigationService;
|
|
22
21
|
isLoading: boolean;
|
|
23
22
|
types: TypeWithStats[];
|
|
24
23
|
filteredTypes: TypeWithStats[];
|
|
@@ -31,7 +30,7 @@ export declare class CredentialsTypesResourceComponent extends BaseResourceCompo
|
|
|
31
30
|
private _metadata;
|
|
32
31
|
private _permissionCache;
|
|
33
32
|
typeEditPanel: CredentialTypeEditPanelComponent;
|
|
34
|
-
constructor(cdr: ChangeDetectorRef
|
|
33
|
+
constructor(cdr: ChangeDetectorRef);
|
|
35
34
|
ngOnInit(): void;
|
|
36
35
|
ngOnDestroy(): void;
|
|
37
36
|
GetResourceDisplayName(data: ResourceData): Promise<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials-types-resource.component.d.ts","sourceRoot":"","sources":["../../../src/Credentials/components/credentials-types-resource.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAsC,MAAM,eAAe,CAAC;AACpH,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEzG,OAAO,EAAE,qBAAqB,
|
|
1
|
+
{"version":3,"file":"credentials-types-resource.component.d.ts","sourceRoot":"","sources":["../../../src/Credentials/components/credentials-types-resource.component.ts"],"names":[],"mappings":"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"}
|