@memberjunction/ng-dashboards 5.34.1 → 5.36.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 (407) hide show
  1. package/dist/AI/components/agents/agent-configuration.component.d.ts +51 -0
  2. package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
  3. package/dist/AI/components/agents/agent-configuration.component.js +399 -292
  4. package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
  5. package/dist/AI/components/analytics/agent-runs/agent-run-analysis.component.d.ts +8 -2
  6. package/dist/AI/components/analytics/agent-runs/agent-run-analysis.component.d.ts.map +1 -1
  7. package/dist/AI/components/analytics/agent-runs/agent-run-analysis.component.js +87 -85
  8. package/dist/AI/components/analytics/agent-runs/agent-run-analysis.component.js.map +1 -1
  9. package/dist/AI/components/analytics/ai-analytics-resource.component.d.ts +96 -0
  10. package/dist/AI/components/analytics/ai-analytics-resource.component.d.ts.map +1 -1
  11. package/dist/AI/components/analytics/ai-analytics-resource.component.js +453 -122
  12. package/dist/AI/components/analytics/ai-analytics-resource.component.js.map +1 -1
  13. package/dist/AI/components/analytics/analytics-filter-bar.component.d.ts +5 -0
  14. package/dist/AI/components/analytics/analytics-filter-bar.component.d.ts.map +1 -1
  15. package/dist/AI/components/analytics/analytics-filter-bar.component.js +184 -135
  16. package/dist/AI/components/analytics/analytics-filter-bar.component.js.map +1 -1
  17. package/dist/AI/components/analytics/cost-budget/cost-budget.component.d.ts +8 -2
  18. package/dist/AI/components/analytics/cost-budget/cost-budget.component.d.ts.map +1 -1
  19. package/dist/AI/components/analytics/cost-budget/cost-budget.component.js +104 -103
  20. package/dist/AI/components/analytics/cost-budget/cost-budget.component.js.map +1 -1
  21. package/dist/AI/components/analytics/error-analysis/error-analysis.component.d.ts +8 -2
  22. package/dist/AI/components/analytics/error-analysis/error-analysis.component.d.ts.map +1 -1
  23. package/dist/AI/components/analytics/error-analysis/error-analysis.component.js +76 -74
  24. package/dist/AI/components/analytics/error-analysis/error-analysis.component.js.map +1 -1
  25. package/dist/AI/components/analytics/executive-summary/executive-summary.component.d.ts.map +1 -1
  26. package/dist/AI/components/analytics/executive-summary/executive-summary.component.js +67 -87
  27. package/dist/AI/components/analytics/executive-summary/executive-summary.component.js.map +1 -1
  28. package/dist/AI/components/analytics/model-performance/model-performance.component.d.ts +12 -19
  29. package/dist/AI/components/analytics/model-performance/model-performance.component.d.ts.map +1 -1
  30. package/dist/AI/components/analytics/model-performance/model-performance.component.js +96 -203
  31. package/dist/AI/components/analytics/model-performance/model-performance.component.js.map +1 -1
  32. package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.d.ts.map +1 -1
  33. package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.js +110 -126
  34. package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.js.map +1 -1
  35. package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.d.ts.map +1 -1
  36. package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.js +61 -77
  37. package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.js.map +1 -1
  38. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +28 -0
  39. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
  40. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +2084 -2079
  41. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  42. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +6 -3
  43. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
  44. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +493 -490
  45. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
  46. package/dist/AI/components/models/model-management.component.d.ts +17 -0
  47. package/dist/AI/components/models/model-management.component.d.ts.map +1 -1
  48. package/dist/AI/components/models/model-management.component.js +370 -425
  49. package/dist/AI/components/models/model-management.component.js.map +1 -1
  50. package/dist/AI/components/prompts/prompt-management.component.d.ts +17 -0
  51. package/dist/AI/components/prompts/prompt-management.component.d.ts.map +1 -1
  52. package/dist/AI/components/prompts/prompt-management.component.js +317 -357
  53. package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
  54. package/dist/AI/components/requests/agent-requests-resource.component.d.ts +11 -0
  55. package/dist/AI/components/requests/agent-requests-resource.component.d.ts.map +1 -1
  56. package/dist/AI/components/requests/agent-requests-resource.component.js +170 -175
  57. package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -1
  58. package/dist/AI/components/system/system-configuration.component.d.ts +19 -0
  59. package/dist/AI/components/system/system-configuration.component.d.ts.map +1 -1
  60. package/dist/AI/components/system/system-configuration.component.js +403 -362
  61. package/dist/AI/components/system/system-configuration.component.js.map +1 -1
  62. package/dist/AI/components/tags/tags-resource.component.d.ts +15 -0
  63. package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -1
  64. package/dist/AI/components/tags/tags-resource.component.js +1423 -1438
  65. package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
  66. package/dist/AI/components/vectors/vector-management-resource.component.d.ts +8 -3
  67. package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
  68. package/dist/AI/components/vectors/vector-management-resource.component.js +547 -521
  69. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
  70. package/dist/APIKeys/api-keys-resource.component.d.ts +12 -8
  71. package/dist/APIKeys/api-keys-resource.component.d.ts.map +1 -1
  72. package/dist/APIKeys/api-keys-resource.component.js +329 -371
  73. package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
  74. package/dist/Actions/components/actions-overview.component.d.ts +6 -0
  75. package/dist/Actions/components/actions-overview.component.d.ts.map +1 -1
  76. package/dist/Actions/components/actions-overview.component.js +202 -158
  77. package/dist/Actions/components/actions-overview.component.js.map +1 -1
  78. package/dist/Actions/components/execution-monitoring.component.d.ts +9 -3
  79. package/dist/Actions/components/execution-monitoring.component.d.ts.map +1 -1
  80. package/dist/Actions/components/execution-monitoring.component.js +191 -142
  81. package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
  82. package/dist/Actions/components/explorer/action-explorer.component.d.ts +41 -1
  83. package/dist/Actions/components/explorer/action-explorer.component.d.ts.map +1 -1
  84. package/dist/Actions/components/explorer/action-explorer.component.js +388 -94
  85. package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
  86. package/dist/Actions/components/explorer/index.d.ts +0 -1
  87. package/dist/Actions/components/explorer/index.d.ts.map +1 -1
  88. package/dist/Actions/components/explorer/index.js +0 -1
  89. package/dist/Actions/components/explorer/index.js.map +1 -1
  90. package/dist/Admin/admin-data-schema.component.js +19 -79
  91. package/dist/Admin/admin-data-schema.component.js.map +1 -1
  92. package/dist/Admin/admin-dev-tools-resource.component.js +19 -79
  93. package/dist/Admin/admin-dev-tools-resource.component.js.map +1 -1
  94. package/dist/Admin/admin-identity-access.component.js +19 -79
  95. package/dist/Admin/admin-identity-access.component.js.map +1 -1
  96. package/dist/Admin/admin-monitoring.component.js +19 -79
  97. package/dist/Admin/admin-monitoring.component.js.map +1 -1
  98. package/dist/Admin/base-admin-container.component.d.ts +9 -7
  99. package/dist/Admin/base-admin-container.component.d.ts.map +1 -1
  100. package/dist/Admin/base-admin-container.component.js +26 -17
  101. package/dist/Admin/base-admin-container.component.js.map +1 -1
  102. package/dist/ApplicationRoles/application-roles-resource.component.js +92 -91
  103. package/dist/ApplicationRoles/application-roles-resource.component.js.map +1 -1
  104. package/dist/Archiving/components/archive-config-resource.component.d.ts.map +1 -1
  105. package/dist/Archiving/components/archive-config-resource.component.js +24 -5
  106. package/dist/Archiving/components/archive-config-resource.component.js.map +1 -1
  107. package/dist/Archiving/components/archive-runs-resource.component.d.ts.map +1 -1
  108. package/dist/Archiving/components/archive-runs-resource.component.js +24 -5
  109. package/dist/Archiving/components/archive-runs-resource.component.js.map +1 -1
  110. package/dist/Communication/communication-logs-resource.component.d.ts +1 -1
  111. package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
  112. package/dist/Communication/communication-logs-resource.component.js +80 -99
  113. package/dist/Communication/communication-logs-resource.component.js.map +1 -1
  114. package/dist/Communication/communication-monitor-resource.component.d.ts.map +1 -1
  115. package/dist/Communication/communication-monitor-resource.component.js +127 -106
  116. package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
  117. package/dist/Communication/communication-new-message-resource.component.d.ts +93 -0
  118. package/dist/Communication/communication-new-message-resource.component.d.ts.map +1 -0
  119. package/dist/Communication/communication-new-message-resource.component.js +661 -0
  120. package/dist/Communication/communication-new-message-resource.component.js.map +1 -0
  121. package/dist/Communication/communication-providers-resource.component.d.ts.map +1 -1
  122. package/dist/Communication/communication-providers-resource.component.js +44 -45
  123. package/dist/Communication/communication-providers-resource.component.js.map +1 -1
  124. package/dist/Communication/communication-runs-resource.component.d.ts.map +1 -1
  125. package/dist/Communication/communication-runs-resource.component.js +60 -58
  126. package/dist/Communication/communication-runs-resource.component.js.map +1 -1
  127. package/dist/Communication/communication-templates-resource.component.d.ts +1 -1
  128. package/dist/Communication/communication-templates-resource.component.d.ts.map +1 -1
  129. package/dist/Communication/communication-templates-resource.component.js +139 -162
  130. package/dist/Communication/communication-templates-resource.component.js.map +1 -1
  131. package/dist/Credentials/components/credentials-audit-resource.component.d.ts +7 -0
  132. package/dist/Credentials/components/credentials-audit-resource.component.d.ts.map +1 -1
  133. package/dist/Credentials/components/credentials-audit-resource.component.js +310 -297
  134. package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
  135. package/dist/Credentials/components/credentials-categories-resource.component.js +238 -266
  136. package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
  137. package/dist/Credentials/components/credentials-list-resource.component.d.ts +7 -0
  138. package/dist/Credentials/components/credentials-list-resource.component.d.ts.map +1 -1
  139. package/dist/Credentials/components/credentials-list-resource.component.js +381 -399
  140. package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
  141. package/dist/Credentials/components/credentials-overview-resource.component.js +222 -228
  142. package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
  143. package/dist/Credentials/components/credentials-types-resource.component.d.ts +6 -0
  144. package/dist/Credentials/components/credentials-types-resource.component.d.ts.map +1 -1
  145. package/dist/Credentials/components/credentials-types-resource.component.js +290 -305
  146. package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
  147. package/dist/DatabaseDesigner/components/database-designer-dashboard.component.d.ts +8 -0
  148. package/dist/DatabaseDesigner/components/database-designer-dashboard.component.d.ts.map +1 -1
  149. package/dist/DatabaseDesigner/components/database-designer-dashboard.component.js +41 -21
  150. package/dist/DatabaseDesigner/components/database-designer-dashboard.component.js.map +1 -1
  151. package/dist/DatabaseDesigner/components/entity-list.component.d.ts +2 -0
  152. package/dist/DatabaseDesigner/components/entity-list.component.d.ts.map +1 -1
  153. package/dist/DatabaseDesigner/components/entity-list.component.js +148 -155
  154. package/dist/DatabaseDesigner/components/entity-list.component.js.map +1 -1
  155. package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts +1 -1
  156. package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts.map +1 -1
  157. package/dist/DatabaseDesigner/database-designer-dashboards.module.js +25 -1
  158. package/dist/DatabaseDesigner/database-designer-dashboards.module.js.map +1 -1
  159. package/dist/DevTools/app-state-inspector.component.d.ts +5 -0
  160. package/dist/DevTools/app-state-inspector.component.d.ts.map +1 -1
  161. package/dist/DevTools/app-state-inspector.component.js +46 -72
  162. package/dist/DevTools/app-state-inspector.component.js.map +1 -1
  163. package/dist/DevTools/class-registry.component.js +88 -100
  164. package/dist/DevTools/class-registry.component.js.map +1 -1
  165. package/dist/DevTools/event-monitor.component.js +158 -168
  166. package/dist/DevTools/event-monitor.component.js.map +1 -1
  167. package/dist/DevTools/graphql-console.component.js +257 -264
  168. package/dist/DevTools/graphql-console.component.js.map +1 -1
  169. package/dist/DevTools/layout-inspector.component.d.ts +5 -0
  170. package/dist/DevTools/layout-inspector.component.d.ts.map +1 -1
  171. package/dist/DevTools/layout-inspector.component.js +46 -64
  172. package/dist/DevTools/layout-inspector.component.js.map +1 -1
  173. package/dist/DevTools/lazy-module-status.component.js +75 -84
  174. package/dist/DevTools/lazy-module-status.component.js.map +1 -1
  175. package/dist/DevTools/settings-explorer.component.js +76 -85
  176. package/dist/DevTools/settings-explorer.component.js.map +1 -1
  177. package/dist/EntityAdmin/entity-admin-dashboard.component.d.ts +2 -0
  178. package/dist/EntityAdmin/entity-admin-dashboard.component.d.ts.map +1 -1
  179. package/dist/EntityAdmin/entity-admin-dashboard.component.js +24 -16
  180. package/dist/EntityAdmin/entity-admin-dashboard.component.js.map +1 -1
  181. package/dist/Home/home-dashboard.component.d.ts +6 -0
  182. package/dist/Home/home-dashboard.component.d.ts.map +1 -1
  183. package/dist/Home/home-dashboard.component.js +521 -485
  184. package/dist/Home/home-dashboard.component.js.map +1 -1
  185. package/dist/Integration/components/activity/activity.component.d.ts +8 -0
  186. package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
  187. package/dist/Integration/components/activity/activity.component.js +307 -318
  188. package/dist/Integration/components/activity/activity.component.js.map +1 -1
  189. package/dist/Integration/components/connections/connections.component.js +654 -648
  190. package/dist/Integration/components/connections/connections.component.js.map +1 -1
  191. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +234 -233
  192. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
  193. package/dist/Integration/components/overview/overview.component.js +182 -163
  194. package/dist/Integration/components/overview/overview.component.js.map +1 -1
  195. package/dist/Integration/components/pipelines/pipelines.component.d.ts +2 -0
  196. package/dist/Integration/components/pipelines/pipelines.component.d.ts.map +1 -1
  197. package/dist/Integration/components/pipelines/pipelines.component.js +595 -606
  198. package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
  199. package/dist/Integration/components/schedules/schedules.component.js +230 -241
  200. package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
  201. package/dist/Integration/integration.module.d.ts +1 -1
  202. package/dist/Integration/integration.module.d.ts.map +1 -1
  203. package/dist/Integration/integration.module.js +28 -1
  204. package/dist/Integration/integration.module.js.map +1 -1
  205. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts +5 -0
  206. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -1
  207. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +1138 -1147
  208. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -1
  209. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +54 -51
  210. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -1
  211. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts +11 -0
  212. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts.map +1 -1
  213. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +684 -697
  214. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
  215. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts +12 -1
  216. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts.map +1 -1
  217. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +191 -120
  218. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -1
  219. package/dist/Lists/components/lists-browse-resource.component.d.ts +120 -1
  220. package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
  221. package/dist/Lists/components/lists-browse-resource.component.js +1239 -610
  222. package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
  223. package/dist/Lists/components/lists-categories-resource.component.d.ts.map +1 -1
  224. package/dist/Lists/components/lists-categories-resource.component.js +152 -160
  225. package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
  226. package/dist/Lists/components/lists-my-lists-resource.component.d.ts.map +1 -1
  227. package/dist/Lists/components/lists-my-lists-resource.component.js +302 -319
  228. package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
  229. package/dist/Lists/components/lists-operations-resource.component.d.ts +133 -3
  230. package/dist/Lists/components/lists-operations-resource.component.d.ts.map +1 -1
  231. package/dist/Lists/components/lists-operations-resource.component.js +1460 -272
  232. package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
  233. package/dist/Lists/components/lists-shared-with-me-resource.component.d.ts +29 -0
  234. package/dist/Lists/components/lists-shared-with-me-resource.component.d.ts.map +1 -0
  235. package/dist/Lists/components/lists-shared-with-me-resource.component.js +77 -0
  236. package/dist/Lists/components/lists-shared-with-me-resource.component.js.map +1 -0
  237. package/dist/Lists/components/venn-diagram/venn-diagram.component.d.ts +6 -0
  238. package/dist/Lists/components/venn-diagram/venn-diagram.component.d.ts.map +1 -1
  239. package/dist/Lists/components/venn-diagram/venn-diagram.component.js +35 -7
  240. package/dist/Lists/components/venn-diagram/venn-diagram.component.js.map +1 -1
  241. package/dist/Lists/index.d.ts +1 -0
  242. package/dist/Lists/index.d.ts.map +1 -1
  243. package/dist/Lists/index.js +1 -0
  244. package/dist/Lists/index.js.map +1 -1
  245. package/dist/Lists/services/list-set-operations.service.d.ts +93 -2
  246. package/dist/Lists/services/list-set-operations.service.d.ts.map +1 -1
  247. package/dist/Lists/services/list-set-operations.service.js +236 -10
  248. package/dist/Lists/services/list-set-operations.service.js.map +1 -1
  249. package/dist/MCP/mcp-dashboard.component.d.ts +20 -0
  250. package/dist/MCP/mcp-dashboard.component.d.ts.map +1 -1
  251. package/dist/MCP/mcp-dashboard.component.js +1248 -1338
  252. package/dist/MCP/mcp-dashboard.component.js.map +1 -1
  253. package/dist/MCP/mcp.module.d.ts +1 -1
  254. package/dist/MCP/mcp.module.d.ts.map +1 -1
  255. package/dist/MCP/mcp.module.js +34 -1
  256. package/dist/MCP/mcp.module.js.map +1 -1
  257. package/dist/Permissions/audit-log-resource.component.js +76 -85
  258. package/dist/Permissions/audit-log-resource.component.js.map +1 -1
  259. package/dist/Permissions/resource-access-resource.component.js +64 -69
  260. package/dist/Permissions/resource-access-resource.component.js.map +1 -1
  261. package/dist/Permissions/user-access-resource.component.js +63 -74
  262. package/dist/Permissions/user-access-resource.component.js.map +1 -1
  263. package/dist/QueryBrowser/query-browser-resource.component.js +2 -2
  264. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  265. package/dist/Scheduling/components/scheduling-activity-resource.component.d.ts +2 -1
  266. package/dist/Scheduling/components/scheduling-activity-resource.component.d.ts.map +1 -1
  267. package/dist/Scheduling/components/scheduling-activity-resource.component.js +11 -12
  268. package/dist/Scheduling/components/scheduling-activity-resource.component.js.map +1 -1
  269. package/dist/Scheduling/components/scheduling-activity.component.d.ts +9 -1
  270. package/dist/Scheduling/components/scheduling-activity.component.d.ts.map +1 -1
  271. package/dist/Scheduling/components/scheduling-activity.component.js +250 -197
  272. package/dist/Scheduling/components/scheduling-activity.component.js.map +1 -1
  273. package/dist/Scheduling/components/scheduling-jobs-resource.component.d.ts +2 -1
  274. package/dist/Scheduling/components/scheduling-jobs-resource.component.d.ts.map +1 -1
  275. package/dist/Scheduling/components/scheduling-jobs-resource.component.js +11 -12
  276. package/dist/Scheduling/components/scheduling-jobs-resource.component.js.map +1 -1
  277. package/dist/Scheduling/components/scheduling-jobs.component.d.ts +9 -1
  278. package/dist/Scheduling/components/scheduling-jobs.component.d.ts.map +1 -1
  279. package/dist/Scheduling/components/scheduling-jobs.component.js +203 -147
  280. package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
  281. package/dist/Scheduling/components/scheduling-overview-resource.component.d.ts +2 -1
  282. package/dist/Scheduling/components/scheduling-overview-resource.component.d.ts.map +1 -1
  283. package/dist/Scheduling/components/scheduling-overview-resource.component.js +11 -12
  284. package/dist/Scheduling/components/scheduling-overview-resource.component.js.map +1 -1
  285. package/dist/Scheduling/components/scheduling-overview.component.d.ts +3 -1
  286. package/dist/Scheduling/components/scheduling-overview.component.d.ts.map +1 -1
  287. package/dist/Scheduling/components/scheduling-overview.component.js +224 -190
  288. package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
  289. package/dist/Scheduling/scheduling-dashboard.component.d.ts +19 -6
  290. package/dist/Scheduling/scheduling-dashboard.component.d.ts.map +1 -1
  291. package/dist/Scheduling/scheduling-dashboard.component.js +259 -103
  292. package/dist/Scheduling/scheduling-dashboard.component.js.map +1 -1
  293. package/dist/SystemDiagnostics/system-diagnostics.component.d.ts +13 -3
  294. package/dist/SystemDiagnostics/system-diagnostics.component.d.ts.map +1 -1
  295. package/dist/SystemDiagnostics/system-diagnostics.component.js +1009 -1264
  296. package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
  297. package/dist/Testing/components/testing-analytics-resource.component.d.ts +2 -1
  298. package/dist/Testing/components/testing-analytics-resource.component.d.ts.map +1 -1
  299. package/dist/Testing/components/testing-analytics-resource.component.js +7 -14
  300. package/dist/Testing/components/testing-analytics-resource.component.js.map +1 -1
  301. package/dist/Testing/components/testing-analytics.component.d.ts +3 -1
  302. package/dist/Testing/components/testing-analytics.component.d.ts.map +1 -1
  303. package/dist/Testing/components/testing-analytics.component.js +420 -393
  304. package/dist/Testing/components/testing-analytics.component.js.map +1 -1
  305. package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts +2 -1
  306. package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts.map +1 -1
  307. package/dist/Testing/components/testing-dashboard-tab-resource.component.js +16 -19
  308. package/dist/Testing/components/testing-dashboard-tab-resource.component.js.map +1 -1
  309. package/dist/Testing/components/testing-dashboard-tab.component.d.ts +3 -1
  310. package/dist/Testing/components/testing-dashboard-tab.component.d.ts.map +1 -1
  311. package/dist/Testing/components/testing-dashboard-tab.component.js +157 -122
  312. package/dist/Testing/components/testing-dashboard-tab.component.js.map +1 -1
  313. package/dist/Testing/components/testing-explorer-resource.component.d.ts +2 -1
  314. package/dist/Testing/components/testing-explorer-resource.component.d.ts.map +1 -1
  315. package/dist/Testing/components/testing-explorer-resource.component.js +7 -12
  316. package/dist/Testing/components/testing-explorer-resource.component.js.map +1 -1
  317. package/dist/Testing/components/testing-explorer.component.d.ts +38 -6
  318. package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
  319. package/dist/Testing/components/testing-explorer.component.js +679 -786
  320. package/dist/Testing/components/testing-explorer.component.js.map +1 -1
  321. package/dist/Testing/components/testing-review-resource.component.d.ts +4 -1
  322. package/dist/Testing/components/testing-review-resource.component.d.ts.map +1 -1
  323. package/dist/Testing/components/testing-review-resource.component.js +9 -12
  324. package/dist/Testing/components/testing-review-resource.component.js.map +1 -1
  325. package/dist/Testing/components/testing-review.component.d.ts +3 -1
  326. package/dist/Testing/components/testing-review.component.d.ts.map +1 -1
  327. package/dist/Testing/components/testing-review.component.js +310 -274
  328. package/dist/Testing/components/testing-review.component.js.map +1 -1
  329. package/dist/Testing/components/testing-runs-resource.component.d.ts +2 -1
  330. package/dist/Testing/components/testing-runs-resource.component.d.ts.map +1 -1
  331. package/dist/Testing/components/testing-runs-resource.component.js +16 -19
  332. package/dist/Testing/components/testing-runs-resource.component.js.map +1 -1
  333. package/dist/Testing/components/testing-runs.component.d.ts +3 -1
  334. package/dist/Testing/components/testing-runs.component.d.ts.map +1 -1
  335. package/dist/Testing/components/testing-runs.component.js +307 -273
  336. package/dist/Testing/components/testing-runs.component.js.map +1 -1
  337. package/dist/Testing/testing-dashboard.component.d.ts +2 -0
  338. package/dist/Testing/testing-dashboard.component.d.ts.map +1 -1
  339. package/dist/Testing/testing-dashboard.component.js +114 -99
  340. package/dist/Testing/testing-dashboard.component.js.map +1 -1
  341. package/dist/VersionHistory/components/diff-resource.component.js +185 -188
  342. package/dist/VersionHistory/components/diff-resource.component.js.map +1 -1
  343. package/dist/VersionHistory/components/graph-resource.component.js +154 -184
  344. package/dist/VersionHistory/components/graph-resource.component.js.map +1 -1
  345. package/dist/VersionHistory/components/labels-resource.component.d.ts +7 -0
  346. package/dist/VersionHistory/components/labels-resource.component.d.ts.map +1 -1
  347. package/dist/VersionHistory/components/labels-resource.component.js +350 -354
  348. package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
  349. package/dist/VersionHistory/components/restore-resource.component.js +163 -169
  350. package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
  351. package/dist/actions-dashboards.module.d.ts +15 -16
  352. package/dist/actions-dashboards.module.d.ts.map +1 -1
  353. package/dist/actions-dashboards.module.js +34 -11
  354. package/dist/actions-dashboards.module.js.map +1 -1
  355. package/dist/ai-dashboards.module.d.ts +45 -48
  356. package/dist/ai-dashboards.module.d.ts.map +1 -1
  357. package/dist/ai-dashboards.module.js +51 -10
  358. package/dist/ai-dashboards.module.js.map +1 -1
  359. package/dist/archiving-dashboards.module.d.ts +2 -1
  360. package/dist/archiving-dashboards.module.d.ts.map +1 -1
  361. package/dist/archiving-dashboards.module.js +12 -2
  362. package/dist/archiving-dashboards.module.js.map +1 -1
  363. package/dist/communication-dashboards.module.d.ts +9 -6
  364. package/dist/communication-dashboards.module.d.ts.map +1 -1
  365. package/dist/communication-dashboards.module.js +37 -7
  366. package/dist/communication-dashboards.module.js.map +1 -1
  367. package/dist/core-dashboards.module.d.ts +1 -1
  368. package/dist/core-dashboards.module.d.ts.map +1 -1
  369. package/dist/core-dashboards.module.js +46 -1
  370. package/dist/core-dashboards.module.js.map +1 -1
  371. package/dist/credentials-dashboards.module.d.ts +1 -1
  372. package/dist/credentials-dashboards.module.d.ts.map +1 -1
  373. package/dist/credentials-dashboards.module.js +28 -1
  374. package/dist/credentials-dashboards.module.js.map +1 -1
  375. package/dist/lists-dashboards.module.d.ts +10 -9
  376. package/dist/lists-dashboards.module.d.ts.map +1 -1
  377. package/dist/lists-dashboards.module.js +40 -2
  378. package/dist/lists-dashboards.module.js.map +1 -1
  379. package/dist/public-api.d.ts +3 -2
  380. package/dist/public-api.d.ts.map +1 -1
  381. package/dist/public-api.js +4 -3
  382. package/dist/public-api.js.map +1 -1
  383. package/dist/scheduling-dashboards.module.d.ts +1 -1
  384. package/dist/scheduling-dashboards.module.d.ts.map +1 -1
  385. package/dist/scheduling-dashboards.module.js +31 -1
  386. package/dist/scheduling-dashboards.module.js.map +1 -1
  387. package/dist/testing-dashboards.module.d.ts +8 -7
  388. package/dist/testing-dashboards.module.d.ts.map +1 -1
  389. package/dist/testing-dashboards.module.js +42 -0
  390. package/dist/testing-dashboards.module.js.map +1 -1
  391. package/package.json +53 -52
  392. package/dist/AI/components/agents/agent-filter-panel.component.d.ts +0 -56
  393. package/dist/AI/components/agents/agent-filter-panel.component.d.ts.map +0 -1
  394. package/dist/AI/components/agents/agent-filter-panel.component.js +0 -285
  395. package/dist/AI/components/agents/agent-filter-panel.component.js.map +0 -1
  396. package/dist/AI/components/prompts/prompt-filter-panel.component.d.ts +0 -49
  397. package/dist/AI/components/prompts/prompt-filter-panel.component.d.ts.map +0 -1
  398. package/dist/AI/components/prompts/prompt-filter-panel.component.js +0 -184
  399. package/dist/AI/components/prompts/prompt-filter-panel.component.js.map +0 -1
  400. package/dist/AI/components/system/system-config-filter-panel.component.d.ts +0 -33
  401. package/dist/AI/components/system/system-config-filter-panel.component.d.ts.map +0 -1
  402. package/dist/AI/components/system/system-config-filter-panel.component.js +0 -144
  403. package/dist/AI/components/system/system-config-filter-panel.component.js.map +0 -1
  404. package/dist/Actions/components/explorer/action-toolbar.component.d.ts +0 -63
  405. package/dist/Actions/components/explorer/action-toolbar.component.d.ts.map +0 -1
  406. package/dist/Actions/components/explorer/action-toolbar.component.js +0 -463
  407. package/dist/Actions/components/explorer/action-toolbar.component.js.map +0 -1
