@memberjunction/ng-dashboards 3.0.0 → 3.1.1

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 (161) hide show
  1. package/dist/AI/components/agents/agent-configuration.component.js +1 -1
  2. package/dist/AI/components/agents/agent-editor.component.js +1 -1
  3. package/dist/AI/components/agents/agent-filter-panel.component.js +1 -1
  4. package/dist/AI/components/charts/performance-heatmap.component.js +1 -1
  5. package/dist/AI/components/charts/time-series-chart.component.js +1 -1
  6. package/dist/AI/components/execution-monitoring.component.js +1 -1
  7. package/dist/AI/components/models/model-management.component.js +1 -1
  8. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +1 -1
  9. package/dist/AI/components/prompts/prompt-filter-panel.component.js +1 -1
  10. package/dist/AI/components/prompts/prompt-management.component.js +1 -1
  11. package/dist/AI/components/prompts/prompt-version-control.component.js +1 -1
  12. package/dist/AI/components/system/system-config-filter-panel.component.js +1 -1
  13. package/dist/AI/components/system/system-configuration.component.js +1 -1
  14. package/dist/AI/components/widgets/kpi-card.component.js +1 -1
  15. package/dist/AI/components/widgets/live-execution-widget.component.js +1 -1
  16. package/dist/Actions/components/actions-list-view.component.js +1 -1
  17. package/dist/Actions/components/actions-overview.component.js +1 -1
  18. package/dist/Actions/components/categories-list-view.component.js +1 -1
  19. package/dist/Actions/components/code-management.component.js +1 -1
  20. package/dist/Actions/components/entity-integration.component.js +1 -1
  21. package/dist/Actions/components/execution-monitoring.component.js +1 -1
  22. package/dist/Actions/components/executions-list-view.component.js +1 -1
  23. package/dist/Actions/components/scheduled-actions.component.js +1 -1
  24. package/dist/Actions/components/security-permissions.component.js +1 -1
  25. package/dist/Communication/communication-dashboard.component.js +1 -1
  26. package/dist/Communication/communication-logs-resource.component.js +1 -1
  27. package/dist/Communication/communication-monitor-resource.component.js +1 -1
  28. package/dist/Communication/communication-providers-resource.component.js +1 -1
  29. package/dist/Communication/communication-runs-resource.component.js +1 -1
  30. package/dist/ComponentStudio/component-studio-dashboard.component.js +1 -1
  31. package/dist/ComponentStudio/components/artifact-load-dialog.component.js +1 -1
  32. package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +1 -1
  33. package/dist/ComponentStudio/components/text-import-dialog.component.js +1 -1
  34. package/dist/Credentials/components/credential-category-edit-panel.component.js +1 -1
  35. package/dist/Credentials/components/credential-edit-panel.component.js +1 -1
  36. package/dist/Credentials/components/credential-type-edit-panel.component.js +1 -1
  37. package/dist/Credentials/components/credentials-audit-resource.component.js +1 -1
  38. package/dist/Credentials/components/credentials-categories-resource.component.js +1 -1
  39. package/dist/Credentials/components/credentials-list-resource.component.js +1 -1
  40. package/dist/Credentials/components/credentials-overview-resource.component.js +1 -1
  41. package/dist/Credentials/components/credentials-types-resource.component.js +1 -1
  42. package/dist/Credentials/credentials-dashboard.component.js +1 -1
  43. package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts +225 -0
  44. package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -0
  45. package/dist/DashboardBrowser/dashboard-browser-resource.component.js +1038 -0
  46. package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -0
  47. package/dist/DashboardBrowser/dashboard-share-dialog.component.d.ts +116 -0
  48. package/dist/DashboardBrowser/dashboard-share-dialog.component.d.ts.map +1 -0
  49. package/dist/DashboardBrowser/dashboard-share-dialog.component.js +549 -0
  50. package/dist/DashboardBrowser/dashboard-share-dialog.component.js.map +1 -0
  51. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +1 -1
  52. package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +1 -1
  53. package/dist/DataExplorer/components/view-selector/view-selector.component.js +1 -1
  54. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +2 -1
  55. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  56. package/dist/DataExplorer/data-explorer-dashboard.component.js +74 -55
  57. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  58. package/dist/DataExplorer/data-explorer-resource.component.d.ts +38 -0
  59. package/dist/DataExplorer/data-explorer-resource.component.d.ts.map +1 -0
  60. package/dist/DataExplorer/data-explorer-resource.component.js +153 -0
  61. package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -0
  62. package/dist/DataExplorer/index.d.ts +1 -0
  63. package/dist/DataExplorer/index.d.ts.map +1 -1
  64. package/dist/DataExplorer/index.js +2 -0
  65. package/dist/DataExplorer/index.js.map +1 -1
  66. package/dist/EntityAdmin/entity-admin-dashboard.component.js +1 -1
  67. package/dist/Home/home-application.d.ts +53 -0
  68. package/dist/Home/home-application.d.ts.map +1 -0
  69. package/dist/Home/home-application.js +148 -0
  70. package/dist/Home/home-application.js.map +1 -0
  71. package/dist/Home/home-dashboard.component.d.ts +10 -10
  72. package/dist/Home/home-dashboard.component.d.ts.map +1 -1
  73. package/dist/Home/home-dashboard.component.js +43 -41
  74. package/dist/Home/home-dashboard.component.js.map +1 -1
  75. package/dist/Lists/components/lists-browse-resource.component.js +1 -1
  76. package/dist/Lists/components/lists-categories-resource.component.js +1 -1
  77. package/dist/Lists/components/lists-my-lists-resource.component.js +1 -1
  78. package/dist/Lists/components/lists-operations-resource.component.js +1 -1
  79. package/dist/Lists/components/venn-diagram/venn-diagram.component.js +1 -1
  80. package/dist/QueryBrowser/query-browser-resource.component.d.ts +101 -0
  81. package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -0
  82. package/dist/QueryBrowser/query-browser-resource.component.js +662 -0
  83. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -0
  84. package/dist/Scheduling/components/scheduling-health-resource.component.js +1 -1
  85. package/dist/Scheduling/components/scheduling-health.component.js +1 -1
  86. package/dist/Scheduling/components/scheduling-history-resource.component.js +1 -1
  87. package/dist/Scheduling/components/scheduling-history.component.js +1 -1
  88. package/dist/Scheduling/components/scheduling-jobs-resource.component.js +1 -1
  89. package/dist/Scheduling/components/scheduling-jobs.component.js +1 -1
  90. package/dist/Scheduling/components/scheduling-monitor-resource.component.js +1 -1
  91. package/dist/Scheduling/components/scheduling-monitoring.component.js +1 -1
  92. package/dist/Scheduling/components/scheduling-types-resource.component.js +1 -1
  93. package/dist/Scheduling/components/scheduling-types.component.js +1 -1
  94. package/dist/Scheduling/scheduling-dashboard.component.js +1 -1
  95. package/dist/SystemDiagnostics/system-diagnostics.component.d.ts +3 -3
  96. package/dist/SystemDiagnostics/system-diagnostics.component.d.ts.map +1 -1
  97. package/dist/SystemDiagnostics/system-diagnostics.component.js +7 -20
  98. package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
  99. package/dist/Testing/components/testing-analytics-resource.component.js +1 -1
  100. package/dist/Testing/components/testing-analytics.component.js +1 -1
  101. package/dist/Testing/components/testing-execution-resource.component.js +1 -1
  102. package/dist/Testing/components/testing-execution.component.js +1 -1
  103. package/dist/Testing/components/testing-feedback-resource.component.js +1 -1
  104. package/dist/Testing/components/testing-feedback.component.js +1 -1
  105. package/dist/Testing/components/testing-overview-resource.component.js +1 -1
  106. package/dist/Testing/components/testing-overview.component.js +1 -1
  107. package/dist/Testing/components/testing-version-comparison.component.js +1 -1
  108. package/dist/Testing/components/testing-version-resource.component.js +1 -1
  109. package/dist/Testing/components/widgets/oracle-breakdown-table.component.js +1 -1
  110. package/dist/Testing/components/widgets/suite-tree.component.js +2 -2
  111. package/dist/Testing/components/widgets/test-run-detail-panel.component.js +1 -1
  112. package/dist/Testing/testing-dashboard.component.js +1 -1
  113. package/dist/module.d.ts +61 -55
  114. package/dist/module.d.ts.map +1 -1
  115. package/dist/module.js +49 -9
  116. package/dist/module.js.map +1 -1
  117. package/dist/public-api.d.ts +5 -0
  118. package/dist/public-api.d.ts.map +1 -1
  119. package/dist/public-api.js +25 -1
  120. package/dist/public-api.js.map +1 -1
  121. package/package.json +32 -30
  122. package/dist/AI/ai-dashboard.component.d.ts +0 -62
  123. package/dist/AI/ai-dashboard.component.d.ts.map +0 -1
  124. package/dist/AI/ai-dashboard.component.js +0 -338
  125. package/dist/AI/ai-dashboard.component.js.map +0 -1
  126. package/dist/AI/components/models/model-management-v2.component.d.ts +0 -96
  127. package/dist/AI/components/models/model-management-v2.component.d.ts.map +0 -1
  128. package/dist/AI/components/models/model-management-v2.component.js +0 -981
  129. package/dist/AI/components/models/model-management-v2.component.js.map +0 -1
  130. package/dist/AI/components/prompts/prompt-management-v2.component.d.ts +0 -97
  131. package/dist/AI/components/prompts/prompt-management-v2.component.d.ts.map +0 -1
  132. package/dist/AI/components/prompts/prompt-management-v2.component.js +0 -811
  133. package/dist/AI/components/prompts/prompt-management-v2.component.js.map +0 -1
  134. package/dist/Actions/actions-management-dashboard.component.d.ts +0 -52
  135. package/dist/Actions/actions-management-dashboard.component.d.ts.map +0 -1
  136. package/dist/Actions/actions-management-dashboard.component.js +0 -308
  137. package/dist/Actions/actions-management-dashboard.component.js.map +0 -1
  138. package/dist/DataExplorer/components/view-config-panel/view-config-panel.component.d.ts +0 -245
  139. package/dist/DataExplorer/components/view-config-panel/view-config-panel.component.d.ts.map +0 -1
  140. package/dist/DataExplorer/components/view-config-panel/view-config-panel.component.js +0 -1143
  141. package/dist/DataExplorer/components/view-config-panel/view-config-panel.component.js.map +0 -1
  142. package/dist/EntityAdmin/components/entity-details.component.d.ts +0 -50
  143. package/dist/EntityAdmin/components/entity-details.component.d.ts.map +0 -1
  144. package/dist/EntityAdmin/components/entity-details.component.js +0 -680
  145. package/dist/EntityAdmin/components/entity-details.component.js.map +0 -1
  146. package/dist/EntityAdmin/components/entity-filter-panel.component.d.ts +0 -31
  147. package/dist/EntityAdmin/components/entity-filter-panel.component.d.ts.map +0 -1
  148. package/dist/EntityAdmin/components/entity-filter-panel.component.js +0 -160
  149. package/dist/EntityAdmin/components/entity-filter-panel.component.js.map +0 -1
  150. package/dist/EntityAdmin/components/erd-composite.component.d.ts +0 -73
  151. package/dist/EntityAdmin/components/erd-composite.component.d.ts.map +0 -1
  152. package/dist/EntityAdmin/components/erd-composite.component.js +0 -271
  153. package/dist/EntityAdmin/components/erd-composite.component.js.map +0 -1
  154. package/dist/EntityAdmin/components/erd-diagram.component.d.ts +0 -47
  155. package/dist/EntityAdmin/components/erd-diagram.component.d.ts.map +0 -1
  156. package/dist/EntityAdmin/components/erd-diagram.component.js +0 -618
  157. package/dist/EntityAdmin/components/erd-diagram.component.js.map +0 -1
  158. package/dist/generic/base-dashboard.d.ts +0 -65
  159. package/dist/generic/base-dashboard.d.ts.map +0 -1
  160. package/dist/generic/base-dashboard.js +0 -74
  161. package/dist/generic/base-dashboard.js.map +0 -1
