@memberjunction/ng-dashboards 5.24.0 → 5.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (284) hide show
  1. package/dist/AI/components/agents/agent-configuration.component.d.ts +15 -33
  2. package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
  3. package/dist/AI/components/agents/agent-configuration.component.js +233 -493
  4. package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
  5. package/dist/AI/components/agents/agent-editor.component.d.ts +2 -2
  6. package/dist/AI/components/agents/agent-editor.component.d.ts.map +1 -1
  7. package/dist/AI/components/agents/agent-editor.component.js +7 -7
  8. package/dist/AI/components/agents/agent-editor.component.js.map +1 -1
  9. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +43 -6
  10. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
  11. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +1135 -864
  12. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  13. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +4 -3
  14. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
  15. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +1 -0
  16. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
  17. package/dist/AI/components/execution-monitoring.component.d.ts +4 -5
  18. package/dist/AI/components/execution-monitoring.component.d.ts.map +1 -1
  19. package/dist/AI/components/execution-monitoring.component.js +14 -15
  20. package/dist/AI/components/execution-monitoring.component.js.map +1 -1
  21. package/dist/AI/components/models/model-management.component.d.ts +4 -4
  22. package/dist/AI/components/models/model-management.component.d.ts.map +1 -1
  23. package/dist/AI/components/models/model-management.component.js +5 -5
  24. package/dist/AI/components/models/model-management.component.js.map +1 -1
  25. package/dist/AI/components/prompts/prompt-management.component.d.ts +4 -4
  26. package/dist/AI/components/prompts/prompt-management.component.d.ts.map +1 -1
  27. package/dist/AI/components/prompts/prompt-management.component.js +5 -5
  28. package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
  29. package/dist/AI/components/requests/agent-requests-resource.component.d.ts +2 -1
  30. package/dist/AI/components/requests/agent-requests-resource.component.d.ts.map +1 -1
  31. package/dist/AI/components/requests/agent-requests-resource.component.js +1 -0
  32. package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -1
  33. package/dist/AI/components/system/system-configuration.component.d.ts +2 -3
  34. package/dist/AI/components/system/system-configuration.component.d.ts.map +1 -1
  35. package/dist/AI/components/system/system-configuration.component.js +9 -11
  36. package/dist/AI/components/system/system-configuration.component.js.map +1 -1
  37. package/dist/AI/components/vectors/vector-management-resource.component.d.ts +44 -8
  38. package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
  39. package/dist/AI/components/vectors/vector-management-resource.component.js +648 -384
  40. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
  41. package/dist/APIKeys/api-keys-resource.component.d.ts +2 -1
  42. package/dist/APIKeys/api-keys-resource.component.d.ts.map +1 -1
  43. package/dist/APIKeys/api-keys-resource.component.js +2 -0
  44. package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
  45. package/dist/Actions/components/actions-overview.component.d.ts +4 -5
  46. package/dist/Actions/components/actions-overview.component.d.ts.map +1 -1
  47. package/dist/Actions/components/actions-overview.component.js +11 -12
  48. package/dist/Actions/components/actions-overview.component.js.map +1 -1
  49. package/dist/Actions/components/code-management.component.d.ts +2 -3
  50. package/dist/Actions/components/code-management.component.d.ts.map +1 -1
  51. package/dist/Actions/components/code-management.component.js +4 -6
  52. package/dist/Actions/components/code-management.component.js.map +1 -1
  53. package/dist/Actions/components/entity-integration.component.d.ts +2 -3
  54. package/dist/Actions/components/entity-integration.component.d.ts.map +1 -1
  55. package/dist/Actions/components/entity-integration.component.js +4 -6
  56. package/dist/Actions/components/entity-integration.component.js.map +1 -1
  57. package/dist/Actions/components/execution-monitoring.component.d.ts +4 -5
  58. package/dist/Actions/components/execution-monitoring.component.d.ts.map +1 -1
  59. package/dist/Actions/components/execution-monitoring.component.js +10 -11
  60. package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
  61. package/dist/Actions/components/explorer/action-explorer.component.d.ts +13 -12
  62. package/dist/Actions/components/explorer/action-explorer.component.d.ts.map +1 -1
  63. package/dist/Actions/components/explorer/action-explorer.component.js +39 -66
  64. package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
  65. package/dist/Actions/components/scheduled-actions.component.d.ts +2 -3
  66. package/dist/Actions/components/scheduled-actions.component.d.ts.map +1 -1
  67. package/dist/Actions/components/scheduled-actions.component.js +4 -6
  68. package/dist/Actions/components/scheduled-actions.component.js.map +1 -1
  69. package/dist/Actions/components/security-permissions.component.d.ts +2 -3
  70. package/dist/Actions/components/security-permissions.component.d.ts.map +1 -1
  71. package/dist/Actions/components/security-permissions.component.js +4 -6
  72. package/dist/Actions/components/security-permissions.component.js.map +1 -1
  73. package/dist/ApplicationRoles/application-roles-resource.component.d.ts +112 -0
  74. package/dist/ApplicationRoles/application-roles-resource.component.d.ts.map +1 -0
  75. package/dist/ApplicationRoles/application-roles-resource.component.js +532 -0
  76. package/dist/ApplicationRoles/application-roles-resource.component.js.map +1 -0
  77. package/dist/Communication/communication-dashboard.component.d.ts.map +1 -1
  78. package/dist/Communication/communication-dashboard.component.js +1 -0
  79. package/dist/Communication/communication-dashboard.component.js.map +1 -1
  80. package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
  81. package/dist/Communication/communication-logs-resource.component.js +4 -1
  82. package/dist/Communication/communication-logs-resource.component.js.map +1 -1
  83. package/dist/Communication/communication-monitor-resource.component.d.ts.map +1 -1
  84. package/dist/Communication/communication-monitor-resource.component.js +4 -1
  85. package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
  86. package/dist/Communication/communication-providers-resource.component.d.ts.map +1 -1
  87. package/dist/Communication/communication-providers-resource.component.js +4 -1
  88. package/dist/Communication/communication-providers-resource.component.js.map +1 -1
  89. package/dist/Communication/communication-runs-resource.component.d.ts.map +1 -1
  90. package/dist/Communication/communication-runs-resource.component.js +4 -1
  91. package/dist/Communication/communication-runs-resource.component.js.map +1 -1
  92. package/dist/Communication/communication-templates-resource.component.d.ts.map +1 -1
  93. package/dist/Communication/communication-templates-resource.component.js +4 -1
  94. package/dist/Communication/communication-templates-resource.component.js.map +1 -1
  95. package/dist/ComponentStudio/component-studio-dashboard.component.d.ts +2 -1
  96. package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
  97. package/dist/ComponentStudio/component-studio-dashboard.component.js +1 -0
  98. package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
  99. package/dist/Credentials/components/credentials-audit-resource.component.d.ts.map +1 -1
  100. package/dist/Credentials/components/credentials-audit-resource.component.js +2 -0
  101. package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
  102. package/dist/Credentials/components/credentials-categories-resource.component.d.ts +2 -3
  103. package/dist/Credentials/components/credentials-categories-resource.component.d.ts.map +1 -1
  104. package/dist/Credentials/components/credentials-categories-resource.component.js +10 -11
  105. package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
  106. package/dist/Credentials/components/credentials-list-resource.component.d.ts +2 -1
  107. package/dist/Credentials/components/credentials-list-resource.component.d.ts.map +1 -1
  108. package/dist/Credentials/components/credentials-list-resource.component.js +2 -0
  109. package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
  110. package/dist/Credentials/components/credentials-overview-resource.component.d.ts +4 -4
  111. package/dist/Credentials/components/credentials-overview-resource.component.d.ts.map +1 -1
  112. package/dist/Credentials/components/credentials-overview-resource.component.js +8 -9
  113. package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
  114. package/dist/Credentials/components/credentials-types-resource.component.d.ts +2 -3
  115. package/dist/Credentials/components/credentials-types-resource.component.d.ts.map +1 -1
  116. package/dist/Credentials/components/credentials-types-resource.component.js +11 -12
  117. package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
  118. package/dist/Credentials/credentials-dashboard.component.d.ts.map +1 -1
  119. package/dist/Credentials/credentials-dashboard.component.js +1 -0
  120. package/dist/Credentials/credentials-dashboard.component.js.map +1 -1
  121. package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts +2 -3
  122. package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
  123. package/dist/DashboardBrowser/dashboard-browser-resource.component.js +9 -10
  124. package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
  125. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +2 -2
  126. package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts +23 -15
  127. package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts.map +1 -1
  128. package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +167 -213
  129. package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js.map +1 -1
  130. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +68 -32
  131. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  132. package/dist/DataExplorer/data-explorer-dashboard.component.js +453 -420
  133. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  134. package/dist/DataExplorer/data-explorer-resource.component.d.ts +10 -3
  135. package/dist/DataExplorer/data-explorer-resource.component.d.ts.map +1 -1
  136. package/dist/DataExplorer/data-explorer-resource.component.js +35 -11
  137. package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -1
  138. package/dist/DataExplorer/models/explorer-state.interface.d.ts +12 -3
  139. package/dist/DataExplorer/models/explorer-state.interface.d.ts.map +1 -1
  140. package/dist/DataExplorer/models/explorer-state.interface.js +5 -1
  141. package/dist/DataExplorer/models/explorer-state.interface.js.map +1 -1
  142. package/dist/Home/home-dashboard.component.d.ts +4 -4
  143. package/dist/Home/home-dashboard.component.d.ts.map +1 -1
  144. package/dist/Home/home-dashboard.component.js +4 -5
  145. package/dist/Home/home-dashboard.component.js.map +1 -1
  146. package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
  147. package/dist/Integration/components/activity/activity.component.js +1 -0
  148. package/dist/Integration/components/activity/activity.component.js.map +1 -1
  149. package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
  150. package/dist/Integration/components/connections/connections.component.js +2 -0
  151. package/dist/Integration/components/connections/connections.component.js.map +1 -1
  152. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.d.ts.map +1 -1
  153. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +1 -0
  154. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
  155. package/dist/Integration/components/overview/overview.component.d.ts.map +1 -1
  156. package/dist/Integration/components/overview/overview.component.js +2 -0
  157. package/dist/Integration/components/overview/overview.component.js.map +1 -1
  158. package/dist/Integration/components/pipelines/pipelines.component.d.ts.map +1 -1
  159. package/dist/Integration/components/pipelines/pipelines.component.js +2 -0
  160. package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
  161. package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -1
  162. package/dist/Integration/components/schedules/schedules.component.js +2 -0
  163. package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
  164. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts +4 -3
  165. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -1
  166. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +1 -0
  167. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -1
  168. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +4 -3
  169. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -1
  170. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +1 -0
  171. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -1
  172. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts +13 -3
  173. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts.map +1 -1
  174. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +220 -138
  175. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
  176. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts +4 -3
  177. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts.map +1 -1
  178. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +1 -0
  179. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -1
  180. package/dist/KnowledgeHub/index.d.ts +0 -1
  181. package/dist/KnowledgeHub/index.d.ts.map +1 -1
  182. package/dist/KnowledgeHub/index.js +0 -1
  183. package/dist/KnowledgeHub/index.js.map +1 -1
  184. package/dist/Lists/components/lists-browse-resource.component.d.ts +2 -1
  185. package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
  186. package/dist/Lists/components/lists-browse-resource.component.js +2 -0
  187. package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
  188. package/dist/Lists/components/lists-categories-resource.component.d.ts +2 -1
  189. package/dist/Lists/components/lists-categories-resource.component.d.ts.map +1 -1
  190. package/dist/Lists/components/lists-categories-resource.component.js +2 -0
  191. package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
  192. package/dist/Lists/components/lists-my-lists-resource.component.d.ts +2 -1
  193. package/dist/Lists/components/lists-my-lists-resource.component.d.ts.map +1 -1
  194. package/dist/Lists/components/lists-my-lists-resource.component.js +2 -0
  195. package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
  196. package/dist/Lists/components/lists-operations-resource.component.d.ts +2 -1
  197. package/dist/Lists/components/lists-operations-resource.component.d.ts.map +1 -1
  198. package/dist/Lists/components/lists-operations-resource.component.js +2 -0
  199. package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
  200. package/dist/MCP/mcp-dashboard.component.d.ts +7 -28
  201. package/dist/MCP/mcp-dashboard.component.d.ts.map +1 -1
  202. package/dist/MCP/mcp-dashboard.component.js +25 -107
  203. package/dist/MCP/mcp-dashboard.component.js.map +1 -1
  204. package/dist/MCP/mcp-resource.component.d.ts.map +1 -1
  205. package/dist/MCP/mcp-resource.component.js +1 -0
  206. package/dist/MCP/mcp-resource.component.js.map +1 -1
  207. package/dist/QueryBrowser/query-browser-resource.component.d.ts +10 -23
  208. package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
  209. package/dist/QueryBrowser/query-browser-resource.component.js +41 -103
  210. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  211. package/dist/Scheduling/components/scheduling-activity-resource.component.d.ts.map +1 -1
  212. package/dist/Scheduling/components/scheduling-activity-resource.component.js +1 -0
  213. package/dist/Scheduling/components/scheduling-activity-resource.component.js.map +1 -1
  214. package/dist/Scheduling/components/scheduling-jobs-resource.component.d.ts.map +1 -1
  215. package/dist/Scheduling/components/scheduling-jobs-resource.component.js +1 -0
  216. package/dist/Scheduling/components/scheduling-jobs-resource.component.js.map +1 -1
  217. package/dist/Scheduling/components/scheduling-overview-resource.component.d.ts.map +1 -1
  218. package/dist/Scheduling/components/scheduling-overview-resource.component.js +1 -0
  219. package/dist/Scheduling/components/scheduling-overview-resource.component.js.map +1 -1
  220. package/dist/Scheduling/scheduling-dashboard.component.d.ts.map +1 -1
  221. package/dist/Scheduling/scheduling-dashboard.component.js +1 -0
  222. package/dist/Scheduling/scheduling-dashboard.component.js.map +1 -1
  223. package/dist/SystemDiagnostics/system-diagnostics.component.d.ts +4 -4
  224. package/dist/SystemDiagnostics/system-diagnostics.component.d.ts.map +1 -1
  225. package/dist/SystemDiagnostics/system-diagnostics.component.js +9 -10
  226. package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
  227. package/dist/Testing/components/testing-analytics-resource.component.d.ts.map +1 -1
  228. package/dist/Testing/components/testing-analytics-resource.component.js +2 -0
  229. package/dist/Testing/components/testing-analytics-resource.component.js.map +1 -1
  230. package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts +2 -1
  231. package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts.map +1 -1
  232. package/dist/Testing/components/testing-dashboard-tab-resource.component.js +2 -0
  233. package/dist/Testing/components/testing-dashboard-tab-resource.component.js.map +1 -1
  234. package/dist/Testing/components/testing-explorer-resource.component.d.ts.map +1 -1
  235. package/dist/Testing/components/testing-explorer-resource.component.js +2 -0
  236. package/dist/Testing/components/testing-explorer-resource.component.js.map +1 -1
  237. package/dist/Testing/components/testing-review-resource.component.d.ts.map +1 -1
  238. package/dist/Testing/components/testing-review-resource.component.js +2 -0
  239. package/dist/Testing/components/testing-review-resource.component.js.map +1 -1
  240. package/dist/Testing/components/testing-runs-resource.component.d.ts +2 -1
  241. package/dist/Testing/components/testing-runs-resource.component.d.ts.map +1 -1
  242. package/dist/Testing/components/testing-runs-resource.component.js +2 -0
  243. package/dist/Testing/components/testing-runs-resource.component.js.map +1 -1
  244. package/dist/Testing/testing-dashboard.component.d.ts +2 -1
  245. package/dist/Testing/testing-dashboard.component.d.ts.map +1 -1
  246. package/dist/Testing/testing-dashboard.component.js +1 -0
  247. package/dist/Testing/testing-dashboard.component.js.map +1 -1
  248. package/dist/VersionHistory/components/diff-resource.component.d.ts +4 -4
  249. package/dist/VersionHistory/components/diff-resource.component.d.ts.map +1 -1
  250. package/dist/VersionHistory/components/diff-resource.component.js +9 -10
  251. package/dist/VersionHistory/components/diff-resource.component.js.map +1 -1
  252. package/dist/VersionHistory/components/graph-resource.component.d.ts +2 -1
  253. package/dist/VersionHistory/components/graph-resource.component.d.ts.map +1 -1
  254. package/dist/VersionHistory/components/graph-resource.component.js +2 -0
  255. package/dist/VersionHistory/components/graph-resource.component.js.map +1 -1
  256. package/dist/VersionHistory/components/labels-resource.component.d.ts +4 -4
  257. package/dist/VersionHistory/components/labels-resource.component.d.ts.map +1 -1
  258. package/dist/VersionHistory/components/labels-resource.component.js +10 -11
  259. package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
  260. package/dist/VersionHistory/components/restore-resource.component.d.ts +2 -1
  261. package/dist/VersionHistory/components/restore-resource.component.d.ts.map +1 -1
  262. package/dist/VersionHistory/components/restore-resource.component.js +2 -0
  263. package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
  264. package/dist/ai-dashboards.module.d.ts +19 -19
  265. package/dist/ai-dashboards.module.d.ts.map +1 -1
  266. package/dist/ai-dashboards.module.js +4 -5
  267. package/dist/ai-dashboards.module.js.map +1 -1
  268. package/dist/core-dashboards.module.d.ts +19 -18
  269. package/dist/core-dashboards.module.d.ts.map +1 -1
  270. package/dist/core-dashboards.module.js +8 -0
  271. package/dist/core-dashboards.module.js.map +1 -1
  272. package/dist/data-explorer-dashboards.module.d.ts +2 -1
  273. package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
  274. package/dist/data-explorer-dashboards.module.js +7 -3
  275. package/dist/data-explorer-dashboards.module.js.map +1 -1
  276. package/dist/public-api.d.ts +1 -1
  277. package/dist/public-api.d.ts.map +1 -1
  278. package/dist/public-api.js +2 -1
  279. package/dist/public-api.js.map +1 -1
  280. package/package.json +47 -47
  281. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts +0 -166
  282. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts.map +0 -1
  283. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js +0 -991
  284. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js.map +0 -1
