@memberjunction/ng-dashboards 3.2.0 → 3.4.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 (402) hide show
  1. package/dist/AI/components/agents/agent-configuration.component.d.ts +24 -0
  2. package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
  3. package/dist/AI/components/agents/agent-configuration.component.js +198 -111
  4. package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
  5. package/dist/AI/components/models/model-management.component.d.ts +23 -0
  6. package/dist/AI/components/models/model-management.component.d.ts.map +1 -1
  7. package/dist/AI/components/models/model-management.component.js +189 -83
  8. package/dist/AI/components/models/model-management.component.js.map +1 -1
  9. package/dist/AI/components/prompts/prompt-management.component.d.ts +23 -0
  10. package/dist/AI/components/prompts/prompt-management.component.d.ts.map +1 -1
  11. package/dist/AI/components/prompts/prompt-management.component.js +135 -30
  12. package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
  13. package/dist/APIKeys/api-applications-panel.component.d.ts +169 -0
  14. package/dist/APIKeys/api-applications-panel.component.d.ts.map +1 -0
  15. package/dist/APIKeys/api-applications-panel.component.js +1058 -0
  16. package/dist/APIKeys/api-applications-panel.component.js.map +1 -0
  17. package/dist/APIKeys/api-key-create-dialog.component.d.ts +125 -0
  18. package/dist/APIKeys/api-key-create-dialog.component.d.ts.map +1 -0
  19. package/dist/APIKeys/api-key-create-dialog.component.js +768 -0
  20. package/dist/APIKeys/api-key-create-dialog.component.js.map +1 -0
  21. package/dist/APIKeys/api-key-edit-panel.component.d.ts +149 -0
  22. package/dist/APIKeys/api-key-edit-panel.component.d.ts.map +1 -0
  23. package/dist/APIKeys/api-key-edit-panel.component.js +1074 -0
  24. package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -0
  25. package/dist/APIKeys/api-key-list.component.d.ts +131 -0
  26. package/dist/APIKeys/api-key-list.component.d.ts.map +1 -0
  27. package/dist/APIKeys/api-key-list.component.js +818 -0
  28. package/dist/APIKeys/api-key-list.component.js.map +1 -0
  29. package/dist/APIKeys/api-keys-resource.component.d.ts +211 -0
  30. package/dist/APIKeys/api-keys-resource.component.d.ts.map +1 -0
  31. package/dist/APIKeys/api-keys-resource.component.js +1150 -0
  32. package/dist/APIKeys/api-keys-resource.component.js.map +1 -0
  33. package/dist/APIKeys/api-scopes-panel.component.d.ts +98 -0
  34. package/dist/APIKeys/api-scopes-panel.component.d.ts.map +1 -0
  35. package/dist/APIKeys/api-scopes-panel.component.js +652 -0
  36. package/dist/APIKeys/api-scopes-panel.component.js.map +1 -0
  37. package/dist/APIKeys/api-usage-panel.component.d.ts +174 -0
  38. package/dist/APIKeys/api-usage-panel.component.d.ts.map +1 -0
  39. package/dist/APIKeys/api-usage-panel.component.js +1013 -0
  40. package/dist/APIKeys/api-usage-panel.component.js.map +1 -0
  41. package/dist/APIKeys/index.d.ts +7 -0
  42. package/dist/APIKeys/index.d.ts.map +1 -0
  43. package/dist/APIKeys/index.js +8 -0
  44. package/dist/APIKeys/index.js.map +1 -0
  45. package/dist/Actions/components/explorer/action-breadcrumb.component.d.ts +22 -0
  46. package/dist/Actions/components/explorer/action-breadcrumb.component.d.ts.map +1 -0
  47. package/dist/Actions/components/explorer/action-breadcrumb.component.js +139 -0
  48. package/dist/Actions/components/explorer/action-breadcrumb.component.js.map +1 -0
  49. package/dist/Actions/components/explorer/action-card.component.d.ts +39 -0
  50. package/dist/Actions/components/explorer/action-card.component.d.ts.map +1 -0
  51. package/dist/Actions/components/explorer/action-card.component.js +410 -0
  52. package/dist/Actions/components/explorer/action-card.component.js.map +1 -0
  53. package/dist/Actions/components/explorer/action-explorer.component.d.ts +62 -0
  54. package/dist/Actions/components/explorer/action-explorer.component.d.ts.map +1 -0
  55. package/dist/Actions/components/explorer/action-explorer.component.js +527 -0
  56. package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -0
  57. package/dist/Actions/components/explorer/action-list-item.component.d.ts +24 -0
  58. package/dist/Actions/components/explorer/action-list-item.component.d.ts.map +1 -0
  59. package/dist/Actions/components/explorer/action-list-item.component.js +210 -0
  60. package/dist/Actions/components/explorer/action-list-item.component.js.map +1 -0
  61. package/dist/Actions/components/explorer/action-toolbar.component.d.ts +63 -0
  62. package/dist/Actions/components/explorer/action-toolbar.component.d.ts.map +1 -0
  63. package/dist/Actions/components/explorer/action-toolbar.component.js +483 -0
  64. package/dist/Actions/components/explorer/action-toolbar.component.js.map +1 -0
  65. package/dist/Actions/components/explorer/action-tree-panel.component.d.ts +57 -0
  66. package/dist/Actions/components/explorer/action-tree-panel.component.d.ts.map +1 -0
  67. package/dist/Actions/components/explorer/action-tree-panel.component.js +454 -0
  68. package/dist/Actions/components/explorer/action-tree-panel.component.js.map +1 -0
  69. package/dist/Actions/components/explorer/index.d.ts +10 -0
  70. package/dist/Actions/components/explorer/index.d.ts.map +1 -0
  71. package/dist/Actions/components/explorer/index.js +14 -0
  72. package/dist/Actions/components/explorer/index.js.map +1 -0
  73. package/dist/Actions/components/explorer/new-action-panel.component.d.ts +49 -0
  74. package/dist/Actions/components/explorer/new-action-panel.component.d.ts.map +1 -0
  75. package/dist/Actions/components/explorer/new-action-panel.component.js +359 -0
  76. package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -0
  77. package/dist/Actions/components/explorer/new-category-panel.component.d.ts +37 -0
  78. package/dist/Actions/components/explorer/new-category-panel.component.d.ts.map +1 -0
  79. package/dist/Actions/components/explorer/new-category-panel.component.js +282 -0
  80. package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -0
  81. package/dist/Actions/index.d.ts +3 -0
  82. package/dist/Actions/index.d.ts.map +1 -1
  83. package/dist/Actions/index.js +5 -0
  84. package/dist/Actions/index.js.map +1 -1
  85. package/dist/Actions/services/action-explorer-state.service.d.ts +104 -0
  86. package/dist/Actions/services/action-explorer-state.service.d.ts.map +1 -0
  87. package/dist/Actions/services/action-explorer-state.service.js +352 -0
  88. package/dist/Actions/services/action-explorer-state.service.js.map +1 -0
  89. package/dist/Communication/communication-dashboard.component.d.ts +2 -6
  90. package/dist/Communication/communication-dashboard.component.d.ts.map +1 -1
  91. package/dist/Communication/communication-dashboard.component.js +142 -93
  92. package/dist/Communication/communication-dashboard.component.js.map +1 -1
  93. package/dist/Communication/communication-logs-resource.component.d.ts +10 -4
  94. package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
  95. package/dist/Communication/communication-logs-resource.component.js +253 -121
  96. package/dist/Communication/communication-logs-resource.component.js.map +1 -1
  97. package/dist/Communication/communication-monitor-resource.component.d.ts +38 -3
  98. package/dist/Communication/communication-monitor-resource.component.d.ts.map +1 -1
  99. package/dist/Communication/communication-monitor-resource.component.js +431 -157
  100. package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
  101. package/dist/Communication/communication-providers-resource.component.d.ts +16 -5
  102. package/dist/Communication/communication-providers-resource.component.d.ts.map +1 -1
  103. package/dist/Communication/communication-providers-resource.component.js +229 -118
  104. package/dist/Communication/communication-providers-resource.component.js.map +1 -1
  105. package/dist/Communication/communication-runs-resource.component.d.ts +4 -2
  106. package/dist/Communication/communication-runs-resource.component.d.ts.map +1 -1
  107. package/dist/Communication/communication-runs-resource.component.js +155 -149
  108. package/dist/Communication/communication-runs-resource.component.js.map +1 -1
  109. package/dist/Communication/communication-templates-resource.component.d.ts +43 -0
  110. package/dist/Communication/communication-templates-resource.component.d.ts.map +1 -0
  111. package/dist/Communication/communication-templates-resource.component.js +371 -0
  112. package/dist/Communication/communication-templates-resource.component.js.map +1 -0
  113. package/dist/ComponentStudio/component-studio-dashboard.component.d.ts +69 -267
  114. package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
  115. package/dist/ComponentStudio/component-studio-dashboard.component.js +698 -1802
  116. package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
  117. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts +68 -0
  118. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts.map +1 -0
  119. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +401 -0
  120. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js.map +1 -0
  121. package/dist/ComponentStudio/components/browser/component-browser.component.d.ts +44 -0
  122. package/dist/ComponentStudio/components/browser/component-browser.component.d.ts.map +1 -0
  123. package/dist/ComponentStudio/components/browser/component-browser.component.js +636 -0
  124. package/dist/ComponentStudio/components/browser/component-browser.component.js.map +1 -0
  125. package/dist/ComponentStudio/components/editors/code-editor-panel.component.d.ts +35 -0
  126. package/dist/ComponentStudio/components/editors/code-editor-panel.component.d.ts.map +1 -0
  127. package/dist/ComponentStudio/components/editors/code-editor-panel.component.js +380 -0
  128. package/dist/ComponentStudio/components/editors/code-editor-panel.component.js.map +1 -0
  129. package/dist/ComponentStudio/components/editors/data-requirements-editor.component.d.ts +24 -0
  130. package/dist/ComponentStudio/components/editors/data-requirements-editor.component.d.ts.map +1 -0
  131. package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +221 -0
  132. package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js.map +1 -0
  133. package/dist/ComponentStudio/components/editors/requirements-editor.component.d.ts +28 -0
  134. package/dist/ComponentStudio/components/editors/requirements-editor.component.d.ts.map +1 -0
  135. package/dist/ComponentStudio/components/editors/requirements-editor.component.js +263 -0
  136. package/dist/ComponentStudio/components/editors/requirements-editor.component.js.map +1 -0
  137. package/dist/ComponentStudio/components/editors/spec-editor.component.d.ts +34 -0
  138. package/dist/ComponentStudio/components/editors/spec-editor.component.d.ts.map +1 -0
  139. package/dist/ComponentStudio/components/editors/spec-editor.component.js +307 -0
  140. package/dist/ComponentStudio/components/editors/spec-editor.component.js.map +1 -0
  141. package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.d.ts +29 -0
  142. package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.d.ts.map +1 -0
  143. package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js +159 -0
  144. package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js.map +1 -0
  145. package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.d.ts +20 -0
  146. package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.d.ts.map +1 -0
  147. package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js +192 -0
  148. package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js.map +1 -0
  149. package/dist/ComponentStudio/components/workspace/component-preview.component.d.ts +57 -0
  150. package/dist/ComponentStudio/components/workspace/component-preview.component.d.ts.map +1 -0
  151. package/dist/ComponentStudio/components/workspace/component-preview.component.js +342 -0
  152. package/dist/ComponentStudio/components/workspace/component-preview.component.js.map +1 -0
  153. package/dist/ComponentStudio/components/workspace/editor-tabs.component.d.ts +15 -0
  154. package/dist/ComponentStudio/components/workspace/editor-tabs.component.d.ts.map +1 -0
  155. package/dist/ComponentStudio/components/workspace/editor-tabs.component.js +144 -0
  156. package/dist/ComponentStudio/components/workspace/editor-tabs.component.js.map +1 -0
  157. package/dist/ComponentStudio/services/component-studio-state.service.d.ts +203 -0
  158. package/dist/ComponentStudio/services/component-studio-state.service.d.ts.map +1 -0
  159. package/dist/ComponentStudio/services/component-studio-state.service.js +651 -0
  160. package/dist/ComponentStudio/services/component-studio-state.service.js.map +1 -0
  161. package/dist/ComponentStudio/services/component-version.service.d.ts +120 -0
  162. package/dist/ComponentStudio/services/component-version.service.d.ts.map +1 -0
  163. package/dist/ComponentStudio/services/component-version.service.js +394 -0
  164. package/dist/ComponentStudio/services/component-version.service.js.map +1 -0
  165. package/dist/Credentials/components/credentials-categories-resource.component.d.ts +1 -1
  166. package/dist/Credentials/components/credentials-categories-resource.component.d.ts.map +1 -1
  167. package/dist/Credentials/components/credentials-categories-resource.component.js +1 -1
  168. package/dist/Credentials/components/credentials-list-resource.component.d.ts +1 -1
  169. package/dist/Credentials/components/credentials-list-resource.component.d.ts.map +1 -1
  170. package/dist/Credentials/components/credentials-list-resource.component.js +1 -1
  171. package/dist/Credentials/components/credentials-types-resource.component.d.ts +1 -1
  172. package/dist/Credentials/components/credentials-types-resource.component.d.ts.map +1 -1
  173. package/dist/Credentials/components/credentials-types-resource.component.js +1 -1
  174. package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
  175. package/dist/DashboardBrowser/dashboard-browser-resource.component.js +4 -2
  176. package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
  177. package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts +2 -2
  178. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +3 -3
  179. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  180. package/dist/DataExplorer/data-explorer-dashboard.component.js +22 -6
  181. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  182. package/dist/EntityAdmin/entity-admin-dashboard.component.js +2 -2
  183. package/dist/MCP/components/mcp-connection-dialog.component.d.ts +72 -0
  184. package/dist/MCP/components/mcp-connection-dialog.component.d.ts.map +1 -0
  185. package/dist/MCP/components/mcp-connection-dialog.component.js +529 -0
  186. package/dist/MCP/components/mcp-connection-dialog.component.js.map +1 -0
  187. package/dist/MCP/components/mcp-log-detail-panel.component.d.ts +77 -0
  188. package/dist/MCP/components/mcp-log-detail-panel.component.d.ts.map +1 -0
  189. package/dist/MCP/components/mcp-log-detail-panel.component.js +535 -0
  190. package/dist/MCP/components/mcp-log-detail-panel.component.js.map +1 -0
  191. package/dist/MCP/components/mcp-server-dialog.component.d.ts +77 -0
  192. package/dist/MCP/components/mcp-server-dialog.component.d.ts.map +1 -0
  193. package/dist/MCP/components/mcp-server-dialog.component.js +437 -0
  194. package/dist/MCP/components/mcp-server-dialog.component.js.map +1 -0
  195. package/dist/MCP/components/mcp-test-tool-dialog.component.d.ts +271 -0
  196. package/dist/MCP/components/mcp-test-tool-dialog.component.d.ts.map +1 -0
  197. package/dist/MCP/components/mcp-test-tool-dialog.component.js +1300 -0
  198. package/dist/MCP/components/mcp-test-tool-dialog.component.js.map +1 -0
  199. package/dist/MCP/index.d.ts +11 -0
  200. package/dist/MCP/index.d.ts.map +1 -0
  201. package/dist/MCP/index.js +15 -0
  202. package/dist/MCP/index.js.map +1 -0
  203. package/dist/MCP/mcp-dashboard.component.d.ts +409 -0
  204. package/dist/MCP/mcp-dashboard.component.d.ts.map +1 -0
  205. package/dist/MCP/mcp-dashboard.component.js +2486 -0
  206. package/dist/MCP/mcp-dashboard.component.js.map +1 -0
  207. package/dist/MCP/mcp-resource.component.d.ts +20 -0
  208. package/dist/MCP/mcp-resource.component.d.ts.map +1 -0
  209. package/dist/MCP/mcp-resource.component.js +55 -0
  210. package/dist/MCP/mcp-resource.component.js.map +1 -0
  211. package/dist/MCP/mcp.module.d.ts +27 -0
  212. package/dist/MCP/mcp.module.d.ts.map +1 -0
  213. package/dist/MCP/mcp.module.js +122 -0
  214. package/dist/MCP/mcp.module.js.map +1 -0
  215. package/dist/MCP/services/mcp-tools.service.d.ts +109 -0
  216. package/dist/MCP/services/mcp-tools.service.d.ts.map +1 -0
  217. package/dist/MCP/services/mcp-tools.service.js +222 -0
  218. package/dist/MCP/services/mcp-tools.service.js.map +1 -0
  219. package/dist/Scheduling/components/index.d.ts +5 -8
  220. package/dist/Scheduling/components/index.d.ts.map +1 -1
  221. package/dist/Scheduling/components/index.js +6 -9
  222. package/dist/Scheduling/components/index.js.map +1 -1
  223. package/dist/Scheduling/components/job-slideout.component.d.ts +45 -0
  224. package/dist/Scheduling/components/job-slideout.component.d.ts.map +1 -0
  225. package/dist/Scheduling/components/job-slideout.component.js +458 -0
  226. package/dist/Scheduling/components/job-slideout.component.js.map +1 -0
  227. package/dist/Scheduling/components/scheduling-activity-resource.component.d.ts +19 -0
  228. package/dist/Scheduling/components/scheduling-activity-resource.component.d.ts.map +1 -0
  229. package/dist/Scheduling/components/scheduling-activity-resource.component.js +51 -0
  230. package/dist/Scheduling/components/scheduling-activity-resource.component.js.map +1 -0
  231. package/dist/Scheduling/components/scheduling-activity.component.d.ts +71 -0
  232. package/dist/Scheduling/components/scheduling-activity.component.d.ts.map +1 -0
  233. package/dist/Scheduling/components/scheduling-activity.component.js +714 -0
  234. package/dist/Scheduling/components/scheduling-activity.component.js.map +1 -0
  235. package/dist/Scheduling/components/scheduling-jobs-resource.component.d.ts +3 -4
  236. package/dist/Scheduling/components/scheduling-jobs-resource.component.d.ts.map +1 -1
  237. package/dist/Scheduling/components/scheduling-jobs-resource.component.js +3 -7
  238. package/dist/Scheduling/components/scheduling-jobs-resource.component.js.map +1 -1
  239. package/dist/Scheduling/components/scheduling-jobs.component.d.ts +52 -34
  240. package/dist/Scheduling/components/scheduling-jobs.component.d.ts.map +1 -1
  241. package/dist/Scheduling/components/scheduling-jobs.component.js +446 -261
  242. package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
  243. package/dist/Scheduling/components/scheduling-overview-resource.component.d.ts +19 -0
  244. package/dist/Scheduling/components/scheduling-overview-resource.component.d.ts.map +1 -0
  245. package/dist/Scheduling/components/scheduling-overview-resource.component.js +51 -0
  246. package/dist/Scheduling/components/scheduling-overview-resource.component.js.map +1 -0
  247. package/dist/Scheduling/components/scheduling-overview.component.d.ts +43 -0
  248. package/dist/Scheduling/components/scheduling-overview.component.d.ts.map +1 -0
  249. package/dist/Scheduling/components/scheduling-overview.component.js +595 -0
  250. package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -0
  251. package/dist/Scheduling/scheduling-dashboard.component.d.ts +22 -32
  252. package/dist/Scheduling/scheduling-dashboard.component.d.ts.map +1 -1
  253. package/dist/Scheduling/scheduling-dashboard.component.js +175 -169
  254. package/dist/Scheduling/scheduling-dashboard.component.js.map +1 -1
  255. package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts +49 -6
  256. package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts.map +1 -1
  257. package/dist/Scheduling/services/scheduling-instrumentation.service.js +218 -149
  258. package/dist/Scheduling/services/scheduling-instrumentation.service.js.map +1 -1
  259. package/dist/Testing/components/index.d.ts +7 -8
  260. package/dist/Testing/components/index.d.ts.map +1 -1
  261. package/dist/Testing/components/index.js +8 -9
  262. package/dist/Testing/components/index.js.map +1 -1
  263. package/dist/Testing/components/testing-analytics-resource.component.d.ts +0 -4
  264. package/dist/Testing/components/testing-analytics-resource.component.d.ts.map +1 -1
  265. package/dist/Testing/components/testing-analytics-resource.component.js +1 -7
  266. package/dist/Testing/components/testing-analytics-resource.component.js.map +1 -1
  267. package/dist/Testing/components/testing-analytics.component.d.ts +52 -37
  268. package/dist/Testing/components/testing-analytics.component.d.ts.map +1 -1
  269. package/dist/Testing/components/testing-analytics.component.js +1023 -569
  270. package/dist/Testing/components/testing-analytics.component.js.map +1 -1
  271. package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts +16 -0
  272. package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts.map +1 -0
  273. package/dist/Testing/components/testing-dashboard-tab-resource.component.js +47 -0
  274. package/dist/Testing/components/testing-dashboard-tab-resource.component.js.map +1 -0
  275. package/dist/Testing/components/testing-dashboard-tab.component.d.ts +57 -0
  276. package/dist/Testing/components/testing-dashboard-tab.component.d.ts.map +1 -0
  277. package/dist/Testing/components/testing-dashboard-tab.component.js +649 -0
  278. package/dist/Testing/components/testing-dashboard-tab.component.js.map +1 -0
  279. package/dist/{Scheduling/components/scheduling-types-resource.component.d.ts → Testing/components/testing-explorer-resource.component.d.ts} +5 -9
  280. package/dist/Testing/components/testing-explorer-resource.component.d.ts.map +1 -0
  281. package/dist/Testing/components/testing-explorer-resource.component.js +47 -0
  282. package/dist/Testing/components/testing-explorer-resource.component.js.map +1 -0
  283. package/dist/Testing/components/testing-explorer.component.d.ts +193 -0
  284. package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -0
  285. package/dist/Testing/components/testing-explorer.component.js +2212 -0
  286. package/dist/Testing/components/testing-explorer.component.js.map +1 -0
  287. package/dist/Testing/components/testing-review-resource.component.d.ts +16 -0
  288. package/dist/Testing/components/testing-review-resource.component.d.ts.map +1 -0
  289. package/dist/Testing/components/testing-review-resource.component.js +47 -0
  290. package/dist/Testing/components/testing-review-resource.component.js.map +1 -0
  291. package/dist/Testing/components/testing-review.component.d.ts +60 -0
  292. package/dist/Testing/components/testing-review.component.d.ts.map +1 -0
  293. package/dist/Testing/components/testing-review.component.js +985 -0
  294. package/dist/Testing/components/testing-review.component.js.map +1 -0
  295. package/dist/Testing/components/testing-runs-resource.component.d.ts +16 -0
  296. package/dist/Testing/components/testing-runs-resource.component.d.ts.map +1 -0
  297. package/dist/Testing/components/testing-runs-resource.component.js +47 -0
  298. package/dist/Testing/components/testing-runs-resource.component.js.map +1 -0
  299. package/dist/Testing/components/testing-runs.component.d.ts +82 -0
  300. package/dist/Testing/components/testing-runs.component.d.ts.map +1 -0
  301. package/dist/Testing/components/testing-runs.component.js +1067 -0
  302. package/dist/Testing/components/testing-runs.component.js.map +1 -0
  303. package/dist/Testing/testing-dashboard.component.d.ts +12 -15
  304. package/dist/Testing/testing-dashboard.component.d.ts.map +1 -1
  305. package/dist/Testing/testing-dashboard.component.js +46 -68
  306. package/dist/Testing/testing-dashboard.component.js.map +1 -1
  307. package/dist/module.d.ts +121 -97
  308. package/dist/module.d.ts.map +1 -1
  309. package/dist/module.js +227 -95
  310. package/dist/module.js.map +1 -1
  311. package/dist/public-api.d.ts +12 -3
  312. package/dist/public-api.d.ts.map +1 -1
  313. package/dist/public-api.js +47 -16
  314. package/dist/public-api.js.map +1 -1
  315. package/dist/shared/pipes/highlight-search.pipe.d.ts +17 -0
  316. package/dist/shared/pipes/highlight-search.pipe.d.ts.map +1 -0
  317. package/dist/shared/pipes/highlight-search.pipe.js +40 -0
  318. package/dist/shared/pipes/highlight-search.pipe.js.map +1 -0
  319. package/dist/shared/pipes/index.d.ts +2 -0
  320. package/dist/shared/pipes/index.d.ts.map +1 -0
  321. package/dist/shared/pipes/index.js +2 -0
  322. package/dist/shared/pipes/index.js.map +1 -0
  323. package/dist/shared/shared-pipes.module.d.ts +11 -0
  324. package/dist/shared/shared-pipes.module.d.ts.map +1 -0
  325. package/dist/shared/shared-pipes.module.js +24 -0
  326. package/dist/shared/shared-pipes.module.js.map +1 -0
  327. package/package.json +39 -32
  328. package/dist/Credentials/components/credential-category-edit-panel.component.d.ts +0 -44
  329. package/dist/Credentials/components/credential-category-edit-panel.component.d.ts.map +0 -1
  330. package/dist/Credentials/components/credential-category-edit-panel.component.js +0 -456
  331. package/dist/Credentials/components/credential-category-edit-panel.component.js.map +0 -1
  332. package/dist/Credentials/components/credential-edit-panel.component.d.ts +0 -70
  333. package/dist/Credentials/components/credential-edit-panel.component.d.ts.map +0 -1
  334. package/dist/Credentials/components/credential-edit-panel.component.js +0 -694
  335. package/dist/Credentials/components/credential-edit-panel.component.js.map +0 -1
  336. package/dist/Credentials/components/credential-type-edit-panel.component.d.ts +0 -56
  337. package/dist/Credentials/components/credential-type-edit-panel.component.d.ts.map +0 -1
  338. package/dist/Credentials/components/credential-type-edit-panel.component.js +0 -563
  339. package/dist/Credentials/components/credential-type-edit-panel.component.js.map +0 -1
  340. package/dist/Scheduling/components/scheduling-health-resource.component.d.ts +0 -20
  341. package/dist/Scheduling/components/scheduling-health-resource.component.d.ts.map +0 -1
  342. package/dist/Scheduling/components/scheduling-health-resource.component.js +0 -55
  343. package/dist/Scheduling/components/scheduling-health-resource.component.js.map +0 -1
  344. package/dist/Scheduling/components/scheduling-health.component.d.ts +0 -30
  345. package/dist/Scheduling/components/scheduling-health.component.d.ts.map +0 -1
  346. package/dist/Scheduling/components/scheduling-health.component.js +0 -315
  347. package/dist/Scheduling/components/scheduling-health.component.js.map +0 -1
  348. package/dist/Scheduling/components/scheduling-history-resource.component.d.ts +0 -20
  349. package/dist/Scheduling/components/scheduling-history-resource.component.d.ts.map +0 -1
  350. package/dist/Scheduling/components/scheduling-history-resource.component.js +0 -55
  351. package/dist/Scheduling/components/scheduling-history-resource.component.js.map +0 -1
  352. package/dist/Scheduling/components/scheduling-history.component.d.ts +0 -48
  353. package/dist/Scheduling/components/scheduling-history.component.d.ts.map +0 -1
  354. package/dist/Scheduling/components/scheduling-history.component.js +0 -377
  355. package/dist/Scheduling/components/scheduling-history.component.js.map +0 -1
  356. package/dist/Scheduling/components/scheduling-monitor-resource.component.d.ts +0 -20
  357. package/dist/Scheduling/components/scheduling-monitor-resource.component.d.ts.map +0 -1
  358. package/dist/Scheduling/components/scheduling-monitor-resource.component.js +0 -55
  359. package/dist/Scheduling/components/scheduling-monitor-resource.component.js.map +0 -1
  360. package/dist/Scheduling/components/scheduling-monitoring.component.d.ts +0 -37
  361. package/dist/Scheduling/components/scheduling-monitoring.component.d.ts.map +0 -1
  362. package/dist/Scheduling/components/scheduling-monitoring.component.js +0 -488
  363. package/dist/Scheduling/components/scheduling-monitoring.component.js.map +0 -1
  364. package/dist/Scheduling/components/scheduling-types-resource.component.d.ts.map +0 -1
  365. package/dist/Scheduling/components/scheduling-types-resource.component.js +0 -55
  366. package/dist/Scheduling/components/scheduling-types-resource.component.js.map +0 -1
  367. package/dist/Scheduling/components/scheduling-types.component.d.ts +0 -22
  368. package/dist/Scheduling/components/scheduling-types.component.d.ts.map +0 -1
  369. package/dist/Scheduling/components/scheduling-types.component.js +0 -165
  370. package/dist/Scheduling/components/scheduling-types.component.js.map +0 -1
  371. package/dist/Testing/components/testing-execution-resource.component.d.ts +0 -20
  372. package/dist/Testing/components/testing-execution-resource.component.d.ts.map +0 -1
  373. package/dist/Testing/components/testing-execution-resource.component.js +0 -55
  374. package/dist/Testing/components/testing-execution-resource.component.js.map +0 -1
  375. package/dist/Testing/components/testing-execution.component.d.ts +0 -71
  376. package/dist/Testing/components/testing-execution.component.d.ts.map +0 -1
  377. package/dist/Testing/components/testing-execution.component.js +0 -845
  378. package/dist/Testing/components/testing-execution.component.js.map +0 -1
  379. package/dist/Testing/components/testing-feedback-resource.component.d.ts +0 -20
  380. package/dist/Testing/components/testing-feedback-resource.component.d.ts.map +0 -1
  381. package/dist/Testing/components/testing-feedback-resource.component.js +0 -55
  382. package/dist/Testing/components/testing-feedback-resource.component.js.map +0 -1
  383. package/dist/Testing/components/testing-feedback.component.d.ts +0 -111
  384. package/dist/Testing/components/testing-feedback.component.d.ts.map +0 -1
  385. package/dist/Testing/components/testing-feedback.component.js +0 -1486
  386. package/dist/Testing/components/testing-feedback.component.js.map +0 -1
  387. package/dist/Testing/components/testing-overview-resource.component.d.ts +0 -20
  388. package/dist/Testing/components/testing-overview-resource.component.d.ts.map +0 -1
  389. package/dist/Testing/components/testing-overview-resource.component.js +0 -55
  390. package/dist/Testing/components/testing-overview-resource.component.js.map +0 -1
  391. package/dist/Testing/components/testing-overview.component.d.ts +0 -30
  392. package/dist/Testing/components/testing-overview.component.d.ts.map +0 -1
  393. package/dist/Testing/components/testing-overview.component.js +0 -361
  394. package/dist/Testing/components/testing-overview.component.js.map +0 -1
  395. package/dist/Testing/components/testing-version-comparison.component.d.ts +0 -62
  396. package/dist/Testing/components/testing-version-comparison.component.d.ts.map +0 -1
  397. package/dist/Testing/components/testing-version-comparison.component.js +0 -815
  398. package/dist/Testing/components/testing-version-comparison.component.js.map +0 -1
  399. package/dist/Testing/components/testing-version-resource.component.d.ts +0 -20
  400. package/dist/Testing/components/testing-version-resource.component.d.ts.map +0 -1
  401. package/dist/Testing/components/testing-version-resource.component.js +0 -55
  402. package/dist/Testing/components/testing-version-resource.component.js.map +0 -1