@@ -606,5 +606,5 @@ export class ArtifactSelectionDialogComponent {
606
606
  type: Component,
607
607
  args: [{ selector: 'app-artifact-selection-dialog', template: "<div>\n <kendo-dialog-titlebar (close)=\"cancel()\">\n <div style=\"font-size: 18px;\">\n <i class=\"fa-solid fa-save\"></i> Save Component to Artifact\n </div>\n </kendo-dialog-titlebar>\n\n <div class=\"artifact-selection-content\">\n <!-- Left Filter Panel -->\n <div class=\"filter-panel\" [style.width]=\"isFilterPanelCollapsed ? '40px' : '280px'\">\n <!-- Panel Header -->\n <div class=\"panel-header\">\n @if (!isFilterPanelCollapsed) {\n <span>Filters</span>\n }\n <button kendoButton (click)=\"toggleFilterPanel()\" \n [fillMode]=\"'flat'\"\n [class.filter-active]=\"getActiveFilterCount() > 0\"\n [themeColor]=\"getActiveFilterCount() > 0 ? 'primary' : 'base'\">\n <i class=\"fa-solid fa-filter\"></i>\n @if (isFilterPanelCollapsed && getActiveFilterCount() > 0) {\n <span class=\"filter-count\">{{ getActiveFilterCount() }}</span>\n }\n </button>\n </div>\n\n @if (!isFilterPanelCollapsed) {\n <div class=\"filter-content\">\n <!-- Search -->\n <div class=\"filter-group\">\n <label>Search</label>\n <input type=\"text\" \n [(ngModel)]=\"searchTerm\"\n (input)=\"onSearchInput()\"\n placeholder=\"Name or description...\"\n class=\"filter-input\">\n </div>\n\n <!-- Artifact Type -->\n <div class=\"filter-group\">\n <label>Artifact Type</label>\n <select [(ngModel)]=\"selectedArtifactType\" \n (change)=\"onArtifactTypeChange()\"\n class=\"filter-select\">\n <option value=\"\">All Types</option>\n <option value=\"Component\">Component</option>\n <option value=\"Report\">Report</option>\n <option value=\"Dashboard\">Dashboard</option>\n </select>\n </div>\n \n <!-- User Email -->\n <div class=\"filter-group\">\n <label>Filter by User</label>\n <input type=\"text\" \n [(ngModel)]=\"userEmail\"\n (input)=\"filterArtifacts()\"\n placeholder=\"Enter user email...\"\n class=\"filter-input\">\n </div>\n </div>\n }\n </div>\n\n <!-- Main Content Area -->\n <div class=\"main-content\">\n <!-- Paging Controls -->\n <div class=\"paging-controls\">\n <button kendoButton \n (click)=\"previousPage()\" \n [disabled]=\"!canGoPrevious()\"\n [themeColor]=\"'base'\">\n <i class=\"fa-solid fa-chevron-left\"></i> Previous\n </button>\n <span class=\"page-info\">\n Page {{ currentPage + 1 }} of {{ getTotalPages() }}\n ({{ totalArtifacts }} total items)\n </span>\n <button kendoButton \n (click)=\"nextPage()\" \n [disabled]=\"!canGoNext()\"\n [themeColor]=\"'base'\">\n Next <i class=\"fa-solid fa-chevron-right\"></i>\n </button>\n </div>\n\n <!-- Existing Artifacts -->\n <div class=\"artifacts-list\">\n @if (isLoading) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading artifacts...\" size=\"small\"></mj-loading>\n </div>\n } \n @else if (artifacts.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-inbox\"></i>\n <p>No artifacts found</p>\n </div>\n } \n @else {\n @for (artifact of artifacts; track artifact.ID) {\n <div class=\"artifact-item\" \n [class.selected]=\"selectedArtifact?.ID === artifact.ID\"\n (click)=\"selectArtifact(artifact)\">\n <div class=\"artifact-content\">\n <div class=\"artifact-main\">\n <div class=\"artifact-name\">\n <i class=\"fa-solid fa-file-code\"></i>\n <span>{{ artifact.Name }}</span>\n </div>\n @if (artifact.Description) {\n <div class=\"artifact-description\">\n {{ artifact.Description }}\n </div>\n }\n </div>\n <div class=\"artifact-meta\">\n <div>{{ artifact.Type }}</div>\n <div>{{ artifact.__mj_UpdatedAt | date:'short' }}</div>\n </div>\n </div>\n </div>\n }\n }\n </div>\n \n <!-- Create New Artifact Section (at bottom) -->\n <div class=\"create-section\">\n <div class=\"divider\">OR CREATE NEW ARTIFACT</div>\n \n <button kendoButton \n (click)=\"selectCreateNew()\"\n [themeColor]=\"'primary'\"\n class=\"create-btn\">\n <i class=\"fa-solid fa-plus\"></i> Create New Artifact\n </button>\n \n @if (showNewArtifactForm) {\n <div class=\"new-artifact-form\">\n <kendo-textbox \n [(value)]=\"newArtifactName\"\n placeholder=\"Artifact name...\">\n </kendo-textbox>\n <kendo-textarea \n [(value)]=\"newArtifactDescription\"\n placeholder=\"Description (optional)...\">\n </kendo-textarea>\n </div>\n }\n </div>\n </div>\n\n <!-- Right Version Panel (only show when artifact selected) -->\n @if (selectedArtifact) {\n <div class=\"version-panel\">\n <div class=\"panel-header\">\n <h4><i class=\"fa-solid fa-code-branch\"></i> Version</h4>\n </div>\n \n @if (artifactVersions.length > 0) {\n <div class=\"version-content\">\n <div class=\"version-actions\">\n <label>Action</label>\n <label class=\"radio-label\">\n <input type=\"radio\" \n name=\"versionAction\" \n value=\"new\"\n [(ngModel)]=\"versionAction\"\n (change)=\"selectedVersion = null\">\n <span>Create New Version (v{{ getNextVersionNumber() }})</span>\n </label>\n \n <label class=\"radio-label\">\n <input type=\"radio\" \n name=\"versionAction\" \n value=\"update\"\n [(ngModel)]=\"versionAction\">\n <span>Update Existing Version</span>\n </label>\n </div>\n \n @if (versionAction === 'update') {\n <div class=\"version-selection\">\n <label>Select Version</label>\n @for (version of artifactVersions; track version.ID) {\n <label class=\"version-item\" \n [class.selected]=\"selectedVersion?.ID === version.ID\">\n <input type=\"radio\"\n name=\"selectedVersion\"\n [value]=\"version\"\n [(ngModel)]=\"selectedVersion\">\n <div class=\"version-info\">\n <div class=\"version-number\">Version {{ version.VersionNumber }}</div>\n <div class=\"version-date\">{{ version.__mj_UpdatedAt | date:'short' }}</div>\n </div>\n </label>\n }\n </div>\n \n @if (selectedVersion) {\n <div class=\"warning\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>Warning: This will overwrite version {{ selectedVersion.VersionNumber }}</span>\n </div>\n }\n }\n </div>\n } @else {\n <div class=\"info-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <p>No versions available for this artifact.</p>\n <p>A new version will be created.</p>\n </div>\n }\n </div>\n }\n </div>\n\n <kendo-dialog-actions>\n <button kendoButton \n [themeColor]=\"versionAction === 'update' && selectedVersion ? 'warning' : 'primary'\" \n (click)=\"save()\"\n [disabled]=\"!canSave()\">\n <i class=\"fa-solid fa-save\"></i> \n {{ getSaveButtonText() }}\n </button>\n <button kendoButton (click)=\"cancel()\">Cancel</button>\n </kendo-dialog-actions>\n</div>\n", styles: ["/* Main container */\n.artifact-selection-content {\n height: 100%;\n display: flex;\n flex-direction: row;\n}\n\n/* Filter Panel */\n.filter-panel {\n height: 100%;\n display: flex;\n flex-direction: column;\n border-right: 1px solid #ddd;\n transition: width 0.3s ease;\n flex-shrink: 0;\n background: #fafafa;\n}\n\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px;\n border-bottom: 1px solid #eee;\n font-weight: bold;\n color: #666;\n}\n\n.filter-content {\n flex: 1;\n padding: 15px;\n overflow-y: auto;\n}\n\n.filter-group {\n margin-bottom: 15px;\n}\n\n.filter-group label {\n display: block;\n margin-bottom: 5px;\n font-weight: 500;\n color: #555;\n}\n\n.filter-input,\n.filter-select {\n width: 100%;\n padding: 8px;\n border: 1px solid #ccc;\n border-radius: 4px;\n font-size: 14px;\n}\n\n.filter-input:focus,\n.filter-select:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 3px rgba(33, 150, 243, 0.3);\n}\n\n/* Main Content Panel */\n.main-content {\n height: 100%;\n display: flex;\n flex-direction: column;\n flex: 2;\n min-width: 0; /* Prevents flex item from growing beyond container */\n}\n\n.paging-controls {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 10px 15px;\n border-bottom: 1px solid #eee;\n}\n\n.page-info {\n color: #666;\n font-size: 14px;\n}\n\n.artifacts-list {\n flex: 1;\n overflow-y: auto;\n padding: 0 15px;\n}\n\n.loading-state,\n.empty-state {\n text-align: center;\n padding: 40px;\n color: #666;\n}\n\n.empty-state i {\n font-size: 48px;\n margin-bottom: 15px;\n color: #999;\n}\n\n.create-section {\n padding: 15px;\n border-top: 1px solid #eee;\n}\n\n.create-btn {\n width: 100%;\n}\n\n.new-artifact-form {\n margin-top: 15px;\n}\n\n.new-artifact-form kendo-textbox {\n width: 100%;\n margin-bottom: 10px;\n}\n\n.new-artifact-form kendo-textarea {\n width: 100%;\n height: 60px;\n}\n\n.divider {\n text-align: center;\n padding: 10px;\n background: #f8f9fa;\n color: #666;\n font-size: 12px;\n margin-bottom: 10px;\n}\n\n.artifact-item {\n border: 1px solid #ddd;\n border-radius: 6px;\n margin: 10px 0;\n padding: 15px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.artifact-item:hover {\n border-color: #2196f3;\n background: #fafafa;\n}\n\n.artifact-item.selected {\n border-color: #2196f3;\n background: #e8f4f8;\n}\n\n.artifact-content {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n}\n\n.artifact-main {\n flex: 1;\n}\n\n.artifact-name {\n display: flex;\n align-items: center;\n margin-bottom: 5px;\n}\n\n.artifact-name i {\n color: #666;\n margin-right: 8px;\n}\n\n.artifact-name span {\n font-weight: 600;\n color: #333;\n}\n\n.artifact-description {\n color: #666;\n font-size: 14px;\n margin-bottom: 8px;\n}\n\n.artifact-meta {\n text-align: right;\n color: #999;\n font-size: 12px;\n}\n\n/* Version Panel */\n.version-panel {\n width: 320px;\n height: 100%;\n display: flex;\n flex-direction: column;\n border-left: 1px solid #ddd;\n flex-shrink: 0;\n background: #fafafa;\n}\n\n.version-content {\n flex: 1;\n padding: 15px;\n overflow-y: auto;\n}\n\n.version-actions {\n margin-bottom: 20px;\n}\n\n.version-actions label:first-child {\n display: block;\n margin-bottom: 10px;\n font-weight: 500;\n color: #555;\n}\n\n.radio-label {\n display: flex;\n align-items: center;\n margin-bottom: 8px;\n cursor: pointer;\n}\n\n.radio-label input {\n margin-right: 8px;\n}\n\n.version-selection {\n margin-bottom: 15px;\n}\n\n.version-selection > label:first-child {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #555;\n}\n\n.version-item {\n display: flex;\n align-items: center;\n margin-bottom: 8px;\n padding: 8px;\n border: 1px solid #eee;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.version-item.selected {\n background: #f0f8ff;\n}\n\n.version-item input {\n margin-right: 8px;\n}\n\n.version-info {\n flex: 1;\n}\n\n.version-number {\n font-weight: 500;\n}\n\n.version-date {\n font-size: 12px;\n color: #666;\n}\n\n.warning {\n background: #fff3cd;\n border: 1px solid #ffeaa7;\n border-radius: 4px;\n padding: 10px;\n}\n\n.warning i {\n color: #856404;\n margin-right: 5px;\n}\n\n.warning span {\n color: #856404;\n font-size: 14px;\n}\n\n.info-state,\n.empty-state {\n padding: 15px;\n text-align: center;\n color: #666;\n}\n\n.info-state i,\n.empty-state i {\n margin-bottom: 10px;\n font-size: 24px;\n}\n\n.info-state p,\n.empty-state p {\n margin: 5px 0;\n}\n\n.info-state p:last-child {\n font-size: 14px;\n}\n\n/* Filter button styling */\n.filter-count {\n background: #fff;\n color: #2196f3;\n border-radius: 50%;\n min-width: 18px;\n height: 18px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n font-weight: bold;\n margin-left: 4px;\n}\n\n.filter-active .filter-count {\n background: #fff;\n color: #2196f3;\n}"] }]
608
608
  }], () => [{ type: i1.DialogRef }, { type: i2.MJNotificationService }], null); })();
