@memberjunction/ng-dashboards 5.11.0 → 5.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AI/components/agents/agent-configuration.component.d.ts +34 -2
- package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-configuration.component.js +586 -223
- package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.js +2 -2
- package/dist/AI/components/agents/agent-filter-panel.component.d.ts +8 -0
- package/dist/AI/components/agents/agent-filter-panel.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-filter-panel.component.js +85 -52
- package/dist/AI/components/agents/agent-filter-panel.component.js.map +1 -1
- package/dist/AI/components/charts/performance-heatmap.component.d.ts +1 -0
- package/dist/AI/components/charts/performance-heatmap.component.d.ts.map +1 -1
- package/dist/AI/components/charts/performance-heatmap.component.js +27 -5
- package/dist/AI/components/charts/performance-heatmap.component.js.map +1 -1
- package/dist/AI/components/charts/time-series-chart.component.d.ts +5 -0
- package/dist/AI/components/charts/time-series-chart.component.d.ts.map +1 -1
- package/dist/AI/components/charts/time-series-chart.component.js +23 -8
- package/dist/AI/components/charts/time-series-chart.component.js.map +1 -1
- package/dist/AI/components/execution-monitoring.component.js +2 -2
- package/dist/AI/components/execution-monitoring.component.js.map +1 -1
- package/dist/AI/components/models/model-management.component.js +2 -2
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +2 -2
- package/dist/AI/components/prompts/prompt-filter-panel.component.js +2 -2
- package/dist/AI/components/prompts/prompt-management.component.js +3 -3
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-version-control.component.js +2 -2
- package/dist/AI/components/requests/agent-requests-resource.component.d.ts +83 -0
- package/dist/AI/components/requests/agent-requests-resource.component.d.ts.map +1 -0
- package/dist/AI/components/requests/agent-requests-resource.component.js +547 -0
- package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -0
- package/dist/AI/components/system/system-config-filter-panel.component.js +2 -2
- package/dist/AI/components/system/system-configuration.component.js +2 -2
- package/dist/AI/components/widgets/kpi-card.component.js +7 -7
- package/dist/AI/components/widgets/kpi-card.component.js.map +1 -1
- package/dist/AI/components/widgets/live-execution-widget.component.d.ts.map +1 -1
- package/dist/AI/components/widgets/live-execution-widget.component.js +6 -6
- package/dist/AI/components/widgets/live-execution-widget.component.js.map +1 -1
- package/dist/AI/index.d.ts +1 -0
- package/dist/AI/index.d.ts.map +1 -1
- package/dist/AI/index.js +2 -0
- package/dist/AI/index.js.map +1 -1
- package/dist/APIKeys/api-applications-panel.component.js +3 -3
- package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
- package/dist/APIKeys/api-key-create-dialog.component.js +3 -3
- package/dist/APIKeys/api-key-create-dialog.component.js.map +1 -1
- package/dist/APIKeys/api-key-edit-panel.component.js +1 -1
- package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -1
- package/dist/APIKeys/api-key-list.component.js +3 -3
- package/dist/APIKeys/api-key-list.component.js.map +1 -1
- package/dist/APIKeys/api-keys-resource.component.js +1 -1
- package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
- package/dist/APIKeys/api-scopes-panel.component.js +2 -2
- package/dist/APIKeys/api-usage-panel.component.js +2 -2
- package/dist/Actions/components/actions-overview.component.js +2 -2
- package/dist/Actions/components/execution-monitoring.component.js +2 -2
- package/dist/Actions/components/explorer/action-breadcrumb.component.js +2 -2
- package/dist/Actions/components/explorer/action-card.component.js +2 -2
- package/dist/Actions/components/explorer/action-explorer.component.js +2 -2
- package/dist/Actions/components/explorer/action-list-item.component.js +2 -2
- package/dist/Actions/components/explorer/action-toolbar.component.js +2 -2
- package/dist/Actions/components/explorer/action-tree-panel.component.js +2 -2
- package/dist/Actions/components/explorer/new-action-panel.component.js +2 -2
- package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -1
- package/dist/Actions/components/explorer/new-category-panel.component.js +2 -2
- package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -1
- package/dist/Communication/communication-dashboard.component.js +2 -2
- package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-logs-resource.component.js +3 -3
- package/dist/Communication/communication-logs-resource.component.js.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.js +5 -5
- package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
- package/dist/Communication/communication-providers-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-providers-resource.component.js +3 -3
- package/dist/Communication/communication-providers-resource.component.js.map +1 -1
- package/dist/Communication/communication-runs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-runs-resource.component.js +3 -3
- package/dist/Communication/communication-runs-resource.component.js.map +1 -1
- package/dist/Communication/communication-templates-resource.component.js +2 -2
- package/dist/Communication/communication-templates-resource.component.js.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +2 -2
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +2 -2
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/browser/component-browser.component.js +2 -2
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js +2 -2
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +2 -2
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js +2 -2
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/spec-editor.component.js +2 -2
- package/dist/ComponentStudio/components/editors/spec-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/text-import-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/text-import-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/workspace/component-preview.component.js +2 -2
- package/dist/ComponentStudio/components/workspace/editor-tabs.component.js +2 -2
- package/dist/ComponentStudio/components/workspace/editor-tabs.component.js.map +1 -1
- package/dist/Credentials/components/credentials-audit-resource.component.js +9 -9
- package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.js +11 -3
- package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +2 -2
- package/dist/Credentials/components/credentials-overview-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-overview-resource.component.js +12 -11
- package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +9 -9
- package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
- package/dist/Credentials/credentials-dashboard.component.js +2 -2
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +2 -2
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js +2 -2
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +2 -2
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +2 -2
- package/dist/DataExplorer/components/view-selector/view-selector.component.js +2 -2
- package/dist/DataExplorer/data-explorer-dashboard.component.js +4 -4
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/Home/home-dashboard.component.js +2 -2
- package/dist/Integration/components/activity/activity.component.d.ts +1 -1
- package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
- package/dist/Integration/components/activity/activity.component.js +5 -5
- package/dist/Integration/components/activity/activity.component.js.map +1 -1
- package/dist/Integration/components/connections/connections.component.d.ts +31 -2
- package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
- package/dist/Integration/components/connections/connections.component.js +753 -412
- package/dist/Integration/components/connections/connections.component.js.map +1 -1
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +3 -3
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
- package/dist/Integration/components/overview/overview.component.d.ts +0 -1
- package/dist/Integration/components/overview/overview.component.d.ts.map +1 -1
- package/dist/Integration/components/overview/overview.component.js +3 -6
- package/dist/Integration/components/overview/overview.component.js.map +1 -1
- package/dist/Integration/components/pipelines/pipelines.component.js +3 -3
- package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
- package/dist/Integration/components/schedules/schedules.component.d.ts +20 -0
- package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -1
- package/dist/Integration/components/schedules/schedules.component.js +97 -5
- package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
- package/dist/Integration/components/visual-editor/visual-editor.component.js +2 -2
- package/dist/Integration/components/widgets/integration-card.component.d.ts.map +1 -1
- package/dist/Integration/components/widgets/integration-card.component.js +5 -1
- package/dist/Integration/components/widgets/integration-card.component.js.map +1 -1
- package/dist/Integration/components/widgets/run-history-panel.component.js +2 -2
- package/dist/Integration/components/widgets/run-history-panel.component.js.map +1 -1
- package/dist/Integration/integration.module.d.ts +2 -1
- package/dist/Integration/integration.module.d.ts.map +1 -1
- package/dist/Integration/integration.module.js +7 -3
- package/dist/Integration/integration.module.js.map +1 -1
- package/dist/Integration/services/integration-data.service.d.ts +27 -2
- package/dist/Integration/services/integration-data.service.d.ts.map +1 -1
- package/dist/Integration/services/integration-data.service.js +107 -4
- package/dist/Integration/services/integration-data.service.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +2 -2
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-categories-resource.component.js +2 -2
- package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +2 -2
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-operations-resource.component.js +2 -2
- package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
- package/dist/Lists/components/venn-diagram/venn-diagram.component.js +3 -3
- package/dist/Lists/components/venn-diagram/venn-diagram.component.js.map +1 -1
- package/dist/MCP/components/mcp-connection-dialog.component.js +2 -2
- package/dist/MCP/components/mcp-log-detail-panel.component.js +2 -2
- package/dist/MCP/components/mcp-log-detail-panel.component.js.map +1 -1
- package/dist/MCP/components/mcp-server-dialog.component.js +2 -2
- package/dist/MCP/components/mcp-test-tool-dialog.component.js +2 -2
- package/dist/MCP/components/mcp-test-tool-dialog.component.js.map +1 -1
- package/dist/MCP/mcp-dashboard.component.js +2 -2
- package/dist/MCP/mcp-filter-panel.component.js +2 -2
- package/dist/QueryBrowser/query-browser-resource.component.js +7 -7
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/Scheduling/components/index.d.ts +0 -1
- package/dist/Scheduling/components/index.d.ts.map +1 -1
- package/dist/Scheduling/components/index.js +0 -1
- package/dist/Scheduling/components/index.js.map +1 -1
- package/dist/Scheduling/components/scheduling-activity.component.js +2 -2
- package/dist/Scheduling/components/scheduling-jobs.component.d.ts +6 -9
- package/dist/Scheduling/components/scheduling-jobs.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs.component.js +118 -110
- package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-overview.component.js +3 -3
- package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
- package/dist/Scheduling/scheduling-dashboard.component.js +2 -2
- package/dist/SystemDiagnostics/system-diagnostics.component.js +4 -4
- package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
- package/dist/Testing/components/testing-analytics.component.js +2 -2
- package/dist/Testing/components/testing-analytics.component.js.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab.component.js +4 -4
- package/dist/Testing/components/testing-dashboard-tab.component.js.map +1 -1
- package/dist/Testing/components/testing-explorer.component.js +2 -2
- package/dist/Testing/components/testing-explorer.component.js.map +1 -1
- package/dist/Testing/components/testing-review.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-review.component.js +5 -5
- package/dist/Testing/components/testing-review.component.js.map +1 -1
- package/dist/Testing/components/testing-runs.component.js +2 -2
- package/dist/Testing/components/testing-runs.component.js.map +1 -1
- package/dist/Testing/components/widgets/oracle-breakdown-table.component.js +2 -2
- package/dist/Testing/components/widgets/oracle-breakdown-table.component.js.map +1 -1
- package/dist/Testing/components/widgets/suite-tree.component.js +4 -4
- package/dist/Testing/components/widgets/suite-tree.component.js.map +1 -1
- package/dist/Testing/components/widgets/test-run-detail-panel.component.js +2 -2
- package/dist/Testing/components/widgets/test-run-detail-panel.component.js.map +1 -1
- package/dist/Testing/testing-dashboard.component.js +2 -2
- package/dist/VersionHistory/components/diff-resource.component.js +2 -2
- package/dist/VersionHistory/components/graph-resource.component.js +2 -2
- package/dist/VersionHistory/components/labels-resource.component.js +3 -3
- package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/restore-resource.component.js +3 -3
- package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
- package/dist/__tests__/integration-data-service.test.js +1 -0
- package/dist/__tests__/integration-data-service.test.js.map +1 -1
- package/dist/module.d.ts +52 -49
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +25 -6
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +1 -1
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -1
- package/dist/public-api.js.map +1 -1
- package/package.json +42 -40
- package/dist/Scheduling/components/job-slideout.component.d.ts +0 -45
- package/dist/Scheduling/components/job-slideout.component.d.ts.map +0 -1
- package/dist/Scheduling/components/job-slideout.component.js +0 -459
- package/dist/Scheduling/components/job-slideout.component.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials-types-resource.component.js","sourceRoot":"","sources":["../../../src/Credentials/components/credentials-types-resource.component.ts","../../../src/Credentials/components/credentials-types-resource.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef, ChangeDetectionStrategy, ViewChild } from '@angular/core';\nimport { ResourceData, MJCredentialTypeEntity, MJCredentialEntity } from '@memberjunction/core-entities';\nimport { RegisterClass , UUIDsEqual } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { RunView, Metadata } from '@memberjunction/core';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { CredentialTypeEditPanelComponent } from '@memberjunction/ng-credentials';\ninterface FieldSchemaProperty {\n name: string;\n type: string;\n title: string;\n description: string;\n isSecret: boolean;\n required: boolean;\n}\n\ninterface TypeWithStats extends MJCredentialTypeEntity {\n credentialCount: number;\n activeCount: number;\n expiringCount: number;\n}\n\n@RegisterClass(BaseResourceComponent, 'CredentialsTypesResource')\n@Component({\n standalone: false,\n selector: 'mj-credentials-types-resource',\n templateUrl: './credentials-types-resource.component.html',\n styleUrls: ['./credentials-types-resource.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class CredentialsTypesResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public isLoading = true;\n public types: TypeWithStats[] = [];\n public filteredTypes: TypeWithStats[] = [];\n public credentials: MJCredentialEntity[] = [];\n public selectedType: TypeWithStats | null = null;\n public schemaProperties: FieldSchemaProperty[] = [];\n\n // Filters\n public searchText = '';\n public selectedCategoryFilter = '';\n public categories: string[] = [];\n\n // Permissions\n private _metadata = new Metadata();\n private _permissionCache = new Map<string, boolean>();\n\n @ViewChild('typeEditPanel') typeEditPanel!: CredentialTypeEditPanelComponent;\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 // Cleanup if needed\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Credential Types';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-cubes';\n }\n\n // === Permission Checks ===\n\n public get UserCanCreate(): boolean {\n return this.checkEntityPermission('MJ: Credential Types', 'Create');\n }\n\n public get UserCanUpdate(): boolean {\n return this.checkEntityPermission('MJ: Credential Types', 'Update');\n }\n\n public get UserCanDelete(): boolean {\n return this.checkEntityPermission('MJ: Credential Types', 'Delete');\n }\n\n public get UserCanCreateCredential(): boolean {\n return this.checkEntityPermission('MJ: Credentials', 'Create');\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 const [typeResult, credResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Credential Types',\n OrderBy: 'Category, Name',\n ResultType: 'entity_object'\n },\n {\n EntityName: 'MJ: Credentials',\n ResultType: 'entity_object'\n }\n ]);\n\n if (typeResult.Success) {\n const baseTypes = typeResult.Results as MJCredentialTypeEntity[];\n this.credentials = credResult.Success ? credResult.Results as MJCredentialEntity[] : [];\n\n // Calculate stats for each type\n this.types = baseTypes.map(type => this.enrichTypeWithStats(type));\n\n // Extract unique categories\n this.categories = [...new Set(this.types.map(t => t.Category))].sort();\n }\n\n // Apply any navigation config (e.g., category filter from Categories nav item)\n this.handleNavigationConfig();\n\n this.applyFilters();\n\n } catch (error) {\n console.error('Error loading credential types:', error);\n MJNotificationService.Instance.CreateSimpleNotification('Error loading credential types', 'error', 3000);\n } finally {\n this.isLoading = false;\n this.NotifyLoadComplete();\n this.cdr.markForCheck();\n }\n }\n\n private handleNavigationConfig(): void {\n const config = this.Data?.Configuration;\n if (!config) {\n return;\n }\n\n // Apply category filter from navigation config\n if (config.categoryFilter) {\n this.selectedCategoryFilter = config.categoryFilter as string;\n }\n }\n\n private enrichTypeWithStats(type: MJCredentialTypeEntity): TypeWithStats {\n const typeCredentials = this.credentials.filter(c => UUIDsEqual(c.CredentialTypeID, type.ID));\n const now = new Date();\n const thirtyDaysFromNow = new Date();\n thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30);\n\n // Add stats properties directly to the entity object\n const enrichedType = type as TypeWithStats;\n enrichedType.credentialCount = typeCredentials.length;\n enrichedType.activeCount = typeCredentials.filter(c => c.IsActive).length;\n enrichedType.expiringCount = typeCredentials.filter(c =>\n c.ExpiresAt &&\n new Date(c.ExpiresAt) >= now &&\n new Date(c.ExpiresAt) <= thirtyDaysFromNow\n ).length;\n\n return enrichedType;\n }\n\n // === CRUD Operations ===\n\n public createNewType(): void {\n if (this.typeEditPanel) {\n this.typeEditPanel.open(null);\n }\n }\n\n public editType(type: TypeWithStats, event?: Event): void {\n if (event) {\n event.stopPropagation();\n }\n if (this.typeEditPanel) {\n this.typeEditPanel.open(type);\n }\n }\n\n public async deleteType(type: TypeWithStats, event?: Event): Promise<void> {\n if (event) {\n event.stopPropagation();\n }\n\n if (!this.UserCanDelete) {\n MJNotificationService.Instance.CreateSimpleNotification('You do not have permission to delete credential types', 'warning', 3000);\n return;\n }\n\n if (type.credentialCount > 0) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Cannot delete \"${type.Name}\" - it has ${type.credentialCount} credential(s) using it`,\n 'warning',\n 4000\n );\n return;\n }\n\n const confirmed = confirm(`Are you sure you want to delete \"${type.Name}\"? This action cannot be undone.`);\n if (!confirmed) return;\n\n try {\n const success = await type.Delete();\n if (success) {\n MJNotificationService.Instance.CreateSimpleNotification(`Credential type \"${type.Name}\" deleted successfully`, 'success', 3000);\n this.types = this.types.filter(t => !UUIDsEqual(t.ID, type.ID));\n if (UUIDsEqual(this.selectedType?.ID, type.ID)) {\n this.closeDetail();\n }\n this.applyFilters();\n } else {\n MJNotificationService.Instance.CreateSimpleNotification('Failed to delete credential type', 'error', 3000);\n }\n } catch (error) {\n console.error('Error deleting credential type:', error);\n MJNotificationService.Instance.CreateSimpleNotification('Error deleting credential type', 'error', 3000);\n }\n }\n\n public createCredentialForType(type: TypeWithStats, event?: Event): void {\n if (event) {\n event.stopPropagation();\n }\n // Navigate to Credentials nav item with the type pre-selected and create panel open\n this.navigationService.OpenNavItemByName('Credentials', {\n typeId: type.ID,\n openCreatePanel: true\n });\n }\n\n // === Panel Event Handlers ===\n\n public onTypeSaved(type: MJCredentialTypeEntity): void {\n const existingIndex = this.types.findIndex(t => UUIDsEqual(t.ID, type.ID));\n const enrichedType = this.enrichTypeWithStats(type);\n\n if (existingIndex >= 0) {\n this.types[existingIndex] = enrichedType;\n } else {\n this.types.unshift(enrichedType);\n }\n\n // Update categories if a new one was added\n if (!this.categories.includes(type.Category)) {\n this.categories = [...new Set(this.types.map(t => t.Category))].sort();\n }\n\n this.applyFilters();\n this.cdr.markForCheck();\n }\n\n public onTypeDeleted(typeId: string): void {\n this.types = this.types.filter(t => !UUIDsEqual(t.ID, typeId));\n if (UUIDsEqual(this.selectedType?.ID, typeId)) {\n this.closeDetail();\n }\n this.applyFilters();\n this.cdr.markForCheck();\n }\n\n // === Filtering ===\n\n public onSearchChange(value: string): void {\n this.searchText = value;\n this.applyFilters();\n }\n\n public onCategoryFilterChange(category: string): void {\n this.selectedCategoryFilter = category;\n this.applyFilters();\n }\n\n public clearFilters(): void {\n this.searchText = '';\n this.selectedCategoryFilter = '';\n this.applyFilters();\n }\n\n private applyFilters(): void {\n let filtered = [...this.types];\n\n // Filter by category\n if (this.selectedCategoryFilter) {\n filtered = filtered.filter(t => t.Category === this.selectedCategoryFilter);\n }\n\n // Filter by search text\n if (this.searchText.trim()) {\n const search = this.searchText.toLowerCase().trim();\n filtered = filtered.filter(t =>\n t.Name.toLowerCase().includes(search) ||\n (t.Description && t.Description.toLowerCase().includes(search)) ||\n t.Category.toLowerCase().includes(search)\n );\n }\n\n this.filteredTypes = filtered;\n this.cdr.markForCheck();\n }\n\n // === Selection ===\n\n public selectType(type: TypeWithStats): void {\n this.selectedType = type;\n this.parseFieldSchema(type.FieldSchema);\n this.cdr.markForCheck();\n }\n\n public closeDetail(): void {\n this.selectedType = null;\n this.schemaProperties = [];\n this.cdr.markForCheck();\n }\n\n private parseFieldSchema(schemaJson: string): void {\n try {\n const schema = JSON.parse(schemaJson) as { properties?: Record<string, Record<string, unknown>>; required?: string[] };\n const properties = schema.properties || {};\n const required = schema.required || [];\n\n this.schemaProperties = Object.entries(properties).map(([name, prop]) => ({\n name,\n type: (prop.type as string) || 'string',\n title: (prop.title as string) || name,\n description: (prop.description as string) || '',\n isSecret: prop.isSecret === true,\n required: required.includes(name)\n }));\n\n // Sort by order if available, otherwise by name\n this.schemaProperties.sort((a, b) => {\n const propA = properties[a.name];\n const propB = properties[b.name];\n const orderA = typeof propA.order === 'number' ? propA.order : 999;\n const orderB = typeof propB.order === 'number' ? propB.order : 999;\n return orderA - orderB;\n });\n\n } catch (e) {\n console.error('Failed to parse field schema:', e);\n this.schemaProperties = [];\n }\n }\n\n // === Helpers ===\n\n public 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 public getCategoryColor(category: string): string {\n const colorMap: Record<string, string> = {\n 'AI': '#8b5cf6',\n 'Communication': '#3b82f6',\n 'Storage': '#06b6d4',\n 'Database': '#f59e0b',\n 'Authentication': '#10b981',\n 'Integration': '#ec4899'\n };\n return colorMap[category] || '#6366f1';\n }\n\n public getTypesByCategory(): Map<string, TypeWithStats[]> {\n const grouped = new Map<string, TypeWithStats[]>();\n for (const type of this.filteredTypes) {\n const category = type.Category;\n if (!grouped.has(category)) {\n grouped.set(category, []);\n }\n grouped.get(category)!.push(type);\n }\n return grouped;\n }\n\n /** Case-insensitive UUID check whether a credential type is the currently selected type. */\n public IsTypeSelected(type: TypeWithStats): boolean {\n return UUIDsEqual(this.selectedType?.ID, type.ID);\n }\n\n public getTotalCredentialCount(): number {\n return this.types.reduce((sum, t) => sum + t.credentialCount, 0);\n }\n\n public refresh(): void {\n this.loadData();\n }\n}\n","<div class=\"types-container\">\n @if (isLoading) {\n <mj-loading text=\"Loading credential types...\"></mj-loading>\n }\n\n @if (!isLoading) {\n <!-- Header -->\n <div class=\"types-header\">\n <div class=\"header-info\">\n <h2 class=\"types-title\">Credential Types</h2>\n <div class=\"header-stats\">\n <span class=\"stat-item\">\n <i class=\"fa-solid fa-shapes\"></i>\n {{types.length}} types\n </span>\n <span class=\"stat-item\">\n <i class=\"fa-solid fa-folder\"></i>\n {{categories.length}} categories\n </span>\n <span class=\"stat-item\">\n <i class=\"fa-solid fa-key\"></i>\n {{getTotalCredentialCount()}} credentials\n </span>\n </div>\n </div>\n <div class=\"header-actions\">\n @if (UserCanCreate) {\n <button class=\"btn-primary\" (click)=\"createNewType()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>New Type</span>\n </button>\n }\n </div>\n </div>\n <!-- Toolbar -->\n <div class=\"toolbar\">\n <div class=\"toolbar-left\">\n <div class=\"search-container\">\n <i class=\"fa-solid fa-search\"></i>\n <input\n type=\"text\"\n placeholder=\"Search types...\"\n [value]=\"searchText\"\n (input)=\"onSearchChange($any($event.target).value)\"\n />\n @if (searchText) {\n <button class=\"search-clear\" (click)=\"onSearchChange('')\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n <select\n class=\"filter-select\"\n [value]=\"selectedCategoryFilter\"\n (change)=\"onCategoryFilterChange($any($event.target).value)\"\n >\n <option value=\"\">All Categories</option>\n @for (cat of categories; track cat) {\n <option [value]=\"cat\">{{cat}}</option>\n }\n </select>\n </div>\n <div class=\"toolbar-right\">\n <div class=\"results-info\">\n {{filteredTypes.length}} of {{types.length}} types\n </div>\n <button class=\"btn-icon\" (click)=\"refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n </div>\n </div>\n <div class=\"types-layout\">\n <!-- Types List -->\n <div class=\"types-list\">\n @for (entry of getTypesByCategory() | keyvalue; track entry) {\n <div class=\"category-section\">\n <div class=\"category-header\" [style.borderLeftColor]=\"getCategoryColor(entry.key)\">\n <i [class]=\"getCategoryIcon(entry.key)\" [style.color]=\"getCategoryColor(entry.key)\"></i>\n <span class=\"category-name\">{{entry.key}}</span>\n <span class=\"count\">{{entry.value.length}}</span>\n </div>\n <div class=\"type-items\">\n @for (type of entry.value; track type) {\n <div\n class=\"type-item\"\n [class.selected]=\"IsTypeSelected(type)\"\n (click)=\"selectType(type)\"\n >\n <div class=\"type-icon\" [style.backgroundColor]=\"getCategoryColor(type.Category) + '15'\" [style.color]=\"getCategoryColor(type.Category)\">\n <i [class]=\"type.IconClass || 'fa-solid fa-key'\"></i>\n </div>\n <div class=\"type-info\">\n <div class=\"type-name\">{{type.Name}}</div>\n @if (type.Description) {\n <div class=\"type-description\">\n {{type.Description | slice:0:60}}{{type.Description.length > 60 ? '...' : ''}}\n </div>\n }\n <div class=\"type-meta\">\n @if (type.credentialCount > 0) {\n <span class=\"meta-badge\">\n <i class=\"fa-solid fa-key\"></i>\n {{type.credentialCount}}\n </span>\n }\n @if (type.activeCount > 0) {\n <span class=\"meta-badge active\">\n <i class=\"fa-solid fa-check\"></i>\n {{type.activeCount}} active\n </span>\n }\n @if (type.expiringCount > 0) {\n <span class=\"meta-badge warning\">\n <i class=\"fa-solid fa-clock\"></i>\n {{type.expiringCount}} expiring\n </span>\n }\n </div>\n </div>\n <div class=\"type-actions\">\n @if (UserCanCreateCredential) {\n <button\n class=\"action-btn\"\n (click)=\"createCredentialForType(type, $event)\"\n title=\"Add Credential\"\n >\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n }\n @if (UserCanUpdate) {\n <button\n class=\"action-btn\"\n (click)=\"editType(type, $event)\"\n title=\"Edit Type\"\n >\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n }\n @if (UserCanDelete && type.credentialCount === 0) {\n <button\n class=\"action-btn danger\"\n (click)=\"deleteType(type, $event)\"\n title=\"Delete Type\"\n >\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n }\n </div>\n <i class=\"fa-solid fa-chevron-right arrow\"></i>\n </div>\n }\n </div>\n </div>\n }\n @if (filteredTypes.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-cubes\"></i>\n </div>\n <h3>No Credential Types Found</h3>\n @if (searchText || selectedCategoryFilter) {\n <p>\n No types match your current filters.\n <button class=\"btn-link\" (click)=\"clearFilters()\">Clear filters</button>\n </p>\n }\n @if (!searchText && !selectedCategoryFilter) {\n <p>\n Get started by creating your first credential type.\n </p>\n }\n @if (UserCanCreate && !searchText && !selectedCategoryFilter) {\n <button class=\"btn-primary\" (click)=\"createNewType()\">\n <i class=\"fa-solid fa-plus\"></i>\n Create Type\n </button>\n }\n </div>\n }\n </div>\n <!-- Type Detail -->\n @if (selectedType) {\n <div class=\"type-detail\">\n <div class=\"detail-header\">\n <div class=\"detail-icon\" [style.backgroundColor]=\"getCategoryColor(selectedType.Category) + '15'\" [style.color]=\"getCategoryColor(selectedType.Category)\">\n <i [class]=\"selectedType.IconClass || 'fa-solid fa-key'\"></i>\n </div>\n <div class=\"detail-title\">\n <h2>{{selectedType.Name}}</h2>\n <span class=\"category-badge\" [style.backgroundColor]=\"getCategoryColor(selectedType.Category) + '20'\" [style.color]=\"getCategoryColor(selectedType.Category)\">\n <i [class]=\"getCategoryIcon(selectedType.Category)\"></i>\n {{selectedType.Category}}\n </span>\n </div>\n <div class=\"detail-actions\">\n @if (UserCanUpdate) {\n <button class=\"action-btn\" (click)=\"editType(selectedType)\" title=\"Edit\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n }\n <button class=\"close-btn\" (click)=\"closeDetail()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n </div>\n <div class=\"detail-body\">\n <!-- Stats Row -->\n <div class=\"detail-stats\">\n <div class=\"detail-stat\">\n <div class=\"stat-value\">{{selectedType.credentialCount}}</div>\n <div class=\"stat-label\">Credentials</div>\n </div>\n <div class=\"detail-stat active\">\n <div class=\"stat-value\">{{selectedType.activeCount}}</div>\n <div class=\"stat-label\">Active</div>\n </div>\n @if (selectedType.expiringCount > 0) {\n <div class=\"detail-stat warning\">\n <div class=\"stat-value\">{{selectedType.expiringCount}}</div>\n <div class=\"stat-label\">Expiring</div>\n </div>\n }\n </div>\n @if (selectedType.Description) {\n <p class=\"description\">\n {{selectedType.Description}}\n </p>\n }\n <div class=\"schema-section\">\n <h3>\n <i class=\"fa-solid fa-list-check\"></i>\n Field Schema\n </h3>\n @if (schemaProperties.length > 0) {\n <div class=\"field-list\">\n @for (prop of schemaProperties; track prop) {\n <div class=\"field-item\">\n <div class=\"field-header\">\n <span class=\"field-name\">{{prop.title}}</span>\n <span class=\"field-badges\">\n <span class=\"badge type\">{{prop.type}}</span>\n @if (prop.isSecret) {\n <span class=\"badge secret\">\n <i class=\"fa-solid fa-lock\"></i> Secret\n </span>\n }\n @if (prop.required) {\n <span class=\"badge required\">Required</span>\n }\n </span>\n </div>\n @if (prop.description) {\n <p class=\"field-description\">\n {{prop.description}}\n </p>\n }\n </div>\n }\n </div>\n }\n @if (schemaProperties.length === 0) {\n <div class=\"no-fields\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>No fields defined in schema</span>\n </div>\n }\n </div>\n @if (selectedType.ValidationEndpoint) {\n <div class=\"validation-section\">\n <h3>\n <i class=\"fa-solid fa-check-circle\"></i>\n Validation\n </h3>\n <div class=\"validation-endpoint\">\n <i class=\"fa-solid fa-link\"></i>\n <span>{{selectedType.ValidationEndpoint}}</span>\n </div>\n </div>\n }\n <!-- Quick Actions -->\n @if (UserCanCreateCredential) {\n <div class=\"detail-quick-actions\">\n <button class=\"btn-primary\" (click)=\"createCredentialForType(selectedType)\">\n <i class=\"fa-solid fa-plus\"></i>\n Create Credential\n </button>\n </div>\n }\n </div>\n </div>\n }\n <!-- No Selection -->\n @if (!selectedType && filteredTypes.length > 0) {\n <div class=\"no-selection\">\n <div class=\"no-selection-icon\">\n <i class=\"fa-solid fa-hand-pointer\"></i>\n </div>\n <h3>Select a Credential Type</h3>\n <p>Click on a credential type to view its details and field schema</p>\n </div>\n }\n </div>\n }\n</div>\n\n<!-- Type Edit Panel -->\n<mj-credential-type-edit-panel\n #typeEditPanel\n (saved)=\"onTypeSaved($any($event))\"\n (deleted)=\"onTypeDeleted($any($event))\"\n></mj-credential-type-edit-panel>\n"]}
|
|
1
|
+
{"version":3,"file":"credentials-types-resource.component.js","sourceRoot":"","sources":["../../../src/Credentials/components/credentials-types-resource.component.ts","../../../src/Credentials/components/credentials-types-resource.component.html"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,SAAS,EAAwC,uBAAuB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAEpH,OAAO,EAAE,aAAa,EAAG,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAqB,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;;;;;;;;;ICHrE,gCAA4D;;;;IAyBtD,kCAAsD;IAA1B,qNAAS,sBAAe,KAAC;IACnD,wBAAgC;IAChC,4BAAM;IAAA,wBAAQ;IAChB,AADgB,iBAAO,EACd;;;;IAgBP,kCAA0D;IAA7B,qNAAS,sBAAe,EAAE,CAAC,KAAC;IACvD,wBAAiC;IACnC,iBAAS;;;IAUT,kCAAsB;IAAA,YAAO;IAAA,iBAAS;;;IAA9B,8BAAa;IAAC,cAAO;IAAP,4BAAO;;;IAoCnB,+BAA8B;IAC5B,YACF;;IAAA,iBAAM;;;IADJ,cACF;IADE,mIACF;;;IAIE,gCAAyB;IACvB,wBAA+B;IAC/B,YACF;IAAA,iBAAO;;;IADL,eACF;IADE,wDACF;;;IAGA,gCAAgC;IAC9B,wBAAiC;IACjC,YACF;IAAA,iBAAO;;;IADL,eACF;IADE,2DACF;;;IAGA,gCAAiC;IAC/B,wBAAiC;IACjC,YACF;IAAA,iBAAO;;;IADL,eACF;IADE,+DACF;;;;IAMF,kCAIG;IAFD,sRAAS,+CAAqC,KAAC;IAG/C,wBAAgC;IAClC,iBAAS;;;;IAGT,kCAIG;IAFD,uRAAS,gCAAsB,KAAC;IAGhC,wBAA+B;IACjC,iBAAS;;;;IAGT,kCAIG;IAFD,uRAAS,kCAAwB,KAAC;IAGlC,wBAAiC;IACnC,iBAAS;;;;IA9Df,+BAIG;IADD,0OAAS,0BAAgB,KAAC;IAE1B,+BAAwI;IACtI,oBAAqD;IACvD,iBAAM;IAEJ,AADF,+BAAuB,cACE;IAAA,YAAa;IAAA,iBAAM;IAC1C,+HAAwB;IAKxB,+BAAuB;IACrB,gIAAgC;IAMhC,gIAA4B;IAM5B,kIAA8B;IAOlC,AADE,iBAAM,EACF;IACN,gCAA0B;IACxB,oIAA+B;IAS/B,oIAAqB;IASrB,oIAAmD;IASrD,iBAAM;IACN,yBAA+C;IACjD,iBAAM;;;;IAhEJ,0DAAuC;IAGhB,cAAgE;IAAC,AAAjE,oFAAgE,oDAAgD;IAClI,cAA6C;IAA7C,qDAA6C;IAGzB,eAAa;IAAb,kCAAa;IACpC,cAIC;IAJD,8CAIC;IAEC,eAKC;IALD,sDAKC;IACD,cAKC;IALD,kDAKC;IACD,cAKC;IALD,qDAKC;IAIH,eAQC;IARD,0DAQC;IACD,cAQC;IARD,gDAQC;IACD,cAQC;IARD,iFAQC;;;IAtET,AADF,+BAA8B,cACuD;IACjF,oBAAwF;IACxF,gCAA4B;IAAA,YAAa;IAAA,iBAAO;IAChD,gCAAoB;IAAA,YAAsB;IAC5C,AAD4C,iBAAO,EAC7C;IACN,+BAAwB;IACtB,8IAoEC;IAEL,AADE,iBAAM,EACF;;;;IA5EyB,cAAqD;IAArD,2EAAqD;IAC7E,cAAoC;IAApC,oDAAoC;IAAC,+DAA2C;IACvD,eAAa;IAAb,mCAAa;IACrB,eAAsB;IAAtB,4CAAsB;IAG1C,eAoEC;IApED,8BAoEC;;;;IAWD,yBAAG;IACD,sDACA;IAAA,kCAAkD;IAAzB,oOAAS,qBAAc,KAAC;IAAC,6BAAa;IACjE,AADiE,iBAAS,EACtE;;;IAGJ,yBAAG;IACD,qEACF;IAAA,iBAAI;;;;IAGJ,kCAAsD;IAA1B,oOAAS,sBAAe,KAAC;IACnD,wBAAgC;IAChC,6BACF;IAAA,iBAAS;;;IAnBX,AADF,+BAAyB,cACC;IACtB,wBAAiC;IACnC,iBAAM;IACN,0BAAI;IAAA,yCAAyB;IAAA,iBAAK;IAClC,2HAA4C;IAM5C,2HAA8C;IAK9C,oIAA+D;IAMjE,iBAAM;;;IAjBJ,eAKC;IALD,6EAKC;IACD,cAIC;IAJD,+EAIC;IACD,cAKC;IALD,uGAKC;;;;IAoBG,kCAAyE;IAA9C,qOAAS,oCAAsB,KAAC;IACzD,wBAA+B;IACjC,iBAAS;;;IAoBP,AADF,+BAAiC,cACP;IAAA,YAA8B;IAAA,iBAAM;IAC5D,+BAAwB;IAAA,wBAAQ;IAClC,AADkC,iBAAM,EAClC;;;IAFoB,eAA8B;IAA9B,uDAA8B;;;IAM1D,6BAAuB;IACrB,YACF;IAAA,iBAAI;;;IADF,cACF;IADE,gEACF;;;IAgBc,gCAA2B;IACzB,wBAAgC;IAAC,wBACnC;IAAA,iBAAO;;;IAGP,gCAA6B;IAAA,wBAAQ;IAAA,iBAAO;;;IAKhD,6BAA6B;IAC3B,YACF;IAAA,iBAAI;;;IADF,cACF;IADE,qDACF;;;IAhBA,AADF,AADF,+BAAwB,cACI,eACC;IAAA,YAAc;IAAA,iBAAO;IAE5C,AADF,gCAA2B,eACA;IAAA,YAAa;IAAA,iBAAO;IAC7C,uJAAqB;IAKrB,uJAAqB;IAIzB,AADE,iBAAO,EACH;IACN,oJAAwB;IAK1B,iBAAM;;;IAlBuB,eAAc;IAAd,oCAAc;IAEZ,eAAa;IAAb,mCAAa;IACtC,cAIC;IAJD,4CAIC;IACD,cAEC;IAFD,4CAEC;IAGL,cAIC;IAJD,+CAIC;;;IArBP,+BAAwB;IACtB,oKAsBC;IACH,iBAAM;;;IAvBJ,cAsBC;IAtBD,sCAsBC;;;IAIH,+BAAuB;IACrB,wBAAuC;IACvC,4BAAM;IAAA,2CAA2B;IACnC,AADmC,iBAAO,EACpC;;;IAKN,AADF,+BAAgC,SAC1B;IACF,wBAAwC;IACxC,4BACF;IAAA,iBAAK;IACL,+BAAiC;IAC/B,yBAAgC;IAChC,4BAAM;IAAA,YAAmC;IAE7C,AADE,AAD2C,iBAAO,EAC5C,EACF;;;IAFI,eAAmC;IAAnC,4DAAmC;;;;IAO3C,AADF,+BAAkC,iBAC4C;IAAhD,qOAAS,mDAAqC,KAAC;IACzE,wBAAgC;IAChC,mCACF;IACF,AADE,iBAAS,EACL;;;;IAtGR,AADF,AADF,+BAAyB,cACI,cACiI;IACxJ,oBAA6D;IAC/D,iBAAM;IAEJ,AADF,+BAA0B,SACpB;IAAA,YAAqB;IAAA,iBAAK;IAC9B,gCAA8J;IAC5J,oBAAwD;IACxD,YACF;IACF,AADE,iBAAO,EACH;IACN,gCAA4B;IAC1B,sIAAqB;IAKrB,mCAAkD;IAAxB,uNAAS,oBAAa,KAAC;IAC/C,yBAAiC;IAGvC,AADE,AADE,iBAAS,EACL,EACF;IAKA,AADF,AADF,AAFF,gCAAyB,eAEG,eACC,eACC;IAAA,aAAgC;IAAA,iBAAM;IAC9D,gCAAwB;IAAA,4BAAW;IACrC,AADqC,iBAAM,EACrC;IAEJ,AADF,gCAAgC,eACN;IAAA,aAA4B;IAAA,iBAAM;IAC1D,gCAAwB;IAAA,uBAAM;IAChC,AADgC,iBAAM,EAChC;IACN,mIAAsC;IAMxC,iBAAM;IACN,iIAAgC;IAM9B,AADF,gCAA4B,UACtB;IACF,yBAAsC;IACtC,+BACF;IAAA,iBAAK;IACL,mIAAmC;IA2BnC,mIAAqC;IAMvC,iBAAM;IACN,mIAAuC;IAavC,mIAA+B;IASnC,AADE,iBAAM,EACF;;;IAzGuB,eAAwE;IAAC,AAAzE,gGAAwE,gEAAwD;IACpJ,cAAqD;IAArD,iEAAqD;IAGpD,eAAqB;IAArB,8CAAqB;IACI,cAAwE;IAAC,AAAzE,gGAAwE,gEAAwD;IACxJ,cAAgD;IAAhD,mEAAgD;IACnD,cACF;IADE,6DACF;IAGA,eAIC;IAJD,gDAIC;IAUyB,eAAgC;IAAhC,yDAAgC;IAIhC,eAA4B;IAA5B,qDAA4B;IAGtD,eAKC;IALD,iEAKC;IAEH,cAIC;IAJD,2DAIC;IAMC,eA0BC;IA1BD,8DA0BC;IACD,cAKC;IALD,gEAKC;IAEH,cAWC;IAXD,kEAWC;IAED,cAOC;IAPD,0DAOC;;;IAOH,AADF,+BAA0B,eACO;IAC7B,yBAAwC;IAC1C,iBAAM;IACN,0BAAI;IAAA,wCAAwB;IAAA,iBAAK;IACjC,yBAAG;IAAA,+EAA+D;IACpE,AADoE,iBAAI,EAClE;;;;IAlSN,AADF,AADF,8BAA0B,aACC,YACC;IAAA,gCAAgB;IAAA,iBAAK;IAE3C,AADF,8BAA0B,cACA;IACtB,uBAAkC;IAClC,YACF;IAAA,iBAAO;IACP,+BAAwB;IACtB,wBAAkC;IAClC,aACF;IAAA,iBAAO;IACP,gCAAwB;IACtB,yBAA+B;IAC/B,aACF;IAEJ,AADE,AADE,iBAAO,EACH,EACF;IACN,gCAA4B;IAC1B,uHAAqB;IAOzB,AADE,iBAAM,EACF;IAIF,AADF,AADF,gCAAqB,eACO,eACM;IAC5B,yBAAkC;IAClC,kCAKI;IADF,2MAAS,0CAAyC,KAAC;IAJrD,iBAKI;IACJ,uHAAkB;IAKpB,iBAAM;IACN,mCAIG;IADD,8MAAU,kDAAiD,KAAC;IAE5D,mCAAiB;IAAA,+BAAc;IAAA,iBAAS;IACxC,0IAEC;IAEL,AADE,iBAAS,EACL;IAEJ,AADF,gCAA2B,eACC;IACxB,aACF;IAAA,iBAAM;IACN,mCAA6D;IAApC,sMAAS,gBAAS,KAAC;IAC1C,yBAAmC;IAGzC,AADE,AADE,iBAAS,EACL,EACF;IAGJ,AAFF,gCAA0B,eAEA;IACtB,wIA+EC;;IACD,oHAAkC;IAyBpC,iBAAM;IAEN,sHAAoB;IA+GpB,oHAAiD;IASnD,iBAAM;;;IAhSE,eACF;IADE,0DACF;IAGE,eACF;IADE,oEACF;IAGE,eACF;IADE,6EACF;IAIF,eAKC;IALD,gDAKC;IAWG,eAAoB;IAApB,yCAAoB;IAGtB,cAIC;IAJD,6CAIC;IAID,cAAgC;IAAhC,qDAAgC;IAIhC,eAEC;IAFD,gCAEC;IAKD,eACF;IADE,+FACF;IASA,eA+EC;IA/ED,qCAAA,2BAAoB,EA+EnB;IACD,eAwBC;IAxBD,6DAwBC;IAGH,cA6GC;IA7GD,+CA6GC;IAED,cAQC;IARD,mFAQC;;AD9QA,IAAM,iCAAiC,GAAvC,MAAM,iCAAkC,SAAQ,qBAAqB;IAoB5D;IACA;IApBL,SAAS,GAAG,IAAI,CAAC;IACjB,KAAK,GAAoB,EAAE,CAAC;IAC5B,aAAa,GAAoB,EAAE,CAAC;IACpC,WAAW,GAAyB,EAAE,CAAC;IACvC,YAAY,GAAyB,IAAI,CAAC;IAC1C,gBAAgB,GAA0B,EAAE,CAAC;IAEpD,UAAU;IACH,UAAU,GAAG,EAAE,CAAC;IAChB,sBAAsB,GAAG,EAAE,CAAC;IAC5B,UAAU,GAAa,EAAE,CAAC;IAEjC,cAAc;IACN,SAAS,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC3B,gBAAgB,GAAG,IAAI,GAAG,EAAmB,CAAC;IAE1B,aAAa,CAAoC;IAE7E,YACY,GAAsB,EACtB,iBAAoC;QAE5C,KAAK,EAAE,CAAC;QAHA,QAAG,GAAH,GAAG,CAAmB;QACtB,sBAAiB,GAAjB,iBAAiB,CAAmB;IAGhD,CAAC;IAED,QAAQ;QACJ,IAAI,CAAC,QAAQ,EAAE,CAAC;IACpB,CAAC;IAED,WAAW;QACP,oBAAoB;IACxB,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,IAAkB;QAC3C,OAAO,kBAAkB,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,IAAkB;QACzC,OAAO,mBAAmB,CAAC;IAC/B,CAAC;IAED,4BAA4B;IAE5B,IAAW,aAAa;QACpB,OAAO,IAAI,CAAC,qBAAqB,CAAC,sBAAsB,EAAE,QAAQ,CAAC,CAAC;IACxE,CAAC;IAED,IAAW,aAAa;QACpB,OAAO,IAAI,CAAC,qBAAqB,CAAC,sBAAsB,EAAE,QAAQ,CAAC,CAAC;IACxE,CAAC;IAED,IAAW,aAAa;QACpB,OAAO,IAAI,CAAC,qBAAqB,CAAC,sBAAsB,EAAE,QAAQ,CAAC,CAAC;IACxE,CAAC;IAED,IAAW,uBAAuB;QAC9B,OAAO,IAAI,CAAC,qBAAqB,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;IACnE,CAAC;IAEO,qBAAqB,CAAC,UAAkB,EAAE,cAAuD;QACrG,MAAM,QAAQ,GAAG,GAAG,UAAU,IAAI,cAAc,EAAE,CAAC;QAEnD,IAAI,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC;QAChD,CAAC;QAED,IAAI,CAAC;YACD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;YAC5E,IAAI,CAAC,UAAU,EAAE,CAAC;gBACd,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;gBAC3C,OAAO,KAAK,CAAC;YACjB,CAAC;YAED,MAAM,eAAe,GAAG,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YACjF,IAAI,aAAa,GAAG,KAAK,CAAC;YAE1B,QAAQ,cAAc,EAAE,CAAC;gBACrB,KAAK,QAAQ;oBAAE,aAAa,GAAG,eAAe,CAAC,SAAS,CAAC;oBAAC,MAAM;gBAChE,KAAK,MAAM;oBAAE,aAAa,GAAG,eAAe,CAAC,OAAO,CAAC;oBAAC,MAAM;gBAC5D,KAAK,QAAQ;oBAAE,aAAa,GAAG,eAAe,CAAC,SAAS,CAAC;oBAAC,MAAM;gBAChE,KAAK,QAAQ;oBAAE,aAAa,GAAG,eAAe,CAAC,SAAS,CAAC;oBAAC,MAAM;YACpE,CAAC;YAED,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;YACnD,OAAO,aAAa,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC3C,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,QAAQ;QAClB,IAAI,CAAC;YACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YAExB,MAAM,EAAE,GAAG,IAAI,OAAO,EAAE,CAAC;YACzB,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC;gBAC/C;oBACI,UAAU,EAAE,sBAAsB;oBAClC,OAAO,EAAE,gBAAgB;oBACzB,UAAU,EAAE,eAAe;iBAC9B;gBACD;oBACI,UAAU,EAAE,iBAAiB;oBAC7B,UAAU,EAAE,eAAe;iBAC9B;aACJ,CAAC,CAAC;YAEH,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;gBACrB,MAAM,SAAS,GAAG,UAAU,CAAC,OAAmC,CAAC;gBACjE,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,OAA+B,CAAC,CAAC,CAAC,EAAE,CAAC;gBAExF,gCAAgC;gBAChC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;gBAEnE,4BAA4B;gBAC5B,IAAI,CAAC,UAAU,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC3E,CAAC;YAED,+EAA+E;YAC/E,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAE9B,IAAI,CAAC,YAAY,EAAE,CAAC;QAExB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;YACxD,qBAAqB,CAAC,QAAQ,CAAC,wBAAwB,CAAC,gCAAgC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAC7G,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC5B,CAAC;IACL,CAAC;IAEO,sBAAsB;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC;QACxC,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,OAAO;QACX,CAAC;QAED,+CAA+C;QAC/C,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;YACxB,IAAI,CAAC,sBAAsB,GAAG,MAAM,CAAC,cAAwB,CAAC;QAClE,CAAC;IACL,CAAC;IAEO,mBAAmB,CAAC,IAA4B;QACpD,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,gBAAgB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9F,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,iBAAiB,GAAG,IAAI,IAAI,EAAE,CAAC;QACrC,iBAAiB,CAAC,OAAO,CAAC,iBAAiB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;QAE5D,qDAAqD;QACrD,MAAM,YAAY,GAAG,IAAqB,CAAC;QAC3C,YAAY,CAAC,eAAe,GAAG,eAAe,CAAC,MAAM,CAAC;QACtD,YAAY,CAAC,WAAW,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;QAC1E,YAAY,CAAC,aAAa,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACpD,CAAC,CAAC,SAAS;YACX,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,GAAG;YAC5B,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,iBAAiB,CAC7C,CAAC,MAAM,CAAC;QAET,OAAO,YAAY,CAAC;IACxB,CAAC;IAED,0BAA0B;IAEnB,aAAa;QAChB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC;IACL,CAAC;IAEM,QAAQ,CAAC,IAAmB,EAAE,KAAa;QAC9C,IAAI,KAAK,EAAE,CAAC;YACR,KAAK,CAAC,eAAe,EAAE,CAAC;QAC5B,CAAC;QACD,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC;IACL,CAAC;IAEM,KAAK,CAAC,UAAU,CAAC,IAAmB,EAAE,KAAa;QACtD,IAAI,KAAK,EAAE,CAAC;YACR,KAAK,CAAC,eAAe,EAAE,CAAC;QAC5B,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACtB,qBAAqB,CAAC,QAAQ,CAAC,wBAAwB,CAAC,uDAAuD,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;YAClI,OAAO;QACX,CAAC;QAED,IAAI,IAAI,CAAC,eAAe,GAAG,CAAC,EAAE,CAAC;YAC3B,qBAAqB,CAAC,QAAQ,CAAC,wBAAwB,CACnD,kBAAkB,IAAI,CAAC,IAAI,cAAc,IAAI,CAAC,eAAe,yBAAyB,EACtF,SAAS,EACT,IAAI,CACP,CAAC;YACF,OAAO;QACX,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,oCAAoC,IAAI,CAAC,IAAI,kCAAkC,CAAC,CAAC;QAC3G,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,IAAI,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;YACpC,IAAI,OAAO,EAAE,CAAC;gBACV,qBAAqB,CAAC,QAAQ,CAAC,wBAAwB,CAAC,oBAAoB,IAAI,CAAC,IAAI,wBAAwB,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;gBAChI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBAChE,IAAI,UAAU,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC7C,IAAI,CAAC,WAAW,EAAE,CAAC;gBACvB,CAAC;gBACD,IAAI,CAAC,YAAY,EAAE,CAAC;YACxB,CAAC;iBAAM,CAAC;gBACJ,qBAAqB,CAAC,QAAQ,CAAC,wBAAwB,CAAC,kCAAkC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;YAC/G,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;YACxD,qBAAqB,CAAC,QAAQ,CAAC,wBAAwB,CAAC,gCAAgC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAC7G,CAAC;IACL,CAAC;IAEM,uBAAuB,CAAC,IAAmB,EAAE,KAAa;QAC7D,IAAI,KAAK,EAAE,CAAC;YACR,KAAK,CAAC,eAAe,EAAE,CAAC;QAC5B,CAAC;QACD,oFAAoF;QACpF,IAAI,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,aAAa,EAAE;YACpD,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,eAAe,EAAE,IAAI;SACxB,CAAC,CAAC;IACP,CAAC;IAED,+BAA+B;IAExB,WAAW,CAAC,IAA4B;QAC3C,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3E,MAAM,YAAY,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAEpD,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;YACrB,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,YAAY,CAAC;QAC7C,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACrC,CAAC;QAED,2CAA2C;QAC3C,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,UAAU,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3E,CAAC;QAED,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAEM,aAAa,CAAC,MAAc;QAC/B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;QAC/D,IAAI,UAAU,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC;YAC5C,IAAI,CAAC,WAAW,EAAE,CAAC;QACvB,CAAC;QACD,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAED,oBAAoB;IAEb,cAAc,CAAC,KAAa;QAC/B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC,YAAY,EAAE,CAAC;IACxB,CAAC;IAEM,sBAAsB,CAAC,QAAgB;QAC1C,IAAI,CAAC,sBAAsB,GAAG,QAAQ,CAAC;QACvC,IAAI,CAAC,YAAY,EAAE,CAAC;IACxB,CAAC;IAEM,YAAY;QACf,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QACrB,IAAI,CAAC,sBAAsB,GAAG,EAAE,CAAC;QACjC,IAAI,CAAC,YAAY,EAAE,CAAC;IACxB,CAAC;IAEO,YAAY;QAChB,IAAI,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAE/B,qBAAqB;QACrB,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAC9B,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAChF,CAAC;QAED,wBAAwB;QACxB,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;YACpD,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAC3B,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC;gBACrC,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBAC/D,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAC5C,CAAC;QACN,CAAC;QAED,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAED,oBAAoB;IAEb,UAAU,CAAC,IAAmB;QACjC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACxC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAEM,WAAW;QACd,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAEO,gBAAgB,CAAC,UAAkB;QACvC,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAkF,CAAC;YACvH,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;YAC3C,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;YAEvC,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;gBACtE,IAAI;gBACJ,IAAI,EAAG,IAAI,CAAC,IAAe,IAAI,QAAQ;gBACvC,KAAK,EAAG,IAAI,CAAC,KAAgB,IAAI,IAAI;gBACrC,WAAW,EAAG,IAAI,CAAC,WAAsB,IAAI,EAAE;gBAC/C,QAAQ,EAAE,IAAI,CAAC,QAAQ,KAAK,IAAI;gBAChC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC;aACpC,CAAC,CAAC,CAAC;YAEJ,gDAAgD;YAChD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;gBAChC,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBACjC,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBACjC,MAAM,MAAM,GAAG,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;gBACnE,MAAM,MAAM,GAAG,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;gBACnE,OAAO,MAAM,GAAG,MAAM,CAAC;YAC3B,CAAC,CAAC,CAAC;QAEP,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,CAAC,CAAC,CAAC;YAClD,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC/B,CAAC;IACL,CAAC;IAED,kBAAkB;IAEX,eAAe,CAAC,QAAgB;QACnC,MAAM,OAAO,GAA2B;YACpC,IAAI,EAAE,mBAAmB;YACzB,eAAe,EAAE,sBAAsB;YACvC,SAAS,EAAE,mBAAmB;YAC9B,UAAU,EAAE,sBAAsB;YAClC,gBAAgB,EAAE,2BAA2B;YAC7C,aAAa,EAAE,kBAAkB;SACpC,CAAC;QACF,OAAO,OAAO,CAAC,QAAQ,CAAC,IAAI,iBAAiB,CAAC;IAClD,CAAC;IAEM,gBAAgB,CAAC,QAAgB;QACpC,MAAM,QAAQ,GAA2B;YACrC,IAAI,EAAE,yBAAyB;YAC/B,eAAe,EAAE,yBAAyB;YAC1C,SAAS,EAAE,yBAAyB;YACpC,UAAU,EAAE,0BAA0B;YACtC,gBAAgB,EAAE,0BAA0B;YAC5C,aAAa,EAAE,yBAAyB;SAC3C,CAAC;QACF,OAAO,QAAQ,CAAC,QAAQ,CAAC,IAAI,yBAAyB,CAAC;IAC3D,CAAC;IAEM,kBAAkB;QACrB,MAAM,OAAO,GAAG,IAAI,GAAG,EAA2B,CAAC;QACnD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;YAC/B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACzB,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAC9B,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,OAAO,CAAC;IACnB,CAAC;IAED,4FAA4F;IACrF,cAAc,CAAC,IAAmB;QACrC,OAAO,UAAU,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IACtD,CAAC;IAEM,uBAAuB;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IACrE,CAAC;IAEM,OAAO;QACV,IAAI,CAAC,QAAQ,EAAE,CAAC;IACpB,CAAC;2HA9YQ,iCAAiC;6DAAjC,iCAAiC;;;;;;;YC9B9C,8BAA6B;YAC3B,0GAAiB;YAIjB,2FAAkB;YA0SpB,iBAAM;YAGN,2DAIC;YADC,AADA,iLAAS,uBAAyB,KAAC,wKACxB,yBAA2B,KAAC;YACxC,iBAAgC;;YArT/B,cAEC;YAFD,wCAEC;YAED,cAySC;YAzSD,yCAySC;;;ADhRU,iCAAiC;IAR7C,aAAa,CAAC,qBAAqB,EAAE,0BAA0B,CAAC;GAQpD,iCAAiC,CA+Y7C;;iFA/YY,iCAAiC;cAP7C,SAAS;6BACI,KAAK,YACL,+BAA+B,mBAGxB,uBAAuB,CAAC,MAAM;;kBAmB9C,SAAS;mBAAC,eAAe;;kFAjBjB,iCAAiC","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef, ChangeDetectionStrategy, ViewChild } from '@angular/core';\nimport { ResourceData, MJCredentialTypeEntity, MJCredentialEntity } from '@memberjunction/core-entities';\nimport { RegisterClass , UUIDsEqual } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { RunView, Metadata } from '@memberjunction/core';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { CredentialTypeEditPanelComponent } from '@memberjunction/ng-credentials';\ninterface FieldSchemaProperty {\n name: string;\n type: string;\n title: string;\n description: string;\n isSecret: boolean;\n required: boolean;\n}\n\ninterface TypeWithStats extends MJCredentialTypeEntity {\n credentialCount: number;\n activeCount: number;\n expiringCount: number;\n}\n\n@RegisterClass(BaseResourceComponent, 'CredentialsTypesResource')\n@Component({\n standalone: false,\n selector: 'mj-credentials-types-resource',\n templateUrl: './credentials-types-resource.component.html',\n styleUrls: ['./credentials-types-resource.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class CredentialsTypesResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public isLoading = true;\n public types: TypeWithStats[] = [];\n public filteredTypes: TypeWithStats[] = [];\n public credentials: MJCredentialEntity[] = [];\n public selectedType: TypeWithStats | null = null;\n public schemaProperties: FieldSchemaProperty[] = [];\n\n // Filters\n public searchText = '';\n public selectedCategoryFilter = '';\n public categories: string[] = [];\n\n // Permissions\n private _metadata = new Metadata();\n private _permissionCache = new Map<string, boolean>();\n\n @ViewChild('typeEditPanel') typeEditPanel!: CredentialTypeEditPanelComponent;\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 // Cleanup if needed\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Credential Types';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-cubes';\n }\n\n // === Permission Checks ===\n\n public get UserCanCreate(): boolean {\n return this.checkEntityPermission('MJ: Credential Types', 'Create');\n }\n\n public get UserCanUpdate(): boolean {\n return this.checkEntityPermission('MJ: Credential Types', 'Update');\n }\n\n public get UserCanDelete(): boolean {\n return this.checkEntityPermission('MJ: Credential Types', 'Delete');\n }\n\n public get UserCanCreateCredential(): boolean {\n return this.checkEntityPermission('MJ: Credentials', 'Create');\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 const [typeResult, credResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Credential Types',\n OrderBy: 'Category, Name',\n ResultType: 'entity_object'\n },\n {\n EntityName: 'MJ: Credentials',\n ResultType: 'entity_object'\n }\n ]);\n\n if (typeResult.Success) {\n const baseTypes = typeResult.Results as MJCredentialTypeEntity[];\n this.credentials = credResult.Success ? credResult.Results as MJCredentialEntity[] : [];\n\n // Calculate stats for each type\n this.types = baseTypes.map(type => this.enrichTypeWithStats(type));\n\n // Extract unique categories\n this.categories = [...new Set(this.types.map(t => t.Category))].sort();\n }\n\n // Apply any navigation config (e.g., category filter from Categories nav item)\n this.handleNavigationConfig();\n\n this.applyFilters();\n\n } catch (error) {\n console.error('Error loading credential types:', error);\n MJNotificationService.Instance.CreateSimpleNotification('Error loading credential types', 'error', 3000);\n } finally {\n this.isLoading = false;\n this.NotifyLoadComplete();\n this.cdr.markForCheck();\n }\n }\n\n private handleNavigationConfig(): void {\n const config = this.Data?.Configuration;\n if (!config) {\n return;\n }\n\n // Apply category filter from navigation config\n if (config.categoryFilter) {\n this.selectedCategoryFilter = config.categoryFilter as string;\n }\n }\n\n private enrichTypeWithStats(type: MJCredentialTypeEntity): TypeWithStats {\n const typeCredentials = this.credentials.filter(c => UUIDsEqual(c.CredentialTypeID, type.ID));\n const now = new Date();\n const thirtyDaysFromNow = new Date();\n thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30);\n\n // Add stats properties directly to the entity object\n const enrichedType = type as TypeWithStats;\n enrichedType.credentialCount = typeCredentials.length;\n enrichedType.activeCount = typeCredentials.filter(c => c.IsActive).length;\n enrichedType.expiringCount = typeCredentials.filter(c =>\n c.ExpiresAt &&\n new Date(c.ExpiresAt) >= now &&\n new Date(c.ExpiresAt) <= thirtyDaysFromNow\n ).length;\n\n return enrichedType;\n }\n\n // === CRUD Operations ===\n\n public createNewType(): void {\n if (this.typeEditPanel) {\n this.typeEditPanel.open(null);\n }\n }\n\n public editType(type: TypeWithStats, event?: Event): void {\n if (event) {\n event.stopPropagation();\n }\n if (this.typeEditPanel) {\n this.typeEditPanel.open(type);\n }\n }\n\n public async deleteType(type: TypeWithStats, event?: Event): Promise<void> {\n if (event) {\n event.stopPropagation();\n }\n\n if (!this.UserCanDelete) {\n MJNotificationService.Instance.CreateSimpleNotification('You do not have permission to delete credential types', 'warning', 3000);\n return;\n }\n\n if (type.credentialCount > 0) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Cannot delete \"${type.Name}\" - it has ${type.credentialCount} credential(s) using it`,\n 'warning',\n 4000\n );\n return;\n }\n\n const confirmed = confirm(`Are you sure you want to delete \"${type.Name}\"? This action cannot be undone.`);\n if (!confirmed) return;\n\n try {\n const success = await type.Delete();\n if (success) {\n MJNotificationService.Instance.CreateSimpleNotification(`Credential type \"${type.Name}\" deleted successfully`, 'success', 3000);\n this.types = this.types.filter(t => !UUIDsEqual(t.ID, type.ID));\n if (UUIDsEqual(this.selectedType?.ID, type.ID)) {\n this.closeDetail();\n }\n this.applyFilters();\n } else {\n MJNotificationService.Instance.CreateSimpleNotification('Failed to delete credential type', 'error', 3000);\n }\n } catch (error) {\n console.error('Error deleting credential type:', error);\n MJNotificationService.Instance.CreateSimpleNotification('Error deleting credential type', 'error', 3000);\n }\n }\n\n public createCredentialForType(type: TypeWithStats, event?: Event): void {\n if (event) {\n event.stopPropagation();\n }\n // Navigate to Credentials nav item with the type pre-selected and create panel open\n this.navigationService.OpenNavItemByName('Credentials', {\n typeId: type.ID,\n openCreatePanel: true\n });\n }\n\n // === Panel Event Handlers ===\n\n public onTypeSaved(type: MJCredentialTypeEntity): void {\n const existingIndex = this.types.findIndex(t => UUIDsEqual(t.ID, type.ID));\n const enrichedType = this.enrichTypeWithStats(type);\n\n if (existingIndex >= 0) {\n this.types[existingIndex] = enrichedType;\n } else {\n this.types.unshift(enrichedType);\n }\n\n // Update categories if a new one was added\n if (!this.categories.includes(type.Category)) {\n this.categories = [...new Set(this.types.map(t => t.Category))].sort();\n }\n\n this.applyFilters();\n this.cdr.markForCheck();\n }\n\n public onTypeDeleted(typeId: string): void {\n this.types = this.types.filter(t => !UUIDsEqual(t.ID, typeId));\n if (UUIDsEqual(this.selectedType?.ID, typeId)) {\n this.closeDetail();\n }\n this.applyFilters();\n this.cdr.markForCheck();\n }\n\n // === Filtering ===\n\n public onSearchChange(value: string): void {\n this.searchText = value;\n this.applyFilters();\n }\n\n public onCategoryFilterChange(category: string): void {\n this.selectedCategoryFilter = category;\n this.applyFilters();\n }\n\n public clearFilters(): void {\n this.searchText = '';\n this.selectedCategoryFilter = '';\n this.applyFilters();\n }\n\n private applyFilters(): void {\n let filtered = [...this.types];\n\n // Filter by category\n if (this.selectedCategoryFilter) {\n filtered = filtered.filter(t => t.Category === this.selectedCategoryFilter);\n }\n\n // Filter by search text\n if (this.searchText.trim()) {\n const search = this.searchText.toLowerCase().trim();\n filtered = filtered.filter(t =>\n t.Name.toLowerCase().includes(search) ||\n (t.Description && t.Description.toLowerCase().includes(search)) ||\n t.Category.toLowerCase().includes(search)\n );\n }\n\n this.filteredTypes = filtered;\n this.cdr.markForCheck();\n }\n\n // === Selection ===\n\n public selectType(type: TypeWithStats): void {\n this.selectedType = type;\n this.parseFieldSchema(type.FieldSchema);\n this.cdr.markForCheck();\n }\n\n public closeDetail(): void {\n this.selectedType = null;\n this.schemaProperties = [];\n this.cdr.markForCheck();\n }\n\n private parseFieldSchema(schemaJson: string): void {\n try {\n const schema = JSON.parse(schemaJson) as { properties?: Record<string, Record<string, unknown>>; required?: string[] };\n const properties = schema.properties || {};\n const required = schema.required || [];\n\n this.schemaProperties = Object.entries(properties).map(([name, prop]) => ({\n name,\n type: (prop.type as string) || 'string',\n title: (prop.title as string) || name,\n description: (prop.description as string) || '',\n isSecret: prop.isSecret === true,\n required: required.includes(name)\n }));\n\n // Sort by order if available, otherwise by name\n this.schemaProperties.sort((a, b) => {\n const propA = properties[a.name];\n const propB = properties[b.name];\n const orderA = typeof propA.order === 'number' ? propA.order : 999;\n const orderB = typeof propB.order === 'number' ? propB.order : 999;\n return orderA - orderB;\n });\n\n } catch (e) {\n console.error('Failed to parse field schema:', e);\n this.schemaProperties = [];\n }\n }\n\n // === Helpers ===\n\n public 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 public getCategoryColor(category: string): string {\n const colorMap: Record<string, string> = {\n 'AI': 'var(--mj-brand-primary)',\n 'Communication': 'var(--mj-brand-primary)',\n 'Storage': 'var(--mj-brand-primary)',\n 'Database': 'var(--mj-status-warning)',\n 'Authentication': 'var(--mj-status-success)',\n 'Integration': 'var(--mj-brand-primary)'\n };\n return colorMap[category] || 'var(--mj-brand-primary)';\n }\n\n public getTypesByCategory(): Map<string, TypeWithStats[]> {\n const grouped = new Map<string, TypeWithStats[]>();\n for (const type of this.filteredTypes) {\n const category = type.Category;\n if (!grouped.has(category)) {\n grouped.set(category, []);\n }\n grouped.get(category)!.push(type);\n }\n return grouped;\n }\n\n /** Case-insensitive UUID check whether a credential type is the currently selected type. */\n public IsTypeSelected(type: TypeWithStats): boolean {\n return UUIDsEqual(this.selectedType?.ID, type.ID);\n }\n\n public getTotalCredentialCount(): number {\n return this.types.reduce((sum, t) => sum + t.credentialCount, 0);\n }\n\n public refresh(): void {\n this.loadData();\n }\n}\n","<div class=\"types-container\">\n @if (isLoading) {\n <mj-loading text=\"Loading credential types...\"></mj-loading>\n }\n\n @if (!isLoading) {\n <!-- Header -->\n <div class=\"types-header\">\n <div class=\"header-info\">\n <h2 class=\"types-title\">Credential Types</h2>\n <div class=\"header-stats\">\n <span class=\"stat-item\">\n <i class=\"fa-solid fa-shapes\"></i>\n {{types.length}} types\n </span>\n <span class=\"stat-item\">\n <i class=\"fa-solid fa-folder\"></i>\n {{categories.length}} categories\n </span>\n <span class=\"stat-item\">\n <i class=\"fa-solid fa-key\"></i>\n {{getTotalCredentialCount()}} credentials\n </span>\n </div>\n </div>\n <div class=\"header-actions\">\n @if (UserCanCreate) {\n <button class=\"btn-primary\" (click)=\"createNewType()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>New Type</span>\n </button>\n }\n </div>\n </div>\n <!-- Toolbar -->\n <div class=\"toolbar\">\n <div class=\"toolbar-left\">\n <div class=\"search-container\">\n <i class=\"fa-solid fa-search\"></i>\n <input\n type=\"text\"\n placeholder=\"Search types...\"\n [value]=\"searchText\"\n (input)=\"onSearchChange($any($event.target).value)\"\n />\n @if (searchText) {\n <button class=\"search-clear\" (click)=\"onSearchChange('')\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n <select\n class=\"filter-select\"\n [value]=\"selectedCategoryFilter\"\n (change)=\"onCategoryFilterChange($any($event.target).value)\"\n >\n <option value=\"\">All Categories</option>\n @for (cat of categories; track cat) {\n <option [value]=\"cat\">{{cat}}</option>\n }\n </select>\n </div>\n <div class=\"toolbar-right\">\n <div class=\"results-info\">\n {{filteredTypes.length}} of {{types.length}} types\n </div>\n <button class=\"btn-icon\" (click)=\"refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n </div>\n </div>\n <div class=\"types-layout\">\n <!-- Types List -->\n <div class=\"types-list\">\n @for (entry of getTypesByCategory() | keyvalue; track entry) {\n <div class=\"category-section\">\n <div class=\"category-header\" [style.borderLeftColor]=\"getCategoryColor(entry.key)\">\n <i [class]=\"getCategoryIcon(entry.key)\" [style.color]=\"getCategoryColor(entry.key)\"></i>\n <span class=\"category-name\">{{entry.key}}</span>\n <span class=\"count\">{{entry.value.length}}</span>\n </div>\n <div class=\"type-items\">\n @for (type of entry.value; track type) {\n <div\n class=\"type-item\"\n [class.selected]=\"IsTypeSelected(type)\"\n (click)=\"selectType(type)\"\n >\n <div class=\"type-icon\" [style.backgroundColor]=\"getCategoryColor(type.Category) + '15'\" [style.color]=\"getCategoryColor(type.Category)\">\n <i [class]=\"type.IconClass || 'fa-solid fa-key'\"></i>\n </div>\n <div class=\"type-info\">\n <div class=\"type-name\">{{type.Name}}</div>\n @if (type.Description) {\n <div class=\"type-description\">\n {{type.Description | slice:0:60}}{{type.Description.length > 60 ? '...' : ''}}\n </div>\n }\n <div class=\"type-meta\">\n @if (type.credentialCount > 0) {\n <span class=\"meta-badge\">\n <i class=\"fa-solid fa-key\"></i>\n {{type.credentialCount}}\n </span>\n }\n @if (type.activeCount > 0) {\n <span class=\"meta-badge active\">\n <i class=\"fa-solid fa-check\"></i>\n {{type.activeCount}} active\n </span>\n }\n @if (type.expiringCount > 0) {\n <span class=\"meta-badge warning\">\n <i class=\"fa-solid fa-clock\"></i>\n {{type.expiringCount}} expiring\n </span>\n }\n </div>\n </div>\n <div class=\"type-actions\">\n @if (UserCanCreateCredential) {\n <button\n class=\"action-btn\"\n (click)=\"createCredentialForType(type, $event)\"\n title=\"Add Credential\"\n >\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n }\n @if (UserCanUpdate) {\n <button\n class=\"action-btn\"\n (click)=\"editType(type, $event)\"\n title=\"Edit Type\"\n >\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n }\n @if (UserCanDelete && type.credentialCount === 0) {\n <button\n class=\"action-btn danger\"\n (click)=\"deleteType(type, $event)\"\n title=\"Delete Type\"\n >\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n }\n </div>\n <i class=\"fa-solid fa-chevron-right arrow\"></i>\n </div>\n }\n </div>\n </div>\n }\n @if (filteredTypes.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-cubes\"></i>\n </div>\n <h3>No Credential Types Found</h3>\n @if (searchText || selectedCategoryFilter) {\n <p>\n No types match your current filters.\n <button class=\"btn-link\" (click)=\"clearFilters()\">Clear filters</button>\n </p>\n }\n @if (!searchText && !selectedCategoryFilter) {\n <p>\n Get started by creating your first credential type.\n </p>\n }\n @if (UserCanCreate && !searchText && !selectedCategoryFilter) {\n <button class=\"btn-primary\" (click)=\"createNewType()\">\n <i class=\"fa-solid fa-plus\"></i>\n Create Type\n </button>\n }\n </div>\n }\n </div>\n <!-- Type Detail -->\n @if (selectedType) {\n <div class=\"type-detail\">\n <div class=\"detail-header\">\n <div class=\"detail-icon\" [style.backgroundColor]=\"getCategoryColor(selectedType.Category) + '15'\" [style.color]=\"getCategoryColor(selectedType.Category)\">\n <i [class]=\"selectedType.IconClass || 'fa-solid fa-key'\"></i>\n </div>\n <div class=\"detail-title\">\n <h2>{{selectedType.Name}}</h2>\n <span class=\"category-badge\" [style.backgroundColor]=\"getCategoryColor(selectedType.Category) + '20'\" [style.color]=\"getCategoryColor(selectedType.Category)\">\n <i [class]=\"getCategoryIcon(selectedType.Category)\"></i>\n {{selectedType.Category}}\n </span>\n </div>\n <div class=\"detail-actions\">\n @if (UserCanUpdate) {\n <button class=\"action-btn\" (click)=\"editType(selectedType)\" title=\"Edit\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n }\n <button class=\"close-btn\" (click)=\"closeDetail()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n </div>\n <div class=\"detail-body\">\n <!-- Stats Row -->\n <div class=\"detail-stats\">\n <div class=\"detail-stat\">\n <div class=\"stat-value\">{{selectedType.credentialCount}}</div>\n <div class=\"stat-label\">Credentials</div>\n </div>\n <div class=\"detail-stat active\">\n <div class=\"stat-value\">{{selectedType.activeCount}}</div>\n <div class=\"stat-label\">Active</div>\n </div>\n @if (selectedType.expiringCount > 0) {\n <div class=\"detail-stat warning\">\n <div class=\"stat-value\">{{selectedType.expiringCount}}</div>\n <div class=\"stat-label\">Expiring</div>\n </div>\n }\n </div>\n @if (selectedType.Description) {\n <p class=\"description\">\n {{selectedType.Description}}\n </p>\n }\n <div class=\"schema-section\">\n <h3>\n <i class=\"fa-solid fa-list-check\"></i>\n Field Schema\n </h3>\n @if (schemaProperties.length > 0) {\n <div class=\"field-list\">\n @for (prop of schemaProperties; track prop) {\n <div class=\"field-item\">\n <div class=\"field-header\">\n <span class=\"field-name\">{{prop.title}}</span>\n <span class=\"field-badges\">\n <span class=\"badge type\">{{prop.type}}</span>\n @if (prop.isSecret) {\n <span class=\"badge secret\">\n <i class=\"fa-solid fa-lock\"></i> Secret\n </span>\n }\n @if (prop.required) {\n <span class=\"badge required\">Required</span>\n }\n </span>\n </div>\n @if (prop.description) {\n <p class=\"field-description\">\n {{prop.description}}\n </p>\n }\n </div>\n }\n </div>\n }\n @if (schemaProperties.length === 0) {\n <div class=\"no-fields\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>No fields defined in schema</span>\n </div>\n }\n </div>\n @if (selectedType.ValidationEndpoint) {\n <div class=\"validation-section\">\n <h3>\n <i class=\"fa-solid fa-check-circle\"></i>\n Validation\n </h3>\n <div class=\"validation-endpoint\">\n <i class=\"fa-solid fa-link\"></i>\n <span>{{selectedType.ValidationEndpoint}}</span>\n </div>\n </div>\n }\n <!-- Quick Actions -->\n @if (UserCanCreateCredential) {\n <div class=\"detail-quick-actions\">\n <button class=\"btn-primary\" (click)=\"createCredentialForType(selectedType)\">\n <i class=\"fa-solid fa-plus\"></i>\n Create Credential\n </button>\n </div>\n }\n </div>\n </div>\n }\n <!-- No Selection -->\n @if (!selectedType && filteredTypes.length > 0) {\n <div class=\"no-selection\">\n <div class=\"no-selection-icon\">\n <i class=\"fa-solid fa-hand-pointer\"></i>\n </div>\n <h3>Select a Credential Type</h3>\n <p>Click on a credential type to view its details and field schema</p>\n </div>\n }\n </div>\n }\n</div>\n\n<!-- Type Edit Panel -->\n<mj-credential-type-edit-panel\n #typeEditPanel\n (saved)=\"onTypeSaved($any($event))\"\n (deleted)=\"onTypeDeleted($any($event))\"\n></mj-credential-type-edit-panel>\n"]}
|
|
@@ -263,7 +263,7 @@ let CredentialsDashboardComponent = class CredentialsDashboardComponent extends
|
|
|
263
263
|
i0.ɵɵclassProp("selected", ctx.activeTab === "audit");
|
|
264
264
|
i0.ɵɵadvance(6);
|
|
265
265
|
i0.ɵɵconditional((tmp_8_0 = ctx.activeTab) === "overview" ? 48 : tmp_8_0 === "credentials" ? 49 : tmp_8_0 === "types" ? 50 : tmp_8_0 === "categories" ? 51 : tmp_8_0 === "audit" ? 52 : -1);
|
|
266
|
-
} }, dependencies: [i1.CredentialsOverviewResourceComponent, i2.CredentialsListResourceComponent, i3.CredentialsTypesResourceComponent, i4.CredentialsCategoriesResourceComponent, i5.CredentialsAuditResourceComponent], styles: [".credentials-dashboard-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background-color: #f8fafc;\n color: #333;\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n}\n\n.dashboard-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 24px;\n background: linear-gradient(135deg, #1e3a5f 0%, #2d5a87 100%);\n border-bottom: 1px solid rgba(255,255,255,0.1);\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);\n}\n\n.header-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 1.25rem;\n font-weight: 600;\n color: #ffffff;\n}\n\n.header-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #fbbf24;\n font-size: 1.5rem;\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.tab-label[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n font-weight: 500;\n color: rgba(255,255,255,0.8);\n background: rgba(255,255,255,0.15);\n padding: 6px 14px;\n border-radius: 20px;\n backdrop-filter: blur(4px);\n}\n\n.security-badge[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 0.75rem;\n font-weight: 600;\n color: #10b981;\n background: rgba(16, 185, 129, 0.15);\n padding: 6px 12px;\n border-radius: 20px;\n}\n\n.dashboard-content[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n overflow: hidden;\n}\n\n.sidebar[_ngcontent-%COMP%] {\n width: 260px;\n background-color: #fff;\n border-right: 1px solid #e2e8f0;\n padding: 20px 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.sidebar-section[_ngcontent-%COMP%] {\n padding: 0 16px;\n margin-bottom: 8px;\n}\n\n.sidebar-section-title[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n font-weight: 700;\n color: #94a3b8;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n padding: 8px 0;\n}\n\n.nav-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 20px;\n margin: 0 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n color: #475569;\n font-weight: 500;\n border-radius: 10px;\n}\n\n.nav-item[_ngcontent-%COMP%]:hover {\n background-color: #f0f7ff;\n color: #3b82f6;\n}\n\n.nav-item.selected[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n color: #ffffff;\n box-shadow: 0 4px 6px -1px rgba(59, 130, 246, 0.3);\n}\n\n.nav-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 20px;\n text-align: center;\n font-size: 1rem;\n}\n\n.nav-item[_ngcontent-%COMP%] .badge[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: 0.7rem;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 12px;\n background: rgba(59, 130, 246, 0.1);\n color: #3b82f6;\n}\n\n.nav-item.selected[_ngcontent-%COMP%] .badge[_ngcontent-%COMP%] {\n background: rgba(255,255,255,0.2);\n color: #ffffff;\n}\n\n.main-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n background: #f8fafc;\n}\n\n.tab-container[_ngcontent-%COMP%] {\n height: 100%;\n}\n\n.tab-content[_ngcontent-%COMP%] {\n height: 100%;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n\n\n.overview-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 24px;\n margin-bottom: 32px;\n}\n\n.stat-card[_ngcontent-%COMP%] {\n background: #ffffff;\n border-radius: 16px;\n padding: 24px;\n border: 1px solid #e2e8f0;\n box-shadow: 0 1px 3px rgba(0,0,0,0.05);\n transition: all 0.3s ease;\n}\n\n.stat-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: 0 10px 25px -5px rgba(0,0,0,0.1);\n}\n\n.stat-card[_ngcontent-%COMP%] .icon-wrapper[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.25rem;\n margin-bottom: 16px;\n}\n\n.stat-card[_ngcontent-%COMP%] .icon-wrapper.blue[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n color: white;\n}\n\n.stat-card[_ngcontent-%COMP%] .icon-wrapper.green[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n color: white;\n}\n\n.stat-card[_ngcontent-%COMP%] .icon-wrapper.amber[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n color: white;\n}\n\n.stat-card[_ngcontent-%COMP%] .icon-wrapper.red[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);\n color: white;\n}\n\n.stat-card[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n font-weight: 500;\n color: #64748b;\n margin-bottom: 4px;\n}\n\n.stat-card[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 2rem;\n font-weight: 800;\n color: #0f172a;\n}\n\n.stat-card[_ngcontent-%COMP%] .stat-change[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 600;\n margin-top: 8px;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.stat-card[_ngcontent-%COMP%] .stat-change.positive[_ngcontent-%COMP%] { color: #10b981; }\n.stat-card[_ngcontent-%COMP%] .stat-change.negative[_ngcontent-%COMP%] { color: #ef4444; }\n\n\n\n.activity-section[_ngcontent-%COMP%] {\n background: #ffffff;\n border-radius: 16px;\n padding: 24px;\n border: 1px solid #e2e8f0;\n}\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n}\n\n.section-title[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n font-weight: 700;\n color: #0f172a;\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n.view-all-link[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n font-weight: 600;\n color: #3b82f6;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.view-all-link[_ngcontent-%COMP%]:hover {\n color: #2563eb;\n text-decoration: underline;\n}\n\n.activity-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.activity-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 12px 16px;\n background: #f8fafc;\n border-radius: 10px;\n transition: all 0.2s ease;\n}\n\n.activity-item[_ngcontent-%COMP%]:hover {\n background: #f1f5f9;\n}\n\n.activity-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 0.875rem;\n}\n\n.activity-icon.decrypt[_ngcontent-%COMP%] { background: #dbeafe; color: #3b82f6; }\n.activity-icon.create[_ngcontent-%COMP%] { background: #dcfce7; color: #16a34a; }\n.activity-icon.update[_ngcontent-%COMP%] { background: #fef3c7; color: #d97706; }\n.activity-icon.delete[_ngcontent-%COMP%] { background: #fee2e2; color: #dc2626; }\n.activity-icon.validate[_ngcontent-%COMP%] { background: #e0e7ff; color: #6366f1; }\n\n.activity-details[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.activity-details[_ngcontent-%COMP%] .action[_ngcontent-%COMP%] {\n font-weight: 600;\n color: #0f172a;\n}\n\n.activity-details[_ngcontent-%COMP%] .target[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n.activity-details[_ngcontent-%COMP%] .meta[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n color: #94a3b8;\n margin-top: 2px;\n}\n\n.activity-status[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 600;\n padding: 4px 10px;\n border-radius: 12px;\n}\n\n.activity-status.success[_ngcontent-%COMP%] { background: #dcfce7; color: #166534; }\n.activity-status.failed[_ngcontent-%COMP%] { background: #fee2e2; color: #991b1b; }\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: 60px 20px;\n text-align: center;\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 4rem;\n color: #cbd5e1;\n margin-bottom: 20px;\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n font-weight: 700;\n color: #334155;\n margin: 0 0 8px;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n color: #64748b;\n margin: 0;\n}\n\n\n\n@media (max-width: 1024px) {\n .sidebar[_ngcontent-%COMP%] {\n width: 220px;\n }\n\n .main-content[_ngcontent-%COMP%] {\n padding: 20px;\n }\n}\n\n@media (max-width: 768px) {\n .dashboard-content[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .sidebar[_ngcontent-%COMP%] {\n width: 100%;\n flex-direction: row;\n padding: 12px;\n gap: 0;\n overflow-x: auto;\n border-right: none;\n border-bottom: 1px solid #e2e8f0;\n }\n\n .sidebar-section[_ngcontent-%COMP%] {\n display: none;\n }\n\n .nav-item[_ngcontent-%COMP%] {\n flex-direction: column;\n padding: 10px 16px;\n margin: 0 4px;\n gap: 6px;\n white-space: nowrap;\n font-size: 12px;\n }\n\n .nav-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .nav-item[_ngcontent-%COMP%] .badge[_ngcontent-%COMP%] {\n position: absolute;\n top: 4px;\n right: 4px;\n margin-left: 0;\n font-size: 9px;\n padding: 1px 5px;\n }\n\n .main-content[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .dashboard-header[_ngcontent-%COMP%] {\n padding: 12px 16px;\n }\n\n .header-title[_ngcontent-%COMP%] {\n font-size: 1rem;\n }\n\n .header-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n }\n\n .tab-label[_ngcontent-%COMP%] {\n display: none;\n }\n\n .security-badge[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: none;\n }\n\n .overview-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .stat-card[_ngcontent-%COMP%] {\n padding: 20px;\n }\n\n .stat-card[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n }\n}\n\n@media (max-width: 480px) {\n .dashboard-header[_ngcontent-%COMP%] {\n padding: 10px 12px;\n }\n\n .header-title[_ngcontent-%COMP%] {\n font-size: 0.9rem;\n gap: 8px;\n }\n\n .header-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.1rem;\n }\n\n .security-badge[_ngcontent-%COMP%] {\n padding: 4px 8px;\n }\n\n .security-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .sidebar[_ngcontent-%COMP%] {\n padding: 8px;\n }\n\n .nav-item[_ngcontent-%COMP%] {\n padding: 8px 12px;\n font-size: 11px;\n }\n\n .nav-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .main-content[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .stat-card[_ngcontent-%COMP%] {\n padding: 16px;\n border-radius: 12px;\n }\n\n .stat-card[_ngcontent-%COMP%] .icon-wrapper[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 1rem;\n }\n\n .stat-card[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n }\n\n .section-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .activity-item[_ngcontent-%COMP%] {\n padding: 10px 12px;\n }\n\n .activity-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n }\n\n .activity-details[_ngcontent-%COMP%] .action[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n}"], changeDetection: 0 });
|
|
266
|
+
} }, dependencies: [i1.CredentialsOverviewResourceComponent, i2.CredentialsListResourceComponent, i3.CredentialsTypesResourceComponent, i4.CredentialsCategoriesResourceComponent, i5.CredentialsAuditResourceComponent], styles: [".credentials-dashboard-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background-color: var(--mj-bg-page);\n color: var(--mj-text-primary);\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n}\n\n.dashboard-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 24px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid color-mix(in srgb, var(--mj-bg-surface) 10%, transparent);\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);\n}\n\n.header-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--mj-text-inverse);\n}\n\n.header-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n font-size: 1.5rem;\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.tab-label[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n font-weight: 500;\n color: color-mix(in srgb, var(--mj-bg-surface) 80%, transparent);\n background: color-mix(in srgb, var(--mj-bg-surface) 15%, transparent);\n padding: 6px 14px;\n border-radius: 20px;\n backdrop-filter: blur(4px);\n}\n\n.security-badge[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--mj-status-success);\n background: color-mix(in srgb, var(--mj-status-success) 15%, transparent);\n padding: 6px 12px;\n border-radius: 20px;\n}\n\n.dashboard-content[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n overflow: hidden;\n}\n\n.sidebar[_ngcontent-%COMP%] {\n width: 260px;\n background-color: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n padding: 20px 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.sidebar-section[_ngcontent-%COMP%] {\n padding: 0 16px;\n margin-bottom: 8px;\n}\n\n.sidebar-section-title[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n font-weight: 700;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n padding: 8px 0;\n}\n\n.nav-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 20px;\n margin: 0 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n color: var(--mj-text-secondary);\n font-weight: 500;\n border-radius: 10px;\n}\n\n.nav-item[_ngcontent-%COMP%]:hover {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.nav-item.selected[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n box-shadow: 0 4px 6px -1px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.nav-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 20px;\n text-align: center;\n font-size: 1rem;\n}\n\n.nav-item[_ngcontent-%COMP%] .badge[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: 0.7rem;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.nav-item.selected[_ngcontent-%COMP%] .badge[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-bg-surface) 20%, transparent);\n color: var(--mj-text-inverse);\n}\n\n.main-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n background: var(--mj-bg-page);\n}\n\n.tab-container[_ngcontent-%COMP%] {\n height: 100%;\n}\n\n.tab-content[_ngcontent-%COMP%] {\n height: 100%;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n\n\n.overview-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 24px;\n margin-bottom: 32px;\n}\n\n.stat-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 16px;\n padding: 24px;\n border: 1px solid var(--mj-border-default);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n transition: all 0.3s ease;\n}\n\n.stat-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1);\n}\n\n.stat-card[_ngcontent-%COMP%] .icon-wrapper[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.25rem;\n margin-bottom: 16px;\n}\n\n.stat-card[_ngcontent-%COMP%] .icon-wrapper.blue[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.stat-card[_ngcontent-%COMP%] .icon-wrapper.green[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n}\n\n.stat-card[_ngcontent-%COMP%] .icon-wrapper.amber[_ngcontent-%COMP%] {\n background: var(--mj-status-warning);\n color: var(--mj-text-inverse);\n}\n\n.stat-card[_ngcontent-%COMP%] .icon-wrapper.red[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n}\n\n.stat-card[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--mj-text-muted);\n margin-bottom: 4px;\n}\n\n.stat-card[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 2rem;\n font-weight: 800;\n color: var(--mj-text-primary);\n}\n\n.stat-card[_ngcontent-%COMP%] .stat-change[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 600;\n margin-top: 8px;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.stat-card[_ngcontent-%COMP%] .stat-change.positive[_ngcontent-%COMP%] { color: var(--mj-status-success); }\n.stat-card[_ngcontent-%COMP%] .stat-change.negative[_ngcontent-%COMP%] { color: var(--mj-status-error); }\n\n\n\n.activity-section[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 16px;\n padding: 24px;\n border: 1px solid var(--mj-border-default);\n}\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n}\n\n.section-title[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.view-all-link[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-brand-primary);\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.view-all-link[_ngcontent-%COMP%]:hover {\n color: var(--mj-brand-primary-hover);\n text-decoration: underline;\n}\n\n.activity-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.activity-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 12px 16px;\n background: var(--mj-bg-page);\n border-radius: 10px;\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: 40px;\n height: 40px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 0.875rem;\n}\n\n.activity-icon.decrypt[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.activity-icon.create[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.activity-icon.update[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n.activity-icon.delete[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n.activity-icon.validate[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n\n.activity-details[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.activity-details[_ngcontent-%COMP%] .action[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.activity-details[_ngcontent-%COMP%] .target[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.activity-details[_ngcontent-%COMP%] .meta[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n color: var(--mj-text-disabled);\n margin-top: 2px;\n}\n\n.activity-status[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 600;\n padding: 4px 10px;\n border-radius: 12px;\n}\n\n.activity-status.success[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.activity-status.failed[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface)); color: var(--mj-status-error); }\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: 60px 20px;\n text-align: center;\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 4rem;\n color: var(--mj-border-strong);\n margin-bottom: 20px;\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n font-weight: 700;\n color: var(--mj-text-secondary);\n margin: 0 0 8px;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n margin: 0;\n}\n\n\n\n@media (max-width: 1024px) {\n .sidebar[_ngcontent-%COMP%] {\n width: 220px;\n }\n\n .main-content[_ngcontent-%COMP%] {\n padding: 20px;\n }\n}\n\n@media (max-width: 768px) {\n .dashboard-content[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .sidebar[_ngcontent-%COMP%] {\n width: 100%;\n flex-direction: row;\n padding: 12px;\n gap: 0;\n overflow-x: auto;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .sidebar-section[_ngcontent-%COMP%] {\n display: none;\n }\n\n .nav-item[_ngcontent-%COMP%] {\n flex-direction: column;\n padding: 10px 16px;\n margin: 0 4px;\n gap: 6px;\n white-space: nowrap;\n font-size: 12px;\n }\n\n .nav-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .nav-item[_ngcontent-%COMP%] .badge[_ngcontent-%COMP%] {\n position: absolute;\n top: 4px;\n right: 4px;\n margin-left: 0;\n font-size: 9px;\n padding: 1px 5px;\n }\n\n .main-content[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .dashboard-header[_ngcontent-%COMP%] {\n padding: 12px 16px;\n }\n\n .header-title[_ngcontent-%COMP%] {\n font-size: 1rem;\n }\n\n .header-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n }\n\n .tab-label[_ngcontent-%COMP%] {\n display: none;\n }\n\n .security-badge[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: none;\n }\n\n .overview-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .stat-card[_ngcontent-%COMP%] {\n padding: 20px;\n }\n\n .stat-card[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n }\n}\n\n@media (max-width: 480px) {\n .dashboard-header[_ngcontent-%COMP%] {\n padding: 10px 12px;\n }\n\n .header-title[_ngcontent-%COMP%] {\n font-size: 0.9rem;\n gap: 8px;\n }\n\n .header-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.1rem;\n }\n\n .security-badge[_ngcontent-%COMP%] {\n padding: 4px 8px;\n }\n\n .security-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .sidebar[_ngcontent-%COMP%] {\n padding: 8px;\n }\n\n .nav-item[_ngcontent-%COMP%] {\n padding: 8px 12px;\n font-size: 11px;\n }\n\n .nav-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .main-content[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .stat-card[_ngcontent-%COMP%] {\n padding: 16px;\n border-radius: 12px;\n }\n\n .stat-card[_ngcontent-%COMP%] .icon-wrapper[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 1rem;\n }\n\n .stat-card[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n }\n\n .section-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .activity-item[_ngcontent-%COMP%] {\n padding: 10px 12px;\n }\n\n .activity-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n }\n\n .activity-details[_ngcontent-%COMP%] .action[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n}"], changeDetection: 0 });
|
|
267
267
|
};
|
|
268
268
|
CredentialsDashboardComponent = __decorate([
|
|
269
269
|
RegisterClass(BaseDashboard, 'CredentialsDashboard')
|
|
@@ -271,7 +271,7 @@ CredentialsDashboardComponent = __decorate([
|
|
|
271
271
|
export { CredentialsDashboardComponent };
|
|
272
272
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CredentialsDashboardComponent, [{
|
|
273
273
|
type: Component,
|
|
274
|
-
args: [{ standalone: false, selector: 'mj-credentials-dashboard', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"credentials-dashboard-container\">\n <div class=\"dashboard-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-key\"></i>\n <span>Credential Management</span>\n </div>\n <div class=\"header-actions\">\n <div class=\"security-badge\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span>Encrypted</span>\n </div>\n <span class=\"tab-label\">{{getCurrentTabLabel()}}</span>\n </div>\n </div>\n\n <div class=\"dashboard-content\">\n <div class=\"sidebar\">\n <div class=\"sidebar-section\">\n <div class=\"sidebar-section-title\">Dashboard</div>\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'overview'\" (click)=\"onTabChange('overview')\">\n <i class=\"fa-solid fa-chart-pie\"></i>\n <span>Overview</span>\n </div>\n\n <div class=\"sidebar-section\">\n <div class=\"sidebar-section-title\">Management</div>\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'credentials'\" (click)=\"onTabChange('credentials')\">\n <i class=\"fa-solid fa-key\"></i>\n <span>Credentials</span>\n @if (credentialCount > 0) {\n <span class=\"badge\">{{credentialCount}}</span>\n }\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'types'\" (click)=\"onTabChange('types')\">\n <i class=\"fa-solid fa-cubes\"></i>\n <span>Types</span>\n @if (typeCount > 0) {\n <span class=\"badge\">{{typeCount}}</span>\n }\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'categories'\" (click)=\"onTabChange('categories')\">\n <i class=\"fa-solid fa-folder-tree\"></i>\n <span>Categories</span>\n </div>\n\n <div class=\"sidebar-section\">\n <div class=\"sidebar-section-title\">Security</div>\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'audit'\" (click)=\"onTabChange('audit')\">\n <i class=\"fa-solid fa-clipboard-list\"></i>\n <span>Audit Trail</span>\n </div>\n </div>\n\n <div class=\"main-content\">\n <div class=\"tab-container\">\n @switch (activeTab) {\n <!-- Overview Tab -->\n @case ('overview') {\n <div class=\"tab-content\">\n <mj-credentials-overview-resource></mj-credentials-overview-resource>\n </div>\n }\n <!-- Credentials Tab -->\n @case ('credentials') {\n <div class=\"tab-content\">\n <mj-credentials-list-resource></mj-credentials-list-resource>\n </div>\n }\n <!-- Types Tab -->\n @case ('types') {\n <div class=\"tab-content\">\n <mj-credentials-types-resource></mj-credentials-types-resource>\n </div>\n }\n <!-- Categories Tab -->\n @case ('categories') {\n <div class=\"tab-content\">\n <mj-credentials-categories-resource></mj-credentials-categories-resource>\n </div>\n }\n <!-- Audit Trail Tab -->\n @case ('audit') {\n <div class=\"tab-content\">\n <mj-credentials-audit-resource></mj-credentials-audit-resource>\n </div>\n }\n }\n </div>\n </div>\n </div>\n</div>\n", styles: [".credentials-dashboard-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background-color: #f8fafc;\n color: #333;\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n}\n\n.dashboard-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 24px;\n background: linear-gradient(135deg, #1e3a5f 0%, #2d5a87 100%);\n border-bottom: 1px solid rgba(255,255,255,0.1);\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 1.25rem;\n font-weight: 600;\n color: #ffffff;\n}\n\n.header-title i {\n color: #fbbf24;\n font-size: 1.5rem;\n}\n\n.header-actions {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.tab-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: rgba(255,255,255,0.8);\n background: rgba(255,255,255,0.15);\n padding: 6px 14px;\n border-radius: 20px;\n backdrop-filter: blur(4px);\n}\n\n.security-badge {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 0.75rem;\n font-weight: 600;\n color: #10b981;\n background: rgba(16, 185, 129, 0.15);\n padding: 6px 12px;\n border-radius: 20px;\n}\n\n.dashboard-content {\n display: flex;\n flex: 1;\n overflow: hidden;\n}\n\n.sidebar {\n width: 260px;\n background-color: #fff;\n border-right: 1px solid #e2e8f0;\n padding: 20px 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.sidebar-section {\n padding: 0 16px;\n margin-bottom: 8px;\n}\n\n.sidebar-section-title {\n font-size: 0.7rem;\n font-weight: 700;\n color: #94a3b8;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n padding: 8px 0;\n}\n\n.nav-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 20px;\n margin: 0 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n color: #475569;\n font-weight: 500;\n border-radius: 10px;\n}\n\n.nav-item:hover {\n background-color: #f0f7ff;\n color: #3b82f6;\n}\n\n.nav-item.selected {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n color: #ffffff;\n box-shadow: 0 4px 6px -1px rgba(59, 130, 246, 0.3);\n}\n\n.nav-item i {\n width: 20px;\n text-align: center;\n font-size: 1rem;\n}\n\n.nav-item .badge {\n margin-left: auto;\n font-size: 0.7rem;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 12px;\n background: rgba(59, 130, 246, 0.1);\n color: #3b82f6;\n}\n\n.nav-item.selected .badge {\n background: rgba(255,255,255,0.2);\n color: #ffffff;\n}\n\n.main-content {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n background: #f8fafc;\n}\n\n.tab-container {\n height: 100%;\n}\n\n.tab-content {\n height: 100%;\n animation: fadeIn 0.3s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* Overview Stats Grid */\n.overview-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 24px;\n margin-bottom: 32px;\n}\n\n.stat-card {\n background: #ffffff;\n border-radius: 16px;\n padding: 24px;\n border: 1px solid #e2e8f0;\n box-shadow: 0 1px 3px rgba(0,0,0,0.05);\n transition: all 0.3s ease;\n}\n\n.stat-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 10px 25px -5px rgba(0,0,0,0.1);\n}\n\n.stat-card .icon-wrapper {\n width: 48px;\n height: 48px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.25rem;\n margin-bottom: 16px;\n}\n\n.stat-card .icon-wrapper.blue {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n color: white;\n}\n\n.stat-card .icon-wrapper.green {\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n color: white;\n}\n\n.stat-card .icon-wrapper.amber {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n color: white;\n}\n\n.stat-card .icon-wrapper.red {\n background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);\n color: white;\n}\n\n.stat-card .stat-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: #64748b;\n margin-bottom: 4px;\n}\n\n.stat-card .stat-value {\n font-size: 2rem;\n font-weight: 800;\n color: #0f172a;\n}\n\n.stat-card .stat-change {\n font-size: 0.75rem;\n font-weight: 600;\n margin-top: 8px;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.stat-card .stat-change.positive { color: #10b981; }\n.stat-card .stat-change.negative { color: #ef4444; }\n\n/* Activity Section */\n.activity-section {\n background: #ffffff;\n border-radius: 16px;\n padding: 24px;\n border: 1px solid #e2e8f0;\n}\n\n.section-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n}\n\n.section-title {\n font-size: 1.125rem;\n font-weight: 700;\n color: #0f172a;\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.section-title i {\n color: #3b82f6;\n}\n\n.view-all-link {\n font-size: 0.875rem;\n font-weight: 600;\n color: #3b82f6;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.view-all-link:hover {\n color: #2563eb;\n text-decoration: underline;\n}\n\n.activity-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.activity-item {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 12px 16px;\n background: #f8fafc;\n border-radius: 10px;\n transition: all 0.2s ease;\n}\n\n.activity-item:hover {\n background: #f1f5f9;\n}\n\n.activity-icon {\n width: 40px;\n height: 40px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 0.875rem;\n}\n\n.activity-icon.decrypt { background: #dbeafe; color: #3b82f6; }\n.activity-icon.create { background: #dcfce7; color: #16a34a; }\n.activity-icon.update { background: #fef3c7; color: #d97706; }\n.activity-icon.delete { background: #fee2e2; color: #dc2626; }\n.activity-icon.validate { background: #e0e7ff; color: #6366f1; }\n\n.activity-details {\n flex: 1;\n}\n\n.activity-details .action {\n font-weight: 600;\n color: #0f172a;\n}\n\n.activity-details .target {\n color: #3b82f6;\n}\n\n.activity-details .meta {\n font-size: 0.75rem;\n color: #94a3b8;\n margin-top: 2px;\n}\n\n.activity-status {\n font-size: 0.75rem;\n font-weight: 600;\n padding: 4px 10px;\n border-radius: 12px;\n}\n\n.activity-status.success { background: #dcfce7; color: #166534; }\n.activity-status.failed { background: #fee2e2; color: #991b1b; }\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n text-align: center;\n}\n\n.empty-state i {\n font-size: 4rem;\n color: #cbd5e1;\n margin-bottom: 20px;\n}\n\n.empty-state h3 {\n font-size: 1.25rem;\n font-weight: 700;\n color: #334155;\n margin: 0 0 8px;\n}\n\n.empty-state p {\n color: #64748b;\n margin: 0;\n}\n\n/* Mobile Responsive Styles */\n@media (max-width: 1024px) {\n .sidebar {\n width: 220px;\n }\n\n .main-content {\n padding: 20px;\n }\n}\n\n@media (max-width: 768px) {\n .dashboard-content {\n flex-direction: column;\n }\n\n .sidebar {\n width: 100%;\n flex-direction: row;\n padding: 12px;\n gap: 0;\n overflow-x: auto;\n border-right: none;\n border-bottom: 1px solid #e2e8f0;\n }\n\n .sidebar-section {\n display: none;\n }\n\n .nav-item {\n flex-direction: column;\n padding: 10px 16px;\n margin: 0 4px;\n gap: 6px;\n white-space: nowrap;\n font-size: 12px;\n }\n\n .nav-item i {\n font-size: 18px;\n }\n\n .nav-item .badge {\n position: absolute;\n top: 4px;\n right: 4px;\n margin-left: 0;\n font-size: 9px;\n padding: 1px 5px;\n }\n\n .main-content {\n padding: 16px;\n }\n\n .dashboard-header {\n padding: 12px 16px;\n }\n\n .header-title {\n font-size: 1rem;\n }\n\n .header-title i {\n font-size: 1.25rem;\n }\n\n .tab-label {\n display: none;\n }\n\n .security-badge span {\n display: none;\n }\n\n .overview-grid {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .stat-card {\n padding: 20px;\n }\n\n .stat-card .stat-value {\n font-size: 1.5rem;\n }\n}\n\n@media (max-width: 480px) {\n .dashboard-header {\n padding: 10px 12px;\n }\n\n .header-title {\n font-size: 0.9rem;\n gap: 8px;\n }\n\n .header-title i {\n font-size: 1.1rem;\n }\n\n .security-badge {\n padding: 4px 8px;\n }\n\n .security-badge i {\n font-size: 14px;\n }\n\n .sidebar {\n padding: 8px;\n }\n\n .nav-item {\n padding: 8px 12px;\n font-size: 11px;\n }\n\n .nav-item i {\n font-size: 16px;\n }\n\n .main-content {\n padding: 12px;\n }\n\n .stat-card {\n padding: 16px;\n border-radius: 12px;\n }\n\n .stat-card .icon-wrapper {\n width: 40px;\n height: 40px;\n font-size: 1rem;\n }\n\n .stat-card .stat-value {\n font-size: 1.25rem;\n }\n\n .section-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .activity-item {\n padding: 10px 12px;\n }\n\n .activity-icon {\n width: 36px;\n height: 36px;\n }\n\n .activity-details .action {\n font-size: 13px;\n }\n}\n"] }]
|
|
274
|
+
args: [{ standalone: false, selector: 'mj-credentials-dashboard', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"credentials-dashboard-container\">\n <div class=\"dashboard-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-key\"></i>\n <span>Credential Management</span>\n </div>\n <div class=\"header-actions\">\n <div class=\"security-badge\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span>Encrypted</span>\n </div>\n <span class=\"tab-label\">{{getCurrentTabLabel()}}</span>\n </div>\n </div>\n\n <div class=\"dashboard-content\">\n <div class=\"sidebar\">\n <div class=\"sidebar-section\">\n <div class=\"sidebar-section-title\">Dashboard</div>\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'overview'\" (click)=\"onTabChange('overview')\">\n <i class=\"fa-solid fa-chart-pie\"></i>\n <span>Overview</span>\n </div>\n\n <div class=\"sidebar-section\">\n <div class=\"sidebar-section-title\">Management</div>\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'credentials'\" (click)=\"onTabChange('credentials')\">\n <i class=\"fa-solid fa-key\"></i>\n <span>Credentials</span>\n @if (credentialCount > 0) {\n <span class=\"badge\">{{credentialCount}}</span>\n }\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'types'\" (click)=\"onTabChange('types')\">\n <i class=\"fa-solid fa-cubes\"></i>\n <span>Types</span>\n @if (typeCount > 0) {\n <span class=\"badge\">{{typeCount}}</span>\n }\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'categories'\" (click)=\"onTabChange('categories')\">\n <i class=\"fa-solid fa-folder-tree\"></i>\n <span>Categories</span>\n </div>\n\n <div class=\"sidebar-section\">\n <div class=\"sidebar-section-title\">Security</div>\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'audit'\" (click)=\"onTabChange('audit')\">\n <i class=\"fa-solid fa-clipboard-list\"></i>\n <span>Audit Trail</span>\n </div>\n </div>\n\n <div class=\"main-content\">\n <div class=\"tab-container\">\n @switch (activeTab) {\n <!-- Overview Tab -->\n @case ('overview') {\n <div class=\"tab-content\">\n <mj-credentials-overview-resource></mj-credentials-overview-resource>\n </div>\n }\n <!-- Credentials Tab -->\n @case ('credentials') {\n <div class=\"tab-content\">\n <mj-credentials-list-resource></mj-credentials-list-resource>\n </div>\n }\n <!-- Types Tab -->\n @case ('types') {\n <div class=\"tab-content\">\n <mj-credentials-types-resource></mj-credentials-types-resource>\n </div>\n }\n <!-- Categories Tab -->\n @case ('categories') {\n <div class=\"tab-content\">\n <mj-credentials-categories-resource></mj-credentials-categories-resource>\n </div>\n }\n <!-- Audit Trail Tab -->\n @case ('audit') {\n <div class=\"tab-content\">\n <mj-credentials-audit-resource></mj-credentials-audit-resource>\n </div>\n }\n }\n </div>\n </div>\n </div>\n</div>\n", styles: [".credentials-dashboard-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background-color: var(--mj-bg-page);\n color: var(--mj-text-primary);\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n}\n\n.dashboard-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 24px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid color-mix(in srgb, var(--mj-bg-surface) 10%, transparent);\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--mj-text-inverse);\n}\n\n.header-title i {\n color: var(--mj-status-warning);\n font-size: 1.5rem;\n}\n\n.header-actions {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.tab-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: color-mix(in srgb, var(--mj-bg-surface) 80%, transparent);\n background: color-mix(in srgb, var(--mj-bg-surface) 15%, transparent);\n padding: 6px 14px;\n border-radius: 20px;\n backdrop-filter: blur(4px);\n}\n\n.security-badge {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--mj-status-success);\n background: color-mix(in srgb, var(--mj-status-success) 15%, transparent);\n padding: 6px 12px;\n border-radius: 20px;\n}\n\n.dashboard-content {\n display: flex;\n flex: 1;\n overflow: hidden;\n}\n\n.sidebar {\n width: 260px;\n background-color: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n padding: 20px 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.sidebar-section {\n padding: 0 16px;\n margin-bottom: 8px;\n}\n\n.sidebar-section-title {\n font-size: 0.7rem;\n font-weight: 700;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n padding: 8px 0;\n}\n\n.nav-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 20px;\n margin: 0 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n color: var(--mj-text-secondary);\n font-weight: 500;\n border-radius: 10px;\n}\n\n.nav-item:hover {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.nav-item.selected {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n box-shadow: 0 4px 6px -1px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.nav-item i {\n width: 20px;\n text-align: center;\n font-size: 1rem;\n}\n\n.nav-item .badge {\n margin-left: auto;\n font-size: 0.7rem;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.nav-item.selected .badge {\n background: color-mix(in srgb, var(--mj-bg-surface) 20%, transparent);\n color: var(--mj-text-inverse);\n}\n\n.main-content {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n background: var(--mj-bg-page);\n}\n\n.tab-container {\n height: 100%;\n}\n\n.tab-content {\n height: 100%;\n animation: fadeIn 0.3s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* Overview Stats Grid */\n.overview-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 24px;\n margin-bottom: 32px;\n}\n\n.stat-card {\n background: var(--mj-bg-surface);\n border-radius: 16px;\n padding: 24px;\n border: 1px solid var(--mj-border-default);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n transition: all 0.3s ease;\n}\n\n.stat-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1);\n}\n\n.stat-card .icon-wrapper {\n width: 48px;\n height: 48px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.25rem;\n margin-bottom: 16px;\n}\n\n.stat-card .icon-wrapper.blue {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.stat-card .icon-wrapper.green {\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n}\n\n.stat-card .icon-wrapper.amber {\n background: var(--mj-status-warning);\n color: var(--mj-text-inverse);\n}\n\n.stat-card .icon-wrapper.red {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n}\n\n.stat-card .stat-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--mj-text-muted);\n margin-bottom: 4px;\n}\n\n.stat-card .stat-value {\n font-size: 2rem;\n font-weight: 800;\n color: var(--mj-text-primary);\n}\n\n.stat-card .stat-change {\n font-size: 0.75rem;\n font-weight: 600;\n margin-top: 8px;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.stat-card .stat-change.positive { color: var(--mj-status-success); }\n.stat-card .stat-change.negative { color: var(--mj-status-error); }\n\n/* Activity Section */\n.activity-section {\n background: var(--mj-bg-surface);\n border-radius: 16px;\n padding: 24px;\n border: 1px solid var(--mj-border-default);\n}\n\n.section-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n}\n\n.section-title {\n font-size: 1.125rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.section-title i {\n color: var(--mj-brand-primary);\n}\n\n.view-all-link {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-brand-primary);\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.view-all-link:hover {\n color: var(--mj-brand-primary-hover);\n text-decoration: underline;\n}\n\n.activity-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.activity-item {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 12px 16px;\n background: var(--mj-bg-page);\n border-radius: 10px;\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: 40px;\n height: 40px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 0.875rem;\n}\n\n.activity-icon.decrypt { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.activity-icon.create { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.activity-icon.update { background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n.activity-icon.delete { background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n.activity-icon.validate { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n\n.activity-details {\n flex: 1;\n}\n\n.activity-details .action {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.activity-details .target {\n color: var(--mj-brand-primary);\n}\n\n.activity-details .meta {\n font-size: 0.75rem;\n color: var(--mj-text-disabled);\n margin-top: 2px;\n}\n\n.activity-status {\n font-size: 0.75rem;\n font-weight: 600;\n padding: 4px 10px;\n border-radius: 12px;\n}\n\n.activity-status.success { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.activity-status.failed { background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n text-align: center;\n}\n\n.empty-state i {\n font-size: 4rem;\n color: var(--mj-border-strong);\n margin-bottom: 20px;\n}\n\n.empty-state h3 {\n font-size: 1.25rem;\n font-weight: 700;\n color: var(--mj-text-secondary);\n margin: 0 0 8px;\n}\n\n.empty-state p {\n color: var(--mj-text-muted);\n margin: 0;\n}\n\n/* Mobile Responsive Styles */\n@media (max-width: 1024px) {\n .sidebar {\n width: 220px;\n }\n\n .main-content {\n padding: 20px;\n }\n}\n\n@media (max-width: 768px) {\n .dashboard-content {\n flex-direction: column;\n }\n\n .sidebar {\n width: 100%;\n flex-direction: row;\n padding: 12px;\n gap: 0;\n overflow-x: auto;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .sidebar-section {\n display: none;\n }\n\n .nav-item {\n flex-direction: column;\n padding: 10px 16px;\n margin: 0 4px;\n gap: 6px;\n white-space: nowrap;\n font-size: 12px;\n }\n\n .nav-item i {\n font-size: 18px;\n }\n\n .nav-item .badge {\n position: absolute;\n top: 4px;\n right: 4px;\n margin-left: 0;\n font-size: 9px;\n padding: 1px 5px;\n }\n\n .main-content {\n padding: 16px;\n }\n\n .dashboard-header {\n padding: 12px 16px;\n }\n\n .header-title {\n font-size: 1rem;\n }\n\n .header-title i {\n font-size: 1.25rem;\n }\n\n .tab-label {\n display: none;\n }\n\n .security-badge span {\n display: none;\n }\n\n .overview-grid {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .stat-card {\n padding: 20px;\n }\n\n .stat-card .stat-value {\n font-size: 1.5rem;\n }\n}\n\n@media (max-width: 480px) {\n .dashboard-header {\n padding: 10px 12px;\n }\n\n .header-title {\n font-size: 0.9rem;\n gap: 8px;\n }\n\n .header-title i {\n font-size: 1.1rem;\n }\n\n .security-badge {\n padding: 4px 8px;\n }\n\n .security-badge i {\n font-size: 14px;\n }\n\n .sidebar {\n padding: 8px;\n }\n\n .nav-item {\n padding: 8px 12px;\n font-size: 11px;\n }\n\n .nav-item i {\n font-size: 16px;\n }\n\n .main-content {\n padding: 12px;\n }\n\n .stat-card {\n padding: 16px;\n border-radius: 12px;\n }\n\n .stat-card .icon-wrapper {\n width: 40px;\n height: 40px;\n font-size: 1rem;\n }\n\n .stat-card .stat-value {\n font-size: 1.25rem;\n }\n\n .section-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .activity-item {\n padding: 10px 12px;\n }\n\n .activity-icon {\n width: 36px;\n height: 36px;\n }\n\n .activity-details .action {\n font-size: 13px;\n }\n}\n"] }]
|
|
275
275
|
}], () => [{ type: i0.ChangeDetectorRef }], null); })();
|
|
276
276
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialsDashboardComponent, { className: "CredentialsDashboardComponent", filePath: "src/Credentials/credentials-dashboard.component.ts", lineNumber: 22 }); })();
|
|
277
277
|
//# sourceMappingURL=credentials-dashboard.component.js.map
|
|
@@ -1035,7 +1035,7 @@ let DashboardBrowserResourceComponent = class DashboardBrowserResourceComponent
|
|
|
1035
1035
|
i0.ɵɵconditional(ctx.mode === "list" ? 1 : -1);
|
|
1036
1036
|
i0.ɵɵadvance();
|
|
1037
1037
|
i0.ɵɵconditional(ctx.mode === "view" || ctx.mode === "edit" ? 2 : -1);
|
|
1038
|
-
} }, dependencies: [i3.DefaultValueAccessor, i3.NgControlStatus, i3.NgModel, i4.DashboardViewerComponent, i4.DashboardBrowserComponent, i4.DashboardBreadcrumbComponent, i4.AddPanelDialogComponent, i4.EditPartDialogComponent, i4.ConfirmDialogComponent, i5.DashboardShareDialogComponent], styles: ["\n\n\n\n\n[_nghost-%COMP%] {\n display: block;\n height: 100%;\n width: 100%;\n}\n\n.dashboard-browser-resource[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background:
|
|
1038
|
+
} }, dependencies: [i3.DefaultValueAccessor, i3.NgControlStatus, i3.NgModel, i4.DashboardViewerComponent, i4.DashboardBrowserComponent, i4.DashboardBreadcrumbComponent, i4.AddPanelDialogComponent, i4.EditPartDialogComponent, i4.ConfirmDialogComponent, i5.DashboardShareDialogComponent], styles: ["\n\n\n\n\n[_nghost-%COMP%] {\n display: block;\n height: 100%;\n width: 100%;\n}\n\n.dashboard-browser-resource[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background: var(--mj-bg-surface-card);\n position: relative;\n}\n\n\n\n.dashboard-browser-resource[_ngcontent-%COMP%] mj-dashboard-browser[_ngcontent-%COMP%] {\n display: block;\n height: 100%;\n width: 100%;\n}\n\n\n\n\n\n\n.viewer-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0 24px 0 0;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n gap: 16px;\n}\n\n.viewer-toolbar[_ngcontent-%COMP%] .toolbar-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n\n\n.shared-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-info);\n border-radius: 16px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-brand-primary);\n white-space: nowrap;\n}\n\n.shared-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n\n\n\n\n\n.viewer-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n transition: background 0.2s, border-color 0.2s;\n}\n\n\n\n.viewer-header.editing[_ngcontent-%COMP%] {\n background: var(--mj-bg-brand);\n border-bottom: 2px solid var(--mj-brand-primary);\n}\n\n.viewer-header[_ngcontent-%COMP%] .header-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n}\n\n.viewer-header[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.viewer-header[_ngcontent-%COMP%] .header-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.back-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.back-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n\n\n.btn-add-part[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s, transform 0.1s;\n box-shadow: 0 2px 4px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.btn-add-part[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n transform: translateY(-1px);\n box-shadow: 0 3px 6px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n.btn-add-part[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n.header-separator[_ngcontent-%COMP%] {\n width: 1px;\n height: 28px;\n background: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n margin: 0 4px;\n}\n\n\n\n\n\n\n.btn-primary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 18px;\n border: none;\n border-radius: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s;\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.btn-icon[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.btn-icon.active[_ngcontent-%COMP%] {\n background: var(--mj-bg-info);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n\n\n.btn-cancel[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 18px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.btn-cancel[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n\n\n\n\n\n.dashboard-info-edit[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n flex: 1;\n}\n\n.dashboard-name-input[_ngcontent-%COMP%] {\n border: 1px solid transparent;\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 16px;\n font-weight: 500;\n color: var(--mj-text-primary);\n background: color-mix(in srgb, var(--mj-bg-surface) 70%, transparent);\n outline: none;\n min-width: 200px;\n max-width: 300px;\n transition: border-color 0.2s, background 0.2s, box-shadow 0.2s;\n}\n\n.dashboard-name-input[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-bg-surface) 90%, transparent);\n}\n\n.dashboard-name-input[_ngcontent-%COMP%]:focus {\n background: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.dashboard-description-input[_ngcontent-%COMP%] {\n border: 1px solid transparent;\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n background: color-mix(in srgb, var(--mj-bg-surface) 50%, transparent);\n outline: none;\n flex: 1;\n min-width: 150px;\n max-width: 400px;\n transition: border-color 0.2s, background 0.2s, box-shadow 0.2s;\n}\n\n.dashboard-description-input[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-bg-surface) 80%, transparent);\n}\n\n.dashboard-description-input[_ngcontent-%COMP%]:focus {\n background: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.dashboard-description-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n font-style: normal;\n}\n\n\n\n\n\n\n.viewer-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n}\n\n.viewer-content[_ngcontent-%COMP%] mj-dashboard-viewer[_ngcontent-%COMP%] {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n\n\n\n\n\n@media (max-width: 768px) {\n .viewer-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 12px;\n align-items: stretch;\n }\n\n .viewer-header[_ngcontent-%COMP%] .header-left[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n }\n\n .dashboard-info-edit[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: stretch;\n }\n\n .dashboard-name-input[_ngcontent-%COMP%], \n .dashboard-description-input[_ngcontent-%COMP%] {\n max-width: none;\n }\n}"], changeDetection: 0 });
|
|
1039
1039
|
};
|
|
1040
1040
|
DashboardBrowserResourceComponent = __decorate([
|
|
1041
1041
|
RegisterClass(BaseResourceComponent, 'DashboardBrowserResource')
|
|
@@ -1043,7 +1043,7 @@ DashboardBrowserResourceComponent = __decorate([
|
|
|
1043
1043
|
export { DashboardBrowserResourceComponent };
|
|
1044
1044
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DashboardBrowserResourceComponent, [{
|
|
1045
1045
|
type: Component,
|
|
1046
|
-
args: [{ standalone: false, selector: 'mj-dashboard-browser-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Dashboard Browser Resource -->\n<div class=\"dashboard-browser-resource\">\n <!-- List Mode - Uses Generic DashboardBrowserComponent -->\n @if (mode === 'list') {\n <mj-dashboard-browser\n [Dashboards]=\"dashboards\"\n [Categories]=\"categories\"\n [SelectedCategoryId]=\"selectedCategoryId\"\n [ViewMode]=\"viewMode\"\n [IsLoading]=\"isLoading\"\n [ShowCreateButton]=\"true\"\n [AllowMultiSelect]=\"true\"\n [AllowDragDrop]=\"true\"\n [DashboardPermissions]=\"dashboardPermissionsMap\"\n [EffectiveCategoryMap]=\"effectiveCategoryMap\"\n (DashboardOpen)=\"onDashboardOpen($event)\"\n (DashboardEdit)=\"onDashboardEdit($event)\"\n (DashboardDelete)=\"onDashboardDelete($event)\"\n (DashboardMove)=\"onDashboardMove($event)\"\n (DashboardCreate)=\"onDashboardCreate($event)\"\n (CategoryCreate)=\"onCategoryCreate($event)\"\n (CategoryDelete)=\"onCategoryDelete($event)\"\n (CategoryChange)=\"onCategoryChange($event)\"\n (ViewPreferenceChange)=\"onViewPreferenceChange($event)\">\n </mj-dashboard-browser>\n }\n\n <!-- View/Edit Mode -->\n @if (mode === 'view' || mode === 'edit') {\n <!-- View Mode Toolbar - matches browser toolbar structure -->\n @if (mode === 'view') {\n <div class=\"viewer-toolbar\">\n <!-- Breadcrumb navigation (includes its own padding/styling) -->\n <mj-dashboard-breadcrumb\n [Categories]=\"categories\"\n [CurrentCategoryId]=\"selectedDashboard?.CategoryID || null\"\n [CurrentDashboard]=\"selectedDashboard\"\n [ShowDashboardName]=\"true\"\n [AllowDragDrop]=\"false\"\n Size=\"large\"\n RootIcon=\"fa-solid fa-gauge-high\"\n RootLabel=\"Dashboards\"\n (Navigate)=\"onBreadcrumbNavigate($event)\">\n </mj-dashboard-breadcrumb>\n <!-- Right-side Actions -->\n <div class=\"toolbar-actions\">\n <!-- Shared indicator for non-owned dashboards -->\n @if (!selectedDashboardPermissions.IsOwner && selectedDashboardPermissions.CanRead) {\n <span class=\"shared-indicator\">\n <i class=\"fa-solid fa-share-nodes\"></i>\n Shared with you\n </span>\n }\n <button\n class=\"btn-icon\"\n title=\"Open in its own tab\"\n (click)=\"openInNewTab()\">\n <i class=\"fa-solid fa-up-right-from-square\"></i>\n </button>\n <!-- Share button - only shown if user can share -->\n @if (selectedDashboardPermissions.CanShare) {\n <button\n class=\"btn-icon\"\n title=\"Share Dashboard\"\n (click)=\"openShareDialog()\">\n <i class=\"fa-solid fa-user-plus\"></i>\n </button>\n }\n <!-- Edit button - only shown if user can edit -->\n @if (selectedDashboardPermissions.CanEdit) {\n <button\n class=\"btn-icon\"\n title=\"Edit Dashboard\"\n (click)=\"toggleEditMode()\">\n <i class=\"fa-solid fa-edit\"></i>\n </button>\n }\n </div>\n </div>\n }\n <!-- Edit Mode Header - different layout -->\n @if (mode === 'edit') {\n <div class=\"viewer-header editing\">\n <div class=\"header-left\">\n <!-- Add Part button on the left -->\n <button\n class=\"btn-add-part\"\n (click)=\"openAddPartDialog()\">\n <i class=\"fa-solid fa-plus\"></i>\n Add Part\n </button>\n <!-- Separator -->\n <div class=\"header-separator\"></div>\n <!-- Editable name/description -->\n <div class=\"dashboard-info-edit\">\n <input\n type=\"text\"\n class=\"dashboard-name-input\"\n [(ngModel)]=\"editingName\"\n placeholder=\"Dashboard name\"\n (blur)=\"onNameBlur()\">\n <input\n type=\"text\"\n class=\"dashboard-description-input\"\n [(ngModel)]=\"editingDescription\"\n placeholder=\"Add a description...\">\n </div>\n </div>\n <div class=\"header-right\">\n <!-- Save, Cancel buttons -->\n <button\n class=\"btn-primary\"\n (click)=\"saveDashboard()\">\n <i class=\"fa-solid fa-save\"></i>\n Save\n </button>\n <button\n class=\"btn-cancel\"\n (click)=\"cancelEdit()\">\n Cancel\n </button>\n </div>\n </div>\n }\n <!-- Dashboard Viewer -->\n <div class=\"viewer-content\">\n <mj-dashboard-viewer\n #dashboardViewer\n [dashboard]=\"selectedDashboard\"\n [isEditing]=\"mode === 'edit'\"\n [showToolbar]=\"false\"\n [showBreadcrumb]=\"false\"\n (panelInteraction)=\"onPanelInteraction($event)\"\n (navigationRequested)=\"onNavigationRequested($event)\">\n </mj-dashboard-viewer>\n </div>\n <!-- Add Panel Dialog -->\n @if (dashboardViewer) {\n <mj-add-panel-dialog\n [visible]=\"showAddPanelDialog\"\n [partTypes]=\"dashboardViewer.getPartTypes()\"\n (panelAdded)=\"onPanelAdded($event)\"\n (cancelled)=\"onAddPanelCancelled()\">\n </mj-add-panel-dialog>\n }\n <!-- Generic Edit Part Dialog - dynamically loads config panels via ClassFactory -->\n <mj-edit-part-dialog\n [Visible]=\"showConfigDialog\"\n [PartType]=\"configDialogPartType\"\n [Panel]=\"configDialogPanel\"\n [Config]=\"configDialogPanel?.config || null\"\n (Saved)=\"onConfigDialogSaved($event)\"\n (Cancelled)=\"onConfigDialogCancelled()\">\n </mj-edit-part-dialog>\n <!-- Remove Part Confirmation Dialog -->\n <mj-confirm-dialog\n [visible]=\"showConfirmDialog\"\n type=\"danger\"\n title=\"Remove Part\"\n [message]=\"'Are you sure you want to remove \\'' + confirmPanelTitle + '\\' from this dashboard?'\"\n confirmText=\"Remove\"\n cancelText=\"Cancel\"\n (confirmed)=\"onRemoveConfirmed()\"\n (cancelled)=\"onRemoveCancelled()\">\n </mj-confirm-dialog>\n <!-- Share Dashboard Dialog -->\n <mj-dashboard-share-dialog\n [Visible]=\"showShareDialog\"\n [Dashboard]=\"selectedDashboard\"\n (Result)=\"onShareDialogResult($event)\">\n </mj-dashboard-share-dialog>\n }\n</div>\n", styles: ["/* Dashboard Browser Resource Styles */\n/* This is a thin wrapper - list mode styles are in the generic DashboardBrowserComponent */\n\n:host {\n display: block;\n height: 100%;\n width: 100%;\n}\n\n.dashboard-browser-resource {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background: #f5f5f5;\n position: relative;\n}\n\n/* Generic browser fills the container in list mode */\n.dashboard-browser-resource mj-dashboard-browser {\n display: block;\n height: 100%;\n width: 100%;\n}\n\n/* ========================================\n Viewer Toolbar (View Mode) - Matches Browser Toolbar\n ======================================== */\n\n.viewer-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0 24px 0 0;\n background: #fff;\n border-bottom: 1px solid #e0e0e0;\n gap: 16px;\n}\n\n.viewer-toolbar .toolbar-actions {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n/* Shared with you indicator */\n.shared-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);\n border-radius: 16px;\n font-size: 12px;\n font-weight: 500;\n color: #1565c0;\n white-space: nowrap;\n}\n\n.shared-indicator i {\n font-size: 11px;\n}\n\n/* ========================================\n Viewer Header (Edit Mode)\n ======================================== */\n\n.viewer-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 24px;\n background: #fff;\n border-bottom: 1px solid #e0e0e0;\n transition: background 0.2s, border-color 0.2s;\n}\n\n/* Edit mode header styling */\n.viewer-header.editing {\n background: linear-gradient(135deg, #e8eaf6 0%, #c5cae9 100%);\n border-bottom: 2px solid #5c6bc0;\n}\n\n.viewer-header .header-left {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n}\n\n.viewer-header h2 {\n margin: 0;\n font-size: 18px;\n font-weight: 500;\n color: #333;\n}\n\n.viewer-header .header-right {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.back-btn {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n border-radius: 6px;\n background: #f5f5f5;\n color: #666;\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.back-btn:hover {\n background: #e0e0e0;\n color: #333;\n}\n\n/* Add Part button (left side in edit mode) */\n.btn-add-part {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n background: #5c6bc0;\n color: #fff;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s, transform 0.1s;\n box-shadow: 0 2px 4px rgba(92, 107, 192, 0.3);\n}\n\n.btn-add-part:hover {\n background: #3f51b5;\n transform: translateY(-1px);\n box-shadow: 0 3px 6px rgba(92, 107, 192, 0.4);\n}\n\n.btn-add-part i {\n font-size: 12px;\n}\n\n/* Header separator */\n.header-separator {\n width: 1px;\n height: 28px;\n background: rgba(92, 107, 192, 0.3);\n margin: 0 4px;\n}\n\n/* ========================================\n Buttons\n ======================================== */\n\n.btn-primary {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 18px;\n border: none;\n border-radius: 6px;\n background: #5c6bc0;\n color: #fff;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s;\n}\n\n.btn-primary:hover {\n background: #3f51b5;\n}\n\n.btn-icon {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n background: #fff;\n color: #666;\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.btn-icon:hover {\n background: #f5f5f5;\n}\n\n.btn-icon.active {\n background: #e3f2fd;\n border-color: #5c6bc0;\n color: #5c6bc0;\n}\n\n/* Cancel button styling */\n.btn-cancel {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 18px;\n border: 1px solid #d0d0d0;\n border-radius: 6px;\n background: #fff;\n color: #666;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.btn-cancel:hover {\n background: #f5f5f5;\n border-color: #bbb;\n color: #333;\n}\n\n/* ========================================\n Dashboard Info Edit (Edit Mode)\n ======================================== */\n\n.dashboard-info-edit {\n display: flex;\n align-items: center;\n gap: 16px;\n flex: 1;\n}\n\n.dashboard-name-input {\n border: 1px solid transparent;\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 16px;\n font-weight: 500;\n color: #333;\n background: rgba(255, 255, 255, 0.7);\n outline: none;\n min-width: 200px;\n max-width: 300px;\n transition: border-color 0.2s, background 0.2s, box-shadow 0.2s;\n}\n\n.dashboard-name-input:hover {\n background: rgba(255, 255, 255, 0.9);\n}\n\n.dashboard-name-input:focus {\n background: #fff;\n border-color: #5c6bc0;\n box-shadow: 0 0 0 2px rgba(92, 107, 192, 0.2);\n}\n\n.dashboard-description-input {\n border: 1px solid transparent;\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 13px;\n color: #555;\n background: rgba(255, 255, 255, 0.5);\n outline: none;\n flex: 1;\n min-width: 150px;\n max-width: 400px;\n transition: border-color 0.2s, background 0.2s, box-shadow 0.2s;\n}\n\n.dashboard-description-input:hover {\n background: rgba(255, 255, 255, 0.8);\n}\n\n.dashboard-description-input:focus {\n background: #fff;\n border-color: #5c6bc0;\n box-shadow: 0 0 0 2px rgba(92, 107, 192, 0.2);\n}\n\n.dashboard-description-input::placeholder {\n color: #888;\n font-style: normal;\n}\n\n/* ========================================\n Viewer Content\n ======================================== */\n\n.viewer-content {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n}\n\n.viewer-content mj-dashboard-viewer {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n/* ========================================\n Responsive\n ======================================== */\n\n@media (max-width: 768px) {\n .viewer-header {\n flex-direction: column;\n gap: 12px;\n align-items: stretch;\n }\n\n .viewer-header .header-left {\n flex-wrap: wrap;\n }\n\n .dashboard-info-edit {\n flex-direction: column;\n align-items: stretch;\n }\n\n .dashboard-name-input,\n .dashboard-description-input {\n max-width: none;\n }\n}\n"] }]
|
|
1046
|
+
args: [{ standalone: false, selector: 'mj-dashboard-browser-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Dashboard Browser Resource -->\n<div class=\"dashboard-browser-resource\">\n <!-- List Mode - Uses Generic DashboardBrowserComponent -->\n @if (mode === 'list') {\n <mj-dashboard-browser\n [Dashboards]=\"dashboards\"\n [Categories]=\"categories\"\n [SelectedCategoryId]=\"selectedCategoryId\"\n [ViewMode]=\"viewMode\"\n [IsLoading]=\"isLoading\"\n [ShowCreateButton]=\"true\"\n [AllowMultiSelect]=\"true\"\n [AllowDragDrop]=\"true\"\n [DashboardPermissions]=\"dashboardPermissionsMap\"\n [EffectiveCategoryMap]=\"effectiveCategoryMap\"\n (DashboardOpen)=\"onDashboardOpen($event)\"\n (DashboardEdit)=\"onDashboardEdit($event)\"\n (DashboardDelete)=\"onDashboardDelete($event)\"\n (DashboardMove)=\"onDashboardMove($event)\"\n (DashboardCreate)=\"onDashboardCreate($event)\"\n (CategoryCreate)=\"onCategoryCreate($event)\"\n (CategoryDelete)=\"onCategoryDelete($event)\"\n (CategoryChange)=\"onCategoryChange($event)\"\n (ViewPreferenceChange)=\"onViewPreferenceChange($event)\">\n </mj-dashboard-browser>\n }\n\n <!-- View/Edit Mode -->\n @if (mode === 'view' || mode === 'edit') {\n <!-- View Mode Toolbar - matches browser toolbar structure -->\n @if (mode === 'view') {\n <div class=\"viewer-toolbar\">\n <!-- Breadcrumb navigation (includes its own padding/styling) -->\n <mj-dashboard-breadcrumb\n [Categories]=\"categories\"\n [CurrentCategoryId]=\"selectedDashboard?.CategoryID || null\"\n [CurrentDashboard]=\"selectedDashboard\"\n [ShowDashboardName]=\"true\"\n [AllowDragDrop]=\"false\"\n Size=\"large\"\n RootIcon=\"fa-solid fa-gauge-high\"\n RootLabel=\"Dashboards\"\n (Navigate)=\"onBreadcrumbNavigate($event)\">\n </mj-dashboard-breadcrumb>\n <!-- Right-side Actions -->\n <div class=\"toolbar-actions\">\n <!-- Shared indicator for non-owned dashboards -->\n @if (!selectedDashboardPermissions.IsOwner && selectedDashboardPermissions.CanRead) {\n <span class=\"shared-indicator\">\n <i class=\"fa-solid fa-share-nodes\"></i>\n Shared with you\n </span>\n }\n <button\n class=\"btn-icon\"\n title=\"Open in its own tab\"\n (click)=\"openInNewTab()\">\n <i class=\"fa-solid fa-up-right-from-square\"></i>\n </button>\n <!-- Share button - only shown if user can share -->\n @if (selectedDashboardPermissions.CanShare) {\n <button\n class=\"btn-icon\"\n title=\"Share Dashboard\"\n (click)=\"openShareDialog()\">\n <i class=\"fa-solid fa-user-plus\"></i>\n </button>\n }\n <!-- Edit button - only shown if user can edit -->\n @if (selectedDashboardPermissions.CanEdit) {\n <button\n class=\"btn-icon\"\n title=\"Edit Dashboard\"\n (click)=\"toggleEditMode()\">\n <i class=\"fa-solid fa-edit\"></i>\n </button>\n }\n </div>\n </div>\n }\n <!-- Edit Mode Header - different layout -->\n @if (mode === 'edit') {\n <div class=\"viewer-header editing\">\n <div class=\"header-left\">\n <!-- Add Part button on the left -->\n <button\n class=\"btn-add-part\"\n (click)=\"openAddPartDialog()\">\n <i class=\"fa-solid fa-plus\"></i>\n Add Part\n </button>\n <!-- Separator -->\n <div class=\"header-separator\"></div>\n <!-- Editable name/description -->\n <div class=\"dashboard-info-edit\">\n <input\n type=\"text\"\n class=\"dashboard-name-input\"\n [(ngModel)]=\"editingName\"\n placeholder=\"Dashboard name\"\n (blur)=\"onNameBlur()\">\n <input\n type=\"text\"\n class=\"dashboard-description-input\"\n [(ngModel)]=\"editingDescription\"\n placeholder=\"Add a description...\">\n </div>\n </div>\n <div class=\"header-right\">\n <!-- Save, Cancel buttons -->\n <button\n class=\"btn-primary\"\n (click)=\"saveDashboard()\">\n <i class=\"fa-solid fa-save\"></i>\n Save\n </button>\n <button\n class=\"btn-cancel\"\n (click)=\"cancelEdit()\">\n Cancel\n </button>\n </div>\n </div>\n }\n <!-- Dashboard Viewer -->\n <div class=\"viewer-content\">\n <mj-dashboard-viewer\n #dashboardViewer\n [dashboard]=\"selectedDashboard\"\n [isEditing]=\"mode === 'edit'\"\n [showToolbar]=\"false\"\n [showBreadcrumb]=\"false\"\n (panelInteraction)=\"onPanelInteraction($event)\"\n (navigationRequested)=\"onNavigationRequested($event)\">\n </mj-dashboard-viewer>\n </div>\n <!-- Add Panel Dialog -->\n @if (dashboardViewer) {\n <mj-add-panel-dialog\n [visible]=\"showAddPanelDialog\"\n [partTypes]=\"dashboardViewer.getPartTypes()\"\n (panelAdded)=\"onPanelAdded($event)\"\n (cancelled)=\"onAddPanelCancelled()\">\n </mj-add-panel-dialog>\n }\n <!-- Generic Edit Part Dialog - dynamically loads config panels via ClassFactory -->\n <mj-edit-part-dialog\n [Visible]=\"showConfigDialog\"\n [PartType]=\"configDialogPartType\"\n [Panel]=\"configDialogPanel\"\n [Config]=\"configDialogPanel?.config || null\"\n (Saved)=\"onConfigDialogSaved($event)\"\n (Cancelled)=\"onConfigDialogCancelled()\">\n </mj-edit-part-dialog>\n <!-- Remove Part Confirmation Dialog -->\n <mj-confirm-dialog\n [visible]=\"showConfirmDialog\"\n type=\"danger\"\n title=\"Remove Part\"\n [message]=\"'Are you sure you want to remove \\'' + confirmPanelTitle + '\\' from this dashboard?'\"\n confirmText=\"Remove\"\n cancelText=\"Cancel\"\n (confirmed)=\"onRemoveConfirmed()\"\n (cancelled)=\"onRemoveCancelled()\">\n </mj-confirm-dialog>\n <!-- Share Dashboard Dialog -->\n <mj-dashboard-share-dialog\n [Visible]=\"showShareDialog\"\n [Dashboard]=\"selectedDashboard\"\n (Result)=\"onShareDialogResult($event)\">\n </mj-dashboard-share-dialog>\n }\n</div>\n", styles: ["/* Dashboard Browser Resource Styles */\n/* This is a thin wrapper - list mode styles are in the generic DashboardBrowserComponent */\n\n:host {\n display: block;\n height: 100%;\n width: 100%;\n}\n\n.dashboard-browser-resource {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background: var(--mj-bg-surface-card);\n position: relative;\n}\n\n/* Generic browser fills the container in list mode */\n.dashboard-browser-resource mj-dashboard-browser {\n display: block;\n height: 100%;\n width: 100%;\n}\n\n/* ========================================\n Viewer Toolbar (View Mode) - Matches Browser Toolbar\n ======================================== */\n\n.viewer-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0 24px 0 0;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n gap: 16px;\n}\n\n.viewer-toolbar .toolbar-actions {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n/* Shared with you indicator */\n.shared-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-info);\n border-radius: 16px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-brand-primary);\n white-space: nowrap;\n}\n\n.shared-indicator i {\n font-size: 11px;\n}\n\n/* ========================================\n Viewer Header (Edit Mode)\n ======================================== */\n\n.viewer-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n transition: background 0.2s, border-color 0.2s;\n}\n\n/* Edit mode header styling */\n.viewer-header.editing {\n background: var(--mj-bg-brand);\n border-bottom: 2px solid var(--mj-brand-primary);\n}\n\n.viewer-header .header-left {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n}\n\n.viewer-header h2 {\n margin: 0;\n font-size: 18px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.viewer-header .header-right {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.back-btn {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.back-btn:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n/* Add Part button (left side in edit mode) */\n.btn-add-part {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s, transform 0.1s;\n box-shadow: 0 2px 4px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.btn-add-part:hover {\n background: var(--mj-brand-primary-hover);\n transform: translateY(-1px);\n box-shadow: 0 3px 6px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n.btn-add-part i {\n font-size: 12px;\n}\n\n/* Header separator */\n.header-separator {\n width: 1px;\n height: 28px;\n background: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n margin: 0 4px;\n}\n\n/* ========================================\n Buttons\n ======================================== */\n\n.btn-primary {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 18px;\n border: none;\n border-radius: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s;\n}\n\n.btn-primary:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-icon {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.btn-icon:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.btn-icon.active {\n background: var(--mj-bg-info);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n/* Cancel button styling */\n.btn-cancel {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 18px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.btn-cancel:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n/* ========================================\n Dashboard Info Edit (Edit Mode)\n ======================================== */\n\n.dashboard-info-edit {\n display: flex;\n align-items: center;\n gap: 16px;\n flex: 1;\n}\n\n.dashboard-name-input {\n border: 1px solid transparent;\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 16px;\n font-weight: 500;\n color: var(--mj-text-primary);\n background: color-mix(in srgb, var(--mj-bg-surface) 70%, transparent);\n outline: none;\n min-width: 200px;\n max-width: 300px;\n transition: border-color 0.2s, background 0.2s, box-shadow 0.2s;\n}\n\n.dashboard-name-input:hover {\n background: color-mix(in srgb, var(--mj-bg-surface) 90%, transparent);\n}\n\n.dashboard-name-input:focus {\n background: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.dashboard-description-input {\n border: 1px solid transparent;\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n background: color-mix(in srgb, var(--mj-bg-surface) 50%, transparent);\n outline: none;\n flex: 1;\n min-width: 150px;\n max-width: 400px;\n transition: border-color 0.2s, background 0.2s, box-shadow 0.2s;\n}\n\n.dashboard-description-input:hover {\n background: color-mix(in srgb, var(--mj-bg-surface) 80%, transparent);\n}\n\n.dashboard-description-input:focus {\n background: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.dashboard-description-input::placeholder {\n color: var(--mj-text-disabled);\n font-style: normal;\n}\n\n/* ========================================\n Viewer Content\n ======================================== */\n\n.viewer-content {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n}\n\n.viewer-content mj-dashboard-viewer {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n/* ========================================\n Responsive\n ======================================== */\n\n@media (max-width: 768px) {\n .viewer-header {\n flex-direction: column;\n gap: 12px;\n align-items: stretch;\n }\n\n .viewer-header .header-left {\n flex-wrap: wrap;\n }\n\n .dashboard-info-edit {\n flex-direction: column;\n align-items: stretch;\n }\n\n .dashboard-name-input,\n .dashboard-description-input {\n max-width: none;\n }\n}\n"] }]
|
|
1047
1047
|
}], () => [{ type: i0.ChangeDetectorRef }, { type: i1.ActivatedRoute }, { type: i2.NavigationService }], { dashboardViewer: [{
|
|
1048
1048
|
type: ViewChild,
|
|
1049
1049
|
args: ['dashboardViewer']
|