@memberjunction/ng-dashboards 5.38.0 → 5.40.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 (321) hide show
  1. package/README.md +14 -7
  2. package/dist/AI/components/agents/agent-configuration.component.js +199 -198
  3. package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
  4. package/dist/AI/components/analytics/ai-analytics-resource.component.d.ts.map +1 -1
  5. package/dist/AI/components/analytics/ai-analytics-resource.component.js +20 -17
  6. package/dist/AI/components/analytics/ai-analytics-resource.component.js.map +1 -1
  7. package/dist/AI/components/analytics/cost-budget/cost-budget.component.d.ts +15 -0
  8. package/dist/AI/components/analytics/cost-budget/cost-budget.component.d.ts.map +1 -1
  9. package/dist/AI/components/analytics/cost-budget/cost-budget.component.js +166 -58
  10. package/dist/AI/components/analytics/cost-budget/cost-budget.component.js.map +1 -1
  11. package/dist/AI/components/analytics/executive-summary/executive-summary.component.d.ts.map +1 -1
  12. package/dist/AI/components/analytics/executive-summary/executive-summary.component.js +2 -1
  13. package/dist/AI/components/analytics/executive-summary/executive-summary.component.js.map +1 -1
  14. package/dist/AI/components/analytics/model-performance/model-performance.component.d.ts +1 -0
  15. package/dist/AI/components/analytics/model-performance/model-performance.component.d.ts.map +1 -1
  16. package/dist/AI/components/analytics/model-performance/model-performance.component.js +55 -36
  17. package/dist/AI/components/analytics/model-performance/model-performance.component.js.map +1 -1
  18. package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.d.ts +9 -1
  19. package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.d.ts.map +1 -1
  20. package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.js +158 -117
  21. package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.js.map +1 -1
  22. package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.d.ts +1 -0
  23. package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.d.ts.map +1 -1
  24. package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.js +22 -8
  25. package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.js.map +1 -1
  26. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +217 -860
  27. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
  28. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +1717 -7802
  29. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  30. package/dist/AI/components/autotagging/components/classify-item-drilldown.component.d.ts +56 -0
  31. package/dist/AI/components/autotagging/components/classify-item-drilldown.component.d.ts.map +1 -0
  32. package/dist/AI/components/autotagging/components/classify-item-drilldown.component.js +423 -0
  33. package/dist/AI/components/autotagging/components/classify-item-drilldown.component.js.map +1 -0
  34. package/dist/AI/components/autotagging/components/classify-item-grid.component.d.ts +70 -0
  35. package/dist/AI/components/autotagging/components/classify-item-grid.component.d.ts.map +1 -0
  36. package/dist/AI/components/autotagging/components/classify-item-grid.component.js +308 -0
  37. package/dist/AI/components/autotagging/components/classify-item-grid.component.js.map +1 -0
  38. package/dist/AI/components/autotagging/components/classify-org-context-editor.component.d.ts +29 -0
  39. package/dist/AI/components/autotagging/components/classify-org-context-editor.component.d.ts.map +1 -0
  40. package/dist/AI/components/autotagging/components/classify-org-context-editor.component.js +186 -0
  41. package/dist/AI/components/autotagging/components/classify-org-context-editor.component.js.map +1 -0
  42. package/dist/AI/components/autotagging/components/classify-overview-analytics.component.d.ts +69 -0
  43. package/dist/AI/components/autotagging/components/classify-overview-analytics.component.d.ts.map +1 -0
  44. package/dist/AI/components/autotagging/components/classify-overview-analytics.component.js +278 -0
  45. package/dist/AI/components/autotagging/components/classify-overview-analytics.component.js.map +1 -0
  46. package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.d.ts +73 -0
  47. package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.d.ts.map +1 -0
  48. package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.js +393 -0
  49. package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.js.map +1 -0
  50. package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.d.ts +122 -0
  51. package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.d.ts.map +1 -0
  52. package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.js +908 -0
  53. package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.js.map +1 -0
  54. package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.d.ts +87 -0
  55. package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.d.ts.map +1 -0
  56. package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.js +475 -0
  57. package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.js.map +1 -0
  58. package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.d.ts +29 -0
  59. package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.d.ts.map +1 -0
  60. package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.js +208 -0
  61. package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.js.map +1 -0
  62. package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.d.ts +21 -0
  63. package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.d.ts.map +1 -0
  64. package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.js +70 -0
  65. package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.js.map +1 -0
  66. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts +333 -0
  67. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts.map +1 -0
  68. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js +2125 -0
  69. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js.map +1 -0
  70. package/dist/AI/components/autotagging/shared/classify.dryrun.d.ts +61 -0
  71. package/dist/AI/components/autotagging/shared/classify.dryrun.d.ts.map +1 -0
  72. package/dist/AI/components/autotagging/shared/classify.dryrun.js +78 -0
  73. package/dist/AI/components/autotagging/shared/classify.dryrun.js.map +1 -0
  74. package/dist/AI/components/autotagging/shared/classify.format.d.ts +58 -0
  75. package/dist/AI/components/autotagging/shared/classify.format.d.ts.map +1 -0
  76. package/dist/AI/components/autotagging/shared/classify.format.js +260 -0
  77. package/dist/AI/components/autotagging/shared/classify.format.js.map +1 -0
  78. package/dist/AI/components/autotagging/shared/classify.types.d.ts +319 -0
  79. package/dist/AI/components/autotagging/shared/classify.types.d.ts.map +1 -0
  80. package/dist/AI/components/autotagging/shared/classify.types.js +6 -0
  81. package/dist/AI/components/autotagging/shared/classify.types.js.map +1 -0
  82. package/dist/AI/components/autotagging/tabs/health-tab.component.d.ts +103 -0
  83. package/dist/AI/components/autotagging/tabs/health-tab.component.d.ts.map +1 -0
  84. package/dist/AI/components/autotagging/tabs/health-tab.component.js +571 -0
  85. package/dist/AI/components/autotagging/tabs/health-tab.component.js.map +1 -0
  86. package/dist/AI/components/autotagging/tabs/history-tab.component.d.ts +77 -0
  87. package/dist/AI/components/autotagging/tabs/history-tab.component.d.ts.map +1 -0
  88. package/dist/AI/components/autotagging/tabs/history-tab.component.js +519 -0
  89. package/dist/AI/components/autotagging/tabs/history-tab.component.js.map +1 -0
  90. package/dist/AI/components/autotagging/tabs/inbox-tab.component.d.ts +107 -0
  91. package/dist/AI/components/autotagging/tabs/inbox-tab.component.d.ts.map +1 -0
  92. package/dist/AI/components/autotagging/tabs/inbox-tab.component.js +719 -0
  93. package/dist/AI/components/autotagging/tabs/inbox-tab.component.js.map +1 -0
  94. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.d.ts +131 -0
  95. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.d.ts.map +1 -0
  96. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.js +813 -0
  97. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.js.map +1 -0
  98. package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts +177 -0
  99. package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts.map +1 -0
  100. package/dist/AI/components/autotagging/tabs/sources-tab.component.js +1465 -0
  101. package/dist/AI/components/autotagging/tabs/sources-tab.component.js.map +1 -0
  102. package/dist/AI/components/autotagging/tabs/tags-tab.component.d.ts +78 -0
  103. package/dist/AI/components/autotagging/tabs/tags-tab.component.d.ts.map +1 -0
  104. package/dist/AI/components/autotagging/tabs/tags-tab.component.js +492 -0
  105. package/dist/AI/components/autotagging/tabs/tags-tab.component.js.map +1 -0
  106. package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.d.ts +397 -0
  107. package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.d.ts.map +1 -0
  108. package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.js +3490 -0
  109. package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.js.map +1 -0
  110. package/dist/AI/components/autotagging/tabs/types-tab.component.d.ts +56 -0
  111. package/dist/AI/components/autotagging/tabs/types-tab.component.d.ts.map +1 -0
  112. package/dist/AI/components/autotagging/tabs/types-tab.component.js +271 -0
  113. package/dist/AI/components/autotagging/tabs/types-tab.component.js.map +1 -0
  114. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +3 -0
  115. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
  116. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +306 -290
  117. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
  118. package/dist/AI/components/execution-monitoring.component.js +1 -1
  119. package/dist/AI/components/execution-monitoring.component.js.map +1 -1
  120. package/dist/AI/components/models/model-management.component.js +209 -208
  121. package/dist/AI/components/models/model-management.component.js.map +1 -1
  122. package/dist/AI/components/prompts/prompt-management.component.js +130 -128
  123. package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
  124. package/dist/AI/components/requests/agent-requests-resource.component.js +61 -61
  125. package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -1
  126. package/dist/AI/components/system/system-configuration.component.js +17 -17
  127. package/dist/AI/components/system/system-configuration.component.js.map +1 -1
  128. package/dist/AI/components/tags/tags-resource.component.d.ts +1 -0
  129. package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -1
  130. package/dist/AI/components/tags/tags-resource.component.js +578 -538
  131. package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
  132. package/dist/AI/components/vectors/vector-management-resource.component.d.ts +3 -0
  133. package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
  134. package/dist/AI/components/vectors/vector-management-resource.component.js +331 -303
  135. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
  136. package/dist/AI/services/ai-instrumentation.service.d.ts +5 -0
  137. package/dist/AI/services/ai-instrumentation.service.d.ts.map +1 -1
  138. package/dist/AI/services/ai-instrumentation.service.js +14 -2
  139. package/dist/AI/services/ai-instrumentation.service.js.map +1 -1
  140. package/dist/AI/services/cache-metrics.d.ts +50 -0
  141. package/dist/AI/services/cache-metrics.d.ts.map +1 -0
  142. package/dist/AI/services/cache-metrics.js +43 -0
  143. package/dist/AI/services/cache-metrics.js.map +1 -0
  144. package/dist/APIKeys/api-applications-panel.component.js +2 -2
  145. package/dist/APIKeys/api-key-create-dialog.component.js +2 -2
  146. package/dist/APIKeys/api-key-edit-panel.component.js +2 -2
  147. package/dist/APIKeys/api-keys-resource.component.js +132 -131
  148. package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
  149. package/dist/Actions/components/actions-overview.component.js +141 -141
  150. package/dist/Actions/components/actions-overview.component.js.map +1 -1
  151. package/dist/Actions/components/execution-monitoring.component.js +15 -15
  152. package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
  153. package/dist/Actions/components/explorer/action-explorer.component.d.ts +0 -5
  154. package/dist/Actions/components/explorer/action-explorer.component.d.ts.map +1 -1
  155. package/dist/Actions/components/explorer/action-explorer.component.js +139 -212
  156. package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
  157. package/dist/Admin/admin-data-schema.component.js +2 -2
  158. package/dist/Admin/admin-data-schema.component.js.map +1 -1
  159. package/dist/Admin/admin-dev-tools-resource.component.js +2 -2
  160. package/dist/Admin/admin-dev-tools-resource.component.js.map +1 -1
  161. package/dist/Admin/admin-identity-access.component.js +2 -2
  162. package/dist/Admin/admin-identity-access.component.js.map +1 -1
  163. package/dist/Admin/admin-monitoring.component.js +2 -2
  164. package/dist/Admin/admin-monitoring.component.js.map +1 -1
  165. package/dist/ApplicationRoles/application-roles-resource.component.js +54 -49
  166. package/dist/ApplicationRoles/application-roles-resource.component.js.map +1 -1
  167. package/dist/Communication/communication-logs-resource.component.d.ts +6 -0
  168. package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
  169. package/dist/Communication/communication-logs-resource.component.js +72 -50
  170. package/dist/Communication/communication-logs-resource.component.js.map +1 -1
  171. package/dist/Communication/communication-monitor-resource.component.js +103 -102
  172. package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
  173. package/dist/Communication/communication-providers-resource.component.js +52 -51
  174. package/dist/Communication/communication-providers-resource.component.js.map +1 -1
  175. package/dist/Communication/communication-runs-resource.component.js +39 -38
  176. package/dist/Communication/communication-runs-resource.component.js.map +1 -1
  177. package/dist/Communication/communication-templates-resource.component.d.ts +6 -0
  178. package/dist/Communication/communication-templates-resource.component.d.ts.map +1 -1
  179. package/dist/Communication/communication-templates-resource.component.js +92 -89
  180. package/dist/Communication/communication-templates-resource.component.js.map +1 -1
  181. package/dist/Credentials/components/credentials-audit-resource.component.js +136 -135
  182. package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
  183. package/dist/Credentials/components/credentials-categories-resource.component.js +155 -152
  184. package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
  185. package/dist/Credentials/components/credentials-list-resource.component.js +119 -118
  186. package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
  187. package/dist/Credentials/components/credentials-overview-resource.component.js +129 -128
  188. package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
  189. package/dist/Credentials/components/credentials-types-resource.component.js +107 -106
  190. package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
  191. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +31 -340
  192. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  193. package/dist/DataExplorer/data-explorer-dashboard.component.js +468 -1958
  194. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  195. package/dist/DataExplorer/data-explorer-resource.component.d.ts.map +1 -1
  196. package/dist/DataExplorer/data-explorer-resource.component.js +10 -0
  197. package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -1
  198. package/dist/DatabaseDesigner/components/database-designer-dashboard.component.js +1 -1
  199. package/dist/DatabaseDesigner/components/entity-list.component.js +115 -114
  200. package/dist/DatabaseDesigner/components/entity-list.component.js.map +1 -1
  201. package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts +5 -6
  202. package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts.map +1 -1
  203. package/dist/DatabaseDesigner/database-designer-dashboards.module.js +4 -5
  204. package/dist/DatabaseDesigner/database-designer-dashboards.module.js.map +1 -1
  205. package/dist/DevTools/app-state-inspector.component.js +18 -17
  206. package/dist/DevTools/app-state-inspector.component.js.map +1 -1
  207. package/dist/DevTools/class-registry.component.js +88 -85
  208. package/dist/DevTools/class-registry.component.js.map +1 -1
  209. package/dist/DevTools/event-monitor.component.js +155 -150
  210. package/dist/DevTools/event-monitor.component.js.map +1 -1
  211. package/dist/DevTools/graphql-console.component.js +245 -243
  212. package/dist/DevTools/graphql-console.component.js.map +1 -1
  213. package/dist/DevTools/layout-inspector.component.js +18 -17
  214. package/dist/DevTools/layout-inspector.component.js.map +1 -1
  215. package/dist/EntityAdmin/entity-admin-dashboard.component.js +20 -19
  216. package/dist/EntityAdmin/entity-admin-dashboard.component.js.map +1 -1
  217. package/dist/Home/home-dashboard.component.js +2 -2
  218. package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
  219. package/dist/Integration/components/activity/activity.component.js +236 -229
  220. package/dist/Integration/components/activity/activity.component.js.map +1 -1
  221. package/dist/Integration/components/connections/connections.component.js +390 -389
  222. package/dist/Integration/components/connections/connections.component.js.map +1 -1
  223. package/dist/Integration/components/overview/overview.component.js +2 -2
  224. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -1
  225. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +14 -11
  226. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -1
  227. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +27 -2
  228. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -1
  229. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +244 -119
  230. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -1
  231. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +293 -291
  232. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
  233. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +62 -61
  234. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -1
  235. package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.d.ts +65 -0
  236. package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.d.ts.map +1 -0
  237. package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.js +176 -0
  238. package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.js.map +1 -0
  239. package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.d.ts +81 -0
  240. package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.d.ts.map +1 -0
  241. package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.js +308 -0
  242. package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.js.map +1 -0
  243. package/dist/KnowledgeHub/components/visualize/visualize-resource.component.d.ts +85 -0
  244. package/dist/KnowledgeHub/components/visualize/visualize-resource.component.d.ts.map +1 -0
  245. package/dist/KnowledgeHub/components/visualize/visualize-resource.component.js +362 -0
  246. package/dist/KnowledgeHub/components/visualize/visualize-resource.component.js.map +1 -0
  247. package/dist/KnowledgeHub/index.d.ts +3 -0
  248. package/dist/KnowledgeHub/index.d.ts.map +1 -1
  249. package/dist/KnowledgeHub/index.js +3 -0
  250. package/dist/KnowledgeHub/index.js.map +1 -1
  251. package/dist/Lists/components/lists-browse-resource.component.d.ts +6 -2
  252. package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
  253. package/dist/Lists/components/lists-browse-resource.component.js +525 -566
  254. package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
  255. package/dist/Lists/components/lists-categories-resource.component.js +135 -134
  256. package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
  257. package/dist/Lists/components/lists-my-lists-resource.component.js +199 -198
  258. package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
  259. package/dist/MCP/components/mcp-server-dialog.component.js +2 -2
  260. package/dist/MCP/mcp-dashboard.component.js +443 -438
  261. package/dist/MCP/mcp-dashboard.component.js.map +1 -1
  262. package/dist/QueryBrowser/query-browser-resource.component.js +1 -1
  263. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  264. package/dist/Scheduling/components/scheduling-activity.component.d.ts.map +1 -1
  265. package/dist/Scheduling/components/scheduling-activity.component.js +146 -147
  266. package/dist/Scheduling/components/scheduling-activity.component.js.map +1 -1
  267. package/dist/Scheduling/components/scheduling-jobs.component.js +76 -75
  268. package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
  269. package/dist/Scheduling/components/scheduling-overview.component.js +97 -96
  270. package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
  271. package/dist/Scheduling/scheduling-dashboard.component.js +24 -22
  272. package/dist/Scheduling/scheduling-dashboard.component.js.map +1 -1
  273. package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts +2 -0
  274. package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts.map +1 -1
  275. package/dist/Scheduling/services/scheduling-instrumentation.service.js +1 -0
  276. package/dist/Scheduling/services/scheduling-instrumentation.service.js.map +1 -1
  277. package/dist/Testing/components/testing-dashboard-tab-resource.component.js +1 -1
  278. package/dist/Testing/components/testing-explorer.component.d.ts +14 -4
  279. package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
  280. package/dist/Testing/components/testing-explorer.component.js +436 -427
  281. package/dist/Testing/components/testing-explorer.component.js.map +1 -1
  282. package/dist/Testing/components/testing-runs-resource.component.js +1 -1
  283. package/dist/Testing/components/testing-runs.component.js +116 -115
  284. package/dist/Testing/components/testing-runs.component.js.map +1 -1
  285. package/dist/Testing/testing-dashboard.component.js +6 -7
  286. package/dist/Testing/testing-dashboard.component.js.map +1 -1
  287. package/dist/VersionHistory/components/labels-resource.component.js +173 -172
  288. package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
  289. package/dist/VersionHistory/components/restore-resource.component.d.ts +6 -0
  290. package/dist/VersionHistory/components/restore-resource.component.d.ts.map +1 -1
  291. package/dist/VersionHistory/components/restore-resource.component.js +116 -92
  292. package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
  293. package/dist/ai-dashboards.module.d.ts +57 -35
  294. package/dist/ai-dashboards.module.d.ts.map +1 -1
  295. package/dist/ai-dashboards.module.js +80 -1
  296. package/dist/ai-dashboards.module.js.map +1 -1
  297. package/dist/communication-dashboards.module.d.ts +1 -1
  298. package/dist/communication-dashboards.module.d.ts.map +1 -1
  299. package/dist/communication-dashboards.module.js +7 -1
  300. package/dist/communication-dashboards.module.js.map +1 -1
  301. package/dist/data-explorer-dashboards.module.d.ts +12 -14
  302. package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
  303. package/dist/data-explorer-dashboards.module.js +5 -14
  304. package/dist/data-explorer-dashboards.module.js.map +1 -1
  305. package/dist/public-api.d.ts +3 -0
  306. package/dist/public-api.d.ts.map +1 -1
  307. package/dist/public-api.js +3 -0
  308. package/dist/public-api.js.map +1 -1
  309. package/dist/testing-dashboards.module.d.ts +4 -5
  310. package/dist/testing-dashboards.module.d.ts.map +1 -1
  311. package/dist/testing-dashboards.module.js +7 -5
  312. package/dist/testing-dashboards.module.js.map +1 -1
  313. package/package.json +57 -54
  314. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.d.ts +0 -79
  315. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.d.ts.map +0 -1
  316. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +0 -195
  317. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js.map +0 -1
  318. package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts +0 -226
  319. package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts.map +0 -1
  320. package/dist/DataExplorer/components/view-selector/view-selector.component.js +0 -861
  321. package/dist/DataExplorer/components/view-selector/view-selector.component.js.map +0 -1