609
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ArtifactSelectionDialogComponent, { className: "ArtifactSelectionDialogComponent" }); })();
609
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ArtifactSelectionDialogComponent, { className: "ArtifactSelectionDialogComponent", filePath: "src/ComponentStudio/components/artifact-selection-dialog.component.ts", lineNumber: 20 }); })();
610
610
  //# sourceMappingURL=artifact-selection-dialog.component.js.map
@@ -117,5 +117,5 @@ export class TextImportDialogComponent {
117
117
  }], cancelDialog: [{
118
118
  type: Output
119
119
  }] }); })();
120
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TextImportDialogComponent, { className: "TextImportDialogComponent" }); })();
120
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TextImportDialogComponent, { className: "TextImportDialogComponent", filePath: "src/ComponentStudio/components/text-import-dialog.component.ts", lineNumber: 96 }); })();
121
121
  //# sourceMappingURL=text-import-dialog.component.js.map
@@ -452,5 +452,5 @@ export class CredentialCategoryEditPanelComponent {
452
452
  }], deleted: [{
453
453
  type: Output
454
454
  }] }); })();
455
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialCategoryEditPanelComponent, { className: "CredentialCategoryEditPanelComponent" }); })();
455
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialCategoryEditPanelComponent, { className: "CredentialCategoryEditPanelComponent", filePath: "src/Credentials/components/credential-category-edit-panel.component.ts", lineNumber: 16 }); })();
456
456
  //# sourceMappingURL=credential-category-edit-panel.component.js.map
@@ -690,5 +690,5 @@ export class CredentialEditPanelComponent {
690
690
  }], deleted: [{
691
691
  type: Output
692
692
  }] }); })();
693
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialEditPanelComponent, { className: "CredentialEditPanelComponent" }); })();
693
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialEditPanelComponent, { className: "CredentialEditPanelComponent", filePath: "src/Credentials/components/credential-edit-panel.component.ts", lineNumber: 30 }); })();
694
694
  //# sourceMappingURL=credential-edit-panel.component.js.map
@@ -559,5 +559,5 @@ export class CredentialTypeEditPanelComponent {
559
559
  }], deleted: [{
560
560
  type: Output
561
561
  }] }); })();
562
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialTypeEditPanelComponent, { className: "CredentialTypeEditPanelComponent" }); })();
562
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialTypeEditPanelComponent, { className: "CredentialTypeEditPanelComponent", filePath: "src/Credentials/components/credential-type-edit-panel.component.ts", lineNumber: 28 }); })();
563
563
  //# sourceMappingURL=credential-type-edit-panel.component.js.map
@@ -860,5 +860,5 @@ export { CredentialsAuditResourceComponent };
860
860
  type: Component,
