@memberjunction/ng-dashboards 5.24.0 → 5.26.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 +49 -48
  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
@@ -12,10 +12,9 @@ import { BaseResourceComponent } from '@memberjunction/ng-shared';
12
12
  import { RunView, Metadata, CompositeKey, EntityRecordNameInput } from '@memberjunction/core';
13
13
  import { UserInfoEngine } from '@memberjunction/core-entities';
14
14
  import * as i0 from "@angular/core";
15
- import * as i1 from "@memberjunction/ng-shared";
16
- import * as i2 from "@angular/common";
17
- import * as i3 from "@angular/forms";
18
- import * as i4 from "@memberjunction/ng-shared-generic";
15
+ import * as i1 from "@angular/common";
16
+ import * as i2 from "@angular/forms";
17
+ import * as i3 from "@memberjunction/ng-shared-generic";
19
18
  function VersionHistoryDiffResourceComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
20
19
  i0.ɵɵelement(0, "mj-loading", 1);
21
20
  } }
@@ -494,7 +493,6 @@ function VersionHistoryDiffResourceComponent_Conditional_2_Template(rf, ctx) { i
494
493
  let VersionHistoryDiffResourceComponent = class VersionHistoryDiffResourceComponent extends BaseResourceComponent {
495
494
  static { VersionHistoryDiffResourceComponent_1 = this; }
496
495
  cdr;
497
- navigationService;
498
496
  IsLoading = true;
499
497
  IsDiffLoading = false;
500
498
  HasDiffResult = false;
@@ -521,16 +519,17 @@ let VersionHistoryDiffResourceComponent = class VersionHistoryDiffResourceCompon
521
519
  preferencesLoaded = false;
522
520
  destroy$ = new Subject();
523
521
  metadata = new Metadata();
524
- constructor(cdr, navigationService) {
522
+ constructor(cdr) {
525
523
  super();
526
524
  this.cdr = cdr;
527
- this.navigationService = navigationService;
528
525
  }
529
526
  ngOnInit() {
527
+ super.ngOnInit();
530
528
  this.loadUserPreferences();
531
529
  this.LoadLabels();
532
530
  }
533
531
  ngOnDestroy() {
532
+ super.ngOnDestroy();
534
533
  this.destroy$.next();
535
534
  this.destroy$.complete();
536
535
  }
@@ -1137,7 +1136,7 @@ let VersionHistoryDiffResourceComponent = class VersionHistoryDiffResourceCompon
1137
1136
  });
1138
1137
  this.FilteredEntityGroups = groups;
1139
1138
  }
1140
- static ɵfac = function VersionHistoryDiffResourceComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || VersionHistoryDiffResourceComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i1.NavigationService)); };
1139
+ static ɵfac = function VersionHistoryDiffResourceComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || VersionHistoryDiffResourceComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
1141
1140
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: VersionHistoryDiffResourceComponent, selectors: [["mj-version-history-diff-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 3, vars: 2, consts: [[1, "diff-container"], ["text", "Loading diff viewer..."], [1, "page-header"], [1, "header-left"], [1, "page-title"], [1, "page-subtitle"], [1, "config-panel"], [1, "mode-selector"], [1, "mode-btn", 3, "click"], [1, "fa-solid", "fa-clock-rotate-left"], [1, "fa-solid", "fa-code-compare"], [1, "label-selectors"], [1, "selector-group"], [1, "selector-label"], [1, "selector-input", 3, "ngModelChange", "ngModel"], ["value", ""], [3, "value"], [1, "selector-arrow"], [1, "btn-primary", 3, "click", "disabled"], [1, "fa-solid", "fa-play"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "empty-state"], ["title", "Swap direction", 1, "swap-btn", 3, "click"], [1, "fa-solid", "fa-arrows-rotate"], [1, "fa-solid", "fa-arrow-right"], [1, "current-state-badge"], [1, "diff-summary"], [1, "diff-stat", "change-added"], [1, "fa-solid", "fa-plus"], [1, "diff-stat-value"], [1, "diff-stat-label"], [1, "diff-stat", "change-removed"], [1, "fa-solid", "fa-minus"], [1, "diff-stat", "change-modified"], [1, "fa-solid", "fa-pen"], [1, "diff-stat", "change-unchanged"], [1, "fa-solid", "fa-equals"], [1, "diff-toolbar"], [1, "entity-groups"], [1, "diff-search"], [1, "fa-solid", "fa-search", "diff-search-icon"], ["type", "text", "placeholder", "Search by entity or record...", 1, "diff-search-input", 3, "ngModelChange", "ngModel"], [1, "diff-filter-pills"], [1, "filter-pill", 3, "click"], [1, "filter-pill", "change-added", 3, "click"], [1, "filter-pill", "change-removed", 3, "click"], [1, "filter-pill", "change-modified", 3, "click"], [1, "diff-toolbar-right"], ["title", "Expand all", 1, "toolbar-action-btn", 3, "click"], [1, "fa-solid", "fa-angles-down"], ["title", "Collapse all", 1, "toolbar-action-btn", 3, "click"], [1, "fa-solid", "fa-angles-up"], [1, "diff-sort-toggle"], ["title", "Sort by name", 1, "toggle-btn-sm", 3, "click"], [1, "fa-solid", 3, "ngClass"], ["title", "Sort by count", 1, "toggle-btn-sm", 3, "click"], [1, "entity-group"], [1, "entity-group-header", 3, "click"], [1, "entity-group-left"], [1, "fa-solid", "fa-chevron-right", "entity-chevron"], [1, "entity-icon"], [1, "entity-group-name"], [1, "entity-group-badges"], [1, "badge", "change-added"], [1, "badge", "change-removed"], [1, "badge", "change-modified"], [1, "entity-group-items"], [1, "diff-item-wrapper"], [1, "diff-item", 3, "click", "ngClass"], [1, "diff-item-icon"], [1, "diff-item-record"], [1, "diff-item-display-name"], [1, "diff-item-type"], ["title", "Open record", 1, "diff-item-open-btn", 3, "click"], [1, "fa-solid", "fa-arrow-up-right-from-square"], [1, "fa-solid", "fa-chevron-right", "diff-item-chevron", 3, "expanded"], [1, "diff-fields"], [1, "fa-solid", "fa-chevron-right", "diff-item-chevron"], ["text", "Loading changes...", "size", "small"], [1, "diff-fields-empty"], [1, "diff-field", 3, "ngClass"], [1, "diff-field-name"], [1, "diff-field-values"], [1, "diff-field-old"], [1, "fa-solid", "fa-arrow-right", "diff-field-arrow"], [1, "diff-field-new"], [1, "fa-solid", "fa-check-circle", "empty-icon", 2, "color", "#10b981"], [1, "fa-solid", "fa-code-compare", "empty-icon"]], template: function VersionHistoryDiffResourceComponent_Template(rf, ctx) { if (rf & 1) {
1142
1141
  i0.ɵɵelementStart(0, "div", 0);
1143
1142
  i0.ɵɵconditionalCreate(1, VersionHistoryDiffResourceComponent_Conditional_1_Template, 1, 0, "mj-loading", 1);
@@ -1148,7 +1147,7 @@ let VersionHistoryDiffResourceComponent = class VersionHistoryDiffResourceCompon
1148
1147
  i0.ɵɵconditional(ctx.IsLoading ? 1 : -1);
1149
1148
  i0.ɵɵadvance();
1150
1149
  i0.ɵɵconditional(!ctx.IsLoading ? 2 : -1);
1151
- } }, dependencies: [i2.NgClass, i3.NgSelectOption, i3.ɵNgSelectMultipleOption, i3.DefaultValueAccessor, i3.SelectControlValueAccessor, i3.NgControlStatus, i3.NgModel, i4.LoadingComponent, i2.SlicePipe], styles: [".diff-container[_ngcontent-%COMP%] {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n}\n\n\n\n.page-header[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n\n.page-title[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 4px 0;\n}\n\n.page-subtitle[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n\n\n.config-panel[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 24px;\n margin-bottom: 24px;\n}\n\n.mode-selector[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-bottom: 20px;\n}\n\n.mode-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 18px;\n background: var(--mj-bg-surface-sunken);\n border: 2px solid transparent;\n border-radius: 8px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.mode-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n}\n\n.mode-btn.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n\n\n.label-selectors[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-end;\n gap: 16px;\n margin-bottom: 20px;\n}\n\n.selector-group[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.selector-label[_ngcontent-%COMP%] {\n display: block;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 6px;\n}\n\n.selector-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 14px;\n color: var(--mj-text-primary);\n outline: none;\n box-sizing: border-box;\n}\n\n.selector-input[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.selector-arrow[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n padding-bottom: 8px;\n color: var(--mj-text-secondary);\n font-size: 16px;\n}\n\n.current-state-badge[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n padding: 2px 8px;\n border-radius: 8px;\n white-space: nowrap;\n}\n\n\n\n.btn-primary[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 10px 24px;\n background: var(--mj-brand-primary);\n border: none;\n border-radius: 8px;\n color: var(--mj-text-inverse);\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-primary[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n\n.diff-summary[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 12px;\n margin-bottom: 24px;\n}\n\n.diff-stat[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 20px;\n border-radius: 10px;\n border: 1px solid var(--mj-border-default);\n}\n\n.diff-stat[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.diff-stat-value[_ngcontent-%COMP%] {\n font-size: 22px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.diff-stat-label[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n\n\n.change-added[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-status-success) 20%, transparent);\n color: var(--mj-status-success);\n}\n\n.change-removed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-status-error) 20%, transparent);\n color: var(--mj-status-error);\n}\n\n.change-modified[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-status-warning) 20%, transparent);\n color: var(--mj-status-warning);\n}\n\n.change-unchanged[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-text-muted) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-text-muted) 20%, transparent);\n color: var(--mj-text-muted);\n}\n\n\n\n.entity-groups[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.entity-group[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.entity-group-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.entity-group-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.entity-group-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.entity-group-left[_ngcontent-%COMP%] i[_ngcontent-%COMP%]:first-child {\n font-size: 12px;\n color: var(--mj-text-muted);\n width: 16px;\n}\n\n.entity-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.entity-group-name[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.entity-group-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n}\n\n.badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n border: none;\n}\n\n\n\n.entity-chevron[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n width: 14px;\n text-align: center;\n transition: transform 0.2s ease;\n}\n\n.entity-chevron.expanded[_ngcontent-%COMP%] {\n transform: rotate(90deg);\n}\n\n\n\n.entity-group-items[_ngcontent-%COMP%] {\n border-top: 1px solid var(--mj-border-default);\n padding: 8px 16px;\n}\n\n.diff-item-wrapper[_ngcontent-%COMP%] {\n margin-bottom: 2px;\n}\n\n.diff-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 12px;\n border-radius: 6px;\n}\n\n.diff-item.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.diff-item.clickable[_ngcontent-%COMP%]:hover {\n filter: brightness(0.97);\n}\n\n.diff-item-icon[_ngcontent-%COMP%] {\n font-size: 12px;\n width: 20px;\n text-align: center;\n}\n\n.diff-item-record[_ngcontent-%COMP%] {\n font-size: 13px;\n font-family: 'SF Mono', 'Fira Code', monospace;\n color: var(--mj-text-primary);\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-item-display-name[_ngcontent-%COMP%] {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n color: var(--mj-text-secondary);\n font-weight: 500;\n}\n\n.diff-item-open-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n border: 1px solid transparent;\n border-radius: 4px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 11px;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.diff-item-open-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, transparent);\n}\n\n.diff-item-type[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.diff-item-chevron[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 0.2s ease;\n}\n\n.diff-item-chevron.expanded[_ngcontent-%COMP%] {\n transform: rotate(90deg);\n}\n\n\n\n.diff-fields[_ngcontent-%COMP%] {\n margin-left: 42px;\n margin-bottom: 8px;\n padding: 8px 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.diff-field[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 6px 10px;\n border-radius: 6px;\n font-size: 13px;\n}\n\n.diff-field.change-added[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 6%, transparent);\n}\n\n.diff-field.change-modified[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 6%, transparent);\n}\n\n.diff-field.change-removed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 6%, transparent);\n}\n\n.diff-field-name[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n min-width: 120px;\n flex-shrink: 0;\n}\n\n.diff-field-values[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n flex: 1;\n}\n\n.diff-field-old[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n text-decoration: line-through;\n opacity: 0.8;\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-field-arrow[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 10px;\n flex-shrink: 0;\n}\n\n.diff-field-new[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-fields-empty[_ngcontent-%COMP%] {\n padding: 6px 10px;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n\n\n.diff-toolbar-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.toolbar-action-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-muted);\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.toolbar-action-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, transparent);\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 20px;\n text-align: center;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--mj-text-muted);\n margin-bottom: 16px;\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 600;\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;\n max-width: 400px;\n}\n\n\n\n.swap-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border: 1px solid var(--mj-border-default);\n border-radius: 50%;\n background: var(--mj-bg-surface-card);\n color: var(--mj-brand-primary);\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.swap-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n border-color: var(--mj-brand-primary);\n transform: rotate(180deg);\n}\n\n\n\n.diff-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 16px;\n flex-wrap: wrap;\n}\n\n.diff-search[_ngcontent-%COMP%] {\n position: relative;\n flex: 1;\n min-width: 200px;\n}\n\n.diff-search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.diff-search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 8px 12px 8px 36px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n box-sizing: border-box;\n}\n\n.diff-search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.diff-filter-pills[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.filter-pill[_ngcontent-%COMP%] {\n padding: 6px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n background: var(--mj-bg-surface-card);\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.filter-pill[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.filter-pill.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.filter-pill.change-added.active[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n border-color: var(--mj-status-success);\n}\n\n.filter-pill.change-removed.active[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n border-color: var(--mj-status-error);\n}\n\n.filter-pill.change-modified.active[_ngcontent-%COMP%] {\n background: var(--mj-status-warning);\n border-color: var(--mj-status-warning);\n}\n\n.diff-sort-toggle[_ngcontent-%COMP%] {\n display: flex;\n gap: 2px;\n}\n\n.toggle-btn-sm[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-muted);\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.toggle-btn-sm[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.toggle-btn-sm.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n@media (max-width: 768px) {\n .diff-summary[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .label-selectors[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n}"], changeDetection: 0 });
1150
+ } }, dependencies: [i1.NgClass, i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.LoadingComponent, i1.SlicePipe], styles: [".diff-container[_ngcontent-%COMP%] {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n}\n\n\n\n.page-header[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n\n.page-title[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 4px 0;\n}\n\n.page-subtitle[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n\n\n.config-panel[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 24px;\n margin-bottom: 24px;\n}\n\n.mode-selector[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-bottom: 20px;\n}\n\n.mode-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 18px;\n background: var(--mj-bg-surface-sunken);\n border: 2px solid transparent;\n border-radius: 8px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.mode-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n}\n\n.mode-btn.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n\n\n.label-selectors[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-end;\n gap: 16px;\n margin-bottom: 20px;\n}\n\n.selector-group[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.selector-label[_ngcontent-%COMP%] {\n display: block;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 6px;\n}\n\n.selector-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 14px;\n color: var(--mj-text-primary);\n outline: none;\n box-sizing: border-box;\n}\n\n.selector-input[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.selector-arrow[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n padding-bottom: 8px;\n color: var(--mj-text-secondary);\n font-size: 16px;\n}\n\n.current-state-badge[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n padding: 2px 8px;\n border-radius: 8px;\n white-space: nowrap;\n}\n\n\n\n.btn-primary[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 10px 24px;\n background: var(--mj-brand-primary);\n border: none;\n border-radius: 8px;\n color: var(--mj-text-inverse);\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-primary[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n\n.diff-summary[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 12px;\n margin-bottom: 24px;\n}\n\n.diff-stat[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 20px;\n border-radius: 10px;\n border: 1px solid var(--mj-border-default);\n}\n\n.diff-stat[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.diff-stat-value[_ngcontent-%COMP%] {\n font-size: 22px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.diff-stat-label[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n\n\n.change-added[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-status-success) 20%, transparent);\n color: var(--mj-status-success);\n}\n\n.change-removed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-status-error) 20%, transparent);\n color: var(--mj-status-error);\n}\n\n.change-modified[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-status-warning) 20%, transparent);\n color: var(--mj-status-warning);\n}\n\n.change-unchanged[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-text-muted) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-text-muted) 20%, transparent);\n color: var(--mj-text-muted);\n}\n\n\n\n.entity-groups[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.entity-group[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.entity-group-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.entity-group-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.entity-group-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.entity-group-left[_ngcontent-%COMP%] i[_ngcontent-%COMP%]:first-child {\n font-size: 12px;\n color: var(--mj-text-muted);\n width: 16px;\n}\n\n.entity-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.entity-group-name[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.entity-group-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n}\n\n.badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n border: none;\n}\n\n\n\n.entity-chevron[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n width: 14px;\n text-align: center;\n transition: transform 0.2s ease;\n}\n\n.entity-chevron.expanded[_ngcontent-%COMP%] {\n transform: rotate(90deg);\n}\n\n\n\n.entity-group-items[_ngcontent-%COMP%] {\n border-top: 1px solid var(--mj-border-default);\n padding: 8px 16px;\n}\n\n.diff-item-wrapper[_ngcontent-%COMP%] {\n margin-bottom: 2px;\n}\n\n.diff-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 12px;\n border-radius: 6px;\n}\n\n.diff-item.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.diff-item.clickable[_ngcontent-%COMP%]:hover {\n filter: brightness(0.97);\n}\n\n.diff-item-icon[_ngcontent-%COMP%] {\n font-size: 12px;\n width: 20px;\n text-align: center;\n}\n\n.diff-item-record[_ngcontent-%COMP%] {\n font-size: 13px;\n font-family: 'SF Mono', 'Fira Code', monospace;\n color: var(--mj-text-primary);\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-item-display-name[_ngcontent-%COMP%] {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n color: var(--mj-text-secondary);\n font-weight: 500;\n}\n\n.diff-item-open-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n border: 1px solid transparent;\n border-radius: 4px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 11px;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.diff-item-open-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, transparent);\n}\n\n.diff-item-type[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.diff-item-chevron[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 0.2s ease;\n}\n\n.diff-item-chevron.expanded[_ngcontent-%COMP%] {\n transform: rotate(90deg);\n}\n\n\n\n.diff-fields[_ngcontent-%COMP%] {\n margin-left: 42px;\n margin-bottom: 8px;\n padding: 8px 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.diff-field[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 6px 10px;\n border-radius: 6px;\n font-size: 13px;\n}\n\n.diff-field.change-added[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 6%, transparent);\n}\n\n.diff-field.change-modified[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 6%, transparent);\n}\n\n.diff-field.change-removed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 6%, transparent);\n}\n\n.diff-field-name[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n min-width: 120px;\n flex-shrink: 0;\n}\n\n.diff-field-values[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n flex: 1;\n}\n\n.diff-field-old[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n text-decoration: line-through;\n opacity: 0.8;\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-field-arrow[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 10px;\n flex-shrink: 0;\n}\n\n.diff-field-new[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-fields-empty[_ngcontent-%COMP%] {\n padding: 6px 10px;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n\n\n.diff-toolbar-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.toolbar-action-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-muted);\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.toolbar-action-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, transparent);\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 20px;\n text-align: center;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--mj-text-muted);\n margin-bottom: 16px;\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 600;\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;\n max-width: 400px;\n}\n\n\n\n.swap-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border: 1px solid var(--mj-border-default);\n border-radius: 50%;\n background: var(--mj-bg-surface-card);\n color: var(--mj-brand-primary);\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.swap-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n border-color: var(--mj-brand-primary);\n transform: rotate(180deg);\n}\n\n\n\n.diff-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 16px;\n flex-wrap: wrap;\n}\n\n.diff-search[_ngcontent-%COMP%] {\n position: relative;\n flex: 1;\n min-width: 200px;\n}\n\n.diff-search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.diff-search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 8px 12px 8px 36px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n box-sizing: border-box;\n}\n\n.diff-search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.diff-filter-pills[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.filter-pill[_ngcontent-%COMP%] {\n padding: 6px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n background: var(--mj-bg-surface-card);\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.filter-pill[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.filter-pill.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.filter-pill.change-added.active[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n border-color: var(--mj-status-success);\n}\n\n.filter-pill.change-removed.active[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n border-color: var(--mj-status-error);\n}\n\n.filter-pill.change-modified.active[_ngcontent-%COMP%] {\n background: var(--mj-status-warning);\n border-color: var(--mj-status-warning);\n}\n\n.diff-sort-toggle[_ngcontent-%COMP%] {\n display: flex;\n gap: 2px;\n}\n\n.toggle-btn-sm[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-muted);\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.toggle-btn-sm[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.toggle-btn-sm.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n@media (max-width: 768px) {\n .diff-summary[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .label-selectors[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n}"], changeDetection: 0 });
1152
1151
  };