@@ -13,88 +13,88 @@ import * as i1 from "@memberjunction/ng-shared";
13
13
  import * as i2 from "@angular/common";
14
14
  import * as i3 from "@memberjunction/ng-shared-generic";
15
15
  import * as i4 from "@memberjunction/ng-ui-components";
16
- function CommunicationProvidersResourceComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
17
- i0.ɵɵelementStart(0, "div", 4);
18
- i0.ɵɵelement(1, "mj-loading", 6);
16
+ function CommunicationProvidersResourceComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
17
+ i0.ɵɵelementStart(0, "div", 5);
18
+ i0.ɵɵelement(1, "mj-loading", 7);
19
19
  i0.ɵɵelementEnd();
20
20
  } }
21
- function CommunicationProvidersResourceComponent_Conditional_8_For_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
22
- i0.ɵɵelementStart(0, "span", 18);
23
- i0.ɵɵelement(1, "i", 27);
21
+ function CommunicationProvidersResourceComponent_Conditional_9_For_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
22
+ i0.ɵɵelementStart(0, "span", 19);
23
+ i0.ɵɵelement(1, "i", 28);
24
24
  i0.ɵɵtext(2, " Scheduled ");
25
25
  i0.ɵɵelementEnd();
26
26
  } }
27
- function CommunicationProvidersResourceComponent_Conditional_8_For_2_Conditional_20_Template(rf, ctx) { if (rf & 1) {
28
- i0.ɵɵelementStart(0, "span", 18);
29
- i0.ɵɵelement(1, "i", 27);
27
+ function CommunicationProvidersResourceComponent_Conditional_9_For_2_Conditional_20_Template(rf, ctx) { if (rf & 1) {
28
+ i0.ɵɵelementStart(0, "span", 19);
29
+ i0.ɵɵelement(1, "i", 28);
30
30
  i0.ɵɵtext(2, " Drafts ");
31
31
  i0.ɵɵelementEnd();
32
32
  } }
33
- function CommunicationProvidersResourceComponent_Conditional_8_For_2_Conditional_21_Template(rf, ctx) { if (rf & 1) {
34
- i0.ɵɵelementStart(0, "span", 18);
35
- i0.ɵɵelement(1, "i", 27);
33
+ function CommunicationProvidersResourceComponent_Conditional_9_For_2_Conditional_21_Template(rf, ctx) { if (rf & 1) {
34
+ i0.ɵɵelementStart(0, "span", 19);
35
+ i0.ɵɵelement(1, "i", 28);
36
36
  i0.ɵɵtext(2, " Forward ");
37
37
  i0.ɵɵelementEnd();
38
38
  } }
39
- function CommunicationProvidersResourceComponent_Conditional_8_For_2_Conditional_22_Template(rf, ctx) { if (rf & 1) {
40
- i0.ɵɵelementStart(0, "span", 18);
41
- i0.ɵɵelement(1, "i", 27);
39
+ function CommunicationProvidersResourceComponent_Conditional_9_For_2_Conditional_22_Template(rf, ctx) { if (rf & 1) {
40
+ i0.ɵɵelementStart(0, "span", 19);
41
+ i0.ɵɵelement(1, "i", 28);
42
42
  i0.ɵɵtext(2, " Reply ");
43
43
  i0.ɵɵelementEnd();
44
44
  } }
45
- function CommunicationProvidersResourceComponent_Conditional_8_For_2_Template(rf, ctx) { if (rf & 1) {
45
+ function CommunicationProvidersResourceComponent_Conditional_9_For_2_Template(rf, ctx) { if (rf & 1) {
46
46
  const _r1 = i0.ɵɵgetCurrentView();
47
- i0.ɵɵelementStart(0, "div", 8)(1, "div", 9)(2, "div", 10);
47
+ i0.ɵɵelementStart(0, "div", 9)(1, "div", 10)(2, "div", 11);
48
48
  i0.ɵɵelement(3, "i");
49
49
  i0.ɵɵelementEnd();
50
- i0.ɵɵelementStart(4, "div", 11)(5, "div", 12);
50
+ i0.ɵɵelementStart(4, "div", 12)(5, "div", 13);
51
51
  i0.ɵɵtext(6);
52
52
  i0.ɵɵelementEnd();
53
- i0.ɵɵelementStart(7, "div", 13);
53
+ i0.ɵɵelementStart(7, "div", 14);
54
54
  i0.ɵɵtext(8);
55
55
  i0.ɵɵelementEnd()();
56
- i0.ɵɵelementStart(9, "span", 14);
56
+ i0.ɵɵelementStart(9, "span", 15);
57
57
  i0.ɵɵtext(10);
58
58
  i0.ɵɵelementEnd()();
59
- i0.ɵɵelementStart(11, "div", 15)(12, "div", 16)(13, "span", 17);
59
+ i0.ɵɵelementStart(11, "div", 16)(12, "div", 17)(13, "span", 18);
60
60
  i0.ɵɵelement(14, "i");
61
61
  i0.ɵɵtext(15, " Sending ");
62
62
  i0.ɵɵelementEnd();
63
- i0.ɵɵelementStart(16, "span", 17);
63
+ i0.ɵɵelementStart(16, "span", 18);
64
64
  i0.ɵɵelement(17, "i");
65
65
  i0.ɵɵtext(18, " Receiving ");
66
66
  i0.ɵɵelementEnd();
67
- i0.ɵɵconditionalCreate(19, CommunicationProvidersResourceComponent_Conditional_8_For_2_Conditional_19_Template, 3, 0, "span", 18);
68
- i0.ɵɵconditionalCreate(20, CommunicationProvidersResourceComponent_Conditional_8_For_2_Conditional_20_Template, 3, 0, "span", 18);
69
- i0.ɵɵconditionalCreate(21, CommunicationProvidersResourceComponent_Conditional_8_For_2_Conditional_21_Template, 3, 0, "span", 18);
70
- i0.ɵɵconditionalCreate(22, CommunicationProvidersResourceComponent_Conditional_8_For_2_Conditional_22_Template, 3, 0, "span", 18);
67
+ i0.ɵɵconditionalCreate(19, CommunicationProvidersResourceComponent_Conditional_9_For_2_Conditional_19_Template, 3, 0, "span", 19);
68
+ i0.ɵɵconditionalCreate(20, CommunicationProvidersResourceComponent_Conditional_9_For_2_Conditional_20_Template, 3, 0, "span", 19);
69
+ i0.ɵɵconditionalCreate(21, CommunicationProvidersResourceComponent_Conditional_9_For_2_Conditional_21_Template, 3, 0, "span", 19);
70
+ i0.ɵɵconditionalCreate(22, CommunicationProvidersResourceComponent_Conditional_9_For_2_Conditional_22_Template, 3, 0, "span", 19);
71
71
  i0.ɵɵelementEnd();
72
- i0.ɵɵelementStart(23, "div", 19)(24, "div", 20)(25, "div", 21);
72
+ i0.ɵɵelementStart(23, "div", 20)(24, "div", 21)(25, "div", 22);
73
73
  i0.ɵɵtext(26);
74
74
  i0.ɵɵelementEnd();
75
- i0.ɵɵelementStart(27, "div", 22);
75
+ i0.ɵɵelementStart(27, "div", 23);
76
76
  i0.ɵɵtext(28, "Sent (24h)");
77
77
  i0.ɵɵelementEnd()();
78
- i0.ɵɵelementStart(29, "div", 20)(30, "div", 21);
78
+ i0.ɵɵelementStart(29, "div", 21)(30, "div", 22);
79
79
  i0.ɵɵtext(31);
80
80
  i0.ɵɵelementEnd();
81
- i0.ɵɵelementStart(32, "div", 22);
81
+ i0.ɵɵelementStart(32, "div", 23);
82
82
  i0.ɵɵtext(33, "Success");
83
83
  i0.ɵɵelementEnd()();
84
- i0.ɵɵelementStart(34, "div", 20)(35, "div", 21);
84
+ i0.ɵɵelementStart(34, "div", 21)(35, "div", 22);
85
85
  i0.ɵɵtext(36);
86
86
  i0.ɵɵelementEnd();
87
- i0.ɵɵelementStart(37, "div", 22);
87
+ i0.ɵɵelementStart(37, "div", 23);
88
88
  i0.ɵɵtext(38, "Failed");
89
89
  i0.ɵɵelementEnd()()()();
90
- i0.ɵɵelementStart(39, "div", 23)(40, "button", 24);
91
- i0.ɵɵlistener("click", function CommunicationProvidersResourceComponent_Conditional_8_For_2_Template_button_click_40_listener() { const card_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.configureProvider(card_r2.Entity)); });
92
- i0.ɵɵelement(41, "i", 25);
90
+ i0.ɵɵelementStart(39, "div", 24)(40, "button", 25);
91
+ i0.ɵɵlistener("click", function CommunicationProvidersResourceComponent_Conditional_9_For_2_Template_button_click_40_listener() { const card_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.configureProvider(card_r2.Entity)); });
92
+ i0.ɵɵelement(41, "i", 26);
93
93
  i0.ɵɵtext(42, " Configure ");
94
94
  i0.ɵɵelementEnd();
95
- i0.ɵɵelementStart(43, "button", 24);
96
- i0.ɵɵlistener("click", function CommunicationProvidersResourceComponent_Conditional_8_For_2_Template_button_click_43_listener() { const card_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.viewProviderLogs(card_r2.Entity)); });
97
- i0.ɵɵelement(44, "i", 26);
95
+ i0.ɵɵelementStart(43, "button", 25);
96
+ i0.ɵɵlistener("click", function CommunicationProvidersResourceComponent_Conditional_9_For_2_Template_button_click_43_listener() { const card_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.viewProviderLogs(card_r2.Entity)); });
97
+ i0.ɵɵelement(44, "i", 27);
98
98
  i0.ɵɵtext(45, " Analytics ");
99
99
  i0.ɵɵelementEnd()()();
100
100
  } if (rf & 2) {
@@ -135,9 +135,9 @@ function CommunicationProvidersResourceComponent_Conditional_8_For_2_Template(rf
135
135
  i0.ɵɵadvance(5);
136
136
  i0.ɵɵtextInterpolate(card_r2.FailedCount);
137
137
  } }
138
- function CommunicationProvidersResourceComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
139
- i0.ɵɵelementStart(0, "div", 5);
140
- i0.ɵɵrepeaterCreate(1, CommunicationProvidersResourceComponent_Conditional_8_For_2_Template, 46, 28, "div", 7, i0.ɵɵrepeaterTrackByIdentity);
138
+ function CommunicationProvidersResourceComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
139
+ i0.ɵɵelementStart(0, "div", 6);
140
+ i0.ɵɵrepeaterCreate(1, CommunicationProvidersResourceComponent_Conditional_9_For_2_Template, 46, 28, "div", 8, i0.ɵɵrepeaterTrackByIdentity);
141
141
  i0.ɵɵelementEnd();
142
142
  } if (rf & 2) {
143
143
  const ctx_r2 = i0.ɵɵnextContext();
@@ -255,21 +255,22 @@ let CommunicationProvidersResourceComponent = class CommunicationProvidersResour
255
255
  return 'fa-solid fa-server';
256
256
  }
257
257
  static ɵfac = function CommunicationProvidersResourceComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CommunicationProvidersResourceComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i1.NavigationService)); };
258
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: CommunicationProvidersResourceComponent, selectors: [["mj-communication-providers-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 9, vars: 2, consts: [["Title", "Providers", "Icon", "fa-solid fa-server", "Subtitle", "Manage your messaging service integrations"], ["actions", ""], ["mjButton", "", "variant", "primary", "size", "sm", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "loading-state"], [1, "providers-grid"], ["text", "Loading providers..."], [1, "provider-card", 3, "disabled"], [1, "provider-card"], [1, "provider-card-header"], [1, "provider-card-logo", 3, "ngClass"], [1, "provider-card-title"], [1, "provider-card-name"], [1, "provider-card-desc"], [1, "provider-card-status", 3, "ngClass"], [1, "provider-card-body"], [1, "provider-capabilities"], [1, "capability-chip"], [1, "capability-chip", "supported"], [1, "provider-card-stats"], [1, "provider-stat"], [1, "provider-stat-value"], [1, "provider-stat-label"], [1, "provider-card-footer"], [3, "click"], [1, "fa-solid", "fa-gear"], [1, "fa-solid", "fa-chart-line"], [1, "fa-solid", "fa-check"]], template: function CommunicationProvidersResourceComponent_Template(rf, ctx) { if (rf & 1) {
258
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: CommunicationProvidersResourceComponent, selectors: [["mj-communication-providers-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 10, vars: 2, consts: [["Title", "Providers", "Icon", "fa-solid fa-server", "Subtitle", "Manage your messaging service integrations"], ["actions", ""], ["mjButton", "", "variant", "primary", "size", "sm", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "action-btn-label"], [1, "loading-state"], [1, "providers-grid"], ["text", "Loading providers..."], [1, "provider-card", 3, "disabled"], [1, "provider-card"], [1, "provider-card-header"], [1, "provider-card-logo", 3, "ngClass"], [1, "provider-card-title"], [1, "provider-card-name"], [1, "provider-card-desc"], [1, "provider-card-status", 3, "ngClass"], [1, "provider-card-body"], [1, "provider-capabilities"], [1, "capability-chip"], [1, "capability-chip", "supported"], [1, "provider-card-stats"], [1, "provider-stat"], [1, "provider-stat-value"], [1, "provider-stat-label"], [1, "provider-card-footer"], [3, "click"], [1, "fa-solid", "fa-gear"], [1, "fa-solid", "fa-chart-line"], [1, "fa-solid", "fa-check"]], template: function CommunicationProvidersResourceComponent_Template(rf, ctx) { if (rf & 1) {
259
259
  i0.ɵɵelementStart(0, "mj-page-layout")(1, "mj-page-header", 0)(2, "div", 1)(3, "button", 2);
260
260
  i0.ɵɵlistener("click", function CommunicationProvidersResourceComponent_Template_button_click_3_listener() { return ctx.addNewProvider(); });
261
261
  i0.ɵɵelement(4, "i", 3);
262
- i0.ɵɵtext(5, " Add Provider ");
263
- i0.ɵɵelementEnd()()();
264
- i0.ɵɵelementStart(6, "mj-page-body");
265
- i0.ɵɵconditionalCreate(7, CommunicationProvidersResourceComponent_Conditional_7_Template, 2, 0, "div", 4);
266
- i0.ɵɵconditionalCreate(8, CommunicationProvidersResourceComponent_Conditional_8_Template, 3, 0, "div", 5);
262
+ i0.ɵɵelementStart(5, "span", 4);
263
+ i0.ɵɵtext(6, "Add Provider");
264
+ i0.ɵɵelementEnd()()()();
265
+ i0.ɵɵelementStart(7, "mj-page-body");
266
+ i0.ɵɵconditionalCreate(8, CommunicationProvidersResourceComponent_Conditional_8_Template, 2, 0, "div", 5);
267
+ i0.ɵɵconditionalCreate(9, CommunicationProvidersResourceComponent_Conditional_9_Template, 3, 0, "div", 6);
267
268
  i0.ɵɵelementEnd()();
268
269
  } if (rf & 2) {
269
- i0.ɵɵadvance(7);
270
- i0.ɵɵconditional(ctx.isLoading ? 7 : -1);
270
+ i0.ɵɵadvance(8);
271
+ i0.ɵɵconditional(ctx.isLoading ? 8 : -1);
271
272
  i0.ɵɵadvance();
272
- i0.ɵɵconditional(!ctx.isLoading ? 8 : -1);
273
+ i0.ɵɵconditional(!ctx.isLoading ? 9 : -1);
273
274
  } }, dependencies: [i2.NgClass, i3.LoadingComponent, i4.MJButtonDirective, i4.MJPageHeaderComponent, i4.MJPageLayoutComponent, i4.MJPageBodyComponent], styles: [".loading-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 80px 0;\n }\n\n \n\n .providers-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));\n gap: 16px;\n }\n .provider-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n transition: all 0.15s ease;\n }\n .provider-card[_ngcontent-%COMP%]:hover {\n box-shadow: 0 2px 8px var(--mj-shadow-md);\n border-color: var(--mj-border-strong);\n }\n .provider-card.disabled[_ngcontent-%COMP%] { opacity: 0.65; }\n\n .provider-card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 20px 20px 16px;\n }\n .provider-card-logo[_ngcontent-%COMP%] {\n width: 48px; height: 48px;\n border-radius: 12px;\n display: flex; align-items: center; justify-content: center;\n font-size: 22px; flex-shrink: 0;\n background: var(--mj-bg-surface-sunken);\n }\n .provider-card-logo.sendgrid[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n .provider-card-logo.twilio[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n .provider-card-logo.gmail[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n .provider-card-logo.msgraph[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n\n .provider-card-title[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n .provider-card-name[_ngcontent-%COMP%] {\n font-size: 15px; font-weight: 700;\n color: var(--mj-text-primary);\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n .provider-card-desc[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n }\n .provider-card-status[_ngcontent-%COMP%] {\n font-size: 10px; font-weight: 700;\n text-transform: uppercase; letter-spacing: 0.5px;\n padding: 3px 10px; border-radius: 10px;\n flex-shrink: 0;\n }\n .provider-card-status.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n .provider-card-status.disabled[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n }\n\n .provider-card-body[_ngcontent-%COMP%] { padding: 0 20px 16px; }\n\n .provider-capabilities[_ngcontent-%COMP%] {\n display: flex; flex-wrap: wrap;\n gap: 6px; margin-bottom: 16px;\n }\n .capability-chip[_ngcontent-%COMP%] {\n display: inline-flex; align-items: center;\n gap: 4px; padding: 4px 10px;\n border-radius: 12px; font-size: 11px; font-weight: 500;\n }\n .capability-chip.supported[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n .capability-chip.unsupported[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n text-decoration: line-through;\n }\n\n .provider-card-stats[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 12px; padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n }\n .provider-stat[_ngcontent-%COMP%] { text-align: center; }\n .provider-stat-value[_ngcontent-%COMP%] {\n font-size: 16px; font-weight: 800;\n color: var(--mj-text-primary);\n }\n .provider-stat-label[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n text-transform: uppercase; letter-spacing: 0.3px;\n }\n\n .provider-card-footer[_ngcontent-%COMP%] {\n display: flex;\n border-top: 1px solid var(--mj-border-default);\n }\n .provider-card-footer[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n flex: 1; padding: 12px;\n border: none; background: transparent;\n font-size: 12px; font-weight: 600;\n color: var(--mj-brand-primary);\n cursor: pointer; transition: background 0.15s;\n font-family: inherit;\n display: flex; align-items: center;\n justify-content: center; gap: 6px;\n }\n .provider-card-footer[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n }\n .provider-card-footer[_ngcontent-%COMP%] button[_ngcontent-%COMP%] + button[_ngcontent-%COMP%] {\n border-left: 1px solid var(--mj-border-default);\n }"] });
274
275
  };