@@ -3,9 +3,46 @@ import { MJListEntity } from '@memberjunction/core-entities';
3
3
  import { Observable } from 'rxjs';
4
4
  import * as i0 from "@angular/core";
5
5
  /**
6
- * Represents a set (list) in the Venn diagram
6
+ * Describes one operand for the Venn / set-op pipeline. The component
7
+ * passes these in instead of raw `MJListEntity`s now that views are
8
+ * supported; the service handles cache-keying + record-ID resolution.
9
+ */
10
+ export interface SetOperand {
11
+ kind: OperandKind;
12
+ /** ID of the underlying MJ List or MJ User View. */
13
+ id: string;
14
+ /** Display name shown in the Venn legend + selection chips. */
15
+ name: string;
16
+ /** Entity ID — used to enforce the same-entity invariant on operations. */
17
+ entityID: string;
18
+ /** Entity name — denormalized for display. */
19
+ entityName: string;
20
+ /** Hex color from the predefined palette; chosen by the component. */
21
+ color: string;
22
+ }
23
+ /**
24
+ * Discriminates a Venn set / set-op operand between a saved MJ List and a
25
+ * User View. The Venn diagram uses this to render views with a dashed
26
+ * stroke (per mockup 10) so users can tell at a glance which inputs are
27
+ * static (lists) vs. dynamic-at-resolution (views).
28
+ */
29
+ export type OperandKind = 'list' | 'view';
30
+ /**
31
+ * Stable key for an operand across cache lookups + state persistence.
32
+ * `list:<id>` and `view:<id>` deliberately namespace the ID so a view and
33
+ * a list with the same UUID (extremely unlikely but possible) can't
34
+ * collide in the cache.
35
+ */
36
+ export declare function OperandCacheKey(kind: OperandKind, id: string): string;
37
+ /**
38
+ * Represents a set (list or view) in the Venn diagram
7
39
  */