@@ -0,0 +1,649 @@
1
+ import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';
2
+ import { Subject } from 'rxjs';
3
+ import { takeUntil, map } from 'rxjs/operators';
4
+ import { CompositeKey } from '@memberjunction/core';
5
+ import { SharedService } from '@memberjunction/ng-shared';
6
+ import { TestEngineBase } from '@memberjunction/testing-engine-base';
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "../services/testing-instrumentation.service";
9
+ import * as i2 from "@memberjunction/ng-testing";
10
+ import * as i3 from "@memberjunction/ng-shared-generic";
11
+ import * as i4 from "../../AI/components/widgets/kpi-card.component";
12
+ import * as i5 from "@angular/common";
13
+ const _forTrack0 = ($index, $item) => $item.title;
14
+ const _forTrack1 = ($index, $item) => $item.id;
15
+ function TestingDashboardTabComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
16
+ i0.ɵɵelementStart(0, "div", 0);
17
+ i0.ɵɵelement(1, "mj-loading", 2);
18
+ i0.ɵɵelementEnd();
19
+ } }
20
+ function TestingDashboardTabComponent_Conditional_1_For_10_Template(rf, ctx) { if (rf & 1) {
21
+ i0.ɵɵelement(0, "app-kpi-card", 9);
22
+ } if (rf & 2) {
23
+ const kpi_r3 = ctx.$implicit;
24
+ i0.ɵɵproperty("data", kpi_r3);
25
+ } }
26
+ function TestingDashboardTabComponent_Conditional_1_Conditional_13_Template(rf, ctx) { if (rf & 1) {
27
+ i0.ɵɵelement(0, "span", 28);
28
+ i0.ɵɵelementStart(1, "h3");
29
+ i0.ɵɵtext(2);
30
+ i0.ɵɵelementEnd();
31
+ } if (rf & 2) {
32
+ const ctx_r1 = i0.ɵɵnextContext(2);
33
+ i0.ɵɵadvance(2);
34
+ i0.ɵɵtextInterpolate2("", ctx_r1.RunningTests.length, " test", ctx_r1.RunningTests.length === 1 ? "" : "s", " running");
35
+ } }
36
+ function TestingDashboardTabComponent_Conditional_1_Conditional_14_Template(rf, ctx) { if (rf & 1) {
37
+ i0.ɵɵelement(0, "i", 29);
38
+ i0.ɵɵelementStart(1, "h3");
39
+ i0.ɵɵtext(2, "No tests currently running");
40
+ i0.ɵɵelementEnd();
41
+ } }
42
+ function TestingDashboardTabComponent_Conditional_1_Conditional_15_For_2_Template(rf, ctx) { if (rf & 1) {
43
+ i0.ɵɵelementStart(0, "div", 30)(1, "div", 31);
44
+ i0.ɵɵtext(2);
45
+ i0.ɵɵelementEnd();
46
+ i0.ɵɵelementStart(3, "div", 32)(4, "span", 33);
47
+ i0.ɵɵtext(5);
48
+ i0.ɵɵelementEnd();
49
+ i0.ɵɵelementStart(6, "span", 34);
50
+ i0.ɵɵelement(7, "span", 35);
51
+ i0.ɵɵelementEnd()()();
52
+ } if (rf & 2) {
53
+ const run_r4 = ctx.$implicit;
54
+ const ctx_r1 = i0.ɵɵnextContext(3);
55
+ i0.ɵɵadvance(2);
56
+ i0.ɵɵtextInterpolate(run_r4.testName);
57
+ i0.ɵɵadvance(3);
58
+ i0.ɵɵtextInterpolate(ctx_r1.FormatDuration(run_r4.duration));
59
+ } }
60
+ function TestingDashboardTabComponent_Conditional_1_Conditional_15_Template(rf, ctx) { if (rf & 1) {
61
+ i0.ɵɵelementStart(0, "div", 12);
62
+ i0.ɵɵrepeaterCreate(1, TestingDashboardTabComponent_Conditional_1_Conditional_15_For_2_Template, 8, 2, "div", 30, _forTrack1);
63
+ i0.ɵɵelementEnd();
64
+ } if (rf & 2) {
65
+ const ctx_r1 = i0.ɵɵnextContext(2);
66
+ i0.ɵɵadvance();
67
+ i0.ɵɵrepeater(ctx_r1.RunningTests);
68
+ } }
69
+ function TestingDashboardTabComponent_Conditional_1_For_24_Template(rf, ctx) { if (rf & 1) {
70
+ const _r5 = i0.ɵɵgetCurrentView();
71
+ i0.ɵɵelementStart(0, "div", 36);
72
+ i0.ɵɵlistener("click", function TestingDashboardTabComponent_Conditional_1_For_24_Template_div_click_0_listener() { const run_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnOpenRun(run_r6)); });
73
+ i0.ɵɵelementStart(1, "div", 37)(2, "span", 38);
74
+ i0.ɵɵtext(3);
75
+ i0.ɵɵelementEnd();
76
+ i0.ɵɵelementStart(4, "span", 39);
77
+ i0.ɵɵtext(5);
78
+ i0.ɵɵelementEnd()();
79
+ i0.ɵɵelementStart(6, "div", 40);
80
+ i0.ɵɵelement(7, "app-test-status-badge", 41)(8, "app-score-indicator", 42);
81
+ i0.ɵɵelementStart(9, "span", 43);
82
+ i0.ɵɵtext(10);
83
+ i0.ɵɵelementEnd();
84
+ i0.ɵɵelement(11, "app-cost-display", 44);
85
+ i0.ɵɵelementEnd()();
86
+ } if (rf & 2) {
87
+ const run_r6 = ctx.$implicit;
88
+ const ctx_r1 = i0.ɵɵnextContext(2);
89
+ i0.ɵɵadvance(3);
90
+ i0.ɵɵtextInterpolate(run_r6.testName);
91
+ i0.ɵɵadvance(2);
92
+ i0.ɵɵtextInterpolate(ctx_r1.FormatTimestamp(run_r6.runDateTime));
93
+ i0.ɵɵadvance(2);
94
+ i0.ɵɵproperty("status", run_r6.status);
95
+ i0.ɵɵadvance();
96
+ i0.ɵɵproperty("score", run_r6.score)("showBar", true);
97
+ i0.ɵɵadvance(2);
98
+ i0.ɵɵtextInterpolate(ctx_r1.FormatDuration(run_r6.duration));
99
+ i0.ɵɵadvance();
100
+ i0.ɵɵproperty("cost", run_r6.cost);
101
+ } }
102
+ function TestingDashboardTabComponent_Conditional_1_ForEmpty_25_Template(rf, ctx) { if (rf & 1) {
103
+ i0.ɵɵelementStart(0, "div", 18);
104
+ i0.ɵɵtext(1, "No completed test runs found");
105
+ i0.ɵɵelementEnd();
106
+ } }
107
+ function TestingDashboardTabComponent_Conditional_1_For_34_Template(rf, ctx) { if (rf & 1) {
108
+ i0.ɵɵelementStart(0, "div", 23)(1, "div", 45)(2, "span", 46);
109
+ i0.ɵɵtext(3);
110
+ i0.ɵɵelementEnd();
111
+ i0.ɵɵelementStart(4, "span", 47);
112
+ i0.ɵɵtext(5);
113
+ i0.ɵɵelementEnd()();
114
+ i0.ɵɵelementStart(6, "div", 48)(7, "div", 49);
115
+ i0.ɵɵelement(8, "div", 50);
116
+ i0.ɵɵelementEnd();
117
+ i0.ɵɵelementStart(9, "span", 51);
118
+ i0.ɵɵtext(10);
119
+ i0.ɵɵpipe(11, "number");
120
+ i0.ɵɵelementEnd()()();
121
+ } if (rf & 2) {
122
+ const suite_r7 = ctx.$implicit;
123
+ const ctx_r1 = i0.ɵɵnextContext(2);
124
+ i0.ɵɵadvance(3);
125
+ i0.ɵɵtextInterpolate(suite_r7.name);
126
+ i0.ɵɵadvance(2);
127
+ i0.ɵɵtextInterpolate1("", suite_r7.testCount, " tests");
128
+ i0.ɵɵadvance(3);
129
+ i0.ɵɵstyleProp("width", suite_r7.passRate, "%")("background", ctx_r1.GetPassRateColor(suite_r7.passRate));
130
+ i0.ɵɵadvance();
131
+ i0.ɵɵstyleProp("color", ctx_r1.GetPassRateColor(suite_r7.passRate));
132
+ i0.ɵɵadvance();
133
+ i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind2(11, 9, suite_r7.passRate, "1.0-0"), "% ");
134
+ } }
135
+ function TestingDashboardTabComponent_Conditional_1_ForEmpty_35_Template(rf, ctx) { if (rf & 1) {
136
+ i0.ɵɵelementStart(0, "div", 18);
137
+ i0.ɵɵtext(1, "No test suites found");
138
+ i0.ɵɵelementEnd();
139
+ } }
140
+ function TestingDashboardTabComponent_Conditional_1_For_43_Conditional_6_Template(rf, ctx) { if (rf & 1) {
141
+ i0.ɵɵtext(0, " Regression detected ");
142
+ } }
143
+ function TestingDashboardTabComponent_Conditional_1_For_43_Conditional_7_Template(rf, ctx) { if (rf & 1) {
144
+ i0.ɵɵtext(0);
145
+ i0.ɵɵpipe(1, "number");
146
+ } if (rf & 2) {
147
+ const alert_r9 = i0.ɵɵnextContext().$implicit;
148
+ i0.ɵɵtextInterpolate1(" Score below 0.5 (", i0.ɵɵpipeBind2(1, 1, alert_r9.score, "1.2-2"), ") ");
149
+ } }
150
+ function TestingDashboardTabComponent_Conditional_1_For_43_Template(rf, ctx) { if (rf & 1) {
151
+ const _r8 = i0.ɵɵgetCurrentView();
152
+ i0.ɵɵelementStart(0, "div", 52);
153
+ i0.ɵɵlistener("click", function TestingDashboardTabComponent_Conditional_1_For_43_Template_div_click_0_listener() { const alert_r9 = i0.ɵɵrestoreView(_r8).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnOpenAlert(alert_r9)); });
154
+ i0.ɵɵelement(1, "i", 53);
155
+ i0.ɵɵelementStart(2, "div", 54)(3, "span", 55);
156
+ i0.ɵɵtext(4);
157
+ i0.ɵɵelementEnd();
158
+ i0.ɵɵelementStart(5, "span", 56);
159
+ i0.ɵɵtemplate(6, TestingDashboardTabComponent_Conditional_1_For_43_Conditional_6_Template, 1, 0)(7, TestingDashboardTabComponent_Conditional_1_For_43_Conditional_7_Template, 2, 4);
160
+ i0.ɵɵelementEnd()();
161
+ i0.ɵɵelement(8, "app-test-status-badge", 41);
162
+ i0.ɵɵelementEnd();
163
+ } if (rf & 2) {
164
+ const alert_r9 = ctx.$implicit;
165
+ i0.ɵɵadvance();
166
+ i0.ɵɵstyleProp("color", alert_r9.reason === "regression" ? "#ef4444" : "#f59e0b");
167
+ i0.ɵɵclassProp("fa-arrow-trend-down", alert_r9.reason === "regression")("fa-circle-exclamation", alert_r9.reason === "low-score");
168
+ i0.ɵɵadvance(3);
169
+ i0.ɵɵtextInterpolate(alert_r9.testName);
170
+ i0.ɵɵadvance(2);
171
+ i0.ɵɵconditional(alert_r9.reason === "regression" ? 6 : 7);
172
+ i0.ɵɵadvance(2);
173
+ i0.ɵɵproperty("status", alert_r9.status);
174
+ } }
175
+ function TestingDashboardTabComponent_Conditional_1_ForEmpty_44_Template(rf, ctx) { if (rf & 1) {
176
+ i0.ɵɵelementStart(0, "div", 18);
177
+ i0.ɵɵelement(1, "i", 57);
178
+ i0.ɵɵtext(2, " No alerts - all tests healthy ");
179
+ i0.ɵɵelementEnd();
180
+ } }
181
+ function TestingDashboardTabComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
182
+ const _r1 = i0.ɵɵgetCurrentView();
183
+ i0.ɵɵelementStart(0, "div", 1)(1, "div", 3)(2, "h2", 4);
184
+ i0.ɵɵelement(3, "i", 5);
185
+ i0.ɵɵtext(4, " Testing Dashboard ");
186
+ i0.ɵɵelementEnd();
187
+ i0.ɵɵelementStart(5, "button", 6);
188
+ i0.ɵɵlistener("click", function TestingDashboardTabComponent_Conditional_1_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnRefresh()); });
189
+ i0.ɵɵelement(6, "i", 7);
190
+ i0.ɵɵtext(7, " Refresh ");
191
+ i0.ɵɵelementEnd()();
192
+ i0.ɵɵelementStart(8, "div", 8);
193
+ i0.ɵɵrepeaterCreate(9, TestingDashboardTabComponent_Conditional_1_For_10_Template, 1, 1, "app-kpi-card", 9, _forTrack0);
194
+ i0.ɵɵelementEnd();
195
+ i0.ɵɵelementStart(11, "div", 10)(12, "div", 11);
196
+ i0.ɵɵtemplate(13, TestingDashboardTabComponent_Conditional_1_Conditional_13_Template, 3, 2)(14, TestingDashboardTabComponent_Conditional_1_Conditional_14_Template, 3, 0);
197
+ i0.ɵɵelementEnd();
198
+ i0.ɵɵtemplate(15, TestingDashboardTabComponent_Conditional_1_Conditional_15_Template, 3, 0, "div", 12);
199
+ i0.ɵɵelementEnd();
200
+ i0.ɵɵelementStart(16, "div", 13)(17, "div", 14)(18, "div", 11)(19, "h3");
201
+ i0.ɵɵelement(20, "i", 15);
202
+ i0.ɵɵtext(21, " Recent Runs");
203
+ i0.ɵɵelementEnd()();
204
+ i0.ɵɵelementStart(22, "div", 16);
205
+ i0.ɵɵrepeaterCreate(23, TestingDashboardTabComponent_Conditional_1_For_24_Template, 12, 7, "div", 17, _forTrack1, false, TestingDashboardTabComponent_Conditional_1_ForEmpty_25_Template, 2, 0, "div", 18);
206
+ i0.ɵɵelementEnd()();
207
+ i0.ɵɵelementStart(26, "div", 19)(27, "div", 20)(28, "div", 11)(29, "h3");
208
+ i0.ɵɵelement(30, "i", 21);
209
+ i0.ɵɵtext(31, " Suite Health");
210
+ i0.ɵɵelementEnd()();
211
+ i0.ɵɵelementStart(32, "div", 22);
212
+ i0.ɵɵrepeaterCreate(33, TestingDashboardTabComponent_Conditional_1_For_34_Template, 12, 12, "div", 23, _forTrack1, false, TestingDashboardTabComponent_Conditional_1_ForEmpty_35_Template, 2, 0, "div", 18);
213
+ i0.ɵɵelementEnd()();
214
+ i0.ɵɵelementStart(36, "div", 24)(37, "div", 11)(38, "h3");
215
+ i0.ɵɵelement(39, "i", 25);
216
+ i0.ɵɵtext(40, " Alerts");
217
+ i0.ɵɵelementEnd()();
218
+ i0.ɵɵelementStart(41, "div", 26);
219
+ i0.ɵɵrepeaterCreate(42, TestingDashboardTabComponent_Conditional_1_For_43_Template, 9, 9, "div", 27, _forTrack1, false, TestingDashboardTabComponent_Conditional_1_ForEmpty_44_Template, 3, 0, "div", 18);
220
+ i0.ɵɵelementEnd()()()()();
221
+ } if (rf & 2) {
222
+ const ctx_r1 = i0.ɵɵnextContext();
223
+ i0.ɵɵadvance(5);
224
+ i0.ɵɵproperty("disabled", ctx_r1.IsLoading);
225
+ i0.ɵɵadvance();
226
+ i0.ɵɵclassProp("spinning", ctx_r1.IsLoading);
227
+ i0.ɵɵadvance(3);
228
+ i0.ɵɵrepeater(ctx_r1.KpiCards);
229
+ i0.ɵɵadvance(4);
230
+ i0.ɵɵconditional(ctx_r1.RunningTests.length > 0 ? 13 : 14);
231
+ i0.ɵɵadvance(2);
232
+ i0.ɵɵconditional(ctx_r1.RunningTests.length > 0 ? 15 : -1);
233
+ i0.ɵɵadvance(8);
234
+ i0.ɵɵrepeater(ctx_r1.RecentRuns);
235
+ i0.ɵɵadvance(10);
236
+ i0.ɵɵrepeater(ctx_r1.SortedSuites);
237
+ i0.ɵɵadvance(9);
238
+ i0.ɵɵrepeater(ctx_r1.Alerts);
239
+ } }
240
+ export class TestingDashboardTabComponent {
241
+ instrumentationService;
242
+ cdr;
243
+ initialState = null;
244
+ stateChange = new EventEmitter();
245
+ destroy$ = new Subject();
246
+ /** Resolved data for the template */
247
+ IsLoading = false;
248
+ KpiCards = [];
249
+ RunningTests = [];
250
+ RecentRuns = [];
251
+ SortedSuites = [];
252
+ Alerts = [];
253
+ constructor(instrumentationService, cdr) {
254
+ this.instrumentationService = instrumentationService;
255
+ this.cdr = cdr;
256
+ }
257
+ // ---------------------------------------------------------------------------
258
+ // Lifecycle
259
+ // ---------------------------------------------------------------------------
260
+ async ngOnInit() {
261
+ await TestEngineBase.Instance.Config(false);
262
+ this.subscribeToStreams();
263
+ this.instrumentationService.refresh();
264
+ }
265
+ ngOnDestroy() {
266
+ this.destroy$.next();
267
+ this.destroy$.complete();
268
+ }
269
+ // ---------------------------------------------------------------------------
270
+ // Public methods (PascalCase)
271
+ // ---------------------------------------------------------------------------
272
+ OnRefresh() {
273
+ this.instrumentationService.refresh();
274
+ }
275
+ OnOpenRun(run) {
276
+ SharedService.Instance.OpenEntityRecord('MJ: Test Runs', CompositeKey.FromID(run.id));
277
+ }
278
+ OnOpenAlert(alert) {
279
+ SharedService.Instance.OpenEntityRecord('MJ: Test Runs', CompositeKey.FromID(alert.id));
280
+ }
281
+ FormatDuration(ms) {
282
+ if (ms < 1000)
283
+ return `${ms}ms`;
284
+ const totalSeconds = Math.floor(ms / 1000);
285
+ const minutes = Math.floor(totalSeconds / 60);
286
+ const seconds = totalSeconds % 60;
287
+ if (minutes > 0)
288
+ return `${minutes}m ${seconds}s`;
289
+ return `${seconds}s`;
290
+ }
291
+ FormatTimestamp(date) {
292
+ if (!date)
293
+ return '';
294
+ const d = date instanceof Date ? date : new Date(date);
295
+ const now = new Date();
296
+ const diffMs = now.getTime() - d.getTime();
297
+ const diffMins = Math.floor(diffMs / 60000);
298
+ if (diffMins < 1)
299
+ return 'Just now';
300
+ if (diffMins < 60)
301
+ return `${diffMins}m ago`;
302
+ const diffHours = Math.floor(diffMins / 60);
303
+ if (diffHours < 24)
304
+ return `${diffHours}h ago`;
305
+ const diffDays = Math.floor(diffHours / 24);
306
+ if (diffDays < 7)
307
+ return `${diffDays}d ago`;
308
+ return d.toLocaleDateString();
309
+ }
310
+ FormatCost(cost) {
311
+ return `$${cost.toFixed(4)}`;
312
+ }
313
+ GetPassRateColor(rate) {
314
+ if (rate >= 90)
315
+ return '#22c55e';
316
+ if (rate >= 70)
317
+ return '#f59e0b';
318
+ return '#ef4444';
319
+ }
320
+ // ---------------------------------------------------------------------------
321
+ // Private helpers (camelCase)
322
+ // ---------------------------------------------------------------------------
323
+ subscribeToStreams() {
324
+ this.subscribeLoading();
325
+ this.subscribeKpis();
326
+ this.subscribeTestRuns();
327
+ this.subscribeSuites();
328
+ }
329
+ subscribeLoading() {
330
+ this.instrumentationService.isLoading$.pipe(takeUntil(this.destroy$)).subscribe(loading => {
331
+ this.IsLoading = loading;
332
+ this.cdr.markForCheck();
333
+ });
334
+ }
335
+ subscribeKpis() {
336
+ this.instrumentationService.kpis$.pipe(takeUntil(this.destroy$), map(kpis => this.buildKpiCards(kpis))).subscribe(cards => {
337
+ this.KpiCards = cards;
338
+ this.cdr.markForCheck();
339
+ });
340
+ }
341
+ subscribeTestRuns() {
342
+ this.instrumentationService.testRuns$.pipe(takeUntil(this.destroy$)).subscribe(runs => {
343
+ this.RunningTests = runs.filter(r => r.status === 'Running');
344
+ this.RecentRuns = runs
345
+ .filter(r => r.status !== 'Running')
346
+ .slice(0, 15);
347
+ this.Alerts = this.buildAlerts(runs);
348
+ this.cdr.markForCheck();
349
+ });
350
+ }
351
+ subscribeSuites() {
352
+ this.instrumentationService.suiteHierarchy$.pipe(takeUntil(this.destroy$)).subscribe(suites => {
353
+ this.SortedSuites = this.flattenAndSort(suites);
354
+ this.cdr.markForCheck();
355
+ });
356
+ }
357
+ buildKpiCards(kpis) {
358
+ const trendDir = kpis.passRateTrend > 0
359
+ ? 'up'
360
+ : kpis.passRateTrend < 0
361
+ ? 'down'
362
+ : 'stable';
363
+ return [
364
+ {
365
+ title: 'Active Tests',
366
+ value: kpis.totalTestsActive,
367
+ icon: 'fa-vial',
368
+ color: 'primary',
369
+ subtitle: `${kpis.totalTestRuns} runs this period`
370
+ },
371
+ {
372
+ title: 'Pass Rate',
373
+ value: `${kpis.passRateThisMonth.toFixed(1)}%`,
374
+ icon: 'fa-check-circle',
375
+ color: kpis.passRateThisMonth >= 90 ? 'success' : kpis.passRateThisMonth >= 75 ? 'warning' : 'danger',
376
+ trend: kpis.passRateTrend !== 0 ? {
377
+ direction: trendDir,
378
+ percentage: Math.abs(Math.round(kpis.passRateTrend * 10) / 10),
379
+ period: 'vs previous period'
380
+ } : undefined
381
+ },
382
+ {
383
+ title: 'Total Cost',
384
+ value: `$${kpis.totalCostThisMonth.toFixed(2)}`,
385
+ icon: 'fa-dollar-sign',
386
+ color: 'warning',
387
+ subtitle: 'This period'
388
+ },
389
+ {
390
+ title: 'Avg Duration',
391
+ value: this.FormatDuration(kpis.averageDuration),
392
+ icon: 'fa-clock',
393
+ color: 'info',
394
+ subtitle: 'Per test run'
395
+ },
396
+ {
397
+ title: 'Pending Review',
398
+ value: kpis.testsPendingReview,
399
+ icon: 'fa-clipboard-check',
400
+ color: kpis.testsPendingReview > 10 ? 'warning' : 'success',
401
+ subtitle: 'Tests need feedback'
402
+ }
403
+ ];
404
+ }
405
+ buildAlerts(runs) {
406
+ const alerts = [];
407
+ // Group runs by test name to detect regressions
408
+ const byTest = new Map();
409
+ for (const run of runs) {
410
+ const existing = byTest.get(run.testName);
411
+ if (existing) {
412
+ existing.push(run);
413
+ }
414
+ else {
415
+ byTest.set(run.testName, [run]);
416
+ }
417
+ }
418
+ this.detectRegressions(byTest, alerts);
419
+ this.detectLowScores(runs, alerts);
420
+ return alerts.slice(0, 20);
421
+ }
422
+ /** Find tests that previously passed but now fail */
423
+ detectRegressions(byTest, alerts) {
424
+ const seenIds = new Set();
425
+ byTest.forEach((testRuns, testName) => {
426
+ if (testRuns.length < 2)
427
+ return;
428
+ // Sort by date descending
429
+ const sorted = [...testRuns].sort((a, b) => b.runDateTime.getTime() - a.runDateTime.getTime());
430
+ const latest = sorted[0];
431
+ const previous = sorted[1];
432
+ if ((latest.status === 'Failed' || latest.status === 'Error') &&
433
+ previous.status === 'Passed' &&
434
+ !seenIds.has(latest.id)) {
435
+ seenIds.add(latest.id);
436
+ alerts.push({
437
+ id: latest.id,
438
+ testName,
439
+ reason: 'regression',
440
+ score: latest.score,
441
+ status: latest.status,
442
+ runDateTime: latest.runDateTime
443
+ });
444
+ }
445
+ });
446
+ }
447
+ /** Flag tests with scores below 0.5 */
448
+ detectLowScores(runs, alerts) {
449
+ const alertIds = new Set(alerts.map(a => a.id));
450
+ for (const run of runs) {
451
+ if (run.score < 0.5 && run.status !== 'Running' && !alertIds.has(run.id)) {
452
+ alerts.push({
453
+ id: run.id,
454
+ testName: run.testName,
455
+ reason: 'low-score',
456
+ score: run.score,
457
+ status: run.status,
458
+ runDateTime: run.runDateTime
459
+ });
460
+ }
461
+ }
462
+ }
463
+ /** Flatten suite hierarchy and sort by worst health first */
464
+ flattenAndSort(nodes) {
465
+ const flat = [];
466
+ this.collectNodes(nodes, flat);
467
+ return flat.sort((a, b) => a.passRate - b.passRate);
468
+ }
469
+ collectNodes(nodes, out) {
470
+ for (const node of nodes) {
471
+ out.push(node);
472
+ if (node.children.length > 0) {
473
+ this.collectNodes(node.children, out);
474
+ }
475
+ }
476
+ }
477
+ static ɵfac = function TestingDashboardTabComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || TestingDashboardTabComponent)(i0.ɵɵdirectiveInject(i1.TestingInstrumentationService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
478
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TestingDashboardTabComponent, selectors: [["app-testing-dashboard-tab"]], inputs: { initialState: "initialState" }, outputs: { stateChange: "stateChange" }, decls: 2, vars: 1, consts: [[1, "full-page-loading"], [1, "dashboard-container"], ["text", "Loading Testing Dashboard..."], [1, "page-header"], [1, "page-title"], [1, "fa-solid", "fa-gauge-high"], [1, "refresh-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-refresh"], [1, "kpi-row"], [3, "data"], [1, "live-activity-card"], [1, "section-header"], [1, "running-tests-list"], [1, "lower-grid"], [1, "card", "recent-runs-card"], [1, "fa-solid", "fa-history"], [1, "runs-list"], [1, "run-row"], [1, "empty-state"], [1, "right-column"], [1, "card", "suite-health-card"], [1, "fa-solid", "fa-heartbeat"], [1, "suite-health-list"], [1, "suite-health-row"], [1, "card", "alerts-card"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "alerts-list"], [1, "alert-row"], [1, "live-dot"], [1, "fa-solid", "fa-circle-pause", "live-idle-icon"], [1, "running-test-item"], [1, "running-test-name"], [1, "running-test-meta"], [1, "running-elapsed"], [1, "running-progress-bar"], [1, "running-progress-fill"], [1, "run-row", 3, "click"], [1, "run-row-left"], [1, "run-row-name"], [1, "run-row-time"], [1, "run-row-right"], [3, "status"], [3, "score", "showBar"], [1, "run-row-duration"], [3, "cost"], [1, "suite-health-info"], [1, "suite-health-name"], [1, "suite-health-count"], [1, "suite-health-bar-wrapper"], [1, "suite-health-bar"], [1, "suite-health-bar-fill"], [1, "suite-health-pct"], [1, "alert-row", 3, "click"], [1, "fa-solid"], [1, "alert-info"], [1, "alert-name"], [1, "alert-reason"], [1, "fa-solid", "fa-check-circle", 2, "color", "#22c55e", "margin-right", "6px"]], template: function TestingDashboardTabComponent_Template(rf, ctx) { if (rf & 1) {
479
+ i0.ɵɵtemplate(0, TestingDashboardTabComponent_Conditional_0_Template, 2, 0, "div", 0)(1, TestingDashboardTabComponent_Conditional_1_Template, 45, 8, "div", 1);
480
+ } if (rf & 2) {
481
+ i0.ɵɵconditional(ctx.IsLoading ? 0 : 1);
482
+ } }, dependencies: [i2.TestStatusBadgeComponent, i2.ScoreIndicatorComponent, i2.CostDisplayComponent, i3.LoadingComponent, i4.KPICardComponent, i5.DecimalPipe], styles: ["\n\n .full-page-loading[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n min-height: 400px;\n background: #f8f9fa;\n }\n\n .dashboard-container[_ngcontent-%COMP%] {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n background: #f8f9fa;\n }\n\n \n\n .page-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 24px;\n }\n\n .page-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 22px;\n font-weight: 700;\n color: #1e293b;\n display: flex;\n align-items: center;\n gap: 10px;\n }\n\n .page-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: #6366f1; }\n\n .refresh-btn[_ngcontent-%COMP%] {\n background: #6366f1;\n color: white;\n border: none;\n padding: 8px 18px;\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n font-weight: 500;\n transition: background 0.2s ease;\n }\n\n .refresh-btn[_ngcontent-%COMP%]:hover:not(:disabled) { background: #4f46e5; }\n .refresh-btn[_ngcontent-%COMP%]:disabled { opacity: 0.6; cursor: not-allowed; }\n .refresh-btn[_ngcontent-%COMP%] i.spinning[_ngcontent-%COMP%] { animation: _ngcontent-%COMP%_spin 1s linear infinite; }\n\n @keyframes _ngcontent-%COMP%_spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n\n \n\n .kpi-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n }\n\n \n\n .card[_ngcontent-%COMP%] {\n background: white;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.08);\n overflow: hidden;\n }\n\n .section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px 20px;\n border-bottom: 1px solid #f1f5f9;\n }\n\n .section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: #334155;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: #6366f1; font-size: 13px; }\n\n \n\n .live-activity-card[_ngcontent-%COMP%] {\n background: white;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.08);\n margin-bottom: 24px;\n overflow: hidden;\n }\n\n .live-dot[_ngcontent-%COMP%] {\n width: 10px;\n height: 10px;\n background: #22c55e;\n border-radius: 50%;\n display: inline-block;\n animation: _ngcontent-%COMP%_pulse-dot 1.5s ease-in-out infinite;\n }\n\n @keyframes _ngcontent-%COMP%_pulse-dot {\n 0%, 100% { box-shadow: 0 0 0 0 rgba(34,197,94,0.5); }\n 50% { box-shadow: 0 0 0 6px rgba(34,197,94,0); }\n }\n\n .live-idle-icon[_ngcontent-%COMP%] { color: #9ca3af; font-size: 14px; }\n\n .running-tests-list[_ngcontent-%COMP%] {\n padding: 0 20px 16px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n }\n\n .running-test-item[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 10px 14px;\n background: #f0fdf4;\n border-radius: 8px;\n border: 1px solid #bbf7d0;\n }\n\n .running-test-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: #166534;\n }\n\n .running-test-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n }\n\n .running-elapsed[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #15803d;\n font-weight: 500;\n }\n\n .running-progress-bar[_ngcontent-%COMP%] {\n width: 60px;\n height: 4px;\n background: #dcfce7;\n border-radius: 2px;\n overflow: hidden;\n }\n\n .running-progress-fill[_ngcontent-%COMP%] {\n display: block;\n width: 100%;\n height: 100%;\n background: linear-gradient(90deg, #22c55e, #86efac);\n animation: _ngcontent-%COMP%_progress-slide 1.2s ease-in-out infinite;\n border-radius: 2px;\n }\n\n @keyframes _ngcontent-%COMP%_progress-slide {\n 0% { transform: translateX(-100%); }\n 100% { transform: translateX(100%); }\n }\n\n \n\n .lower-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 24px;\n }\n\n .right-column[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 24px;\n }\n\n \n\n .runs-list[_ngcontent-%COMP%] {\n max-height: 520px;\n overflow-y: auto;\n }\n\n .run-row[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 10px 20px;\n border-bottom: 1px solid #f8fafc;\n cursor: pointer;\n transition: background 0.15s ease;\n }\n\n .run-row[_ngcontent-%COMP%]:hover { background: #f8fafc; }\n\n .run-row-left[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n flex: 1;\n min-width: 0;\n }\n\n .run-row-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: #1e293b;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .run-row-time[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #94a3b8;\n }\n\n .run-row-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n }\n\n .run-row-duration[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #64748b;\n min-width: 44px;\n text-align: right;\n }\n\n \n\n .suite-health-list[_ngcontent-%COMP%] {\n padding: 8px 0;\n max-height: 260px;\n overflow-y: auto;\n }\n\n .suite-health-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 20px;\n }\n\n .suite-health-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n flex: 1;\n min-width: 0;\n }\n\n .suite-health-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: #1e293b;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .suite-health-count[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #94a3b8;\n }\n\n .suite-health-bar-wrapper[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n }\n\n .suite-health-bar[_ngcontent-%COMP%] {\n width: 80px;\n height: 6px;\n background: #f1f5f9;\n border-radius: 3px;\n overflow: hidden;\n }\n\n .suite-health-bar-fill[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 3px;\n transition: width 0.3s ease;\n }\n\n .suite-health-pct[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n min-width: 36px;\n text-align: right;\n }\n\n \n\n .alerts-list[_ngcontent-%COMP%] {\n max-height: 220px;\n overflow-y: auto;\n }\n\n .alert-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 20px;\n border-bottom: 1px solid #f8fafc;\n cursor: pointer;\n transition: background 0.15s ease;\n }\n\n .alert-row[_ngcontent-%COMP%]:hover { background: #fef2f2; }\n\n .alert-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n flex: 1;\n min-width: 0;\n }\n\n .alert-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: #1e293b;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .alert-reason[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #94a3b8;\n }\n\n \n\n .empty-state[_ngcontent-%COMP%] {\n padding: 32px 20px;\n text-align: center;\n color: #94a3b8;\n font-size: 13px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n \n\n @media (max-width: 900px) {\n .lower-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n }\n\n @media (max-width: 640px) {\n .dashboard-container[_ngcontent-%COMP%] { padding: 16px; }\n .kpi-row[_ngcontent-%COMP%] { grid-template-columns: 1fr; }\n }"], changeDetection: 0 });
483
+ }
484
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TestingDashboardTabComponent, [{
485
+ type: Component,
486
+ args: [{ selector: 'app-testing-dashboard-tab', changeDetection: ChangeDetectionStrategy.OnPush, template: `
487
+ <!-- Full-page loading state -->
488
+ @if (IsLoading) {
489
+ <div class="full-page-loading">
490
+ <mj-loading text="Loading Testing Dashboard..."></mj-loading>
491
+ </div>
492
+ } @else {
493
+ <div class="dashboard-container">
494
+
495
+ <!-- Page Header -->
496
+ <div class="page-header">
497
+ <h2 class="page-title">
498
+ <i class="fa-solid fa-gauge-high"></i>
499
+ Testing Dashboard
500
+ </h2>
501
+ <button class="refresh-btn" (click)="OnRefresh()" [disabled]="IsLoading">
502
+ <i class="fa-solid fa-refresh" [class.spinning]="IsLoading"></i>
503
+ Refresh
504
+ </button>
505
+ </div>
506
+
507
+ <!-- KPI Row -->
508
+ <div class="kpi-row">
509
+ @for (kpi of KpiCards; track kpi.title) {
510
+ <app-kpi-card [data]="kpi"></app-kpi-card>
511
+ }
512
+ </div>
513
+
514
+ <!-- Live Activity Section -->
515
+ <div class="live-activity-card">
516
+ <div class="section-header">
517
+ @if (RunningTests.length > 0) {
518
+ <span class="live-dot"></span>
519
+ <h3>{{ RunningTests.length }} test{{ RunningTests.length === 1 ? '' : 's' }} running</h3>
520
+ } @else {
521
+ <i class="fa-solid fa-circle-pause live-idle-icon"></i>
522
+ <h3>No tests currently running</h3>
523
+ }
524
+ </div>
525
+ @if (RunningTests.length > 0) {
526
+ <div class="running-tests-list">
527
+ @for (run of RunningTests; track run.id) {
528
+ <div class="running-test-item">
529
+ <div class="running-test-name">{{ run.testName }}</div>
530
+ <div class="running-test-meta">
531
+ <span class="running-elapsed">{{ FormatDuration(run.duration) }}</span>
532
+ <span class="running-progress-bar">
533
+ <span class="running-progress-fill"></span>
534
+ </span>
535
+ </div>
536
+ </div>
537
+ }
538
+ </div>
539
+ }
540
+ </div>
541
+
542
+ <!-- Lower Content: 2-column layout -->
543
+ <div class="lower-grid">
544
+
545
+ <!-- Left Column: Recent Runs -->
546
+ <div class="card recent-runs-card">
547
+ <div class="section-header">
548
+ <h3><i class="fa-solid fa-history"></i> Recent Runs</h3>
549
+ </div>
550
+ <div class="runs-list">
551
+ @for (run of RecentRuns; track run.id) {
552
+ <div class="run-row" (click)="OnOpenRun(run)">
553
+ <div class="run-row-left">
554
+ <span class="run-row-name">{{ run.testName }}</span>
555
+ <span class="run-row-time">{{ FormatTimestamp(run.runDateTime) }}</span>
556
+ </div>
557
+ <div class="run-row-right">
558
+ <app-test-status-badge [status]="run.status"></app-test-status-badge>
559
+ <app-score-indicator [score]="run.score" [showBar]="true"></app-score-indicator>
560
+ <span class="run-row-duration">{{ FormatDuration(run.duration) }}</span>
561
+ <app-cost-display [cost]="run.cost"></app-cost-display>
562
+ </div>
563
+ </div>
564
+ } @empty {
565
+ <div class="empty-state">No completed test runs found</div>
566
+ }
567
+ </div>
568
+ </div>
569
+
570
+ <!-- Right Column: Suite Health + Alerts -->
571
+ <div class="right-column">
572
+
573
+ <!-- Suite Health -->
574
+ <div class="card suite-health-card">
575
+ <div class="section-header">
576
+ <h3><i class="fa-solid fa-heartbeat"></i> Suite Health</h3>
577
+ </div>
578
+ <div class="suite-health-list">
579
+ @for (suite of SortedSuites; track suite.id) {
580
+ <div class="suite-health-row">
581
+ <div class="suite-health-info">
582
+ <span class="suite-health-name">{{ suite.name }}</span>
583
+ <span class="suite-health-count">{{ suite.testCount }} tests</span>
584
+ </div>
585
+ <div class="suite-health-bar-wrapper">
586
+ <div class="suite-health-bar">
587
+ <div
588
+ class="suite-health-bar-fill"
589
+ [style.width.%]="suite.passRate"
590
+ [style.background]="GetPassRateColor(suite.passRate)">
591
+ </div>
592
+ </div>
593
+ <span class="suite-health-pct" [style.color]="GetPassRateColor(suite.passRate)">
594
+ {{ suite.passRate | number:'1.0-0' }}%
595
+ </span>
596
+ </div>
597
+ </div>
598
+ } @empty {
599
+ <div class="empty-state">No test suites found</div>
600
+ }
601
+ </div>
602
+ </div>
603
+
604
+ <!-- Alerts -->
605
+ <div class="card alerts-card">
606
+ <div class="section-header">
607
+ <h3><i class="fa-solid fa-triangle-exclamation"></i> Alerts</h3>
608
+ </div>
609
+ <div class="alerts-list">
610
+ @for (alert of Alerts; track alert.id) {
611
+ <div class="alert-row" (click)="OnOpenAlert(alert)">
612
+ <i class="fa-solid"
613
+ [class.fa-arrow-trend-down]="alert.reason === 'regression'"
614
+ [class.fa-circle-exclamation]="alert.reason === 'low-score'"
615
+ [style.color]="alert.reason === 'regression' ? '#ef4444' : '#f59e0b'">
616
+ </i>
617
+ <div class="alert-info">
618
+ <span class="alert-name">{{ alert.testName }}</span>
619
+ <span class="alert-reason">
620
+ @if (alert.reason === 'regression') {
621
+ Regression detected
622
+ } @else {
623
+ Score below 0.5 ({{ alert.score | number:'1.2-2' }})
624
+ }
625
+ </span>
626
+ </div>
627
+ <app-test-status-badge [status]="alert.status"></app-test-status-badge>
628
+ </div>
629
+ } @empty {
630
+ <div class="empty-state">
631
+ <i class="fa-solid fa-check-circle" style="color: #22c55e; margin-right: 6px;"></i>
632
+ No alerts - all tests healthy
633
+ </div>
634
+ }
635
+ </div>
636
+ </div>
637
+
638
+ </div>
639
+ </div>
640
+ </div>
641
+ }
642
+ `, styles: ["\n /* ===== Layout ===== */\n .full-page-loading {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n min-height: 400px;\n background: #f8f9fa;\n }\n\n .dashboard-container {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n background: #f8f9fa;\n }\n\n /* ===== Page Header ===== */\n .page-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 24px;\n }\n\n .page-title {\n margin: 0;\n font-size: 22px;\n font-weight: 700;\n color: #1e293b;\n display: flex;\n align-items: center;\n gap: 10px;\n }\n\n .page-title i { color: #6366f1; }\n\n .refresh-btn {\n background: #6366f1;\n color: white;\n border: none;\n padding: 8px 18px;\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n font-weight: 500;\n transition: background 0.2s ease;\n }\n\n .refresh-btn:hover:not(:disabled) { background: #4f46e5; }\n .refresh-btn:disabled { opacity: 0.6; cursor: not-allowed; }\n .refresh-btn i.spinning { animation: spin 1s linear infinite; }\n\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n\n /* ===== KPI Row ===== */\n .kpi-row {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n }\n\n /* ===== Card Base ===== */\n .card {\n background: white;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.08);\n overflow: hidden;\n }\n\n .section-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px 20px;\n border-bottom: 1px solid #f1f5f9;\n }\n\n .section-header h3 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: #334155;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .section-header h3 i { color: #6366f1; font-size: 13px; }\n\n /* ===== Live Activity ===== */\n .live-activity-card {\n background: white;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.08);\n margin-bottom: 24px;\n overflow: hidden;\n }\n\n .live-dot {\n width: 10px;\n height: 10px;\n background: #22c55e;\n border-radius: 50%;\n display: inline-block;\n animation: pulse-dot 1.5s ease-in-out infinite;\n }\n\n @keyframes pulse-dot {\n 0%, 100% { box-shadow: 0 0 0 0 rgba(34,197,94,0.5); }\n 50% { box-shadow: 0 0 0 6px rgba(34,197,94,0); }\n }\n\n .live-idle-icon { color: #9ca3af; font-size: 14px; }\n\n .running-tests-list {\n padding: 0 20px 16px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n }\n\n .running-test-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 10px 14px;\n background: #f0fdf4;\n border-radius: 8px;\n border: 1px solid #bbf7d0;\n }\n\n .running-test-name {\n font-size: 13px;\n font-weight: 500;\n color: #166534;\n }\n\n .running-test-meta {\n display: flex;\n align-items: center;\n gap: 10px;\n }\n\n .running-elapsed {\n font-size: 12px;\n color: #15803d;\n font-weight: 500;\n }\n\n .running-progress-bar {\n width: 60px;\n height: 4px;\n background: #dcfce7;\n border-radius: 2px;\n overflow: hidden;\n }\n\n .running-progress-fill {\n display: block;\n width: 100%;\n height: 100%;\n background: linear-gradient(90deg, #22c55e, #86efac);\n animation: progress-slide 1.2s ease-in-out infinite;\n border-radius: 2px;\n }\n\n @keyframes progress-slide {\n 0% { transform: translateX(-100%); }\n 100% { transform: translateX(100%); }\n }\n\n /* ===== Lower Grid ===== */\n .lower-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 24px;\n }\n\n .right-column {\n display: flex;\n flex-direction: column;\n gap: 24px;\n }\n\n /* ===== Recent Runs ===== */\n .runs-list {\n max-height: 520px;\n overflow-y: auto;\n }\n\n .run-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 10px 20px;\n border-bottom: 1px solid #f8fafc;\n cursor: pointer;\n transition: background 0.15s ease;\n }\n\n .run-row:hover { background: #f8fafc; }\n\n .run-row-left {\n display: flex;\n flex-direction: column;\n gap: 2px;\n flex: 1;\n min-width: 0;\n }\n\n .run-row-name {\n font-size: 13px;\n font-weight: 500;\n color: #1e293b;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .run-row-time {\n font-size: 11px;\n color: #94a3b8;\n }\n\n .run-row-right {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n }\n\n .run-row-duration {\n font-size: 11px;\n color: #64748b;\n min-width: 44px;\n text-align: right;\n }\n\n /* ===== Suite Health ===== */\n .suite-health-list {\n padding: 8px 0;\n max-height: 260px;\n overflow-y: auto;\n }\n\n .suite-health-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 20px;\n }\n\n .suite-health-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n flex: 1;\n min-width: 0;\n }\n\n .suite-health-name {\n font-size: 13px;\n font-weight: 500;\n color: #1e293b;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .suite-health-count {\n font-size: 11px;\n color: #94a3b8;\n }\n\n .suite-health-bar-wrapper {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n }\n\n .suite-health-bar {\n width: 80px;\n height: 6px;\n background: #f1f5f9;\n border-radius: 3px;\n overflow: hidden;\n }\n\n .suite-health-bar-fill {\n height: 100%;\n border-radius: 3px;\n transition: width 0.3s ease;\n }\n\n .suite-health-pct {\n font-size: 12px;\n font-weight: 600;\n min-width: 36px;\n text-align: right;\n }\n\n /* ===== Alerts ===== */\n .alerts-list {\n max-height: 220px;\n overflow-y: auto;\n }\n\n .alert-row {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 20px;\n border-bottom: 1px solid #f8fafc;\n cursor: pointer;\n transition: background 0.15s ease;\n }\n\n .alert-row:hover { background: #fef2f2; }\n\n .alert-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n flex: 1;\n min-width: 0;\n }\n\n .alert-name {\n font-size: 13px;\n font-weight: 500;\n color: #1e293b;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .alert-reason {\n font-size: 11px;\n color: #94a3b8;\n }\n\n /* ===== Empty State ===== */\n .empty-state {\n padding: 32px 20px;\n text-align: center;\n color: #94a3b8;\n font-size: 13px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n /* ===== Responsive ===== */\n @media (max-width: 900px) {\n .lower-grid {\n grid-template-columns: 1fr;\n }\n }\n\n @media (max-width: 640px) {\n .dashboard-container { padding: 16px; }\n .kpi-row { grid-template-columns: 1fr; }\n }\n "] }]
643
+ }], () => [{ type: i1.TestingInstrumentationService }, { type: i0.ChangeDetectorRef }], { initialState: [{
644
+ type: Input
645
+ }], stateChange: [{
646
+ type: Output
647
+ }] }); })();
648
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingDashboardTabComponent, { className: "TestingDashboardTabComponent", filePath: "src/Testing/components/testing-dashboard-tab.component.ts", lineNumber: 566 }); })();
649
+ //# sourceMappingURL=testing-dashboard-tab.component.js.map