275
276
  CommunicationProvidersResourceComponent = __decorate([
@@ -286,7 +287,7 @@ export { CommunicationProvidersResourceComponent };
286
287
  Subtitle="Manage your messaging service integrations">
287
288
  <div actions>
288
289
  <button mjButton variant="primary" size="sm" (click)="addNewProvider()">
289
- <i class="fa-solid fa-plus"></i> Add Provider
290
+ <i class="fa-solid fa-plus"></i> <span class="action-btn-label">Add Provider</span>
290
291
  </button>
291
292
  </div>
292
293
  </mj-page-header>
@@ -1 +1 @@
1
- {"version":3,"file":"communication-providers-resource.component.js","sourceRoot":"","sources":["../../src/Communication/communication-providers-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { ResourceData, MJCommunicationProviderEntity, MJCommunicationLogEntity } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { Metadata, RunView, CompositeKey } from '@memberjunction/core';\n\ninterface ProviderCardData {\n Entity: MJCommunicationProviderEntity;\n SentCount: number;\n SuccessRate: number;\n FailedCount: number;\n IconClass: string;\n LogoClass: string;\n}\n@RegisterClass(BaseResourceComponent, 'CommunicationProvidersResource')\n@Component({\n standalone: false,\n selector: 'mj-communication-providers-resource',\n template: `\n <mj-page-layout>\n <mj-page-header\n Title=\"Providers\"\n Icon=\"fa-solid fa-server\"\n Subtitle=\"Manage your messaging service integrations\">\n <div actions>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"addNewProvider()\">\n <i class=\"fa-solid fa-plus\"></i> Add Provider\n </button>\n </div>\n </mj-page-header>\n\n <mj-page-body>\n @if (isLoading) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading providers...\"></mj-loading>\n </div>\n }\n \n @if (!isLoading) {\n <div class=\"providers-grid\">\n @for (card of providerCards; track card) {\n <div class=\"provider-card\" [class.disabled]=\"card.Entity.Status === 'Disabled'\">\n <div class=\"provider-card-header\">\n <div class=\"provider-card-logo\" [ngClass]=\"card.LogoClass\">\n <i [class]=\"card.IconClass\"></i>\n </div>\n <div class=\"provider-card-title\">\n <div class=\"provider-card-name\">{{card.Entity.Name}}</div>\n <div class=\"provider-card-desc\">{{card.Entity.Description || 'No description'}}</div>\n </div>\n <span class=\"provider-card-status\" [ngClass]=\"card.Entity.Status.toLowerCase()\">\n {{card.Entity.Status}}\n </span>\n </div>\n <div class=\"provider-card-body\">\n <div class=\"provider-capabilities\">\n <span class=\"capability-chip\" [class.supported]=\"card.Entity.SupportsSending\" [class.unsupported]=\"!card.Entity.SupportsSending\">\n <i [class]=\"card.Entity.SupportsSending ? 'fa-solid fa-check' : 'fa-solid fa-xmark'\"></i> Sending\n </span>\n <span class=\"capability-chip\" [class.supported]=\"card.Entity.SupportsReceiving\" [class.unsupported]=\"!card.Entity.SupportsReceiving\">\n <i [class]=\"card.Entity.SupportsReceiving ? 'fa-solid fa-check' : 'fa-solid fa-xmark'\"></i> Receiving\n </span>\n @if (card.Entity.SupportsScheduledSending) {\n <span class=\"capability-chip supported\">\n <i class=\"fa-solid fa-check\"></i> Scheduled\n </span>\n }\n @if (card.Entity.SupportsDrafts) {\n <span class=\"capability-chip supported\">\n <i class=\"fa-solid fa-check\"></i> Drafts\n </span>\n }\n @if (card.Entity.SupportsForwarding) {\n <span class=\"capability-chip supported\">\n <i class=\"fa-solid fa-check\"></i> Forward\n </span>\n }\n @if (card.Entity.SupportsReplying) {\n <span class=\"capability-chip supported\">\n <i class=\"fa-solid fa-check\"></i> Reply\n </span>\n }\n </div>\n <div class=\"provider-card-stats\">\n <div class=\"provider-stat\">\n <div class=\"provider-stat-value\">{{card.SentCount}}</div>\n <div class=\"provider-stat-label\">Sent (24h)</div>\n </div>\n <div class=\"provider-stat\">\n <div class=\"provider-stat-value\">{{card.SuccessRate}}%</div>\n <div class=\"provider-stat-label\">Success</div>\n </div>\n <div class=\"provider-stat\">\n <div class=\"provider-stat-value\">{{card.FailedCount}}</div>\n <div class=\"provider-stat-label\">Failed</div>\n </div>\n </div>\n </div>\n <div class=\"provider-card-footer\">\n <button (click)=\"configureProvider(card.Entity)\">\n <i class=\"fa-solid fa-gear\"></i> Configure\n </button>\n <button (click)=\"viewProviderLogs(card.Entity)\">\n <i class=\"fa-solid fa-chart-line\"></i> Analytics\n </button>\n </div>\n </div>\n }\n </div>\n }\n </mj-page-body>\n </mj-page-layout>\n `,\n styles: [`\n .loading-state {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 80px 0;\n }\n\n /* GRID */\n .providers-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));\n gap: 16px;\n }\n .provider-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n transition: all 0.15s ease;\n }\n .provider-card:hover {\n box-shadow: 0 2px 8px var(--mj-shadow-md);\n border-color: var(--mj-border-strong);\n }\n .provider-card.disabled { opacity: 0.65; }\n\n .provider-card-header {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 20px 20px 16px;\n }\n .provider-card-logo {\n width: 48px; height: 48px;\n border-radius: 12px;\n display: flex; align-items: center; justify-content: center;\n font-size: 22px; flex-shrink: 0;\n background: var(--mj-bg-surface-sunken);\n }\n .provider-card-logo.sendgrid {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n .provider-card-logo.twilio {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n .provider-card-logo.gmail {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n .provider-card-logo.msgraph {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n\n .provider-card-title { flex: 1; min-width: 0; }\n .provider-card-name {\n font-size: 15px; font-weight: 700;\n color: var(--mj-text-primary);\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n .provider-card-desc {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n }\n .provider-card-status {\n font-size: 10px; font-weight: 700;\n text-transform: uppercase; letter-spacing: 0.5px;\n padding: 3px 10px; border-radius: 10px;\n flex-shrink: 0;\n }\n .provider-card-status.active {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n .provider-card-status.disabled {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n }\n\n .provider-card-body { padding: 0 20px 16px; }\n\n .provider-capabilities {\n display: flex; flex-wrap: wrap;\n gap: 6px; margin-bottom: 16px;\n }\n .capability-chip {\n display: inline-flex; align-items: center;\n gap: 4px; padding: 4px 10px;\n border-radius: 12px; font-size: 11px; font-weight: 500;\n }\n .capability-chip.supported {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n .capability-chip.unsupported {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n text-decoration: line-through;\n }\n\n .provider-card-stats {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 12px; padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n }\n .provider-stat { text-align: center; }\n .provider-stat-value {\n font-size: 16px; font-weight: 800;\n color: var(--mj-text-primary);\n }\n .provider-stat-label {\n font-size: 10px;\n color: var(--mj-text-muted);\n text-transform: uppercase; letter-spacing: 0.3px;\n }\n\n .provider-card-footer {\n display: flex;\n border-top: 1px solid var(--mj-border-default);\n }\n .provider-card-footer button {\n flex: 1; padding: 12px;\n border: none; background: transparent;\n font-size: 12px; font-weight: 600;\n color: var(--mj-brand-primary);\n cursor: pointer; transition: background 0.15s;\n font-family: inherit;\n display: flex; align-items: center;\n justify-content: center; gap: 6px;\n }\n .provider-card-footer button:hover {\n background: var(--mj-bg-surface-sunken);\n }\n .provider-card-footer button + button {\n border-left: 1px solid var(--mj-border-default);\n }\n `]\n})\nexport class CommunicationProvidersResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public isLoading = false;\n public providerCards: ProviderCardData[] = [];\n\n constructor(private cdr: ChangeDetectorRef, private navService: NavigationService) {\n super();\n }\n\n async ngOnInit(): Promise<void> {\n super.ngOnInit();\n await this.loadData();\n this.NotifyLoadComplete();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n }\n\n public async loadData(): Promise<void> {\n try {\n this.isLoading = true;\n this.cdr.detectChanges();\n\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const yesterday = new Date();\n yesterday.setDate(yesterday.getDate() - 1);\n const yesterdayIso = yesterday.toISOString();\n\n const [providersResult, logsResult] = await Promise.all([\n rv.RunView<MJCommunicationProviderEntity>({\n EntityName: 'MJ: Communication Providers',\n OrderBy: 'Name ASC',\n ResultType: 'entity_object'\n }),\n rv.RunView<MJCommunicationLogEntity>({\n EntityName: 'MJ: Communication Logs',\n ExtraFilter: `MessageDate >= '${yesterdayIso}'`,\n ResultType: 'entity_object'\n })\n ]);\n\n if (providersResult.Success) {\n const logs = logsResult.Success ? logsResult.Results : [];\n this.providerCards = providersResult.Results.map(p => this.buildProviderCard(p, logs));\n }\n } catch (error) {\n console.error('Error loading providers:', error);\n } finally {\n this.isLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n private buildProviderCard(provider: MJCommunicationProviderEntity, logs: MJCommunicationLogEntity[]): ProviderCardData {\n const providerLogs = logs.filter(l => l.CommunicationProvider === provider.Name);\n const sent = providerLogs.length;\n const failed = providerLogs.filter(l => l.Status === 'Failed').length;\n const rate = sent > 0 ? parseFloat(((sent - failed) / sent * 100).toFixed(1)) : 100;\n\n return {\n Entity: provider,\n SentCount: sent,\n SuccessRate: rate,\n FailedCount: failed,\n IconClass: this.getProviderIcon(provider.Name),\n LogoClass: this.getProviderLogoClass(provider.Name)\n };\n }\n\n private getProviderIcon(name: string): string {\n const n = name.toLowerCase();\n if (n.includes('sendgrid')) return 'fa-solid fa-envelope';\n if (n.includes('twilio')) return 'fa-solid fa-comment-sms';\n if (n.includes('gmail') || n.includes('google')) return 'fa-brands fa-google';\n if (n.includes('microsoft') || n.includes('graph') || n.includes('outlook')) return 'fa-brands fa-microsoft';\n if (n.includes('aws') || n.includes('ses')) return 'fa-brands fa-aws';\n if (n.includes('slack')) return 'fa-brands fa-slack';\n return 'fa-solid fa-server';\n }\n\n private getProviderLogoClass(name: string): string {\n const n = name.toLowerCase();\n if (n.includes('sendgrid')) return 'sendgrid';\n if (n.includes('twilio')) return 'twilio';\n if (n.includes('gmail') || n.includes('google')) return 'gmail';\n if (n.includes('microsoft') || n.includes('graph') || n.includes('outlook')) return 'msgraph';\n return '';\n }\n\n public configureProvider(provider: MJCommunicationProviderEntity): void {\n const pk = new CompositeKey();\n pk.LoadFromEntityInfoAndRecord(this.ProviderToUse.Entities.find(e => e.Name === 'MJ: Communication Providers')!, provider);\n this.navService.OpenEntityRecord('MJ: Communication Providers', pk);\n }\n\n public viewProviderLogs(provider: MJCommunicationProviderEntity): void {\n console.log('View analytics for provider:', provider.Name);\n }\n\n public addNewProvider(): void {\n this.navService.OpenEntityRecord('MJ: Communication Providers', new CompositeKey());\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Providers';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-server';\n }\n}\n"]}
1
+ {"version":3,"file":"communication-providers-resource.component.js","sourceRoot":"","sources":["../../src/Communication/communication-providers-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { ResourceData, MJCommunicationProviderEntity, MJCommunicationLogEntity } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { Metadata, RunView, CompositeKey } from '@memberjunction/core';\n\ninterface ProviderCardData {\n Entity: MJCommunicationProviderEntity;\n SentCount: number;\n SuccessRate: number;\n FailedCount: number;\n IconClass: string;\n LogoClass: string;\n}\n@RegisterClass(BaseResourceComponent, 'CommunicationProvidersResource')\n@Component({\n standalone: false,\n selector: 'mj-communication-providers-resource',\n template: `\n <mj-page-layout>\n <mj-page-header\n Title=\"Providers\"\n Icon=\"fa-solid fa-server\"\n Subtitle=\"Manage your messaging service integrations\">\n <div actions>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"addNewProvider()\">\n <i class=\"fa-solid fa-plus\"></i> <span class=\"action-btn-label\">Add Provider</span>\n </button>\n </div>\n </mj-page-header>\n\n <mj-page-body>\n @if (isLoading) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading providers...\"></mj-loading>\n </div>\n }\n \n @if (!isLoading) {\n <div class=\"providers-grid\">\n @for (card of providerCards; track card) {\n <div class=\"provider-card\" [class.disabled]=\"card.Entity.Status === 'Disabled'\">\n <div class=\"provider-card-header\">\n <div class=\"provider-card-logo\" [ngClass]=\"card.LogoClass\">\n <i [class]=\"card.IconClass\"></i>\n </div>\n <div class=\"provider-card-title\">\n <div class=\"provider-card-name\">{{card.Entity.Name}}</div>\n <div class=\"provider-card-desc\">{{card.Entity.Description || 'No description'}}</div>\n </div>\n <span class=\"provider-card-status\" [ngClass]=\"card.Entity.Status.toLowerCase()\">\n {{card.Entity.Status}}\n </span>\n </div>\n <div class=\"provider-card-body\">\n <div class=\"provider-capabilities\">\n <span class=\"capability-chip\" [class.supported]=\"card.Entity.SupportsSending\" [class.unsupported]=\"!card.Entity.SupportsSending\">\n <i [class]=\"card.Entity.SupportsSending ? 'fa-solid fa-check' : 'fa-solid fa-xmark'\"></i> Sending\n </span>\n <span class=\"capability-chip\" [class.supported]=\"card.Entity.SupportsReceiving\" [class.unsupported]=\"!card.Entity.SupportsReceiving\">\n <i [class]=\"card.Entity.SupportsReceiving ? 'fa-solid fa-check' : 'fa-solid fa-xmark'\"></i> Receiving\n </span>\n @if (card.Entity.SupportsScheduledSending) {\n <span class=\"capability-chip supported\">\n <i class=\"fa-solid fa-check\"></i> Scheduled\n </span>\n }\n @if (card.Entity.SupportsDrafts) {\n <span class=\"capability-chip supported\">\n <i class=\"fa-solid fa-check\"></i> Drafts\n </span>\n }\n @if (card.Entity.SupportsForwarding) {\n <span class=\"capability-chip supported\">\n <i class=\"fa-solid fa-check\"></i> Forward\n </span>\n }\n @if (card.Entity.SupportsReplying) {\n <span class=\"capability-chip supported\">\n <i class=\"fa-solid fa-check\"></i> Reply\n </span>\n }\n </div>\n <div class=\"provider-card-stats\">\n <div class=\"provider-stat\">\n <div class=\"provider-stat-value\">{{card.SentCount}}</div>\n <div class=\"provider-stat-label\">Sent (24h)</div>\n </div>\n <div class=\"provider-stat\">\n <div class=\"provider-stat-value\">{{card.SuccessRate}}%</div>\n <div class=\"provider-stat-label\">Success</div>\n </div>\n <div class=\"provider-stat\">\n <div class=\"provider-stat-value\">{{card.FailedCount}}</div>\n <div class=\"provider-stat-label\">Failed</div>\n </div>\n </div>\n </div>\n <div class=\"provider-card-footer\">\n <button (click)=\"configureProvider(card.Entity)\">\n <i class=\"fa-solid fa-gear\"></i> Configure\n </button>\n <button (click)=\"viewProviderLogs(card.Entity)\">\n <i class=\"fa-solid fa-chart-line\"></i> Analytics\n </button>\n </div>\n </div>\n }\n </div>\n }\n </mj-page-body>\n </mj-page-layout>\n `,\n styles: [`\n .loading-state {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 80px 0;\n }\n\n /* GRID */\n .providers-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));\n gap: 16px;\n }\n .provider-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n transition: all 0.15s ease;\n }\n .provider-card:hover {\n box-shadow: 0 2px 8px var(--mj-shadow-md);\n border-color: var(--mj-border-strong);\n }\n .provider-card.disabled { opacity: 0.65; }\n\n .provider-card-header {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 20px 20px 16px;\n }\n .provider-card-logo {\n width: 48px; height: 48px;\n border-radius: 12px;\n display: flex; align-items: center; justify-content: center;\n font-size: 22px; flex-shrink: 0;\n background: var(--mj-bg-surface-sunken);\n }\n .provider-card-logo.sendgrid {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n .provider-card-logo.twilio {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n .provider-card-logo.gmail {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n .provider-card-logo.msgraph {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n\n .provider-card-title { flex: 1; min-width: 0; }\n .provider-card-name {\n font-size: 15px; font-weight: 700;\n color: var(--mj-text-primary);\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n .provider-card-desc {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n }\n .provider-card-status {\n font-size: 10px; font-weight: 700;\n text-transform: uppercase; letter-spacing: 0.5px;\n padding: 3px 10px; border-radius: 10px;\n flex-shrink: 0;\n }\n .provider-card-status.active {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n .provider-card-status.disabled {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n }\n\n .provider-card-body { padding: 0 20px 16px; }\n\n .provider-capabilities {\n display: flex; flex-wrap: wrap;\n gap: 6px; margin-bottom: 16px;\n }\n .capability-chip {\n display: inline-flex; align-items: center;\n gap: 4px; padding: 4px 10px;\n border-radius: 12px; font-size: 11px; font-weight: 500;\n }\n .capability-chip.supported {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n .capability-chip.unsupported {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n text-decoration: line-through;\n }\n\n .provider-card-stats {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 12px; padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n }\n .provider-stat { text-align: center; }\n .provider-stat-value {\n font-size: 16px; font-weight: 800;\n color: var(--mj-text-primary);\n }\n .provider-stat-label {\n font-size: 10px;\n color: var(--mj-text-muted);\n text-transform: uppercase; letter-spacing: 0.3px;\n }\n\n .provider-card-footer {\n display: flex;\n border-top: 1px solid var(--mj-border-default);\n }\n .provider-card-footer button {\n flex: 1; padding: 12px;\n border: none; background: transparent;\n font-size: 12px; font-weight: 600;\n color: var(--mj-brand-primary);\n cursor: pointer; transition: background 0.15s;\n font-family: inherit;\n display: flex; align-items: center;\n justify-content: center; gap: 6px;\n }\n .provider-card-footer button:hover {\n background: var(--mj-bg-surface-sunken);\n }\n .provider-card-footer button + button {\n border-left: 1px solid var(--mj-border-default);\n }\n `]\n})\nexport class CommunicationProvidersResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public isLoading = false;\n public providerCards: ProviderCardData[] = [];\n\n constructor(private cdr: ChangeDetectorRef, private navService: NavigationService) {\n super();\n }\n\n async ngOnInit(): Promise<void> {\n super.ngOnInit();\n await this.loadData();\n this.NotifyLoadComplete();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n }\n\n public async loadData(): Promise<void> {\n try {\n this.isLoading = true;\n this.cdr.detectChanges();\n\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const yesterday = new Date();\n yesterday.setDate(yesterday.getDate() - 1);\n const yesterdayIso = yesterday.toISOString();\n\n const [providersResult, logsResult] = await Promise.all([\n rv.RunView<MJCommunicationProviderEntity>({\n EntityName: 'MJ: Communication Providers',\n OrderBy: 'Name ASC',\n ResultType: 'entity_object'\n }),\n rv.RunView<MJCommunicationLogEntity>({\n EntityName: 'MJ: Communication Logs',\n ExtraFilter: `MessageDate >= '${yesterdayIso}'`,\n ResultType: 'entity_object'\n })\n ]);\n\n if (providersResult.Success) {\n const logs = logsResult.Success ? logsResult.Results : [];\n this.providerCards = providersResult.Results.map(p => this.buildProviderCard(p, logs));\n }\n } catch (error) {\n console.error('Error loading providers:', error);\n } finally {\n this.isLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n private buildProviderCard(provider: MJCommunicationProviderEntity, logs: MJCommunicationLogEntity[]): ProviderCardData {\n const providerLogs = logs.filter(l => l.CommunicationProvider === provider.Name);\n const sent = providerLogs.length;\n const failed = providerLogs.filter(l => l.Status === 'Failed').length;\n const rate = sent > 0 ? parseFloat(((sent - failed) / sent * 100).toFixed(1)) : 100;\n\n return {\n Entity: provider,\n SentCount: sent,\n SuccessRate: rate,\n FailedCount: failed,\n IconClass: this.getProviderIcon(provider.Name),\n LogoClass: this.getProviderLogoClass(provider.Name)\n };\n }\n\n private getProviderIcon(name: string): string {\n const n = name.toLowerCase();\n if (n.includes('sendgrid')) return 'fa-solid fa-envelope';\n if (n.includes('twilio')) return 'fa-solid fa-comment-sms';\n if (n.includes('gmail') || n.includes('google')) return 'fa-brands fa-google';\n if (n.includes('microsoft') || n.includes('graph') || n.includes('outlook')) return 'fa-brands fa-microsoft';\n if (n.includes('aws') || n.includes('ses')) return 'fa-brands fa-aws';\n if (n.includes('slack')) return 'fa-brands fa-slack';\n return 'fa-solid fa-server';\n }\n\n private getProviderLogoClass(name: string): string {\n const n = name.toLowerCase();\n if (n.includes('sendgrid')) return 'sendgrid';\n if (n.includes('twilio')) return 'twilio';\n if (n.includes('gmail') || n.includes('google')) return 'gmail';\n if (n.includes('microsoft') || n.includes('graph') || n.includes('outlook')) return 'msgraph';\n return '';\n }\n\n public configureProvider(provider: MJCommunicationProviderEntity): void {\n const pk = new CompositeKey();\n pk.LoadFromEntityInfoAndRecord(this.ProviderToUse.Entities.find(e => e.Name === 'MJ: Communication Providers')!, provider);\n this.navService.OpenEntityRecord('MJ: Communication Providers', pk);\n }\n\n public viewProviderLogs(provider: MJCommunicationProviderEntity): void {\n console.log('View analytics for provider:', provider.Name);\n }\n\n public addNewProvider(): void {\n this.navService.OpenEntityRecord('MJ: Communication Providers', new CompositeKey());\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Providers';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-server';\n }\n}\n"]}
@@ -11,9 +11,9 @@ import { RunView } from '@memberjunction/core';
11
11
  import * as i0 from "@angular/core";
12
12
  import * as i1 from "@angular/common";
13
13
  import * as i2 from "@memberjunction/ng-ui-components";
14
- function CommunicationRunsResourceComponent_For_26_Conditional_16_Template(rf, ctx) { if (rf & 1) {
14
+ function CommunicationRunsResourceComponent_For_27_Conditional_16_Template(rf, ctx) { if (rf & 1) {
15
15
  i0.ɵɵelementStart(0, "span");
16
- i0.ɵɵelement(1, "i", 23);
16
+ i0.ɵɵelement(1, "i", 24);
17
17
  i0.ɵɵtext(2);
18
18
  i0.ɵɵpipe(3, "date");
19
19
  i0.ɵɵelementEnd();
@@ -22,8 +22,8 @@ function CommunicationRunsResourceComponent_For_26_Conditional_16_Template(rf, c
22
22
  i0.ɵɵadvance(2);
23
23
  i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind2(3, 1, run_r1.EndedAt, "shortTime"));
24
24
  } }
25
- function CommunicationRunsResourceComponent_For_26_Conditional_17_Template(rf, ctx) { if (rf & 1) {
26
- i0.ɵɵelementStart(0, "div", 22);
25
+ function CommunicationRunsResourceComponent_For_27_Conditional_17_Template(rf, ctx) { if (rf & 1) {
26
+ i0.ɵɵelementStart(0, "div", 23);
27
27
  i0.ɵɵtext(1);
28
28
  i0.ɵɵelementEnd();
29
29
  } if (rf & 2) {
@@ -31,27 +31,27 @@ function CommunicationRunsResourceComponent_For_26_Conditional_17_Template(rf, c
31
31
  i0.ɵɵadvance();
32
32
  i0.ɵɵtextInterpolate1(" ", run_r1.Comments, " ");
33
33
  } }
34
- function CommunicationRunsResourceComponent_For_26_Template(rf, ctx) { if (rf & 1) {
35
- i0.ɵɵelementStart(0, "div", 12);
36
- i0.ɵɵelement(1, "div", 14);
37
- i0.ɵɵelementStart(2, "div", 15)(3, "div", 16)(4, "span", 17);
34
+ function CommunicationRunsResourceComponent_For_27_Template(rf, ctx) { if (rf & 1) {
35
+ i0.ɵɵelementStart(0, "div", 13);
36
+ i0.ɵɵelement(1, "div", 15);
37
+ i0.ɵɵelementStart(2, "div", 16)(3, "div", 17)(4, "span", 18);
38
38
  i0.ɵɵtext(5);
39
39
  i0.ɵɵelementEnd();
40
- i0.ɵɵelementStart(6, "span", 18);
40
+ i0.ɵɵelementStart(6, "span", 19);
41
41
  i0.ɵɵtext(7);
42
42
  i0.ɵɵelementEnd()();
43
- i0.ɵɵelementStart(8, "div", 19)(9, "span");
44
- i0.ɵɵelement(10, "i", 20);
43
+ i0.ɵɵelementStart(8, "div", 20)(9, "span");
44
+ i0.ɵɵelement(10, "i", 21);
45
45
  i0.ɵɵtext(11);
46
46
  i0.ɵɵelementEnd();
47
47
  i0.ɵɵelementStart(12, "span");
48
- i0.ɵɵelement(13, "i", 21);
48
+ i0.ɵɵelement(13, "i", 22);
49
49
  i0.ɵɵtext(14);
50
50
  i0.ɵɵpipe(15, "date");
51
51
  i0.ɵɵelementEnd();
52
- i0.ɵɵconditionalCreate(16, CommunicationRunsResourceComponent_For_26_Conditional_16_Template, 4, 4, "span");
52
+ i0.ɵɵconditionalCreate(16, CommunicationRunsResourceComponent_For_27_Conditional_16_Template, 4, 4, "span");
53
53
  i0.ɵɵelementEnd();
54
- i0.ɵɵconditionalCreate(17, CommunicationRunsResourceComponent_For_26_Conditional_17_Template, 2, 1, "div", 22);
54
+ i0.ɵɵconditionalCreate(17, CommunicationRunsResourceComponent_For_27_Conditional_17_Template, 2, 1, "div", 23);
55
55
  i0.ɵɵelementEnd()();
56
56
  } if (rf & 2) {
57
57
  const run_r1 = ctx.$implicit;
@@ -73,9 +73,9 @@ function CommunicationRunsResourceComponent_For_26_Template(rf, ctx) { if (rf &
73
73
  i0.ɵɵadvance();
74
74
  i0.ɵɵconditional(run_r1.Comments ? 17 : -1);
75
75
  } }
76
- function CommunicationRunsResourceComponent_Conditional_27_Template(rf, ctx) { if (rf & 1) {
77
- i0.ɵɵelementStart(0, "div", 13);
78
- i0.ɵɵelement(1, "i", 24);
76
+ function CommunicationRunsResourceComponent_Conditional_28_Template(rf, ctx) { if (rf & 1) {
77
+ i0.ɵɵelementStart(0, "div", 14);
78
+ i0.ɵɵelement(1, "i", 25);
79
79
  i0.ɵɵelementStart(2, "p");
80
80
  i0.ɵɵtext(3, "No communication runs found");
81
81
  i0.ɵɵelementEnd()();
@@ -179,40 +179,41 @@ let CommunicationRunsResourceComponent = class CommunicationRunsResourceComponen
179
179
  return 'fa-solid fa-play-circle';
180
180
  }
181
181
  static ɵfac = function CommunicationRunsResourceComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CommunicationRunsResourceComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
182
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: CommunicationRunsResourceComponent, selectors: [["mj-communication-runs-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 28, vars: 7, consts: [["Title", "Runs", "Icon", "fa-solid fa-play-circle", "Subtitle", "Bulk communication run history"], ["actions", ""], ["mjButton", "", "variant", "secondary", "size", "sm", "title", "Refresh", 3, "click", "disabled"], [1, "fa-solid", "fa-rotate"], [1, "card"], [1, "runs-summary"], [1, "run-stat-card", "info"], [1, "run-stat-value"], [1, "run-stat-label"], [1, "run-stat-card", "success"], [1, "run-stat-card", "neutral"], [1, "run-timeline"], [1, "run-entry"], [1, "empty-state"], [1, "run-timeline-dot", 3, "ngClass"], [1, "run-entry-content"], [1, "run-entry-header"], [1, "run-entry-title"], [1, "run-status-badge", 3, "ngClass"], [1, "run-entry-meta"], [1, "fa-solid", "fa-user"], [1, "fa-solid", "fa-clock"], [1, "run-entry-comments"], [1, "fa-solid", "fa-flag-checkered"], [1, "fa-solid", "fa-play-circle"]], template: function CommunicationRunsResourceComponent_Template(rf, ctx) { if (rf & 1) {
182
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: CommunicationRunsResourceComponent, selectors: [["mj-communication-runs-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 29, vars: 7, consts: [["Title", "Runs", "Icon", "fa-solid fa-play-circle", "Subtitle", "Bulk communication run history"], ["actions", ""], ["mjButton", "", "variant", "secondary", "size", "sm", "title", "Refresh", 3, "click", "disabled"], [1, "fa-solid", "fa-rotate"], [1, "action-btn-label"], [1, "card"], [1, "runs-summary"], [1, "run-stat-card", "info"], [1, "run-stat-value"], [1, "run-stat-label"], [1, "run-stat-card", "success"], [1, "run-stat-card", "neutral"], [1, "run-timeline"], [1, "run-entry"], [1, "empty-state"], [1, "run-timeline-dot", 3, "ngClass"], [1, "run-entry-content"], [1, "run-entry-header"], [1, "run-entry-title"], [1, "run-status-badge", 3, "ngClass"], [1, "run-entry-meta"], [1, "fa-solid", "fa-user"], [1, "fa-solid", "fa-clock"], [1, "run-entry-comments"], [1, "fa-solid", "fa-flag-checkered"], [1, "fa-solid", "fa-play-circle"]], template: function CommunicationRunsResourceComponent_Template(rf, ctx) { if (rf & 1) {
183
183
  i0.ɵɵelementStart(0, "mj-page-layout")(1, "mj-page-header", 0)(2, "div", 1)(3, "button", 2);
184
184
  i0.ɵɵlistener("click", function CommunicationRunsResourceComponent_Template_button_click_3_listener() { return ctx.loadData(); });
185
185
  i0.ɵɵelement(4, "i", 3);
186
- i0.ɵɵtext(5, " Refresh ");
187
- i0.ɵɵelementEnd()()();
188
- i0.ɵɵelementStart(6, "mj-page-body")(7, "div", 4)(8, "div", 5)(9, "div", 6)(10, "div", 7);
189
- i0.ɵɵtext(11);
186
+ i0.ɵɵelementStart(5, "span", 4);
187
+ i0.ɵɵtext(6, "Refresh");
188
+ i0.ɵɵelementEnd()()()();
189
+ i0.ɵɵelementStart(7, "mj-page-body")(8, "div", 5)(9, "div", 6)(10, "div", 7)(11, "div", 8);
190
+ i0.ɵɵtext(12);
190
191
  i0.ɵɵelementEnd();
191
- i0.ɵɵelementStart(12, "div", 8);
192
- i0.ɵɵtext(13, "Active Runs");
192
+ i0.ɵɵelementStart(13, "div", 9);
193
+ i0.ɵɵtext(14, "Active Runs");
193
194
  i0.ɵɵelementEnd()();
194
- i0.ɵɵelementStart(14, "div", 9)(15, "div", 7);
195
- i0.ɵɵtext(16);
195
+ i0.ɵɵelementStart(15, "div", 10)(16, "div", 8);
196
+ i0.ɵɵtext(17);
196
197
  i0.ɵɵelementEnd();
197
- i0.ɵɵelementStart(17, "div", 8);
198
- i0.ɵɵtext(18, "Completed (24h)");
198
+ i0.ɵɵelementStart(18, "div", 9);
199
+ i0.ɵɵtext(19, "Completed (24h)");
199
200
  i0.ɵɵelementEnd()();
200
- i0.ɵɵelementStart(19, "div", 10)(20, "div", 7);
201
- i0.ɵɵtext(21);
201
+ i0.ɵɵelementStart(20, "div", 11)(21, "div", 8);
202
+ i0.ɵɵtext(22);
202
203
  i0.ɵɵelementEnd();
203
- i0.ɵɵelementStart(22, "div", 8);
204
- i0.ɵɵtext(23, "Success Rate");
204
+ i0.ɵɵelementStart(23, "div", 9);
205
+ i0.ɵɵtext(24, "Success Rate");
205
206
  i0.ɵɵelementEnd()()();
206
- i0.ɵɵelementStart(24, "div", 11);
207
- i0.ɵɵrepeaterCreate(25, CommunicationRunsResourceComponent_For_26_Template, 18, 11, "div", 12, i0.ɵɵrepeaterTrackByIdentity);
208
- i0.ɵɵconditionalCreate(27, CommunicationRunsResourceComponent_Conditional_27_Template, 4, 0, "div", 13);
207
+ i0.ɵɵelementStart(25, "div", 12);
208
+ i0.ɵɵrepeaterCreate(26, CommunicationRunsResourceComponent_For_27_Template, 18, 11, "div", 13, i0.ɵɵrepeaterTrackByIdentity);
209
+ i0.ɵɵconditionalCreate(28, CommunicationRunsResourceComponent_Conditional_28_Template, 4, 0, "div", 14);
209
210
  i0.ɵɵelementEnd()()()();
210
211
  } if (rf & 2) {
211
212
  i0.ɵɵadvance(3);
212
213
  i0.ɵɵproperty("disabled", ctx.isLoading);
213
214
  i0.ɵɵadvance();
214
215
  i0.ɵɵclassProp("spinning", ctx.isLoading);
215
- i0.ɵɵadvance(7);
216
+ i0.ɵɵadvance(8);
216
217
  i0.ɵɵtextInterpolate(ctx.summary.active);
217
218
  i0.ɵɵadvance(5);
218
219
  i0.ɵɵtextInterpolate(ctx.summary.completed);
@@ -221,7 +222,7 @@ let CommunicationRunsResourceComponent = class CommunicationRunsResourceComponen
221
222
  i0.ɵɵadvance(4);
222
223
  i0.ɵɵrepeater(ctx.runs);
223
224
  i0.ɵɵadvance(2);
224
- i0.ɵɵconditional(ctx.runs.length === 0 && !ctx.isLoading ? 27 : -1);
225
+ i0.ɵɵconditional(ctx.runs.length === 0 && !ctx.isLoading ? 28 : -1);
225
226
  } }, dependencies: [i1.NgClass, i2.MJButtonDirective, i2.MJPageHeaderComponent, i2.MJPageLayoutComponent, i2.MJPageBodyComponent, i1.DatePipe], styles: [".card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n padding: 16px 0 0;\n }\n @keyframes _ngcontent-%COMP%_spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }\n .spinning[_ngcontent-%COMP%] { animation: _ngcontent-%COMP%_spin 1s linear infinite; }\n\n \n\n .runs-summary[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 16px;\n padding: 20px;\n }\n .run-stat-card[_ngcontent-%COMP%] {\n border-radius: 12px;\n padding: 16px 20px;\n text-align: center;\n }\n .run-stat-card.info[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n }\n .run-stat-card.success[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n }\n .run-stat-card.neutral[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n }\n\n .run-stat-value[_ngcontent-%COMP%] {\n font-size: 24px; font-weight: 800;\n color: var(--mj-text-primary);\n }\n .run-stat-card.info[_ngcontent-%COMP%] .run-stat-value[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n .run-stat-card.success[_ngcontent-%COMP%] .run-stat-value[_ngcontent-%COMP%] { color: var(--mj-status-success); }\n\n .run-stat-label[_ngcontent-%COMP%] {\n font-size: 11px; font-weight: 600;\n text-transform: uppercase; letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n }\n\n \n\n .run-timeline[_ngcontent-%COMP%] { padding: 8px 20px 20px; }\n .run-entry[_ngcontent-%COMP%] {\n display: flex; gap: 16px;\n padding: 16px 0;\n border-bottom: 1px solid var(--mj-border-default);\n align-items: flex-start;\n }\n .run-entry[_ngcontent-%COMP%]:last-child { border-bottom: none; }\n\n .run-timeline-dot[_ngcontent-%COMP%] {\n width: 12px; height: 12px;\n border-radius: 50%;\n margin-top: 4px; flex-shrink: 0;\n }\n .run-timeline-dot.complete[_ngcontent-%COMP%] { background: var(--mj-status-success); }\n .run-timeline-dot.failed[_ngcontent-%COMP%] { background: var(--mj-status-error); }\n .run-timeline-dot.in-progress[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n animation: _ngcontent-%COMP%_pulse-dot 1.5s ease-in-out infinite;\n }\n .run-timeline-dot.pending[_ngcontent-%COMP%] { background: var(--mj-status-warning); }\n\n @keyframes _ngcontent-%COMP%_pulse-dot {\n 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--mj-brand-primary) 40%, transparent); }\n 50% { box-shadow: 0 0 0 6px transparent; }\n }\n\n .run-entry-content[_ngcontent-%COMP%] { flex: 1; }\n .run-entry-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n .run-entry-title[_ngcontent-%COMP%] {\n font-size: 13px; font-weight: 600;\n color: var(--mj-text-primary);\n }\n .run-status-badge[_ngcontent-%COMP%] {\n font-size: 10px; font-weight: 700;\n text-transform: uppercase; letter-spacing: 0.3px;\n padding: 3px 8px;\n border-radius: 4px;\n }\n .run-status-badge.complete[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n }\n .run-status-badge.failed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n }\n .run-status-badge.pending[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n }\n .run-status-badge.in-progress[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n }\n\n .run-entry-meta[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 4px;\n display: flex; align-items: center; gap: 12px;\n }\n .run-entry-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: flex; align-items: center; gap: 4px;\n }\n .run-entry-meta[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 10px; }\n\n .run-entry-comments[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 6px;\n font-style: italic;\n }\n\n \n\n .empty-state[_ngcontent-%COMP%] {\n display: flex; flex-direction: column;\n align-items: center; justify-content: center;\n padding: 48px 0; color: var(--mj-text-muted);\n }\n .empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 2rem; margin-bottom: 12px; opacity: 0.5; }\n .empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] { margin: 0; font-size: 13px; }"] });
226
227
  };
227
228
  CommunicationRunsResourceComponent = __decorate([
@@ -238,7 +239,7 @@ export { CommunicationRunsResourceComponent };
238
239
  Subtitle="Bulk communication run history">
239
240
  <div actions>
240
241
  <button mjButton variant="secondary" size="sm" (click)="loadData()" [disabled]="isLoading" title="Refresh">
241
- <i class="fa-solid fa-rotate" [class.spinning]="isLoading"></i> Refresh
242
+ <i class="fa-solid fa-rotate" [class.spinning]="isLoading"></i> <span class="action-btn-label">Refresh</span>
242
243
  </button>
243
244
  </div>
244
245
  </mj-page-header>
@@ -1 +1 @@
1
- {"version":3,"file":"communication-runs-resource.component.js","sourceRoot":"","sources":["../../src/Communication/communication-runs-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { ResourceData, MJCommunicationRunEntity } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { RunView } from '@memberjunction/core';\n@RegisterClass(BaseResourceComponent, 'CommunicationRunsResource')\n@Component({\n standalone: false,\n selector: 'mj-communication-runs-resource',\n template: `\n <mj-page-layout>\n <mj-page-header\n Title=\"Runs\"\n Icon=\"fa-solid fa-play-circle\"\n Subtitle=\"Bulk communication run history\">\n <div actions>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"loadData()\" [disabled]=\"isLoading\" title=\"Refresh\">\n <i class=\"fa-solid fa-rotate\" [class.spinning]=\"isLoading\"></i> Refresh\n </button>\n </div>\n </mj-page-header>\n\n <mj-page-body>\n <div class=\"card\">\n <!-- SUMMARY STATS -->\n <div class=\"runs-summary\">\n <div class=\"run-stat-card info\">\n <div class=\"run-stat-value\">{{summary.active}}</div>\n <div class=\"run-stat-label\">Active Runs</div>\n </div>\n <div class=\"run-stat-card success\">\n <div class=\"run-stat-value\">{{summary.completed}}</div>\n <div class=\"run-stat-label\">Completed (24h)</div>\n </div>\n <div class=\"run-stat-card neutral\">\n <div class=\"run-stat-value\">{{summary.successRate}}%</div>\n <div class=\"run-stat-label\">Success Rate</div>\n </div>\n </div>\n \n <!-- TIMELINE -->\n <div class=\"run-timeline\">\n @for (run of runs; track run) {\n <div class=\"run-entry\">\n <div class=\"run-timeline-dot\" [ngClass]=\"getRunDotClass(run.Status)\"></div>\n <div class=\"run-entry-content\">\n <div class=\"run-entry-header\">\n <span class=\"run-entry-title\">Run #{{run.ID.substring(0, 8)}}</span>\n <span class=\"run-status-badge\" [ngClass]=\"getStatusClass(run.Status)\">\n {{run.Status}}\n </span>\n </div>\n <div class=\"run-entry-meta\">\n <span><i class=\"fa-solid fa-user\"></i> {{run.User || 'System'}}</span>\n <span><i class=\"fa-solid fa-clock\"></i> {{run.StartedAt | date:'medium'}}</span>\n @if (run.EndedAt) {\n <span><i class=\"fa-solid fa-flag-checkered\"></i> {{run.EndedAt | date:'shortTime'}}</span>\n }\n </div>\n @if (run.Comments) {\n <div class=\"run-entry-comments\">\n {{run.Comments}}\n </div>\n }\n </div>\n </div>\n }\n \n @if (runs.length === 0 && !isLoading) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-play-circle\"></i>\n <p>No communication runs found</p>\n </div>\n }\n </div>\n </div>\n </mj-page-body>\n </mj-page-layout>\n `,\n styles: [`\n .card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n padding: 16px 0 0;\n }\n @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }\n .spinning { animation: spin 1s linear infinite; }\n\n /* SUMMARY */\n .runs-summary {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 16px;\n padding: 20px;\n }\n .run-stat-card {\n border-radius: 12px;\n padding: 16px 20px;\n text-align: center;\n }\n .run-stat-card.info {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n }\n .run-stat-card.success {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n }\n .run-stat-card.neutral {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n }\n\n .run-stat-value {\n font-size: 24px; font-weight: 800;\n color: var(--mj-text-primary);\n }\n .run-stat-card.info .run-stat-value { color: var(--mj-brand-primary); }\n .run-stat-card.success .run-stat-value { color: var(--mj-status-success); }\n\n .run-stat-label {\n font-size: 11px; font-weight: 600;\n text-transform: uppercase; letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n }\n\n /* TIMELINE */\n .run-timeline { padding: 8px 20px 20px; }\n .run-entry {\n display: flex; gap: 16px;\n padding: 16px 0;\n border-bottom: 1px solid var(--mj-border-default);\n align-items: flex-start;\n }\n .run-entry:last-child { border-bottom: none; }\n\n .run-timeline-dot {\n width: 12px; height: 12px;\n border-radius: 50%;\n margin-top: 4px; flex-shrink: 0;\n }\n .run-timeline-dot.complete { background: var(--mj-status-success); }\n .run-timeline-dot.failed { background: var(--mj-status-error); }\n .run-timeline-dot.in-progress {\n background: var(--mj-brand-primary);\n animation: pulse-dot 1.5s ease-in-out infinite;\n }\n .run-timeline-dot.pending { background: var(--mj-status-warning); }\n\n @keyframes pulse-dot {\n 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--mj-brand-primary) 40%, transparent); }\n 50% { box-shadow: 0 0 0 6px transparent; }\n }\n\n .run-entry-content { flex: 1; }\n .run-entry-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n .run-entry-title {\n font-size: 13px; font-weight: 600;\n color: var(--mj-text-primary);\n }\n .run-status-badge {\n font-size: 10px; font-weight: 700;\n text-transform: uppercase; letter-spacing: 0.3px;\n padding: 3px 8px;\n border-radius: 4px;\n }\n .run-status-badge.complete {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n }\n .run-status-badge.failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n }\n .run-status-badge.pending {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n }\n .run-status-badge.in-progress {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n }\n\n .run-entry-meta {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 4px;\n display: flex; align-items: center; gap: 12px;\n }\n .run-entry-meta span {\n display: flex; align-items: center; gap: 4px;\n }\n .run-entry-meta i { font-size: 10px; }\n\n .run-entry-comments {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 6px;\n font-style: italic;\n }\n\n /* EMPTY STATE */\n .empty-state {\n display: flex; flex-direction: column;\n align-items: center; justify-content: center;\n padding: 48px 0; color: var(--mj-text-muted);\n }\n .empty-state i { font-size: 2rem; margin-bottom: 12px; opacity: 0.5; }\n .empty-state p { margin: 0; font-size: 13px; }\n `]\n})\nexport class CommunicationRunsResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public runs: MJCommunicationRunEntity[] = [];\n public isLoading = false;\n public summary = {\n active: 0,\n completed: 0,\n successRate: 0\n };\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n async ngOnInit(): Promise<void> {\n super.ngOnInit();\n await this.loadData();\n this.NotifyLoadComplete();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n }\n\n public async loadData(): Promise<void> {\n try {\n this.isLoading = true;\n this.cdr.detectChanges();\n\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const yesterday = new Date();\n yesterday.setDate(yesterday.getDate() - 1);\n const yesterdayIso = yesterday.toISOString();\n\n const [runsResult, activeResult, completedResult, failedResult] = await Promise.all([\n rv.RunView<MJCommunicationRunEntity>({\n EntityName: 'MJ: Communication Runs',\n OrderBy: 'StartedAt DESC',\n MaxRows: 50,\n ResultType: 'entity_object'\n }),\n rv.RunView({\n EntityName: 'MJ: Communication Runs',\n ExtraFilter: `Status = 'In-Progress'`,\n ResultType: 'count_only'\n }),\n rv.RunView({\n EntityName: 'MJ: Communication Runs',\n ExtraFilter: `EndedAt >= '${yesterdayIso}' AND Status = 'Complete'`,\n ResultType: 'count_only'\n }),\n rv.RunView({\n EntityName: 'MJ: Communication Runs',\n ExtraFilter: `EndedAt >= '${yesterdayIso}' AND Status = 'Failed'`,\n ResultType: 'count_only'\n })\n ]);\n\n if (runsResult.Success) {\n this.runs = runsResult.Results;\n }\n\n if (activeResult.Success) this.summary.active = activeResult.TotalRowCount;\n if (completedResult.Success) this.summary.completed = completedResult.TotalRowCount;\n\n const totalCompleted = this.summary.completed + (failedResult.Success ? failedResult.TotalRowCount : 0);\n this.summary.successRate = totalCompleted > 0\n ? Math.round((this.summary.completed / totalCompleted) * 100)\n : 100;\n\n } catch (error) {\n console.error('Error loading runs:', error);\n } finally {\n this.isLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n public getRunDotClass(status: string): string {\n const s = (status || '').toLowerCase();\n if (s === 'complete') return 'complete';\n if (s === 'failed') return 'failed';\n if (s === 'in-progress') return 'in-progress';\n return 'pending';\n }\n\n public getStatusClass(status: string): string {\n const s = (status || '').toLowerCase();\n if (s === 'complete') return 'complete';\n if (s === 'failed') return 'failed';\n if (s === 'in-progress') return 'in-progress';\n return 'pending';\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Bulk Runs';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-play-circle';\n }\n}\n"]}
1
+ {"version":3,"file":"communication-runs-resource.component.js","sourceRoot":"","sources":["../../src/Communication/communication-runs-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { ResourceData, MJCommunicationRunEntity } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { RunView } from '@memberjunction/core';\n@RegisterClass(BaseResourceComponent, 'CommunicationRunsResource')\n@Component({\n standalone: false,\n selector: 'mj-communication-runs-resource',\n template: `\n <mj-page-layout>\n <mj-page-header\n Title=\"Runs\"\n Icon=\"fa-solid fa-play-circle\"\n Subtitle=\"Bulk communication run history\">\n <div actions>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"loadData()\" [disabled]=\"isLoading\" title=\"Refresh\">\n <i class=\"fa-solid fa-rotate\" [class.spinning]=\"isLoading\"></i> <span class=\"action-btn-label\">Refresh</span>\n </button>\n </div>\n </mj-page-header>\n\n <mj-page-body>\n <div class=\"card\">\n <!-- SUMMARY STATS -->\n <div class=\"runs-summary\">\n <div class=\"run-stat-card info\">\n <div class=\"run-stat-value\">{{summary.active}}</div>\n <div class=\"run-stat-label\">Active Runs</div>\n </div>\n <div class=\"run-stat-card success\">\n <div class=\"run-stat-value\">{{summary.completed}}</div>\n <div class=\"run-stat-label\">Completed (24h)</div>\n </div>\n <div class=\"run-stat-card neutral\">\n <div class=\"run-stat-value\">{{summary.successRate}}%</div>\n <div class=\"run-stat-label\">Success Rate</div>\n </div>\n </div>\n \n <!-- TIMELINE -->\n <div class=\"run-timeline\">\n @for (run of runs; track run) {\n <div class=\"run-entry\">\n <div class=\"run-timeline-dot\" [ngClass]=\"getRunDotClass(run.Status)\"></div>\n <div class=\"run-entry-content\">\n <div class=\"run-entry-header\">\n <span class=\"run-entry-title\">Run #{{run.ID.substring(0, 8)}}</span>\n <span class=\"run-status-badge\" [ngClass]=\"getStatusClass(run.Status)\">\n {{run.Status}}\n </span>\n </div>\n <div class=\"run-entry-meta\">\n <span><i class=\"fa-solid fa-user\"></i> {{run.User || 'System'}}</span>\n <span><i class=\"fa-solid fa-clock\"></i> {{run.StartedAt | date:'medium'}}</span>\n @if (run.EndedAt) {\n <span><i class=\"fa-solid fa-flag-checkered\"></i> {{run.EndedAt | date:'shortTime'}}</span>\n }\n </div>\n @if (run.Comments) {\n <div class=\"run-entry-comments\">\n {{run.Comments}}\n </div>\n }\n </div>\n </div>\n }\n \n @if (runs.length === 0 && !isLoading) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-play-circle\"></i>\n <p>No communication runs found</p>\n </div>\n }\n </div>\n </div>\n </mj-page-body>\n </mj-page-layout>\n `,\n styles: [`\n .card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n padding: 16px 0 0;\n }\n @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }\n .spinning { animation: spin 1s linear infinite; }\n\n /* SUMMARY */\n .runs-summary {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 16px;\n padding: 20px;\n }\n .run-stat-card {\n border-radius: 12px;\n padding: 16px 20px;\n text-align: center;\n }\n .run-stat-card.info {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n }\n .run-stat-card.success {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n }\n .run-stat-card.neutral {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n }\n\n .run-stat-value {\n font-size: 24px; font-weight: 800;\n color: var(--mj-text-primary);\n }\n .run-stat-card.info .run-stat-value { color: var(--mj-brand-primary); }\n .run-stat-card.success .run-stat-value { color: var(--mj-status-success); }\n\n .run-stat-label {\n font-size: 11px; font-weight: 600;\n text-transform: uppercase; letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n }\n\n /* TIMELINE */\n .run-timeline { padding: 8px 20px 20px; }\n .run-entry {\n display: flex; gap: 16px;\n padding: 16px 0;\n border-bottom: 1px solid var(--mj-border-default);\n align-items: flex-start;\n }\n .run-entry:last-child { border-bottom: none; }\n\n .run-timeline-dot {\n width: 12px; height: 12px;\n border-radius: 50%;\n margin-top: 4px; flex-shrink: 0;\n }\n .run-timeline-dot.complete { background: var(--mj-status-success); }\n .run-timeline-dot.failed { background: var(--mj-status-error); }\n .run-timeline-dot.in-progress {\n background: var(--mj-brand-primary);\n animation: pulse-dot 1.5s ease-in-out infinite;\n }\n .run-timeline-dot.pending { background: var(--mj-status-warning); }\n\n @keyframes pulse-dot {\n 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--mj-brand-primary) 40%, transparent); }\n 50% { box-shadow: 0 0 0 6px transparent; }\n }\n\n .run-entry-content { flex: 1; }\n .run-entry-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n .run-entry-title {\n font-size: 13px; font-weight: 600;\n color: var(--mj-text-primary);\n }\n .run-status-badge {\n font-size: 10px; font-weight: 700;\n text-transform: uppercase; letter-spacing: 0.3px;\n padding: 3px 8px;\n border-radius: 4px;\n }\n .run-status-badge.complete {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n }\n .run-status-badge.failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n }\n .run-status-badge.pending {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n }\n .run-status-badge.in-progress {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n }\n\n .run-entry-meta {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 4px;\n display: flex; align-items: center; gap: 12px;\n }\n .run-entry-meta span {\n display: flex; align-items: center; gap: 4px;\n }\n .run-entry-meta i { font-size: 10px; }\n\n .run-entry-comments {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 6px;\n font-style: italic;\n }\n\n /* EMPTY STATE */\n .empty-state {\n display: flex; flex-direction: column;\n align-items: center; justify-content: center;\n padding: 48px 0; color: var(--mj-text-muted);\n }\n .empty-state i { font-size: 2rem; margin-bottom: 12px; opacity: 0.5; }\n .empty-state p { margin: 0; font-size: 13px; }\n `]\n})\nexport class CommunicationRunsResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public runs: MJCommunicationRunEntity[] = [];\n public isLoading = false;\n public summary = {\n active: 0,\n completed: 0,\n successRate: 0\n };\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n async ngOnInit(): Promise<void> {\n super.ngOnInit();\n await this.loadData();\n this.NotifyLoadComplete();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n }\n\n public async loadData(): Promise<void> {\n try {\n this.isLoading = true;\n this.cdr.detectChanges();\n\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const yesterday = new Date();\n yesterday.setDate(yesterday.getDate() - 1);\n const yesterdayIso = yesterday.toISOString();\n\n const [runsResult, activeResult, completedResult, failedResult] = await Promise.all([\n rv.RunView<MJCommunicationRunEntity>({\n EntityName: 'MJ: Communication Runs',\n OrderBy: 'StartedAt DESC',\n MaxRows: 50,\n ResultType: 'entity_object'\n }),\n rv.RunView({\n EntityName: 'MJ: Communication Runs',\n ExtraFilter: `Status = 'In-Progress'`,\n ResultType: 'count_only'\n }),\n rv.RunView({\n EntityName: 'MJ: Communication Runs',\n ExtraFilter: `EndedAt >= '${yesterdayIso}' AND Status = 'Complete'`,\n ResultType: 'count_only'\n }),\n rv.RunView({\n EntityName: 'MJ: Communication Runs',\n ExtraFilter: `EndedAt >= '${yesterdayIso}' AND Status = 'Failed'`,\n ResultType: 'count_only'\n })\n ]);\n\n if (runsResult.Success) {\n this.runs = runsResult.Results;\n }\n\n if (activeResult.Success) this.summary.active = activeResult.TotalRowCount;\n if (completedResult.Success) this.summary.completed = completedResult.TotalRowCount;\n\n const totalCompleted = this.summary.completed + (failedResult.Success ? failedResult.TotalRowCount : 0);\n this.summary.successRate = totalCompleted > 0\n ? Math.round((this.summary.completed / totalCompleted) * 100)\n : 100;\n\n } catch (error) {\n console.error('Error loading runs:', error);\n } finally {\n this.isLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n public getRunDotClass(status: string): string {\n const s = (status || '').toLowerCase();\n if (s === 'complete') return 'complete';\n if (s === 'failed') return 'failed';\n if (s === 'in-progress') return 'in-progress';\n return 'pending';\n }\n\n public getStatusClass(status: string): string {\n const s = (status || '').toLowerCase();\n if (s === 'complete') return 'complete';\n if (s === 'failed') return 'failed';\n if (s === 'in-progress') return 'in-progress';\n return 'pending';\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Bulk Runs';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-play-circle';\n }\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import { OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
2
2
  import { ResourceData, MJTemplateEntity } from '@memberjunction/core-entities';
3
3
  import { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';
4
+ import { FilterFieldConfig } from '@memberjunction/ng-ui-components';
4
5
  import * as i0 from "@angular/core";
5
6
  interface TemplateCardData {
6
7
  Entity: MJTemplateEntity;
@@ -26,6 +27,11 @@ export declare class CommunicationTemplatesResourceComponent extends BaseResourc
26
27
  getCategoryCount(category: string): number;
27
28
  onSearchValue(value: string): void;
28
29
  onCategoryFilter(category: string): void;
30
+ get filterFields(): FilterFieldConfig[];
31
+ get filterValues(): Record<string, unknown>;
32
+ get ActiveFilterCount(): number;
33
+ onFilterValuesChange(values: Record<string, unknown>): void;
34
+ resetFilters(): void;
29
35
  private applyFilter;
30
36
  openTemplate(template: MJTemplateEntity): void;
31
37
  addNewTemplate(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"communication-templates-resource.component.d.ts","sourceRoot":"","sources":["../../src/Communication/communication-templates-resource.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAA2B,MAAM,+BAA+B,CAAC;AAExG,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;;AAGrF,UAAU,gBAAgB;IACtB,MAAM,EAAE,gBAAgB,CAAC;IACzB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACxB;AACD,qBAiMa,uCAAwC,SAAQ,qBAAsB,YAAW,MAAM,EAAE,SAAS;IAQ/F,OAAO,CAAC,GAAG;IAAqB,OAAO,CAAC,UAAU;IAPvD,YAAY,EAAE,gBAAgB,EAAE,CAAM;IACtC,iBAAiB,EAAE,gBAAgB,EAAE,CAAM;IAC3C,UAAU,EAAE,MAAM,EAAE,CAAM;IAC1B,cAAc,SAAM;IACpB,SAAS,UAAS;IACzB,OAAO,CAAC,UAAU,CAAM;gBAEJ,GAAG,EAAE,iBAAiB,EAAU,UAAU,EAAE,iBAAiB;IAI3E,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAM/B,WAAW,IAAI,IAAI;IAIN,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAgCtC,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,iBAAiB;IAKlB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAI1C,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKlC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAK/C,OAAO,CAAC,WAAW;IAmBZ,YAAY,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI;IAM9C,cAAc,IAAI,IAAI;IAItB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAQzC,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAI3D,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;yCAhItD,uCAAuC;2CAAvC,uCAAuC;CAmInD"}
1
+ {"version":3,"file":"communication-templates-resource.component.d.ts","sourceRoot":"","sources":["../../src/Communication/communication-templates-resource.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAA2B,MAAM,+BAA+B,CAAC;AAExG,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAErF,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;;AAErE,UAAU,gBAAgB;IACtB,MAAM,EAAE,gBAAgB,CAAC;IACzB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACxB;AACD,qBA4La,uCAAwC,SAAQ,qBAAsB,YAAW,MAAM,EAAE,SAAS;IAQ/F,OAAO,CAAC,GAAG;IAAqB,OAAO,CAAC,UAAU;IAPvD,YAAY,EAAE,gBAAgB,EAAE,CAAM;IACtC,iBAAiB,EAAE,gBAAgB,EAAE,CAAM;IAC3C,UAAU,EAAE,MAAM,EAAE,CAAM;IAC1B,cAAc,SAAM;IACpB,SAAS,UAAS;IACzB,OAAO,CAAC,UAAU,CAAM;gBAEJ,GAAG,EAAE,iBAAiB,EAAU,UAAU,EAAE,iBAAiB;IAI3E,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAM/B,WAAW,IAAI,IAAI;IAIN,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAgCtC,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,iBAAiB;IAKlB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAI1C,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKlC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAO/C,IAAW,YAAY,IAAI,iBAAiB,EAAE,CAU7C;IAED,IAAW,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEjD;IAED,IAAW,iBAAiB,IAAI,MAAM,CAErC;IAEM,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI3D,YAAY,IAAI,IAAI;IAI3B,OAAO,CAAC,WAAW;IAmBZ,YAAY,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI;IAM9C,cAAc,IAAI,IAAI;IAItB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAQzC,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAI3D,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;yCA9JtD,uCAAuC;2CAAvC,uCAAuC;CAiKnD"}