861
861
  args: [{ selector: 'mj-credentials-audit-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"audit-container\">\n <mj-loading *ngIf=\"isLoading\" text=\"Loading audit logs...\"></mj-loading>\n\n <ng-container *ngIf=\"!isLoading\">\n <!-- Header -->\n <div class=\"audit-header\">\n <div class=\"header-info\">\n <h2 class=\"audit-title\">Audit Trail</h2>\n <p class=\"audit-subtitle\">Credential access and modification history</p>\n </div>\n <div class=\"header-actions\">\n <button class=\"btn-secondary\" (click)=\"exportToCSV()\" title=\"Export to CSV\">\n <i class=\"fa-solid fa-download\"></i>\n <span>Export</span>\n </button>\n <button class=\"btn-icon\" (click)=\"refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n </div>\n </div>\n\n <!-- Stats Cards -->\n <div class=\"stats-grid\">\n <div class=\"stat-card\">\n <div class=\"stat-icon total\">\n <i class=\"fa-solid fa-clipboard-list\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{auditLogs.length}}</div>\n <div class=\"stat-label\">Total Events</div>\n </div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon success\">\n <i class=\"fa-solid fa-check-circle\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value success\">{{getSuccessCount()}}</div>\n <div class=\"stat-label\">Successful</div>\n </div>\n <div class=\"stat-rate\">{{getSuccessRate()}}%</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon failed\">\n <i class=\"fa-solid fa-times-circle\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value failed\">{{getFailedCount()}}</div>\n <div class=\"stat-label\">Failed</div>\n </div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon users\">\n <i class=\"fa-solid fa-users\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{getUniqueUserCount()}}</div>\n <div class=\"stat-label\">Unique Users</div>\n </div>\n </div>\n </div>\n\n <!-- Activity Chart -->\n <div class=\"activity-chart\" *ngIf=\"hourlyData.length > 0\">\n <div class=\"chart-header\">\n <h3>\n <i class=\"fa-solid fa-chart-bar\"></i>\n Today's Activity\n </h3>\n </div>\n <div class=\"chart-container\">\n <div class=\"chart-bars\">\n <div\n class=\"chart-bar-wrapper\"\n *ngFor=\"let data of hourlyData\"\n [title]=\"data.hour + ': ' + (data.success + data.failed) + ' events'\"\n >\n <div class=\"chart-bar\">\n <div\n class=\"bar-segment success\"\n [style.height.%]=\"(data.success / getMaxHourlyCount()) * 100\"\n ></div>\n <div\n class=\"bar-segment failed\"\n [style.height.%]=\"(data.failed / getMaxHourlyCount()) * 100\"\n ></div>\n </div>\n <span class=\"chart-label\">{{data.hour.split(':')[0]}}</span>\n </div>\n </div>\n </div>\n <div class=\"chart-legend\">\n <span class=\"legend-item\">\n <span class=\"legend-color success\"></span>\n Success\n </span>\n <span class=\"legend-item\">\n <span class=\"legend-color failed\"></span>\n Failed\n </span>\n </div>\n </div>\n\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 logs...\"\n [value]=\"searchText\"\n (input)=\"onSearchChange($any($event.target).value)\"\n />\n <button class=\"search-clear\" *ngIf=\"searchText\" (click)=\"clearSearch()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <select\n class=\"filter-select\"\n [value]=\"selectedStatus\"\n (change)=\"onStatusFilterChange($any($event.target).value)\"\n >\n <option value=\"\">All Statuses</option>\n <option value=\"Success\">Success</option>\n <option value=\"Failed\">Failed</option>\n </select>\n\n <select\n class=\"filter-select\"\n [value]=\"selectedOperation\"\n (change)=\"onOperationFilterChange($any($event.target).value)\"\n >\n <option value=\"\">All Operations</option>\n <option *ngFor=\"let op of getOperationList()\" [value]=\"op\">{{op}}</option>\n </select>\n\n <select\n class=\"filter-select\"\n [value]=\"dateRange\"\n (change)=\"onDateRangeChange($any($event.target).value)\"\n >\n <option value=\"1\">Last 24 hours</option>\n <option value=\"7\">Last 7 days</option>\n <option value=\"30\">Last 30 days</option>\n <option value=\"90\">Last 90 days</option>\n </select>\n </div>\n\n <div class=\"toolbar-right\">\n <div class=\"results-info\">\n {{filteredLogs.length}} of {{auditLogs.length}} events\n </div>\n <div class=\"view-toggle\">\n <button\n class=\"toggle-btn\"\n [class.active]=\"viewMode === 'timeline'\"\n (click)=\"setViewMode('timeline')\"\n title=\"Timeline View\"\n >\n <i class=\"fa-solid fa-timeline\"></i>\n </button>\n <button\n class=\"toggle-btn\"\n [class.active]=\"viewMode === 'table'\"\n (click)=\"setViewMode('table')\"\n title=\"Table View\"\n >\n <i class=\"fa-solid fa-table\"></i>\n </button>\n </div>\n </div>\n </div>\n\n <!-- Timeline View -->\n <div class=\"timeline-container\" *ngIf=\"viewMode === 'timeline' && timelineGroups.length > 0\">\n <div class=\"timeline-group\" *ngFor=\"let group of timelineGroups\">\n <div class=\"timeline-date\">\n <span class=\"date-label\">{{group.displayDate}}</span>\n <span class=\"date-count\">{{group.logs.length}} events</span>\n </div>\n <div class=\"timeline-items\">\n <div\n class=\"timeline-item\"\n *ngFor=\"let log of group.logs\"\n [class.expanded]=\"expandedLogId === log.ID\"\n [class.failed]=\"log.Status === 'Failed'\"\n >\n <div class=\"timeline-line\">\n <div\n class=\"timeline-dot\"\n [style.backgroundColor]=\"getOperationColor(getOperationType(log))\"\n ></div>\n </div>\n <div class=\"timeline-content\" (click)=\"toggleLogExpand(log.ID)\">\n <div class=\"timeline-header\">\n <div class=\"timeline-operation\">\n <i [class]=\"getOperationIcon(getOperationType(log))\" [style.color]=\"getOperationColor(getOperationType(log))\"></i>\n <span class=\"operation-name\">{{getOperationType(log)}}</span>\n </div>\n <div class=\"timeline-time\">{{formatTime(log.__mj_CreatedAt)}}</div>\n </div>\n <div class=\"timeline-body\">\n <div class=\"timeline-user\">\n <i class=\"fa-solid fa-user\"></i>\n {{log.User || 'Unknown'}}\n </div>\n <div class=\"timeline-description\" *ngIf=\"log.Description\">\n {{log.Description}}\n </div>\n <div class=\"timeline-badges\">\n <span class=\"status-badge\" [ngClass]=\"getStatusClass(log.Status)\">\n <i [class]=\"log.Status === 'Success' ? 'fa-solid fa-check' : 'fa-solid fa-times'\"></i>\n {{log.Status}}\n </span>\n <span class=\"subsystem-badge\" *ngIf=\"getSubsystem(log)\">\n {{getSubsystem(log)}}\n </span>\n <span class=\"type-badge\" *ngIf=\"log.parsedDetails?.credentialType\">\n <i class=\"fa-solid fa-key\"></i>\n {{log.parsedDetails?.credentialType}}\n </span>\n </div>\n </div>\n <div class=\"timeline-details\" *ngIf=\"expandedLogId === log.ID\">\n <div class=\"detail-grid\">\n <div class=\"detail-item\" *ngIf=\"log.parsedDetails?.ipAddress\">\n <span class=\"detail-label\">IP Address</span>\n <span class=\"detail-value\">{{log.parsedDetails?.ipAddress}}</span>\n </div>\n <div class=\"detail-item\" *ngIf=\"log.parsedDetails?.duration\">\n <span class=\"detail-label\">Duration</span>\n <span class=\"detail-value\">{{formatDuration(log.parsedDetails?.duration)}}</span>\n </div>\n <div class=\"detail-item\" *ngIf=\"log.parsedDetails?.credentialId\">\n <span class=\"detail-label\">Credential ID</span>\n <span class=\"detail-value mono\">{{log.parsedDetails?.credentialId}}</span>\n </div>\n <div class=\"detail-item full-width\" *ngIf=\"log.parsedDetails?.errorMessage\">\n <span class=\"detail-label\">Error Message</span>\n <span class=\"detail-value error\">{{log.parsedDetails?.errorMessage}}</span>\n </div>\n <div class=\"detail-item full-width\" *ngIf=\"log.parsedDetails?.userAgent\">\n <span class=\"detail-label\">User Agent</span>\n <span class=\"detail-value mono small\">{{log.parsedDetails?.userAgent}}</span>\n </div>\n </div>\n </div>\n <button class=\"expand-btn\">\n <i [class]=\"expandedLogId === log.ID ? 'fa-solid fa-chevron-up' : 'fa-solid fa-chevron-down'\"></i>\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Table View -->\n <div class=\"audit-table-container\" *ngIf=\"viewMode === 'table' && filteredLogs.length > 0\">\n <table class=\"audit-table\">\n <thead>\n <tr>\n <th>Timestamp</th>\n <th>User</th>\n <th>Operation</th>\n <th>Description</th>\n <th>Subsystem</th>\n <th>Status</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let log of filteredLogs\" [class.failed-row]=\"log.Status === 'Failed'\">\n <td class=\"timestamp\">{{formatDate(log.__mj_CreatedAt)}}</td>\n <td class=\"user\">{{log.User || 'Unknown'}}</td>\n <td class=\"operation\">\n <span class=\"operation-badge\" [style.backgroundColor]=\"getOperationColor(getOperationType(log)) + '20'\" [style.color]=\"getOperationColor(getOperationType(log))\">\n <i [class]=\"getOperationIcon(getOperationType(log))\"></i>\n {{getOperationType(log)}}\n </span>\n </td>\n <td class=\"description\">{{log.Description || '-'}}</td>\n <td class=\"subsystem\">{{getSubsystem(log) || '-'}}</td>\n <td class=\"status\">\n <span class=\"status-badge\" [ngClass]=\"getStatusClass(log.Status)\">\n <i [class]=\"log.Status === 'Success' ? 'fa-solid fa-check' : 'fa-solid fa-times'\"></i>\n {{log.Status}}\n </span>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <!-- Empty State -->\n <div class=\"empty-state\" *ngIf=\"filteredLogs.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-clipboard-list\"></i>\n </div>\n <h3>No Audit Logs</h3>\n <p *ngIf=\"searchText || selectedStatus || selectedOperation\">\n No events match your current filters.\n <button class=\"btn-link\" (click)=\"searchText = ''; selectedStatus = ''; selectedOperation = ''; applyFilters()\">Clear filters</button>\n </p>\n <p *ngIf=\"!searchText && !selectedStatus && !selectedOperation\">\n No credential access events in the selected time range.\n </p>\n </div>\n </ng-container>\n</div>\n", styles: [".audit-container {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n background: var(--background-secondary, #f8fafc);\n}\n\n/* Header */\n.audit-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n margin-bottom: 24px;\n}\n\n.header-info {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.audit-title {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0;\n}\n\n.audit-subtitle {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n}\n\n.btn-secondary {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n font-size: 13px;\n font-weight: 500;\n color: var(--text-primary, #374151);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-secondary:hover {\n background: var(--hover-background, #f9fafb);\n border-color: var(--accent-color, #6366f1);\n color: var(--accent-color, #6366f1);\n}\n\n.btn-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-icon:hover {\n background: var(--hover-background, #f9fafb);\n color: var(--accent-color, #6366f1);\n}\n\n/* Stats Grid */\n.stats-grid {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.stat-card {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 20px;\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n position: relative;\n}\n\n.stat-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 12px;\n flex-shrink: 0;\n}\n\n.stat-icon.total {\n background: rgba(99, 102, 241, 0.1);\n color: #6366f1;\n}\n\n.stat-icon.success {\n background: rgba(16, 185, 129, 0.1);\n color: #10b981;\n}\n\n.stat-icon.failed {\n background: rgba(239, 68, 68, 0.1);\n color: #ef4444;\n}\n\n.stat-icon.users {\n background: rgba(139, 92, 246, 0.1);\n color: #8b5cf6;\n}\n\n.stat-icon i {\n font-size: 20px;\n}\n\n.stat-content {\n flex: 1;\n}\n\n.stat-value {\n font-size: 28px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n line-height: 1;\n}\n\n.stat-value.success {\n color: #10b981;\n}\n\n.stat-value.failed {\n color: #ef4444;\n}\n\n.stat-label {\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n margin-top: 4px;\n}\n\n.stat-rate {\n position: absolute;\n top: 12px;\n right: 16px;\n font-size: 12px;\n font-weight: 600;\n color: #10b981;\n background: rgba(16, 185, 129, 0.1);\n padding: 4px 8px;\n border-radius: 8px;\n}\n\n/* Activity Chart */\n.activity-chart {\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n padding: 20px;\n margin-bottom: 20px;\n}\n\n.chart-header {\n margin-bottom: 16px;\n}\n\n.chart-header h3 {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin: 0;\n}\n\n.chart-header h3 i {\n color: var(--accent-color, #6366f1);\n}\n\n.chart-container {\n height: 120px;\n padding: 0 4px;\n}\n\n.chart-bars {\n display: flex;\n align-items: flex-end;\n height: 100%;\n gap: 2px;\n}\n\n.chart-bar-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n height: 100%;\n}\n\n.chart-bar {\n flex: 1;\n width: 100%;\n max-width: 24px;\n display: flex;\n flex-direction: column-reverse;\n border-radius: 4px 4px 0 0;\n overflow: hidden;\n background: var(--bar-background, #f3f4f6);\n}\n\n.bar-segment {\n width: 100%;\n transition: height 0.3s ease;\n}\n\n.bar-segment.success {\n background: linear-gradient(180deg, #10b981 0%, #059669 100%);\n}\n\n.bar-segment.failed {\n background: linear-gradient(180deg, #ef4444 0%, #dc2626 100%);\n}\n\n.chart-label {\n font-size: 10px;\n color: var(--text-secondary, #9ca3af);\n margin-top: 4px;\n}\n\n.chart-legend {\n display: flex;\n justify-content: center;\n gap: 24px;\n margin-top: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--border-color, #f3f4f6);\n}\n\n.legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n.legend-color {\n width: 12px;\n height: 12px;\n border-radius: 3px;\n}\n\n.legend-color.success {\n background: #10b981;\n}\n\n.legend-color.failed {\n background: #ef4444;\n}\n\n/* Toolbar */\n.toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n margin-bottom: 20px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.toolbar-left {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.toolbar-right {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n/* Search */\n.search-container {\n position: relative;\n min-width: 200px;\n}\n\n.search-container i.fa-search {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--text-secondary, #9ca3af);\n font-size: 13px;\n}\n\n.search-container input {\n width: 100%;\n padding: 8px 36px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n font-size: 13px;\n background: var(--input-background, #f9fafb);\n transition: all 0.2s ease;\n}\n\n.search-container input:focus {\n outline: none;\n border-color: var(--accent-color, #6366f1);\n background: white;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\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 border: none;\n background: var(--button-hover, #e5e7eb);\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, #9ca3af);\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, #f9fafb);\n font-size: 13px;\n color: var(--text-primary, #1f2937);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.filter-select:focus {\n outline: none;\n border-color: var(--accent-color, #6366f1);\n}\n\n.results-info {\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n}\n\n/* View Toggle */\n.view-toggle {\n display: flex;\n background: var(--toggle-background, #f3f4f6);\n border-radius: 8px;\n padding: 4px;\n}\n\n.toggle-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n border-radius: 6px;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.toggle-btn:hover {\n color: var(--text-primary, #1f2937);\n}\n\n.toggle-btn.active {\n background: var(--card-background, #ffffff);\n color: var(--accent-color, #6366f1);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n/* Timeline View */\n.timeline-container {\n display: flex;\n flex-direction: column;\n gap: 24px;\n}\n\n.timeline-group {\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n overflow: hidden;\n}\n\n.timeline-date {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: var(--header-background, #f9fafb);\n border-bottom: 1px solid var(--border-color, #f3f4f6);\n}\n\n.date-label {\n font-size: 14px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n}\n\n.date-count {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n background: var(--badge-background, #e5e7eb);\n padding: 4px 10px;\n border-radius: 12px;\n}\n\n.timeline-items {\n padding: 8px 0;\n}\n\n.timeline-item {\n display: flex;\n padding: 12px 20px;\n transition: background 0.2s ease;\n}\n\n.timeline-item:hover {\n background: var(--hover-background, #f9fafb);\n}\n\n.timeline-item.failed {\n background: rgba(239, 68, 68, 0.02);\n}\n\n.timeline-item.failed:hover {\n background: rgba(239, 68, 68, 0.05);\n}\n\n.timeline-line {\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 24px;\n margin-right: 16px;\n flex-shrink: 0;\n}\n\n.timeline-dot {\n width: 12px;\n height: 12px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.timeline-content {\n flex: 1;\n min-width: 0;\n cursor: pointer;\n position: relative;\n}\n\n.timeline-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 8px;\n}\n\n.timeline-operation {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.timeline-operation i {\n font-size: 14px;\n}\n\n.operation-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n}\n\n.timeline-time {\n font-size: 12px;\n font-family: monospace;\n color: var(--text-secondary, #6b7280);\n}\n\n.timeline-body {\n margin-bottom: 8px;\n}\n\n.timeline-user {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n margin-bottom: 4px;\n}\n\n.timeline-user i {\n font-size: 11px;\n}\n\n.timeline-description {\n font-size: 13px;\n color: var(--text-primary, #374151);\n margin-bottom: 8px;\n}\n\n.timeline-badges {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-badge.success {\n background: #d1fae5;\n color: #059669;\n}\n\n.status-badge.failed {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.status-badge.unknown {\n background: #f3f4f6;\n color: #6b7280;\n}\n\n.status-badge i {\n font-size: 10px;\n}\n\n.subsystem-badge,\n.type-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n background: var(--badge-background, #f3f4f6);\n border-radius: 12px;\n font-size: 11px;\n color: var(--text-secondary, #6b7280);\n}\n\n.type-badge {\n background: rgba(99, 102, 241, 0.1);\n color: var(--accent-color, #6366f1);\n}\n\n.type-badge i {\n font-size: 10px;\n}\n\n/* Timeline Details */\n.timeline-details {\n margin-top: 12px;\n padding: 16px;\n background: var(--detail-background, #f9fafb);\n border-radius: 8px;\n border: 1px solid var(--border-color, #e5e7eb);\n}\n\n.detail-grid {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 12px;\n}\n\n.detail-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.detail-item.full-width {\n grid-column: 1 / -1;\n}\n\n.detail-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--text-secondary, #6b7280);\n}\n\n.detail-value {\n font-size: 13px;\n color: var(--text-primary, #1f2937);\n}\n\n.detail-value.mono {\n font-family: monospace;\n font-size: 12px;\n}\n\n.detail-value.small {\n font-size: 11px;\n word-break: break-all;\n}\n\n.detail-value.error {\n color: #dc2626;\n}\n\n.expand-btn {\n position: absolute;\n top: 0;\n right: 0;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n color: var(--text-secondary, #9ca3af);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.expand-btn:hover {\n color: var(--accent-color, #6366f1);\n}\n\n.expand-btn i {\n font-size: 10px;\n}\n\n/* Table View */\n.audit-table-container {\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n overflow: hidden;\n}\n\n.audit-table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.audit-table th {\n padding: 14px 16px;\n text-align: left;\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--text-secondary, #6b7280);\n background: var(--header-background, #f9fafb);\n border-bottom: 1px solid var(--border-color, #e5e7eb);\n}\n\n.audit-table td {\n padding: 14px 16px;\n font-size: 13px;\n color: var(--text-primary, #1f2937);\n border-bottom: 1px solid var(--border-color, #f3f4f6);\n}\n\n.audit-table tr:last-child td {\n border-bottom: none;\n}\n\n.audit-table tr:hover td {\n background: var(--hover-background, #f9fafb);\n}\n\n.audit-table tr.failed-row td {\n background: rgba(239, 68, 68, 0.02);\n}\n\n.audit-table tr.failed-row:hover td {\n background: rgba(239, 68, 68, 0.05);\n}\n\n.timestamp {\n font-family: monospace;\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n white-space: nowrap;\n}\n\n.user {\n font-weight: 500;\n}\n\n.operation-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.operation-badge i {\n font-size: 10px;\n}\n\n.description {\n max-width: 300px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.subsystem {\n color: var(--text-secondary, #6b7280);\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: 64px 24px;\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n text-align: center;\n}\n\n.empty-icon {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--icon-background, #f3f4f6);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon i {\n font-size: 32px;\n color: var(--text-secondary, #d1d5db);\n}\n\n.empty-state h3 {\n font-size: 18px;\n font-weight: 600;\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;\n}\n\n.btn-link {\n background: none;\n border: none;\n color: var(--accent-color, #6366f1);\n cursor: pointer;\n font-size: inherit;\n padding: 0;\n text-decoration: underline;\n}\n\n.btn-link:hover {\n color: var(--accent-hover, #4f46e5);\n}\n\n/* Responsive */\n@media (max-width: 1200px) {\n .stats-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 768px) {\n .audit-container {\n padding: 16px;\n }\n\n .audit-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 16px;\n }\n\n .stats-grid {\n grid-template-columns: 1fr;\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 width: 100%;\n }\n\n .filter-select {\n width: 100%;\n }\n\n .toolbar-right {\n justify-content: space-between;\n }\n\n .detail-grid {\n grid-template-columns: 1fr;\n }\n\n .chart-label {\n display: none;\n }\n\n .chart-label:nth-child(4n+1) {\n display: block;\n }\n}\n"] }]