1153
1152
  VersionHistoryDiffResourceComponent = VersionHistoryDiffResourceComponent_1 = __decorate([
1154
1153
  RegisterClass(BaseResourceComponent, 'VersionHistoryDiffResource')
@@ -1157,6 +1156,6 @@ export { VersionHistoryDiffResourceComponent };
1157
1156
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(VersionHistoryDiffResourceComponent, [{
1158
1157
  type: Component,
1159
1158
  args: [{ standalone: false, selector: 'mj-version-history-diff-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"diff-container\">\n @if (IsLoading) {\n <mj-loading text=\"Loading diff viewer...\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <!-- Header -->\n <div class=\"page-header\">\n <div class=\"header-left\">\n <h2 class=\"page-title\">Diff Viewer</h2>\n <p class=\"page-subtitle\">Compare states between version labels or against current data</p>\n </div>\n </div>\n <!-- Diff Configuration Panel -->\n <div class=\"config-panel\">\n <!-- Mode Selector -->\n <div class=\"mode-selector\">\n <button class=\"mode-btn\"\n [class.active]=\"DiffMode === 'label-to-current'\"\n (click)=\"OnDiffModeChange('label-to-current')\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n Label vs Current\n </button>\n <button class=\"mode-btn\"\n [class.active]=\"DiffMode === 'label-to-label'\"\n (click)=\"OnDiffModeChange('label-to-label')\">\n <i class=\"fa-solid fa-code-compare\"></i>\n Label vs Label\n </button>\n </div>\n <!-- Label Selectors -->\n <div class=\"label-selectors\">\n <div class=\"selector-group\">\n <label class=\"selector-label\">\n {{DiffMode === 'label-to-current' ? 'Compare label' : 'From label'}}\n </label>\n <select class=\"selector-input\"\n [(ngModel)]=\"FromLabelId\">\n <option value=\"\">Select a label...</option>\n @for (label of FilteredFromLabels; track label) {\n <option\n [value]=\"label.ID\">\n {{FormatLabelOption(label)}}\n </option>\n }\n </select>\n </div>\n @if (DiffMode === 'label-to-label') {\n <div class=\"selector-arrow\">\n <button class=\"swap-btn\" (click)=\"SwapLabels()\" title=\"Swap direction\">\n <i class=\"fa-solid fa-arrows-rotate\"></i>\n </button>\n </div>\n }\n @if (DiffMode === 'label-to-current') {\n <div class=\"selector-arrow\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n <span class=\"current-state-badge\">Current State</span>\n </div>\n }\n @if (DiffMode === 'label-to-label') {\n <div class=\"selector-group\">\n <label class=\"selector-label\">To label</label>\n <select class=\"selector-input\"\n [(ngModel)]=\"ToLabelId\">\n <option value=\"\">Select a label...</option>\n @for (label of FilteredToLabels; track label) {\n <option\n [value]=\"label.ID\">\n {{FormatLabelOption(label)}}\n </option>\n }\n </select>\n </div>\n }\n </div>\n <!-- Run Button -->\n <button class=\"btn-primary\"\n [disabled]=\"!CanRunDiff || IsDiffLoading\"\n (click)=\"RunDiff()\">\n @if (!IsDiffLoading) {\n <i class=\"fa-solid fa-play\"></i>\n }\n @if (IsDiffLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n }\n <span>{{IsDiffLoading ? 'Comparing...' : 'Compare'}}</span>\n </button>\n </div>\n <!-- Diff Results -->\n @if (HasDiffResult) {\n <!-- Summary Stats -->\n <div class=\"diff-summary\">\n <div class=\"diff-stat change-added\">\n <i class=\"fa-solid fa-plus\"></i>\n <span class=\"diff-stat-value\">{{TotalAdded}}</span>\n <span class=\"diff-stat-label\">Added</span>\n </div>\n <div class=\"diff-stat change-removed\">\n <i class=\"fa-solid fa-minus\"></i>\n <span class=\"diff-stat-value\">{{TotalRemoved}}</span>\n <span class=\"diff-stat-label\">Removed</span>\n </div>\n <div class=\"diff-stat change-modified\">\n <i class=\"fa-solid fa-pen\"></i>\n <span class=\"diff-stat-value\">{{TotalModified}}</span>\n <span class=\"diff-stat-label\">Modified</span>\n </div>\n <div class=\"diff-stat change-unchanged\">\n <i class=\"fa-solid fa-equals\"></i>\n <span class=\"diff-stat-value\">{{TotalUnchanged}}</span>\n <span class=\"diff-stat-label\">Unchanged</span>\n </div>\n </div>\n <!-- Results toolbar -->\n @if (EntityGroups.length > 0) {\n <div class=\"diff-toolbar\">\n <div class=\"diff-search\">\n <i class=\"fa-solid fa-search diff-search-icon\"></i>\n <input type=\"text\" class=\"diff-search-input\"\n placeholder=\"Search by entity or record...\"\n [ngModel]=\"DiffSearch\"\n (ngModelChange)=\"OnDiffSearchChange($event)\" />\n </div>\n <div class=\"diff-filter-pills\">\n <button class=\"filter-pill\" [class.active]=\"DiffFilterType === 'all'\"\n (click)=\"OnDiffFilterChange('all')\">All</button>\n <button class=\"filter-pill change-added\" [class.active]=\"DiffFilterType === 'added'\"\n (click)=\"OnDiffFilterChange('added')\">Added</button>\n <button class=\"filter-pill change-removed\" [class.active]=\"DiffFilterType === 'removed'\"\n (click)=\"OnDiffFilterChange('removed')\">Removed</button>\n <button class=\"filter-pill change-modified\" [class.active]=\"DiffFilterType === 'modified'\"\n (click)=\"OnDiffFilterChange('modified')\">Modified</button>\n </div>\n <div class=\"diff-toolbar-right\">\n <button class=\"toolbar-action-btn\" (click)=\"ExpandAllGroups()\" title=\"Expand all\">\n <i class=\"fa-solid fa-angles-down\"></i>\n </button>\n <button class=\"toolbar-action-btn\" (click)=\"CollapseAllGroups()\" title=\"Collapse all\">\n <i class=\"fa-solid fa-angles-up\"></i>\n </button>\n <div class=\"diff-sort-toggle\">\n <button class=\"toggle-btn-sm\" [class.active]=\"DiffSortBy === 'name'\"\n (click)=\"OnDiffSortChange('name')\" title=\"Sort by name\">\n <i class=\"fa-solid\" [ngClass]=\"DiffSortBy === 'name' && DiffSortDir === 'desc' ? 'fa-arrow-up-z-a' : 'fa-arrow-down-a-z'\"></i>\n </button>\n <button class=\"toggle-btn-sm\" [class.active]=\"DiffSortBy === 'count'\"\n (click)=\"OnDiffSortChange('count')\" title=\"Sort by count\">\n <i class=\"fa-solid\" [ngClass]=\"DiffSortBy === 'count' && DiffSortDir === 'asc' ? 'fa-arrow-up-1-9' : 'fa-arrow-down-9-1'\"></i>\n </button>\n </div>\n </div>\n </div>\n }\n <!-- Entity Groups -->\n @if (FilteredEntityGroups.length > 0) {\n <div class=\"entity-groups\">\n @for (group of FilteredEntityGroups; track group) {\n <div class=\"entity-group\">\n <div class=\"entity-group-header\" (click)=\"ToggleEntityGroup(group)\">\n <div class=\"entity-group-left\">\n <i class=\"fa-solid fa-chevron-right entity-chevron\"\n [class.expanded]=\"group.IsExpanded\">\n </i>\n <i [class]=\"group.EntityIcon\" class=\"entity-icon\"></i>\n <span class=\"entity-group-name\">{{group.EntityName}}</span>\n </div>\n <div class=\"entity-group-badges\">\n @if (group.AddedCount > 0) {\n <span class=\"badge change-added\">\n +{{group.AddedCount}}\n </span>\n }\n @if (group.RemovedCount > 0) {\n <span class=\"badge change-removed\">\n -{{group.RemovedCount}}\n </span>\n }\n @if (group.ModifiedCount > 0) {\n <span class=\"badge change-modified\">\n ~{{group.ModifiedCount}}\n </span>\n }\n </div>\n </div>\n @if (group.IsExpanded) {\n <div class=\"entity-group-items\">\n @for (item of group.Items; track item) {\n <div class=\"diff-item-wrapper\">\n <div class=\"diff-item\" [ngClass]=\"GetChangeTypeClass(item.ChangeType)\"\n [class.clickable]=\"item.ChangeType === 'Modified'\"\n (click)=\"ToggleItem(item)\">\n <i [class]=\"GetChangeTypeIcon(item.ChangeType)\" class=\"diff-item-icon\"></i>\n <span class=\"diff-item-record\">\n {{FormatRecordID(item.RecordID)}}\n @if (item.DisplayName) {\n <span class=\"diff-item-display-name\"> ({{item.DisplayName}})</span>\n }\n </span>\n <span class=\"diff-item-type\">{{item.ChangeType}}</span>\n <button class=\"diff-item-open-btn\" (click)=\"OnOpenRecord(item); $event.stopPropagation()\"\n title=\"Open record\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i>\n </button>\n @if (item.ChangeType === 'Modified') {\n <i class=\"fa-solid fa-chevron-right diff-item-chevron\"\n [class.expanded]=\"item.IsExpanded\"\n ></i>\n }\n </div>\n <!-- Field-level changes -->\n @if (item.IsExpanded && item.ChangeType === 'Modified') {\n <div class=\"diff-fields\">\n @if (item.IsLoadingFields) {\n <mj-loading text=\"Loading changes...\" size=\"small\"></mj-loading>\n }\n @if (!item.IsLoadingFields && item.FieldChanges.length > 0) {\n @for (field of item.FieldChanges; track field) {\n <div class=\"diff-field\"\n [ngClass]=\"GetChangeTypeClass(field.ChangeType)\">\n <span class=\"diff-field-name\">{{field.FieldName}}</span>\n <span class=\"diff-field-values\">\n @if (field.OldValue) {\n <span class=\"diff-field-old\">{{field.OldValue | slice:0:60}}</span>\n }\n @if (field.OldValue && field.NewValue) {\n <i class=\"fa-solid fa-arrow-right diff-field-arrow\"></i>\n }\n @if (field.NewValue) {\n <span class=\"diff-field-new\">{{field.NewValue | slice:0:60}}</span>\n }\n </span>\n </div>\n }\n }\n @if (!item.IsLoadingFields && item.FieldsLoaded && item.FieldChanges.length === 0) {\n <div class=\"diff-fields-empty\">\n <span>No field-level changes available</span>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n <!-- No changes -->\n @if (FilteredEntityGroups.length === 0 && TotalChanges === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-check-circle empty-icon\" style=\"color: #10b981;\"></i>\n <h3>No differences found</h3>\n <p>The compared states are identical.</p>\n </div>\n }\n }\n <!-- No results yet -->\n @if (!HasDiffResult && !IsDiffLoading) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-code-compare empty-icon\"></i>\n <h3>Select labels to compare</h3>\n <p>Choose a diff mode and select labels above, then click Compare.</p>\n </div>\n }\n }\n</div>\n", styles: [".diff-container {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n}\n\n/* Header */\n.page-header {\n margin-bottom: 24px;\n}\n\n.page-title {\n font-size: 24px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 4px 0;\n}\n\n.page-subtitle {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n/* Config Panel */\n.config-panel {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 24px;\n margin-bottom: 24px;\n}\n\n.mode-selector {\n display: flex;\n gap: 8px;\n margin-bottom: 20px;\n}\n\n.mode-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 18px;\n background: var(--mj-bg-surface-sunken);\n border: 2px solid transparent;\n border-radius: 8px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.mode-btn:hover {\n background: var(--mj-border-default);\n}\n\n.mode-btn.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n/* Label Selectors */\n.label-selectors {\n display: flex;\n align-items: flex-end;\n gap: 16px;\n margin-bottom: 20px;\n}\n\n.selector-group {\n flex: 1;\n}\n\n.selector-label {\n display: block;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 6px;\n}\n\n.selector-input {\n width: 100%;\n padding: 10px 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 14px;\n color: var(--mj-text-primary);\n outline: none;\n box-sizing: border-box;\n}\n\n.selector-input:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.selector-arrow {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n padding-bottom: 8px;\n color: var(--mj-text-secondary);\n font-size: 16px;\n}\n\n.current-state-badge {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n padding: 2px 8px;\n border-radius: 8px;\n white-space: nowrap;\n}\n\n/* Run Button */\n.btn-primary {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 10px 24px;\n background: var(--mj-brand-primary);\n border: none;\n border-radius: 8px;\n color: var(--mj-text-inverse);\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Diff Summary */\n.diff-summary {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 12px;\n margin-bottom: 24px;\n}\n\n.diff-stat {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 20px;\n border-radius: 10px;\n border: 1px solid var(--mj-border-default);\n}\n\n.diff-stat i {\n font-size: 16px;\n}\n\n.diff-stat-value {\n font-size: 22px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.diff-stat-label {\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n/* Change type colors */\n.change-added {\n background: color-mix(in srgb, var(--mj-status-success) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-status-success) 20%, transparent);\n color: var(--mj-status-success);\n}\n\n.change-removed {\n background: color-mix(in srgb, var(--mj-status-error) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-status-error) 20%, transparent);\n color: var(--mj-status-error);\n}\n\n.change-modified {\n background: color-mix(in srgb, var(--mj-status-warning) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-status-warning) 20%, transparent);\n color: var(--mj-status-warning);\n}\n\n.change-unchanged {\n background: color-mix(in srgb, var(--mj-text-muted) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-text-muted) 20%, transparent);\n color: var(--mj-text-muted);\n}\n\n/* Entity Groups */\n.entity-groups {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.entity-group {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.entity-group-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.entity-group-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.entity-group-left {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.entity-group-left i:first-child {\n font-size: 12px;\n color: var(--mj-text-muted);\n width: 16px;\n}\n\n.entity-icon {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.entity-group-name {\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.entity-group-badges {\n display: flex;\n gap: 6px;\n}\n\n.badge {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n border: none;\n}\n\n/* Entity chevron animation */\n.entity-chevron {\n font-size: 11px;\n color: var(--mj-text-muted);\n width: 14px;\n text-align: center;\n transition: transform 0.2s ease;\n}\n\n.entity-chevron.expanded {\n transform: rotate(90deg);\n}\n\n/* Entity group items */\n.entity-group-items {\n border-top: 1px solid var(--mj-border-default);\n padding: 8px 16px;\n}\n\n.diff-item-wrapper {\n margin-bottom: 2px;\n}\n\n.diff-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 12px;\n border-radius: 6px;\n}\n\n.diff-item.clickable {\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.diff-item.clickable:hover {\n filter: brightness(0.97);\n}\n\n.diff-item-icon {\n font-size: 12px;\n width: 20px;\n text-align: center;\n}\n\n.diff-item-record {\n font-size: 13px;\n font-family: 'SF Mono', 'Fira Code', monospace;\n color: var(--mj-text-primary);\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-item-display-name {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n color: var(--mj-text-secondary);\n font-weight: 500;\n}\n\n.diff-item-open-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n border: 1px solid transparent;\n border-radius: 4px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 11px;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.diff-item-open-btn:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, transparent);\n}\n\n.diff-item-type {\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.diff-item-chevron {\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 0.2s ease;\n}\n\n.diff-item-chevron.expanded {\n transform: rotate(90deg);\n}\n\n/* Field-level diff changes */\n.diff-fields {\n margin-left: 42px;\n margin-bottom: 8px;\n padding: 8px 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.diff-field {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 6px 10px;\n border-radius: 6px;\n font-size: 13px;\n}\n\n.diff-field.change-added {\n background: color-mix(in srgb, var(--mj-status-success) 6%, transparent);\n}\n\n.diff-field.change-modified {\n background: color-mix(in srgb, var(--mj-status-warning) 6%, transparent);\n}\n\n.diff-field.change-removed {\n background: color-mix(in srgb, var(--mj-status-error) 6%, transparent);\n}\n\n.diff-field-name {\n font-weight: 600;\n color: var(--mj-text-primary);\n min-width: 120px;\n flex-shrink: 0;\n}\n\n.diff-field-values {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n flex: 1;\n}\n\n.diff-field-old {\n color: var(--mj-status-error);\n text-decoration: line-through;\n opacity: 0.8;\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-field-arrow {\n color: var(--mj-text-muted);\n font-size: 10px;\n flex-shrink: 0;\n}\n\n.diff-field-new {\n color: var(--mj-status-success);\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-fields-empty {\n padding: 6px 10px;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n/* Toolbar actions */\n.diff-toolbar-right {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.toolbar-action-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-muted);\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.toolbar-action-btn:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, transparent);\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 20px;\n text-align: center;\n}\n\n.empty-icon {\n font-size: 48px;\n color: var(--mj-text-muted);\n margin-bottom: 16px;\n}\n\n.empty-state h3 {\n font-size: 18px;\n font-weight: 600;\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;\n max-width: 400px;\n}\n\n/* Swap Button */\n.swap-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border: 1px solid var(--mj-border-default);\n border-radius: 50%;\n background: var(--mj-bg-surface-card);\n color: var(--mj-brand-primary);\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.swap-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n border-color: var(--mj-brand-primary);\n transform: rotate(180deg);\n}\n\n/* Diff Results Toolbar */\n.diff-toolbar {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 16px;\n flex-wrap: wrap;\n}\n\n.diff-search {\n position: relative;\n flex: 1;\n min-width: 200px;\n}\n\n.diff-search-icon {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.diff-search-input {\n width: 100%;\n padding: 8px 12px 8px 36px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n box-sizing: border-box;\n}\n\n.diff-search-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.diff-filter-pills {\n display: flex;\n gap: 4px;\n}\n\n.filter-pill {\n padding: 6px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n background: var(--mj-bg-surface-card);\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.filter-pill:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.filter-pill.active {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.filter-pill.change-added.active {\n background: var(--mj-status-success);\n border-color: var(--mj-status-success);\n}\n\n.filter-pill.change-removed.active {\n background: var(--mj-status-error);\n border-color: var(--mj-status-error);\n}\n\n.filter-pill.change-modified.active {\n background: var(--mj-status-warning);\n border-color: var(--mj-status-warning);\n}\n\n.diff-sort-toggle {\n display: flex;\n gap: 2px;\n}\n\n.toggle-btn-sm {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-muted);\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.toggle-btn-sm:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.toggle-btn-sm.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n@media (max-width: 768px) {\n .diff-summary {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .label-selectors {\n flex-direction: column;\n }\n}\n"] }]
1160
- }], () => [{ type: i0.ChangeDetectorRef }, { type: i1.NavigationService }], null); })();
1159
+ }], () => [{ type: i0.ChangeDetectorRef }], null); })();
1161
1160
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(VersionHistoryDiffResourceComponent, { className: "VersionHistoryDiffResourceComponent", filePath: "src/VersionHistory/components/diff-resource.component.ts", lineNumber: 59 }); })();
1162
1161
  //# sourceMappingURL=diff-resource.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"diff-resource.component.js","sourceRoot":"","sources":["../../../src/VersionHistory/components/diff-resource.component.ts","../../../src/VersionHistory/components/diff-resource.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { RegisterClass , UUIDsEqual } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { RunView, Metadata, CompositeKey, EntityRecordNameInput } from '@memberjunction/core';\nimport { ResourceData, UserInfoEngine, MJVersionLabelEntityType, MJVersionLabelItemEntityType } from '@memberjunction/core-entities';\n\ninterface VersionDiffPreferences {\n DiffMode: 'label-to-label' | 'label-to-current';\n}\ninterface DiffItemView {\n EntityName: string;\n EntityID: string;\n RecordID: string;\n DisplayName: string;\n ChangeType: 'Added' | 'Removed' | 'Modified' | 'Unchanged';\n FieldChanges: FieldChangeView[];\n IsExpanded: boolean;\n IsLoadingFields: boolean;\n FieldsLoaded: boolean;\n /** RecordChangeID from the \"from\" label (for loading FullRecordJSON). */\n FromRecordChangeID: string;\n /** RecordChangeID from the \"to\" label (for loading FullRecordJSON). */\n ToRecordChangeID: string;\n}\n\ninterface FieldChangeView {\n FieldName: string;\n OldValue: string;\n NewValue: string;\n ChangeType: 'Added' | 'Modified' | 'Removed';\n}\n\ninterface RecordChangeRow {\n ID: string;\n FullRecordJSON: string;\n}\n\ninterface EntityGroupView {\n EntityName: string;\n EntityIcon: string;\n Items: DiffItemView[];\n AddedCount: number;\n RemovedCount: number;\n ModifiedCount: number;\n IsExpanded: boolean;\n NamesLoaded: boolean;\n IsLoadingNames: boolean;\n}\n\n@RegisterClass(BaseResourceComponent, 'VersionHistoryDiffResource')\n@Component({\n standalone: false,\n selector: 'mj-version-history-diff-resource',\n templateUrl: './diff-resource.component.html',\n styleUrls: ['./diff-resource.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class VersionHistoryDiffResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public IsLoading = true;\n public IsDiffLoading = false;\n public HasDiffResult = false;\n\n // Label selection\n public AvailableLabels: MJVersionLabelEntityType[] = [];\n public FromLabelId = '';\n public ToLabelId = '';\n public DiffMode: 'label-to-label' | 'label-to-current' = 'label-to-current';\n\n // Diff results\n public EntityGroups: EntityGroupView[] = [];\n public FilteredEntityGroups: EntityGroupView[] = [];\n public TotalAdded = 0;\n public TotalRemoved = 0;\n public TotalModified = 0;\n public TotalUnchanged = 0;\n\n // Diff result filtering/sorting\n public DiffSortBy: 'name' | 'count' = 'count';\n public DiffSortDir: 'asc' | 'desc' = 'desc';\n public DiffFilterType: 'all' | 'added' | 'removed' | 'modified' = 'all';\n public DiffSearch = '';\n\n // UI state\n public ExpandedEntities = new Set<string>();\n\n private static readonly PREFS_KEY = 'VersionHistory.Diff.UserPreferences';\n private preferencesLoaded = false;\n private destroy$ = new Subject<void>();\n private metadata = new Metadata();\n\n constructor(private cdr: ChangeDetectorRef, private navigationService: NavigationService) {\n super();\n }\n\n ngOnInit(): void {\n this.loadUserPreferences();\n this.LoadLabels();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Diff Viewer';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-code-compare';\n }\n\n public async LoadLabels(): Promise<void> {\n try {\n this.IsLoading = true;\n this.cdr.markForCheck();\n\n const rv = new RunView();\n const result = await rv.RunView<MJVersionLabelEntityType>({\n EntityName: 'MJ: Version Labels',\n ExtraFilter: \"Status = 'Active'\",\n OrderBy: '__mj_CreatedAt DESC',\n MaxRows: 200,\n ResultType: 'simple'\n });\n\n if (result.Success) {\n this.AvailableLabels = result.Results;\n }\n } catch (error) {\n console.error('Error loading labels for diff:', error);\n } finally {\n this.IsLoading = false;\n this.NotifyLoadComplete();\n this.cdr.markForCheck();\n }\n }\n\n public OnDiffModeChange(mode: 'label-to-label' | 'label-to-current'): void {\n this.DiffMode = mode;\n this.HasDiffResult = false;\n this.EntityGroups = [];\n this.cdr.markForCheck();\n this.persistPreferences();\n }\n\n private loadUserPreferences(): void {\n try {\n const raw = UserInfoEngine.Instance.GetSetting(VersionHistoryDiffResourceComponent.PREFS_KEY);\n if (raw) {\n const prefs: VersionDiffPreferences = JSON.parse(raw);\n if (prefs.DiffMode === 'label-to-label' || prefs.DiffMode === 'label-to-current') {\n this.DiffMode = prefs.DiffMode;\n }\n }\n } catch (error) {\n console.error('Error loading diff preferences:', error);\n this.DiffMode = 'label-to-current';\n }\n this.preferencesLoaded = true;\n }\n\n private persistPreferences(): void {\n if (!this.preferencesLoaded) return;\n const prefs: VersionDiffPreferences = {\n DiffMode: this.DiffMode\n };\n UserInfoEngine.Instance.SetSettingDebounced(VersionHistoryDiffResourceComponent.PREFS_KEY, JSON.stringify(prefs));\n }\n\n public async RunDiff(): Promise<void> {\n if (!this.FromLabelId) return;\n if (this.DiffMode === 'label-to-label' && !this.ToLabelId) return;\n\n try {\n this.IsDiffLoading = true;\n this.HasDiffResult = false;\n this.cdr.markForCheck();\n\n // Load label items for comparison\n const rv = new RunView();\n const fromItems = await this.loadLabelItems(rv, this.FromLabelId);\n\n if (this.DiffMode === 'label-to-label') {\n const toItems = await this.loadLabelItems(rv, this.ToLabelId);\n this.computeDiff(fromItems, toItems);\n } else {\n // Label-to-current: compare label state against live data\n await this.computeDiffToCurrentState(rv, fromItems);\n }\n\n this.HasDiffResult = true;\n } catch (error) {\n console.error('Error running diff:', error);\n } finally {\n this.IsDiffLoading = false;\n this.cdr.markForCheck();\n }\n }\n\n private async loadLabelItems(\n rv: RunView,\n labelId: string\n ): Promise<MJVersionLabelItemEntityType[]> {\n const result = await rv.RunView<MJVersionLabelItemEntityType>({\n EntityName: 'MJ: Version Label Items',\n ExtraFilter: `VersionLabelID = '${labelId}'`,\n ResultType: 'simple'\n });\n return result.Success ? result.Results : [];\n }\n\n private computeDiff(\n fromItems: MJVersionLabelItemEntityType[],\n toItems: MJVersionLabelItemEntityType[]\n ): void {\n const entityMap = new Map<string, DiffItemView[]>();\n\n // Build lookup maps keyed by EntityID + RecordID\n const fromMap = this.buildItemKeyMap(fromItems);\n const toMap = this.buildItemKeyMap(toItems);\n\n // Items in 'to' but not in 'from' = Added\n for (const [key, item] of toMap) {\n const entityName = this.resolveEntityName(item.EntityID ?? '');\n if (!entityMap.has(entityName)) entityMap.set(entityName, []);\n\n if (!fromMap.has(key)) {\n entityMap.get(entityName)!.push({\n EntityName: entityName,\n EntityID: item.EntityID ?? '',\n RecordID: item.RecordID ?? '',\n DisplayName: '',\n ChangeType: 'Added',\n FieldChanges: [],\n IsExpanded: false,\n IsLoadingFields: false,\n FieldsLoaded: false,\n FromRecordChangeID: '',\n ToRecordChangeID: item.RecordChangeID ?? ''\n });\n }\n }\n\n // Items in 'from' but not in 'to' = Removed\n for (const [key, item] of fromMap) {\n const entityName = this.resolveEntityName(item.EntityID ?? '');\n if (!entityMap.has(entityName)) entityMap.set(entityName, []);\n\n if (!toMap.has(key)) {\n entityMap.get(entityName)!.push({\n EntityName: entityName,\n EntityID: item.EntityID ?? '',\n RecordID: item.RecordID ?? '',\n DisplayName: '',\n ChangeType: 'Removed',\n FieldChanges: [],\n IsExpanded: false,\n IsLoadingFields: false,\n FieldsLoaded: false,\n FromRecordChangeID: item.RecordChangeID ?? '',\n ToRecordChangeID: ''\n });\n } else {\n // Both exist - check if RecordChangeID differs (= Modified)\n const toItem = toMap.get(key)!;\n const changeType = !UUIDsEqual(item.RecordChangeID, toItem.RecordChangeID)\n ? 'Modified' : 'Unchanged';\n entityMap.get(entityName)!.push({\n EntityName: entityName,\n EntityID: item.EntityID ?? '',\n RecordID: item.RecordID ?? '',\n DisplayName: '',\n ChangeType: changeType,\n FieldChanges: [],\n IsExpanded: false,\n IsLoadingFields: false,\n FieldsLoaded: false,\n FromRecordChangeID: item.RecordChangeID ?? '',\n ToRecordChangeID: toItem.RecordChangeID ?? ''\n });\n }\n }\n\n this.buildEntityGroups(entityMap);\n }\n\n private async computeDiffToCurrentState(\n rv: RunView,\n labelItems: MJVersionLabelItemEntityType[]\n ): Promise<void> {\n // For label-to-current, compare snapshot RecordChangeIDs against\n // the latest RecordChange for each entity/record combination.\n const entityMap = new Map<string, DiffItemView[]>();\n\n for (const item of labelItems) {\n const entityId = item.EntityID ?? '';\n const entityName = this.resolveEntityName(entityId);\n if (!entityMap.has(entityName)) entityMap.set(entityName, []);\n\n // Load the latest RecordChange for this record\n const latestChangeId = await this.loadLatestRecordChange(rv, entityId, item.RecordID ?? '');\n const isModified = latestChangeId != null && latestChangeId !== item.RecordChangeID;\n\n entityMap.get(entityName)!.push({\n EntityName: entityName,\n EntityID: entityId,\n RecordID: item.RecordID ?? '',\n DisplayName: '',\n ChangeType: isModified ? 'Modified' : 'Unchanged',\n FieldChanges: [],\n IsExpanded: false,\n IsLoadingFields: false,\n FieldsLoaded: false,\n FromRecordChangeID: item.RecordChangeID ?? '',\n ToRecordChangeID: latestChangeId ?? ''\n });\n }\n\n this.buildEntityGroups(entityMap);\n }\n\n private buildItemKeyMap(\n items: MJVersionLabelItemEntityType[]\n ): Map<string, MJVersionLabelItemEntityType> {\n const map = new Map<string, MJVersionLabelItemEntityType>();\n for (const item of items) {\n const key = `${item.EntityID ?? ''}|${item.RecordID ?? ''}`;\n map.set(key, item);\n }\n return map;\n }\n\n private buildEntityGroups(entityMap: Map<string, DiffItemView[]>): void {\n this.TotalAdded = 0;\n this.TotalRemoved = 0;\n this.TotalModified = 0;\n this.TotalUnchanged = 0;\n\n this.EntityGroups = Array.from(entityMap.entries()).map(([entityName, items]) => {\n const added = items.filter(i => i.ChangeType === 'Added').length;\n const removed = items.filter(i => i.ChangeType === 'Removed').length;\n const modified = items.filter(i => i.ChangeType === 'Modified').length;\n\n this.TotalAdded += added;\n this.TotalRemoved += removed;\n this.TotalModified += modified;\n this.TotalUnchanged += items.filter(i => i.ChangeType === 'Unchanged').length;\n\n // Resolve entity icon from first item's EntityID\n const firstItem = items[0];\n const entityIcon = this.resolveEntityIcon(firstItem?.EntityID ?? '');\n\n return {\n EntityName: entityName,\n EntityIcon: entityIcon,\n Items: items.filter(i => i.ChangeType !== 'Unchanged'),\n AddedCount: added,\n RemovedCount: removed,\n ModifiedCount: modified,\n IsExpanded: false,\n NamesLoaded: false,\n IsLoadingNames: false\n };\n }).filter(g => g.Items.length > 0)\n .sort((a, b) => b.Items.length - a.Items.length);\n\n this.ExpandedEntities.clear();\n this.applySortAndFilterDiff();\n }\n\n private resolveEntityName(entityId: string): string {\n if (!entityId) return 'Unknown';\n const entity = this.metadata.Entities.find(e => UUIDsEqual(e.ID, entityId));\n return entity ? entity.Name : 'Unknown';\n }\n\n private resolveEntityIcon(entityId: string): string {\n if (!entityId) return 'fa-solid fa-table';\n const entity = this.metadata.Entities.find(e => UUIDsEqual(e.ID, entityId));\n return entity?.Icon || 'fa-solid fa-table';\n }\n\n // =========================================================================\n // Expand / Collapse\n // =========================================================================\n\n public ToggleEntityGroup(group: EntityGroupView): void {\n group.IsExpanded = !group.IsExpanded;\n if (group.IsExpanded) {\n this.ExpandedEntities.add(group.EntityName);\n // Auto-expand all Modified items so field details show immediately\n for (const item of group.Items) {\n if (item.ChangeType === 'Modified') {\n item.IsExpanded = true;\n }\n }\n // Auto-load field changes for modified items when group opens\n this.loadFieldChangesForGroup(group);\n // Load record display names\n if (!group.NamesLoaded && !group.IsLoadingNames) {\n this.loadGroupRecordNames(group);\n }\n } else {\n this.ExpandedEntities.delete(group.EntityName);\n }\n this.cdr.markForCheck();\n }\n\n public ToggleItem(item: DiffItemView): void {\n if (item.ChangeType !== 'Modified') return;\n item.IsExpanded = !item.IsExpanded;\n if (item.IsExpanded && !item.FieldsLoaded) {\n this.loadFieldChangesForItem(item);\n }\n this.cdr.markForCheck();\n }\n\n public ExpandAllGroups(): void {\n for (const group of this.FilteredEntityGroups) {\n group.IsExpanded = true;\n this.ExpandedEntities.add(group.EntityName);\n this.loadFieldChangesForGroup(group);\n for (const item of group.Items) {\n if (item.ChangeType === 'Modified') {\n item.IsExpanded = true;\n }\n }\n if (!group.NamesLoaded && !group.IsLoadingNames) {\n this.loadGroupRecordNames(group);\n }\n }\n this.cdr.markForCheck();\n }\n\n public CollapseAllGroups(): void {\n for (const group of this.FilteredEntityGroups) {\n group.IsExpanded = false;\n this.ExpandedEntities.delete(group.EntityName);\n for (const item of group.Items) {\n item.IsExpanded = false;\n }\n }\n this.cdr.markForCheck();\n }\n\n public IsEntityExpanded(entityName: string): boolean {\n return this.ExpandedEntities.has(entityName);\n }\n\n /** Open a record in the explorer via NavigationService. */\n public OnOpenRecord(item: DiffItemView): void {\n const rawId = this.extractRawRecordId(item.RecordID);\n const pkey = new CompositeKey([{ FieldName: 'ID', Value: rawId }]);\n this.navigationService.OpenEntityRecord(item.EntityName, pkey);\n }\n\n // =========================================================================\n // Record name resolution\n // =========================================================================\n\n /** Lazy-load record display names for a group using Metadata.GetEntityRecordNames. */\n private async loadGroupRecordNames(group: EntityGroupView): Promise<void> {\n group.IsLoadingNames = true;\n this.cdr.markForCheck();\n\n try {\n const inputs: EntityRecordNameInput[] = group.Items.map(item => {\n const rawId = this.extractRawRecordId(item.RecordID);\n const input = new EntityRecordNameInput();\n input.EntityName = group.EntityName;\n input.CompositeKey = new CompositeKey([{ FieldName: 'ID', Value: rawId }]);\n return input;\n });\n\n const results = await this.metadata.GetEntityRecordNames(inputs);\n\n for (const result of results) {\n if (result.Success && result.RecordName) {\n const resultId = result.CompositeKey?.KeyValuePairs?.[0]?.Value;\n if (resultId) {\n const item = group.Items.find(i =>\n this.extractRawRecordId(i.RecordID) === String(resultId)\n );\n if (item) {\n item.DisplayName = result.RecordName;\n }\n }\n }\n }\n } catch (e) {\n console.error('Error loading record names for group:', group.EntityName, e);\n } finally {\n group.IsLoadingNames = false;\n group.NamesLoaded = true;\n this.cdr.markForCheck();\n }\n }\n\n /** Extract the raw UUID from a RecordID that may be in \"ID|<uuid>\" format. */\n private extractRawRecordId(recordId: string): string {\n if (!recordId) return '';\n const parts = recordId.split('||');\n if (parts.length === 1) {\n const singleParts = recordId.split('|');\n if (singleParts.length === 2) {\n return singleParts[1];\n }\n }\n return recordId;\n }\n\n // =========================================================================\n // Field-level diff loading\n // =========================================================================\n\n /** Auto-load field changes for all modified items in a group (when first expanded). */\n private loadFieldChangesForGroup(group: EntityGroupView): void {\n for (const item of group.Items) {\n if (item.ChangeType === 'Modified' && !item.FieldsLoaded && !item.IsLoadingFields) {\n this.loadFieldChangesForItem(item);\n }\n }\n }\n\n /** Lazy-load field-level changes for a single modified item. */\n private async loadFieldChangesForItem(item: DiffItemView): Promise<void> {\n if (!item.FromRecordChangeID || !item.ToRecordChangeID) {\n item.FieldsLoaded = true;\n return;\n }\n\n item.IsLoadingFields = true;\n this.cdr.markForCheck();\n\n try {\n item.FieldChanges = await this.computeFieldChanges(item.FromRecordChangeID, item.ToRecordChangeID);\n } catch (e) {\n console.error('Error loading field changes:', e);\n } finally {\n item.IsLoadingFields = false;\n item.FieldsLoaded = true;\n this.cdr.markForCheck();\n }\n }\n\n private async loadLatestRecordChange(rv: RunView, entityId: string, recordId: string): Promise<string | null> {\n if (!entityId || !recordId) return null;\n\n const result = await rv.RunView<RecordChangeRow>({\n EntityName: 'MJ: Record Changes',\n ExtraFilter: `EntityID = '${entityId}' AND RecordID = '${recordId}'`,\n OrderBy: 'ChangedAt DESC',\n MaxRows: 1,\n Fields: ['ID'],\n ResultType: 'simple'\n });\n\n if (result.Success && result.Results.length > 0) {\n return result.Results[0].ID;\n }\n return null;\n }\n\n private async computeFieldChanges(oldChangeId: string, newChangeId: string): Promise<FieldChangeView[]> {\n if (!oldChangeId || !newChangeId) return [];\n\n try {\n const rv = new RunView();\n const [oldResult, newResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Record Changes',\n ExtraFilter: `ID = '${oldChangeId}'`,\n Fields: ['FullRecordJSON'],\n ResultType: 'simple'\n },\n {\n EntityName: 'MJ: Record Changes',\n ExtraFilter: `ID = '${newChangeId}'`,\n Fields: ['FullRecordJSON'],\n ResultType: 'simple'\n }\n ]);\n\n if (!oldResult.Success || !newResult.Success) return [];\n if (oldResult.Results.length === 0 || newResult.Results.length === 0) return [];\n\n const oldRow = oldResult.Results[0] as RecordChangeRow;\n const newRow = newResult.Results[0] as RecordChangeRow;\n\n return this.diffRecordJson(oldRow.FullRecordJSON, newRow.FullRecordJSON);\n } catch {\n return [];\n }\n }\n\n private diffRecordJson(oldJson: string, newJson: string): FieldChangeView[] {\n const changes: FieldChangeView[] = [];\n\n try {\n const oldData = JSON.parse(oldJson || '{}') as Record<string, unknown>;\n const newData = JSON.parse(newJson || '{}') as Record<string, unknown>;\n const allKeys = new Set([...Object.keys(oldData), ...Object.keys(newData)]);\n\n for (const key of allKeys) {\n if (key.startsWith('__mj_')) continue;\n\n const oldVal = oldData[key];\n const newVal = newData[key];\n\n if (oldVal === undefined && newVal !== undefined) {\n changes.push({ FieldName: key, OldValue: '', NewValue: this.formatFieldValue(newVal), ChangeType: 'Added' });\n } else if (oldVal !== undefined && newVal === undefined) {\n changes.push({ FieldName: key, OldValue: this.formatFieldValue(oldVal), NewValue: '', ChangeType: 'Removed' });\n } else if (JSON.stringify(oldVal) !== JSON.stringify(newVal)) {\n changes.push({ FieldName: key, OldValue: this.formatFieldValue(oldVal), NewValue: this.formatFieldValue(newVal), ChangeType: 'Modified' });\n }\n }\n } catch {\n // Invalid JSON - skip\n }\n\n return changes;\n }\n\n private formatFieldValue(value: unknown): string {\n if (value == null) return 'null';\n if (typeof value === 'object') return JSON.stringify(value);\n return String(value);\n }\n\n // =========================================================================\n // Display helpers\n // =========================================================================\n\n public GetChangeTypeClass(changeType: string): string {\n const classes: Record<string, string> = {\n 'Added': 'change-added',\n 'Removed': 'change-removed',\n 'Modified': 'change-modified',\n 'Unchanged': 'change-unchanged'\n };\n return classes[changeType] ?? '';\n }\n\n public GetChangeTypeIcon(changeType: string): string {\n const icons: Record<string, string> = {\n 'Added': 'fa-solid fa-plus',\n 'Removed': 'fa-solid fa-minus',\n 'Modified': 'fa-solid fa-pen',\n 'Unchanged': 'fa-solid fa-equals'\n };\n return icons[changeType] ?? 'fa-solid fa-circle';\n }\n\n public FormatRecordID(recordId: string): string {\n return this.extractRawRecordId(recordId);\n }\n\n public FormatLabelOption(label: MJVersionLabelEntityType): string {\n const dateVal = label.__mj_CreatedAt;\n const date = dateVal instanceof Date\n ? dateVal.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })\n : new Date(dateVal as unknown as string).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n return `${label.Name} (${label.Scope}, ${date})`;\n }\n\n public Refresh(): void {\n this.LoadLabels();\n }\n\n public get CanRunDiff(): boolean {\n if (!this.FromLabelId) return false;\n if (this.DiffMode === 'label-to-label' && !this.ToLabelId) return false;\n return true;\n }\n\n public get TotalChanges(): number {\n return this.TotalAdded + this.TotalRemoved + this.TotalModified;\n }\n\n // =========================================================================\n // Label selection helpers\n // =========================================================================\n\n /** From dropdown excludes the currently selected To label. */\n public get FilteredFromLabels(): MJVersionLabelEntityType[] {\n if (!this.ToLabelId) return this.AvailableLabels;\n return this.AvailableLabels.filter(l => !UUIDsEqual(l.ID, this.ToLabelId));\n }\n\n /** To dropdown excludes the currently selected From label. */\n public get FilteredToLabels(): MJVersionLabelEntityType[] {\n if (!this.FromLabelId) return this.AvailableLabels;\n return this.AvailableLabels.filter(l => !UUIDsEqual(l.ID, this.FromLabelId));\n }\n\n /** Swap From and To label selections. */\n public SwapLabels(): void {\n const temp = this.FromLabelId;\n this.FromLabelId = this.ToLabelId;\n this.ToLabelId = temp;\n this.cdr.markForCheck();\n }\n\n // =========================================================================\n // Diff result sorting & filtering\n // =========================================================================\n\n public OnDiffSortChange(sortBy: 'name' | 'count'): void {\n if (this.DiffSortBy === sortBy) {\n this.DiffSortDir = this.DiffSortDir === 'asc' ? 'desc' : 'asc';\n } else {\n this.DiffSortBy = sortBy;\n this.DiffSortDir = sortBy === 'name' ? 'asc' : 'desc';\n }\n this.applySortAndFilterDiff();\n this.cdr.markForCheck();\n }\n\n public OnDiffFilterChange(filterType: 'all' | 'added' | 'removed' | 'modified'): void {\n this.DiffFilterType = filterType;\n this.applySortAndFilterDiff();\n this.cdr.markForCheck();\n }\n\n public OnDiffSearchChange(text: string): void {\n this.DiffSearch = text;\n this.applySortAndFilterDiff();\n this.cdr.markForCheck();\n }\n\n private applySortAndFilterDiff(): void {\n let groups = [...this.EntityGroups];\n\n // Filter by change type\n if (this.DiffFilterType !== 'all') {\n groups = groups.map(g => ({\n ...g,\n Items: g.Items.filter(i => i.ChangeType.toLowerCase() === this.DiffFilterType)\n })).filter(g => g.Items.length > 0);\n }\n\n // Filter by search text\n if (this.DiffSearch) {\n const search = this.DiffSearch.toLowerCase();\n groups = groups\n .filter(g => g.EntityName.toLowerCase().includes(search) ||\n g.Items.some(i => i.RecordID.toLowerCase().includes(search) || i.DisplayName.toLowerCase().includes(search)))\n .map(g => ({\n ...g,\n Items: g.Items.filter(i =>\n i.RecordID.toLowerCase().includes(search) ||\n i.DisplayName.toLowerCase().includes(search) ||\n g.EntityName.toLowerCase().includes(search)\n )\n }))\n .filter(g => g.Items.length > 0);\n }\n\n // Sort\n groups.sort((a, b) => {\n if (this.DiffSortBy === 'name') {\n const cmp = a.EntityName.localeCompare(b.EntityName);\n return this.DiffSortDir === 'asc' ? cmp : -cmp;\n }\n const cmp = a.Items.length - b.Items.length;\n return this.DiffSortDir === 'asc' ? cmp : -cmp;\n });\n\n this.FilteredEntityGroups = groups;\n }\n}\n","<div class=\"diff-container\">\n @if (IsLoading) {\n <mj-loading text=\"Loading diff viewer...\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <!-- Header -->\n <div class=\"page-header\">\n <div class=\"header-left\">\n <h2 class=\"page-title\">Diff Viewer</h2>\n <p class=\"page-subtitle\">Compare states between version labels or against current data</p>\n </div>\n </div>\n <!-- Diff Configuration Panel -->\n <div class=\"config-panel\">\n <!-- Mode Selector -->\n <div class=\"mode-selector\">\n <button class=\"mode-btn\"\n [class.active]=\"DiffMode === 'label-to-current'\"\n (click)=\"OnDiffModeChange('label-to-current')\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n Label vs Current\n </button>\n <button class=\"mode-btn\"\n [class.active]=\"DiffMode === 'label-to-label'\"\n (click)=\"OnDiffModeChange('label-to-label')\">\n <i class=\"fa-solid fa-code-compare\"></i>\n Label vs Label\n </button>\n </div>\n <!-- Label Selectors -->\n <div class=\"label-selectors\">\n <div class=\"selector-group\">\n <label class=\"selector-label\">\n {{DiffMode === 'label-to-current' ? 'Compare label' : 'From label'}}\n </label>\n <select class=\"selector-input\"\n [(ngModel)]=\"FromLabelId\">\n <option value=\"\">Select a label...</option>\n @for (label of FilteredFromLabels; track label) {\n <option\n [value]=\"label.ID\">\n {{FormatLabelOption(label)}}\n </option>\n }\n </select>\n </div>\n @if (DiffMode === 'label-to-label') {\n <div class=\"selector-arrow\">\n <button class=\"swap-btn\" (click)=\"SwapLabels()\" title=\"Swap direction\">\n <i class=\"fa-solid fa-arrows-rotate\"></i>\n </button>\n </div>\n }\n @if (DiffMode === 'label-to-current') {\n <div class=\"selector-arrow\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n <span class=\"current-state-badge\">Current State</span>\n </div>\n }\n @if (DiffMode === 'label-to-label') {\n <div class=\"selector-group\">\n <label class=\"selector-label\">To label</label>\n <select class=\"selector-input\"\n [(ngModel)]=\"ToLabelId\">\n <option value=\"\">Select a label...</option>\n @for (label of FilteredToLabels; track label) {\n <option\n [value]=\"label.ID\">\n {{FormatLabelOption(label)}}\n </option>\n }\n </select>\n </div>\n }\n </div>\n <!-- Run Button -->\n <button class=\"btn-primary\"\n [disabled]=\"!CanRunDiff || IsDiffLoading\"\n (click)=\"RunDiff()\">\n @if (!IsDiffLoading) {\n <i class=\"fa-solid fa-play\"></i>\n }\n @if (IsDiffLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n }\n <span>{{IsDiffLoading ? 'Comparing...' : 'Compare'}}</span>\n </button>\n </div>\n <!-- Diff Results -->\n @if (HasDiffResult) {\n <!-- Summary Stats -->\n <div class=\"diff-summary\">\n <div class=\"diff-stat change-added\">\n <i class=\"fa-solid fa-plus\"></i>\n <span class=\"diff-stat-value\">{{TotalAdded}}</span>\n <span class=\"diff-stat-label\">Added</span>\n </div>\n <div class=\"diff-stat change-removed\">\n <i class=\"fa-solid fa-minus\"></i>\n <span class=\"diff-stat-value\">{{TotalRemoved}}</span>\n <span class=\"diff-stat-label\">Removed</span>\n </div>\n <div class=\"diff-stat change-modified\">\n <i class=\"fa-solid fa-pen\"></i>\n <span class=\"diff-stat-value\">{{TotalModified}}</span>\n <span class=\"diff-stat-label\">Modified</span>\n </div>\n <div class=\"diff-stat change-unchanged\">\n <i class=\"fa-solid fa-equals\"></i>\n <span class=\"diff-stat-value\">{{TotalUnchanged}}</span>\n <span class=\"diff-stat-label\">Unchanged</span>\n </div>\n </div>\n <!-- Results toolbar -->\n @if (EntityGroups.length > 0) {\n <div class=\"diff-toolbar\">\n <div class=\"diff-search\">\n <i class=\"fa-solid fa-search diff-search-icon\"></i>\n <input type=\"text\" class=\"diff-search-input\"\n placeholder=\"Search by entity or record...\"\n [ngModel]=\"DiffSearch\"\n (ngModelChange)=\"OnDiffSearchChange($event)\" />\n </div>\n <div class=\"diff-filter-pills\">\n <button class=\"filter-pill\" [class.active]=\"DiffFilterType === 'all'\"\n (click)=\"OnDiffFilterChange('all')\">All</button>\n <button class=\"filter-pill change-added\" [class.active]=\"DiffFilterType === 'added'\"\n (click)=\"OnDiffFilterChange('added')\">Added</button>\n <button class=\"filter-pill change-removed\" [class.active]=\"DiffFilterType === 'removed'\"\n (click)=\"OnDiffFilterChange('removed')\">Removed</button>\n <button class=\"filter-pill change-modified\" [class.active]=\"DiffFilterType === 'modified'\"\n (click)=\"OnDiffFilterChange('modified')\">Modified</button>\n </div>\n <div class=\"diff-toolbar-right\">\n <button class=\"toolbar-action-btn\" (click)=\"ExpandAllGroups()\" title=\"Expand all\">\n <i class=\"fa-solid fa-angles-down\"></i>\n </button>\n <button class=\"toolbar-action-btn\" (click)=\"CollapseAllGroups()\" title=\"Collapse all\">\n <i class=\"fa-solid fa-angles-up\"></i>\n </button>\n <div class=\"diff-sort-toggle\">\n <button class=\"toggle-btn-sm\" [class.active]=\"DiffSortBy === 'name'\"\n (click)=\"OnDiffSortChange('name')\" title=\"Sort by name\">\n <i class=\"fa-solid\" [ngClass]=\"DiffSortBy === 'name' && DiffSortDir === 'desc' ? 'fa-arrow-up-z-a' : 'fa-arrow-down-a-z'\"></i>\n </button>\n <button class=\"toggle-btn-sm\" [class.active]=\"DiffSortBy === 'count'\"\n (click)=\"OnDiffSortChange('count')\" title=\"Sort by count\">\n <i class=\"fa-solid\" [ngClass]=\"DiffSortBy === 'count' && DiffSortDir === 'asc' ? 'fa-arrow-up-1-9' : 'fa-arrow-down-9-1'\"></i>\n </button>\n </div>\n </div>\n </div>\n }\n <!-- Entity Groups -->\n @if (FilteredEntityGroups.length > 0) {\n <div class=\"entity-groups\">\n @for (group of FilteredEntityGroups; track group) {\n <div class=\"entity-group\">\n <div class=\"entity-group-header\" (click)=\"ToggleEntityGroup(group)\">\n <div class=\"entity-group-left\">\n <i class=\"fa-solid fa-chevron-right entity-chevron\"\n [class.expanded]=\"group.IsExpanded\">\n </i>\n <i [class]=\"group.EntityIcon\" class=\"entity-icon\"></i>\n <span class=\"entity-group-name\">{{group.EntityName}}</span>\n </div>\n <div class=\"entity-group-badges\">\n @if (group.AddedCount > 0) {\n <span class=\"badge change-added\">\n +{{group.AddedCount}}\n </span>\n }\n @if (group.RemovedCount > 0) {\n <span class=\"badge change-removed\">\n -{{group.RemovedCount}}\n </span>\n }\n @if (group.ModifiedCount > 0) {\n <span class=\"badge change-modified\">\n ~{{group.ModifiedCount}}\n </span>\n }\n </div>\n </div>\n @if (group.IsExpanded) {\n <div class=\"entity-group-items\">\n @for (item of group.Items; track item) {\n <div class=\"diff-item-wrapper\">\n <div class=\"diff-item\" [ngClass]=\"GetChangeTypeClass(item.ChangeType)\"\n [class.clickable]=\"item.ChangeType === 'Modified'\"\n (click)=\"ToggleItem(item)\">\n <i [class]=\"GetChangeTypeIcon(item.ChangeType)\" class=\"diff-item-icon\"></i>\n <span class=\"diff-item-record\">\n {{FormatRecordID(item.RecordID)}}\n @if (item.DisplayName) {\n <span class=\"diff-item-display-name\"> ({{item.DisplayName}})</span>\n }\n </span>\n <span class=\"diff-item-type\">{{item.ChangeType}}</span>\n <button class=\"diff-item-open-btn\" (click)=\"OnOpenRecord(item); $event.stopPropagation()\"\n title=\"Open record\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i>\n </button>\n @if (item.ChangeType === 'Modified') {\n <i class=\"fa-solid fa-chevron-right diff-item-chevron\"\n [class.expanded]=\"item.IsExpanded\"\n ></i>\n }\n </div>\n <!-- Field-level changes -->\n @if (item.IsExpanded && item.ChangeType === 'Modified') {\n <div class=\"diff-fields\">\n @if (item.IsLoadingFields) {\n <mj-loading text=\"Loading changes...\" size=\"small\"></mj-loading>\n }\n @if (!item.IsLoadingFields && item.FieldChanges.length > 0) {\n @for (field of item.FieldChanges; track field) {\n <div class=\"diff-field\"\n [ngClass]=\"GetChangeTypeClass(field.ChangeType)\">\n <span class=\"diff-field-name\">{{field.FieldName}}</span>\n <span class=\"diff-field-values\">\n @if (field.OldValue) {\n <span class=\"diff-field-old\">{{field.OldValue | slice:0:60}}</span>\n }\n @if (field.OldValue && field.NewValue) {\n <i class=\"fa-solid fa-arrow-right diff-field-arrow\"></i>\n }\n @if (field.NewValue) {\n <span class=\"diff-field-new\">{{field.NewValue | slice:0:60}}</span>\n }\n </span>\n </div>\n }\n }\n @if (!item.IsLoadingFields && item.FieldsLoaded && item.FieldChanges.length === 0) {\n <div class=\"diff-fields-empty\">\n <span>No field-level changes available</span>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n <!-- No changes -->\n @if (FilteredEntityGroups.length === 0 && TotalChanges === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-check-circle empty-icon\" style=\"color: #10b981;\"></i>\n <h3>No differences found</h3>\n <p>The compared states are identical.</p>\n </div>\n }\n }\n <!-- No results yet -->\n @if (!HasDiffResult && !IsDiffLoading) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-code-compare empty-icon\"></i>\n <h3>Select labels to compare</h3>\n <p>Choose a diff mode and select labels above, then click Compare.</p>\n </div>\n }\n }\n</div>\n"]}