@@ -10,12 +10,11 @@ import { BaseResourceComponent } from '@memberjunction/ng-shared';
10
10
  import { RunView, Metadata } from '@memberjunction/core';
11
11
  import { MJNotificationService } from '@memberjunction/ng-notifications';
12
12
  import * as i0 from "@angular/core";
13
- import * as i1 from "@memberjunction/ng-shared";
14
- import * as i2 from "@angular/forms";
15
- import * as i3 from "@memberjunction/ng-ui-components";
16
- import * as i4 from "@memberjunction/ng-shared-generic";
17
- import * as i5 from "@memberjunction/ng-credentials";
18
- import * as i6 from "@angular/common";
13
+ import * as i1 from "@angular/forms";
14
+ import * as i2 from "@memberjunction/ng-ui-components";
15
+ import * as i3 from "@memberjunction/ng-shared-generic";
16
+ import * as i4 from "@memberjunction/ng-credentials";
17
+ import * as i5 from "@angular/common";
19
18
  const _c0 = ["typeEditPanel"];
20
19
  function CredentialsTypesResourceComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
21
20
  i0.ɵɵelement(0, "mj-loading", 2);
@@ -503,7 +502,6 @@ function CredentialsTypesResourceComponent_Conditional_2_Template(rf, ctx) { if
503
502
  } }
504
503
  let CredentialsTypesResourceComponent = class CredentialsTypesResourceComponent extends BaseResourceComponent {
505
504
  cdr;
506
- navigationService;
507
505
  isLoading = true;
508
506
  types = [];
509
507
  filteredTypes = [];
@@ -518,15 +516,16 @@ let CredentialsTypesResourceComponent = class CredentialsTypesResourceComponent
518
516
  _metadata = new Metadata();
519
517
  _permissionCache = new Map();
520
518
  typeEditPanel;
521
- constructor(cdr, navigationService) {
519
+ constructor(cdr) {
522
520
  super();
523
521
  this.cdr = cdr;
524
- this.navigationService = navigationService;
525
522
  }
526
523
  ngOnInit() {
524
+ super.ngOnInit();
527
525
  this.loadData();
528
526
  }
529
527
  ngOnDestroy() {
528
+ super.ngOnDestroy();
530
529
  // Cleanup if needed
531
530
  }
532
531
  async GetResourceDisplayName(data) {
@@ -840,7 +839,7 @@ let CredentialsTypesResourceComponent = class CredentialsTypesResourceComponent
840
839
  refresh() {
841
840
  this.loadData();
842
841
  }
843
- static ɵfac = function CredentialsTypesResourceComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CredentialsTypesResourceComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i1.NavigationService)); };
842
+ static ɵfac = function CredentialsTypesResourceComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CredentialsTypesResourceComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
844
843
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: CredentialsTypesResourceComponent, selectors: [["mj-credentials-types-resource"]], viewQuery: function CredentialsTypesResourceComponent_Query(rf, ctx) { if (rf & 1) {
845
844
  i0.ɵɵviewQuery(_c0, 5);
846
845
  } if (rf & 2) {
@@ -860,7 +859,7 @@ let CredentialsTypesResourceComponent = class CredentialsTypesResourceComponent
860
859
  i0.ɵɵconditional(ctx.isLoading ? 1 : -1);
861
860
  i0.ɵɵadvance();
862
861
  i0.ɵɵconditional(!ctx.isLoading ? 2 : -1);
863
- } }, dependencies: [i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i3.MJButtonDirective, i4.LoadingComponent, i5.CredentialTypeEditPanelComponent, i6.SlicePipe, i6.KeyValuePipe], styles: [".types-container[_ngcontent-%COMP%] {\n height: 100%;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n padding: 24px;\n background: var(--mj-bg-page);\n}\n\n\n\n.types-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n margin-bottom: 24px;\n flex-wrap: wrap;\n gap: 16px;\n}\n\n.header-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.types-title[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.header-stats[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.stat-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.stat-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 10px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 16px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n.btn-primary[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 13px;\n}\n\n\n\n.toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n margin-bottom: 16px;\n flex-wrap: wrap;\n background: var(--mj-bg-surface);\n padding: 16px;\n border-radius: 12px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n\n.toolbar-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n flex: 1;\n}\n\n.toolbar-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.search-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 8px 12px;\n min-width: 240px;\n position: relative;\n}\n\n.search-container[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n margin-right: 8px;\n}\n\n.search-container[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n border: none;\n background: transparent;\n outline: none;\n flex: 1;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.search-clear[_ngcontent-%COMP%] {\n position: absolute;\n right: 8px;\n top: 50%;\n transform: translateY(-50%);\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-border-default);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 10px;\n}\n\n.search-clear[_ngcontent-%COMP%]:hover {\n background: var(--mj-text-secondary);\n color: var(--mj-text-inverse);\n}\n\n.filter-select[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n font-size: 14px;\n color: var(--mj-text-primary);\n cursor: pointer;\n min-width: 160px;\n}\n\n.results-info[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n}\n\n.btn-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-icon[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n\n\n.types-layout[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 420px 1fr;\n flex: 1;\n min-height: 0;\n gap: 20px;\n}\n\n\n\n.types-list[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n overflow-y: auto;\n padding: 16px;\n}\n\n.category-section[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.category-section[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.category-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n color: var(--mj-text-secondary);\n letter-spacing: 0.5px;\n border-left: 3px solid var(--mj-brand-primary);\n background: var(--mj-bg-surface-card);\n border-radius: 0 8px 8px 0;\n margin-bottom: 8px;\n}\n\n.category-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.category-name[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.category-header[_ngcontent-%COMP%] .count[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n padding: 2px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n.type-items[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.type-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px 14px;\n background: var(--mj-bg-surface);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n border: 2px solid transparent;\n position: relative;\n}\n\n.type-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-page);\n border-color: var(--mj-border-default);\n}\n\n.type-item.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n}\n\n.type-icon[_ngcontent-%COMP%] {\n width: 42px;\n height: 42px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.type-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.type-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.type-name[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.type-description[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-disabled);\n margin-top: 2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.type-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-top: 6px;\n}\n\n.meta-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 10px;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.meta-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n}\n\n.meta-badge.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.meta-badge.warning[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.type-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n margin-right: 8px;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.type-item[_ngcontent-%COMP%]:hover .type-actions[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n font-size: 12px;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.action-btn.danger[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-error);\n}\n\n.arrow[_ngcontent-%COMP%] {\n color: var(--mj-border-strong);\n font-size: 12px;\n}\n\n\n\n.type-detail[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n overflow-y: auto;\n}\n\n.detail-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 24px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.detail-icon[_ngcontent-%COMP%] {\n width: 60px;\n height: 60px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 14px;\n margin-right: 16px;\n flex-shrink: 0;\n}\n\n.detail-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 26px;\n}\n\n.detail-title[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.detail-title[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 22px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 8px 0;\n}\n\n.category-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.category-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.detail-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.close-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.detail-body[_ngcontent-%COMP%] {\n padding: 24px;\n}\n\n\n\n.detail-stats[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n margin-bottom: 24px;\n padding-bottom: 24px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.detail-stat[_ngcontent-%COMP%] {\n flex: 1;\n text-align: center;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: 12px;\n}\n\n.detail-stat[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 28px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.detail-stat[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n}\n\n.detail-stat.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 8%, var(--mj-bg-surface));\n}\n\n.detail-stat.active[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.detail-stat.warning[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n}\n\n.detail-stat.warning[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.description[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-secondary);\n line-height: 1.6;\n margin: 0 0 24px 0;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: 10px;\n}\n\n.schema-section[_ngcontent-%COMP%], \n.validation-section[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n\n.schema-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%], \n.validation-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 14px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 16px 0;\n}\n\n.schema-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.validation-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.field-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.field-item[_ngcontent-%COMP%] {\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: 10px;\n border: 1px solid var(--mj-border-default);\n transition: all 0.2s ease;\n}\n\n.field-item[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.field-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.field-name[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.field-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.badge[_ngcontent-%COMP%] {\n padding: 3px 10px;\n border-radius: 6px;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.badge.type[_ngcontent-%COMP%] {\n background: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.badge.secret[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.badge.secret[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 3px;\n}\n\n.badge.required[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.field-description[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n margin: 10px 0 0 0;\n line-height: 1.5;\n}\n\n.no-fields[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: 10px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n.no-fields[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.validation-endpoint[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 14px 18px;\n background: var(--mj-bg-surface-card);\n border-radius: 10px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n font-family: 'SF Mono', 'Monaco', 'Inconsolata', monospace;\n border: 1px solid var(--mj-border-default);\n}\n\n.validation-endpoint[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.detail-quick-actions[_ngcontent-%COMP%] {\n margin-top: 24px;\n padding-top: 24px;\n border-top: 1px solid var(--mj-bg-surface-sunken);\n}\n\n\n\n.no-selection[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n text-align: center;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n padding: 48px;\n}\n\n.no-selection-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-radius: 20px;\n margin-bottom: 24px;\n}\n\n.no-selection-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: var(--mj-brand-primary);\n}\n\n.no-selection[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 8px 0;\n}\n\n.no-selection[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n width: 72px;\n height: 72px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-radius: 18px;\n margin-bottom: 20px;\n}\n\n.empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: var(--mj-brand-primary);\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 8px 0;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0 0 20px 0;\n}\n\n.btn-link[_ngcontent-%COMP%] {\n background: none;\n border: none;\n color: var(--mj-brand-primary);\n font-size: 14px;\n cursor: pointer;\n text-decoration: underline;\n padding: 0;\n}\n\n.btn-link[_ngcontent-%COMP%]:hover {\n color: var(--mj-brand-primary-hover);\n}\n\n\n\n@media (max-width: 1024px) {\n .types-layout[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .types-list[_ngcontent-%COMP%] {\n max-height: 400px;\n }\n}\n\n@media (max-width: 768px) {\n .types-container[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .types-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .toolbar[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: stretch;\n }\n\n .toolbar-left[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .search-container[_ngcontent-%COMP%] {\n min-width: 100%;\n }\n\n .filter-select[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .toolbar-right[_ngcontent-%COMP%] {\n justify-content: space-between;\n }\n\n .detail-stats[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n}"], changeDetection: 0 });
862
+ } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i2.MJButtonDirective, i3.LoadingComponent, i4.CredentialTypeEditPanelComponent, i5.SlicePipe, i5.KeyValuePipe], styles: [".types-container[_ngcontent-%COMP%] {\n height: 100%;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n padding: 24px;\n background: var(--mj-bg-page);\n}\n\n\n\n.types-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n margin-bottom: 24px;\n flex-wrap: wrap;\n gap: 16px;\n}\n\n.header-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.types-title[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.header-stats[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.stat-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.stat-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 10px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 16px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n.btn-primary[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 13px;\n}\n\n\n\n.toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n margin-bottom: 16px;\n flex-wrap: wrap;\n background: var(--mj-bg-surface);\n padding: 16px;\n border-radius: 12px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n\n.toolbar-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n flex: 1;\n}\n\n.toolbar-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.search-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 8px 12px;\n min-width: 240px;\n position: relative;\n}\n\n.search-container[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n margin-right: 8px;\n}\n\n.search-container[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n border: none;\n background: transparent;\n outline: none;\n flex: 1;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.search-clear[_ngcontent-%COMP%] {\n position: absolute;\n right: 8px;\n top: 50%;\n transform: translateY(-50%);\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-border-default);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 10px;\n}\n\n.search-clear[_ngcontent-%COMP%]:hover {\n background: var(--mj-text-secondary);\n color: var(--mj-text-inverse);\n}\n\n.filter-select[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n font-size: 14px;\n color: var(--mj-text-primary);\n cursor: pointer;\n min-width: 160px;\n}\n\n.results-info[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n}\n\n.btn-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-icon[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n\n\n.types-layout[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 420px 1fr;\n flex: 1;\n min-height: 0;\n gap: 20px;\n}\n\n\n\n.types-list[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n overflow-y: auto;\n padding: 16px;\n}\n\n.category-section[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.category-section[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.category-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n color: var(--mj-text-secondary);\n letter-spacing: 0.5px;\n border-left: 3px solid var(--mj-brand-primary);\n background: var(--mj-bg-surface-card);\n border-radius: 0 8px 8px 0;\n margin-bottom: 8px;\n}\n\n.category-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.category-name[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.category-header[_ngcontent-%COMP%] .count[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n padding: 2px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n.type-items[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.type-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px 14px;\n background: var(--mj-bg-surface);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n border: 2px solid transparent;\n position: relative;\n}\n\n.type-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-page);\n border-color: var(--mj-border-default);\n}\n\n.type-item.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n}\n\n.type-icon[_ngcontent-%COMP%] {\n width: 42px;\n height: 42px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.type-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.type-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.type-name[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.type-description[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-disabled);\n margin-top: 2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.type-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-top: 6px;\n}\n\n.meta-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 10px;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.meta-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n}\n\n.meta-badge.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.meta-badge.warning[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.type-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n margin-right: 8px;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.type-item[_ngcontent-%COMP%]:hover .type-actions[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n font-size: 12px;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.action-btn.danger[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-error);\n}\n\n.arrow[_ngcontent-%COMP%] {\n color: var(--mj-border-strong);\n font-size: 12px;\n}\n\n\n\n.type-detail[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n overflow-y: auto;\n}\n\n.detail-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 24px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.detail-icon[_ngcontent-%COMP%] {\n width: 60px;\n height: 60px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 14px;\n margin-right: 16px;\n flex-shrink: 0;\n}\n\n.detail-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 26px;\n}\n\n.detail-title[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.detail-title[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 22px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 8px 0;\n}\n\n.category-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.category-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.detail-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.close-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.detail-body[_ngcontent-%COMP%] {\n padding: 24px;\n}\n\n\n\n.detail-stats[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n margin-bottom: 24px;\n padding-bottom: 24px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.detail-stat[_ngcontent-%COMP%] {\n flex: 1;\n text-align: center;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: 12px;\n}\n\n.detail-stat[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 28px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.detail-stat[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n}\n\n.detail-stat.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 8%, var(--mj-bg-surface));\n}\n\n.detail-stat.active[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.detail-stat.warning[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n}\n\n.detail-stat.warning[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.description[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-secondary);\n line-height: 1.6;\n margin: 0 0 24px 0;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: 10px;\n}\n\n.schema-section[_ngcontent-%COMP%], \n.validation-section[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n\n.schema-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%], \n.validation-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 14px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 16px 0;\n}\n\n.schema-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.validation-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.field-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.field-item[_ngcontent-%COMP%] {\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: 10px;\n border: 1px solid var(--mj-border-default);\n transition: all 0.2s ease;\n}\n\n.field-item[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.field-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.field-name[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.field-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.badge[_ngcontent-%COMP%] {\n padding: 3px 10px;\n border-radius: 6px;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.badge.type[_ngcontent-%COMP%] {\n background: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.badge.secret[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.badge.secret[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 3px;\n}\n\n.badge.required[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.field-description[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n margin: 10px 0 0 0;\n line-height: 1.5;\n}\n\n.no-fields[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: 10px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n.no-fields[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.validation-endpoint[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 14px 18px;\n background: var(--mj-bg-surface-card);\n border-radius: 10px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n font-family: 'SF Mono', 'Monaco', 'Inconsolata', monospace;\n border: 1px solid var(--mj-border-default);\n}\n\n.validation-endpoint[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.detail-quick-actions[_ngcontent-%COMP%] {\n margin-top: 24px;\n padding-top: 24px;\n border-top: 1px solid var(--mj-bg-surface-sunken);\n}\n\n\n\n.no-selection[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n text-align: center;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n padding: 48px;\n}\n\n.no-selection-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-radius: 20px;\n margin-bottom: 24px;\n}\n\n.no-selection-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: var(--mj-brand-primary);\n}\n\n.no-selection[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 8px 0;\n}\n\n.no-selection[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n width: 72px;\n height: 72px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-radius: 18px;\n margin-bottom: 20px;\n}\n\n.empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: var(--mj-brand-primary);\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 8px 0;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0 0 20px 0;\n}\n\n.btn-link[_ngcontent-%COMP%] {\n background: none;\n border: none;\n color: var(--mj-brand-primary);\n font-size: 14px;\n cursor: pointer;\n text-decoration: underline;\n padding: 0;\n}\n\n.btn-link[_ngcontent-%COMP%]:hover {\n color: var(--mj-brand-primary-hover);\n}\n\n\n\n@media (max-width: 1024px) {\n .types-layout[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .types-list[_ngcontent-%COMP%] {\n max-height: 400px;\n }\n}\n\n@media (max-width: 768px) {\n .types-container[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .types-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .toolbar[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: stretch;\n }\n\n .toolbar-left[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .search-container[_ngcontent-%COMP%] {\n min-width: 100%;\n }\n\n .filter-select[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .toolbar-right[_ngcontent-%COMP%] {\n justify-content: space-between;\n }\n\n .detail-stats[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n}"], changeDetection: 0 });
864
863
  };