862
862
  }], () => [{ type: i0.ChangeDetectorRef }], null); })();
863
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialsAuditResourceComponent, { className: "CredentialsAuditResourceComponent" }); })();
863
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialsAuditResourceComponent, { className: "CredentialsAuditResourceComponent", filePath: "src/Credentials/components/credentials-audit-resource.component.ts", lineNumber: 42 }); })();
864
864
  //# sourceMappingURL=credentials-audit-resource.component.js.map
@@ -812,5 +812,5 @@ export { CredentialsCategoriesResourceComponent };
812
812
  type: ViewChild,
813
813
  args: ['categoryEditPanel']
814
814
  }] }); })();
815
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialsCategoriesResourceComponent, { className: "CredentialsCategoriesResourceComponent" }); })();
815
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialsCategoriesResourceComponent, { className: "CredentialsCategoriesResourceComponent", filePath: "src/Credentials/components/credentials-categories-resource.component.ts", lineNumber: 28 }); })();
816
816
  //# sourceMappingURL=credentials-categories-resource.component.js.map
@@ -1249,5 +1249,5 @@ export { CredentialsListResourceComponent };
1249
1249
  type: ViewChild,
1250
1250
  args: ['editPanel']
1251
1251
  }] }); })();
1252
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialsListResourceComponent, { className: "CredentialsListResourceComponent" }); })();
1252
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialsListResourceComponent, { className: "CredentialsListResourceComponent", filePath: "src/Credentials/components/credentials-list-resource.component.ts", lineNumber: 24 }); })();
1253
1253
  //# sourceMappingURL=credentials-list-resource.component.js.map
@@ -932,5 +932,5 @@ export { CredentialsOverviewResourceComponent };
932
932
  type: Component,
