@memberjunction/ng-dashboards 5.4.1 → 5.6.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.
Files changed (123) hide show
  1. package/dist/AI/components/agents/agent-configuration.component.js +4 -4
  2. package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
  3. package/dist/AI/components/agents/agent-editor.component.d.ts.map +1 -1
  4. package/dist/AI/components/agents/agent-editor.component.js +5 -4
  5. package/dist/AI/components/agents/agent-editor.component.js.map +1 -1
  6. package/dist/AI/components/models/model-management.component.js +3 -3
  7. package/dist/AI/components/models/model-management.component.js.map +1 -1
  8. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts.map +1 -1
  9. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +8 -7
  10. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js.map +1 -1
  11. package/dist/AI/components/prompts/prompt-management.component.js +3 -3
  12. package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
  13. package/dist/AI/components/system/system-configuration.component.js +4 -4
  14. package/dist/AI/components/system/system-configuration.component.js.map +1 -1
  15. package/dist/APIKeys/api-applications-panel.component.d.ts.map +1 -1
  16. package/dist/APIKeys/api-applications-panel.component.js +3 -2
  17. package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
  18. package/dist/APIKeys/api-keys-resource.component.js +2 -2
  19. package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
  20. package/dist/APIKeys/api-scopes-panel.component.d.ts.map +1 -1
  21. package/dist/APIKeys/api-scopes-panel.component.js +4 -3
  22. package/dist/APIKeys/api-scopes-panel.component.js.map +1 -1
  23. package/dist/Actions/components/actions-overview.component.js +3 -3
  24. package/dist/Actions/components/actions-overview.component.js.map +1 -1
  25. package/dist/Actions/components/categories-list-view.component.d.ts.map +1 -1
  26. package/dist/Actions/components/categories-list-view.component.js +3 -2
  27. package/dist/Actions/components/categories-list-view.component.js.map +1 -1
  28. package/dist/Actions/components/execution-monitoring.component.js +2 -2
  29. package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
  30. package/dist/Actions/components/explorer/action-explorer.component.js +2 -2
  31. package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
  32. package/dist/Actions/components/explorer/new-action-panel.component.d.ts.map +1 -1
  33. package/dist/Actions/components/explorer/new-action-panel.component.js +3 -2
  34. package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -1
  35. package/dist/Actions/components/explorer/new-category-panel.component.d.ts.map +1 -1
  36. package/dist/Actions/components/explorer/new-category-panel.component.js +3 -2
  37. package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -1
  38. package/dist/Communication/communication-templates-resource.component.js +2 -2
  39. package/dist/Communication/communication-templates-resource.component.js.map +1 -1
  40. package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts +6 -0
  41. package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts.map +1 -1
  42. package/dist/ComponentStudio/components/artifact-load-dialog.component.js +19 -6
  43. package/dist/ComponentStudio/components/artifact-load-dialog.component.js.map +1 -1
  44. package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts +4 -0
  45. package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts.map +1 -1
  46. package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +13 -4
  47. package/dist/ComponentStudio/components/artifact-selection-dialog.component.js.map +1 -1
  48. package/dist/Credentials/components/credentials-categories-resource.component.d.ts +2 -0
  49. package/dist/Credentials/components/credentials-categories-resource.component.d.ts.map +1 -1
  50. package/dist/Credentials/components/credentials-categories-resource.component.js +13 -9
  51. package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
  52. package/dist/Credentials/components/credentials-list-resource.component.js +11 -11
  53. package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
  54. package/dist/Credentials/components/credentials-overview-resource.component.js +3 -3
  55. package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
  56. package/dist/Credentials/components/credentials-types-resource.component.d.ts +2 -0
  57. package/dist/Credentials/components/credentials-types-resource.component.d.ts.map +1 -1
  58. package/dist/Credentials/components/credentials-types-resource.component.js +13 -9
  59. package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
  60. package/dist/DashboardBrowser/dashboard-browser-resource.component.js +11 -11
  61. package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
  62. package/dist/DashboardBrowser/dashboard-share-dialog.component.d.ts.map +1 -1
  63. package/dist/DashboardBrowser/dashboard-share-dialog.component.js +4 -3
  64. package/dist/DashboardBrowser/dashboard-share-dialog.component.js.map +1 -1
  65. package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts.map +1 -1
  66. package/dist/DataExplorer/components/view-selector/view-selector.component.js +4 -3
  67. package/dist/DataExplorer/components/view-selector/view-selector.component.js.map +1 -1
  68. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +11 -0
  69. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  70. package/dist/DataExplorer/data-explorer-dashboard.component.js +140 -108
  71. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  72. package/dist/DataExplorer/data-explorer-resource.component.d.ts.map +1 -1
  73. package/dist/DataExplorer/data-explorer-resource.component.js +4 -1
  74. package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -1
  75. package/dist/DataExplorer/services/explorer-state.service.d.ts.map +1 -1
  76. package/dist/DataExplorer/services/explorer-state.service.js +9 -8
  77. package/dist/DataExplorer/services/explorer-state.service.js.map +1 -1
  78. package/dist/EntityAdmin/entity-admin-dashboard.component.js +2 -2
  79. package/dist/EntityAdmin/entity-admin-dashboard.component.js.map +1 -1
  80. package/dist/Home/home-application.js +2 -2
  81. package/dist/Home/home-application.js.map +1 -1
  82. package/dist/Lists/components/lists-browse-resource.component.js +3 -3
  83. package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
  84. package/dist/Lists/components/lists-categories-resource.component.d.ts +1 -0
  85. package/dist/Lists/components/lists-categories-resource.component.d.ts.map +1 -1
  86. package/dist/Lists/components/lists-categories-resource.component.js +17 -14
  87. package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
  88. package/dist/Lists/components/lists-my-lists-resource.component.js +2 -2
  89. package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
  90. package/dist/Lists/components/lists-operations-resource.component.d.ts +1 -0
  91. package/dist/Lists/components/lists-operations-resource.component.d.ts.map +1 -1
  92. package/dist/Lists/components/lists-operations-resource.component.js +15 -12
  93. package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
  94. package/dist/MCP/components/mcp-connection-dialog.component.d.ts.map +1 -1
  95. package/dist/MCP/components/mcp-connection-dialog.component.js +3 -2
  96. package/dist/MCP/components/mcp-connection-dialog.component.js.map +1 -1
  97. package/dist/MCP/components/mcp-test-tool-dialog.component.d.ts.map +1 -1
  98. package/dist/MCP/components/mcp-test-tool-dialog.component.js +8 -7
  99. package/dist/MCP/components/mcp-test-tool-dialog.component.js.map +1 -1
  100. package/dist/MCP/mcp-dashboard.component.js +22 -22
  101. package/dist/MCP/mcp-dashboard.component.js.map +1 -1
  102. package/dist/QueryBrowser/query-browser-resource.component.d.ts +2 -0
  103. package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
  104. package/dist/QueryBrowser/query-browser-resource.component.js +14 -10
  105. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  106. package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts.map +1 -1
  107. package/dist/Scheduling/services/scheduling-instrumentation.service.js +2 -1
  108. package/dist/Scheduling/services/scheduling-instrumentation.service.js.map +1 -1
  109. package/dist/Testing/components/testing-explorer.component.d.ts +1 -0
  110. package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
  111. package/dist/Testing/components/testing-explorer.component.js +22 -18
  112. package/dist/Testing/components/testing-explorer.component.js.map +1 -1
  113. package/dist/Testing/components/testing-review.component.d.ts +1 -0
  114. package/dist/Testing/components/testing-review.component.d.ts.map +1 -1
  115. package/dist/Testing/components/testing-review.component.js +14 -10
  116. package/dist/Testing/components/testing-review.component.js.map +1 -1
  117. package/dist/VersionHistory/components/diff-resource.component.js +6 -6
  118. package/dist/VersionHistory/components/diff-resource.component.js.map +1 -1
  119. package/dist/VersionHistory/components/graph-resource.component.js +2 -2
  120. package/dist/VersionHistory/components/graph-resource.component.js.map +1 -1
  121. package/dist/VersionHistory/components/labels-resource.component.js +3 -3
  122. package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
  123. package/package.json +38 -38