865
864
  CredentialsTypesResourceComponent = __decorate([
866
865
  RegisterClass(BaseResourceComponent, 'CredentialsTypesResource')
@@ -869,7 +868,7 @@ export { CredentialsTypesResourceComponent };
869
868
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CredentialsTypesResourceComponent, [{
870
869
  type: Component,
871
870
  args: [{ standalone: false, selector: 'mj-credentials-types-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"types-container\">\n @if (isLoading) {\n <mj-loading text=\"Loading credential types...\"></mj-loading>\n }\n\n @if (!isLoading) {\n <!-- Header -->\n <div class=\"types-header\">\n <div class=\"header-info\">\n <h2 class=\"types-title\">Credential Types</h2>\n <div class=\"header-stats\">\n <span class=\"stat-item\">\n <i class=\"fa-solid fa-shapes\"></i>\n {{types.length}} types\n </span>\n <span class=\"stat-item\">\n <i class=\"fa-solid fa-folder\"></i>\n {{categories.length}} categories\n </span>\n <span class=\"stat-item\">\n <i class=\"fa-solid fa-key\"></i>\n {{getTotalCredentialCount()}} credentials\n </span>\n </div>\n </div>\n <div class=\"header-actions\">\n @if (UserCanCreate) {\n <button class=\"btn-primary\" (click)=\"createNewType()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>New Type</span>\n </button>\n }\n </div>\n </div>\n <!-- Toolbar -->\n <div class=\"toolbar\">\n <div class=\"toolbar-left\">\n <div class=\"search-container\">\n <i class=\"fa-solid fa-search\"></i>\n <input\n type=\"text\"\n placeholder=\"Search types...\"\n [value]=\"searchText\"\n (input)=\"onSearchChange($any($event.target).value)\"\n />\n @if (searchText) {\n <button class=\"search-clear\" (click)=\"onSearchChange('')\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n <select\n class=\"filter-select\"\n [value]=\"selectedCategoryFilter\"\n (change)=\"onCategoryFilterChange($any($event.target).value)\"\n >\n <option value=\"\">All Categories</option>\n @for (cat of categories; track cat) {\n <option [value]=\"cat\">{{cat}}</option>\n }\n </select>\n </div>\n <div class=\"toolbar-right\">\n <div class=\"results-info\">\n {{filteredTypes.length}} of {{types.length}} types\n </div>\n <button class=\"btn-icon\" (click)=\"refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n </div>\n </div>\n <div class=\"types-layout\">\n <!-- Types List -->\n <div class=\"types-list\">\n @for (entry of getTypesByCategory() | keyvalue; track entry) {\n <div class=\"category-section\">\n <div class=\"category-header\" [style.borderLeftColor]=\"getCategoryColor(entry.key)\">\n <i [class]=\"getCategoryIcon(entry.key)\" [style.color]=\"getCategoryColor(entry.key)\"></i>\n <span class=\"category-name\">{{entry.key}}</span>\n <span class=\"count\">{{entry.value.length}}</span>\n </div>\n <div class=\"type-items\">\n @for (type of entry.value; track type) {\n <div\n class=\"type-item\"\n [class.selected]=\"IsTypeSelected(type)\"\n (click)=\"selectType(type)\"\n >\n <div class=\"type-icon\" [style.backgroundColor]=\"getCategoryColor(type.Category) + '15'\" [style.color]=\"getCategoryColor(type.Category)\">\n <i [class]=\"type.IconClass || 'fa-solid fa-key'\"></i>\n </div>\n <div class=\"type-info\">\n <div class=\"type-name\">{{type.Name}}</div>\n @if (type.Description) {\n <div class=\"type-description\">\n {{type.Description | slice:0:60}}{{type.Description.length > 60 ? '...' : ''}}\n </div>\n }\n <div class=\"type-meta\">\n @if (type.credentialCount > 0) {\n <span class=\"meta-badge\">\n <i class=\"fa-solid fa-key\"></i>\n {{type.credentialCount}}\n </span>\n }\n @if (type.activeCount > 0) {\n <span class=\"meta-badge active\">\n <i class=\"fa-solid fa-check\"></i>\n {{type.activeCount}} active\n </span>\n }\n @if (type.expiringCount > 0) {\n <span class=\"meta-badge warning\">\n <i class=\"fa-solid fa-clock\"></i>\n {{type.expiringCount}} expiring\n </span>\n }\n </div>\n </div>\n <div class=\"type-actions\">\n @if (UserCanCreateCredential) {\n <button mjButton variant=\"flat\" size=\"sm\"\n (click)=\"createCredentialForType(type, $event)\"\n title=\"Add Credential\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n }\n @if (UserCanUpdate) {\n <button mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editType(type, $event)\"\n title=\"Edit Type\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n }\n @if (UserCanDelete && type.credentialCount === 0) {\n <button mjButton variant=\"danger\" size=\"sm\"\n (click)=\"deleteType(type, $event)\"\n title=\"Delete Type\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n }\n </div>\n <i class=\"fa-solid fa-chevron-right arrow\"></i>\n </div>\n }\n </div>\n </div>\n }\n @if (filteredTypes.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-cubes\"></i>\n </div>\n <h3>No Credential Types Found</h3>\n @if (searchText || selectedCategoryFilter) {\n <p>\n No types match your current filters.\n <button class=\"btn-link\" (click)=\"clearFilters()\">Clear filters</button>\n </p>\n }\n @if (!searchText && !selectedCategoryFilter) {\n <p>\n Get started by creating your first credential type.\n </p>\n }\n @if (UserCanCreate && !searchText && !selectedCategoryFilter) {\n <button class=\"btn-primary\" (click)=\"createNewType()\">\n <i class=\"fa-solid fa-plus\"></i>\n Create Type\n </button>\n }\n </div>\n }\n </div>\n <!-- Type Detail -->\n @if (selectedType) {\n <div class=\"type-detail\">\n <div class=\"detail-header\">\n <div class=\"detail-icon\" [style.backgroundColor]=\"getCategoryColor(selectedType.Category) + '15'\" [style.color]=\"getCategoryColor(selectedType.Category)\">\n <i [class]=\"selectedType.IconClass || 'fa-solid fa-key'\"></i>\n </div>\n <div class=\"detail-title\">\n <h2>{{selectedType.Name}}</h2>\n <span class=\"category-badge\" [style.backgroundColor]=\"getCategoryColor(selectedType.Category) + '20'\" [style.color]=\"getCategoryColor(selectedType.Category)\">\n <i [class]=\"getCategoryIcon(selectedType.Category)\"></i>\n {{selectedType.Category}}\n </span>\n </div>\n <div class=\"detail-actions\">\n @if (UserCanUpdate) {\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"editType(selectedType)\" title=\"Edit\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n }\n <button class=\"close-btn\" (click)=\"closeDetail()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n </div>\n <div class=\"detail-body\">\n <!-- Stats Row -->\n <div class=\"detail-stats\">\n <div class=\"detail-stat\">\n <div class=\"stat-value\">{{selectedType.credentialCount}}</div>\n <div class=\"stat-label\">Credentials</div>\n </div>\n <div class=\"detail-stat active\">\n <div class=\"stat-value\">{{selectedType.activeCount}}</div>\n <div class=\"stat-label\">Active</div>\n </div>\n @if (selectedType.expiringCount > 0) {\n <div class=\"detail-stat warning\">\n <div class=\"stat-value\">{{selectedType.expiringCount}}</div>\n <div class=\"stat-label\">Expiring</div>\n </div>\n }\n </div>\n @if (selectedType.Description) {\n <p class=\"description\">\n {{selectedType.Description}}\n </p>\n }\n <div class=\"schema-section\">\n <h3>\n <i class=\"fa-solid fa-list-check\"></i>\n Field Schema\n </h3>\n @if (schemaProperties.length > 0) {\n <div class=\"field-list\">\n @for (prop of schemaProperties; track prop) {\n <div class=\"field-item\">\n <div class=\"field-header\">\n <span class=\"field-name\">{{prop.title}}</span>\n <span class=\"field-badges\">\n <span class=\"badge type\">{{prop.type}}</span>\n @if (prop.isSecret) {\n <span class=\"badge secret\">\n <i class=\"fa-solid fa-lock\"></i> Secret\n </span>\n }\n @if (prop.required) {\n <span class=\"badge required\">Required</span>\n }\n </span>\n </div>\n @if (prop.description) {\n <p class=\"field-description\">\n {{prop.description}}\n </p>\n }\n </div>\n }\n </div>\n }\n @if (schemaProperties.length === 0) {\n <div class=\"no-fields\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>No fields defined in schema</span>\n </div>\n }\n </div>\n @if (selectedType.ValidationEndpoint) {\n <div class=\"validation-section\">\n <h3>\n <i class=\"fa-solid fa-check-circle\"></i>\n Validation\n </h3>\n <div class=\"validation-endpoint\">\n <i class=\"fa-solid fa-link\"></i>\n <span>{{selectedType.ValidationEndpoint}}</span>\n </div>\n </div>\n }\n <!-- Quick Actions -->\n @if (UserCanCreateCredential) {\n <div class=\"detail-quick-actions\">\n <button class=\"btn-primary\" (click)=\"createCredentialForType(selectedType)\">\n <i class=\"fa-solid fa-plus\"></i>\n Create Credential\n </button>\n </div>\n }\n </div>\n </div>\n }\n <!-- No Selection -->\n @if (!selectedType && filteredTypes.length > 0) {\n <div class=\"no-selection\">\n <div class=\"no-selection-icon\">\n <i class=\"fa-solid fa-hand-pointer\"></i>\n </div>\n <h3>Select a Credential Type</h3>\n <p>Click on a credential type to view its details and field schema</p>\n </div>\n }\n </div>\n }\n</div>\n\n<!-- Type Edit Panel -->\n<mj-credential-type-edit-panel\n #typeEditPanel\n (saved)=\"onTypeSaved($any($event))\"\n (deleted)=\"onTypeDeleted($any($event))\"\n></mj-credential-type-edit-panel>\n", styles: [".types-container {\n height: 100%;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n padding: 24px;\n background: var(--mj-bg-page);\n}\n\n/* Header */\n.types-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n margin-bottom: 24px;\n flex-wrap: wrap;\n gap: 16px;\n}\n\n.header-info {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.types-title {\n font-size: 24px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.header-stats {\n display: flex;\n align-items: center;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.stat-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.stat-item i {\n font-size: 12px;\n}\n\n.header-actions {\n display: flex;\n gap: 12px;\n}\n\n.btn-primary {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 10px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.btn-primary:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 16px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n.btn-primary i {\n font-size: 13px;\n}\n\n/* Toolbar */\n.toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n margin-bottom: 16px;\n flex-wrap: wrap;\n background: var(--mj-bg-surface);\n padding: 16px;\n border-radius: 12px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n\n.toolbar-left {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n flex: 1;\n}\n\n.toolbar-right {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.search-container {\n display: flex;\n align-items: center;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 8px 12px;\n min-width: 240px;\n position: relative;\n}\n\n.search-container i {\n color: var(--mj-text-secondary);\n margin-right: 8px;\n}\n\n.search-container input {\n border: none;\n background: transparent;\n outline: none;\n flex: 1;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.search-clear {\n position: absolute;\n right: 8px;\n top: 50%;\n transform: translateY(-50%);\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-border-default);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 10px;\n}\n\n.search-clear:hover {\n background: var(--mj-text-secondary);\n color: var(--mj-text-inverse);\n}\n\n.filter-select {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n font-size: 14px;\n color: var(--mj-text-primary);\n cursor: pointer;\n min-width: 160px;\n}\n\n.results-info {\n font-size: 13px;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n}\n\n.btn-icon {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-icon:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n/* Layout */\n.types-layout {\n display: grid;\n grid-template-columns: 420px 1fr;\n flex: 1;\n min-height: 0;\n gap: 20px;\n}\n\n/* Types List */\n.types-list {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n overflow-y: auto;\n padding: 16px;\n}\n\n.category-section {\n margin-bottom: 20px;\n}\n\n.category-section:last-child {\n margin-bottom: 0;\n}\n\n.category-header {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n color: var(--mj-text-secondary);\n letter-spacing: 0.5px;\n border-left: 3px solid var(--mj-brand-primary);\n background: var(--mj-bg-surface-card);\n border-radius: 0 8px 8px 0;\n margin-bottom: 8px;\n}\n\n.category-header i {\n font-size: 14px;\n}\n\n.category-name {\n flex: 1;\n}\n\n.category-header .count {\n background: var(--mj-bg-surface);\n padding: 2px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n.type-items {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.type-item {\n display: flex;\n align-items: center;\n padding: 12px 14px;\n background: var(--mj-bg-surface);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n border: 2px solid transparent;\n position: relative;\n}\n\n.type-item:hover {\n background: var(--mj-bg-page);\n border-color: var(--mj-border-default);\n}\n\n.type-item.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n}\n\n.type-icon {\n width: 42px;\n height: 42px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.type-icon i {\n font-size: 16px;\n}\n\n.type-info {\n flex: 1;\n min-width: 0;\n}\n\n.type-name {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.type-description {\n font-size: 12px;\n color: var(--mj-text-disabled);\n margin-top: 2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.type-meta {\n display: flex;\n gap: 8px;\n margin-top: 6px;\n}\n\n.meta-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 10px;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.meta-badge i {\n font-size: 9px;\n}\n\n.meta-badge.active {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.meta-badge.warning {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.type-actions {\n display: flex;\n gap: 4px;\n margin-right: 8px;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.type-item:hover .type-actions {\n opacity: 1;\n}\n\n.action-btn {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n font-size: 12px;\n}\n\n.action-btn:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.action-btn.danger:hover {\n background: var(--mj-status-error);\n}\n\n.arrow {\n color: var(--mj-border-strong);\n font-size: 12px;\n}\n\n/* Type Detail */\n.type-detail {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n overflow-y: auto;\n}\n\n.detail-header {\n display: flex;\n align-items: center;\n padding: 24px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.detail-icon {\n width: 60px;\n height: 60px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 14px;\n margin-right: 16px;\n flex-shrink: 0;\n}\n\n.detail-icon i {\n font-size: 26px;\n}\n\n.detail-title {\n flex: 1;\n}\n\n.detail-title h2 {\n font-size: 22px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 8px 0;\n}\n\n.category-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.category-badge i {\n font-size: 11px;\n}\n\n.detail-actions {\n display: flex;\n gap: 8px;\n}\n\n.close-btn {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.close-btn:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.detail-body {\n padding: 24px;\n}\n\n/* Detail Stats */\n.detail-stats {\n display: flex;\n gap: 16px;\n margin-bottom: 24px;\n padding-bottom: 24px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.detail-stat {\n flex: 1;\n text-align: center;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: 12px;\n}\n\n.detail-stat .stat-value {\n font-size: 28px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.detail-stat .stat-label {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n}\n\n.detail-stat.active {\n background: color-mix(in srgb, var(--mj-status-success) 8%, var(--mj-bg-surface));\n}\n\n.detail-stat.active .stat-value {\n color: var(--mj-status-success);\n}\n\n.detail-stat.warning {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n}\n\n.detail-stat.warning .stat-value {\n color: var(--mj-status-warning);\n}\n\n.description {\n font-size: 14px;\n color: var(--mj-text-secondary);\n line-height: 1.6;\n margin: 0 0 24px 0;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: 10px;\n}\n\n.schema-section,\n.validation-section {\n margin-bottom: 24px;\n}\n\n.schema-section h3,\n.validation-section h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 14px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 16px 0;\n}\n\n.schema-section h3 i,\n.validation-section h3 i {\n color: var(--mj-brand-primary);\n}\n\n.field-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.field-item {\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: 10px;\n border: 1px solid var(--mj-border-default);\n transition: all 0.2s ease;\n}\n\n.field-item:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.field-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.field-name {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.field-badges {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.badge {\n padding: 3px 10px;\n border-radius: 6px;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.badge.type {\n background: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.badge.secret {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.badge.secret i {\n margin-right: 3px;\n}\n\n.badge.required {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.field-description {\n font-size: 13px;\n color: var(--mj-text-secondary);\n margin: 10px 0 0 0;\n line-height: 1.5;\n}\n\n.no-fields {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: 10px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n.no-fields i {\n color: var(--mj-brand-primary);\n}\n\n.validation-endpoint {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 14px 18px;\n background: var(--mj-bg-surface-card);\n border-radius: 10px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n font-family: 'SF Mono', 'Monaco', 'Inconsolata', monospace;\n border: 1px solid var(--mj-border-default);\n}\n\n.validation-endpoint i {\n color: var(--mj-brand-primary);\n}\n\n.detail-quick-actions {\n margin-top: 24px;\n padding-top: 24px;\n border-top: 1px solid var(--mj-bg-surface-sunken);\n}\n\n/* No Selection */\n.no-selection {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n text-align: center;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n padding: 48px;\n}\n\n.no-selection-icon {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-radius: 20px;\n margin-bottom: 24px;\n}\n\n.no-selection-icon i {\n font-size: 32px;\n color: var(--mj-brand-primary);\n}\n\n.no-selection h3 {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 8px 0;\n}\n\n.no-selection p {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n}\n\n.empty-icon {\n width: 72px;\n height: 72px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-radius: 18px;\n margin-bottom: 20px;\n}\n\n.empty-icon i {\n font-size: 32px;\n color: var(--mj-brand-primary);\n}\n\n.empty-state h3 {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 8px 0;\n}\n\n.empty-state p {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0 0 20px 0;\n}\n\n.btn-link {\n background: none;\n border: none;\n color: var(--mj-brand-primary);\n font-size: 14px;\n cursor: pointer;\n text-decoration: underline;\n padding: 0;\n}\n\n.btn-link:hover {\n color: var(--mj-brand-primary-hover);\n}\n\n/* Responsive */\n@media (max-width: 1024px) {\n .types-layout {\n grid-template-columns: 1fr;\n }\n\n .types-list {\n max-height: 400px;\n }\n}\n\n@media (max-width: 768px) {\n .types-container {\n padding: 16px;\n }\n\n .types-header {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .toolbar {\n flex-direction: column;\n align-items: stretch;\n }\n\n .toolbar-left {\n flex-direction: column;\n }\n\n .search-container {\n min-width: 100%;\n }\n\n .filter-select {\n width: 100%;\n }\n\n .toolbar-right {\n justify-content: space-between;\n }\n\n .detail-stats {\n flex-direction: column;\n }\n}\n"] }]
872
- }], () => [{ type: i0.ChangeDetectorRef }, { type: i1.NavigationService }], { typeEditPanel: [{
871
+ }], () => [{ type: i0.ChangeDetectorRef }], { typeEditPanel: [{
873
872
  type: ViewChild,
874
873
  args: ['typeEditPanel']
875
874
  }] }); })();
@@ -1 +1 @@
1
- {"version":3,"file":"credentials-types-resource.component.js","sourceRoot":"","sources":["../../../src/Credentials/components/credentials-types-resource.component.ts","../../../src/Credentials/components/credentials-types-resource.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef, ChangeDetectionStrategy, ViewChild } from '@angular/core';\nimport { ResourceData, MJCredentialTypeEntity, MJCredentialEntity } from '@memberjunction/core-entities';\nimport { RegisterClass , UUIDsEqual } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { RunView, Metadata } from '@memberjunction/core';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { CredentialTypeEditPanelComponent } from '@memberjunction/ng-credentials';\ninterface FieldSchemaProperty {\n name: string;\n type: string;\n title: string;\n description: string;\n isSecret: boolean;\n required: boolean;\n}\n\ninterface TypeWithStats extends MJCredentialTypeEntity {\n credentialCount: number;\n activeCount: number;\n expiringCount: number;\n}\n\n@RegisterClass(BaseResourceComponent, 'CredentialsTypesResource')\n@Component({\n standalone: false,\n selector: 'mj-credentials-types-resource',\n templateUrl: './credentials-types-resource.component.html',\n styleUrls: ['./credentials-types-resource.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class CredentialsTypesResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public isLoading = true;\n public types: TypeWithStats[] = [];\n public filteredTypes: TypeWithStats[] = [];\n public credentials: MJCredentialEntity[] = [];\n public selectedType: TypeWithStats | null = null;\n public schemaProperties: FieldSchemaProperty[] = [];\n\n // Filters\n public searchText = '';\n public selectedCategoryFilter = '';\n public categories: string[] = [];\n\n // Permissions\n private _metadata = new Metadata();\n private _permissionCache = new Map<string, boolean>();\n\n @ViewChild('typeEditPanel') typeEditPanel!: CredentialTypeEditPanelComponent;\n\n constructor(\n private cdr: ChangeDetectorRef,\n private navigationService: NavigationService\n ) {\n super();\n }\n\n ngOnInit(): void {\n this.loadData();\n }\n\n ngOnDestroy(): void {\n // Cleanup if needed\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Credential Types';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-cubes';\n }\n\n // === Permission Checks ===\n\n public get UserCanCreate(): boolean {\n return this.checkEntityPermission('MJ: Credential Types', 'Create');\n }\n\n public get UserCanUpdate(): boolean {\n return this.checkEntityPermission('MJ: Credential Types', 'Update');\n }\n\n public get UserCanDelete(): boolean {\n return this.checkEntityPermission('MJ: Credential Types', 'Delete');\n }\n\n public get UserCanCreateCredential(): boolean {\n return this.checkEntityPermission('MJ: Credentials', 'Create');\n }\n\n private checkEntityPermission(entityName: string, permissionType: 'Create' | 'Read' | 'Update' | 'Delete'): boolean {\n const cacheKey = `${entityName}_${permissionType}`;\n\n if (this._permissionCache.has(cacheKey)) {\n return this._permissionCache.get(cacheKey)!;\n }\n\n try {\n const entityInfo = this._metadata.Entities.find(e => e.Name === entityName);\n if (!entityInfo) {\n this._permissionCache.set(cacheKey, false);\n return false;\n }\n\n const userPermissions = entityInfo.GetUserPermisions(this._metadata.CurrentUser);\n let hasPermission = false;\n\n switch (permissionType) {\n case 'Create': hasPermission = userPermissions.CanCreate; break;\n case 'Read': hasPermission = userPermissions.CanRead; break;\n case 'Update': hasPermission = userPermissions.CanUpdate; break;\n case 'Delete': hasPermission = userPermissions.CanDelete; break;\n }\n\n this._permissionCache.set(cacheKey, hasPermission);\n return hasPermission;\n } catch (error) {\n this._permissionCache.set(cacheKey, false);\n return false;\n }\n }\n\n private async loadData(): Promise<void> {\n try {\n this.isLoading = true;\n this.cdr.markForCheck();\n\n const rv = new RunView();\n const [typeResult, credResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Credential Types',\n OrderBy: 'Category, Name',\n ResultType: 'entity_object'\n },\n {\n EntityName: 'MJ: Credentials',\n ResultType: 'entity_object'\n }\n ]);\n\n if (typeResult.Success) {\n const baseTypes = typeResult.Results as MJCredentialTypeEntity[];\n this.credentials = credResult.Success ? credResult.Results as MJCredentialEntity[] : [];\n\n // Calculate stats for each type\n this.types = baseTypes.map(type => this.enrichTypeWithStats(type));\n\n // Extract unique categories\n this.categories = [...new Set(this.types.map(t => t.Category))].sort();\n }\n\n // Apply any navigation config (e.g., category filter from Categories nav item)\n this.handleNavigationConfig();\n\n this.applyFilters();\n\n } catch (error) {\n console.error('Error loading credential types:', error);\n MJNotificationService.Instance.CreateSimpleNotification('Error loading credential types', 'error', 3000);\n } finally {\n this.isLoading = false;\n this.NotifyLoadComplete();\n this.cdr.markForCheck();\n }\n }\n\n private handleNavigationConfig(): void {\n const config = this.Data?.Configuration;\n if (!config) {\n return;\n }\n\n // Apply category filter from navigation config\n if (config.categoryFilter) {\n this.selectedCategoryFilter = config.categoryFilter as string;\n }\n }\n\n private enrichTypeWithStats(type: MJCredentialTypeEntity): TypeWithStats {\n const typeCredentials = this.credentials.filter(c => UUIDsEqual(c.CredentialTypeID, type.ID));\n const now = new Date();\n const thirtyDaysFromNow = new Date();\n thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30);\n\n // Add stats properties directly to the entity object\n const enrichedType = type as TypeWithStats;\n enrichedType.credentialCount = typeCredentials.length;\n enrichedType.activeCount = typeCredentials.filter(c => c.IsActive).length;\n enrichedType.expiringCount = typeCredentials.filter(c =>\n c.ExpiresAt &&\n new Date(c.ExpiresAt) >= now &&\n new Date(c.ExpiresAt) <= thirtyDaysFromNow\n ).length;\n\n return enrichedType;\n }\n\n // === CRUD Operations ===\n\n public createNewType(): void {\n if (this.typeEditPanel) {\n this.typeEditPanel.open(null);\n }\n }\n\n public editType(type: TypeWithStats, event?: Event): void {\n if (event) {\n event.stopPropagation();\n }\n if (this.typeEditPanel) {\n this.typeEditPanel.open(type);\n }\n }\n\n public async deleteType(type: TypeWithStats, event?: Event): Promise<void> {\n if (event) {\n event.stopPropagation();\n }\n\n if (!this.UserCanDelete) {\n MJNotificationService.Instance.CreateSimpleNotification('You do not have permission to delete credential types', 'warning', 3000);\n return;\n }\n\n if (type.credentialCount > 0) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Cannot delete \"${type.Name}\" - it has ${type.credentialCount} credential(s) using it`,\n 'warning',\n 4000\n );\n return;\n }\n\n const confirmed = confirm(`Are you sure you want to delete \"${type.Name}\"? This action cannot be undone.`);\n if (!confirmed) return;\n\n try {\n const success = await type.Delete();\n if (success) {\n MJNotificationService.Instance.CreateSimpleNotification(`Credential type \"${type.Name}\" deleted successfully`, 'success', 3000);\n this.types = this.types.filter(t => !UUIDsEqual(t.ID, type.ID));\n if (UUIDsEqual(this.selectedType?.ID, type.ID)) {\n this.closeDetail();\n }\n this.applyFilters();\n } else {\n MJNotificationService.Instance.CreateSimpleNotification('Failed to delete credential type', 'error', 3000);\n }\n } catch (error) {\n console.error('Error deleting credential type:', error);\n MJNotificationService.Instance.CreateSimpleNotification('Error deleting credential type', 'error', 3000);\n }\n }\n\n public createCredentialForType(type: TypeWithStats, event?: Event): void {\n if (event) {\n event.stopPropagation();\n }\n // Navigate to Credentials nav item with the type pre-selected and create panel open\n this.navigationService.OpenNavItemByName('Credentials', {\n typeId: type.ID,\n openCreatePanel: true\n });\n }\n\n // === Panel Event Handlers ===\n\n public onTypeSaved(type: MJCredentialTypeEntity): void {\n const existingIndex = this.types.findIndex(t => UUIDsEqual(t.ID, type.ID));\n const enrichedType = this.enrichTypeWithStats(type);\n\n if (existingIndex >= 0) {\n this.types[existingIndex] = enrichedType;\n } else {\n this.types.unshift(enrichedType);\n }\n\n // Update categories if a new one was added\n if (!this.categories.includes(type.Category)) {\n this.categories = [...new Set(this.types.map(t => t.Category))].sort();\n }\n\n this.applyFilters();\n this.cdr.markForCheck();\n }\n\n public onTypeDeleted(typeId: string): void {\n this.types = this.types.filter(t => !UUIDsEqual(t.ID, typeId));\n if (UUIDsEqual(this.selectedType?.ID, typeId)) {\n this.closeDetail();\n }\n this.applyFilters();\n this.cdr.markForCheck();\n }\n\n // === Filtering ===\n\n public onSearchChange(value: string): void {\n this.searchText = value;\n this.applyFilters();\n }\n\n public onCategoryFilterChange(category: string): void {\n this.selectedCategoryFilter = category;\n this.applyFilters();\n }\n\n public clearFilters(): void {\n this.searchText = '';\n this.selectedCategoryFilter = '';\n this.applyFilters();\n }\n\n private applyFilters(): void {\n let filtered = [...this.types];\n\n // Filter by category\n if (this.selectedCategoryFilter) {\n filtered = filtered.filter(t => t.Category === this.selectedCategoryFilter);\n }\n\n // Filter by search text\n if (this.searchText.trim()) {\n const search = this.searchText.toLowerCase().trim();\n filtered = filtered.filter(t =>\n t.Name.toLowerCase().includes(search) ||\n (t.Description && t.Description.toLowerCase().includes(search)) ||\n t.Category.toLowerCase().includes(search)\n );\n }\n\n this.filteredTypes = filtered;\n this.cdr.markForCheck();\n }\n\n // === Selection ===\n\n public selectType(type: TypeWithStats): void {\n this.selectedType = type;\n this.parseFieldSchema(type.FieldSchema);\n this.cdr.markForCheck();\n }\n\n public closeDetail(): void {\n this.selectedType = null;\n this.schemaProperties = [];\n this.cdr.markForCheck();\n }\n\n private parseFieldSchema(schemaJson: string): void {\n try {\n const schema = JSON.parse(schemaJson) as { properties?: Record<string, Record<string, unknown>>; required?: string[] };\n const properties = schema.properties || {};\n const required = schema.required || [];\n\n this.schemaProperties = Object.entries(properties).map(([name, prop]) => ({\n name,\n type: (prop.type as string) || 'string',\n title: (prop.title as string) || name,\n description: (prop.description as string) || '',\n isSecret: prop.isSecret === true,\n required: required.includes(name)\n }));\n\n // Sort by order if available, otherwise by name\n this.schemaProperties.sort((a, b) => {\n const propA = properties[a.name];\n const propB = properties[b.name];\n const orderA = typeof propA.order === 'number' ? propA.order : 999;\n const orderB = typeof propB.order === 'number' ? propB.order : 999;\n return orderA - orderB;\n });\n\n } catch (e) {\n console.error('Failed to parse field schema:', e);\n this.schemaProperties = [];\n }\n }\n\n // === Helpers ===\n\n public getCategoryIcon(category: string): string {\n const iconMap: Record<string, string> = {\n 'AI': 'fa-solid fa-brain',\n 'Communication': 'fa-solid fa-envelope',\n 'Storage': 'fa-solid fa-cloud',\n 'Database': 'fa-solid fa-database',\n 'Authentication': 'fa-solid fa-shield-halved',\n 'Integration': 'fa-solid fa-plug'\n };\n return iconMap[category] || 'fa-solid fa-key';\n }\n\n public getCategoryColor(category: string): string {\n const colorMap: Record<string, string> = {\n 'AI': 'var(--mj-brand-primary)',\n 'Communication': 'var(--mj-brand-primary)',\n 'Storage': 'var(--mj-brand-primary)',\n 'Database': 'var(--mj-status-warning)',\n 'Authentication': 'var(--mj-status-success)',\n 'Integration': 'var(--mj-brand-primary)'\n };\n return colorMap[category] || 'var(--mj-brand-primary)';\n }\n\n public getTypesByCategory(): Map<string, TypeWithStats[]> {\n const grouped = new Map<string, TypeWithStats[]>();\n for (const type of this.filteredTypes) {\n const category = type.Category;\n if (!grouped.has(category)) {\n grouped.set(category, []);\n }\n grouped.get(category)!.push(type);\n }\n return grouped;\n }\n\n /** Case-insensitive UUID check whether a credential type is the currently selected type. */\n public IsTypeSelected(type: TypeWithStats): boolean {\n return UUIDsEqual(this.selectedType?.ID, type.ID);\n }\n\n public getTotalCredentialCount(): number {\n return this.types.reduce((sum, t) => sum + t.credentialCount, 0);\n }\n\n public refresh(): void {\n this.loadData();\n }\n}\n","<div class=\"types-container\">\n @if (isLoading) {\n <mj-loading text=\"Loading credential types...\"></mj-loading>\n }\n\n @if (!isLoading) {\n <!-- Header -->\n <div class=\"types-header\">\n <div class=\"header-info\">\n <h2 class=\"types-title\">Credential Types</h2>\n <div class=\"header-stats\">\n <span class=\"stat-item\">\n <i class=\"fa-solid fa-shapes\"></i>\n {{types.length}} types\n </span>\n <span class=\"stat-item\">\n <i class=\"fa-solid fa-folder\"></i>\n {{categories.length}} categories\n </span>\n <span class=\"stat-item\">\n <i class=\"fa-solid fa-key\"></i>\n {{getTotalCredentialCount()}} credentials\n </span>\n </div>\n </div>\n <div class=\"header-actions\">\n @if (UserCanCreate) {\n <button class=\"btn-primary\" (click)=\"createNewType()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>New Type</span>\n </button>\n }\n </div>\n </div>\n <!-- Toolbar -->\n <div class=\"toolbar\">\n <div class=\"toolbar-left\">\n <div class=\"search-container\">\n <i class=\"fa-solid fa-search\"></i>\n <input\n type=\"text\"\n placeholder=\"Search types...\"\n [value]=\"searchText\"\n (input)=\"onSearchChange($any($event.target).value)\"\n />\n @if (searchText) {\n <button class=\"search-clear\" (click)=\"onSearchChange('')\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n <select\n class=\"filter-select\"\n [value]=\"selectedCategoryFilter\"\n (change)=\"onCategoryFilterChange($any($event.target).value)\"\n >\n <option value=\"\">All Categories</option>\n @for (cat of categories; track cat) {\n <option [value]=\"cat\">{{cat}}</option>\n }\n </select>\n </div>\n <div class=\"toolbar-right\">\n <div class=\"results-info\">\n {{filteredTypes.length}} of {{types.length}} types\n </div>\n <button class=\"btn-icon\" (click)=\"refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n </div>\n </div>\n <div class=\"types-layout\">\n <!-- Types List -->\n <div class=\"types-list\">\n @for (entry of getTypesByCategory() | keyvalue; track entry) {\n <div class=\"category-section\">\n <div class=\"category-header\" [style.borderLeftColor]=\"getCategoryColor(entry.key)\">\n <i [class]=\"getCategoryIcon(entry.key)\" [style.color]=\"getCategoryColor(entry.key)\"></i>\n <span class=\"category-name\">{{entry.key}}</span>\n <span class=\"count\">{{entry.value.length}}</span>\n </div>\n <div class=\"type-items\">\n @for (type of entry.value; track type) {\n <div\n class=\"type-item\"\n [class.selected]=\"IsTypeSelected(type)\"\n (click)=\"selectType(type)\"\n >\n <div class=\"type-icon\" [style.backgroundColor]=\"getCategoryColor(type.Category) + '15'\" [style.color]=\"getCategoryColor(type.Category)\">\n <i [class]=\"type.IconClass || 'fa-solid fa-key'\"></i>\n </div>\n <div class=\"type-info\">\n <div class=\"type-name\">{{type.Name}}</div>\n @if (type.Description) {\n <div class=\"type-description\">\n {{type.Description | slice:0:60}}{{type.Description.length > 60 ? '...' : ''}}\n </div>\n }\n <div class=\"type-meta\">\n @if (type.credentialCount > 0) {\n <span class=\"meta-badge\">\n <i class=\"fa-solid fa-key\"></i>\n {{type.credentialCount}}\n </span>\n }\n @if (type.activeCount > 0) {\n <span class=\"meta-badge active\">\n <i class=\"fa-solid fa-check\"></i>\n {{type.activeCount}} active\n </span>\n }\n @if (type.expiringCount > 0) {\n <span class=\"meta-badge warning\">\n <i class=\"fa-solid fa-clock\"></i>\n {{type.expiringCount}} expiring\n </span>\n }\n </div>\n </div>\n <div class=\"type-actions\">\n @if (UserCanCreateCredential) {\n <button mjButton variant=\"flat\" size=\"sm\"\n (click)=\"createCredentialForType(type, $event)\"\n title=\"Add Credential\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n }\n @if (UserCanUpdate) {\n <button mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editType(type, $event)\"\n title=\"Edit Type\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n }\n @if (UserCanDelete && type.credentialCount === 0) {\n <button mjButton variant=\"danger\" size=\"sm\"\n (click)=\"deleteType(type, $event)\"\n title=\"Delete Type\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n }\n </div>\n <i class=\"fa-solid fa-chevron-right arrow\"></i>\n </div>\n }\n </div>\n </div>\n }\n @if (filteredTypes.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-cubes\"></i>\n </div>\n <h3>No Credential Types Found</h3>\n @if (searchText || selectedCategoryFilter) {\n <p>\n No types match your current filters.\n <button class=\"btn-link\" (click)=\"clearFilters()\">Clear filters</button>\n </p>\n }\n @if (!searchText && !selectedCategoryFilter) {\n <p>\n Get started by creating your first credential type.\n </p>\n }\n @if (UserCanCreate && !searchText && !selectedCategoryFilter) {\n <button class=\"btn-primary\" (click)=\"createNewType()\">\n <i class=\"fa-solid fa-plus\"></i>\n Create Type\n </button>\n }\n </div>\n }\n </div>\n <!-- Type Detail -->\n @if (selectedType) {\n <div class=\"type-detail\">\n <div class=\"detail-header\">\n <div class=\"detail-icon\" [style.backgroundColor]=\"getCategoryColor(selectedType.Category) + '15'\" [style.color]=\"getCategoryColor(selectedType.Category)\">\n <i [class]=\"selectedType.IconClass || 'fa-solid fa-key'\"></i>\n </div>\n <div class=\"detail-title\">\n <h2>{{selectedType.Name}}</h2>\n <span class=\"category-badge\" [style.backgroundColor]=\"getCategoryColor(selectedType.Category) + '20'\" [style.color]=\"getCategoryColor(selectedType.Category)\">\n <i [class]=\"getCategoryIcon(selectedType.Category)\"></i>\n {{selectedType.Category}}\n </span>\n </div>\n <div class=\"detail-actions\">\n @if (UserCanUpdate) {\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"editType(selectedType)\" title=\"Edit\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n }\n <button class=\"close-btn\" (click)=\"closeDetail()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n </div>\n <div class=\"detail-body\">\n <!-- Stats Row -->\n <div class=\"detail-stats\">\n <div class=\"detail-stat\">\n <div class=\"stat-value\">{{selectedType.credentialCount}}</div>\n <div class=\"stat-label\">Credentials</div>\n </div>\n <div class=\"detail-stat active\">\n <div class=\"stat-value\">{{selectedType.activeCount}}</div>\n <div class=\"stat-label\">Active</div>\n </div>\n @if (selectedType.expiringCount > 0) {\n <div class=\"detail-stat warning\">\n <div class=\"stat-value\">{{selectedType.expiringCount}}</div>\n <div class=\"stat-label\">Expiring</div>\n </div>\n }\n </div>\n @if (selectedType.Description) {\n <p class=\"description\">\n {{selectedType.Description}}\n </p>\n }\n <div class=\"schema-section\">\n <h3>\n <i class=\"fa-solid fa-list-check\"></i>\n Field Schema\n </h3>\n @if (schemaProperties.length > 0) {\n <div class=\"field-list\">\n @for (prop of schemaProperties; track prop) {\n <div class=\"field-item\">\n <div class=\"field-header\">\n <span class=\"field-name\">{{prop.title}}</span>\n <span class=\"field-badges\">\n <span class=\"badge type\">{{prop.type}}</span>\n @if (prop.isSecret) {\n <span class=\"badge secret\">\n <i class=\"fa-solid fa-lock\"></i> Secret\n </span>\n }\n @if (prop.required) {\n <span class=\"badge required\">Required</span>\n }\n </span>\n </div>\n @if (prop.description) {\n <p class=\"field-description\">\n {{prop.description}}\n </p>\n }\n </div>\n }\n </div>\n }\n @if (schemaProperties.length === 0) {\n <div class=\"no-fields\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>No fields defined in schema</span>\n </div>\n }\n </div>\n @if (selectedType.ValidationEndpoint) {\n <div class=\"validation-section\">\n <h3>\n <i class=\"fa-solid fa-check-circle\"></i>\n Validation\n </h3>\n <div class=\"validation-endpoint\">\n <i class=\"fa-solid fa-link\"></i>\n <span>{{selectedType.ValidationEndpoint}}</span>\n </div>\n </div>\n }\n <!-- Quick Actions -->\n @if (UserCanCreateCredential) {\n <div class=\"detail-quick-actions\">\n <button class=\"btn-primary\" (click)=\"createCredentialForType(selectedType)\">\n <i class=\"fa-solid fa-plus\"></i>\n Create Credential\n </button>\n </div>\n }\n </div>\n </div>\n }\n <!-- No Selection -->\n @if (!selectedType && filteredTypes.length > 0) {\n <div class=\"no-selection\">\n <div class=\"no-selection-icon\">\n <i class=\"fa-solid fa-hand-pointer\"></i>\n </div>\n <h3>Select a Credential Type</h3>\n <p>Click on a credential type to view its details and field schema</p>\n </div>\n }\n </div>\n }\n</div>\n\n<!-- Type Edit Panel -->\n<mj-credential-type-edit-panel\n #typeEditPanel\n (saved)=\"onTypeSaved($any($event))\"\n (deleted)=\"onTypeDeleted($any($event))\"\n></mj-credential-type-edit-panel>\n"]}
1
+ {"version":3,"file":"credentials-types-resource.component.js","sourceRoot":"","sources":["../../../src/Credentials/components/credentials-types-resource.component.ts","../../../src/Credentials/components/credentials-types-resource.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef, ChangeDetectionStrategy, ViewChild } from '@angular/core';\nimport { ResourceData, MJCredentialTypeEntity, MJCredentialEntity } from '@memberjunction/core-entities';\nimport { RegisterClass , UUIDsEqual } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { RunView, Metadata } from '@memberjunction/core';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { CredentialTypeEditPanelComponent } from '@memberjunction/ng-credentials';\ninterface FieldSchemaProperty {\n name: string;\n type: string;\n title: string;\n description: string;\n isSecret: boolean;\n required: boolean;\n}\n\ninterface TypeWithStats extends MJCredentialTypeEntity {\n credentialCount: number;\n activeCount: number;\n expiringCount: number;\n}\n\n@RegisterClass(BaseResourceComponent, 'CredentialsTypesResource')\n@Component({\n standalone: false,\n selector: 'mj-credentials-types-resource',\n templateUrl: './credentials-types-resource.component.html',\n styleUrls: ['./credentials-types-resource.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class CredentialsTypesResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public isLoading = true;\n public types: TypeWithStats[] = [];\n public filteredTypes: TypeWithStats[] = [];\n public credentials: MJCredentialEntity[] = [];\n public selectedType: TypeWithStats | null = null;\n public schemaProperties: FieldSchemaProperty[] = [];\n\n // Filters\n public searchText = '';\n public selectedCategoryFilter = '';\n public categories: string[] = [];\n\n // Permissions\n private _metadata = new Metadata();\n private _permissionCache = new Map<string, boolean>();\n\n @ViewChild('typeEditPanel') typeEditPanel!: CredentialTypeEditPanelComponent;\n\n constructor(\n private cdr: ChangeDetectorRef) {\n super();\n }\n\n ngOnInit(): void {\n super.ngOnInit();\n this.loadData();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n // Cleanup if needed\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Credential Types';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-cubes';\n }\n\n // === Permission Checks ===\n\n public get UserCanCreate(): boolean {\n return this.checkEntityPermission('MJ: Credential Types', 'Create');\n }\n\n public get UserCanUpdate(): boolean {\n return this.checkEntityPermission('MJ: Credential Types', 'Update');\n }\n\n public get UserCanDelete(): boolean {\n return this.checkEntityPermission('MJ: Credential Types', 'Delete');\n }\n\n public get UserCanCreateCredential(): boolean {\n return this.checkEntityPermission('MJ: Credentials', 'Create');\n }\n\n private checkEntityPermission(entityName: string, permissionType: 'Create' | 'Read' | 'Update' | 'Delete'): boolean {\n const cacheKey = `${entityName}_${permissionType}`;\n\n if (this._permissionCache.has(cacheKey)) {\n return this._permissionCache.get(cacheKey)!;\n }\n\n try {\n const entityInfo = this._metadata.Entities.find(e => e.Name === entityName);\n if (!entityInfo) {\n this._permissionCache.set(cacheKey, false);\n return false;\n }\n\n const userPermissions = entityInfo.GetUserPermisions(this._metadata.CurrentUser);\n let hasPermission = false;\n\n switch (permissionType) {\n case 'Create': hasPermission = userPermissions.CanCreate; break;\n case 'Read': hasPermission = userPermissions.CanRead; break;\n case 'Update': hasPermission = userPermissions.CanUpdate; break;\n case 'Delete': hasPermission = userPermissions.CanDelete; break;\n }\n\n this._permissionCache.set(cacheKey, hasPermission);\n return hasPermission;\n } catch (error) {\n this._permissionCache.set(cacheKey, false);\n return false;\n }\n }\n\n private async loadData(): Promise<void> {\n try {\n this.isLoading = true;\n this.cdr.markForCheck();\n\n const rv = new RunView();\n const [typeResult, credResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Credential Types',\n OrderBy: 'Category, Name',\n ResultType: 'entity_object'\n },\n {\n EntityName: 'MJ: Credentials',\n ResultType: 'entity_object'\n }\n ]);\n\n if (typeResult.Success) {\n const baseTypes = typeResult.Results as MJCredentialTypeEntity[];\n this.credentials = credResult.Success ? credResult.Results as MJCredentialEntity[] : [];\n\n // Calculate stats for each type\n this.types = baseTypes.map(type => this.enrichTypeWithStats(type));\n\n // Extract unique categories\n this.categories = [...new Set(this.types.map(t => t.Category))].sort();\n }\n\n // Apply any navigation config (e.g., category filter from Categories nav item)\n this.handleNavigationConfig();\n\n this.applyFilters();\n\n } catch (error) {\n console.error('Error loading credential types:', error);\n MJNotificationService.Instance.CreateSimpleNotification('Error loading credential types', 'error', 3000);\n } finally {\n this.isLoading = false;\n this.NotifyLoadComplete();\n this.cdr.markForCheck();\n }\n }\n\n private handleNavigationConfig(): void {\n const config = this.Data?.Configuration;\n if (!config) {\n return;\n }\n\n // Apply category filter from navigation config\n if (config.categoryFilter) {\n this.selectedCategoryFilter = config.categoryFilter as string;\n }\n }\n\n private enrichTypeWithStats(type: MJCredentialTypeEntity): TypeWithStats {\n const typeCredentials = this.credentials.filter(c => UUIDsEqual(c.CredentialTypeID, type.ID));\n const now = new Date();\n const thirtyDaysFromNow = new Date();\n thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30);\n\n // Add stats properties directly to the entity object\n const enrichedType = type as TypeWithStats;\n enrichedType.credentialCount = typeCredentials.length;\n enrichedType.activeCount = typeCredentials.filter(c => c.IsActive).length;\n enrichedType.expiringCount = typeCredentials.filter(c =>\n c.ExpiresAt &&\n new Date(c.ExpiresAt) >= now &&\n new Date(c.ExpiresAt) <= thirtyDaysFromNow\n ).length;\n\n return enrichedType;\n }\n\n // === CRUD Operations ===\n\n public createNewType(): void {\n if (this.typeEditPanel) {\n this.typeEditPanel.open(null);\n }\n }\n\n public editType(type: TypeWithStats, event?: Event): void {\n if (event) {\n event.stopPropagation();\n }\n if (this.typeEditPanel) {\n this.typeEditPanel.open(type);\n }\n }\n\n public async deleteType(type: TypeWithStats, event?: Event): Promise<void> {\n if (event) {\n event.stopPropagation();\n }\n\n if (!this.UserCanDelete) {\n MJNotificationService.Instance.CreateSimpleNotification('You do not have permission to delete credential types', 'warning', 3000);\n return;\n }\n\n if (type.credentialCount > 0) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Cannot delete \"${type.Name}\" - it has ${type.credentialCount} credential(s) using it`,\n 'warning',\n 4000\n );\n return;\n }\n\n const confirmed = confirm(`Are you sure you want to delete \"${type.Name}\"? This action cannot be undone.`);\n if (!confirmed) return;\n\n try {\n const success = await type.Delete();\n if (success) {\n MJNotificationService.Instance.CreateSimpleNotification(`Credential type \"${type.Name}\" deleted successfully`, 'success', 3000);\n this.types = this.types.filter(t => !UUIDsEqual(t.ID, type.ID));\n if (UUIDsEqual(this.selectedType?.ID, type.ID)) {\n this.closeDetail();\n }\n this.applyFilters();\n } else {\n MJNotificationService.Instance.CreateSimpleNotification('Failed to delete credential type', 'error', 3000);\n }\n } catch (error) {\n console.error('Error deleting credential type:', error);\n MJNotificationService.Instance.CreateSimpleNotification('Error deleting credential type', 'error', 3000);\n }\n }\n\n public createCredentialForType(type: TypeWithStats, event?: Event): void {\n if (event) {\n event.stopPropagation();\n }\n // Navigate to Credentials nav item with the type pre-selected and create panel open\n this.navigationService.OpenNavItemByName('Credentials', {\n typeId: type.ID,\n openCreatePanel: true\n });\n }\n\n // === Panel Event Handlers ===\n\n public onTypeSaved(type: MJCredentialTypeEntity): void {\n const existingIndex = this.types.findIndex(t => UUIDsEqual(t.ID, type.ID));\n const enrichedType = this.enrichTypeWithStats(type);\n\n if (existingIndex >= 0) {\n this.types[existingIndex] = enrichedType;\n } else {\n this.types.unshift(enrichedType);\n }\n\n // Update categories if a new one was added\n if (!this.categories.includes(type.Category)) {\n this.categories = [...new Set(this.types.map(t => t.Category))].sort();\n }\n\n this.applyFilters();\n this.cdr.markForCheck();\n }\n\n public onTypeDeleted(typeId: string): void {\n this.types = this.types.filter(t => !UUIDsEqual(t.ID, typeId));\n if (UUIDsEqual(this.selectedType?.ID, typeId)) {\n this.closeDetail();\n }\n this.applyFilters();\n this.cdr.markForCheck();\n }\n\n // === Filtering ===\n\n public onSearchChange(value: string): void {\n this.searchText = value;\n this.applyFilters();\n }\n\n public onCategoryFilterChange(category: string): void {\n this.selectedCategoryFilter = category;\n this.applyFilters();\n }\n\n public clearFilters(): void {\n this.searchText = '';\n this.selectedCategoryFilter = '';\n this.applyFilters();\n }\n\n private applyFilters(): void {\n let filtered = [...this.types];\n\n // Filter by category\n if (this.selectedCategoryFilter) {\n filtered = filtered.filter(t => t.Category === this.selectedCategoryFilter);\n }\n\n // Filter by search text\n if (this.searchText.trim()) {\n const search = this.searchText.toLowerCase().trim();\n filtered = filtered.filter(t =>\n t.Name.toLowerCase().includes(search) ||\n (t.Description && t.Description.toLowerCase().includes(search)) ||\n t.Category.toLowerCase().includes(search)\n );\n }\n\n this.filteredTypes = filtered;\n this.cdr.markForCheck();\n }\n\n // === Selection ===\n\n public selectType(type: TypeWithStats): void {\n this.selectedType = type;\n this.parseFieldSchema(type.FieldSchema);\n this.cdr.markForCheck();\n }\n\n public closeDetail(): void {\n this.selectedType = null;\n this.schemaProperties = [];\n this.cdr.markForCheck();\n }\n\n private parseFieldSchema(schemaJson: string): void {\n try {\n const schema = JSON.parse(schemaJson) as { properties?: Record<string, Record<string, unknown>>; required?: string[] };\n const properties = schema.properties || {};\n const required = schema.required || [];\n\n this.schemaProperties = Object.entries(properties).map(([name, prop]) => ({\n name,\n type: (prop.type as string) || 'string',\n title: (prop.title as string) || name,\n description: (prop.description as string) || '',\n isSecret: prop.isSecret === true,\n required: required.includes(name)\n }));\n\n // Sort by order if available, otherwise by name\n this.schemaProperties.sort((a, b) => {\n const propA = properties[a.name];\n const propB = properties[b.name];\n const orderA = typeof propA.order === 'number' ? propA.order : 999;\n const orderB = typeof propB.order === 'number' ? propB.order : 999;\n return orderA - orderB;\n });\n\n } catch (e) {\n console.error('Failed to parse field schema:', e);\n this.schemaProperties = [];\n }\n }\n\n // === Helpers ===\n\n public getCategoryIcon(category: string): string {\n const iconMap: Record<string, string> = {\n 'AI': 'fa-solid fa-brain',\n 'Communication': 'fa-solid fa-envelope',\n 'Storage': 'fa-solid fa-cloud',\n 'Database': 'fa-solid fa-database',\n 'Authentication': 'fa-solid fa-shield-halved',\n 'Integration': 'fa-solid fa-plug'\n };\n return iconMap[category] || 'fa-solid fa-key';\n }\n\n public getCategoryColor(category: string): string {\n const colorMap: Record<string, string> = {\n 'AI': 'var(--mj-brand-primary)',\n 'Communication': 'var(--mj-brand-primary)',\n 'Storage': 'var(--mj-brand-primary)',\n 'Database': 'var(--mj-status-warning)',\n 'Authentication': 'var(--mj-status-success)',\n 'Integration': 'var(--mj-brand-primary)'\n };\n return colorMap[category] || 'var(--mj-brand-primary)';\n }\n\n public getTypesByCategory(): Map<string, TypeWithStats[]> {\n const grouped = new Map<string, TypeWithStats[]>();\n for (const type of this.filteredTypes) {\n const category = type.Category;\n if (!grouped.has(category)) {\n grouped.set(category, []);\n }\n grouped.get(category)!.push(type);\n }\n return grouped;\n }\n\n /** Case-insensitive UUID check whether a credential type is the currently selected type. */\n public IsTypeSelected(type: TypeWithStats): boolean {\n return UUIDsEqual(this.selectedType?.ID, type.ID);\n }\n\n public getTotalCredentialCount(): number {\n return this.types.reduce((sum, t) => sum + t.credentialCount, 0);\n }\n\n public refresh(): void {\n this.loadData();\n }\n}\n","<div class=\"types-container\">\n @if (isLoading) {\n <mj-loading text=\"Loading credential types...\"></mj-loading>\n }\n\n @if (!isLoading) {\n <!-- Header -->\n <div class=\"types-header\">\n <div class=\"header-info\">\n <h2 class=\"types-title\">Credential Types</h2>\n <div class=\"header-stats\">\n <span class=\"stat-item\">\n <i class=\"fa-solid fa-shapes\"></i>\n {{types.length}} types\n </span>\n <span class=\"stat-item\">\n <i class=\"fa-solid fa-folder\"></i>\n {{categories.length}} categories\n </span>\n <span class=\"stat-item\">\n <i class=\"fa-solid fa-key\"></i>\n {{getTotalCredentialCount()}} credentials\n </span>\n </div>\n </div>\n <div class=\"header-actions\">\n @if (UserCanCreate) {\n <button class=\"btn-primary\" (click)=\"createNewType()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>New Type</span>\n </button>\n }\n </div>\n </div>\n <!-- Toolbar -->\n <div class=\"toolbar\">\n <div class=\"toolbar-left\">\n <div class=\"search-container\">\n <i class=\"fa-solid fa-search\"></i>\n <input\n type=\"text\"\n placeholder=\"Search types...\"\n [value]=\"searchText\"\n (input)=\"onSearchChange($any($event.target).value)\"\n />\n @if (searchText) {\n <button class=\"search-clear\" (click)=\"onSearchChange('')\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n <select\n class=\"filter-select\"\n [value]=\"selectedCategoryFilter\"\n (change)=\"onCategoryFilterChange($any($event.target).value)\"\n >\n <option value=\"\">All Categories</option>\n @for (cat of categories; track cat) {\n <option [value]=\"cat\">{{cat}}</option>\n }\n </select>\n </div>\n <div class=\"toolbar-right\">\n <div class=\"results-info\">\n {{filteredTypes.length}} of {{types.length}} types\n </div>\n <button class=\"btn-icon\" (click)=\"refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n </div>\n </div>\n <div class=\"types-layout\">\n <!-- Types List -->\n <div class=\"types-list\">\n @for (entry of getTypesByCategory() | keyvalue; track entry) {\n <div class=\"category-section\">\n <div class=\"category-header\" [style.borderLeftColor]=\"getCategoryColor(entry.key)\">\n <i [class]=\"getCategoryIcon(entry.key)\" [style.color]=\"getCategoryColor(entry.key)\"></i>\n <span class=\"category-name\">{{entry.key}}</span>\n <span class=\"count\">{{entry.value.length}}</span>\n </div>\n <div class=\"type-items\">\n @for (type of entry.value; track type) {\n <div\n class=\"type-item\"\n [class.selected]=\"IsTypeSelected(type)\"\n (click)=\"selectType(type)\"\n >\n <div class=\"type-icon\" [style.backgroundColor]=\"getCategoryColor(type.Category) + '15'\" [style.color]=\"getCategoryColor(type.Category)\">\n <i [class]=\"type.IconClass || 'fa-solid fa-key'\"></i>\n </div>\n <div class=\"type-info\">\n <div class=\"type-name\">{{type.Name}}</div>\n @if (type.Description) {\n <div class=\"type-description\">\n {{type.Description | slice:0:60}}{{type.Description.length > 60 ? '...' : ''}}\n </div>\n }\n <div class=\"type-meta\">\n @if (type.credentialCount > 0) {\n <span class=\"meta-badge\">\n <i class=\"fa-solid fa-key\"></i>\n {{type.credentialCount}}\n </span>\n }\n @if (type.activeCount > 0) {\n <span class=\"meta-badge active\">\n <i class=\"fa-solid fa-check\"></i>\n {{type.activeCount}} active\n </span>\n }\n @if (type.expiringCount > 0) {\n <span class=\"meta-badge warning\">\n <i class=\"fa-solid fa-clock\"></i>\n {{type.expiringCount}} expiring\n </span>\n }\n </div>\n </div>\n <div class=\"type-actions\">\n @if (UserCanCreateCredential) {\n <button mjButton variant=\"flat\" size=\"sm\"\n (click)=\"createCredentialForType(type, $event)\"\n title=\"Add Credential\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n }\n @if (UserCanUpdate) {\n <button mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editType(type, $event)\"\n title=\"Edit Type\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n }\n @if (UserCanDelete && type.credentialCount === 0) {\n <button mjButton variant=\"danger\" size=\"sm\"\n (click)=\"deleteType(type, $event)\"\n title=\"Delete Type\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n }\n </div>\n <i class=\"fa-solid fa-chevron-right arrow\"></i>\n </div>\n }\n </div>\n </div>\n }\n @if (filteredTypes.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-cubes\"></i>\n </div>\n <h3>No Credential Types Found</h3>\n @if (searchText || selectedCategoryFilter) {\n <p>\n No types match your current filters.\n <button class=\"btn-link\" (click)=\"clearFilters()\">Clear filters</button>\n </p>\n }\n @if (!searchText && !selectedCategoryFilter) {\n <p>\n Get started by creating your first credential type.\n </p>\n }\n @if (UserCanCreate && !searchText && !selectedCategoryFilter) {\n <button class=\"btn-primary\" (click)=\"createNewType()\">\n <i class=\"fa-solid fa-plus\"></i>\n Create Type\n </button>\n }\n </div>\n }\n </div>\n <!-- Type Detail -->\n @if (selectedType) {\n <div class=\"type-detail\">\n <div class=\"detail-header\">\n <div class=\"detail-icon\" [style.backgroundColor]=\"getCategoryColor(selectedType.Category) + '15'\" [style.color]=\"getCategoryColor(selectedType.Category)\">\n <i [class]=\"selectedType.IconClass || 'fa-solid fa-key'\"></i>\n </div>\n <div class=\"detail-title\">\n <h2>{{selectedType.Name}}</h2>\n <span class=\"category-badge\" [style.backgroundColor]=\"getCategoryColor(selectedType.Category) + '20'\" [style.color]=\"getCategoryColor(selectedType.Category)\">\n <i [class]=\"getCategoryIcon(selectedType.Category)\"></i>\n {{selectedType.Category}}\n </span>\n </div>\n <div class=\"detail-actions\">\n @if (UserCanUpdate) {\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"editType(selectedType)\" title=\"Edit\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n }\n <button class=\"close-btn\" (click)=\"closeDetail()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n </div>\n <div class=\"detail-body\">\n <!-- Stats Row -->\n <div class=\"detail-stats\">\n <div class=\"detail-stat\">\n <div class=\"stat-value\">{{selectedType.credentialCount}}</div>\n <div class=\"stat-label\">Credentials</div>\n </div>\n <div class=\"detail-stat active\">\n <div class=\"stat-value\">{{selectedType.activeCount}}</div>\n <div class=\"stat-label\">Active</div>\n </div>\n @if (selectedType.expiringCount > 0) {\n <div class=\"detail-stat warning\">\n <div class=\"stat-value\">{{selectedType.expiringCount}}</div>\n <div class=\"stat-label\">Expiring</div>\n </div>\n }\n </div>\n @if (selectedType.Description) {\n <p class=\"description\">\n {{selectedType.Description}}\n </p>\n }\n <div class=\"schema-section\">\n <h3>\n <i class=\"fa-solid fa-list-check\"></i>\n Field Schema\n </h3>\n @if (schemaProperties.length > 0) {\n <div class=\"field-list\">\n @for (prop of schemaProperties; track prop) {\n <div class=\"field-item\">\n <div class=\"field-header\">\n <span class=\"field-name\">{{prop.title}}</span>\n <span class=\"field-badges\">\n <span class=\"badge type\">{{prop.type}}</span>\n @if (prop.isSecret) {\n <span class=\"badge secret\">\n <i class=\"fa-solid fa-lock\"></i> Secret\n </span>\n }\n @if (prop.required) {\n <span class=\"badge required\">Required</span>\n }\n </span>\n </div>\n @if (prop.description) {\n <p class=\"field-description\">\n {{prop.description}}\n </p>\n }\n </div>\n }\n </div>\n }\n @if (schemaProperties.length === 0) {\n <div class=\"no-fields\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>No fields defined in schema</span>\n </div>\n }\n </div>\n @if (selectedType.ValidationEndpoint) {\n <div class=\"validation-section\">\n <h3>\n <i class=\"fa-solid fa-check-circle\"></i>\n Validation\n </h3>\n <div class=\"validation-endpoint\">\n <i class=\"fa-solid fa-link\"></i>\n <span>{{selectedType.ValidationEndpoint}}</span>\n </div>\n </div>\n }\n <!-- Quick Actions -->\n @if (UserCanCreateCredential) {\n <div class=\"detail-quick-actions\">\n <button class=\"btn-primary\" (click)=\"createCredentialForType(selectedType)\">\n <i class=\"fa-solid fa-plus\"></i>\n Create Credential\n </button>\n </div>\n }\n </div>\n </div>\n }\n <!-- No Selection -->\n @if (!selectedType && filteredTypes.length > 0) {\n <div class=\"no-selection\">\n <div class=\"no-selection-icon\">\n <i class=\"fa-solid fa-hand-pointer\"></i>\n </div>\n <h3>Select a Credential Type</h3>\n <p>Click on a credential type to view its details and field schema</p>\n </div>\n }\n </div>\n }\n</div>\n\n<!-- Type Edit Panel -->\n<mj-credential-type-edit-panel\n #typeEditPanel\n (saved)=\"onTypeSaved($any($event))\"\n (deleted)=\"onTypeDeleted($any($event))\"\n></mj-credential-type-edit-panel>\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"credentials-dashboard.component.d.ts","sourceRoot":"","sources":["../../src/Credentials/credentials-dashboard.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,aAAa,EAAE,SAAS,EAAE,iBAAiB,EAA2B,MAAM,eAAe,CAAC;AAChH,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAK1D,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;;AAG7D,UAAU,yBAAyB;IAC/B,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,qBAQa,6BAA8B,SAAQ,aAAc,YAAW,aAAa,EAAE,SAAS;IAyBpF,OAAO,CAAC,GAAG;IAxBhB,SAAS,UAAS;IAClB,SAAS,SAAc;IACvB,aAAa,SAAK;IAGlB,eAAe,SAAK;IACpB,SAAS,SAAK;IAGrB,OAAO,CAAC,WAAW,CAAqB;IAGjC,eAAe,EAAE,MAAM,EAAE,CAA+D;IAExF,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMtC;IAEF,OAAO,CAAC,kBAAkB,CAA4C;gBAElD,GAAG,EAAE,iBAAiB;IAKpC,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAIjE,eAAe,IAAI,IAAI;IAOvB,WAAW,IAAI,IAAI;YAIL,UAAU;IA6BjB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAehC,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIzC,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,eAAe;IAQhB,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,yBAAyB,CAAC,GAAG,IAAI;IAWrE,aAAa,IAAI,IAAI;IAWrB,QAAQ,IAAI,IAAI;IAYT,kBAAkB,IAAI,MAAM;yCA/I1B,6BAA6B;2CAA7B,6BAA6B;CAkJzC"}
1
+ {"version":3,"file":"credentials-dashboard.component.d.ts","sourceRoot":"","sources":["../../src/Credentials/credentials-dashboard.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,aAAa,EAAE,SAAS,EAAE,iBAAiB,EAA2B,MAAM,eAAe,CAAC;AAChH,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAK1D,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;;AAG7D,UAAU,yBAAyB;IAC/B,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,qBAQa,6BAA8B,SAAQ,aAAc,YAAW,aAAa,EAAE,SAAS;IAyBpF,OAAO,CAAC,GAAG;IAxBhB,SAAS,UAAS;IAClB,SAAS,SAAc;IACvB,aAAa,SAAK;IAGlB,eAAe,SAAK;IACpB,SAAS,SAAK;IAGrB,OAAO,CAAC,WAAW,CAAqB;IAGjC,eAAe,EAAE,MAAM,EAAE,CAA+D;IAExF,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMtC;IAEF,OAAO,CAAC,kBAAkB,CAA4C;gBAElD,GAAG,EAAE,iBAAiB;IAKpC,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAIjE,eAAe,IAAI,IAAI;IAOvB,WAAW,IAAI,IAAI;YAKL,UAAU;IA6BjB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAehC,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIzC,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,eAAe;IAQhB,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,yBAAyB,CAAC,GAAG,IAAI;IAWrE,aAAa,IAAI,IAAI;IAWrB,QAAQ,IAAI,IAAI;IAYT,kBAAkB,IAAI,MAAM;yCAhJ1B,6BAA6B;2CAA7B,6BAA6B;CAmJzC"}
@@ -95,6 +95,7 @@ let CredentialsDashboardComponent = class CredentialsDashboardComponent extends
95
95
  this.cdr.detectChanges();
96
96
  }
97
97
  ngOnDestroy() {
98
+ super.ngOnDestroy();
98
99
  this.stateChangeSubject.complete();
99
100
  }
100
101
  async loadCounts() {
@@ -1 +1 @@
1
- {"version":3,"file":"credentials-dashboard.component.js","sourceRoot":"","sources":["../../src/Credentials/credentials-dashboard.component.ts","../../src/Credentials/credentials-dashboard.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, AfterViewInit, OnDestroy, ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core';\nimport { BaseDashboard } from '@memberjunction/ng-shared';\nimport { RegisterClass } from '@memberjunction/global';\nimport { Subject } from 'rxjs';\nimport { debounceTime } from 'rxjs/operators';\nimport { SharedService } from '@memberjunction/ng-shared';\nimport { ResourceData } from '@memberjunction/core-entities';\nimport { RunView } from '@memberjunction/core';\n\ninterface CredentialsDashboardState {\n activeTab: string;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-credentials-dashboard',\n templateUrl: './credentials-dashboard.component.html',\n styleUrls: ['./credentials-dashboard.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\n@RegisterClass(BaseDashboard, 'CredentialsDashboard')\nexport class CredentialsDashboardComponent extends BaseDashboard implements AfterViewInit, OnDestroy {\n public isLoading = false;\n public activeTab = 'overview';\n public selectedIndex = 0;\n\n // Counts for badges\n public credentialCount = 0;\n public typeCount = 0;\n\n // Track visited tabs for lazy loading\n private visitedTabs = new Set<string>();\n\n // Navigation items\n public navigationItems: string[] = ['overview', 'credentials', 'types', 'categories', 'audit'];\n\n public tabLabels: Record<string, string> = {\n 'overview': 'Overview',\n 'credentials': 'Credentials',\n 'types': 'Credential Types',\n 'categories': 'Categories',\n 'audit': 'Audit Trail'\n };\n\n private stateChangeSubject = new Subject<CredentialsDashboardState>();\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n this.setupStateManagement();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return \"Credentials\";\n }\n\n ngAfterViewInit(): void {\n this.visitedTabs.add(this.activeTab);\n this.loadCounts();\n this.emitStateChange();\n this.cdr.detectChanges();\n }\n\n ngOnDestroy(): void {\n this.stateChangeSubject.complete();\n }\n\n private async loadCounts(): Promise<void> {\n try {\n const rv = new RunView();\n\n // Load credential count\n const credResult = await rv.RunView({\n EntityName: 'MJ: Credentials',\n ExtraFilter: 'IsActive = 1',\n ResultType: 'count_only'\n });\n if (credResult.Success) {\n this.credentialCount = credResult.RowCount;\n }\n\n // Load type count\n const typeResult = await rv.RunView({\n EntityName: 'MJ: Credential Types',\n ResultType: 'count_only'\n });\n if (typeResult.Success) {\n this.typeCount = typeResult.RowCount;\n }\n\n this.cdr.markForCheck();\n } catch (error) {\n console.error('Error loading counts:', error);\n }\n }\n\n public onTabChange(tabId: string): void {\n this.activeTab = tabId;\n const index = this.navigationItems.indexOf(tabId);\n\n this.selectedIndex = index >= 0 ? index : 0;\n\n setTimeout(() => {\n SharedService.Instance.InvokeManualResize();\n }, 100);\n\n this.visitedTabs.add(tabId);\n this.emitStateChange();\n this.cdr.markForCheck();\n }\n\n public hasVisited(tabId: string): boolean {\n return this.visitedTabs.has(tabId);\n }\n\n private setupStateManagement(): void {\n this.stateChangeSubject.pipe(\n debounceTime(50)\n ).subscribe(state => {\n this.UserStateChanged.emit(state);\n });\n }\n\n private emitStateChange(): void {\n const state: CredentialsDashboardState = {\n activeTab: this.activeTab\n };\n\n this.stateChangeSubject.next(state);\n }\n\n public loadUserState(state: Partial<CredentialsDashboardState>): void {\n if (state.activeTab) {\n this.activeTab = state.activeTab;\n const index = this.navigationItems.indexOf(state.activeTab);\n this.selectedIndex = index >= 0 ? index : 0;\n this.visitedTabs.add(state.activeTab);\n }\n\n this.cdr.markForCheck();\n }\n\n initDashboard(): void {\n try {\n this.isLoading = true;\n } catch (error) {\n console.error('Error initializing Credentials dashboard:', error);\n this.Error.emit(new Error('Failed to initialize Credentials dashboard. Please try again.'));\n } finally {\n this.isLoading = false;\n }\n }\n\n loadData(): void {\n if (this.Config?.userState) {\n setTimeout(() => {\n if (this.Config?.userState) {\n this.loadUserState(this.Config.userState);\n }\n }, 0);\n }\n\n this.NotifyLoadComplete();\n }\n\n public getCurrentTabLabel(): string {\n return this.tabLabels[this.activeTab] || 'Credential Management';\n }\n}\n","<div class=\"credentials-dashboard-container\">\n <div class=\"dashboard-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-key\"></i>\n <span>Credential Management</span>\n </div>\n <div class=\"header-actions\">\n <div class=\"security-badge\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span>Encrypted</span>\n </div>\n <span class=\"tab-label\">{{getCurrentTabLabel()}}</span>\n </div>\n </div>\n\n <div class=\"dashboard-content\">\n <div class=\"sidebar\">\n <div class=\"sidebar-section\">\n <div class=\"sidebar-section-title\">Dashboard</div>\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'overview'\" (click)=\"onTabChange('overview')\">\n <i class=\"fa-solid fa-chart-pie\"></i>\n <span>Overview</span>\n </div>\n\n <div class=\"sidebar-section\">\n <div class=\"sidebar-section-title\">Management</div>\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'credentials'\" (click)=\"onTabChange('credentials')\">\n <i class=\"fa-solid fa-key\"></i>\n <span>Credentials</span>\n @if (credentialCount > 0) {\n <span class=\"badge\">{{credentialCount}}</span>\n }\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'types'\" (click)=\"onTabChange('types')\">\n <i class=\"fa-solid fa-cubes\"></i>\n <span>Types</span>\n @if (typeCount > 0) {\n <span class=\"badge\">{{typeCount}}</span>\n }\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'categories'\" (click)=\"onTabChange('categories')\">\n <i class=\"fa-solid fa-folder-tree\"></i>\n <span>Categories</span>\n </div>\n\n <div class=\"sidebar-section\">\n <div class=\"sidebar-section-title\">Security</div>\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'audit'\" (click)=\"onTabChange('audit')\">\n <i class=\"fa-solid fa-clipboard-list\"></i>\n <span>Audit Trail</span>\n </div>\n </div>\n\n <div class=\"main-content\">\n <div class=\"tab-container\">\n @switch (activeTab) {\n <!-- Overview Tab -->\n @case ('overview') {\n <div class=\"tab-content\">\n <mj-credentials-overview-resource></mj-credentials-overview-resource>\n </div>\n }\n <!-- Credentials Tab -->\n @case ('credentials') {\n <div class=\"tab-content\">\n <mj-credentials-list-resource></mj-credentials-list-resource>\n </div>\n }\n <!-- Types Tab -->\n @case ('types') {\n <div class=\"tab-content\">\n <mj-credentials-types-resource></mj-credentials-types-resource>\n </div>\n }\n <!-- Categories Tab -->\n @case ('categories') {\n <div class=\"tab-content\">\n <mj-credentials-categories-resource></mj-credentials-categories-resource>\n </div>\n }\n <!-- Audit Trail Tab -->\n @case ('audit') {\n <div class=\"tab-content\">\n <mj-credentials-audit-resource></mj-credentials-audit-resource>\n </div>\n }\n }\n </div>\n </div>\n </div>\n</div>\n"]}
1
+ {"version":3,"file":"credentials-dashboard.component.js","sourceRoot":"","sources":["../../src/Credentials/credentials-dashboard.component.ts","../../src/Credentials/credentials-dashboard.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, AfterViewInit, OnDestroy, ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core';\nimport { BaseDashboard } from '@memberjunction/ng-shared';\nimport { RegisterClass } from '@memberjunction/global';\nimport { Subject } from 'rxjs';\nimport { debounceTime } from 'rxjs/operators';\nimport { SharedService } from '@memberjunction/ng-shared';\nimport { ResourceData } from '@memberjunction/core-entities';\nimport { RunView } from '@memberjunction/core';\n\ninterface CredentialsDashboardState {\n activeTab: string;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-credentials-dashboard',\n templateUrl: './credentials-dashboard.component.html',\n styleUrls: ['./credentials-dashboard.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\n@RegisterClass(BaseDashboard, 'CredentialsDashboard')\nexport class CredentialsDashboardComponent extends BaseDashboard implements AfterViewInit, OnDestroy {\n public isLoading = false;\n public activeTab = 'overview';\n public selectedIndex = 0;\n\n // Counts for badges\n public credentialCount = 0;\n public typeCount = 0;\n\n // Track visited tabs for lazy loading\n private visitedTabs = new Set<string>();\n\n // Navigation items\n public navigationItems: string[] = ['overview', 'credentials', 'types', 'categories', 'audit'];\n\n public tabLabels: Record<string, string> = {\n 'overview': 'Overview',\n 'credentials': 'Credentials',\n 'types': 'Credential Types',\n 'categories': 'Categories',\n 'audit': 'Audit Trail'\n };\n\n private stateChangeSubject = new Subject<CredentialsDashboardState>();\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n this.setupStateManagement();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return \"Credentials\";\n }\n\n ngAfterViewInit(): void {\n this.visitedTabs.add(this.activeTab);\n this.loadCounts();\n this.emitStateChange();\n this.cdr.detectChanges();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n this.stateChangeSubject.complete();\n }\n\n private async loadCounts(): Promise<void> {\n try {\n const rv = new RunView();\n\n // Load credential count\n const credResult = await rv.RunView({\n EntityName: 'MJ: Credentials',\n ExtraFilter: 'IsActive = 1',\n ResultType: 'count_only'\n });\n if (credResult.Success) {\n this.credentialCount = credResult.RowCount;\n }\n\n // Load type count\n const typeResult = await rv.RunView({\n EntityName: 'MJ: Credential Types',\n ResultType: 'count_only'\n });\n if (typeResult.Success) {\n this.typeCount = typeResult.RowCount;\n }\n\n this.cdr.markForCheck();\n } catch (error) {\n console.error('Error loading counts:', error);\n }\n }\n\n public onTabChange(tabId: string): void {\n this.activeTab = tabId;\n const index = this.navigationItems.indexOf(tabId);\n\n this.selectedIndex = index >= 0 ? index : 0;\n\n setTimeout(() => {\n SharedService.Instance.InvokeManualResize();\n }, 100);\n\n this.visitedTabs.add(tabId);\n this.emitStateChange();\n this.cdr.markForCheck();\n }\n\n public hasVisited(tabId: string): boolean {\n return this.visitedTabs.has(tabId);\n }\n\n private setupStateManagement(): void {\n this.stateChangeSubject.pipe(\n debounceTime(50)\n ).subscribe(state => {\n this.UserStateChanged.emit(state);\n });\n }\n\n private emitStateChange(): void {\n const state: CredentialsDashboardState = {\n activeTab: this.activeTab\n };\n\n this.stateChangeSubject.next(state);\n }\n\n public loadUserState(state: Partial<CredentialsDashboardState>): void {\n if (state.activeTab) {\n this.activeTab = state.activeTab;\n const index = this.navigationItems.indexOf(state.activeTab);\n this.selectedIndex = index >= 0 ? index : 0;\n this.visitedTabs.add(state.activeTab);\n }\n\n this.cdr.markForCheck();\n }\n\n initDashboard(): void {\n try {\n this.isLoading = true;\n } catch (error) {\n console.error('Error initializing Credentials dashboard:', error);\n this.Error.emit(new Error('Failed to initialize Credentials dashboard. Please try again.'));\n } finally {\n this.isLoading = false;\n }\n }\n\n loadData(): void {\n if (this.Config?.userState) {\n setTimeout(() => {\n if (this.Config?.userState) {\n this.loadUserState(this.Config.userState);\n }\n }, 0);\n }\n\n this.NotifyLoadComplete();\n }\n\n public getCurrentTabLabel(): string {\n return this.tabLabels[this.activeTab] || 'Credential Management';\n }\n}\n","<div class=\"credentials-dashboard-container\">\n <div class=\"dashboard-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-key\"></i>\n <span>Credential Management</span>\n </div>\n <div class=\"header-actions\">\n <div class=\"security-badge\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span>Encrypted</span>\n </div>\n <span class=\"tab-label\">{{getCurrentTabLabel()}}</span>\n </div>\n </div>\n\n <div class=\"dashboard-content\">\n <div class=\"sidebar\">\n <div class=\"sidebar-section\">\n <div class=\"sidebar-section-title\">Dashboard</div>\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'overview'\" (click)=\"onTabChange('overview')\">\n <i class=\"fa-solid fa-chart-pie\"></i>\n <span>Overview</span>\n </div>\n\n <div class=\"sidebar-section\">\n <div class=\"sidebar-section-title\">Management</div>\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'credentials'\" (click)=\"onTabChange('credentials')\">\n <i class=\"fa-solid fa-key\"></i>\n <span>Credentials</span>\n @if (credentialCount > 0) {\n <span class=\"badge\">{{credentialCount}}</span>\n }\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'types'\" (click)=\"onTabChange('types')\">\n <i class=\"fa-solid fa-cubes\"></i>\n <span>Types</span>\n @if (typeCount > 0) {\n <span class=\"badge\">{{typeCount}}</span>\n }\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'categories'\" (click)=\"onTabChange('categories')\">\n <i class=\"fa-solid fa-folder-tree\"></i>\n <span>Categories</span>\n </div>\n\n <div class=\"sidebar-section\">\n <div class=\"sidebar-section-title\">Security</div>\n </div>\n <div class=\"nav-item\" [class.selected]=\"activeTab === 'audit'\" (click)=\"onTabChange('audit')\">\n <i class=\"fa-solid fa-clipboard-list\"></i>\n <span>Audit Trail</span>\n </div>\n </div>\n\n <div class=\"main-content\">\n <div class=\"tab-container\">\n @switch (activeTab) {\n <!-- Overview Tab -->\n @case ('overview') {\n <div class=\"tab-content\">\n <mj-credentials-overview-resource></mj-credentials-overview-resource>\n </div>\n }\n <!-- Credentials Tab -->\n @case ('credentials') {\n <div class=\"tab-content\">\n <mj-credentials-list-resource></mj-credentials-list-resource>\n </div>\n }\n <!-- Types Tab -->\n @case ('types') {\n <div class=\"tab-content\">\n <mj-credentials-types-resource></mj-credentials-types-resource>\n </div>\n }\n <!-- Categories Tab -->\n @case ('categories') {\n <div class=\"tab-content\">\n <mj-credentials-categories-resource></mj-credentials-categories-resource>\n </div>\n }\n <!-- Audit Trail Tab -->\n @case ('audit') {\n <div class=\"tab-content\">\n <mj-credentials-audit-resource></mj-credentials-audit-resource>\n </div>\n }\n }\n </div>\n </div>\n </div>\n</div>\n"]}
@@ -1,6 +1,6 @@
1
1
  import { OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
2
2
  import { ActivatedRoute } from '@angular/router';
3
- import { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';
3
+ import { BaseResourceComponent } from '@memberjunction/ng-shared';
4
4
  import { ResourceData, MJDashboardEntity, MJDashboardCategoryEntity, MJDashboardPartTypeEntity, DashboardUserPermissions } from '@memberjunction/core-entities';
5
5
  import { ShareDialogResult } from './dashboard-share-dialog.component';
6
6
  import { DashboardViewerComponent, DashboardNavRequestEvent, PanelInteractionEvent, AddPanelResult, DashboardPanel, EditPartDialogResult, DashboardOpenEvent, DashboardEditEvent, DashboardDeleteEvent, DashboardMoveEvent, DashboardCreateEvent, CategoryCreateEvent, CategoryDeleteEvent, CategoryChangeEvent, ViewPreferenceChangeEvent, DashboardBrowserViewMode, BreadcrumbNavigateEvent } from '@memberjunction/ng-dashboard-viewer';
@@ -17,7 +17,6 @@ type BrowserMode = 'list' | 'view' | 'edit';
17
17
  export declare class DashboardBrowserResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {
18
18
  private cdr;
19
19
  private route;
20
- private navigationService;
21
20
  mode: BrowserMode;
22
21
  isLoading: boolean;
23
22
  dashboards: MJDashboardEntity[];
@@ -44,7 +43,7 @@ export declare class DashboardBrowserResourceComponent extends BaseResourceCompo
44
43
  effectiveCategoryMap: Map<string, string | null>;
45
44
  private readonly _destroy$;
46
45
  dashboardViewer: DashboardViewerComponent;
47
- constructor(cdr: ChangeDetectorRef, route: ActivatedRoute, navigationService: NavigationService);
46
+ constructor(cdr: ChangeDetectorRef, route: ActivatedRoute);
48
47
  ngOnInit(): void;
49
48
  ngOnDestroy(): void;
50
49
  GetResourceDisplayName(data: ResourceData): Promise<string>;