933
933
  args: [{ selector: 'mj-credentials-overview-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"overview-container\">\n <mj-loading *ngIf=\"isLoading\" text=\"Loading overview...\"></mj-loading>\n\n <ng-container *ngIf=\"!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 <button class=\"btn-primary\" *ngIf=\"UserCanCreateCredentials\" (click)=\"createNewCredential()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>New Credential</span>\n </button>\n </div>\n </div>\n\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 <span *ngIf=\"expiredCredentials > 0\" class=\"health-alert\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{expiredCredentials}} expired\n </span>\n <span *ngIf=\"expiringSoonCount > 0\" class=\"health-warning-text\" (click)=\"viewExpiringCredentials()\">\n <i class=\"fa-solid fa-clock\"></i>\n {{expiringSoonCount}} expiring soon\n </span>\n <span *ngIf=\"expiredCredentials === 0 && expiringSoonCount === 0\" class=\"health-ok\">\n <i class=\"fa-solid fa-check-circle\"></i>\n All credentials healthy\n </span>\n </div>\n </div>\n </div>\n\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\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\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\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 <div class=\"kpi-trend warning\" *ngIf=\"expiringSoonCount > 0\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n </div>\n\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\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 <div class=\"category-chart\" *ngIf=\"categoryStats.length > 0\">\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 <ng-container *ngFor=\"let stat of categoryStats; let i = index\">\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 </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 <div class=\"legend-item\" *ngFor=\"let stat of categoryStats\" (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 </div>\n </div>\n <div class=\"empty-state\" *ngIf=\"categoryStats.length === 0\">\n <i class=\"fa-solid fa-folder-open\"></i>\n <span>No credentials configured</span>\n </div>\n </div>\n </div>\n\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 <div class=\"type-list\" *ngIf=\"typeStats.length > 0\">\n <div class=\"type-item\" *ngFor=\"let type of typeStats.slice(0, 6)\" (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 <span class=\"indicator active\" *ngIf=\"type.activeCount > 0\" title=\"Active\">\n <i class=\"fa-solid fa-circle\"></i> {{type.activeCount}}\n </span>\n <span class=\"indicator warning\" *ngIf=\"type.expiringCount > 0\" title=\"Expiring Soon\">\n <i class=\"fa-solid fa-clock\"></i> {{type.expiringCount}}\n </span>\n </div>\n </div>\n </div>\n </div>\n <div class=\"empty-state\" *ngIf=\"typeStats.length === 0\">\n <i class=\"fa-solid fa-shapes\"></i>\n <span>No credential types configured</span>\n </div>\n </div>\n </div>\n\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 <div class=\"activity-list\" *ngIf=\"recentActivity.length > 0\">\n <div class=\"activity-item\" *ngFor=\"let activity of recentActivity\" (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 <span class=\"activity-user\" *ngIf=\"activity.user\">by {{activity.user}}</span>\n </div>\n </div>\n <div class=\"activity-time\">\n {{formatDate(activity.date)}}\n </div>\n </div>\n </div>\n <div class=\"empty-state\" *ngIf=\"recentActivity.length === 0\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No recent activity</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Quick Actions -->\n <div class=\"quick-actions\" *ngIf=\"UserCanCreateCredentials\">\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 </ng-container>\n</div>\n", styles: [".overview-container {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n}\n\n/* Header */\n.overview-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.header-left {\n flex: 1;\n}\n\n.overview-title {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 4px 0;\n}\n\n.overview-subtitle {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n}\n\n.header-actions {\n display: flex;\n gap: 12px;\n}\n\n.btn-refresh {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-refresh:hover {\n background: var(--item-hover, #f3f4f6);\n}\n\n.btn-refresh i {\n color: var(--text-secondary, #6b7280);\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: 8px;\n font-weight: 600;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-primary:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4);\n}\n\n/* Health Banner */\n.health-banner {\n display: flex;\n align-items: center;\n padding: 20px 24px;\n background: linear-gradient(135deg, #ecfdf5 0%, #d1fae5 100%);\n border: 1px solid #a7f3d0;\n border-radius: 16px;\n margin-bottom: 24px;\n}\n\n.health-banner.health-warning {\n background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);\n border-color: #fcd34d;\n}\n\n.health-banner.health-critical {\n background: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%);\n border-color: #fca5a5;\n}\n\n.health-score-container {\n margin-right: 24px;\n}\n\n.health-score-ring {\n position: relative;\n width: 80px;\n height: 80px;\n}\n\n.circular-chart {\n display: block;\n margin: 0 auto;\n max-height: 80px;\n transform: rotate(-90deg);\n}\n\n.circle-bg {\n fill: none;\n stroke: #e5e7eb;\n stroke-width: 3.8;\n}\n\n.circle {\n fill: none;\n stroke-width: 3.8;\n stroke-linecap: round;\n stroke: #10b981;\n animation: progress 1s ease-out forwards;\n}\n\n.health-banner.health-warning .circle {\n stroke: #f59e0b;\n}\n\n.health-banner.health-critical .circle {\n stroke: #ef4444;\n}\n\n@keyframes progress {\n 0% {\n stroke-dasharray: 0 100;\n }\n}\n\n.health-score-value {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 20px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n}\n\n.health-info {\n flex: 1;\n}\n\n.health-label {\n font-size: 18px;\n font-weight: 700;\n color: #059669;\n margin-bottom: 4px;\n}\n\n.health-banner.health-warning .health-label {\n color: #d97706;\n}\n\n.health-banner.health-critical .health-label {\n color: #dc2626;\n}\n\n.health-details {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.health-alert {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #dc2626;\n font-weight: 500;\n font-size: 14px;\n}\n\n.health-warning-text {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #d97706;\n font-weight: 500;\n font-size: 14px;\n cursor: pointer;\n}\n\n.health-warning-text:hover {\n text-decoration: underline;\n}\n\n.health-ok {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #059669;\n font-weight: 500;\n font-size: 14px;\n}\n\n/* KPI Cards */\n.kpi-row {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card {\n display: flex;\n align-items: center;\n padding: 16px 20px;\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.kpi-card.clickable {\n cursor: pointer;\n}\n\n.kpi-card.clickable:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n\n.kpi-card.active .kpi-icon {\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n}\n\n.kpi-card.warning .kpi-icon {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n}\n\n.kpi-card.danger .kpi-icon {\n background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);\n}\n\n.kpi-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);\n border-radius: 10px;\n margin-right: 14px;\n flex-shrink: 0;\n}\n\n.kpi-icon i {\n font-size: 20px;\n color: white;\n}\n\n.kpi-content {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n line-height: 1.2;\n}\n\n.kpi-label {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n margin-top: 2px;\n white-space: nowrap;\n}\n\n.kpi-trend {\n display: flex;\n align-items: center;\n margin-left: 8px;\n color: var(--text-tertiary, #9ca3af);\n}\n\n.kpi-trend.success {\n color: #10b981;\n}\n\n.kpi-trend.warning {\n color: #f59e0b;\n}\n\n.kpi-trend .percentage {\n font-size: 12px;\n font-weight: 600;\n}\n\n/* Content Grid */\n.content-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n grid-template-rows: auto auto;\n gap: 20px;\n margin-bottom: 24px;\n}\n\n.category-panel {\n grid-row: span 2;\n}\n\n.panel {\n background: var(--card-background, #ffffff);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: var(--header-background, #f9fafb);\n border-bottom: 1px solid var(--border-color, #e5e7eb);\n}\n\n.panel-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-weight: 600;\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n}\n\n.panel-title i {\n color: var(--accent-color, #6366f1);\n}\n\n.panel-subtitle {\n font-size: 12px;\n color: var(--text-tertiary, #9ca3af);\n}\n\n.panel-action {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: transparent;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.panel-action:hover {\n background: var(--accent-color, #6366f1);\n border-color: var(--accent-color, #6366f1);\n color: white;\n}\n\n.panel-body {\n padding: 20px;\n flex: 1;\n overflow-y: auto;\n}\n\n/* Category Chart */\n.category-chart {\n display: flex;\n flex-direction: column;\n gap: 24px;\n height: 100%;\n}\n\n.donut-chart-container {\n position: relative;\n width: 200px;\n height: 200px;\n margin: 0 auto;\n}\n\n.donut-chart {\n width: 100%;\n height: 100%;\n transform: rotate(-90deg);\n}\n\n.donut-segment {\n cursor: pointer;\n transition: opacity 0.2s ease;\n}\n\n.donut-segment:hover {\n opacity: 0.8;\n}\n\n.donut-center {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n text-align: center;\n}\n\n.donut-total {\n font-size: 32px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n}\n\n.donut-label {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n/* Category Legend */\n.category-legend {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.legend-item {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n background: var(--item-background, #f9fafb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.legend-item:hover {\n background: var(--item-hover, #f3f4f6);\n transform: translateX(4px);\n}\n\n.legend-color {\n width: 12px;\n height: 12px;\n border-radius: 4px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.legend-info {\n flex: 1;\n}\n\n.legend-name {\n font-size: 14px;\n font-weight: 500;\n color: var(--text-primary, #1f2937);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.legend-name i {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n.legend-value {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n.legend-arrow {\n color: var(--text-tertiary, #9ca3af);\n font-size: 10px;\n}\n\n/* Type List */\n.type-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.type-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px;\n background: var(--item-background, #f9fafb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.type-item:hover {\n background: var(--item-hover, #f3f4f6);\n}\n\n.type-info {\n flex: 1;\n min-width: 0;\n}\n\n.type-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.type-category {\n font-size: 11px;\n color: var(--text-tertiary, #9ca3af);\n margin-top: 2px;\n}\n\n.type-stats {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 4px;\n flex-shrink: 0;\n margin-left: 16px;\n}\n\n.type-count {\n display: flex;\n align-items: baseline;\n gap: 4px;\n}\n\n.count-value {\n font-size: 16px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n}\n\n.count-label {\n font-size: 11px;\n color: var(--text-tertiary, #9ca3af);\n}\n\n.type-bar {\n width: 100px;\n height: 4px;\n background: #e5e7eb;\n border-radius: 2px;\n overflow: hidden;\n}\n\n.type-bar-fill {\n height: 100%;\n background: linear-gradient(90deg, #6366f1, #8b5cf6);\n border-radius: 2px;\n transition: width 0.3s ease;\n}\n\n.type-indicators {\n display: flex;\n gap: 8px;\n}\n\n.indicator {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n}\n\n.indicator.active {\n color: #10b981;\n}\n\n.indicator.warning {\n color: #f59e0b;\n}\n\n.indicator i {\n font-size: 6px;\n}\n\n/* Activity List */\n.activity-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.activity-item {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n background: var(--item-background, #f9fafb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.activity-item:hover {\n background: var(--item-hover, #f3f4f6);\n}\n\n.activity-icon {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--icon-background, #e0e7ff);\n border-radius: 6px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.activity-icon i {\n font-size: 12px;\n color: var(--accent-color, #6366f1);\n}\n\n.activity-icon.action-created {\n background: #d1fae5;\n}\n\n.activity-icon.action-created i {\n color: #059669;\n}\n\n.activity-icon.action-updated {\n background: #e0e7ff;\n}\n\n.activity-icon.action-updated i {\n color: #6366f1;\n}\n\n.activity-icon.action-accessed {\n background: #fef3c7;\n}\n\n.activity-icon.action-accessed i {\n color: #d97706;\n}\n\n.activity-icon.action-rotated {\n background: #dbeafe;\n}\n\n.activity-icon.action-rotated i {\n color: #3b82f6;\n}\n\n.activity-info {\n flex: 1;\n min-width: 0;\n}\n\n.activity-name {\n font-weight: 500;\n font-size: 13px;\n color: var(--text-primary, #1f2937);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.activity-meta {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 2px;\n font-size: 11px;\n color: var(--text-secondary, #6b7280);\n}\n\n.activity-type {\n background: var(--tag-background, #e5e7eb);\n padding: 1px 6px;\n border-radius: 4px;\n}\n\n.activity-action {\n font-weight: 500;\n}\n\n.activity-time {\n font-size: 11px;\n color: var(--text-tertiary, #9ca3af);\n white-space: nowrap;\n}\n\n/* Quick Actions */\n.quick-actions {\n margin-bottom: 24px;\n}\n\n.quick-actions-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin-bottom: 12px;\n}\n\n.quick-actions-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 12px;\n}\n\n.quick-action {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 16px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.quick-action:hover {\n border-color: var(--accent-color, #6366f1);\n background: #f5f3ff;\n transform: translateY(-2px);\n}\n\n.quick-action i {\n font-size: 20px;\n color: var(--accent-color, #6366f1);\n}\n\n.quick-action span {\n font-size: 12px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 32px;\n color: var(--text-secondary, #6b7280);\n text-align: center;\n}\n\n.empty-state i {\n font-size: 32px;\n margin-bottom: 12px;\n opacity: 0.5;\n}\n\n/* Security Notice */\n.security-notice {\n display: flex;\n align-items: flex-start;\n padding: 16px 20px;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n border-radius: 12px;\n border: 1px solid #bfdbfe;\n}\n\n.security-notice i {\n font-size: 20px;\n color: #3b82f6;\n margin-right: 12px;\n margin-top: 2px;\n}\n\n.notice-content {\n font-size: 13px;\n color: #1e40af;\n line-height: 1.5;\n}\n\n.notice-content strong {\n font-weight: 600;\n}\n\n/* Responsive */\n@media (max-width: 1024px) {\n .content-grid {\n grid-template-columns: 1fr;\n }\n\n .category-panel {\n grid-row: auto;\n }\n\n .category-chart {\n flex-direction: row;\n align-items: center;\n }\n\n .donut-chart-container {\n width: 160px;\n height: 160px;\n }\n\n .category-legend {\n flex: 1;\n }\n}\n\n@media (max-width: 768px) {\n .overview-container {\n padding: 16px;\n }\n\n .overview-header {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: flex-end;\n }\n\n .health-banner {\n flex-direction: column;\n text-align: center;\n }\n\n .health-score-container {\n margin-right: 0;\n margin-bottom: 16px;\n }\n\n .kpi-row {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .category-chart {\n flex-direction: column;\n }\n\n .quick-actions-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n"] }]
934
934
  }], () => [{ type: i0.ChangeDetectorRef }, { type: i1.NavigationService }], null); })();
935
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialsOverviewResourceComponent, { className: "CredentialsOverviewResourceComponent" }); })();
935
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialsOverviewResourceComponent, { className: "CredentialsOverviewResourceComponent", filePath: "src/Credentials/components/credentials-overview-resource.component.ts", lineNumber: 54 }); })();
936
936
  //# sourceMappingURL=credentials-overview-resource.component.js.map
@@ -864,5 +864,5 @@ export { CredentialsTypesResourceComponent };
864
864
  type: ViewChild,
865
865
  args: ['typeEditPanel']
866
866
  }] }); })();
867
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialsTypesResourceComponent, { className: "CredentialsTypesResourceComponent" }); })();
867
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialsTypesResourceComponent, { className: "CredentialsTypesResourceComponent", filePath: "src/Credentials/components/credentials-types-resource.component.ts", lineNumber: 35 }); })();
868
868
  //# sourceMappingURL=credentials-types-resource.component.js.map
@@ -283,7 +283,7 @@ export { CredentialsDashboardComponent };
283
283
  type: Component,