1
+ {"version":3,"file":"diff-resource.component.js","sourceRoot":"","sources":["../../../src/VersionHistory/components/diff-resource.component.ts","../../../src/VersionHistory/components/diff-resource.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { RegisterClass , UUIDsEqual } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { RunView, Metadata, CompositeKey, EntityRecordNameInput } from '@memberjunction/core';\nimport { ResourceData, UserInfoEngine, MJVersionLabelEntityType, MJVersionLabelItemEntityType } from '@memberjunction/core-entities';\n\ninterface VersionDiffPreferences {\n DiffMode: 'label-to-label' | 'label-to-current';\n}\ninterface DiffItemView {\n EntityName: string;\n EntityID: string;\n RecordID: string;\n DisplayName: string;\n ChangeType: 'Added' | 'Removed' | 'Modified' | 'Unchanged';\n FieldChanges: FieldChangeView[];\n IsExpanded: boolean;\n IsLoadingFields: boolean;\n FieldsLoaded: boolean;\n /** RecordChangeID from the \"from\" label (for loading FullRecordJSON). */\n FromRecordChangeID: string;\n /** RecordChangeID from the \"to\" label (for loading FullRecordJSON). */\n ToRecordChangeID: string;\n}\n\ninterface FieldChangeView {\n FieldName: string;\n OldValue: string;\n NewValue: string;\n ChangeType: 'Added' | 'Modified' | 'Removed';\n}\n\ninterface RecordChangeRow {\n ID: string;\n FullRecordJSON: string;\n}\n\ninterface EntityGroupView {\n EntityName: string;\n EntityIcon: string;\n Items: DiffItemView[];\n AddedCount: number;\n RemovedCount: number;\n ModifiedCount: number;\n IsExpanded: boolean;\n NamesLoaded: boolean;\n IsLoadingNames: boolean;\n}\n\n@RegisterClass(BaseResourceComponent, 'VersionHistoryDiffResource')\n@Component({\n standalone: false,\n selector: 'mj-version-history-diff-resource',\n templateUrl: './diff-resource.component.html',\n styleUrls: ['./diff-resource.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class VersionHistoryDiffResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public IsLoading = true;\n public IsDiffLoading = false;\n public HasDiffResult = false;\n\n // Label selection\n public AvailableLabels: MJVersionLabelEntityType[] = [];\n public FromLabelId = '';\n public ToLabelId = '';\n public DiffMode: 'label-to-label' | 'label-to-current' = 'label-to-current';\n\n // Diff results\n public EntityGroups: EntityGroupView[] = [];\n public FilteredEntityGroups: EntityGroupView[] = [];\n public TotalAdded = 0;\n public TotalRemoved = 0;\n public TotalModified = 0;\n public TotalUnchanged = 0;\n\n // Diff result filtering/sorting\n public DiffSortBy: 'name' | 'count' = 'count';\n public DiffSortDir: 'asc' | 'desc' = 'desc';\n public DiffFilterType: 'all' | 'added' | 'removed' | 'modified' = 'all';\n public DiffSearch = '';\n\n // UI state\n public ExpandedEntities = new Set<string>();\n\n private static readonly PREFS_KEY = 'VersionHistory.Diff.UserPreferences';\n private preferencesLoaded = false;\n protected override destroy$ = new Subject<void>();\n private metadata = new Metadata();\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n ngOnInit(): void {\n super.ngOnInit();\n this.loadUserPreferences();\n this.LoadLabels();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Diff Viewer';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-code-compare';\n }\n\n public async LoadLabels(): Promise<void> {\n try {\n this.IsLoading = true;\n this.cdr.markForCheck();\n\n const rv = new RunView();\n const result = await rv.RunView<MJVersionLabelEntityType>({\n EntityName: 'MJ: Version Labels',\n ExtraFilter: \"Status = 'Active'\",\n OrderBy: '__mj_CreatedAt DESC',\n MaxRows: 200,\n ResultType: 'simple'\n });\n\n if (result.Success) {\n this.AvailableLabels = result.Results;\n }\n } catch (error) {\n console.error('Error loading labels for diff:', error);\n } finally {\n this.IsLoading = false;\n this.NotifyLoadComplete();\n this.cdr.markForCheck();\n }\n }\n\n public OnDiffModeChange(mode: 'label-to-label' | 'label-to-current'): void {\n this.DiffMode = mode;\n this.HasDiffResult = false;\n this.EntityGroups = [];\n this.cdr.markForCheck();\n this.persistPreferences();\n }\n\n private loadUserPreferences(): void {\n try {\n const raw = UserInfoEngine.Instance.GetSetting(VersionHistoryDiffResourceComponent.PREFS_KEY);\n if (raw) {\n const prefs: VersionDiffPreferences = JSON.parse(raw);\n if (prefs.DiffMode === 'label-to-label' || prefs.DiffMode === 'label-to-current') {\n this.DiffMode = prefs.DiffMode;\n }\n }\n } catch (error) {\n console.error('Error loading diff preferences:', error);\n this.DiffMode = 'label-to-current';\n }\n this.preferencesLoaded = true;\n }\n\n private persistPreferences(): void {\n if (!this.preferencesLoaded) return;\n const prefs: VersionDiffPreferences = {\n DiffMode: this.DiffMode\n };\n UserInfoEngine.Instance.SetSettingDebounced(VersionHistoryDiffResourceComponent.PREFS_KEY, JSON.stringify(prefs));\n }\n\n public async RunDiff(): Promise<void> {\n if (!this.FromLabelId) return;\n if (this.DiffMode === 'label-to-label' && !this.ToLabelId) return;\n\n try {\n this.IsDiffLoading = true;\n this.HasDiffResult = false;\n this.cdr.markForCheck();\n\n // Load label items for comparison\n const rv = new RunView();\n const fromItems = await this.loadLabelItems(rv, this.FromLabelId);\n\n if (this.DiffMode === 'label-to-label') {\n const toItems = await this.loadLabelItems(rv, this.ToLabelId);\n this.computeDiff(fromItems, toItems);\n } else {\n // Label-to-current: compare label state against live data\n await this.computeDiffToCurrentState(rv, fromItems);\n }\n\n this.HasDiffResult = true;\n } catch (error) {\n console.error('Error running diff:', error);\n } finally {\n this.IsDiffLoading = false;\n this.cdr.markForCheck();\n }\n }\n\n private async loadLabelItems(\n rv: RunView,\n labelId: string\n ): Promise<MJVersionLabelItemEntityType[]> {\n const result = await rv.RunView<MJVersionLabelItemEntityType>({\n EntityName: 'MJ: Version Label Items',\n ExtraFilter: `VersionLabelID = '${labelId}'`,\n ResultType: 'simple'\n });\n return result.Success ? result.Results : [];\n }\n\n private computeDiff(\n fromItems: MJVersionLabelItemEntityType[],\n toItems: MJVersionLabelItemEntityType[]\n ): void {\n const entityMap = new Map<string, DiffItemView[]>();\n\n // Build lookup maps keyed by EntityID + RecordID\n const fromMap = this.buildItemKeyMap(fromItems);\n const toMap = this.buildItemKeyMap(toItems);\n\n // Items in 'to' but not in 'from' = Added\n for (const [key, item] of toMap) {\n const entityName = this.resolveEntityName(item.EntityID ?? '');\n if (!entityMap.has(entityName)) entityMap.set(entityName, []);\n\n if (!fromMap.has(key)) {\n entityMap.get(entityName)!.push({\n EntityName: entityName,\n EntityID: item.EntityID ?? '',\n RecordID: item.RecordID ?? '',\n DisplayName: '',\n ChangeType: 'Added',\n FieldChanges: [],\n IsExpanded: false,\n IsLoadingFields: false,\n FieldsLoaded: false,\n FromRecordChangeID: '',\n ToRecordChangeID: item.RecordChangeID ?? ''\n });\n }\n }\n\n // Items in 'from' but not in 'to' = Removed\n for (const [key, item] of fromMap) {\n const entityName = this.resolveEntityName(item.EntityID ?? '');\n if (!entityMap.has(entityName)) entityMap.set(entityName, []);\n\n if (!toMap.has(key)) {\n entityMap.get(entityName)!.push({\n EntityName: entityName,\n EntityID: item.EntityID ?? '',\n RecordID: item.RecordID ?? '',\n DisplayName: '',\n ChangeType: 'Removed',\n FieldChanges: [],\n IsExpanded: false,\n IsLoadingFields: false,\n FieldsLoaded: false,\n FromRecordChangeID: item.RecordChangeID ?? '',\n ToRecordChangeID: ''\n });\n } else {\n // Both exist - check if RecordChangeID differs (= Modified)\n const toItem = toMap.get(key)!;\n const changeType = !UUIDsEqual(item.RecordChangeID, toItem.RecordChangeID)\n ? 'Modified' : 'Unchanged';\n entityMap.get(entityName)!.push({\n EntityName: entityName,\n EntityID: item.EntityID ?? '',\n RecordID: item.RecordID ?? '',\n DisplayName: '',\n ChangeType: changeType,\n FieldChanges: [],\n IsExpanded: false,\n IsLoadingFields: false,\n FieldsLoaded: false,\n FromRecordChangeID: item.RecordChangeID ?? '',\n ToRecordChangeID: toItem.RecordChangeID ?? ''\n });\n }\n }\n\n this.buildEntityGroups(entityMap);\n }\n\n private async computeDiffToCurrentState(\n rv: RunView,\n labelItems: MJVersionLabelItemEntityType[]\n ): Promise<void> {\n // For label-to-current, compare snapshot RecordChangeIDs against\n // the latest RecordChange for each entity/record combination.\n const entityMap = new Map<string, DiffItemView[]>();\n\n for (const item of labelItems) {\n const entityId = item.EntityID ?? '';\n const entityName = this.resolveEntityName(entityId);\n if (!entityMap.has(entityName)) entityMap.set(entityName, []);\n\n // Load the latest RecordChange for this record\n const latestChangeId = await this.loadLatestRecordChange(rv, entityId, item.RecordID ?? '');\n const isModified = latestChangeId != null && latestChangeId !== item.RecordChangeID;\n\n entityMap.get(entityName)!.push({\n EntityName: entityName,\n EntityID: entityId,\n RecordID: item.RecordID ?? '',\n DisplayName: '',\n ChangeType: isModified ? 'Modified' : 'Unchanged',\n FieldChanges: [],\n IsExpanded: false,\n IsLoadingFields: false,\n FieldsLoaded: false,\n FromRecordChangeID: item.RecordChangeID ?? '',\n ToRecordChangeID: latestChangeId ?? ''\n });\n }\n\n this.buildEntityGroups(entityMap);\n }\n\n private buildItemKeyMap(\n items: MJVersionLabelItemEntityType[]\n ): Map<string, MJVersionLabelItemEntityType> {\n const map = new Map<string, MJVersionLabelItemEntityType>();\n for (const item of items) {\n const key = `${item.EntityID ?? ''}|${item.RecordID ?? ''}`;\n map.set(key, item);\n }\n return map;\n }\n\n private buildEntityGroups(entityMap: Map<string, DiffItemView[]>): void {\n this.TotalAdded = 0;\n this.TotalRemoved = 0;\n this.TotalModified = 0;\n this.TotalUnchanged = 0;\n\n this.EntityGroups = Array.from(entityMap.entries()).map(([entityName, items]) => {\n const added = items.filter(i => i.ChangeType === 'Added').length;\n const removed = items.filter(i => i.ChangeType === 'Removed').length;\n const modified = items.filter(i => i.ChangeType === 'Modified').length;\n\n this.TotalAdded += added;\n this.TotalRemoved += removed;\n this.TotalModified += modified;\n this.TotalUnchanged += items.filter(i => i.ChangeType === 'Unchanged').length;\n\n // Resolve entity icon from first item's EntityID\n const firstItem = items[0];\n const entityIcon = this.resolveEntityIcon(firstItem?.EntityID ?? '');\n\n return {\n EntityName: entityName,\n EntityIcon: entityIcon,\n Items: items.filter(i => i.ChangeType !== 'Unchanged'),\n AddedCount: added,\n RemovedCount: removed,\n ModifiedCount: modified,\n IsExpanded: false,\n NamesLoaded: false,\n IsLoadingNames: false\n };\n }).filter(g => g.Items.length > 0)\n .sort((a, b) => b.Items.length - a.Items.length);\n\n this.ExpandedEntities.clear();\n this.applySortAndFilterDiff();\n }\n\n private resolveEntityName(entityId: string): string {\n if (!entityId) return 'Unknown';\n const entity = this.metadata.Entities.find(e => UUIDsEqual(e.ID, entityId));\n return entity ? entity.Name : 'Unknown';\n }\n\n private resolveEntityIcon(entityId: string): string {\n if (!entityId) return 'fa-solid fa-table';\n const entity = this.metadata.Entities.find(e => UUIDsEqual(e.ID, entityId));\n return entity?.Icon || 'fa-solid fa-table';\n }\n\n // =========================================================================\n // Expand / Collapse\n // =========================================================================\n\n public ToggleEntityGroup(group: EntityGroupView): void {\n group.IsExpanded = !group.IsExpanded;\n if (group.IsExpanded) {\n this.ExpandedEntities.add(group.EntityName);\n // Auto-expand all Modified items so field details show immediately\n for (const item of group.Items) {\n if (item.ChangeType === 'Modified') {\n item.IsExpanded = true;\n }\n }\n // Auto-load field changes for modified items when group opens\n this.loadFieldChangesForGroup(group);\n // Load record display names\n if (!group.NamesLoaded && !group.IsLoadingNames) {\n this.loadGroupRecordNames(group);\n }\n } else {\n this.ExpandedEntities.delete(group.EntityName);\n }\n this.cdr.markForCheck();\n }\n\n public ToggleItem(item: DiffItemView): void {\n if (item.ChangeType !== 'Modified') return;\n item.IsExpanded = !item.IsExpanded;\n if (item.IsExpanded && !item.FieldsLoaded) {\n this.loadFieldChangesForItem(item);\n }\n this.cdr.markForCheck();\n }\n\n public ExpandAllGroups(): void {\n for (const group of this.FilteredEntityGroups) {\n group.IsExpanded = true;\n this.ExpandedEntities.add(group.EntityName);\n this.loadFieldChangesForGroup(group);\n for (const item of group.Items) {\n if (item.ChangeType === 'Modified') {\n item.IsExpanded = true;\n }\n }\n if (!group.NamesLoaded && !group.IsLoadingNames) {\n this.loadGroupRecordNames(group);\n }\n }\n this.cdr.markForCheck();\n }\n\n public CollapseAllGroups(): void {\n for (const group of this.FilteredEntityGroups) {\n group.IsExpanded = false;\n this.ExpandedEntities.delete(group.EntityName);\n for (const item of group.Items) {\n item.IsExpanded = false;\n }\n }\n this.cdr.markForCheck();\n }\n\n public IsEntityExpanded(entityName: string): boolean {\n return this.ExpandedEntities.has(entityName);\n }\n\n /** Open a record in the explorer via NavigationService. */\n public OnOpenRecord(item: DiffItemView): void {\n const rawId = this.extractRawRecordId(item.RecordID);\n const pkey = new CompositeKey([{ FieldName: 'ID', Value: rawId }]);\n this.navigationService.OpenEntityRecord(item.EntityName, pkey);\n }\n\n // =========================================================================\n // Record name resolution\n // =========================================================================\n\n /** Lazy-load record display names for a group using Metadata.GetEntityRecordNames. */\n private async loadGroupRecordNames(group: EntityGroupView): Promise<void> {\n group.IsLoadingNames = true;\n this.cdr.markForCheck();\n\n try {\n const inputs: EntityRecordNameInput[] = group.Items.map(item => {\n const rawId = this.extractRawRecordId(item.RecordID);\n const input = new EntityRecordNameInput();\n input.EntityName = group.EntityName;\n input.CompositeKey = new CompositeKey([{ FieldName: 'ID', Value: rawId }]);\n return input;\n });\n\n const results = await this.metadata.GetEntityRecordNames(inputs);\n\n for (const result of results) {\n if (result.Success && result.RecordName) {\n const resultId = result.CompositeKey?.KeyValuePairs?.[0]?.Value;\n if (resultId) {\n const item = group.Items.find(i =>\n this.extractRawRecordId(i.RecordID) === String(resultId)\n );\n if (item) {\n item.DisplayName = result.RecordName;\n }\n }\n }\n }\n } catch (e) {\n console.error('Error loading record names for group:', group.EntityName, e);\n } finally {\n group.IsLoadingNames = false;\n group.NamesLoaded = true;\n this.cdr.markForCheck();\n }\n }\n\n /** Extract the raw UUID from a RecordID that may be in \"ID|<uuid>\" format. */\n private extractRawRecordId(recordId: string): string {\n if (!recordId) return '';\n const parts = recordId.split('||');\n if (parts.length === 1) {\n const singleParts = recordId.split('|');\n if (singleParts.length === 2) {\n return singleParts[1];\n }\n }\n return recordId;\n }\n\n // =========================================================================\n // Field-level diff loading\n // =========================================================================\n\n /** Auto-load field changes for all modified items in a group (when first expanded). */\n private loadFieldChangesForGroup(group: EntityGroupView): void {\n for (const item of group.Items) {\n if (item.ChangeType === 'Modified' && !item.FieldsLoaded && !item.IsLoadingFields) {\n this.loadFieldChangesForItem(item);\n }\n }\n }\n\n /** Lazy-load field-level changes for a single modified item. */\n private async loadFieldChangesForItem(item: DiffItemView): Promise<void> {\n if (!item.FromRecordChangeID || !item.ToRecordChangeID) {\n item.FieldsLoaded = true;\n return;\n }\n\n item.IsLoadingFields = true;\n this.cdr.markForCheck();\n\n try {\n item.FieldChanges = await this.computeFieldChanges(item.FromRecordChangeID, item.ToRecordChangeID);\n } catch (e) {\n console.error('Error loading field changes:', e);\n } finally {\n item.IsLoadingFields = false;\n item.FieldsLoaded = true;\n this.cdr.markForCheck();\n }\n }\n\n private async loadLatestRecordChange(rv: RunView, entityId: string, recordId: string): Promise<string | null> {\n if (!entityId || !recordId) return null;\n\n const result = await rv.RunView<RecordChangeRow>({\n EntityName: 'MJ: Record Changes',\n ExtraFilter: `EntityID = '${entityId}' AND RecordID = '${recordId}'`,\n OrderBy: 'ChangedAt DESC',\n MaxRows: 1,\n Fields: ['ID'],\n ResultType: 'simple'\n });\n\n if (result.Success && result.Results.length > 0) {\n return result.Results[0].ID;\n }\n return null;\n }\n\n private async computeFieldChanges(oldChangeId: string, newChangeId: string): Promise<FieldChangeView[]> {\n if (!oldChangeId || !newChangeId) return [];\n\n try {\n const rv = new RunView();\n const [oldResult, newResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Record Changes',\n ExtraFilter: `ID = '${oldChangeId}'`,\n Fields: ['FullRecordJSON'],\n ResultType: 'simple'\n },\n {\n EntityName: 'MJ: Record Changes',\n ExtraFilter: `ID = '${newChangeId}'`,\n Fields: ['FullRecordJSON'],\n ResultType: 'simple'\n }\n ]);\n\n if (!oldResult.Success || !newResult.Success) return [];\n if (oldResult.Results.length === 0 || newResult.Results.length === 0) return [];\n\n const oldRow = oldResult.Results[0] as RecordChangeRow;\n const newRow = newResult.Results[0] as RecordChangeRow;\n\n return this.diffRecordJson(oldRow.FullRecordJSON, newRow.FullRecordJSON);\n } catch {\n return [];\n }\n }\n\n private diffRecordJson(oldJson: string, newJson: string): FieldChangeView[] {\n const changes: FieldChangeView[] = [];\n\n try {\n const oldData = JSON.parse(oldJson || '{}') as Record<string, unknown>;\n const newData = JSON.parse(newJson || '{}') as Record<string, unknown>;\n const allKeys = new Set([...Object.keys(oldData), ...Object.keys(newData)]);\n\n for (const key of allKeys) {\n if (key.startsWith('__mj_')) continue;\n\n const oldVal = oldData[key];\n const newVal = newData[key];\n\n if (oldVal === undefined && newVal !== undefined) {\n changes.push({ FieldName: key, OldValue: '', NewValue: this.formatFieldValue(newVal), ChangeType: 'Added' });\n } else if (oldVal !== undefined && newVal === undefined) {\n changes.push({ FieldName: key, OldValue: this.formatFieldValue(oldVal), NewValue: '', ChangeType: 'Removed' });\n } else if (JSON.stringify(oldVal) !== JSON.stringify(newVal)) {\n changes.push({ FieldName: key, OldValue: this.formatFieldValue(oldVal), NewValue: this.formatFieldValue(newVal), ChangeType: 'Modified' });\n }\n }\n } catch {\n // Invalid JSON - skip\n }\n\n return changes;\n }\n\n private formatFieldValue(value: unknown): string {\n if (value == null) return 'null';\n if (typeof value === 'object') return JSON.stringify(value);\n return String(value);\n }\n\n // =========================================================================\n // Display helpers\n // =========================================================================\n\n public GetChangeTypeClass(changeType: string): string {\n const classes: Record<string, string> = {\n 'Added': 'change-added',\n 'Removed': 'change-removed',\n 'Modified': 'change-modified',\n 'Unchanged': 'change-unchanged'\n };\n return classes[changeType] ?? '';\n }\n\n public GetChangeTypeIcon(changeType: string): string {\n const icons: Record<string, string> = {\n 'Added': 'fa-solid fa-plus',\n 'Removed': 'fa-solid fa-minus',\n 'Modified': 'fa-solid fa-pen',\n 'Unchanged': 'fa-solid fa-equals'\n };\n return icons[changeType] ?? 'fa-solid fa-circle';\n }\n\n public FormatRecordID(recordId: string): string {\n return this.extractRawRecordId(recordId);\n }\n\n public FormatLabelOption(label: MJVersionLabelEntityType): string {\n const dateVal = label.__mj_CreatedAt;\n const date = dateVal instanceof Date\n ? dateVal.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })\n : new Date(dateVal as unknown as string).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n return `${label.Name} (${label.Scope}, ${date})`;\n }\n\n public Refresh(): void {\n this.LoadLabels();\n }\n\n public get CanRunDiff(): boolean {\n if (!this.FromLabelId) return false;\n if (this.DiffMode === 'label-to-label' && !this.ToLabelId) return false;\n return true;\n }\n\n public get TotalChanges(): number {\n return this.TotalAdded + this.TotalRemoved + this.TotalModified;\n }\n\n // =========================================================================\n // Label selection helpers\n // =========================================================================\n\n /** From dropdown excludes the currently selected To label. */\n public get FilteredFromLabels(): MJVersionLabelEntityType[] {\n if (!this.ToLabelId) return this.AvailableLabels;\n return this.AvailableLabels.filter(l => !UUIDsEqual(l.ID, this.ToLabelId));\n }\n\n /** To dropdown excludes the currently selected From label. */\n public get FilteredToLabels(): MJVersionLabelEntityType[] {\n if (!this.FromLabelId) return this.AvailableLabels;\n return this.AvailableLabels.filter(l => !UUIDsEqual(l.ID, this.FromLabelId));\n }\n\n /** Swap From and To label selections. */\n public SwapLabels(): void {\n const temp = this.FromLabelId;\n this.FromLabelId = this.ToLabelId;\n this.ToLabelId = temp;\n this.cdr.markForCheck();\n }\n\n // =========================================================================\n // Diff result sorting & filtering\n // =========================================================================\n\n public OnDiffSortChange(sortBy: 'name' | 'count'): void {\n if (this.DiffSortBy === sortBy) {\n this.DiffSortDir = this.DiffSortDir === 'asc' ? 'desc' : 'asc';\n } else {\n this.DiffSortBy = sortBy;\n this.DiffSortDir = sortBy === 'name' ? 'asc' : 'desc';\n }\n this.applySortAndFilterDiff();\n this.cdr.markForCheck();\n }\n\n public OnDiffFilterChange(filterType: 'all' | 'added' | 'removed' | 'modified'): void {\n this.DiffFilterType = filterType;\n this.applySortAndFilterDiff();\n this.cdr.markForCheck();\n }\n\n public OnDiffSearchChange(text: string): void {\n this.DiffSearch = text;\n this.applySortAndFilterDiff();\n this.cdr.markForCheck();\n }\n\n private applySortAndFilterDiff(): void {\n let groups = [...this.EntityGroups];\n\n // Filter by change type\n if (this.DiffFilterType !== 'all') {\n groups = groups.map(g => ({\n ...g,\n Items: g.Items.filter(i => i.ChangeType.toLowerCase() === this.DiffFilterType)\n })).filter(g => g.Items.length > 0);\n }\n\n // Filter by search text\n if (this.DiffSearch) {\n const search = this.DiffSearch.toLowerCase();\n groups = groups\n .filter(g => g.EntityName.toLowerCase().includes(search) ||\n g.Items.some(i => i.RecordID.toLowerCase().includes(search) || i.DisplayName.toLowerCase().includes(search)))\n .map(g => ({\n ...g,\n Items: g.Items.filter(i =>\n i.RecordID.toLowerCase().includes(search) ||\n i.DisplayName.toLowerCase().includes(search) ||\n g.EntityName.toLowerCase().includes(search)\n )\n }))\n .filter(g => g.Items.length > 0);\n }\n\n // Sort\n groups.sort((a, b) => {\n if (this.DiffSortBy === 'name') {\n const cmp = a.EntityName.localeCompare(b.EntityName);\n return this.DiffSortDir === 'asc' ? cmp : -cmp;\n }\n const cmp = a.Items.length - b.Items.length;\n return this.DiffSortDir === 'asc' ? cmp : -cmp;\n });\n\n this.FilteredEntityGroups = groups;\n }\n}\n","<div class=\"diff-container\">\n @if (IsLoading) {\n <mj-loading text=\"Loading diff viewer...\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <!-- Header -->\n <div class=\"page-header\">\n <div class=\"header-left\">\n <h2 class=\"page-title\">Diff Viewer</h2>\n <p class=\"page-subtitle\">Compare states between version labels or against current data</p>\n </div>\n </div>\n <!-- Diff Configuration Panel -->\n <div class=\"config-panel\">\n <!-- Mode Selector -->\n <div class=\"mode-selector\">\n <button class=\"mode-btn\"\n [class.active]=\"DiffMode === 'label-to-current'\"\n (click)=\"OnDiffModeChange('label-to-current')\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n Label vs Current\n </button>\n <button class=\"mode-btn\"\n [class.active]=\"DiffMode === 'label-to-label'\"\n (click)=\"OnDiffModeChange('label-to-label')\">\n <i class=\"fa-solid fa-code-compare\"></i>\n Label vs Label\n </button>\n </div>\n <!-- Label Selectors -->\n <div class=\"label-selectors\">\n <div class=\"selector-group\">\n <label class=\"selector-label\">\n {{DiffMode === 'label-to-current' ? 'Compare label' : 'From label'}}\n </label>\n <select class=\"selector-input\"\n [(ngModel)]=\"FromLabelId\">\n <option value=\"\">Select a label...</option>\n @for (label of FilteredFromLabels; track label) {\n <option\n [value]=\"label.ID\">\n {{FormatLabelOption(label)}}\n </option>\n }\n </select>\n </div>\n @if (DiffMode === 'label-to-label') {\n <div class=\"selector-arrow\">\n <button class=\"swap-btn\" (click)=\"SwapLabels()\" title=\"Swap direction\">\n <i class=\"fa-solid fa-arrows-rotate\"></i>\n </button>\n </div>\n }\n @if (DiffMode === 'label-to-current') {\n <div class=\"selector-arrow\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n <span class=\"current-state-badge\">Current State</span>\n </div>\n }\n @if (DiffMode === 'label-to-label') {\n <div class=\"selector-group\">\n <label class=\"selector-label\">To label</label>\n <select class=\"selector-input\"\n [(ngModel)]=\"ToLabelId\">\n <option value=\"\">Select a label...</option>\n @for (label of FilteredToLabels; track label) {\n <option\n [value]=\"label.ID\">\n {{FormatLabelOption(label)}}\n </option>\n }\n </select>\n </div>\n }\n </div>\n <!-- Run Button -->\n <button class=\"btn-primary\"\n [disabled]=\"!CanRunDiff || IsDiffLoading\"\n (click)=\"RunDiff()\">\n @if (!IsDiffLoading) {\n <i class=\"fa-solid fa-play\"></i>\n }\n @if (IsDiffLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n }\n <span>{{IsDiffLoading ? 'Comparing...' : 'Compare'}}</span>\n </button>\n </div>\n <!-- Diff Results -->\n @if (HasDiffResult) {\n <!-- Summary Stats -->\n <div class=\"diff-summary\">\n <div class=\"diff-stat change-added\">\n <i class=\"fa-solid fa-plus\"></i>\n <span class=\"diff-stat-value\">{{TotalAdded}}</span>\n <span class=\"diff-stat-label\">Added</span>\n </div>\n <div class=\"diff-stat change-removed\">\n <i class=\"fa-solid fa-minus\"></i>\n <span class=\"diff-stat-value\">{{TotalRemoved}}</span>\n <span class=\"diff-stat-label\">Removed</span>\n </div>\n <div class=\"diff-stat change-modified\">\n <i class=\"fa-solid fa-pen\"></i>\n <span class=\"diff-stat-value\">{{TotalModified}}</span>\n <span class=\"diff-stat-label\">Modified</span>\n </div>\n <div class=\"diff-stat change-unchanged\">\n <i class=\"fa-solid fa-equals\"></i>\n <span class=\"diff-stat-value\">{{TotalUnchanged}}</span>\n <span class=\"diff-stat-label\">Unchanged</span>\n </div>\n </div>\n <!-- Results toolbar -->\n @if (EntityGroups.length > 0) {\n <div class=\"diff-toolbar\">\n <div class=\"diff-search\">\n <i class=\"fa-solid fa-search diff-search-icon\"></i>\n <input type=\"text\" class=\"diff-search-input\"\n placeholder=\"Search by entity or record...\"\n [ngModel]=\"DiffSearch\"\n (ngModelChange)=\"OnDiffSearchChange($event)\" />\n </div>\n <div class=\"diff-filter-pills\">\n <button class=\"filter-pill\" [class.active]=\"DiffFilterType === 'all'\"\n (click)=\"OnDiffFilterChange('all')\">All</button>\n <button class=\"filter-pill change-added\" [class.active]=\"DiffFilterType === 'added'\"\n (click)=\"OnDiffFilterChange('added')\">Added</button>\n <button class=\"filter-pill change-removed\" [class.active]=\"DiffFilterType === 'removed'\"\n (click)=\"OnDiffFilterChange('removed')\">Removed</button>\n <button class=\"filter-pill change-modified\" [class.active]=\"DiffFilterType === 'modified'\"\n (click)=\"OnDiffFilterChange('modified')\">Modified</button>\n </div>\n <div class=\"diff-toolbar-right\">\n <button class=\"toolbar-action-btn\" (click)=\"ExpandAllGroups()\" title=\"Expand all\">\n <i class=\"fa-solid fa-angles-down\"></i>\n </button>\n <button class=\"toolbar-action-btn\" (click)=\"CollapseAllGroups()\" title=\"Collapse all\">\n <i class=\"fa-solid fa-angles-up\"></i>\n </button>\n <div class=\"diff-sort-toggle\">\n <button class=\"toggle-btn-sm\" [class.active]=\"DiffSortBy === 'name'\"\n (click)=\"OnDiffSortChange('name')\" title=\"Sort by name\">\n <i class=\"fa-solid\" [ngClass]=\"DiffSortBy === 'name' && DiffSortDir === 'desc' ? 'fa-arrow-up-z-a' : 'fa-arrow-down-a-z'\"></i>\n </button>\n <button class=\"toggle-btn-sm\" [class.active]=\"DiffSortBy === 'count'\"\n (click)=\"OnDiffSortChange('count')\" title=\"Sort by count\">\n <i class=\"fa-solid\" [ngClass]=\"DiffSortBy === 'count' && DiffSortDir === 'asc' ? 'fa-arrow-up-1-9' : 'fa-arrow-down-9-1'\"></i>\n </button>\n </div>\n </div>\n </div>\n }\n <!-- Entity Groups -->\n @if (FilteredEntityGroups.length > 0) {\n <div class=\"entity-groups\">\n @for (group of FilteredEntityGroups; track group) {\n <div class=\"entity-group\">\n <div class=\"entity-group-header\" (click)=\"ToggleEntityGroup(group)\">\n <div class=\"entity-group-left\">\n <i class=\"fa-solid fa-chevron-right entity-chevron\"\n [class.expanded]=\"group.IsExpanded\">\n </i>\n <i [class]=\"group.EntityIcon\" class=\"entity-icon\"></i>\n <span class=\"entity-group-name\">{{group.EntityName}}</span>\n </div>\n <div class=\"entity-group-badges\">\n @if (group.AddedCount > 0) {\n <span class=\"badge change-added\">\n +{{group.AddedCount}}\n </span>\n }\n @if (group.RemovedCount > 0) {\n <span class=\"badge change-removed\">\n -{{group.RemovedCount}}\n </span>\n }\n @if (group.ModifiedCount > 0) {\n <span class=\"badge change-modified\">\n ~{{group.ModifiedCount}}\n </span>\n }\n </div>\n </div>\n @if (group.IsExpanded) {\n <div class=\"entity-group-items\">\n @for (item of group.Items; track item) {\n <div class=\"diff-item-wrapper\">\n <div class=\"diff-item\" [ngClass]=\"GetChangeTypeClass(item.ChangeType)\"\n [class.clickable]=\"item.ChangeType === 'Modified'\"\n (click)=\"ToggleItem(item)\">\n <i [class]=\"GetChangeTypeIcon(item.ChangeType)\" class=\"diff-item-icon\"></i>\n <span class=\"diff-item-record\">\n {{FormatRecordID(item.RecordID)}}\n @if (item.DisplayName) {\n <span class=\"diff-item-display-name\"> ({{item.DisplayName}})</span>\n }\n </span>\n <span class=\"diff-item-type\">{{item.ChangeType}}</span>\n <button class=\"diff-item-open-btn\" (click)=\"OnOpenRecord(item); $event.stopPropagation()\"\n title=\"Open record\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i>\n </button>\n @if (item.ChangeType === 'Modified') {\n <i class=\"fa-solid fa-chevron-right diff-item-chevron\"\n [class.expanded]=\"item.IsExpanded\"\n ></i>\n }\n </div>\n <!-- Field-level changes -->\n @if (item.IsExpanded && item.ChangeType === 'Modified') {\n <div class=\"diff-fields\">\n @if (item.IsLoadingFields) {\n <mj-loading text=\"Loading changes...\" size=\"small\"></mj-loading>\n }\n @if (!item.IsLoadingFields && item.FieldChanges.length > 0) {\n @for (field of item.FieldChanges; track field) {\n <div class=\"diff-field\"\n [ngClass]=\"GetChangeTypeClass(field.ChangeType)\">\n <span class=\"diff-field-name\">{{field.FieldName}}</span>\n <span class=\"diff-field-values\">\n @if (field.OldValue) {\n <span class=\"diff-field-old\">{{field.OldValue | slice:0:60}}</span>\n }\n @if (field.OldValue && field.NewValue) {\n <i class=\"fa-solid fa-arrow-right diff-field-arrow\"></i>\n }\n @if (field.NewValue) {\n <span class=\"diff-field-new\">{{field.NewValue | slice:0:60}}</span>\n }\n </span>\n </div>\n }\n }\n @if (!item.IsLoadingFields && item.FieldsLoaded && item.FieldChanges.length === 0) {\n <div class=\"diff-fields-empty\">\n <span>No field-level changes available</span>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n <!-- No changes -->\n @if (FilteredEntityGroups.length === 0 && TotalChanges === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-check-circle empty-icon\" style=\"color: #10b981;\"></i>\n <h3>No differences found</h3>\n <p>The compared states are identical.</p>\n </div>\n }\n }\n <!-- No results yet -->\n @if (!HasDiffResult && !IsDiffLoading) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-code-compare empty-icon\"></i>\n <h3>Select labels to compare</h3>\n <p>Choose a diff mode and select labels above, then click Compare.</p>\n </div>\n }\n }\n</div>\n"]}
@@ -1,4 +1,5 @@
1
1
  import { OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
2
+ import { Subject } from 'rxjs';
2
3
  import { BaseResourceComponent } from '@memberjunction/ng-shared';
3
4
  import { EntityInfo } from '@memberjunction/core';
4
5
  import { ResourceData } from '@memberjunction/core-entities';
@@ -35,7 +36,7 @@ export declare class VersionHistoryGraphResourceComponent extends BaseResourceCo
35
36
  private static readonly PREFS_KEY;
36
37
  private preferencesLoaded;
37
38
  private metadata;
38
- private destroy$;
39
+ protected destroy$: Subject<void>;
39
40
  constructor(cdr: ChangeDetectorRef);
40
41
  ngOnInit(): void;
41
42
  ngOnDestroy(): void;