8
40
  export interface VennSet {
41
+ /** Stable cache key. Use `OperandCacheKey()` to construct. */
42
+ operandKey: string;
43
+ /** Discriminator — drives the dashed-vs-solid stroke in the Venn diagram. */
44
+ kind: OperandKind;
45
+ /** Underlying list / view ID. Same UUID space as the entity it points at. */
9
46
  listId: string;
10
47
  listName: string;
11
48
  color: string;
@@ -79,6 +116,25 @@ export declare class ListSetOperationsService {
79
116
  * Load list data and calculate all intersections for Venn visualization
80
117
  */
81
118
  calculateVennData(lists: MJListEntity[]): Promise<VennData>;
119
+ /**
120
+ * Generalized Venn-data loader supporting both lists and views.
121
+ *
122
+ * - Lists resolve via the same `MJ: List Details` query as the legacy
123
+ * path (cached by `list:<id>`).
124
+ * - Views resolve via `RunView({ViewID})` and primary-key serialization;
125
+ * cached by `view:<id>` so picking the same view twice doesn't
126
+ * re-query.
127
+ *
128
+ * The cache deliberately namespaces the kind — a list and a view that
129
+ * shared the same UUID would still hit distinct entries.
130
+ */
131
+ calculateVennDataForOperands(operands: SetOperand[]): Promise<VennData>;
132
+ /**
133
+ * Operand-aware sibling of `performOperation`. `operandKeys` are the
134
+ * `OperandCacheKey()` strings produced by `calculateVennDataForOperands`,
135
+ * so callers can stay in operand-key space end-to-end.
136
+ */
137
+ performOperationForOperands(operation: SetOperation, operands: SetOperand[], allOperands?: SetOperand[]): Promise<SetOperationResult>;
82
138
  /**
83
139
  * Calculate all possible intersections between the given sets
84
140
  */
@@ -96,7 +152,42 @@ export declare class ListSetOperationsService {
96
152
  */
97
153
  performOperation(operation: SetOperation, listIds: string[], allListIds?: string[]): Promise<SetOperationResult>;
98
154
  /**
99
- * Ensure list details are loaded for the given list IDs
155
+ * Cached lookup keyed by operand kind+id. Lists and views share the
156
+ * cache map but their entries can't collide thanks to the key namespace.
157
+ */
158
+ private cacheGet;
159
+ /**
160
+ * Bulk-load any operands not already cached. Lists batch through a
161
+ * single `MJ: List Details` query (same shape as before); views resolve
162
+ * one at a time because each is a separate parameterized RunView. Both
163
+ * paths populate the same cache map.
164
+ */
165
+ private ensureOperandsLoaded;
166
+ private loadMissingLists;
167
+ private loadMissingViews;
168
+ /**
169
+ * Resolve a view to a set of record IDs in the canonical `MJ: List
170
+ * Details.RecordID` format (single-PK → raw value; composite-PK →
171
+ * `Field1|Value1||Field2|Value2`, matching `CompositeKey.ToConcatenatedString`).
172
+ * This keeps view operands cache-compatible with list operands without
173
+ * any transformation in the set-op logic.
174
+ */
175
+ private loadSingleView;
176
+ /**
177
+ * Mirror of `ListOperations.serializeRecordId` so view operands produce
178
+ * IDs that round-trip cleanly against MJ List Details.
179
+ */
180
+ private serializeRecordId;
181
+ /**
182
+ * Pure compute step shared by the legacy and operand-aware paths.
183
+ * Operates on raw `Set<string>` inputs so it stays agnostic to where
184
+ * those sets came from.
185
+ */
186
+ private computeOperationResult;
187
+ /**
188
+ * Ensure list details are loaded for the given list IDs. Cache keys use
189
+ * the `list:<id>` namespace introduced for operand support; the legacy
190
+ * list-only callers go through here without needing to know the format.
100
191
  */
101
192
  private ensureListsLoaded;
102
193
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"list-set-operations.service.d.ts","sourceRoot":"","sources":["../../../src/Lists/services/list-set-operations.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAsB,MAAM,+BAA+B,CAAC;AACjF,OAAO,EAAmB,UAAU,EAAE,MAAM,MAAM,CAAC;;AAEnD;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;IAEjB;;OAEG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;IAEpB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;IAEpB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,aAAa,EAAE,gBAAgB,EAAE,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,cAAc,GAAG,YAAY,GAAG,sBAAsB,GAAG,YAAY,CAAC;AAE3G;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,YAAY,CAAC;IACxB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;CACrB;AAcD;;GAEG;AACH,qBAGa,wBAAwB;IACnC,OAAO,CAAC,SAAS,CAAkC;IACnD,sGAAsG;IACtG,IAAW,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,EAElD;IACD,IAAW,QAAQ,IAAI,iBAAiB,CAEvC;IACD,OAAO,CAAC,cAAc,CAAuC;IACtD,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,CAAsC;IAG1E,OAAO,CAAC,gBAAgB,CAAkC;;IAI1D;;OAEG;IACG,iBAAiB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC;IA8DjE;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAqCjC;;OAEG;IACH,OAAO,CAAC,8BAA8B;IAoBtC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAO9B;;OAEG;IACG,gBAAgB,CACpB,SAAS,EAAE,YAAY,EACvB,OAAO,EAAE,MAAM,EAAE,EACjB,UAAU,CAAC,EAAE,MAAM,EAAE,GACpB,OAAO,CAAC,kBAAkB,CAAC;IAgE9B;;OAEG;YACW,iBAAiB;IA8B/B;;OAEG;IACH,OAAO,CAAC,SAAS;IAUjB;;OAEG;IACH,OAAO,CAAC,UAAU;IAUlB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAUhB;;OAEG;IACH,OAAO,CAAC,YAAY;IAWpB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAqB9B;;OAEG;IACH,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAIvC;;OAEG;IACH,UAAU,IAAI,IAAI;yCA1VP,wBAAwB;6CAAxB,wBAAwB;CA6VpC"}
1
+ {"version":3,"file":"list-set-operations.service.d.ts","sourceRoot":"","sources":["../../../src/Lists/services/list-set-operations.service.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,34 @@
1
1
  import { Injectable } from '@angular/core';
2
- import { RunView, Metadata } from '@memberjunction/core';
2
+ import { RunView, Metadata, CompositeKey } from '@memberjunction/core';
3
+ import { NormalizeUUID } from '@memberjunction/global';
3
4
  import { BehaviorSubject } from 'rxjs';
4
5
  import * as i0 from "@angular/core";
6
+ /**
7
+ * Normalize an `MJ: List Details.RecordID`-style string so set operations
8
+ * compare correctly regardless of where the value originated.
9
+ *
10
+ * The wrinkle: SQL Server returns UUIDs uppercased, PostgreSQL returns
11
+ * them lowercased — and the same DB can host List Details written by
12
+ * different code paths with different casing. Composite-PK keys are
13
+ * concatenated strings (`Field1|Value1||Field2|Value2`); normalizing
14
+ * the whole string is safe — `NormalizeUUID` lowercases anything that
15
+ * pattern-matches a UUID and is a no-op on other content. The pipe
16
+ * separators in composite keys are unaffected.
17
+ */
18
+ function normalizeRecordId(raw) {
19
+ if (raw == null)
20
+ return '';
21
+ return NormalizeUUID(String(raw));
22
+ }
23
+ /**
24
+ * Stable key for an operand across cache lookups + state persistence.
25
+ * `list:<id>` and `view:<id>` deliberately namespace the ID so a view and
26
+ * a list with the same UUID (extremely unlikely but possible) can't
27
+ * collide in the cache.
28
+ */
29
+ export function OperandCacheKey(kind, id) {
30
+ return `${kind}:${id}`;
31
+ }
5
32
  // Predefined color palette for Venn sets
6
33
  const VENN_COLORS = [
7
34
  '#2196F3', // Blue
@@ -62,12 +89,18 @@ export class ListSetOperationsService {
62
89
  }
63
90
  }
64
91
  }
65
- // Update cache
92
+ // Update cache — namespaced under `list:` so view operands can share
93
+ // the same cache map without collision.
66
94
  for (const [listId, records] of setsMap) {
67
- this.listDetailsCache.set(listId, records);
95
+ this.listDetailsCache.set(OperandCacheKey('list', listId), records);
68
96
  }
69
- // Build VennSet objects
97
+ // Build VennSet objects. We keep the legacy `MJListEntity` overload's
98
+ // shape but populate the new discriminator fields so the diagram +
99
+ // downstream operations stay consistent regardless of which entry
100
+ // point was used.
70
101
  const sets = lists.map((list, index) => ({
102
+ operandKey: OperandCacheKey('list', list.ID),
103
+ kind: 'list',
71
104
  listId: list.ID,
72
105
  listName: list.Name,
73
106
  color: VENN_COLORS[index % VENN_COLORS.length],
@@ -85,6 +118,64 @@ export class ListSetOperationsService {
85
118
  this.loadingSubject.next(false);
86
119
  }
87
120
  }
121
+ /**
122
+ * Generalized Venn-data loader supporting both lists and views.
123
+ *
124
+ * - Lists resolve via the same `MJ: List Details` query as the legacy
125
+ * path (cached by `list:<id>`).
126
+ * - Views resolve via `RunView({ViewID})` and primary-key serialization;
127
+ * cached by `view:<id>` so picking the same view twice doesn't
128
+ * re-query.
129
+ *
130
+ * The cache deliberately namespaces the kind — a list and a view that
131
+ * shared the same UUID would still hit distinct entries.
132
+ */
133
+ async calculateVennDataForOperands(operands) {
134
+ if (operands.length === 0)
135
+ return { sets: [], intersections: [] };
136
+ this.loadingSubject.next(true);
137
+ try {
138
+ await this.ensureOperandsLoaded(operands);
139
+ const sets = operands.map((op) => ({
140
+ operandKey: OperandCacheKey(op.kind, op.id),
141
+ kind: op.kind,
142
+ listId: op.id,
143
+ listName: op.name,
144
+ color: op.color,
145
+ recordIds: this.cacheGet(op) ?? new Set(),
146
+ size: this.cacheGet(op)?.size ?? 0,
147
+ }));
148
+ const intersections = this.calculateAllIntersections(sets);
149
+ const entityId = operands[0]?.entityID;
150
+ const entityName = operands[0]?.entityName;
151
+ return { sets, intersections, entityId, entityName };
152
+ }
153
+ finally {
154
+ this.loadingSubject.next(false);
155
+ }
156
+ }
157
+ /**
158
+ * Operand-aware sibling of `performOperation`. `operandKeys` are the
159
+ * `OperandCacheKey()` strings produced by `calculateVennDataForOperands`,
160
+ * so callers can stay in operand-key space end-to-end.
161
+ */
162
+ async performOperationForOperands(operation, operands, allOperands) {
163
+ this.loadingSubject.next(true);
164
+ try {
165
+ await this.ensureOperandsLoaded([...operands, ...(allOperands ?? [])]);
166
+ const sets = operands.map((op) => this.cacheGet(op) ?? new Set());
167
+ const resultSet = this.computeOperationResult(operation, sets, allOperands);
168
+ return {
169
+ operation,
170
+ inputSetIds: operands.map((op) => OperandCacheKey(op.kind, op.id)),
171
+ resultRecordIds: Array.from(resultSet),
172
+ resultCount: resultSet.size,
173
+ };
174
+ }
175
+ finally {
176
+ this.loadingSubject.next(false);
177
+ }
178
+ }
88
179
  /**
89
180
  * Calculate all possible intersections between the given sets
90
181
  */
@@ -154,7 +245,7 @@ export class ListSetOperationsService {
154
245
  try {
155
246
  // Ensure we have the list details loaded
156
247
  await this.ensureListsLoaded(listIds);
157
- const sets = listIds.map(id => this.listDetailsCache.get(id) || new Set());
248
+ const sets = listIds.map(id => this.listDetailsCache.get(OperandCacheKey('list', id)) || new Set());
158
249
  let resultSet;
159
250
  switch (operation) {
160
251
  case 'union':
@@ -183,7 +274,7 @@ export class ListSetOperationsService {
183
274
  // Records NOT in any of the selected sets (requires allListIds)
184
275
  if (allListIds) {
185
276
  await this.ensureListsLoaded(allListIds);
186
- const allSets = allListIds.map(id => this.listDetailsCache.get(id) || new Set());
277
+ const allSets = allListIds.map(id => this.listDetailsCache.get(OperandCacheKey('list', id)) || new Set());
187
278
  const allRecords = this.unionAll(allSets);
188
279
  const selectedRecords = this.unionAll(sets);
189
280
  resultSet = this.difference(allRecords, selectedRecords);
@@ -207,10 +298,145 @@ export class ListSetOperationsService {
207
298
  }
208
299
  }
209
300
  /**
210
- * Ensure list details are loaded for the given list IDs
301
+ * Cached lookup keyed by operand kind+id. Lists and views share the
302
+ * cache map but their entries can't collide thanks to the key namespace.
303
+ */
304
+ cacheGet(operand) {
305
+ return this.listDetailsCache.get(OperandCacheKey(operand.kind, operand.id));
306
+ }
307
+ /**
308
+ * Bulk-load any operands not already cached. Lists batch through a
309
+ * single `MJ: List Details` query (same shape as before); views resolve
310
+ * one at a time because each is a separate parameterized RunView. Both
311
+ * paths populate the same cache map.
312
+ */
313
+ async ensureOperandsLoaded(operands) {
314
+ const missingLists = [];
315
+ const missingViews = [];
316
+ for (const op of operands) {
317
+ if (this.cacheGet(op))
318
+ continue;
319
+ if (op.kind === 'list')
320
+ missingLists.push(op.id);
321
+ else
322
+ missingViews.push(op);
323
+ }
324
+ await Promise.all([
325
+ missingLists.length > 0 ? this.loadMissingLists(missingLists) : Promise.resolve(),
326
+ missingViews.length > 0 ? this.loadMissingViews(missingViews) : Promise.resolve(),
327
+ ]);
328
+ }
329
+ async loadMissingLists(listIds) {
330
+ const listIdFilter = listIds.map((id) => `'${id}'`).join(',');
331
+ const rv = RunView.FromMetadataProvider(this.Provider);
332
+ const result = await rv.RunView({
333
+ EntityName: 'MJ: List Details',
334
+ ExtraFilter: `ListID IN (${listIdFilter})`,
335
+ Fields: ['ListID', 'RecordID'],
336
+ ResultType: 'simple',
337
+ });
338
+ for (const id of listIds) {
339
+ this.listDetailsCache.set(OperandCacheKey('list', id), new Set());
340
+ }
341
+ if (result.Success && result.Results) {
342
+ for (const detail of result.Results) {
343
+ // Normalize on the ListID we look up by AND on the RecordID we
344
+ // store — mixed casing on either side would otherwise produce
345
+ // empty intersections between lists that actually share records.
346
+ const set = this.listDetailsCache.get(OperandCacheKey('list', NormalizeUUID(detail.ListID)))
347
+ ?? this.listDetailsCache.get(OperandCacheKey('list', detail.ListID));
348
+ if (set)
349
+ set.add(normalizeRecordId(detail.RecordID));
350
+ }
351
+ }
352
+ }
353
+ async loadMissingViews(operands) {
354
+ // Fire view queries in parallel — each one is small and independent.
355
+ const tasks = operands.map((op) => this.loadSingleView(op));
356
+ await Promise.all(tasks);
357
+ }
358
+ /**
359
+ * Resolve a view to a set of record IDs in the canonical `MJ: List
360
+ * Details.RecordID` format (single-PK → raw value; composite-PK →
361
+ * `Field1|Value1||Field2|Value2`, matching `CompositeKey.ToConcatenatedString`).
362
+ * This keeps view operands cache-compatible with list operands without
363
+ * any transformation in the set-op logic.
364
+ */
365
+ async loadSingleView(operand) {
366
+ const md = this.Provider;
367
+ const entityInfo = md.EntityByName(operand.entityName);
368
+ if (!entityInfo) {
369
+ this.listDetailsCache.set(OperandCacheKey('view', operand.id), new Set());
370
+ return;
371
+ }
372
+ const pkFields = entityInfo.PrimaryKeys.map((pk) => pk.Name);
373
+ const rv = RunView.FromMetadataProvider(md);
374
+ const result = await rv.RunView({
375
+ ViewID: operand.id,
376
+ Fields: pkFields,
377
+ ResultType: 'simple',
378
+ });
379
+ const set = new Set();
380
+ if (result.Success && result.Results) {
381
+ for (const row of result.Results) {
382
+ set.add(this.serializeRecordId(entityInfo, row));
383
+ }
384
+ }
385
+ this.listDetailsCache.set(OperandCacheKey('view', operand.id), set);
386
+ }
387
+ /**
388
+ * Mirror of `ListOperations.serializeRecordId` so view operands produce
389
+ * IDs that round-trip cleanly against MJ List Details.
390
+ */
391
+ serializeRecordId(entityInfo, row) {
392
+ if (entityInfo.PrimaryKeys.length === 1) {
393
+ return normalizeRecordId(String(row[entityInfo.PrimaryKeys[0].Name]));
394
+ }
395
+ const ck = new CompositeKey();
396
+ ck.KeyValuePairs = entityInfo.PrimaryKeys.map((pk) => ({
397
+ FieldName: pk.Name,
398
+ Value: row[pk.Name],
399
+ }));
400
+ return normalizeRecordId(ck.ToConcatenatedString());
401
+ }
402
+ /**
403
+ * Pure compute step shared by the legacy and operand-aware paths.
404
+ * Operates on raw `Set<string>` inputs so it stays agnostic to where
405
+ * those sets came from.
406
+ */
407
+ computeOperationResult(operation, sets, allOperandsForComplement) {
408
+ switch (operation) {
409
+ case 'union':
410
+ return this.unionAll(sets);
411
+ case 'intersection':
412
+ return this.intersectAll(sets);
413
+ case 'difference': {
414
+ if (sets.length < 2)
415
+ return sets[0] ?? new Set();
416
+ let r = new Set(sets[0]);
417
+ for (let i = 1; i < sets.length; i++)
418
+ r = this.difference(r, sets[i]);
419
+ return r;
420
+ }
421
+ case 'symmetric_difference':
422
+ return this.symmetricDifferenceAll(sets);
423
+ case 'complement': {
424
+ if (!allOperandsForComplement)
425
+ return new Set();
426
+ const allSets = allOperandsForComplement.map((op) => this.cacheGet(op) ?? new Set());
427
+ return this.difference(this.unionAll(allSets), this.unionAll(sets));
428
+ }
429
+ default:
430
+ return new Set();
431
+ }
432
+ }
433
+ /**
434
+ * Ensure list details are loaded for the given list IDs. Cache keys use
435
+ * the `list:<id>` namespace introduced for operand support; the legacy
436
+ * list-only callers go through here without needing to know the format.
211
437
  */
212
438
  async ensureListsLoaded(listIds) {
213
- const missingIds = listIds.filter(id => !this.listDetailsCache.has(id));
439
+ const missingIds = listIds.filter(id => !this.listDetailsCache.has(OperandCacheKey('list', id)));
214
440
  if (missingIds.length === 0)
215
441
  return;
216
442
  const listIdFilter = missingIds.map(id => `'${id}'`).join(',');
@@ -223,11 +449,11 @@ export class ListSetOperationsService {
223
449
  });
224
450
  // Initialize sets for missing lists
225
451
  for (const id of missingIds) {
226
- this.listDetailsCache.set(id, new Set());
452
+ this.listDetailsCache.set(OperandCacheKey('list', id), new Set());
227
453
  }
228
454
  if (result.Success && result.Results) {
229
455
  for (const detail of result.Results) {
230
- const set = this.listDetailsCache.get(detail.ListID);
456
+ const set = this.listDetailsCache.get(OperandCacheKey('list', detail.ListID));
231
457
  if (set) {
232
458
  set.add(detail.RecordID);
233
459
  }
@@ -1 +1 @@
1
- {"version":3,"file":"list-set-operations.service.js","sourceRoot":"","sources":["../../../src/Lists/services/list-set-operations.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { RunView, Metadata, IMetadataProvider } from '@memberjunction/core';\nimport { MJListEntity, MJListDetailEntity } from '@memberjunction/core-entities';\nimport { BehaviorSubject, Observable } from 'rxjs';\n\n/**\n * Represents a set (list) in the Venn diagram\n */\nexport interface VennSet {\n listId: string;\n listName: string;\n color: string;\n recordIds: Set<string>;\n size: number;\n}\n\n/**\n * Represents an intersection region in the Venn diagram\n */\nexport interface VennIntersection {\n /**\n * IDs of lists that participate in this intersection\n */\n setIds: string[];\n\n /**\n * Labels of lists that participate in this intersection\n */\n setLabels: string[];\n\n /**\n * Number of records in this intersection\n */\n size: number;\n\n /**\n * Actual record IDs in this intersection\n */\n recordIds: string[];\n\n /**\n * Display label for this region\n */\n label: string;\n\n /**\n * Whether this region is currently selected\n */\n isSelected: boolean;\n}\n\n/**\n * Complete Venn data for visualization\n */\nexport interface VennData {\n sets: VennSet[];\n intersections: VennIntersection[];\n entityId?: string;\n entityName?: string;\n}\n\n/**\n * Set operation types\n */\nexport type SetOperation = 'union' | 'intersection' | 'difference' | 'symmetric_difference' | 'complement';\n\n/**\n * Result of a set operation\n */\nexport interface SetOperationResult {\n operation: SetOperation;\n inputSetIds: string[];\n resultRecordIds: string[];\n resultCount: number;\n}\n\n// Predefined color palette for Venn sets\nconst VENN_COLORS = [\n '#2196F3', // Blue\n '#4CAF50', // Green\n '#FF9800', // Orange\n '#E91E63', // Pink\n '#9C27B0', // Purple\n '#00BCD4', // Cyan\n '#F44336', // Red\n '#8BC34A' // Light Green\n];\n\n/**\n * Service for performing set operations on lists and preparing data for Venn visualization.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class ListSetOperationsService {\n private _provider: IMetadataProvider | null = null;\n /** Set the metadata provider this service should use. Components should call this after injection. */\n public set Provider(value: IMetadataProvider | null) {\n this._provider = value;\n }\n public get Provider(): IMetadataProvider {\n return this._provider ?? Metadata.Provider;\n }\n private loadingSubject = new BehaviorSubject<boolean>(false);\n public loading$: Observable<boolean> = this.loadingSubject.asObservable();\n\n // Cache for list details\n private listDetailsCache = new Map<string, Set<string>>();\n\n constructor() {}\n\n /**\n * Load list data and calculate all intersections for Venn visualization\n */\n async calculateVennData(lists: MJListEntity[]): Promise<VennData> {\n if (lists.length === 0) {\n return { sets: [], intersections: [] };\n }\n\n this.loadingSubject.next(true);\n\n try {\n // Load all list details in a single query\n const listIds = lists.map(l => l.ID);\n const listIdFilter = listIds.map(id => `'${id}'`).join(',');\n\n const rv = RunView.FromMetadataProvider(this.Provider);\n const result = await rv.RunView<{ ListID: string; RecordID: string }>({\n EntityName: 'MJ: List Details',\n ExtraFilter: `ListID IN (${listIdFilter})`,\n Fields: ['ListID', 'RecordID'],\n ResultType: 'simple'\n });\n\n // Build sets per list\n const setsMap = new Map<string, Set<string>>();\n for (const listId of listIds) {\n setsMap.set(listId, new Set());\n }\n\n if (result.Success && result.Results) {\n for (const detail of result.Results) {\n const set = setsMap.get(detail.ListID);\n if (set) {\n set.add(detail.RecordID);\n }\n }\n }\n\n // Update cache\n for (const [listId, records] of setsMap) {\n this.listDetailsCache.set(listId, records);\n }\n\n // Build VennSet objects\n const sets: VennSet[] = lists.map((list, index) => ({\n listId: list.ID,\n listName: list.Name,\n color: VENN_COLORS[index % VENN_COLORS.length],\n recordIds: setsMap.get(list.ID) || new Set(),\n size: setsMap.get(list.ID)?.size || 0\n }));\n\n // Calculate all possible intersections\n const intersections = this.calculateAllIntersections(sets);\n\n // Get entity info from the first list (assuming all lists are same entity)\n const entityId = lists[0]?.EntityID;\n const entityName = lists[0]?.Entity;\n\n return { sets, intersections, entityId, entityName };\n } finally {\n this.loadingSubject.next(false);\n }\n }\n\n /**\n * Calculate all possible intersections between the given sets\n */\n private calculateAllIntersections(sets: VennSet[]): VennIntersection[] {\n const intersections: VennIntersection[] = [];\n const n = sets.length;\n\n // Generate all non-empty subsets of sets\n for (let mask = 1; mask < (1 << n); mask++) {\n const subset: VennSet[] = [];\n for (let i = 0; i < n; i++) {\n if (mask & (1 << i)) {\n subset.push(sets[i]);\n }\n }\n\n // Calculate exclusive intersection (records in exactly these sets)\n const recordIds = this.calculateExclusiveIntersection(subset, sets);\n\n if (recordIds.length > 0 || subset.length === 1) {\n const setIds = subset.map(s => s.listId);\n const setLabels = subset.map(s => s.listName);\n\n intersections.push({\n setIds,\n setLabels,\n size: recordIds.length,\n recordIds,\n label: this.buildIntersectionLabel(setLabels),\n isSelected: false\n });\n }\n }\n\n // Sort by number of sets (single sets first, then pairs, etc.)\n intersections.sort((a, b) => a.setIds.length - b.setIds.length);\n\n return intersections;\n }\n\n /**\n * Calculate records that are in ALL of the specified sets but NONE of the other sets\n */\n private calculateExclusiveIntersection(includedSets: VennSet[], allSets: VennSet[]): string[] {\n if (includedSets.length === 0) return [];\n\n // Start with records in the first included set\n let result = new Set(includedSets[0].recordIds);\n\n // Intersect with all other included sets\n for (let i = 1; i < includedSets.length; i++) {\n result = this.intersect(result, includedSets[i].recordIds);\n }\n\n // Remove records that are in excluded sets\n const excludedSets = allSets.filter(s => !includedSets.includes(s));\n for (const excluded of excludedSets) {\n result = this.difference(result, excluded.recordIds);\n }\n\n return Array.from(result);\n }\n\n /**\n * Build a display label for an intersection\n */\n private buildIntersectionLabel(setLabels: string[]): string {\n if (setLabels.length === 1) {\n return `Only in ${setLabels[0]}`;\n }\n return setLabels.join(' ∩ ');\n }\n\n /**\n * Perform a set operation on multiple lists\n */\n async performOperation(\n operation: SetOperation,\n listIds: string[],\n allListIds?: string[]\n ): Promise<SetOperationResult> {\n this.loadingSubject.next(true);\n\n try {\n // Ensure we have the list details loaded\n await this.ensureListsLoaded(listIds);\n\n const sets = listIds.map(id => this.listDetailsCache.get(id) || new Set<string>());\n let resultSet: Set<string>;\n\n switch (operation) {\n case 'union':\n resultSet = this.unionAll(sets);\n break;\n\n case 'intersection':\n resultSet = this.intersectAll(sets);\n break;\n\n case 'difference':\n // A - B - C - ... (first set minus all others)\n if (sets.length < 2) {\n resultSet = sets[0] || new Set();\n } else {\n resultSet = new Set(sets[0]);\n for (let i = 1; i < sets.length; i++) {\n resultSet = this.difference(resultSet, sets[i]);\n }\n }\n break;\n\n case 'symmetric_difference':\n // Records that are in exactly one of the sets\n resultSet = this.symmetricDifferenceAll(sets);\n break;\n\n case 'complement':\n // Records NOT in any of the selected sets (requires allListIds)\n if (allListIds) {\n await this.ensureListsLoaded(allListIds);\n const allSets = allListIds.map(id => this.listDetailsCache.get(id) || new Set<string>());\n const allRecords = this.unionAll(allSets);\n const selectedRecords = this.unionAll(sets);\n resultSet = this.difference(allRecords, selectedRecords);\n } else {\n resultSet = new Set();\n }\n break;\n\n default:\n resultSet = new Set();\n }\n\n return {\n operation,\n inputSetIds: listIds,\n resultRecordIds: Array.from(resultSet),\n resultCount: resultSet.size\n };\n } finally {\n this.loadingSubject.next(false);\n }\n }\n\n /**\n * Ensure list details are loaded for the given list IDs\n */\n private async ensureListsLoaded(listIds: string[]): Promise<void> {\n const missingIds = listIds.filter(id => !this.listDetailsCache.has(id));\n\n if (missingIds.length === 0) return;\n\n const listIdFilter = missingIds.map(id => `'${id}'`).join(',');\n const rv = RunView.FromMetadataProvider(this.Provider);\n\n const result = await rv.RunView<{ ListID: string; RecordID: string }>({\n EntityName: 'MJ: List Details',\n ExtraFilter: `ListID IN (${listIdFilter})`,\n Fields: ['ListID', 'RecordID'],\n ResultType: 'simple'\n });\n\n // Initialize sets for missing lists\n for (const id of missingIds) {\n this.listDetailsCache.set(id, new Set());\n }\n\n if (result.Success && result.Results) {\n for (const detail of result.Results) {\n const set = this.listDetailsCache.get(detail.ListID);\n if (set) {\n set.add(detail.RecordID);\n }\n }\n }\n }\n\n /**\n * Set intersection of two sets\n */\n private intersect(a: Set<string>, b: Set<string>): Set<string> {\n const result = new Set<string>();\n for (const item of a) {\n if (b.has(item)) {\n result.add(item);\n }\n }\n return result;\n }\n\n /**\n * Set difference (a - b)\n */\n private difference(a: Set<string>, b: Set<string>): Set<string> {\n const result = new Set<string>();\n for (const item of a) {\n if (!b.has(item)) {\n result.add(item);\n }\n }\n return result;\n }\n\n /**\n * Union of multiple sets\n */\n private unionAll(sets: Set<string>[]): Set<string> {\n const result = new Set<string>();\n for (const set of sets) {\n for (const item of set) {\n result.add(item);\n }\n }\n return result;\n }\n\n /**\n * Intersection of multiple sets\n */\n private intersectAll(sets: Set<string>[]): Set<string> {\n if (sets.length === 0) return new Set();\n if (sets.length === 1) return new Set(sets[0]);\n\n let result = new Set(sets[0]);\n for (let i = 1; i < sets.length; i++) {\n result = this.intersect(result, sets[i]);\n }\n return result;\n }\n\n /**\n * Symmetric difference of multiple sets (items in exactly one set)\n */\n private symmetricDifferenceAll(sets: Set<string>[]): Set<string> {\n if (sets.length === 0) return new Set();\n\n // Count occurrences of each item\n const counts = new Map<string, number>();\n for (const set of sets) {\n for (const item of set) {\n counts.set(item, (counts.get(item) || 0) + 1);\n }\n }\n\n // Keep only items that appear exactly once\n const result = new Set<string>();\n for (const [item, count] of counts) {\n if (count === 1) {\n result.add(item);\n }\n }\n return result;\n }\n\n /**\n * Get the color for a list by its index\n */\n getColorForIndex(index: number): string {\n return VENN_COLORS[index % VENN_COLORS.length];\n }\n\n /**\n * Clear the cache\n */\n clearCache(): void {\n this.listDetailsCache.clear();\n }\n}\n"]}
1
+ {"version":3,"file":"list-set-operations.service.js","sourceRoot":"","sources":["../../../src/Lists/services/list-set-operations.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { RunView, Metadata, IMetadataProvider, CompositeKey, EntityInfo } from '@memberjunction/core';\nimport { MJListEntity, MJListDetailEntity, MJUserViewEntity } from '@memberjunction/core-entities';\nimport { NormalizeUUID } from '@memberjunction/global';\nimport { BehaviorSubject, Observable } from 'rxjs';\n\n/**\n * Normalize an `MJ: List Details.RecordID`-style string so set operations\n * compare correctly regardless of where the value originated.\n *\n * The wrinkle: SQL Server returns UUIDs uppercased, PostgreSQL returns\n * them lowercased — and the same DB can host List Details written by\n * different code paths with different casing. Composite-PK keys are\n * concatenated strings (`Field1|Value1||Field2|Value2`); normalizing\n * the whole string is safe — `NormalizeUUID` lowercases anything that\n * pattern-matches a UUID and is a no-op on other content. The pipe\n * separators in composite keys are unaffected.\n */\nfunction normalizeRecordId(raw: string | null | undefined): string {\n if (raw == null) return '';\n return NormalizeUUID(String(raw));\n}\n\n/**\n * Describes one operand for the Venn / set-op pipeline. The component\n * passes these in instead of raw `MJListEntity`s now that views are\n * supported; the service handles cache-keying + record-ID resolution.\n */\nexport interface SetOperand {\n kind: OperandKind;\n /** ID of the underlying MJ List or MJ User View. */\n id: string;\n /** Display name shown in the Venn legend + selection chips. */\n name: string;\n /** Entity ID — used to enforce the same-entity invariant on operations. */\n entityID: string;\n /** Entity name — denormalized for display. */\n entityName: string;\n /** Hex color from the predefined palette; chosen by the component. */\n color: string;\n}\n\n/**\n * Discriminates a Venn set / set-op operand between a saved MJ List and a\n * User View. The Venn diagram uses this to render views with a dashed\n * stroke (per mockup 10) so users can tell at a glance which inputs are\n * static (lists) vs. dynamic-at-resolution (views).\n */\nexport type OperandKind = 'list' | 'view';\n\n/**\n * Stable key for an operand across cache lookups + state persistence.\n * `list:<id>` and `view:<id>` deliberately namespace the ID so a view and\n * a list with the same UUID (extremely unlikely but possible) can't\n * collide in the cache.\n */\nexport function OperandCacheKey(kind: OperandKind, id: string): string {\n return `${kind}:${id}`;\n}\n\n/**\n * Represents a set (list or view) in the Venn diagram\n */\nexport interface VennSet {\n /** Stable cache key. Use `OperandCacheKey()` to construct. */\n operandKey: string;\n /** Discriminator — drives the dashed-vs-solid stroke in the Venn diagram. */\n kind: OperandKind;\n /** Underlying list / view ID. Same UUID space as the entity it points at. */\n listId: string;\n listName: string;\n color: string;\n recordIds: Set<string>;\n size: number;\n}\n\n/**\n * Represents an intersection region in the Venn diagram\n */\nexport interface VennIntersection {\n /**\n * IDs of lists that participate in this intersection\n */\n setIds: string[];\n\n /**\n * Labels of lists that participate in this intersection\n */\n setLabels: string[];\n\n /**\n * Number of records in this intersection\n */\n size: number;\n\n /**\n * Actual record IDs in this intersection\n */\n recordIds: string[];\n\n /**\n * Display label for this region\n */\n label: string;\n\n /**\n * Whether this region is currently selected\n */\n isSelected: boolean;\n}\n\n/**\n * Complete Venn data for visualization\n */\nexport interface VennData {\n sets: VennSet[];\n intersections: VennIntersection[];\n entityId?: string;\n entityName?: string;\n}\n\n/**\n * Set operation types\n */\nexport type SetOperation = 'union' | 'intersection' | 'difference' | 'symmetric_difference' | 'complement';\n\n/**\n * Result of a set operation\n */\nexport interface SetOperationResult {\n operation: SetOperation;\n inputSetIds: string[];\n resultRecordIds: string[];\n resultCount: number;\n}\n\n// Predefined color palette for Venn sets\nconst VENN_COLORS = [\n '#2196F3', // Blue\n '#4CAF50', // Green\n '#FF9800', // Orange\n '#E91E63', // Pink\n '#9C27B0', // Purple\n '#00BCD4', // Cyan\n '#F44336', // Red\n '#8BC34A' // Light Green\n];\n\n/**\n * Service for performing set operations on lists and preparing data for Venn visualization.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class ListSetOperationsService {\n private _provider: IMetadataProvider | null = null;\n /** Set the metadata provider this service should use. Components should call this after injection. */\n public set Provider(value: IMetadataProvider | null) {\n this._provider = value;\n }\n public get Provider(): IMetadataProvider {\n return this._provider ?? Metadata.Provider;\n }\n private loadingSubject = new BehaviorSubject<boolean>(false);\n public loading$: Observable<boolean> = this.loadingSubject.asObservable();\n\n // Cache for list details\n private listDetailsCache = new Map<string, Set<string>>();\n\n constructor() {}\n\n /**\n * Load list data and calculate all intersections for Venn visualization\n */\n async calculateVennData(lists: MJListEntity[]): Promise<VennData> {\n if (lists.length === 0) {\n return { sets: [], intersections: [] };\n }\n\n this.loadingSubject.next(true);\n\n try {\n // Load all list details in a single query\n const listIds = lists.map(l => l.ID);\n const listIdFilter = listIds.map(id => `'${id}'`).join(',');\n\n const rv = RunView.FromMetadataProvider(this.Provider);\n const result = await rv.RunView<{ ListID: string; RecordID: string }>({\n EntityName: 'MJ: List Details',\n ExtraFilter: `ListID IN (${listIdFilter})`,\n Fields: ['ListID', 'RecordID'],\n ResultType: 'simple'\n });\n\n // Build sets per list\n const setsMap = new Map<string, Set<string>>();\n for (const listId of listIds) {\n setsMap.set(listId, new Set());\n }\n\n if (result.Success && result.Results) {\n for (const detail of result.Results) {\n const set = setsMap.get(detail.ListID);\n if (set) {\n set.add(detail.RecordID);\n }\n }\n }\n\n // Update cache — namespaced under `list:` so view operands can share\n // the same cache map without collision.\n for (const [listId, records] of setsMap) {\n this.listDetailsCache.set(OperandCacheKey('list', listId), records);\n }\n\n // Build VennSet objects. We keep the legacy `MJListEntity` overload's\n // shape but populate the new discriminator fields so the diagram +\n // downstream operations stay consistent regardless of which entry\n // point was used.\n const sets: VennSet[] = lists.map((list, index) => ({\n operandKey: OperandCacheKey('list', list.ID),\n kind: 'list' as const,\n listId: list.ID,\n listName: list.Name,\n color: VENN_COLORS[index % VENN_COLORS.length],\n recordIds: setsMap.get(list.ID) || new Set(),\n size: setsMap.get(list.ID)?.size || 0\n }));\n\n // Calculate all possible intersections\n const intersections = this.calculateAllIntersections(sets);\n\n // Get entity info from the first list (assuming all lists are same entity)\n const entityId = lists[0]?.EntityID;\n const entityName = lists[0]?.Entity;\n\n return { sets, intersections, entityId, entityName };\n } finally {\n this.loadingSubject.next(false);\n }\n }\n\n /**\n * Generalized Venn-data loader supporting both lists and views.\n *\n * - Lists resolve via the same `MJ: List Details` query as the legacy\n * path (cached by `list:<id>`).\n * - Views resolve via `RunView({ViewID})` and primary-key serialization;\n * cached by `view:<id>` so picking the same view twice doesn't\n * re-query.\n *\n * The cache deliberately namespaces the kind — a list and a view that\n * shared the same UUID would still hit distinct entries.\n */\n async calculateVennDataForOperands(operands: SetOperand[]): Promise<VennData> {\n if (operands.length === 0) return { sets: [], intersections: [] };\n this.loadingSubject.next(true);\n try {\n await this.ensureOperandsLoaded(operands);\n\n const sets: VennSet[] = operands.map((op) => ({\n operandKey: OperandCacheKey(op.kind, op.id),\n kind: op.kind,\n listId: op.id,\n listName: op.name,\n color: op.color,\n recordIds: this.cacheGet(op) ?? new Set<string>(),\n size: this.cacheGet(op)?.size ?? 0,\n }));\n\n const intersections = this.calculateAllIntersections(sets);\n const entityId = operands[0]?.entityID;\n const entityName = operands[0]?.entityName;\n return { sets, intersections, entityId, entityName };\n } finally {\n this.loadingSubject.next(false);\n }\n }\n\n /**\n * Operand-aware sibling of `performOperation`. `operandKeys` are the\n * `OperandCacheKey()` strings produced by `calculateVennDataForOperands`,\n * so callers can stay in operand-key space end-to-end.\n */\n async performOperationForOperands(\n operation: SetOperation,\n operands: SetOperand[],\n allOperands?: SetOperand[],\n ): Promise<SetOperationResult> {\n this.loadingSubject.next(true);\n try {\n await this.ensureOperandsLoaded([...operands, ...(allOperands ?? [])]);\n const sets = operands.map((op) => this.cacheGet(op) ?? new Set<string>());\n const resultSet = this.computeOperationResult(operation, sets, allOperands);\n return {\n operation,\n inputSetIds: operands.map((op) => OperandCacheKey(op.kind, op.id)),\n resultRecordIds: Array.from(resultSet),\n resultCount: resultSet.size,\n };\n } finally {\n this.loadingSubject.next(false);\n }\n }\n\n /**\n * Calculate all possible intersections between the given sets\n */\n private calculateAllIntersections(sets: VennSet[]): VennIntersection[] {\n const intersections: VennIntersection[] = [];\n const n = sets.length;\n\n // Generate all non-empty subsets of sets\n for (let mask = 1; mask < (1 << n); mask++) {\n const subset: VennSet[] = [];\n for (let i = 0; i < n; i++) {\n if (mask & (1 << i)) {\n subset.push(sets[i]);\n }\n }\n\n // Calculate exclusive intersection (records in exactly these sets)\n const recordIds = this.calculateExclusiveIntersection(subset, sets);\n\n if (recordIds.length > 0 || subset.length === 1) {\n const setIds = subset.map(s => s.listId);\n const setLabels = subset.map(s => s.listName);\n\n intersections.push({\n setIds,\n setLabels,\n size: recordIds.length,\n recordIds,\n label: this.buildIntersectionLabel(setLabels),\n isSelected: false\n });\n }\n }\n\n // Sort by number of sets (single sets first, then pairs, etc.)\n intersections.sort((a, b) => a.setIds.length - b.setIds.length);\n\n return intersections;\n }\n\n /**\n * Calculate records that are in ALL of the specified sets but NONE of the other sets\n */\n private calculateExclusiveIntersection(includedSets: VennSet[], allSets: VennSet[]): string[] {\n if (includedSets.length === 0) return [];\n\n // Start with records in the first included set\n let result = new Set(includedSets[0].recordIds);\n\n // Intersect with all other included sets\n for (let i = 1; i < includedSets.length; i++) {\n result = this.intersect(result, includedSets[i].recordIds);\n }\n\n // Remove records that are in excluded sets\n const excludedSets = allSets.filter(s => !includedSets.includes(s));\n for (const excluded of excludedSets) {\n result = this.difference(result, excluded.recordIds);\n }\n\n return Array.from(result);\n }\n\n /**\n * Build a display label for an intersection\n */\n private buildIntersectionLabel(setLabels: string[]): string {\n if (setLabels.length === 1) {\n return `Only in ${setLabels[0]}`;\n }\n return setLabels.join(' ∩ ');\n }\n\n /**\n * Perform a set operation on multiple lists\n */\n async performOperation(\n operation: SetOperation,\n listIds: string[],\n allListIds?: string[]\n ): Promise<SetOperationResult> {\n this.loadingSubject.next(true);\n\n try {\n // Ensure we have the list details loaded\n await this.ensureListsLoaded(listIds);\n\n const sets = listIds.map(id => this.listDetailsCache.get(OperandCacheKey('list', id)) || new Set<string>());\n let resultSet: Set<string>;\n\n switch (operation) {\n case 'union':\n resultSet = this.unionAll(sets);\n break;\n\n case 'intersection':\n resultSet = this.intersectAll(sets);\n break;\n\n case 'difference':\n // A - B - C - ... (first set minus all others)\n if (sets.length < 2) {\n resultSet = sets[0] || new Set();\n } else {\n resultSet = new Set(sets[0]);\n for (let i = 1; i < sets.length; i++) {\n resultSet = this.difference(resultSet, sets[i]);\n }\n }\n break;\n\n case 'symmetric_difference':\n // Records that are in exactly one of the sets\n resultSet = this.symmetricDifferenceAll(sets);\n break;\n\n case 'complement':\n // Records NOT in any of the selected sets (requires allListIds)\n if (allListIds) {\n await this.ensureListsLoaded(allListIds);\n const allSets = allListIds.map(id => this.listDetailsCache.get(OperandCacheKey('list', id)) || new Set<string>());\n const allRecords = this.unionAll(allSets);\n const selectedRecords = this.unionAll(sets);\n resultSet = this.difference(allRecords, selectedRecords);\n } else {\n resultSet = new Set();\n }\n break;\n\n default:\n resultSet = new Set();\n }\n\n return {\n operation,\n inputSetIds: listIds,\n resultRecordIds: Array.from(resultSet),\n resultCount: resultSet.size\n };\n } finally {\n this.loadingSubject.next(false);\n }\n }\n\n /**\n * Cached lookup keyed by operand kind+id. Lists and views share the\n * cache map but their entries can't collide thanks to the key namespace.\n */\n private cacheGet(operand: SetOperand): Set<string> | undefined {\n return this.listDetailsCache.get(OperandCacheKey(operand.kind, operand.id));\n }\n\n /**\n * Bulk-load any operands not already cached. Lists batch through a\n * single `MJ: List Details` query (same shape as before); views resolve\n * one at a time because each is a separate parameterized RunView. Both\n * paths populate the same cache map.\n */\n private async ensureOperandsLoaded(operands: SetOperand[]): Promise<void> {\n const missingLists: string[] = [];\n const missingViews: SetOperand[] = [];\n for (const op of operands) {\n if (this.cacheGet(op)) continue;\n if (op.kind === 'list') missingLists.push(op.id);\n else missingViews.push(op);\n }\n await Promise.all([\n missingLists.length > 0 ? this.loadMissingLists(missingLists) : Promise.resolve(),\n missingViews.length > 0 ? this.loadMissingViews(missingViews) : Promise.resolve(),\n ]);\n }\n\n private async loadMissingLists(listIds: string[]): Promise<void> {\n const listIdFilter = listIds.map((id) => `'${id}'`).join(',');\n const rv = RunView.FromMetadataProvider(this.Provider);\n const result = await rv.RunView<{ ListID: string; RecordID: string }>({\n EntityName: 'MJ: List Details',\n ExtraFilter: `ListID IN (${listIdFilter})`,\n Fields: ['ListID', 'RecordID'],\n ResultType: 'simple',\n });\n\n for (const id of listIds) {\n this.listDetailsCache.set(OperandCacheKey('list', id), new Set<string>());\n }\n if (result.Success && result.Results) {\n for (const detail of result.Results) {\n // Normalize on the ListID we look up by AND on the RecordID we\n // store — mixed casing on either side would otherwise produce\n // empty intersections between lists that actually share records.\n const set = this.listDetailsCache.get(OperandCacheKey('list', NormalizeUUID(detail.ListID)))\n ?? this.listDetailsCache.get(OperandCacheKey('list', detail.ListID));\n if (set) set.add(normalizeRecordId(detail.RecordID));\n }\n }\n }\n\n private async loadMissingViews(operands: SetOperand[]): Promise<void> {\n // Fire view queries in parallel — each one is small and independent.\n const tasks = operands.map((op) => this.loadSingleView(op));\n await Promise.all(tasks);\n }\n\n /**\n * Resolve a view to a set of record IDs in the canonical `MJ: List\n * Details.RecordID` format (single-PK → raw value; composite-PK →\n * `Field1|Value1||Field2|Value2`, matching `CompositeKey.ToConcatenatedString`).\n * This keeps view operands cache-compatible with list operands without\n * any transformation in the set-op logic.\n */\n private async loadSingleView(operand: SetOperand): Promise<void> {\n const md = this.Provider;\n const entityInfo = md.EntityByName(operand.entityName);\n if (!entityInfo) {\n this.listDetailsCache.set(OperandCacheKey('view', operand.id), new Set<string>());\n return;\n }\n const pkFields = entityInfo.PrimaryKeys.map((pk) => pk.Name);\n\n const rv = RunView.FromMetadataProvider(md);\n const result = await rv.RunView({\n ViewID: operand.id,\n Fields: pkFields,\n ResultType: 'simple',\n });\n\n const set = new Set<string>();\n if (result.Success && result.Results) {\n for (const row of result.Results) {\n set.add(this.serializeRecordId(entityInfo, row as Record<string, unknown>));\n }\n }\n this.listDetailsCache.set(OperandCacheKey('view', operand.id), set);\n }\n\n /**\n * Mirror of `ListOperations.serializeRecordId` so view operands produce\n * IDs that round-trip cleanly against MJ List Details.\n */\n private serializeRecordId(entityInfo: EntityInfo, row: Record<string, unknown>): string {\n if (entityInfo.PrimaryKeys.length === 1) {\n return normalizeRecordId(String(row[entityInfo.PrimaryKeys[0].Name]));\n }\n const ck = new CompositeKey();\n ck.KeyValuePairs = entityInfo.PrimaryKeys.map((pk) => ({\n FieldName: pk.Name,\n Value: row[pk.Name] as string | number | Date | null | undefined,\n }));\n return normalizeRecordId(ck.ToConcatenatedString());\n }\n\n /**\n * Pure compute step shared by the legacy and operand-aware paths.\n * Operates on raw `Set<string>` inputs so it stays agnostic to where\n * those sets came from.\n */\n private computeOperationResult(\n operation: SetOperation,\n sets: Set<string>[],\n allOperandsForComplement?: SetOperand[],\n ): Set<string> {\n switch (operation) {\n case 'union':\n return this.unionAll(sets);\n case 'intersection':\n return this.intersectAll(sets);\n case 'difference': {\n if (sets.length < 2) return sets[0] ?? new Set<string>();\n let r = new Set(sets[0]);\n for (let i = 1; i < sets.length; i++) r = this.difference(r, sets[i]);\n return r;\n }\n case 'symmetric_difference':\n return this.symmetricDifferenceAll(sets);\n case 'complement': {\n if (!allOperandsForComplement) return new Set<string>();\n const allSets = allOperandsForComplement.map((op) => this.cacheGet(op) ?? new Set<string>());\n return this.difference(this.unionAll(allSets), this.unionAll(sets));\n }\n default:\n return new Set<string>();\n }\n }\n\n /**\n * Ensure list details are loaded for the given list IDs. Cache keys use\n * the `list:<id>` namespace introduced for operand support; the legacy\n * list-only callers go through here without needing to know the format.\n */\n private async ensureListsLoaded(listIds: string[]): Promise<void> {\n const missingIds = listIds.filter(id => !this.listDetailsCache.has(OperandCacheKey('list', id)));\n\n if (missingIds.length === 0) return;\n\n const listIdFilter = missingIds.map(id => `'${id}'`).join(',');\n const rv = RunView.FromMetadataProvider(this.Provider);\n\n const result = await rv.RunView<{ ListID: string; RecordID: string }>({\n EntityName: 'MJ: List Details',\n ExtraFilter: `ListID IN (${listIdFilter})`,\n Fields: ['ListID', 'RecordID'],\n ResultType: 'simple'\n });\n\n // Initialize sets for missing lists\n for (const id of missingIds) {\n this.listDetailsCache.set(OperandCacheKey('list', id), new Set());\n }\n\n if (result.Success && result.Results) {\n for (const detail of result.Results) {\n const set = this.listDetailsCache.get(OperandCacheKey('list', detail.ListID));\n if (set) {\n set.add(detail.RecordID);\n }\n }\n }\n }\n\n /**\n * Set intersection of two sets\n */\n private intersect(a: Set<string>, b: Set<string>): Set<string> {\n const result = new Set<string>();\n for (const item of a) {\n if (b.has(item)) {\n result.add(item);\n }\n }\n return result;\n }\n\n /**\n * Set difference (a - b)\n */\n private difference(a: Set<string>, b: Set<string>): Set<string> {\n const result = new Set<string>();\n for (const item of a) {\n if (!b.has(item)) {\n result.add(item);\n }\n }\n return result;\n }\n\n /**\n * Union of multiple sets\n */\n private unionAll(sets: Set<string>[]): Set<string> {\n const result = new Set<string>();\n for (const set of sets) {\n for (const item of set) {\n result.add(item);\n }\n }\n return result;\n }\n\n /**\n * Intersection of multiple sets\n */\n private intersectAll(sets: Set<string>[]): Set<string> {\n if (sets.length === 0) return new Set();\n if (sets.length === 1) return new Set(sets[0]);\n\n let result = new Set(sets[0]);\n for (let i = 1; i < sets.length; i++) {\n result = this.intersect(result, sets[i]);\n }\n return result;\n }\n\n /**\n * Symmetric difference of multiple sets (items in exactly one set)\n */\n private symmetricDifferenceAll(sets: Set<string>[]): Set<string> {\n if (sets.length === 0) return new Set();\n\n // Count occurrences of each item\n const counts = new Map<string, number>();\n for (const set of sets) {\n for (const item of set) {\n counts.set(item, (counts.get(item) || 0) + 1);\n }\n }\n\n // Keep only items that appear exactly once\n const result = new Set<string>();\n for (const [item, count] of counts) {\n if (count === 1) {\n result.add(item);\n }\n }\n return result;\n }\n\n /**\n * Get the color for a list by its index\n */\n getColorForIndex(index: number): string {\n return VENN_COLORS[index % VENN_COLORS.length];\n }\n\n /**\n * Clear the cache\n */\n clearCache(): void {\n this.listDetailsCache.clear();\n }\n}\n"]}
@@ -363,6 +363,26 @@ export declare class MCPDashboardComponent extends BaseDashboard implements OnIn
363
363
  count: number;
364
364
  }>;
365
365
  resetAllFilters(): void;
366
+ /** Reset only the popover filters — leave searchTerm (toolbar) untouched. */
367
+ resetPopoverFilters(): void;
368
+ /** Tools-tab view-mode options for the shared <mj-view-toggle>. */
369
+ readonly toolsViewOptions: {
370
+ key: string;
371
+ icon: string;
372
+ title: string;
373
+ }[];
374
+ /** Tab config consumed by the centralized <mj-tab-nav>. */
375
+ get mcpTabs(): import('@memberjunction/ng-ui-components').TabConfig[];
376
+ /** Active filter count excluding searchTerm (surfaced separately via toolbar mj-page-search). */
377
+ get ActiveFilterCount(): number;
378
+ /** Values record consumed by the centralized <mj-filter-panel>, scoped to the current tab. */
379
+ get mcpFilterValues(): Record<string, unknown>;
380
+ /** Field config built dynamically based on the active tab. */
381
+ get mcpFilterFields(): import('@memberjunction/ng-ui-components').FilterFieldConfig[];
382
+ /** Receive updated values from <mj-filter-panel> and propagate to filters$. */
383
+ onFilterValuesChange(values: Record<string, unknown>): void;
384
+ /** Update searchTerm from the toolbar mj-page-search. */
385
+ onSearchTermChange(value: string): void;
366
386
  /**
367
387
  * Get the current filtered count based on active tab
368
388
  */