284
284
  args: [{ selector: 'mj-credentials-dashboard', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"credentials-dashboard-container\">\n <div class=\"dashboard-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-key\"></i>\n <span>Credential Management</span>\n </div>\n <div class=\"header-actions\">\n <div class=\"security-badge\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span>Encrypted</span>\n </div>\n <span class=\"tab-label\">{{getCurrentTabLabel()}}</span>\n </div>\n </div>\n\n <div class=\"dashboard-content\">\n <div class=\"sidebar\">\n <div class=\"sidebar-section\">\n <div class=\"sidebar-section-title\">Dashboard</div>\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'overview'\" (click)=\"onTabChange('overview')\">\n <i class=\"fa-solid fa-chart-pie\"></i>\n <span>Overview</span>\n </div>\n\n <div class=\"sidebar-section\">\n <div class=\"sidebar-section-title\">Management</div>\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'credentials'\" (click)=\"onTabChange('credentials')\">\n <i class=\"fa-solid fa-key\"></i>\n <span>Credentials</span>\n <span class=\"badge\" *ngIf=\"credentialCount > 0\">{{credentialCount}}</span>\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'types'\" (click)=\"onTabChange('types')\">\n <i class=\"fa-solid fa-cubes\"></i>\n <span>Types</span>\n <span class=\"badge\" *ngIf=\"typeCount > 0\">{{typeCount}}</span>\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'categories'\" (click)=\"onTabChange('categories')\">\n <i class=\"fa-solid fa-folder-tree\"></i>\n <span>Categories</span>\n </div>\n\n <div class=\"sidebar-section\">\n <div class=\"sidebar-section-title\">Security</div>\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'audit'\" (click)=\"onTabChange('audit')\">\n <i class=\"fa-solid fa-clipboard-list\"></i>\n <span>Audit Trail</span>\n </div>\n </div>\n\n <div class=\"main-content\">\n <div [ngSwitch]=\"activeTab\" class=\"tab-container\">\n <!-- Overview Tab -->\n <div *ngSwitchCase=\"'overview'\" class=\"tab-content\">\n <mj-credentials-overview-resource></mj-credentials-overview-resource>\n </div>\n\n <!-- Credentials Tab -->\n <div *ngSwitchCase=\"'credentials'\" class=\"tab-content\">\n <mj-credentials-list-resource></mj-credentials-list-resource>\n </div>\n\n <!-- Types Tab -->\n <div *ngSwitchCase=\"'types'\" class=\"tab-content\">\n <mj-credentials-types-resource></mj-credentials-types-resource>\n </div>\n\n <!-- Categories Tab -->\n <div *ngSwitchCase=\"'categories'\" class=\"tab-content\">\n <mj-credentials-categories-resource></mj-credentials-categories-resource>\n </div>\n\n <!-- Audit Trail Tab -->\n <div *ngSwitchCase=\"'audit'\" class=\"tab-content\">\n <mj-credentials-audit-resource></mj-credentials-audit-resource>\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [".credentials-dashboard-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background-color: #f8fafc;\n color: #333;\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n}\n\n.dashboard-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 24px;\n background: linear-gradient(135deg, #1e3a5f 0%, #2d5a87 100%);\n border-bottom: 1px solid rgba(255,255,255,0.1);\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 1.25rem;\n font-weight: 600;\n color: #ffffff;\n}\n\n.header-title i {\n color: #fbbf24;\n font-size: 1.5rem;\n}\n\n.header-actions {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.tab-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: rgba(255,255,255,0.8);\n background: rgba(255,255,255,0.15);\n padding: 6px 14px;\n border-radius: 20px;\n backdrop-filter: blur(4px);\n}\n\n.security-badge {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 0.75rem;\n font-weight: 600;\n color: #10b981;\n background: rgba(16, 185, 129, 0.15);\n padding: 6px 12px;\n border-radius: 20px;\n}\n\n.dashboard-content {\n display: flex;\n flex: 1;\n overflow: hidden;\n}\n\n.sidebar {\n width: 260px;\n background-color: #fff;\n border-right: 1px solid #e2e8f0;\n padding: 20px 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.sidebar-section {\n padding: 0 16px;\n margin-bottom: 8px;\n}\n\n.sidebar-section-title {\n font-size: 0.7rem;\n font-weight: 700;\n color: #94a3b8;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n padding: 8px 0;\n}\n\n.nav-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 20px;\n margin: 0 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n color: #475569;\n font-weight: 500;\n border-radius: 10px;\n}\n\n.nav-item:hover {\n background-color: #f0f7ff;\n color: #3b82f6;\n}\n\n.nav-item.selected {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n color: #ffffff;\n box-shadow: 0 4px 6px -1px rgba(59, 130, 246, 0.3);\n}\n\n.nav-item i {\n width: 20px;\n text-align: center;\n font-size: 1rem;\n}\n\n.nav-item .badge {\n margin-left: auto;\n font-size: 0.7rem;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 12px;\n background: rgba(59, 130, 246, 0.1);\n color: #3b82f6;\n}\n\n.nav-item.selected .badge {\n background: rgba(255,255,255,0.2);\n color: #ffffff;\n}\n\n.main-content {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n background: #f8fafc;\n}\n\n.tab-container {\n height: 100%;\n}\n\n.tab-content {\n height: 100%;\n animation: fadeIn 0.3s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* Overview Stats Grid */\n.overview-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 24px;\n margin-bottom: 32px;\n}\n\n.stat-card {\n background: #ffffff;\n border-radius: 16px;\n padding: 24px;\n border: 1px solid #e2e8f0;\n box-shadow: 0 1px 3px rgba(0,0,0,0.05);\n transition: all 0.3s ease;\n}\n\n.stat-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 10px 25px -5px rgba(0,0,0,0.1);\n}\n\n.stat-card .icon-wrapper {\n width: 48px;\n height: 48px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.25rem;\n margin-bottom: 16px;\n}\n\n.stat-card .icon-wrapper.blue {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n color: white;\n}\n\n.stat-card .icon-wrapper.green {\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n color: white;\n}\n\n.stat-card .icon-wrapper.amber {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n color: white;\n}\n\n.stat-card .icon-wrapper.red {\n background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);\n color: white;\n}\n\n.stat-card .stat-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: #64748b;\n margin-bottom: 4px;\n}\n\n.stat-card .stat-value {\n font-size: 2rem;\n font-weight: 800;\n color: #0f172a;\n}\n\n.stat-card .stat-change {\n font-size: 0.75rem;\n font-weight: 600;\n margin-top: 8px;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.stat-card .stat-change.positive { color: #10b981; }\n.stat-card .stat-change.negative { color: #ef4444; }\n\n/* Activity Section */\n.activity-section {\n background: #ffffff;\n border-radius: 16px;\n padding: 24px;\n border: 1px solid #e2e8f0;\n}\n\n.section-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n}\n\n.section-title {\n font-size: 1.125rem;\n font-weight: 700;\n color: #0f172a;\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.section-title i {\n color: #3b82f6;\n}\n\n.view-all-link {\n font-size: 0.875rem;\n font-weight: 600;\n color: #3b82f6;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.view-all-link:hover {\n color: #2563eb;\n text-decoration: underline;\n}\n\n.activity-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.activity-item {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 12px 16px;\n background: #f8fafc;\n border-radius: 10px;\n transition: all 0.2s ease;\n}\n\n.activity-item:hover {\n background: #f1f5f9;\n}\n\n.activity-icon {\n width: 40px;\n height: 40px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 0.875rem;\n}\n\n.activity-icon.decrypt { background: #dbeafe; color: #3b82f6; }\n.activity-icon.create { background: #dcfce7; color: #16a34a; }\n.activity-icon.update { background: #fef3c7; color: #d97706; }\n.activity-icon.delete { background: #fee2e2; color: #dc2626; }\n.activity-icon.validate { background: #e0e7ff; color: #6366f1; }\n\n.activity-details {\n flex: 1;\n}\n\n.activity-details .action {\n font-weight: 600;\n color: #0f172a;\n}\n\n.activity-details .target {\n color: #3b82f6;\n}\n\n.activity-details .meta {\n font-size: 0.75rem;\n color: #94a3b8;\n margin-top: 2px;\n}\n\n.activity-status {\n font-size: 0.75rem;\n font-weight: 600;\n padding: 4px 10px;\n border-radius: 12px;\n}\n\n.activity-status.success { background: #dcfce7; color: #166534; }\n.activity-status.failed { background: #fee2e2; color: #991b1b; }\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n text-align: center;\n}\n\n.empty-state i {\n font-size: 4rem;\n color: #cbd5e1;\n margin-bottom: 20px;\n}\n\n.empty-state h3 {\n font-size: 1.25rem;\n font-weight: 700;\n color: #334155;\n margin: 0 0 8px;\n}\n\n.empty-state p {\n color: #64748b;\n margin: 0;\n}\n\n/* Mobile Responsive Styles */\n@media (max-width: 1024px) {\n .sidebar {\n width: 220px;\n }\n\n .main-content {\n padding: 20px;\n }\n}\n\n@media (max-width: 768px) {\n .dashboard-content {\n flex-direction: column;\n }\n\n .sidebar {\n width: 100%;\n flex-direction: row;\n padding: 12px;\n gap: 0;\n overflow-x: auto;\n border-right: none;\n border-bottom: 1px solid #e2e8f0;\n }\n\n .sidebar-section {\n display: none;\n }\n\n .nav-item {\n flex-direction: column;\n padding: 10px 16px;\n margin: 0 4px;\n gap: 6px;\n white-space: nowrap;\n font-size: 12px;\n }\n\n .nav-item i {\n font-size: 18px;\n }\n\n .nav-item .badge {\n position: absolute;\n top: 4px;\n right: 4px;\n margin-left: 0;\n font-size: 9px;\n padding: 1px 5px;\n }\n\n .main-content {\n padding: 16px;\n }\n\n .dashboard-header {\n padding: 12px 16px;\n }\n\n .header-title {\n font-size: 1rem;\n }\n\n .header-title i {\n font-size: 1.25rem;\n }\n\n .tab-label {\n display: none;\n }\n\n .security-badge span {\n display: none;\n }\n\n .overview-grid {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .stat-card {\n padding: 20px;\n }\n\n .stat-card .stat-value {\n font-size: 1.5rem;\n }\n}\n\n@media (max-width: 480px) {\n .dashboard-header {\n padding: 10px 12px;\n }\n\n .header-title {\n font-size: 0.9rem;\n gap: 8px;\n }\n\n .header-title i {\n font-size: 1.1rem;\n }\n\n .security-badge {\n padding: 4px 8px;\n }\n\n .security-badge i {\n font-size: 14px;\n }\n\n .sidebar {\n padding: 8px;\n }\n\n .nav-item {\n padding: 8px 12px;\n font-size: 11px;\n }\n\n .nav-item i {\n font-size: 16px;\n }\n\n .main-content {\n padding: 12px;\n }\n\n .stat-card {\n padding: 16px;\n border-radius: 12px;\n }\n\n .stat-card .icon-wrapper {\n width: 40px;\n height: 40px;\n font-size: 1rem;\n }\n\n .stat-card .stat-value {\n font-size: 1.25rem;\n }\n\n .section-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .activity-item {\n padding: 10px 12px;\n }\n\n .activity-icon {\n width: 36px;\n height: 36px;\n }\n\n .activity-details .action {\n font-size: 13px;\n }\n}\n"] }]
285
285
  }], () => [{ type: i0.ChangeDetectorRef }], null); })();
286
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialsDashboardComponent, { className: "CredentialsDashboardComponent" }); })();
286
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialsDashboardComponent, { className: "CredentialsDashboardComponent", filePath: "src/Credentials/credentials-dashboard.component.ts", lineNumber: 21 }); })();
287
287
  export function LoadCredentialsDashboard() {
288
288
  // Prevents tree-shaking
289
289
  }