@@ -1 +1 @@
1
- {"version":3,"file":"credentials-overview-resource.component.js","sourceRoot":"","sources":["../../../src/Credentials/components/credentials-overview-resource.component.ts","../../../src/Credentials/components/credentials-overview-resource.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { ResourceData, MJCredentialEntity, MJCredentialTypeEntity, MJCredentialCategoryEntity, MJAuditLogEntity } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { RunView, Metadata, CompositeKey } from '@memberjunction/core';\ninterface CategoryStat {\n category: string;\n categoryId: string;\n count: number;\n iconClass: string;\n color: string;\n percentage: number;\n}\n\ninterface TypeStat {\n typeId: string;\n typeName: string;\n category: string;\n credentialCount: number;\n activeCount: number;\n expiringCount: number;\n}\n\ninterface ActivityItem {\n id: string;\n credentialName: string;\n credentialId: string;\n typeName: string;\n action: 'Created' | 'Updated' | 'Accessed' | 'Rotated';\n date: Date;\n user?: string;\n}\n\ninterface UsageTrendPoint {\n timestamp: Date;\n accessCount: number;\n uniqueCredentials: number;\n successRate: number;\n}\n\n@RegisterClass(BaseResourceComponent, 'CredentialsOverviewResource')\n@Component({\n standalone: false,\n selector: 'mj-credentials-overview-resource',\n templateUrl: './credentials-overview-resource.component.html',\n styleUrls: ['./credentials-overview-resource.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class CredentialsOverviewResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public isLoading = true;\n\n // Summary stats\n public totalCredentials = 0;\n public activeCredentials = 0;\n public expiredCredentials = 0;\n public expiringSoonCount = 0;\n public credentialTypes = 0;\n public categories = 0;\n\n // Grouped data\n public categoryStats: CategoryStat[] = [];\n public typeStats: TypeStat[] = [];\n public recentActivity: ActivityItem[] = [];\n public usageTrend: UsageTrendPoint[] = [];\n\n // Raw data\n private credentials: MJCredentialEntity[] = [];\n private types: MJCredentialTypeEntity[] = [];\n private categoryList: MJCredentialCategoryEntity[] = [];\n private auditLogs: MJAuditLogEntity[] = [];\n\n // Permissions\n private _metadata = new Metadata();\n private _permissionCache = new Map<string, boolean>();\n\n // Category colors for charts\n private categoryColors: Record<string, string> = {\n 'AI': '#8b5cf6',\n 'Communication': '#3b82f6',\n 'Storage': '#10b981',\n 'Database': '#f59e0b',\n 'Authentication': '#ef4444',\n 'Integration': '#6366f1'\n };\n\n private destroy$ = new Subject<void>();\n\n constructor(\n private cdr: ChangeDetectorRef,\n private navigationService: NavigationService\n ) {\n super();\n }\n\n ngOnInit(): void {\n this.loadData();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Overview';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-chart-pie';\n }\n\n // === Permission Checks ===\n public get UserCanCreateCredentials(): boolean {\n return this.checkEntityPermission('MJ: Credentials', 'Create');\n }\n\n public get UserCanUpdateCredentials(): boolean {\n return this.checkEntityPermission('MJ: Credentials', 'Update');\n }\n\n private checkEntityPermission(entityName: string, permissionType: 'Create' | 'Read' | 'Update' | 'Delete'): boolean {\n const cacheKey = `${entityName}_${permissionType}`;\n\n if (this._permissionCache.has(cacheKey)) {\n return this._permissionCache.get(cacheKey)!;\n }\n\n try {\n const entityInfo = this._metadata.Entities.find(e => e.Name === entityName);\n if (!entityInfo) {\n this._permissionCache.set(cacheKey, false);\n return false;\n }\n\n const userPermissions = entityInfo.GetUserPermisions(this._metadata.CurrentUser);\n let hasPermission = false;\n\n switch (permissionType) {\n case 'Create': hasPermission = userPermissions.CanCreate; break;\n case 'Read': hasPermission = userPermissions.CanRead; break;\n case 'Update': hasPermission = userPermissions.CanUpdate; break;\n case 'Delete': hasPermission = userPermissions.CanDelete; break;\n }\n\n this._permissionCache.set(cacheKey, hasPermission);\n return hasPermission;\n } catch (error) {\n this._permissionCache.set(cacheKey, false);\n return false;\n }\n }\n\n private async loadData(): Promise<void> {\n try {\n this.isLoading = true;\n this.cdr.markForCheck();\n\n const rv = new RunView();\n\n // Calculate date range for audit logs (last 30 days)\n const thirtyDaysAgo = new Date();\n thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);\n const dateFilter = `__mj_CreatedAt >= '${thirtyDaysAgo.toISOString()}'`;\n\n // Load all data in parallel using RunViews\n const [credResult, typeResult, categoryResult, auditResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Credentials',\n ResultType: 'entity_object'\n },\n {\n EntityName: 'MJ: Credential Types',\n ResultType: 'entity_object'\n },\n {\n EntityName: 'MJ: Credential Categories',\n ResultType: 'entity_object'\n },\n {\n EntityName: 'MJ: Audit Logs',\n ExtraFilter: `AuditLogType LIKE '%Credential%' AND ${dateFilter}`,\n OrderBy: '__mj_CreatedAt DESC',\n MaxRows: 100,\n ResultType: 'entity_object'\n }\n ]);\n\n if (credResult.Success) {\n this.credentials = credResult.Results as MJCredentialEntity[];\n this.processCredentialStats();\n }\n\n if (typeResult.Success) {\n this.types = typeResult.Results as MJCredentialTypeEntity[];\n this.credentialTypes = this.types.length;\n this.processTypeStats();\n }\n\n if (categoryResult.Success) {\n this.categoryList = categoryResult.Results as MJCredentialCategoryEntity[];\n this.categories = this.categoryList.length;\n this.processCategoryStats();\n }\n\n if (auditResult.Success) {\n this.auditLogs = auditResult.Results as MJAuditLogEntity[];\n this.processActivityAndTrends();\n }\n\n // Build recent activity from credentials if no audit logs\n if (this.recentActivity.length === 0) {\n this.buildActivityFromCredentials();\n }\n\n } catch (error) {\n console.error('Error loading credentials overview:', error);\n } finally {\n this.isLoading = false;\n this.NotifyLoadComplete();\n this.cdr.markForCheck();\n }\n }\n\n private processCredentialStats(): void {\n this.totalCredentials = this.credentials.length;\n this.activeCredentials = this.credentials.filter(c => c.IsActive).length;\n\n const now = new Date();\n const thirtyDaysFromNow = new Date();\n thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30);\n\n this.expiredCredentials = this.credentials.filter(c =>\n c.ExpiresAt && new Date(c.ExpiresAt) < now\n ).length;\n\n this.expiringSoonCount = this.credentials.filter(c =>\n c.ExpiresAt &&\n new Date(c.ExpiresAt) >= now &&\n new Date(c.ExpiresAt) <= thirtyDaysFromNow &&\n c.IsActive\n ).length;\n }\n\n private processTypeStats(): void {\n const now = new Date();\n const thirtyDaysFromNow = new Date();\n thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30);\n\n this.typeStats = this.types.map(type => {\n const typeCredentials = this.credentials.filter(c => c.CredentialTypeID === type.ID);\n\n return {\n typeId: type.ID,\n typeName: type.Name,\n category: type.Category,\n credentialCount: typeCredentials.length,\n activeCount: typeCredentials.filter(c => c.IsActive).length,\n expiringCount: typeCredentials.filter(c =>\n c.ExpiresAt &&\n new Date(c.ExpiresAt) >= now &&\n new Date(c.ExpiresAt) <= thirtyDaysFromNow\n ).length\n };\n }).sort((a, b) => b.credentialCount - a.credentialCount);\n }\n\n private processCategoryStats(): void {\n const categoryMap = new Map<string, CategoryStat>();\n\n // Initialize from credential types\n for (const type of this.types) {\n const category = type.Category;\n const existing = categoryMap.get(category);\n const categoryCredentials = this.credentials.filter(c => c.CredentialTypeID === type.ID);\n\n if (existing) {\n existing.count += categoryCredentials.length;\n } else {\n categoryMap.set(category, {\n category: category,\n categoryId: category, // Use category name as ID for filtering\n count: categoryCredentials.length,\n iconClass: this.getCategoryIcon(category),\n color: this.categoryColors[category] || '#64748b',\n percentage: 0\n });\n }\n }\n\n // Calculate percentages\n const total = this.totalCredentials || 1;\n categoryMap.forEach(stat => {\n stat.percentage = Math.round((stat.count / total) * 100);\n });\n\n this.categoryStats = Array.from(categoryMap.values())\n .sort((a, b) => b.count - a.count);\n }\n\n private processActivityAndTrends(): void {\n // Process recent activity from audit logs\n this.recentActivity = this.auditLogs\n .slice(0, 10)\n .map(log => ({\n id: log.ID,\n credentialName: this.extractCredentialName(log.Description || ''),\n credentialId: '', // Would need to parse from log\n typeName: 'Credential',\n action: this.extractAction(log.Description || '') as ActivityItem['action'],\n date: new Date(log.__mj_CreatedAt),\n user: log.User\n }));\n\n // Build usage trend data (group by day)\n const trendMap = new Map<string, UsageTrendPoint>();\n const uniqueCredentialsPerDay = new Map<string, Set<string>>();\n\n for (const log of this.auditLogs) {\n const dateKey = new Date(log.__mj_CreatedAt).toISOString().split('T')[0];\n\n if (!trendMap.has(dateKey)) {\n trendMap.set(dateKey, {\n timestamp: new Date(dateKey),\n accessCount: 0,\n uniqueCredentials: 0,\n successRate: 100\n });\n uniqueCredentialsPerDay.set(dateKey, new Set());\n }\n\n const point = trendMap.get(dateKey)!;\n point.accessCount++;\n\n // Track unique credentials (would need proper parsing)\n const credId = this.extractCredentialId(log.Description || '');\n if (credId) {\n uniqueCredentialsPerDay.get(dateKey)!.add(credId);\n }\n }\n\n // Finalize unique counts\n trendMap.forEach((point, dateKey) => {\n point.uniqueCredentials = uniqueCredentialsPerDay.get(dateKey)?.size || 0;\n });\n\n this.usageTrend = Array.from(trendMap.values())\n .sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());\n }\n\n private buildActivityFromCredentials(): void {\n this.recentActivity = this.credentials\n .filter(c => c.__mj_UpdatedAt)\n .sort((a, b) => new Date(b.__mj_UpdatedAt).getTime() - new Date(a.__mj_UpdatedAt).getTime())\n .slice(0, 10)\n .map(c => ({\n id: c.ID,\n credentialName: c.Name,\n credentialId: c.ID,\n typeName: c.CredentialType || 'Unknown',\n action: 'Updated' as const,\n date: new Date(c.__mj_UpdatedAt),\n user: undefined\n }));\n }\n\n private extractCredentialName(description: string): string {\n // Try to extract credential name from audit log description\n const match = description.match(/credential[:\\s]+['\"]?([^'\"]+)['\"]?/i);\n return match ? match[1] : 'Unknown Credential';\n }\n\n private extractAction(description: string): string {\n if (description.toLowerCase().includes('creat')) return 'Created';\n if (description.toLowerCase().includes('rotat')) return 'Rotated';\n if (description.toLowerCase().includes('access')) return 'Accessed';\n return 'Updated';\n }\n\n private extractCredentialId(description: string): string {\n const match = description.match(/[a-f0-9-]{36}/i);\n return match ? match[0] : '';\n }\n\n private getCategoryIcon(category: string): string {\n const iconMap: Record<string, string> = {\n 'AI': 'fa-solid fa-brain',\n 'Communication': 'fa-solid fa-envelope',\n 'Storage': 'fa-solid fa-cloud',\n 'Database': 'fa-solid fa-database',\n 'Authentication': 'fa-solid fa-shield-halved',\n 'Integration': 'fa-solid fa-plug'\n };\n return iconMap[category] || 'fa-solid fa-key';\n }\n\n // === Navigation Actions ===\n\n public createNewCredential(): void {\n // Navigate to Credentials tab with openCreatePanel flag to show the slide-in editor\n this.navigationService.OpenNavItemByName('Credentials', {\n openCreatePanel: true\n });\n }\n\n public openCredential(credentialId: string): void {\n const key = new CompositeKey([{ FieldName: 'ID', Value: credentialId }]);\n this.navigationService.OpenEntityRecord('MJ: Credentials', key);\n }\n\n public onCategoryClick(category: CategoryStat): void {\n // Navigate to types nav item with category filter\n this.navigationService.OpenNavItemByName('Types', {\n categoryFilter: category.category\n });\n }\n\n public onTypeClick(typeStat: TypeStat): void {\n // Navigate to credentials nav item with type filter\n this.navigationService.OpenNavItemByName('Credentials', {\n typeId: typeStat.typeId\n });\n }\n\n public onActivityClick(activity: ActivityItem): void {\n if (activity.credentialId) {\n this.openCredential(activity.credentialId);\n }\n }\n\n public viewAllCredentials(): void {\n this.navigationService.OpenNavItemByName('Credentials');\n }\n\n public viewAuditLog(): void {\n this.navigationService.OpenNavItemByName('Audit Log');\n }\n\n public viewAllTypes(): void {\n this.navigationService.OpenNavItemByName('Types');\n }\n\n public viewAllCategories(): void {\n this.navigationService.OpenNavItemByName('Categories');\n }\n\n public viewExpiringCredentials(): void {\n this.navigationService.OpenNavItemByName('Credentials', {\n filter: 'expiring'\n });\n }\n\n // === Formatting Helpers ===\n\n public formatDate(date: Date): string {\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return 'Just now';\n if (diffMins < 60) return `${diffMins}m ago`;\n if (diffHours < 24) return `${diffHours}h ago`;\n if (diffDays < 7) return `${diffDays}d ago`;\n\n return date.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n });\n }\n\n public getActionIcon(action: string): string {\n const iconMap: Record<string, string> = {\n 'Created': 'fa-solid fa-plus',\n 'Updated': 'fa-solid fa-pen',\n 'Accessed': 'fa-solid fa-eye',\n 'Rotated': 'fa-solid fa-rotate'\n };\n return iconMap[action] || 'fa-solid fa-circle';\n }\n\n public getActionClass(action: string): string {\n const classMap: Record<string, string> = {\n 'Created': 'action-created',\n 'Updated': 'action-updated',\n 'Accessed': 'action-accessed',\n 'Rotated': 'action-rotated'\n };\n return classMap[action] || '';\n }\n\n public refresh(): void {\n this.loadData();\n }\n\n public getHealthScore(): number {\n if (this.totalCredentials === 0) return 100;\n\n const activeRatio = this.activeCredentials / this.totalCredentials;\n const expiredPenalty = (this.expiredCredentials / this.totalCredentials) * 30;\n const expiringPenalty = (this.expiringSoonCount / this.totalCredentials) * 15;\n\n return Math.max(0, Math.min(100, Math.round((activeRatio * 100) - expiredPenalty - expiringPenalty)));\n }\n\n public getHealthClass(): string {\n const score = this.getHealthScore();\n if (score >= 80) return 'health-good';\n if (score >= 60) return 'health-warning';\n return 'health-critical';\n }\n\n public getHealthLabel(): string {\n const score = this.getHealthScore();\n if (score >= 80) return 'Healthy';\n if (score >= 60) return 'Needs Attention';\n return 'Critical';\n }\n\n public getDonutOffset(index: number): number {\n // Calculate cumulative offset for donut chart segments\n // Each segment starts where the previous one ended\n // The circumference is 251 (2 * PI * 40)\n let offset = 63; // Start at top (25% of circumference = 90 degrees rotation)\n\n for (let i = 0; i < index; i++) {\n offset -= this.categoryStats[i].percentage * 2.51;\n }\n\n return offset;\n }\n}\n","<div class=\"overview-container\">\n @if (isLoading) {\n <mj-loading text=\"Loading overview...\"></mj-loading>\n }\n\n @if (!isLoading) {\n <!-- Header with Actions -->\n <div class=\"overview-header\">\n <div class=\"header-left\">\n <h2 class=\"overview-title\">Credential Overview</h2>\n <p class=\"overview-subtitle\">Monitor and manage your organization's credentials</p>\n </div>\n <div class=\"header-actions\">\n <button class=\"btn-refresh\" (click)=\"refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n @if (UserCanCreateCredentials) {\n <button class=\"btn-primary\" (click)=\"createNewCredential()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>New Credential</span>\n </button>\n }\n </div>\n </div>\n <!-- Health Score Banner -->\n <div class=\"health-banner\" [ngClass]=\"getHealthClass()\">\n <div class=\"health-score-container\">\n <div class=\"health-score-ring\">\n <svg viewBox=\"0 0 36 36\" class=\"circular-chart\">\n <path class=\"circle-bg\"\n d=\"M18 2.0845\n a 15.9155 15.9155 0 0 1 0 31.831\n a 15.9155 15.9155 0 0 1 0 -31.831\"\n />\n <path class=\"circle\"\n [attr.stroke-dasharray]=\"getHealthScore() + ', 100'\"\n d=\"M18 2.0845\n a 15.9155 15.9155 0 0 1 0 31.831\n a 15.9155 15.9155 0 0 1 0 -31.831\"\n />\n </svg>\n <div class=\"health-score-value\">{{getHealthScore()}}</div>\n </div>\n </div>\n <div class=\"health-info\">\n <div class=\"health-label\">{{getHealthLabel()}}</div>\n <div class=\"health-details\">\n @if (expiredCredentials > 0) {\n <span class=\"health-alert\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{expiredCredentials}} expired\n </span>\n }\n @if (expiringSoonCount > 0) {\n <span class=\"health-warning-text\" (click)=\"viewExpiringCredentials()\">\n <i class=\"fa-solid fa-clock\"></i>\n {{expiringSoonCount}} expiring soon\n </span>\n }\n @if (expiredCredentials === 0 && expiringSoonCount === 0) {\n <span class=\"health-ok\">\n <i class=\"fa-solid fa-check-circle\"></i>\n All credentials healthy\n </span>\n }\n </div>\n </div>\n </div>\n <!-- KPI Cards Row -->\n <div class=\"kpi-row\">\n <div class=\"kpi-card clickable\" (click)=\"viewAllCredentials()\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-key\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{totalCredentials}}</div>\n <div class=\"kpi-label\">Total Credentials</div>\n </div>\n <div class=\"kpi-trend\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n </div>\n <div class=\"kpi-card active clickable\" (click)=\"viewAllCredentials()\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-check-circle\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{activeCredentials}}</div>\n <div class=\"kpi-label\">Active</div>\n </div>\n <div class=\"kpi-trend success\">\n <span class=\"percentage\">{{totalCredentials > 0 ? (activeCredentials / totalCredentials * 100).toFixed(0) : 0}}%</span>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-cubes\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{credentialTypes}}</div>\n <div class=\"kpi-label\">Types</div>\n </div>\n </div>\n <div class=\"kpi-card clickable\" [class.warning]=\"expiringSoonCount > 0\" (click)=\"viewExpiringCredentials()\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-clock\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{expiringSoonCount}}</div>\n <div class=\"kpi-label\">Expiring Soon</div>\n </div>\n @if (expiringSoonCount > 0) {\n <div class=\"kpi-trend warning\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n }\n </div>\n <div class=\"kpi-card\" [class.danger]=\"expiredCredentials > 0\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-circle-xmark\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{expiredCredentials}}</div>\n <div class=\"kpi-label\">Expired</div>\n </div>\n </div>\n </div>\n <!-- Content Grid -->\n <div class=\"content-grid\">\n <!-- Category Distribution Chart -->\n <div class=\"panel category-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-chart-pie\"></i>\n <span>Credentials by Category</span>\n </div>\n <span class=\"panel-subtitle\">Click to filter by category</span>\n </div>\n <div class=\"panel-body\">\n @if (categoryStats.length > 0) {\n <div class=\"category-chart\">\n <!-- Visual Donut Chart -->\n <div class=\"donut-chart-container\">\n <svg viewBox=\"0 0 100 100\" class=\"donut-chart\">\n <circle cx=\"50\" cy=\"50\" r=\"40\" fill=\"none\" stroke=\"#e5e7eb\" stroke-width=\"12\"/>\n @for (stat of categoryStats; track stat; let i = $index) {\n <ng-container>\n <circle\n cx=\"50\" cy=\"50\" r=\"40\"\n fill=\"none\"\n [attr.stroke]=\"stat.color\"\n stroke-width=\"12\"\n [attr.stroke-dasharray]=\"stat.percentage * 2.51 + ' ' + (251 - stat.percentage * 2.51)\"\n [attr.stroke-dashoffset]=\"getDonutOffset(i)\"\n class=\"donut-segment\"\n (click)=\"onCategoryClick(stat)\"\n />\n </ng-container>\n }\n </svg>\n <div class=\"donut-center\">\n <div class=\"donut-total\">{{totalCredentials}}</div>\n <div class=\"donut-label\">Total</div>\n </div>\n </div>\n <!-- Legend -->\n <div class=\"category-legend\">\n @for (stat of categoryStats; track stat) {\n <div class=\"legend-item\" (click)=\"onCategoryClick(stat)\">\n <div class=\"legend-color\" [style.backgroundColor]=\"stat.color\"></div>\n <div class=\"legend-info\">\n <div class=\"legend-name\">\n <i [class]=\"stat.iconClass\"></i>\n {{stat.category}}\n </div>\n <div class=\"legend-value\">{{stat.count}} ({{stat.percentage}}%)</div>\n </div>\n <i class=\"fa-solid fa-chevron-right legend-arrow\"></i>\n </div>\n }\n </div>\n </div>\n }\n @if (categoryStats.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-folder-open\"></i>\n <span>No credentials configured</span>\n </div>\n }\n </div>\n </div>\n <!-- Types Breakdown -->\n <div class=\"panel types-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-cubes\"></i>\n <span>Top Credential Types</span>\n </div>\n <button class=\"panel-action\" (click)=\"viewAllTypes()\">\n View All <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n </div>\n <div class=\"panel-body\">\n @if (typeStats.length > 0) {\n <div class=\"type-list\">\n @for (type of typeStats.slice(0, 6); track type) {\n <div class=\"type-item\" (click)=\"onTypeClick(type)\">\n <div class=\"type-info\">\n <div class=\"type-name\">{{type.typeName}}</div>\n <div class=\"type-category\">{{type.category}}</div>\n </div>\n <div class=\"type-stats\">\n <div class=\"type-count\">\n <span class=\"count-value\">{{type.credentialCount}}</span>\n <span class=\"count-label\">credentials</span>\n </div>\n <div class=\"type-bar\">\n <div class=\"type-bar-fill\"\n [style.width.%]=\"totalCredentials > 0 ? (type.credentialCount / totalCredentials * 100) : 0\">\n </div>\n </div>\n <div class=\"type-indicators\">\n @if (type.activeCount > 0) {\n <span class=\"indicator active\" title=\"Active\">\n <i class=\"fa-solid fa-circle\"></i> {{type.activeCount}}\n </span>\n }\n @if (type.expiringCount > 0) {\n <span class=\"indicator warning\" title=\"Expiring Soon\">\n <i class=\"fa-solid fa-clock\"></i> {{type.expiringCount}}\n </span>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n @if (typeStats.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-shapes\"></i>\n <span>No credential types configured</span>\n </div>\n }\n </div>\n </div>\n <!-- Recent Activity -->\n <div class=\"panel activity-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n <span>Recent Activity</span>\n </div>\n <button class=\"panel-action\" (click)=\"viewAuditLog()\">\n View All <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n </div>\n <div class=\"panel-body\">\n @if (recentActivity.length > 0) {\n <div class=\"activity-list\">\n @for (activity of recentActivity; track activity) {\n <div class=\"activity-item\" (click)=\"onActivityClick(activity)\">\n <div class=\"activity-icon\" [ngClass]=\"getActionClass(activity.action)\">\n <i [class]=\"getActionIcon(activity.action)\"></i>\n </div>\n <div class=\"activity-info\">\n <div class=\"activity-name\">{{activity.credentialName}}</div>\n <div class=\"activity-meta\">\n <span class=\"activity-type\">{{activity.typeName}}</span>\n <span class=\"activity-action\">{{activity.action}}</span>\n @if (activity.user) {\n <span class=\"activity-user\">by {{activity.user}}</span>\n }\n </div>\n </div>\n <div class=\"activity-time\">\n {{formatDate(activity.date)}}\n </div>\n </div>\n }\n </div>\n }\n @if (recentActivity.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No recent activity</span>\n </div>\n }\n </div>\n </div>\n </div>\n <!-- Quick Actions -->\n @if (UserCanCreateCredentials) {\n <div class=\"quick-actions\">\n <div class=\"quick-actions-title\">Quick Actions</div>\n <div class=\"quick-actions-grid\">\n <button class=\"quick-action\" (click)=\"createNewCredential()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Add Credential</span>\n </button>\n <button class=\"quick-action\" (click)=\"viewAllTypes()\">\n <i class=\"fa-solid fa-shapes\"></i>\n <span>Manage Types</span>\n </button>\n <button class=\"quick-action\" (click)=\"viewAllCategories()\">\n <i class=\"fa-solid fa-folder-tree\"></i>\n <span>Categories</span>\n </button>\n <button class=\"quick-action\" (click)=\"viewAuditLog()\">\n <i class=\"fa-solid fa-clipboard-list\"></i>\n <span>Audit Log</span>\n </button>\n </div>\n </div>\n }\n <!-- Security Notice -->\n <div class=\"security-notice\">\n <i class=\"fa-solid fa-shield-check\"></i>\n <div class=\"notice-content\">\n <strong>Security Note:</strong> All credential values are encrypted.\n Access to credentials is logged in the audit trail for compliance and security monitoring.\n </div>\n </div>\n }\n</div>\n"]}
1
+ {"version":3,"file":"credentials-overview-resource.component.js","sourceRoot":"","sources":["../../../src/Credentials/components/credentials-overview-resource.component.ts","../../../src/Credentials/components/credentials-overview-resource.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { ResourceData, MJCredentialEntity, MJCredentialTypeEntity, MJCredentialCategoryEntity, MJAuditLogEntity } from '@memberjunction/core-entities';\nimport { RegisterClass , UUIDsEqual } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { RunView, Metadata, CompositeKey } from '@memberjunction/core';\ninterface CategoryStat {\n category: string;\n categoryId: string;\n count: number;\n iconClass: string;\n color: string;\n percentage: number;\n}\n\ninterface TypeStat {\n typeId: string;\n typeName: string;\n category: string;\n credentialCount: number;\n activeCount: number;\n expiringCount: number;\n}\n\ninterface ActivityItem {\n id: string;\n credentialName: string;\n credentialId: string;\n typeName: string;\n action: 'Created' | 'Updated' | 'Accessed' | 'Rotated';\n date: Date;\n user?: string;\n}\n\ninterface UsageTrendPoint {\n timestamp: Date;\n accessCount: number;\n uniqueCredentials: number;\n successRate: number;\n}\n\n@RegisterClass(BaseResourceComponent, 'CredentialsOverviewResource')\n@Component({\n standalone: false,\n selector: 'mj-credentials-overview-resource',\n templateUrl: './credentials-overview-resource.component.html',\n styleUrls: ['./credentials-overview-resource.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class CredentialsOverviewResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public isLoading = true;\n\n // Summary stats\n public totalCredentials = 0;\n public activeCredentials = 0;\n public expiredCredentials = 0;\n public expiringSoonCount = 0;\n public credentialTypes = 0;\n public categories = 0;\n\n // Grouped data\n public categoryStats: CategoryStat[] = [];\n public typeStats: TypeStat[] = [];\n public recentActivity: ActivityItem[] = [];\n public usageTrend: UsageTrendPoint[] = [];\n\n // Raw data\n private credentials: MJCredentialEntity[] = [];\n private types: MJCredentialTypeEntity[] = [];\n private categoryList: MJCredentialCategoryEntity[] = [];\n private auditLogs: MJAuditLogEntity[] = [];\n\n // Permissions\n private _metadata = new Metadata();\n private _permissionCache = new Map<string, boolean>();\n\n // Category colors for charts\n private categoryColors: Record<string, string> = {\n 'AI': '#8b5cf6',\n 'Communication': '#3b82f6',\n 'Storage': '#10b981',\n 'Database': '#f59e0b',\n 'Authentication': '#ef4444',\n 'Integration': '#6366f1'\n };\n\n private destroy$ = new Subject<void>();\n\n constructor(\n private cdr: ChangeDetectorRef,\n private navigationService: NavigationService\n ) {\n super();\n }\n\n ngOnInit(): void {\n this.loadData();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Overview';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-chart-pie';\n }\n\n // === Permission Checks ===\n public get UserCanCreateCredentials(): boolean {\n return this.checkEntityPermission('MJ: Credentials', 'Create');\n }\n\n public get UserCanUpdateCredentials(): boolean {\n return this.checkEntityPermission('MJ: Credentials', 'Update');\n }\n\n private checkEntityPermission(entityName: string, permissionType: 'Create' | 'Read' | 'Update' | 'Delete'): boolean {\n const cacheKey = `${entityName}_${permissionType}`;\n\n if (this._permissionCache.has(cacheKey)) {\n return this._permissionCache.get(cacheKey)!;\n }\n\n try {\n const entityInfo = this._metadata.Entities.find(e => e.Name === entityName);\n if (!entityInfo) {\n this._permissionCache.set(cacheKey, false);\n return false;\n }\n\n const userPermissions = entityInfo.GetUserPermisions(this._metadata.CurrentUser);\n let hasPermission = false;\n\n switch (permissionType) {\n case 'Create': hasPermission = userPermissions.CanCreate; break;\n case 'Read': hasPermission = userPermissions.CanRead; break;\n case 'Update': hasPermission = userPermissions.CanUpdate; break;\n case 'Delete': hasPermission = userPermissions.CanDelete; break;\n }\n\n this._permissionCache.set(cacheKey, hasPermission);\n return hasPermission;\n } catch (error) {\n this._permissionCache.set(cacheKey, false);\n return false;\n }\n }\n\n private async loadData(): Promise<void> {\n try {\n this.isLoading = true;\n this.cdr.markForCheck();\n\n const rv = new RunView();\n\n // Calculate date range for audit logs (last 30 days)\n const thirtyDaysAgo = new Date();\n thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);\n const dateFilter = `__mj_CreatedAt >= '${thirtyDaysAgo.toISOString()}'`;\n\n // Load all data in parallel using RunViews\n const [credResult, typeResult, categoryResult, auditResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Credentials',\n ResultType: 'entity_object'\n },\n {\n EntityName: 'MJ: Credential Types',\n ResultType: 'entity_object'\n },\n {\n EntityName: 'MJ: Credential Categories',\n ResultType: 'entity_object'\n },\n {\n EntityName: 'MJ: Audit Logs',\n ExtraFilter: `AuditLogType LIKE '%Credential%' AND ${dateFilter}`,\n OrderBy: '__mj_CreatedAt DESC',\n MaxRows: 100,\n ResultType: 'entity_object'\n }\n ]);\n\n if (credResult.Success) {\n this.credentials = credResult.Results as MJCredentialEntity[];\n this.processCredentialStats();\n }\n\n if (typeResult.Success) {\n this.types = typeResult.Results as MJCredentialTypeEntity[];\n this.credentialTypes = this.types.length;\n this.processTypeStats();\n }\n\n if (categoryResult.Success) {\n this.categoryList = categoryResult.Results as MJCredentialCategoryEntity[];\n this.categories = this.categoryList.length;\n this.processCategoryStats();\n }\n\n if (auditResult.Success) {\n this.auditLogs = auditResult.Results as MJAuditLogEntity[];\n this.processActivityAndTrends();\n }\n\n // Build recent activity from credentials if no audit logs\n if (this.recentActivity.length === 0) {\n this.buildActivityFromCredentials();\n }\n\n } catch (error) {\n console.error('Error loading credentials overview:', error);\n } finally {\n this.isLoading = false;\n this.NotifyLoadComplete();\n this.cdr.markForCheck();\n }\n }\n\n private processCredentialStats(): void {\n this.totalCredentials = this.credentials.length;\n this.activeCredentials = this.credentials.filter(c => c.IsActive).length;\n\n const now = new Date();\n const thirtyDaysFromNow = new Date();\n thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30);\n\n this.expiredCredentials = this.credentials.filter(c =>\n c.ExpiresAt && new Date(c.ExpiresAt) < now\n ).length;\n\n this.expiringSoonCount = this.credentials.filter(c =>\n c.ExpiresAt &&\n new Date(c.ExpiresAt) >= now &&\n new Date(c.ExpiresAt) <= thirtyDaysFromNow &&\n c.IsActive\n ).length;\n }\n\n private processTypeStats(): void {\n const now = new Date();\n const thirtyDaysFromNow = new Date();\n thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30);\n\n this.typeStats = this.types.map(type => {\n const typeCredentials = this.credentials.filter(c => UUIDsEqual(c.CredentialTypeID, type.ID));\n\n return {\n typeId: type.ID,\n typeName: type.Name,\n category: type.Category,\n credentialCount: typeCredentials.length,\n activeCount: typeCredentials.filter(c => c.IsActive).length,\n expiringCount: typeCredentials.filter(c =>\n c.ExpiresAt &&\n new Date(c.ExpiresAt) >= now &&\n new Date(c.ExpiresAt) <= thirtyDaysFromNow\n ).length\n };\n }).sort((a, b) => b.credentialCount - a.credentialCount);\n }\n\n private processCategoryStats(): void {\n const categoryMap = new Map<string, CategoryStat>();\n\n // Initialize from credential types\n for (const type of this.types) {\n const category = type.Category;\n const existing = categoryMap.get(category);\n const categoryCredentials = this.credentials.filter(c => UUIDsEqual(c.CredentialTypeID, type.ID));\n\n if (existing) {\n existing.count += categoryCredentials.length;\n } else {\n categoryMap.set(category, {\n category: category,\n categoryId: category, // Use category name as ID for filtering\n count: categoryCredentials.length,\n iconClass: this.getCategoryIcon(category),\n color: this.categoryColors[category] || '#64748b',\n percentage: 0\n });\n }\n }\n\n // Calculate percentages\n const total = this.totalCredentials || 1;\n categoryMap.forEach(stat => {\n stat.percentage = Math.round((stat.count / total) * 100);\n });\n\n this.categoryStats = Array.from(categoryMap.values())\n .sort((a, b) => b.count - a.count);\n }\n\n private processActivityAndTrends(): void {\n // Process recent activity from audit logs\n this.recentActivity = this.auditLogs\n .slice(0, 10)\n .map(log => ({\n id: log.ID,\n credentialName: this.extractCredentialName(log.Description || ''),\n credentialId: '', // Would need to parse from log\n typeName: 'Credential',\n action: this.extractAction(log.Description || '') as ActivityItem['action'],\n date: new Date(log.__mj_CreatedAt),\n user: log.User\n }));\n\n // Build usage trend data (group by day)\n const trendMap = new Map<string, UsageTrendPoint>();\n const uniqueCredentialsPerDay = new Map<string, Set<string>>();\n\n for (const log of this.auditLogs) {\n const dateKey = new Date(log.__mj_CreatedAt).toISOString().split('T')[0];\n\n if (!trendMap.has(dateKey)) {\n trendMap.set(dateKey, {\n timestamp: new Date(dateKey),\n accessCount: 0,\n uniqueCredentials: 0,\n successRate: 100\n });\n uniqueCredentialsPerDay.set(dateKey, new Set());\n }\n\n const point = trendMap.get(dateKey)!;\n point.accessCount++;\n\n // Track unique credentials (would need proper parsing)\n const credId = this.extractCredentialId(log.Description || '');\n if (credId) {\n uniqueCredentialsPerDay.get(dateKey)!.add(credId);\n }\n }\n\n // Finalize unique counts\n trendMap.forEach((point, dateKey) => {\n point.uniqueCredentials = uniqueCredentialsPerDay.get(dateKey)?.size || 0;\n });\n\n this.usageTrend = Array.from(trendMap.values())\n .sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());\n }\n\n private buildActivityFromCredentials(): void {\n this.recentActivity = this.credentials\n .filter(c => c.__mj_UpdatedAt)\n .sort((a, b) => new Date(b.__mj_UpdatedAt).getTime() - new Date(a.__mj_UpdatedAt).getTime())\n .slice(0, 10)\n .map(c => ({\n id: c.ID,\n credentialName: c.Name,\n credentialId: c.ID,\n typeName: c.CredentialType || 'Unknown',\n action: 'Updated' as const,\n date: new Date(c.__mj_UpdatedAt),\n user: undefined\n }));\n }\n\n private extractCredentialName(description: string): string {\n // Try to extract credential name from audit log description\n const match = description.match(/credential[:\\s]+['\"]?([^'\"]+)['\"]?/i);\n return match ? match[1] : 'Unknown Credential';\n }\n\n private extractAction(description: string): string {\n if (description.toLowerCase().includes('creat')) return 'Created';\n if (description.toLowerCase().includes('rotat')) return 'Rotated';\n if (description.toLowerCase().includes('access')) return 'Accessed';\n return 'Updated';\n }\n\n private extractCredentialId(description: string): string {\n const match = description.match(/[a-f0-9-]{36}/i);\n return match ? match[0] : '';\n }\n\n private getCategoryIcon(category: string): string {\n const iconMap: Record<string, string> = {\n 'AI': 'fa-solid fa-brain',\n 'Communication': 'fa-solid fa-envelope',\n 'Storage': 'fa-solid fa-cloud',\n 'Database': 'fa-solid fa-database',\n 'Authentication': 'fa-solid fa-shield-halved',\n 'Integration': 'fa-solid fa-plug'\n };\n return iconMap[category] || 'fa-solid fa-key';\n }\n\n // === Navigation Actions ===\n\n public createNewCredential(): void {\n // Navigate to Credentials tab with openCreatePanel flag to show the slide-in editor\n this.navigationService.OpenNavItemByName('Credentials', {\n openCreatePanel: true\n });\n }\n\n public openCredential(credentialId: string): void {\n const key = new CompositeKey([{ FieldName: 'ID', Value: credentialId }]);\n this.navigationService.OpenEntityRecord('MJ: Credentials', key);\n }\n\n public onCategoryClick(category: CategoryStat): void {\n // Navigate to types nav item with category filter\n this.navigationService.OpenNavItemByName('Types', {\n categoryFilter: category.category\n });\n }\n\n public onTypeClick(typeStat: TypeStat): void {\n // Navigate to credentials nav item with type filter\n this.navigationService.OpenNavItemByName('Credentials', {\n typeId: typeStat.typeId\n });\n }\n\n public onActivityClick(activity: ActivityItem): void {\n if (activity.credentialId) {\n this.openCredential(activity.credentialId);\n }\n }\n\n public viewAllCredentials(): void {\n this.navigationService.OpenNavItemByName('Credentials');\n }\n\n public viewAuditLog(): void {\n this.navigationService.OpenNavItemByName('Audit Log');\n }\n\n public viewAllTypes(): void {\n this.navigationService.OpenNavItemByName('Types');\n }\n\n public viewAllCategories(): void {\n this.navigationService.OpenNavItemByName('Categories');\n }\n\n public viewExpiringCredentials(): void {\n this.navigationService.OpenNavItemByName('Credentials', {\n filter: 'expiring'\n });\n }\n\n // === Formatting Helpers ===\n\n public formatDate(date: Date): string {\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return 'Just now';\n if (diffMins < 60) return `${diffMins}m ago`;\n if (diffHours < 24) return `${diffHours}h ago`;\n if (diffDays < 7) return `${diffDays}d ago`;\n\n return date.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n });\n }\n\n public getActionIcon(action: string): string {\n const iconMap: Record<string, string> = {\n 'Created': 'fa-solid fa-plus',\n 'Updated': 'fa-solid fa-pen',\n 'Accessed': 'fa-solid fa-eye',\n 'Rotated': 'fa-solid fa-rotate'\n };\n return iconMap[action] || 'fa-solid fa-circle';\n }\n\n public getActionClass(action: string): string {\n const classMap: Record<string, string> = {\n 'Created': 'action-created',\n 'Updated': 'action-updated',\n 'Accessed': 'action-accessed',\n 'Rotated': 'action-rotated'\n };\n return classMap[action] || '';\n }\n\n public refresh(): void {\n this.loadData();\n }\n\n public getHealthScore(): number {\n if (this.totalCredentials === 0) return 100;\n\n const activeRatio = this.activeCredentials / this.totalCredentials;\n const expiredPenalty = (this.expiredCredentials / this.totalCredentials) * 30;\n const expiringPenalty = (this.expiringSoonCount / this.totalCredentials) * 15;\n\n return Math.max(0, Math.min(100, Math.round((activeRatio * 100) - expiredPenalty - expiringPenalty)));\n }\n\n public getHealthClass(): string {\n const score = this.getHealthScore();\n if (score >= 80) return 'health-good';\n if (score >= 60) return 'health-warning';\n return 'health-critical';\n }\n\n public getHealthLabel(): string {\n const score = this.getHealthScore();\n if (score >= 80) return 'Healthy';\n if (score >= 60) return 'Needs Attention';\n return 'Critical';\n }\n\n public getDonutOffset(index: number): number {\n // Calculate cumulative offset for donut chart segments\n // Each segment starts where the previous one ended\n // The circumference is 251 (2 * PI * 40)\n let offset = 63; // Start at top (25% of circumference = 90 degrees rotation)\n\n for (let i = 0; i < index; i++) {\n offset -= this.categoryStats[i].percentage * 2.51;\n }\n\n return offset;\n }\n}\n","<div class=\"overview-container\">\n @if (isLoading) {\n <mj-loading text=\"Loading overview...\"></mj-loading>\n }\n\n @if (!isLoading) {\n <!-- Header with Actions -->\n <div class=\"overview-header\">\n <div class=\"header-left\">\n <h2 class=\"overview-title\">Credential Overview</h2>\n <p class=\"overview-subtitle\">Monitor and manage your organization's credentials</p>\n </div>\n <div class=\"header-actions\">\n <button class=\"btn-refresh\" (click)=\"refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n @if (UserCanCreateCredentials) {\n <button class=\"btn-primary\" (click)=\"createNewCredential()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>New Credential</span>\n </button>\n }\n </div>\n </div>\n <!-- Health Score Banner -->\n <div class=\"health-banner\" [ngClass]=\"getHealthClass()\">\n <div class=\"health-score-container\">\n <div class=\"health-score-ring\">\n <svg viewBox=\"0 0 36 36\" class=\"circular-chart\">\n <path class=\"circle-bg\"\n d=\"M18 2.0845\n a 15.9155 15.9155 0 0 1 0 31.831\n a 15.9155 15.9155 0 0 1 0 -31.831\"\n />\n <path class=\"circle\"\n [attr.stroke-dasharray]=\"getHealthScore() + ', 100'\"\n d=\"M18 2.0845\n a 15.9155 15.9155 0 0 1 0 31.831\n a 15.9155 15.9155 0 0 1 0 -31.831\"\n />\n </svg>\n <div class=\"health-score-value\">{{getHealthScore()}}</div>\n </div>\n </div>\n <div class=\"health-info\">\n <div class=\"health-label\">{{getHealthLabel()}}</div>\n <div class=\"health-details\">\n @if (expiredCredentials > 0) {\n <span class=\"health-alert\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{expiredCredentials}} expired\n </span>\n }\n @if (expiringSoonCount > 0) {\n <span class=\"health-warning-text\" (click)=\"viewExpiringCredentials()\">\n <i class=\"fa-solid fa-clock\"></i>\n {{expiringSoonCount}} expiring soon\n </span>\n }\n @if (expiredCredentials === 0 && expiringSoonCount === 0) {\n <span class=\"health-ok\">\n <i class=\"fa-solid fa-check-circle\"></i>\n All credentials healthy\n </span>\n }\n </div>\n </div>\n </div>\n <!-- KPI Cards Row -->\n <div class=\"kpi-row\">\n <div class=\"kpi-card clickable\" (click)=\"viewAllCredentials()\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-key\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{totalCredentials}}</div>\n <div class=\"kpi-label\">Total Credentials</div>\n </div>\n <div class=\"kpi-trend\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n </div>\n <div class=\"kpi-card active clickable\" (click)=\"viewAllCredentials()\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-check-circle\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{activeCredentials}}</div>\n <div class=\"kpi-label\">Active</div>\n </div>\n <div class=\"kpi-trend success\">\n <span class=\"percentage\">{{totalCredentials > 0 ? (activeCredentials / totalCredentials * 100).toFixed(0) : 0}}%</span>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-cubes\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{credentialTypes}}</div>\n <div class=\"kpi-label\">Types</div>\n </div>\n </div>\n <div class=\"kpi-card clickable\" [class.warning]=\"expiringSoonCount > 0\" (click)=\"viewExpiringCredentials()\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-clock\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{expiringSoonCount}}</div>\n <div class=\"kpi-label\">Expiring Soon</div>\n </div>\n @if (expiringSoonCount > 0) {\n <div class=\"kpi-trend warning\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n }\n </div>\n <div class=\"kpi-card\" [class.danger]=\"expiredCredentials > 0\">\n <div class=\"kpi-icon\">\n <i class=\"fa-solid fa-circle-xmark\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{expiredCredentials}}</div>\n <div class=\"kpi-label\">Expired</div>\n </div>\n </div>\n </div>\n <!-- Content Grid -->\n <div class=\"content-grid\">\n <!-- Category Distribution Chart -->\n <div class=\"panel category-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-chart-pie\"></i>\n <span>Credentials by Category</span>\n </div>\n <span class=\"panel-subtitle\">Click to filter by category</span>\n </div>\n <div class=\"panel-body\">\n @if (categoryStats.length > 0) {\n <div class=\"category-chart\">\n <!-- Visual Donut Chart -->\n <div class=\"donut-chart-container\">\n <svg viewBox=\"0 0 100 100\" class=\"donut-chart\">\n <circle cx=\"50\" cy=\"50\" r=\"40\" fill=\"none\" stroke=\"#e5e7eb\" stroke-width=\"12\"/>\n @for (stat of categoryStats; track stat; let i = $index) {\n <ng-container>\n <circle\n cx=\"50\" cy=\"50\" r=\"40\"\n fill=\"none\"\n [attr.stroke]=\"stat.color\"\n stroke-width=\"12\"\n [attr.stroke-dasharray]=\"stat.percentage * 2.51 + ' ' + (251 - stat.percentage * 2.51)\"\n [attr.stroke-dashoffset]=\"getDonutOffset(i)\"\n class=\"donut-segment\"\n (click)=\"onCategoryClick(stat)\"\n />\n </ng-container>\n }\n </svg>\n <div class=\"donut-center\">\n <div class=\"donut-total\">{{totalCredentials}}</div>\n <div class=\"donut-label\">Total</div>\n </div>\n </div>\n <!-- Legend -->\n <div class=\"category-legend\">\n @for (stat of categoryStats; track stat) {\n <div class=\"legend-item\" (click)=\"onCategoryClick(stat)\">\n <div class=\"legend-color\" [style.backgroundColor]=\"stat.color\"></div>\n <div class=\"legend-info\">\n <div class=\"legend-name\">\n <i [class]=\"stat.iconClass\"></i>\n {{stat.category}}\n </div>\n <div class=\"legend-value\">{{stat.count}} ({{stat.percentage}}%)</div>\n </div>\n <i class=\"fa-solid fa-chevron-right legend-arrow\"></i>\n </div>\n }\n </div>\n </div>\n }\n @if (categoryStats.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-folder-open\"></i>\n <span>No credentials configured</span>\n </div>\n }\n </div>\n </div>\n <!-- Types Breakdown -->\n <div class=\"panel types-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-cubes\"></i>\n <span>Top Credential Types</span>\n </div>\n <button class=\"panel-action\" (click)=\"viewAllTypes()\">\n View All <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n </div>\n <div class=\"panel-body\">\n @if (typeStats.length > 0) {\n <div class=\"type-list\">\n @for (type of typeStats.slice(0, 6); track type) {\n <div class=\"type-item\" (click)=\"onTypeClick(type)\">\n <div class=\"type-info\">\n <div class=\"type-name\">{{type.typeName}}</div>\n <div class=\"type-category\">{{type.category}}</div>\n </div>\n <div class=\"type-stats\">\n <div class=\"type-count\">\n <span class=\"count-value\">{{type.credentialCount}}</span>\n <span class=\"count-label\">credentials</span>\n </div>\n <div class=\"type-bar\">\n <div class=\"type-bar-fill\"\n [style.width.%]=\"totalCredentials > 0 ? (type.credentialCount / totalCredentials * 100) : 0\">\n </div>\n </div>\n <div class=\"type-indicators\">\n @if (type.activeCount > 0) {\n <span class=\"indicator active\" title=\"Active\">\n <i class=\"fa-solid fa-circle\"></i> {{type.activeCount}}\n </span>\n }\n @if (type.expiringCount > 0) {\n <span class=\"indicator warning\" title=\"Expiring Soon\">\n <i class=\"fa-solid fa-clock\"></i> {{type.expiringCount}}\n </span>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n @if (typeStats.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-shapes\"></i>\n <span>No credential types configured</span>\n </div>\n }\n </div>\n </div>\n <!-- Recent Activity -->\n <div class=\"panel activity-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n <span>Recent Activity</span>\n </div>\n <button class=\"panel-action\" (click)=\"viewAuditLog()\">\n View All <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n </div>\n <div class=\"panel-body\">\n @if (recentActivity.length > 0) {\n <div class=\"activity-list\">\n @for (activity of recentActivity; track activity) {\n <div class=\"activity-item\" (click)=\"onActivityClick(activity)\">\n <div class=\"activity-icon\" [ngClass]=\"getActionClass(activity.action)\">\n <i [class]=\"getActionIcon(activity.action)\"></i>\n </div>\n <div class=\"activity-info\">\n <div class=\"activity-name\">{{activity.credentialName}}</div>\n <div class=\"activity-meta\">\n <span class=\"activity-type\">{{activity.typeName}}</span>\n <span class=\"activity-action\">{{activity.action}}</span>\n @if (activity.user) {\n <span class=\"activity-user\">by {{activity.user}}</span>\n }\n </div>\n </div>\n <div class=\"activity-time\">\n {{formatDate(activity.date)}}\n </div>\n </div>\n }\n </div>\n }\n @if (recentActivity.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No recent activity</span>\n </div>\n }\n </div>\n </div>\n </div>\n <!-- Quick Actions -->\n @if (UserCanCreateCredentials) {\n <div class=\"quick-actions\">\n <div class=\"quick-actions-title\">Quick Actions</div>\n <div class=\"quick-actions-grid\">\n <button class=\"quick-action\" (click)=\"createNewCredential()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Add Credential</span>\n </button>\n <button class=\"quick-action\" (click)=\"viewAllTypes()\">\n <i class=\"fa-solid fa-shapes\"></i>\n <span>Manage Types</span>\n </button>\n <button class=\"quick-action\" (click)=\"viewAllCategories()\">\n <i class=\"fa-solid fa-folder-tree\"></i>\n <span>Categories</span>\n </button>\n <button class=\"quick-action\" (click)=\"viewAuditLog()\">\n <i class=\"fa-solid fa-clipboard-list\"></i>\n <span>Audit Log</span>\n </button>\n </div>\n </div>\n }\n <!-- Security Notice -->\n <div class=\"security-notice\">\n <i class=\"fa-solid fa-shield-check\"></i>\n <div class=\"notice-content\">\n <strong>Security Note:</strong> All credential values are encrypted.\n Access to credentials is logged in the audit trail for compliance and security monitoring.\n </div>\n </div>\n }\n</div>\n"]}
@@ -60,6 +60,8 @@ export declare class CredentialsTypesResourceComponent extends BaseResourceCompo
60
60
  getCategoryIcon(category: string): string;