@@ -0,0 +1,225 @@
1
+ import { OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
2
+ import { ActivatedRoute } from '@angular/router';
3
+ import { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';
4
+ import { ResourceData, DashboardEntity, DashboardCategoryEntity, DashboardPartTypeEntity, DashboardUserPermissions } from '@memberjunction/core-entities';
5
+ import { ShareDialogResult } from './dashboard-share-dialog.component';
6
+ import { DashboardViewerComponent, DashboardNavRequestEvent, PanelInteractionEvent, AddPanelResult, DashboardPanel, EditPartDialogResult, DashboardOpenEvent, DashboardEditEvent, DashboardDeleteEvent, DashboardMoveEvent, DashboardCreateEvent, CategoryCreateEvent, CategoryDeleteEvent, CategoryChangeEvent, ViewPreferenceChangeEvent, DashboardBrowserViewMode, BreadcrumbNavigateEvent } from '@memberjunction/ng-dashboard-viewer';
7
+ import * as i0 from "@angular/core";
8
+ export declare function LoadDashboardBrowserResource(): void;
9
+ /**
10
+ * Mode for the dashboard browser
11
+ */
12
+ type BrowserMode = 'list' | 'view' | 'edit';
13
+ /**
14
+ * Resource component for browsing, creating, and editing dashboards.
15
+ * Uses the generic DashboardBrowserComponent for list mode and handles
16
+ * view/edit mode internally with routing integration.
17
+ */
18
+ export declare class DashboardBrowserResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {
19
+ private cdr;
20
+ private route;
21
+ private navigationService;
22
+ mode: BrowserMode;
23
+ isLoading: boolean;
24
+ dashboards: DashboardEntity[];
25
+ categories: DashboardCategoryEntity[];
26
+ selectedDashboard: DashboardEntity | null;
27
+ selectedCategoryId: string | null;
28
+ viewMode: DashboardBrowserViewMode;
29
+ showAddPanelDialog: boolean;
30
+ showConfigDialog: boolean;
31
+ configDialogPanel: DashboardPanel | null;
32
+ configDialogPartType: DashboardPartTypeEntity | null;
33
+ configDialogClass: string;
34
+ showConfirmDialog: boolean;
35
+ confirmPanelId: string;
36
+ confirmPanelTitle: string;
37
+ showShareDialog: boolean;
38
+ editingName: string;
39
+ editingDescription: string;
40
+ private originalName;
41
+ private originalDescription;
42
+ private originalConfig;
43
+ selectedDashboardPermissions: DashboardUserPermissions;
44
+ dashboardPermissionsMap: Map<string, DashboardUserPermissions>;
45
+ effectiveCategoryMap: Map<string, string | null>;
46
+ private readonly _destroy$;
47
+ dashboardViewer: DashboardViewerComponent;
48
+ constructor(cdr: ChangeDetectorRef, route: ActivatedRoute, navigationService: NavigationService);
49
+ ngOnInit(): void;
50
+ ngOnDestroy(): void;
51
+ GetResourceDisplayName(data: ResourceData): Promise<string>;
52
+ GetResourceIconClass(data: ResourceData): Promise<string>;
53
+ /**
54
+ * Handle dashboard open request from generic browser
55
+ */
56
+ onDashboardOpen(event: DashboardOpenEvent): void;
57
+ /**
58
+ * Open the current dashboard in its own dedicated Explorer tab
59
+ */
60
+ openInNewTab(): void;
61
+ /**
62
+ * Handle dashboard edit request from generic browser
63
+ */
64
+ onDashboardEdit(event: DashboardEditEvent): void;
65
+ /**
66
+ * Handle dashboard delete request from generic browser
67
+ */
68
+ onDashboardDelete(event: DashboardDeleteEvent): Promise<void>;
69
+ /**
70
+ * Handle dashboard move request from generic browser.
71
+ * For owned dashboards: updates the dashboard's CategoryID directly.
72
+ * For shared dashboards: creates/updates a DashboardCategoryLink to organize without modifying the original.
73
+ */
74
+ onDashboardMove(event: DashboardMoveEvent): Promise<void>;
75
+ /**
76
+ * Creates or updates a DashboardCategoryLink for organizing a shared dashboard.
77
+ * Ensures only one link exists per user/dashboard combination.
78
+ * @param dashboardId - The ID of the shared dashboard
79
+ * @param userId - The current user's ID
80
+ * @param categoryId - The target category ID (null for root/uncategorized)
81
+ */
82
+ private createOrUpdateCategoryLink;
83
+ /**
84
+ * Handle create dashboard request from generic browser
85
+ */
86
+ onDashboardCreate(event: DashboardCreateEvent): Promise<void>;
87
+ /**
88
+ * Handle category change from generic browser - update URL
89
+ */
90
+ onCategoryChange(event: CategoryChangeEvent): void;
91
+ /**
92
+ * Handle view preference change from generic browser - persist
93
+ */
94
+ onViewPreferenceChange(event: ViewPreferenceChangeEvent): void;
95
+ /**
96
+ * Handle category create request from generic browser
97
+ * Includes extensive logging for debugging category creation issues
98
+ */
99
+ onCategoryCreate(event: CategoryCreateEvent): Promise<void>;
100
+ /**
101
+ * Handle category delete request from generic browser
102
+ * Performs recursive deletion of category and all children
103
+ */
104
+ onCategoryDelete(event: CategoryDeleteEvent): Promise<void>;
105
+ /**
106
+ * Handle breadcrumb navigation event
107
+ * Navigates back to list view with optional category selection
108
+ */
109
+ onBreadcrumbNavigate(event: BreadcrumbNavigateEvent): void;
110
+ /**
111
+ * Open a dashboard for viewing
112
+ */
113
+ openDashboard(dashboard: DashboardEntity): void;
114
+ /**
115
+ * Open a dashboard for editing
116
+ */
117
+ editDashboard(dashboard: DashboardEntity): void;
118
+ /**
119
+ * Go back to list view
120
+ */
121
+ backToList(): void;
122
+ /**
123
+ * Toggle edit mode for current dashboard
124
+ */
125
+ toggleEditMode(): void;
126
+ /**
127
+ * Open the share dialog for the current dashboard
128
+ */
129
+ openShareDialog(): void;
130
+ /**
131
+ * Close the share dialog
132
+ */
133
+ closeShareDialog(): void;
134
+ /**
135
+ * Handle share dialog result
136
+ */
137
+ onShareDialogResult(result: ShareDialogResult): void;
138
+ /**
139
+ * Create a new dashboard
140
+ */
141
+ createDashboard(categoryId?: string | null): Promise<void>;
142
+ /**
143
+ * Save the current dashboard
144
+ */
145
+ saveDashboard(): Promise<void>;
146
+ /**
147
+ * Cancel editing and revert changes
148
+ */
149
+ cancelEdit(): void;
150
+ /**
151
+ * Handle name input blur - validate name is not empty
152
+ */
153
+ onNameBlur(): void;
154
+ /**
155
+ * Open the Add Part dialog
156
+ */
157
+ openAddPartDialog(): void;
158
+ /**
159
+ * Handle panel interaction events from the viewer
160
+ */
161
+ onPanelInteraction(event: PanelInteractionEvent): void;
162
+ /**
163
+ * Handle navigation events from panels
164
+ */
165
+ onNavigationRequested(event: DashboardNavRequestEvent): void;
166
+ /**
167
+ * Handle add panel dialog result
168
+ */
169
+ onPanelAdded(result: AddPanelResult): void;
170
+ /**
171
+ * Handle add panel dialog cancel
172
+ */
173
+ onAddPanelCancelled(): void;
174
+ /**
175
+ * Open the config dialog for a panel
176
+ */
177
+ openConfigDialog(panelId: string): void;
178
+ /**
179
+ * Handle config dialog save
180
+ */
181
+ onConfigDialogSaved(result: EditPartDialogResult): void;
182
+ /**
183
+ * Handle config dialog cancel
184
+ */
185
+ onConfigDialogCancelled(): void;
186
+ /**
187
+ * Close the config dialog
188
+ */
189
+ private closeConfigDialog;
190
+ /**
191
+ * Open the remove confirmation dialog
192
+ */
193
+ openRemoveConfirmDialog(panelId: string, panelTitle: string): void;
194
+ /**
195
+ * Handle remove confirmation
196
+ */
197
+ onRemoveConfirmed(): void;
198
+ /**
199
+ * Handle remove cancel
200
+ */
201
+ onRemoveCancelled(): void;
202
+ /**
203
+ * Close the remove confirm dialog
204
+ */
205
+ private closeRemoveConfirmDialog;
206
+ private loadDashboards;
207
+ private subscribeToQueryParams;
208
+ /**
209
+ * Update the URL query params for the current tab.
210
+ * Uses NavigationService to update the tab configuration, which triggers
211
+ * the shell's URL sync mechanism to update the browser URL properly
212
+ * while respecting app-scoped routes.
213
+ */
214
+ private updateUrlQueryParams;
215
+ /**
216
+ * Get all child categories of a parent category recursively
217
+ */
218
+ private getChildCategoriesRecursive;
219
+ private loadViewPreference;
220
+ private saveViewPreference;
221
+ static ɵfac: i0.ɵɵFactoryDeclaration<DashboardBrowserResourceComponent, never>;
222
+ static ɵcmp: i0.ɵɵComponentDeclaration<DashboardBrowserResourceComponent, "mj-dashboard-browser-resource", never, {}, {}, never, never, false, never>;
223
+ }
224
+ export {};
225
+ //# sourceMappingURL=dashboard-browser-resource.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-browser-resource.component.d.ts","sourceRoot":"","sources":["../../src/DashboardBrowser/dashboard-browser-resource.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAsC,MAAM,eAAe,CAAC;AACpH,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAKjD,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,uBAAuB,EAAE,uBAAuB,EAAmB,wBAAwB,EAA+B,MAAM,+BAA+B,CAAC;AACxM,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EACH,wBAAwB,EACxB,wBAAwB,EACxB,qBAAqB,EACrB,cAAc,EAEd,cAAc,EACd,oBAAoB,EAEpB,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,yBAAyB,EACzB,wBAAwB,EACxB,uBAAuB,EAC1B,MAAM,qCAAqC,CAAC;;AAE7C,wBAAgB,4BAA4B,SAE3C;AAED;;GAEG;AACH,KAAK,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5C;;;;GAIG;AACH,qBAOa,iCAAkC,SAAQ,qBAAsB,YAAW,MAAM,EAAE,SAAS;IA6DjG,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,iBAAiB;IA1DtB,IAAI,EAAE,WAAW,CAAU;IAC3B,SAAS,UAAS;IAClB,UAAU,EAAE,eAAe,EAAE,CAAM;IACnC,UAAU,EAAE,uBAAuB,EAAE,CAAM;IAC3C,iBAAiB,EAAE,eAAe,GAAG,IAAI,CAAQ;IACjD,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACzC,QAAQ,EAAE,wBAAwB,CAAW;IAC7C,kBAAkB,UAAS;IAG3B,gBAAgB,UAAS;IACzB,iBAAiB,EAAE,cAAc,GAAG,IAAI,CAAQ;IAChD,oBAAoB,EAAE,uBAAuB,GAAG,IAAI,CAAQ;IAC5D,iBAAiB,EAAE,MAAM,CAAM;IAG/B,iBAAiB,UAAS;IAC1B,cAAc,EAAE,MAAM,CAAM;IAC5B,iBAAiB,EAAE,MAAM,CAAM;IAG/B,eAAe,UAAS;IAGxB,WAAW,SAAM;IACjB,kBAAkB,SAAM;IAC/B,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,mBAAmB,CAAM;IACjC,OAAO,CAAC,cAAc,CAAM;IAGrB,4BAA4B,EAAE,wBAAwB,CAQ3D;IAGK,uBAAuB,EAAE,GAAG,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAa;IAG3E,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAa;IAEpE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;IAEnB,eAAe,EAAG,wBAAwB,CAAC;gBAO7D,GAAG,EAAE,iBAAiB,EACtB,KAAK,EAAE,cAAc,EACrB,iBAAiB,EAAE,iBAAiB;IAShD,QAAQ,IAAI,IAAI;IAMhB,WAAW,IAAI,IAAI;IASb,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAI3D,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAQ/D;;OAEG;IACI,eAAe,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAcvD;;OAEG;IACI,YAAY,IAAI,IAAI;IAU3B;;OAEG;IACI,eAAe,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAIvD;;OAEG;IACU,iBAAiB,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B1E;;;;OAIG;IACU,eAAe,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAyCtE;;;;;;OAMG;YACW,0BAA0B;IAgCxC;;OAEG;IACU,iBAAiB,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1E;;OAEG;IACI,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;IAKzD;;OAEG;IACI,sBAAsB,CAAC,KAAK,EAAE,yBAAyB,GAAG,IAAI;IAKrE;;;OAGG;IACU,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmExE;;;OAGG;IACU,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IA6CxE;;;OAGG;IACI,oBAAoB,CAAC,KAAK,EAAE,uBAAuB,GAAG,IAAI;IAajE;;OAEG;IACI,aAAa,CAAC,SAAS,EAAE,eAAe,GAAG,IAAI;IAetD;;OAEG;IACI,aAAa,CAAC,SAAS,EAAE,eAAe,GAAG,IAAI;IA6BtD;;OAEG;IACI,UAAU,IAAI,IAAI;IAOzB;;OAEG;IACI,cAAc,IAAI,IAAI;IAS7B;;OAEG;IACI,eAAe,IAAI,IAAI;IAa9B;;OAEG;IACI,gBAAgB,IAAI,IAAI;IAK/B;;OAEG;IACI,mBAAmB,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAmB3D;;OAEG;IACU,eAAe,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAoCvE;;OAEG;IACU,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IA8B3C;;OAEG;IACI,UAAU,IAAI,IAAI;IAiBzB;;OAEG;IACI,UAAU,IAAI,IAAI;IAUzB;;OAEG;IACI,iBAAiB,IAAI,IAAI;IAKhC;;OAEG;IACI,kBAAkB,CAAC,KAAK,EAAE,qBAAqB,GAAG,IAAI;IAuB7D;;OAEG;IACI,qBAAqB,CAAC,KAAK,EAAE,wBAAwB,GAAG,IAAI;IAoDnE;;OAEG;IACI,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAajD;;OAEG;IACI,mBAAmB,IAAI,IAAI;IASlC;;OAEG;IACI,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAkB9C;;OAEG;IACI,mBAAmB,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI;IAY9D;;OAEG;IACI,uBAAuB,IAAI,IAAI;IAItC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAYzB;;OAEG;IACI,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAOzE;;OAEG;IACI,iBAAiB,IAAI,IAAI;IAOhC;;OAEG;IACI,iBAAiB,IAAI,IAAI;IAIhC;;OAEG;IACH,OAAO,CAAC,wBAAwB;YAWlB,cAAc;IAwE5B,OAAO,CAAC,sBAAsB;IAiC9B;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IA0B5B;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAgBnC,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,kBAAkB;yCAt/BjB,iCAAiC;2CAAjC,iCAAiC;CA0/B7C"}