61
61
  getCategoryColor(category: string): string;
62
62
  getTypesByCategory(): Map<string, TypeWithStats[]>;
63
+ /** Case-insensitive UUID check whether a credential type is the currently selected type. */
64
+ IsTypeSelected(type: TypeWithStats): boolean;
63
65
  getTotalCredentialCount(): number;
64
66
  refresh(): void;
65
67
  static ɵfac: i0.ɵɵFactoryDeclaration<CredentialsTypesResourceComponent, never>;
@@ -1 +1 @@
1
- {"version":3,"file":"credentials-types-resource.component.d.ts","sourceRoot":"","sources":["../../../src/Credentials/components/credentials-types-resource.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"credentials-types-resource.component.d.ts","sourceRoot":"","sources":["../../../src/Credentials/components/credentials-types-resource.component.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { Component, ChangeDetectionStrategy, ViewChild } from '@angular/core';
8
- import { RegisterClass } from '@memberjunction/global';
8
+ import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
9
9
  import { BaseResourceComponent } from '@memberjunction/ng-shared';
10
10
  import { RunView, Metadata } from '@memberjunction/core';
11
11
  import { MJNotificationService } from '@memberjunction/ng-notifications';
@@ -132,7 +132,7 @@ function CredentialsTypesResourceComponent_Conditional_2_For_35_For_9_Template(r
132
132
  } if (rf & 2) {
133
133
  const type_r8 = ctx.$implicit;
134
134
  const ctx_r3 = i0.ɵɵnextContext(3);
135
- i0.ɵɵclassProp("selected", (ctx_r3.selectedType == null ? null : ctx_r3.selectedType.ID) === type_r8.ID);
135
+ i0.ɵɵclassProp("selected", ctx_r3.IsTypeSelected(type_r8));
136
136
  i0.ɵɵadvance();
137
137
  i0.ɵɵstyleProp("background-color", ctx_r3.getCategoryColor(type_r8.Category) + "15")("color", ctx_r3.getCategoryColor(type_r8.Category));
138
138
  i0.ɵɵadvance();
@@ -631,7 +631,7 @@ let CredentialsTypesResourceComponent = class CredentialsTypesResourceComponent
631
631
  }
632
632
  }
633
633
  enrichTypeWithStats(type) {
634
- const typeCredentials = this.credentials.filter(c => c.CredentialTypeID === type.ID);
634
+ const typeCredentials = this.credentials.filter(c => UUIDsEqual(c.CredentialTypeID, type.ID));
635
635
  const now = new Date();
636
636
  const thirtyDaysFromNow = new Date();
637
637
  thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30);
@@ -677,8 +677,8 @@ let CredentialsTypesResourceComponent = class CredentialsTypesResourceComponent
677
677
  const success = await type.Delete();
678
678
  if (success) {
679
679
  MJNotificationService.Instance.CreateSimpleNotification(`Credential type "${type.Name}" deleted successfully`, 'success', 3000);
680
- this.types = this.types.filter(t => t.ID !== type.ID);
681
- if (this.selectedType?.ID === type.ID) {
680
+ this.types = this.types.filter(t => !UUIDsEqual(t.ID, type.ID));
681
+ if (UUIDsEqual(this.selectedType?.ID, type.ID)) {
682
682
  this.closeDetail();
683
683
  }
684
684
  this.applyFilters();
@@ -704,7 +704,7 @@ let CredentialsTypesResourceComponent = class CredentialsTypesResourceComponent
704
704
  }
705
705
  // === Panel Event Handlers ===
706
706
  onTypeSaved(type) {
707
- const existingIndex = this.types.findIndex(t => t.ID === type.ID);
707
+ const existingIndex = this.types.findIndex(t => UUIDsEqual(t.ID, type.ID));
708
708
  const enrichedType = this.enrichTypeWithStats(type);
709
709
  if (existingIndex >= 0) {
710
710
  this.types[existingIndex] = enrichedType;
@@ -720,8 +720,8 @@ let CredentialsTypesResourceComponent = class CredentialsTypesResourceComponent
720
720
  this.cdr.markForCheck();
721
721
  }
722
722
  onTypeDeleted(typeId) {
723
- this.types = this.types.filter(t => t.ID !== typeId);
724
- if (this.selectedType?.ID === typeId) {
723
+ this.types = this.types.filter(t => !UUIDsEqual(t.ID, typeId));
724
+ if (UUIDsEqual(this.selectedType?.ID, typeId)) {
725
725
  this.closeDetail();
726
726
  }
727
727
  this.applyFilters();
@@ -829,6 +829,10 @@ let CredentialsTypesResourceComponent = class CredentialsTypesResourceComponent
829
829
  }
830
830
  return grouped;
831
831
  }
832
+ /** Case-insensitive UUID check whether a credential type is the currently selected type. */
833
+ IsTypeSelected(type) {
834
+ return UUIDsEqual(this.selectedType?.ID, type.ID);
835
+ }
832
836
  getTotalCredentialCount() {
833
837
  return this.types.reduce((sum, t) => sum + t.credentialCount, 0);
834
838
  }
@@ -863,7 +867,7 @@ CredentialsTypesResourceComponent = __decorate([
863
867
  export { CredentialsTypesResourceComponent };
864
868
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CredentialsTypesResourceComponent, [{
865
869
  type: Component,
866
- args: [{ standalone: false, selector: 'mj-credentials-types-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<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]=\"selectedType?.ID === type.ID\"\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", styles: [".types-container {\n height: 100%;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n padding: 24px;\n background: var(--page-background, #f8fafc);\n}\n\n/* Header */\n.types-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n margin-bottom: 24px;\n flex-wrap: wrap;\n gap: 16px;\n}\n\n.header-info {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.types-title {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0;\n}\n\n.header-stats {\n display: flex;\n align-items: center;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.stat-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n}\n\n.stat-item i {\n font-size: 12px;\n}\n\n.header-actions {\n display: flex;\n gap: 12px;\n}\n\n.btn-primary {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);\n color: white;\n border: none;\n border-radius: 10px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n box-shadow: 0 2px 8px rgba(99, 102, 241, 0.3);\n}\n\n.btn-primary:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 16px rgba(99, 102, 241, 0.4);\n}\n\n.btn-primary i {\n font-size: 13px;\n}\n\n/* Toolbar */\n.toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n margin-bottom: 16px;\n flex-wrap: wrap;\n background: var(--card-background, #ffffff);\n padding: 16px;\n border-radius: 12px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n\n.toolbar-left {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n flex: 1;\n}\n\n.toolbar-right {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.search-container {\n display: flex;\n align-items: center;\n background: var(--input-background, #f9fafb);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n padding: 8px 12px;\n min-width: 240px;\n position: relative;\n}\n\n.search-container i {\n color: var(--text-secondary, #6b7280);\n margin-right: 8px;\n}\n\n.search-container input {\n border: none;\n background: transparent;\n outline: none;\n flex: 1;\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n}\n\n.search-clear {\n position: absolute;\n right: 8px;\n top: 50%;\n transform: translateY(-50%);\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--border-color, #e5e7eb);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n color: var(--text-secondary, #6b7280);\n font-size: 10px;\n}\n\n.search-clear:hover {\n background: var(--text-secondary, #6b7280);\n color: white;\n}\n\n.filter-select {\n padding: 8px 12px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n background: var(--input-background, #ffffff);\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n cursor: pointer;\n min-width: 160px;\n}\n\n.results-info {\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n white-space: nowrap;\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(--border-color, #e5e7eb);\n border-radius: 8px;\n background: var(--button-background, #ffffff);\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-icon:hover {\n background: var(--button-hover, #f3f4f6);\n color: var(--accent-color, #6366f1);\n}\n\n/* Layout */\n.types-layout {\n display: grid;\n grid-template-columns: 420px 1fr;\n flex: 1;\n min-height: 0;\n gap: 20px;\n}\n\n/* Types List */\n.types-list {\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n overflow-y: auto;\n padding: 16px;\n}\n\n.category-section {\n margin-bottom: 20px;\n}\n\n.category-section:last-child {\n margin-bottom: 0;\n}\n\n.category-header {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n color: var(--text-secondary, #6b7280);\n letter-spacing: 0.5px;\n border-left: 3px solid var(--accent-color, #6366f1);\n background: var(--header-background, #f9fafb);\n border-radius: 0 8px 8px 0;\n margin-bottom: 8px;\n}\n\n.category-header i {\n font-size: 14px;\n}\n\n.category-name {\n flex: 1;\n}\n\n.category-header .count {\n background: white;\n padding: 2px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n.type-items {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.type-item {\n display: flex;\n align-items: center;\n padding: 12px 14px;\n background: var(--item-background, #ffffff);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n border: 2px solid transparent;\n position: relative;\n}\n\n.type-item:hover {\n background: var(--item-hover, #f8fafc);\n border-color: var(--border-color, #e5e7eb);\n}\n\n.type-item.selected {\n background: linear-gradient(to right, rgba(99, 102, 241, 0.05), white);\n border-color: var(--accent-color, #6366f1);\n}\n\n.type-icon {\n width: 42px;\n height: 42px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.type-icon i {\n font-size: 16px;\n}\n\n.type-info {\n flex: 1;\n min-width: 0;\n}\n\n.type-name {\n font-weight: 600;\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n}\n\n.type-description {\n font-size: 12px;\n color: var(--text-secondary, #9ca3af);\n margin-top: 2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.type-meta {\n display: flex;\n gap: 8px;\n margin-top: 6px;\n}\n\n.meta-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: var(--badge-background, #f3f4f6);\n border-radius: 10px;\n font-size: 11px;\n color: var(--text-secondary, #6b7280);\n}\n\n.meta-badge i {\n font-size: 9px;\n}\n\n.meta-badge.active {\n background: #d1fae5;\n color: #059669;\n}\n\n.meta-badge.warning {\n background: #fef3c7;\n color: #d97706;\n}\n\n.type-actions {\n display: flex;\n gap: 4px;\n margin-right: 8px;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.type-item:hover .type-actions {\n opacity: 1;\n}\n\n.action-btn {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: var(--input-background, #f3f4f6);\n border-radius: 6px;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.2s ease;\n font-size: 12px;\n}\n\n.action-btn:hover {\n background: var(--accent-color, #6366f1);\n color: white;\n}\n\n.action-btn.danger:hover {\n background: #ef4444;\n}\n\n.arrow {\n color: var(--text-tertiary, #d1d5db);\n font-size: 12px;\n}\n\n/* Type Detail */\n.type-detail {\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n overflow-y: auto;\n}\n\n.detail-header {\n display: flex;\n align-items: center;\n padding: 24px;\n border-bottom: 1px solid var(--border-color, #f3f4f6);\n}\n\n.detail-icon {\n width: 60px;\n height: 60px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 14px;\n margin-right: 16px;\n flex-shrink: 0;\n}\n\n.detail-icon i {\n font-size: 26px;\n}\n\n.detail-title {\n flex: 1;\n}\n\n.detail-title h2 {\n font-size: 22px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 8px 0;\n}\n\n.category-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.category-badge i {\n font-size: 11px;\n}\n\n.detail-actions {\n display: flex;\n gap: 8px;\n}\n\n.close-btn {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: var(--button-background, #f3f4f6);\n border-radius: 8px;\n cursor: pointer;\n color: var(--text-secondary, #6b7280);\n transition: all 0.2s ease;\n}\n\n.close-btn:hover {\n background: var(--button-hover, #e5e7eb);\n color: var(--text-primary, #1f2937);\n}\n\n.detail-body {\n padding: 24px;\n}\n\n/* Detail Stats */\n.detail-stats {\n display: flex;\n gap: 16px;\n margin-bottom: 24px;\n padding-bottom: 24px;\n border-bottom: 1px solid var(--border-color, #f3f4f6);\n}\n\n.detail-stat {\n flex: 1;\n text-align: center;\n padding: 16px;\n background: var(--stat-background, #f9fafb);\n border-radius: 12px;\n}\n\n.detail-stat .stat-value {\n font-size: 28px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n}\n\n.detail-stat .stat-label {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n margin-top: 4px;\n}\n\n.detail-stat.active {\n background: linear-gradient(135deg, rgba(16, 185, 129, 0.1) 0%, rgba(5, 150, 105, 0.05) 100%);\n}\n\n.detail-stat.active .stat-value {\n color: #059669;\n}\n\n.detail-stat.warning {\n background: linear-gradient(135deg, rgba(245, 158, 11, 0.1) 0%, rgba(217, 119, 6, 0.05) 100%);\n}\n\n.detail-stat.warning .stat-value {\n color: #d97706;\n}\n\n.description {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n line-height: 1.6;\n margin: 0 0 24px 0;\n padding: 16px;\n background: var(--description-background, #f9fafb);\n border-radius: 10px;\n}\n\n.schema-section,\n.validation-section {\n margin-bottom: 24px;\n}\n\n.schema-section h3,\n.validation-section h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 14px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 16px 0;\n}\n\n.schema-section h3 i,\n.validation-section h3 i {\n color: var(--accent-color, #6366f1);\n}\n\n.field-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.field-item {\n padding: 16px;\n background: var(--field-background, #f9fafb);\n border-radius: 10px;\n border: 1px solid var(--border-color, #e5e7eb);\n transition: all 0.2s ease;\n}\n\n.field-item:hover {\n border-color: var(--accent-color, #6366f1);\n background: var(--field-hover, #f3f4f6);\n}\n\n.field-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.field-name {\n font-weight: 600;\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n}\n\n.field-badges {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.badge {\n padding: 3px 10px;\n border-radius: 6px;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.badge.type {\n background: var(--type-badge, #e5e7eb);\n color: var(--text-secondary, #6b7280);\n}\n\n.badge.secret {\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n color: #b45309;\n}\n\n.badge.secret i {\n margin-right: 3px;\n}\n\n.badge.required {\n background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);\n color: #b91c1c;\n}\n\n.field-description {\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n margin: 10px 0 0 0;\n line-height: 1.5;\n}\n\n.no-fields {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px;\n background: var(--field-background, #f9fafb);\n border-radius: 10px;\n color: var(--text-secondary, #9ca3af);\n font-size: 13px;\n}\n\n.no-fields i {\n color: var(--accent-color, #6366f1);\n}\n\n.validation-endpoint {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 14px 18px;\n background: var(--endpoint-background, #f9fafb);\n border-radius: 10px;\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n font-family: 'SF Mono', 'Monaco', 'Inconsolata', monospace;\n border: 1px solid var(--border-color, #e5e7eb);\n}\n\n.validation-endpoint i {\n color: var(--accent-color, #6366f1);\n}\n\n.detail-quick-actions {\n margin-top: 24px;\n padding-top: 24px;\n border-top: 1px solid var(--border-color, #f3f4f6);\n}\n\n/* No Selection */\n.no-selection {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n text-align: center;\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n padding: 48px;\n}\n\n.no-selection-icon {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #e0e7ff 0%, #c7d2fe 100%);\n border-radius: 20px;\n margin-bottom: 24px;\n}\n\n.no-selection-icon i {\n font-size: 32px;\n color: var(--accent-color, #6366f1);\n}\n\n.no-selection h3 {\n font-size: 18px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 8px 0;\n}\n\n.no-selection p {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n}\n\n.empty-icon {\n width: 72px;\n height: 72px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #e0e7ff 0%, #c7d2fe 100%);\n border-radius: 18px;\n margin-bottom: 20px;\n}\n\n.empty-icon i {\n font-size: 32px;\n color: var(--accent-color, #6366f1);\n}\n\n.empty-state h3 {\n font-size: 18px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 8px 0;\n}\n\n.empty-state p {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0 0 20px 0;\n}\n\n.btn-link {\n background: none;\n border: none;\n color: var(--accent-color, #6366f1);\n font-size: 14px;\n cursor: pointer;\n text-decoration: underline;\n padding: 0;\n}\n\n.btn-link:hover {\n color: var(--accent-hover, #4f46e5);\n}\n\n/* Responsive */\n@media (max-width: 1024px) {\n .types-layout {\n grid-template-columns: 1fr;\n }\n\n .types-list {\n max-height: 400px;\n }\n}\n\n@media (max-width: 768px) {\n .types-container {\n padding: 16px;\n }\n\n .types-header {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .toolbar {\n flex-direction: column;\n align-items: stretch;\n }\n\n .toolbar-left {\n flex-direction: column;\n }\n\n .search-container {\n min-width: 100%;\n }\n\n .filter-select {\n width: 100%;\n }\n\n .toolbar-right {\n justify-content: space-between;\n }\n\n .detail-stats {\n flex-direction: column;\n }\n}\n"] }]
870
+ args: [{ standalone: false, selector: 'mj-credentials-types-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<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", styles: [".types-container {\n height: 100%;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n padding: 24px;\n background: var(--page-background, #f8fafc);\n}\n\n/* Header */\n.types-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n margin-bottom: 24px;\n flex-wrap: wrap;\n gap: 16px;\n}\n\n.header-info {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.types-title {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0;\n}\n\n.header-stats {\n display: flex;\n align-items: center;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.stat-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n}\n\n.stat-item i {\n font-size: 12px;\n}\n\n.header-actions {\n display: flex;\n gap: 12px;\n}\n\n.btn-primary {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);\n color: white;\n border: none;\n border-radius: 10px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n box-shadow: 0 2px 8px rgba(99, 102, 241, 0.3);\n}\n\n.btn-primary:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 16px rgba(99, 102, 241, 0.4);\n}\n\n.btn-primary i {\n font-size: 13px;\n}\n\n/* Toolbar */\n.toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n margin-bottom: 16px;\n flex-wrap: wrap;\n background: var(--card-background, #ffffff);\n padding: 16px;\n border-radius: 12px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n\n.toolbar-left {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n flex: 1;\n}\n\n.toolbar-right {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.search-container {\n display: flex;\n align-items: center;\n background: var(--input-background, #f9fafb);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n padding: 8px 12px;\n min-width: 240px;\n position: relative;\n}\n\n.search-container i {\n color: var(--text-secondary, #6b7280);\n margin-right: 8px;\n}\n\n.search-container input {\n border: none;\n background: transparent;\n outline: none;\n flex: 1;\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n}\n\n.search-clear {\n position: absolute;\n right: 8px;\n top: 50%;\n transform: translateY(-50%);\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--border-color, #e5e7eb);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n color: var(--text-secondary, #6b7280);\n font-size: 10px;\n}\n\n.search-clear:hover {\n background: var(--text-secondary, #6b7280);\n color: white;\n}\n\n.filter-select {\n padding: 8px 12px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n background: var(--input-background, #ffffff);\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n cursor: pointer;\n min-width: 160px;\n}\n\n.results-info {\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n white-space: nowrap;\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(--border-color, #e5e7eb);\n border-radius: 8px;\n background: var(--button-background, #ffffff);\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-icon:hover {\n background: var(--button-hover, #f3f4f6);\n color: var(--accent-color, #6366f1);\n}\n\n/* Layout */\n.types-layout {\n display: grid;\n grid-template-columns: 420px 1fr;\n flex: 1;\n min-height: 0;\n gap: 20px;\n}\n\n/* Types List */\n.types-list {\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n overflow-y: auto;\n padding: 16px;\n}\n\n.category-section {\n margin-bottom: 20px;\n}\n\n.category-section:last-child {\n margin-bottom: 0;\n}\n\n.category-header {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n color: var(--text-secondary, #6b7280);\n letter-spacing: 0.5px;\n border-left: 3px solid var(--accent-color, #6366f1);\n background: var(--header-background, #f9fafb);\n border-radius: 0 8px 8px 0;\n margin-bottom: 8px;\n}\n\n.category-header i {\n font-size: 14px;\n}\n\n.category-name {\n flex: 1;\n}\n\n.category-header .count {\n background: white;\n padding: 2px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n.type-items {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.type-item {\n display: flex;\n align-items: center;\n padding: 12px 14px;\n background: var(--item-background, #ffffff);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n border: 2px solid transparent;\n position: relative;\n}\n\n.type-item:hover {\n background: var(--item-hover, #f8fafc);\n border-color: var(--border-color, #e5e7eb);\n}\n\n.type-item.selected {\n background: linear-gradient(to right, rgba(99, 102, 241, 0.05), white);\n border-color: var(--accent-color, #6366f1);\n}\n\n.type-icon {\n width: 42px;\n height: 42px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.type-icon i {\n font-size: 16px;\n}\n\n.type-info {\n flex: 1;\n min-width: 0;\n}\n\n.type-name {\n font-weight: 600;\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n}\n\n.type-description {\n font-size: 12px;\n color: var(--text-secondary, #9ca3af);\n margin-top: 2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.type-meta {\n display: flex;\n gap: 8px;\n margin-top: 6px;\n}\n\n.meta-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: var(--badge-background, #f3f4f6);\n border-radius: 10px;\n font-size: 11px;\n color: var(--text-secondary, #6b7280);\n}\n\n.meta-badge i {\n font-size: 9px;\n}\n\n.meta-badge.active {\n background: #d1fae5;\n color: #059669;\n}\n\n.meta-badge.warning {\n background: #fef3c7;\n color: #d97706;\n}\n\n.type-actions {\n display: flex;\n gap: 4px;\n margin-right: 8px;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.type-item:hover .type-actions {\n opacity: 1;\n}\n\n.action-btn {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: var(--input-background, #f3f4f6);\n border-radius: 6px;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.2s ease;\n font-size: 12px;\n}\n\n.action-btn:hover {\n background: var(--accent-color, #6366f1);\n color: white;\n}\n\n.action-btn.danger:hover {\n background: #ef4444;\n}\n\n.arrow {\n color: var(--text-tertiary, #d1d5db);\n font-size: 12px;\n}\n\n/* Type Detail */\n.type-detail {\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n overflow-y: auto;\n}\n\n.detail-header {\n display: flex;\n align-items: center;\n padding: 24px;\n border-bottom: 1px solid var(--border-color, #f3f4f6);\n}\n\n.detail-icon {\n width: 60px;\n height: 60px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 14px;\n margin-right: 16px;\n flex-shrink: 0;\n}\n\n.detail-icon i {\n font-size: 26px;\n}\n\n.detail-title {\n flex: 1;\n}\n\n.detail-title h2 {\n font-size: 22px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 8px 0;\n}\n\n.category-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.category-badge i {\n font-size: 11px;\n}\n\n.detail-actions {\n display: flex;\n gap: 8px;\n}\n\n.close-btn {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: var(--button-background, #f3f4f6);\n border-radius: 8px;\n cursor: pointer;\n color: var(--text-secondary, #6b7280);\n transition: all 0.2s ease;\n}\n\n.close-btn:hover {\n background: var(--button-hover, #e5e7eb);\n color: var(--text-primary, #1f2937);\n}\n\n.detail-body {\n padding: 24px;\n}\n\n/* Detail Stats */\n.detail-stats {\n display: flex;\n gap: 16px;\n margin-bottom: 24px;\n padding-bottom: 24px;\n border-bottom: 1px solid var(--border-color, #f3f4f6);\n}\n\n.detail-stat {\n flex: 1;\n text-align: center;\n padding: 16px;\n background: var(--stat-background, #f9fafb);\n border-radius: 12px;\n}\n\n.detail-stat .stat-value {\n font-size: 28px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n}\n\n.detail-stat .stat-label {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n margin-top: 4px;\n}\n\n.detail-stat.active {\n background: linear-gradient(135deg, rgba(16, 185, 129, 0.1) 0%, rgba(5, 150, 105, 0.05) 100%);\n}\n\n.detail-stat.active .stat-value {\n color: #059669;\n}\n\n.detail-stat.warning {\n background: linear-gradient(135deg, rgba(245, 158, 11, 0.1) 0%, rgba(217, 119, 6, 0.05) 100%);\n}\n\n.detail-stat.warning .stat-value {\n color: #d97706;\n}\n\n.description {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n line-height: 1.6;\n margin: 0 0 24px 0;\n padding: 16px;\n background: var(--description-background, #f9fafb);\n border-radius: 10px;\n}\n\n.schema-section,\n.validation-section {\n margin-bottom: 24px;\n}\n\n.schema-section h3,\n.validation-section h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 14px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 16px 0;\n}\n\n.schema-section h3 i,\n.validation-section h3 i {\n color: var(--accent-color, #6366f1);\n}\n\n.field-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.field-item {\n padding: 16px;\n background: var(--field-background, #f9fafb);\n border-radius: 10px;\n border: 1px solid var(--border-color, #e5e7eb);\n transition: all 0.2s ease;\n}\n\n.field-item:hover {\n border-color: var(--accent-color, #6366f1);\n background: var(--field-hover, #f3f4f6);\n}\n\n.field-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.field-name {\n font-weight: 600;\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n}\n\n.field-badges {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.badge {\n padding: 3px 10px;\n border-radius: 6px;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.badge.type {\n background: var(--type-badge, #e5e7eb);\n color: var(--text-secondary, #6b7280);\n}\n\n.badge.secret {\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n color: #b45309;\n}\n\n.badge.secret i {\n margin-right: 3px;\n}\n\n.badge.required {\n background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);\n color: #b91c1c;\n}\n\n.field-description {\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n margin: 10px 0 0 0;\n line-height: 1.5;\n}\n\n.no-fields {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px;\n background: var(--field-background, #f9fafb);\n border-radius: 10px;\n color: var(--text-secondary, #9ca3af);\n font-size: 13px;\n}\n\n.no-fields i {\n color: var(--accent-color, #6366f1);\n}\n\n.validation-endpoint {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 14px 18px;\n background: var(--endpoint-background, #f9fafb);\n border-radius: 10px;\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n font-family: 'SF Mono', 'Monaco', 'Inconsolata', monospace;\n border: 1px solid var(--border-color, #e5e7eb);\n}\n\n.validation-endpoint i {\n color: var(--accent-color, #6366f1);\n}\n\n.detail-quick-actions {\n margin-top: 24px;\n padding-top: 24px;\n border-top: 1px solid var(--border-color, #f3f4f6);\n}\n\n/* No Selection */\n.no-selection {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n text-align: center;\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n padding: 48px;\n}\n\n.no-selection-icon {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #e0e7ff 0%, #c7d2fe 100%);\n border-radius: 20px;\n margin-bottom: 24px;\n}\n\n.no-selection-icon i {\n font-size: 32px;\n color: var(--accent-color, #6366f1);\n}\n\n.no-selection h3 {\n font-size: 18px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 8px 0;\n}\n\n.no-selection p {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n}\n\n.empty-icon {\n width: 72px;\n height: 72px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #e0e7ff 0%, #c7d2fe 100%);\n border-radius: 18px;\n margin-bottom: 20px;\n}\n\n.empty-icon i {\n font-size: 32px;\n color: var(--accent-color, #6366f1);\n}\n\n.empty-state h3 {\n font-size: 18px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 8px 0;\n}\n\n.empty-state p {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0 0 20px 0;\n}\n\n.btn-link {\n background: none;\n border: none;\n color: var(--accent-color, #6366f1);\n font-size: 14px;\n cursor: pointer;\n text-decoration: underline;\n padding: 0;\n}\n\n.btn-link:hover {\n color: var(--accent-hover, #4f46e5);\n}\n\n/* Responsive */\n@media (max-width: 1024px) {\n .types-layout {\n grid-template-columns: 1fr;\n }\n\n .types-list {\n max-height: 400px;\n }\n}\n\n@media (max-width: 768px) {\n .types-container {\n padding: 16px;\n }\n\n .types-header {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .toolbar {\n flex-direction: column;\n align-items: stretch;\n }\n\n .toolbar-left {\n flex-direction: column;\n }\n\n .search-container {\n min-width: 100%;\n }\n\n .filter-select {\n width: 100%;\n }\n\n .toolbar-right {\n justify-content: space-between;\n }\n\n .detail-stats {\n flex-direction: column;\n }\n}\n"] }]
867
871
  }], () => [{ type: i0.ChangeDetectorRef }, { type: i1.NavigationService }], { typeEditPanel: [{
868
872
  type: ViewChild,
869
873
  args: ['typeEditPanel']