@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
@@ -0,0 +1,719 @@
1
+ /**
2
+ * @fileoverview Classify · Suggestions Inbox tab.
3
+ *
4
+ * Self-contained sub-page that surfaces `MJ: Tag Suggestions` — the
5
+ * human-in-the-loop review queue produced by the classifier when a tag lands in
6
+ * the ambiguous band (BelowThreshold, ConstrainedMode, ParentFrozen, …) and by
7
+ * the server-side TagHealthJob (merge / low-usage / wide-node candidates).
8
+ *
9
+ * 3-pane layout: (1) a filter rail by Reason (with counts) + Status,
10
+ * (2) the suggestion list, (3) a reading pane with the proposed name/parent,
11
+ * best-match score on a threshold-band gradient, the source-item link, and the
12
+ * Approve / Merge / Reject action bar.
13
+ *
14
+ * Data is TRANSACTIONAL and can grow — it is loaded via RunView (NOT cached).
15
+ * Status filtering re-queries the DB; Reason filtering is applied in-memory on
16
+ * the loaded Pending set.
17
+ *
18
+ * The host owns the lightweight pending-count badge on the nav rail; this tab
19
+ * emits `(Resolved)` after every action so the host can refresh that badge.
20
+ */
21
+ import { Component, ChangeDetectorRef, EventEmitter, Output, inject } from '@angular/core';
22
+ import { RunView } from '@memberjunction/core';
23
+ import { UUIDsEqual } from '@memberjunction/global';
24
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
25
+ import { MJNotificationService } from '@memberjunction/ng-notifications';
26
+ import { TagEngineBase } from '@memberjunction/tag-engine-base';
27
+ import { formatShortDate } from '../shared/classify.format';
28
+ import * as i0 from "@angular/core";
29
+ import * as i1 from "@angular/forms";
30
+ import * as i2 from "@memberjunction/ng-shared-generic";
31
+ import * as i3 from "@memberjunction/ng-ui-components";
32
+ import * as i4 from "@angular/common";
33
+ const _forTrack0 = ($index, $item) => $item.Reason;
34
+ const _forTrack1 = ($index, $item) => $item.ID;
35
+ function ClassifyInboxTabComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
36
+ i0.ɵɵelement(0, "i", 10);
37
+ i0.ɵɵelementStart(1, "span", 11);
38
+ i0.ɵɵtext(2, "Refreshing\u2026");
39
+ i0.ɵɵelementEnd();
40
+ } }
41
+ function ClassifyInboxTabComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
42
+ i0.ɵɵelement(0, "i", 12);
43
+ i0.ɵɵelementStart(1, "span", 11);
44
+ i0.ɵɵtext(2, "Refresh");
45
+ i0.ɵɵelementEnd();
46
+ } }
47
+ function ClassifyInboxTabComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
48
+ i0.ɵɵelementStart(0, "div", 8);
49
+ i0.ɵɵelement(1, "mj-loading", 13);
50
+ i0.ɵɵelementEnd();
51
+ } }
52
+ function ClassifyInboxTabComponent_Conditional_12_For_9_Template(rf, ctx) { if (rf & 1) {
53
+ const _r3 = i0.ɵɵgetCurrentView();
54
+ i0.ɵɵelementStart(0, "a", 15);
55
+ i0.ɵɵlistener("click", function ClassifyInboxTabComponent_Conditional_12_For_9_Template_a_click_0_listener() { const rc_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SetReasonFilter(rc_r4.Reason)); });
56
+ i0.ɵɵtext(1);
57
+ i0.ɵɵelementStart(2, "span", 16);
58
+ i0.ɵɵtext(3);
59
+ i0.ɵɵelementEnd()();
60
+ } if (rf & 2) {
61
+ const rc_r4 = ctx.$implicit;
62
+ const ctx_r1 = i0.ɵɵnextContext(2);
63
+ i0.ɵɵclassProp("ci-active", ctx_r1.ReasonFilter === rc_r4.Reason);
64
+ i0.ɵɵadvance();
65
+ i0.ɵɵtextInterpolate1(" ", rc_r4.Label, " ");
66
+ i0.ɵɵadvance(2);
67
+ i0.ɵɵtextInterpolate(rc_r4.Count);
68
+ } }
69
+ function ClassifyInboxTabComponent_Conditional_12_For_13_Template(rf, ctx) { if (rf & 1) {
70
+ const _r5 = i0.ɵɵgetCurrentView();
71
+ i0.ɵɵelementStart(0, "a", 15);
72
+ i0.ɵɵlistener("click", function ClassifyInboxTabComponent_Conditional_12_For_13_Template_a_click_0_listener() { const st_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SetStatusFilter(st_r6)); });
73
+ i0.ɵɵtext(1);
74
+ i0.ɵɵelementEnd();
75
+ } if (rf & 2) {
76
+ const st_r6 = ctx.$implicit;
77
+ const ctx_r1 = i0.ɵɵnextContext(2);
78
+ i0.ɵɵclassProp("ci-active", ctx_r1.StatusFilter === st_r6);
79
+ i0.ɵɵadvance();
80
+ i0.ɵɵtextInterpolate1(" ", st_r6, " ");
81
+ } }
82
+ function ClassifyInboxTabComponent_Conditional_12_Conditional_22_Template(rf, ctx) { if (rf & 1) {
83
+ i0.ɵɵelementStart(0, "div", 22);
84
+ i0.ɵɵelement(1, "i", 24);
85
+ i0.ɵɵelementStart(2, "p");
86
+ i0.ɵɵtext(3);
87
+ i0.ɵɵpipe(4, "lowercase");
88
+ i0.ɵɵelementEnd()();
89
+ } if (rf & 2) {
90
+ const ctx_r1 = i0.ɵɵnextContext(2);
91
+ i0.ɵɵadvance(3);
92
+ i0.ɵɵtextInterpolate2("No ", i0.ɵɵpipeBind1(4, 2, ctx_r1.StatusFilter), " suggestions", ctx_r1.ReasonFilter ? " for this reason" : "", ".");
93
+ } }
94
+ function ClassifyInboxTabComponent_Conditional_12_Conditional_23_For_1_Conditional_9_Template(rf, ctx) { if (rf & 1) {
95
+ i0.ɵɵelementStart(0, "span", 32);
96
+ i0.ɵɵtext(1, "\u2248 ");
97
+ i0.ɵɵelementStart(2, "b");
98
+ i0.ɵɵtext(3);
99
+ i0.ɵɵelementEnd();
100
+ i0.ɵɵtext(4);
101
+ i0.ɵɵelementEnd();
102
+ } if (rf & 2) {
103
+ const s_r8 = i0.ɵɵnextContext().$implicit;
104
+ const ctx_r1 = i0.ɵɵnextContext(3);
105
+ i0.ɵɵadvance(3);
106
+ i0.ɵɵtextInterpolate(s_r8.BestMatchTag);
107
+ i0.ɵɵadvance();
108
+ i0.ɵɵtextInterpolate1(" \u00B7 ", ctx_r1.FormatScore(s_r8.BestMatchScore));
109
+ } }
110
+ function ClassifyInboxTabComponent_Conditional_12_Conditional_23_For_1_Template(rf, ctx) { if (rf & 1) {
111
+ const _r7 = i0.ɵɵgetCurrentView();
112
+ i0.ɵɵelementStart(0, "div", 26);
113
+ i0.ɵɵlistener("click", function ClassifyInboxTabComponent_Conditional_12_Conditional_23_For_1_Template_div_click_0_listener() { const s_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.SelectSuggestion(s_r8)); });
114
+ i0.ɵɵelementStart(1, "div", 27)(2, "span", 28);
115
+ i0.ɵɵtext(3);
116
+ i0.ɵɵelementEnd();
117
+ i0.ɵɵelementStart(4, "span", 29);
118
+ i0.ɵɵtext(5);
119
+ i0.ɵɵelementEnd()();
120
+ i0.ɵɵelementStart(6, "div", 30)(7, "span", 31);
121
+ i0.ɵɵtext(8);
122
+ i0.ɵɵelementEnd();
123
+ i0.ɵɵconditionalCreate(9, ClassifyInboxTabComponent_Conditional_12_Conditional_23_For_1_Conditional_9_Template, 5, 2, "span", 32);
124
+ i0.ɵɵelementEnd()();
125
+ } if (rf & 2) {
126
+ const s_r8 = ctx.$implicit;
127
+ const ctx_r1 = i0.ɵɵnextContext(3);
128
+ i0.ɵɵclassProp("ci-sel", (ctx_r1.Selected == null ? null : ctx_r1.Selected.ID) === s_r8.ID);
129
+ i0.ɵɵadvance(3);
130
+ i0.ɵɵtextInterpolate1("\"", s_r8.ProposedName, "\"");
131
+ i0.ɵɵadvance(2);
132
+ i0.ɵɵtextInterpolate(ctx_r1.formatShortDate(s_r8.__mj_CreatedAt + ""));
133
+ i0.ɵɵadvance(2);
134
+ i0.ɵɵclassMap("ci-pill-" + ctx_r1.ReasonPill(s_r8.Reason));
135
+ i0.ɵɵadvance();
136
+ i0.ɵɵtextInterpolate(ctx_r1.ReasonLabel(s_r8.Reason));
137
+ i0.ɵɵadvance();
138
+ i0.ɵɵconditional(s_r8.BestMatchTag ? 9 : -1);
139
+ } }
140
+ function ClassifyInboxTabComponent_Conditional_12_Conditional_23_Template(rf, ctx) { if (rf & 1) {
141
+ i0.ɵɵrepeaterCreate(0, ClassifyInboxTabComponent_Conditional_12_Conditional_23_For_1_Template, 10, 8, "div", 25, _forTrack1);
142
+ } if (rf & 2) {
143
+ const ctx_r1 = i0.ɵɵnextContext(2);
144
+ i0.ɵɵrepeater(ctx_r1.FilteredSuggestions);
145
+ } }
146
+ function ClassifyInboxTabComponent_Conditional_12_Conditional_25_Template(rf, ctx) { if (rf & 1) {
147
+ i0.ɵɵelementStart(0, "div", 22);
148
+ i0.ɵɵelement(1, "i", 33);
149
+ i0.ɵɵelementStart(2, "p");
150
+ i0.ɵɵtext(3, "Select a suggestion to review it.");
151
+ i0.ɵɵelementEnd()();
152
+ } }
153
+ function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Conditional_17_Template(rf, ctx) { if (rf & 1) {
154
+ i0.ɵɵtext(0);
155
+ i0.ɵɵelementStart(1, "span", 42);
156
+ i0.ɵɵtext(2, "(existing tag)");
157
+ i0.ɵɵelementEnd();
158
+ } if (rf & 2) {
159
+ const ctx_r1 = i0.ɵɵnextContext(3);
160
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.Selected.BestMatchTag, " ");
161
+ } }
162
+ function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Conditional_18_Template(rf, ctx) { if (rf & 1) {
163
+ i0.ɵɵelementStart(0, "span", 42);
164
+ i0.ɵɵtext(1, "No close match");
165
+ i0.ɵɵelementEnd();
166
+ } }
167
+ function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Conditional_19_Template(rf, ctx) { if (rf & 1) {
168
+ i0.ɵɵelementStart(0, "div", 40);
169
+ i0.ɵɵtext(1, "From content item");
170
+ i0.ɵɵelementEnd();
171
+ i0.ɵɵelementStart(2, "div", 57);
172
+ i0.ɵɵtext(3);
173
+ i0.ɵɵelementEnd();
174
+ } if (rf & 2) {
175
+ const ctx_r1 = i0.ɵɵnextContext(3);
176
+ i0.ɵɵadvance(3);
177
+ i0.ɵɵtextInterpolate(ctx_r1.Selected.SourceContentItem);
178
+ } }
179
+ function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Conditional_20_Template(rf, ctx) { if (rf & 1) {
180
+ i0.ɵɵelementStart(0, "div", 40);
181
+ i0.ɵɵtext(1, "Source text");
182
+ i0.ɵɵelementEnd();
183
+ i0.ɵɵelementStart(2, "div", 58);
184
+ i0.ɵɵtext(3);
185
+ i0.ɵɵelementEnd();
186
+ } if (rf & 2) {
187
+ const ctx_r1 = i0.ɵɵnextContext(3);
188
+ i0.ɵɵadvance(3);
189
+ i0.ɵɵtextInterpolate(ctx_r1.Selected.SourceText);
190
+ } }
191
+ function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Conditional_21_Template(rf, ctx) { if (rf & 1) {
192
+ i0.ɵɵelementStart(0, "div", 43)(1, "h5");
193
+ i0.ɵɵtext(2, "Match confidence vs thresholds");
194
+ i0.ɵɵelementEnd();
195
+ i0.ɵɵelementStart(3, "div", 59);
196
+ i0.ɵɵelement(4, "div", 60);
197
+ i0.ɵɵelementStart(5, "div", 61);
198
+ i0.ɵɵtext(6);
199
+ i0.ɵɵelementEnd();
200
+ i0.ɵɵelement(7, "div", 60);
201
+ i0.ɵɵelementStart(8, "div", 61);
202
+ i0.ɵɵtext(9);
203
+ i0.ɵɵelementEnd();
204
+ i0.ɵɵelementStart(10, "div", 62);
205
+ i0.ɵɵtext(11);
206
+ i0.ɵɵelementEnd()();
207
+ i0.ɵɵelementStart(12, "div", 63)(13, "span");
208
+ i0.ɵɵtext(14, "reject / new");
209
+ i0.ɵɵelementEnd();
210
+ i0.ɵɵelementStart(15, "span");
211
+ i0.ɵɵtext(16, "review band");
212
+ i0.ɵɵelementEnd();
213
+ i0.ɵɵelementStart(17, "span");
214
+ i0.ɵɵtext(18, "auto-apply");
215
+ i0.ɵɵelementEnd()()();
216
+ } if (rf & 2) {
217
+ const ctx_r1 = i0.ɵɵnextContext(3);
218
+ i0.ɵɵadvance(4);
219
+ i0.ɵɵstyleProp("left", ctx_r1.ScorePct(ctx_r1.SuggestThreshold), "%");
220
+ i0.ɵɵadvance();
221
+ i0.ɵɵstyleProp("left", ctx_r1.ScorePct(ctx_r1.SuggestThreshold), "%");
222
+ i0.ɵɵadvance();
223
+ i0.ɵɵtextInterpolate1("Suggest ", ctx_r1.FormatScore(ctx_r1.SuggestThreshold));
224
+ i0.ɵɵadvance();
225
+ i0.ɵɵstyleProp("left", ctx_r1.ScorePct(ctx_r1.MatchThreshold), "%");
226
+ i0.ɵɵadvance();
227
+ i0.ɵɵstyleProp("left", ctx_r1.ScorePct(ctx_r1.MatchThreshold), "%");
228
+ i0.ɵɵadvance();
229
+ i0.ɵɵtextInterpolate1("Match ", ctx_r1.FormatScore(ctx_r1.MatchThreshold));
230
+ i0.ɵɵadvance();
231
+ i0.ɵɵstyleProp("left", ctx_r1.ScorePct(ctx_r1.Selected.BestMatchScore), "%");
232
+ i0.ɵɵadvance();
233
+ i0.ɵɵtextInterpolate(ctx_r1.FormatScore(ctx_r1.Selected.BestMatchScore));
234
+ } }
235
+ function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Template(rf, ctx) { if (rf & 1) {
236
+ const _r9 = i0.ɵɵgetCurrentView();
237
+ i0.ɵɵelementStart(0, "div", 34)(1, "div")(2, "div", 35);
238
+ i0.ɵɵtext(3);
239
+ i0.ɵɵelementEnd();
240
+ i0.ɵɵelementStart(4, "h4", 36);
241
+ i0.ɵɵtext(5);
242
+ i0.ɵɵelementEnd()();
243
+ i0.ɵɵelementStart(6, "span", 37);
244
+ i0.ɵɵelement(7, "i", 38);
245
+ i0.ɵɵtext(8);
246
+ i0.ɵɵelementEnd()();
247
+ i0.ɵɵelementStart(9, "div", 39)(10, "div", 40);
248
+ i0.ɵɵtext(11, "Proposed parent");
249
+ i0.ɵɵelementEnd();
250
+ i0.ɵɵelementStart(12, "div", 41);
251
+ i0.ɵɵtext(13);
252
+ i0.ɵɵelementEnd();
253
+ i0.ɵɵelementStart(14, "div", 40);
254
+ i0.ɵɵtext(15, "Best match");
255
+ i0.ɵɵelementEnd();
256
+ i0.ɵɵelementStart(16, "div", 41);
257
+ i0.ɵɵconditionalCreate(17, ClassifyInboxTabComponent_Conditional_12_Conditional_26_Conditional_17_Template, 3, 1)(18, ClassifyInboxTabComponent_Conditional_12_Conditional_26_Conditional_18_Template, 2, 0, "span", 42);
258
+ i0.ɵɵelementEnd();
259
+ i0.ɵɵconditionalCreate(19, ClassifyInboxTabComponent_Conditional_12_Conditional_26_Conditional_19_Template, 4, 1);
260
+ i0.ɵɵconditionalCreate(20, ClassifyInboxTabComponent_Conditional_12_Conditional_26_Conditional_20_Template, 4, 1);
261
+ i0.ɵɵelementEnd();
262
+ i0.ɵɵconditionalCreate(21, ClassifyInboxTabComponent_Conditional_12_Conditional_26_Conditional_21_Template, 19, 13, "div", 43);
263
+ i0.ɵɵelementStart(22, "div", 44)(23, "label", 45);
264
+ i0.ɵɵtext(24, "Merge target");
265
+ i0.ɵɵelementEnd();
266
+ i0.ɵɵelementStart(25, "mj-combobox", 46);
267
+ i0.ɵɵlistener("ValueChange", function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Template_mj_combobox_ValueChange_25_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnMergeTargetChange($event)); });
268
+ i0.ɵɵelementEnd()();
269
+ i0.ɵɵelementStart(26, "div", 47)(27, "label", 45);
270
+ i0.ɵɵtext(28, "Reviewer note (optional)");
271
+ i0.ɵɵelementEnd();
272
+ i0.ɵɵelementStart(29, "textarea", 48);
273
+ i0.ɵɵtwoWayListener("ngModelChange", function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Template_textarea_ngModelChange_29_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.ReviewerNotes, $event) || (ctx_r1.ReviewerNotes = $event); return i0.ɵɵresetView($event); });
274
+ i0.ɵɵelementEnd()();
275
+ i0.ɵɵelementStart(30, "div", 49)(31, "button", 50);
276
+ i0.ɵɵlistener("click", function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Template_button_click_31_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.MergeIntoExisting()); });
277
+ i0.ɵɵelement(32, "i", 51);
278
+ i0.ɵɵtext(33);
279
+ i0.ɵɵelementEnd();
280
+ i0.ɵɵelementStart(34, "button", 52);
281
+ i0.ɵɵlistener("click", function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Template_button_click_34_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ApproveAsNewTag()); });
282
+ i0.ɵɵelement(35, "i", 53);
283
+ i0.ɵɵtext(36, " Approve as new tag ");
284
+ i0.ɵɵelementEnd();
285
+ i0.ɵɵelement(37, "span", 54);
286
+ i0.ɵɵelementStart(38, "button", 55);
287
+ i0.ɵɵlistener("click", function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Template_button_click_38_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.Reject()); });
288
+ i0.ɵɵelement(39, "i", 56);
289
+ i0.ɵɵtext(40, " Reject ");
290
+ i0.ɵɵelementEnd()();
291
+ } if (rf & 2) {
292
+ const ctx_r1 = i0.ɵɵnextContext(2);
293
+ i0.ɵɵadvance(3);
294
+ i0.ɵɵtextInterpolate1(" Source \u00B7 ", ctx_r1.Selected.SourceContentSource ?? "Unknown source", " ");
295
+ i0.ɵɵadvance(2);
296
+ i0.ɵɵtextInterpolate1("\"", ctx_r1.Selected.ProposedName, "\"");
297
+ i0.ɵɵadvance();
298
+ i0.ɵɵclassMap("ci-pill-" + ctx_r1.ReasonPill(ctx_r1.Selected.Reason));
299
+ i0.ɵɵadvance(2);
300
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.ReasonLabel(ctx_r1.Selected.Reason), " ");
301
+ i0.ɵɵadvance(5);
302
+ i0.ɵɵtextInterpolate(ctx_r1.Selected.ProposedParent ?? "\u2014 (root)");
303
+ i0.ɵɵadvance(4);
304
+ i0.ɵɵconditional(ctx_r1.Selected.BestMatchTag ? 17 : 18);
305
+ i0.ɵɵadvance(2);
306
+ i0.ɵɵconditional(ctx_r1.Selected.SourceContentItem ? 19 : -1);
307
+ i0.ɵɵadvance();
308
+ i0.ɵɵconditional(ctx_r1.Selected.SourceText ? 20 : -1);
309
+ i0.ɵɵadvance();
310
+ i0.ɵɵconditional(ctx_r1.Selected.BestMatchScore != null ? 21 : -1);
311
+ i0.ɵɵadvance(4);
312
+ i0.ɵɵproperty("Data", ctx_r1.TagOptions)("ValuePrimitive", true)("Filterable", true)("ngModel", ctx_r1.MergeTargetID);
313
+ i0.ɵɵadvance(4);
314
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.ReviewerNotes);
315
+ i0.ɵɵadvance(2);
316
+ i0.ɵɵproperty("disabled", ctx_r1.IsActing || !ctx_r1.MergeTargetID);
317
+ i0.ɵɵadvance(2);
318
+ i0.ɵɵtextInterpolate1(" Merge into \"", ctx_r1.MergeTargetLabel || "\u2026", "\" ");
319
+ i0.ɵɵadvance();
320
+ i0.ɵɵproperty("disabled", ctx_r1.IsActing);
321
+ i0.ɵɵadvance(4);
322
+ i0.ɵɵproperty("disabled", ctx_r1.IsActing);
323
+ } }
324
+ function ClassifyInboxTabComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
325
+ const _r1 = i0.ɵɵgetCurrentView();
326
+ i0.ɵɵelementStart(0, "div", 9)(1, "div", 14)(2, "h5");
327
+ i0.ɵɵtext(3, "By reason");
328
+ i0.ɵɵelementEnd();
329
+ i0.ɵɵelementStart(4, "a", 15);
330
+ i0.ɵɵlistener("click", function ClassifyInboxTabComponent_Conditional_12_Template_a_click_4_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.SetReasonFilter("")); });
331
+ i0.ɵɵtext(5, " All ");
332
+ i0.ɵɵelementStart(6, "span", 16);
333
+ i0.ɵɵtext(7);
334
+ i0.ɵɵelementEnd()();
335
+ i0.ɵɵrepeaterCreate(8, ClassifyInboxTabComponent_Conditional_12_For_9_Template, 4, 4, "a", 17, _forTrack0);
336
+ i0.ɵɵelementStart(10, "h5", 18);
337
+ i0.ɵɵtext(11, "Status");
338
+ i0.ɵɵelementEnd();
339
+ i0.ɵɵrepeaterCreate(12, ClassifyInboxTabComponent_Conditional_12_For_13_Template, 2, 3, "a", 17, i0.ɵɵrepeaterTrackByIdentity);
340
+ i0.ɵɵelementStart(14, "h5", 18);
341
+ i0.ɵɵtext(15, "Scope");
342
+ i0.ɵɵelementEnd();
343
+ i0.ɵɵelementStart(16, "a", 15);
344
+ i0.ɵɵlistener("click", function ClassifyInboxTabComponent_Conditional_12_Template_a_click_16_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ToggleHealthReasons()); });
345
+ i0.ɵɵelementStart(17, "span");
346
+ i0.ɵɵelement(18, "i", 19);
347
+ i0.ɵɵtext(19, " Include health reasons");
348
+ i0.ɵɵelementEnd();
349
+ i0.ɵɵelement(20, "i", 20);
350
+ i0.ɵɵelementEnd()();
351
+ i0.ɵɵelementStart(21, "div", 21);
352
+ i0.ɵɵconditionalCreate(22, ClassifyInboxTabComponent_Conditional_12_Conditional_22_Template, 5, 4, "div", 22)(23, ClassifyInboxTabComponent_Conditional_12_Conditional_23_Template, 2, 0);
353
+ i0.ɵɵelementEnd();
354
+ i0.ɵɵelementStart(24, "div", 23);
355
+ i0.ɵɵconditionalCreate(25, ClassifyInboxTabComponent_Conditional_12_Conditional_25_Template, 4, 0, "div", 22)(26, ClassifyInboxTabComponent_Conditional_12_Conditional_26_Template, 41, 19);
356
+ i0.ɵɵelementEnd()();
357
+ } if (rf & 2) {
358
+ const ctx_r1 = i0.ɵɵnextContext();
359
+ i0.ɵɵadvance(4);
360
+ i0.ɵɵclassProp("ci-active", ctx_r1.ReasonFilter === "");
361
+ i0.ɵɵadvance(3);
362
+ i0.ɵɵtextInterpolate(ctx_r1.TotalLoadedCount);
363
+ i0.ɵɵadvance();
364
+ i0.ɵɵrepeater(ctx_r1.ReasonCounts);
365
+ i0.ɵɵadvance(4);
366
+ i0.ɵɵrepeater(ctx_r1.StatusOptions);
367
+ i0.ɵɵadvance(4);
368
+ i0.ɵɵclassProp("ci-active", ctx_r1.IncludeHealthReasons);
369
+ i0.ɵɵadvance(4);
370
+ i0.ɵɵclassProp("fa-toggle-on", ctx_r1.IncludeHealthReasons)("fa-toggle-off", !ctx_r1.IncludeHealthReasons);
371
+ i0.ɵɵadvance(2);
372
+ i0.ɵɵconditional(ctx_r1.FilteredSuggestions.length === 0 ? 22 : 23);
373
+ i0.ɵɵadvance(3);
374
+ i0.ɵɵconditional(!ctx_r1.Selected ? 25 : 26);
375
+ } }
376
+ /** Reasons owned by the Health tab — excluded from the Inbox default view. */
377
+ const HEALTH_REASONS = ['MergeCandidate', 'LowUsage', 'WideNode'];
378
+ /** Human-readable labels + pill class for each Reason value. */
379
+ const REASON_META = {
380
+ ConstrainedMode: { label: 'Constrained mode', pill: 'gray' },
381
+ BelowThreshold: { label: 'Below threshold', pill: 'amber' },
382
+ ParentFrozen: { label: 'Parent frozen', pill: 'red' },
383
+ AutoGrowDisabled: { label: 'Auto-grow disabled', pill: 'gray' },
384
+ MaxChildrenExceeded: { label: 'Max children', pill: 'red' },
385
+ MaxDepthExceeded: { label: 'Max depth', pill: 'red' },
386
+ BelowMinWeight: { label: 'Below min weight', pill: 'amber' },
387
+ RequiresReview: { label: 'Requires review', pill: 'amber' },
388
+ MergeCandidate: { label: 'Merge candidate', pill: 'blue' },
389
+ LowUsage: { label: 'Low usage', pill: 'gray' },
390
+ WideNode: { label: 'Wide node', pill: 'blue' },
391
+ };
392
+ export class ClassifyInboxTabComponent extends BaseAngularComponent {
393
+ cdr = inject(ChangeDetectorRef);
394
+ /** Threshold markers shown on the band gradient (match the server defaults). */
395
+ SuggestThreshold = 0.70;
396
+ MatchThreshold = 0.87;
397
+ // ── Loaded data (NOT cached — transactional) ──
398
+ allSuggestions = [];
399
+ FilteredSuggestions = [];
400
+ ReasonCounts = [];
401
+ Selected = null;
402
+ IsLoading = false;
403
+ hasLoaded = false;
404
+ // ── Filters ──
405
+ StatusFilter = 'Pending';
406
+ StatusOptions = ['Pending', 'Approved', 'Merged', 'Rejected'];
407
+ /** Active reason filter; '' = all (human-review reasons), 'all' = include health reasons. */
408
+ ReasonFilter = '';
409
+ /** When true, include the 3 Health-owned reasons that the Health tab normally owns. */
410
+ IncludeHealthReasons = false;
411
+ // ── Merge-target state ──
412
+ TagOptions = [];
413
+ /** Selected merge-target tag ID (defaults to BestMatchTagID on selection). */
414
+ MergeTargetID = null;
415
+ ReviewerNotes = '';
416
+ IsActing = false;
417
+ /** Number of Pending suggestions currently in the loaded set (for the host badge). */
418
+ get PendingCount() {
419
+ return this.StatusFilter === 'Pending' ? this.allSuggestions.length : 0;
420
+ }
421
+ /** Total loaded suggestions (across all reasons) for the "All" filter count. */
422
+ get TotalLoadedCount() {
423
+ return this.allSuggestions.length;
424
+ }
425
+ /** Template-facing formatter. */
426
+ formatShortDate = formatShortDate;
427
+ /** Emitted after any Approve/Merge/Reject so the host refreshes its pending badge. */
428
+ Resolved = new EventEmitter();
429
+ // ════════════════════════════════════════════
430
+ // ACTIVATION + LOAD
431
+ // ════════════════════════════════════════════
432
+ /** Lazy-load on first activation (host calls this when the tab becomes active). */
433
+ async EnsureLoaded() {
434
+ if (this.hasLoaded)
435
+ return;
436
+ this.hasLoaded = true;
437
+ await Promise.all([this.loadSuggestions(), this.loadTagOptions()]);
438
+ }
439
+ /** Public refresh — re-pull suggestions for the current status filter. */
440
+ async Refresh() {
441
+ await this.loadSuggestions();
442
+ }
443
+ buildStatusFilterClause() {
444
+ // Health-reason suggestions (MergeCandidate / LowUsage / WideNode) are owned
445
+ // by the Health tab. By default the Inbox shows only the human-review reasons
446
+ // and EXCLUDES the 3 health reasons; the "include health reasons" toggle lifts
447
+ // that exclusion so an operator can see everything in one place.
448
+ const statusClause = `Status='${this.StatusFilter}'`;
449
+ if (this.IncludeHealthReasons)
450
+ return statusClause;
451
+ const excluded = HEALTH_REASONS.map(r => `'${r}'`).join(',');
452
+ return `${statusClause} AND Reason NOT IN (${excluded})`;
453
+ }
454
+ async loadSuggestions() {
455
+ this.IsLoading = true;
456
+ this.cdr.detectChanges();
457
+ const rv = RunView.FromMetadataProvider(this.ProviderToUse);
458
+ const result = await rv.RunView({
459
+ EntityName: 'MJ: Tag Suggestions',
460
+ ExtraFilter: this.buildStatusFilterClause(),
461
+ OrderBy: '__mj_CreatedAt DESC',
462
+ ResultType: 'entity_object',
463
+ }, this.ProviderToUse.CurrentUser);
464
+ this.allSuggestions = result.Success ? result.Results : [];
465
+ this.buildReasonCounts();
466
+ this.applyReasonFilter();
467
+ this.IsLoading = false;
468
+ this.cdr.detectChanges();
469
+ }
470
+ async loadTagOptions() {
471
+ await TagEngineBase.Instance.Config(false, this.ProviderToUse.CurrentUser, this.ProviderToUse);
472
+ this.TagOptions = TagEngineBase.Instance.Tags
473
+ .filter(t => t.Status === 'Active')
474
+ .map(t => ({ ID: t.ID, Label: t.DisplayName || t.Name }))
475
+ .sort((a, b) => a.Label.localeCompare(b.Label));
476
+ }
477
+ // ════════════════════════════════════════════
478
+ // FILTERING
479
+ // ════════════════════════════════════════════
480
+ buildReasonCounts() {
481
+ const counts = new Map();
482
+ for (const s of this.allSuggestions) {
483
+ counts.set(s.Reason, (counts.get(s.Reason) ?? 0) + 1);
484
+ }
485
+ this.ReasonCounts = Array.from(counts.entries())
486
+ .map(([Reason, Count]) => ({ Reason, Label: this.ReasonLabel(Reason), Count }))
487
+ .sort((a, b) => b.Count - a.Count);
488
+ }
489
+ applyReasonFilter() {
490
+ this.FilteredSuggestions = this.ReasonFilter
491
+ ? this.allSuggestions.filter(s => s.Reason === this.ReasonFilter)
492
+ : this.allSuggestions;
493
+ // Keep selection valid; otherwise select the first row.
494
+ if (!this.Selected || !this.FilteredSuggestions.some(s => UUIDsEqual(s.ID, this.Selected.ID))) {
495
+ this.SelectSuggestion(this.FilteredSuggestions[0] ?? null);
496
+ }
497
+ }
498
+ SetReasonFilter(reason) {
499
+ this.ReasonFilter = reason;
500
+ this.applyReasonFilter();
501
+ this.cdr.detectChanges();
502
+ }
503
+ async SetStatusFilter(status) {
504
+ if (status === this.StatusFilter)
505
+ return;
506
+ this.StatusFilter = status;
507
+ this.ReasonFilter = '';
508
+ this.Selected = null;
509
+ await this.loadSuggestions();
510
+ }
511
+ async ToggleHealthReasons() {
512
+ this.IncludeHealthReasons = !this.IncludeHealthReasons;
513
+ this.ReasonFilter = '';
514
+ await this.loadSuggestions();
515
+ }
516
+ SelectSuggestion(suggestion) {
517
+ this.Selected = suggestion;
518
+ this.MergeTargetID = suggestion?.BestMatchTagID ?? null;
519
+ this.ReviewerNotes = '';
520
+ this.cdr.detectChanges();
521
+ }
522
+ OnMergeTargetChange(value) {
523
+ this.MergeTargetID = value ?? null;
524
+ }
525
+ // ════════════════════════════════════════════
526
+ // DISPLAY HELPERS
527
+ // ════════════════════════════════════════════
528
+ ReasonLabel(reason) {
529
+ return REASON_META[reason]?.label ?? reason;
530
+ }
531
+ ReasonPill(reason) {
532
+ return REASON_META[reason]?.pill ?? 'gray';
533
+ }
534
+ /** Score as a 0..100 percent for band/marker positioning. */
535
+ ScorePct(score) {
536
+ if (score == null)
537
+ return 0;
538
+ return Math.round(Math.min(1, Math.max(0, score)) * 100);
539
+ }
540
+ FormatScore(score) {
541
+ return score == null ? '—' : score.toFixed(2);
542
+ }
543
+ /** Resolve the merge-target tag's display label for confirmation copy. */
544
+ get MergeTargetLabel() {
545
+ if (!this.MergeTargetID)
546
+ return '';
547
+ return this.TagOptions.find(t => UUIDsEqual(t.ID, this.MergeTargetID))?.Label ?? 'selected tag';
548
+ }
549
+ // ════════════════════════════════════════════
550
+ // ACTIONS — entity-level mutations on the client
551
+ // ════════════════════════════════════════════
552
+ //
553
+ // NOTE: full content-item-tag re-pointing (moving every ContentItemTag from the
554
+ // suggested name onto the resolved tag) is handled by the server-side promotion
555
+ // job. This UI performs the CORE promotion: it creates/links the tag and stamps
556
+ // the suggestion's Status / ResolvedTagID / reviewer fields. The server-only
557
+ // TagGovernanceEngine is intentionally NOT used here (it is server-side).
558
+ stampReviewFields(suggestion) {
559
+ suggestion.ReviewedByUserID = this.ProviderToUse.CurrentUser.ID;
560
+ suggestion.ReviewedAt = new Date();
561
+ if (this.ReviewerNotes.trim()) {
562
+ suggestion.ReviewerNotes = this.ReviewerNotes.trim();
563
+ }
564
+ }
565
+ /** Approve as a brand-new tag: create the MJTagEntity, then resolve the suggestion. */
566
+ async ApproveAsNewTag() {
567
+ const suggestion = this.Selected;
568
+ if (!suggestion || this.IsActing)
569
+ return;
570
+ this.IsActing = true;
571
+ this.cdr.detectChanges();
572
+ try {
573
+ const p = this.ProviderToUse;
574
+ const tag = await p.GetEntityObject('MJ: Tags', p.CurrentUser);
575
+ tag.NewRecord();
576
+ tag.Name = suggestion.ProposedName;
577
+ tag.DisplayName = suggestion.ProposedName;
578
+ tag.ParentID = suggestion.ProposedParentID;
579
+ const tagSaved = await tag.Save();
580
+ if (!tagSaved) {
581
+ this.notifyFailure('Failed to create tag', tag.LatestResult?.CompleteMessage);
582
+ return;
583
+ }
584
+ this.stampReviewFields(suggestion);
585
+ suggestion.Status = 'Approved';
586
+ suggestion.ResolvedTagID = tag.ID;
587
+ const sugSaved = await suggestion.Save();
588
+ if (!sugSaved) {
589
+ this.notifyFailure('Tag created but failed to resolve suggestion', suggestion.LatestResult?.CompleteMessage);
590
+ return;
591
+ }
592
+ MJNotificationService.Instance.CreateSimpleNotification(`Approved "${suggestion.ProposedName}" as a new tag`, 'success', 3000);
593
+ this.finishAction(suggestion);
594
+ }
595
+ catch (error) {
596
+ this.notifyError(error);
597
+ }
598
+ finally {
599
+ this.IsActing = false;
600
+ this.cdr.detectChanges();
601
+ }
602
+ }
603
+ /** Merge into an existing tag (default target = BestMatchTagID, override via dropdown). */
604
+ async MergeIntoExisting() {
605
+ const suggestion = this.Selected;
606
+ if (!suggestion || this.IsActing)
607
+ return;
608
+ if (!this.MergeTargetID) {
609
+ MJNotificationService.Instance.CreateSimpleNotification('Select a tag to merge into first', 'warning', 3000);
610
+ return;
611
+ }
612
+ this.IsActing = true;
613
+ this.cdr.detectChanges();
614
+ try {
615
+ this.stampReviewFields(suggestion);
616
+ suggestion.Status = 'Merged';
617
+ suggestion.ResolvedTagID = this.MergeTargetID;
618
+ const saved = await suggestion.Save();
619
+ if (!saved) {
620
+ this.notifyFailure('Failed to merge suggestion', suggestion.LatestResult?.CompleteMessage);
621
+ return;
622
+ }
623
+ MJNotificationService.Instance.CreateSimpleNotification(`Merged "${suggestion.ProposedName}" into "${this.MergeTargetLabel}"`, 'success', 3000);
624
+ this.finishAction(suggestion);
625
+ }
626
+ catch (error) {
627
+ this.notifyError(error);
628
+ }
629
+ finally {
630
+ this.IsActing = false;
631
+ this.cdr.detectChanges();
632
+ }
633
+ }
634
+ /** Reject the suggestion. */
635
+ async Reject() {
636
+ const suggestion = this.Selected;
637
+ if (!suggestion || this.IsActing)
638
+ return;
639
+ this.IsActing = true;
640
+ this.cdr.detectChanges();
641
+ try {
642
+ this.stampReviewFields(suggestion);
643
+ suggestion.Status = 'Rejected';
644
+ const saved = await suggestion.Save();
645
+ if (!saved) {
646
+ this.notifyFailure('Failed to reject suggestion', suggestion.LatestResult?.CompleteMessage);
647
+ return;
648
+ }
649
+ MJNotificationService.Instance.CreateSimpleNotification(`Rejected "${suggestion.ProposedName}"`, 'success', 2500);
650
+ this.finishAction(suggestion);
651
+ }
652
+ catch (error) {
653
+ this.notifyError(error);
654
+ }
655
+ finally {
656
+ this.IsActing = false;
657
+ this.cdr.detectChanges();
658
+ }
659
+ }
660
+ /** Remove a resolved row, advance selection, rebuild counts, notify the host. */
661
+ finishAction(resolved) {
662
+ const idx = this.FilteredSuggestions.findIndex(s => UUIDsEqual(s.ID, resolved.ID));
663
+ this.allSuggestions = this.allSuggestions.filter(s => !UUIDsEqual(s.ID, resolved.ID));
664
+ this.buildReasonCounts();
665
+ this.applyReasonFilterAfterRemoval(idx);
666
+ this.Resolved.emit();
667
+ this.cdr.detectChanges();
668
+ }
669
+ /** Rebuild the filtered list and advance selection to the next sensible row. */
670
+ applyReasonFilterAfterRemoval(removedIndex) {
671
+ this.FilteredSuggestions = this.ReasonFilter
672
+ ? this.allSuggestions.filter(s => s.Reason === this.ReasonFilter)
673
+ : this.allSuggestions;
674
+ const next = this.FilteredSuggestions[removedIndex] ?? this.FilteredSuggestions[removedIndex - 1] ?? null;
675
+ this.SelectSuggestion(next);
676
+ }
677
+ notifyFailure(prefix, detail) {
678
+ MJNotificationService.Instance.CreateSimpleNotification(`${prefix}: ${detail ?? 'unknown error'}`, 'error', 5000);
679
+ }
680
+ notifyError(error) {
681
+ const msg = error instanceof Error ? error.message : String(error);
682
+ MJNotificationService.Instance.CreateSimpleNotification(`Error: ${msg}`, 'error', 5000);
683
+ }
684
+ static ɵfac = /*@__PURE__*/ (() => { let ɵClassifyInboxTabComponent_BaseFactory; return function ClassifyInboxTabComponent_Factory(__ngFactoryType__) { return (ɵClassifyInboxTabComponent_BaseFactory || (ɵClassifyInboxTabComponent_BaseFactory = i0.ɵɵgetInheritedFactory(ClassifyInboxTabComponent)))(__ngFactoryType__ || ClassifyInboxTabComponent); }; })();
685
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ClassifyInboxTabComponent, selectors: [["classify-inbox-tab"]], outputs: { Resolved: "Resolved" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 13, vars: 8, consts: [["Title", "Suggestions Inbox", "Subtitle", "Review classifications that landed in the ambiguous band"], ["meta", ""], [1, "ci-status-pill"], [1, "fa-solid", "fa-inbox"], ["actions", ""], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click", "disabled"], [3, "Padding", "Flex"], [1, "at-main-area"], [1, "at-page-body"], [1, "ci-inbox"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "mj-action-label"], [1, "fa-solid", "fa-arrows-rotate"], ["text", "Loading suggestions\u2026"], [1, "ci-col", "ci-filter"], [1, "ci-filter-link", 3, "click"], [1, "ci-n"], [1, "ci-filter-link", 3, "ci-active"], [1, "ci-section-gap"], [1, "fa-solid", "fa-heart-pulse"], [1, "fa-solid"], [1, "ci-col", "ci-list"], [1, "at-empty-state"], [1, "ci-col", "ci-read"], [1, "fa-solid", "fa-check-circle"], [1, "ci-row", 3, "ci-sel"], [1, "ci-row", 3, "click"], [1, "ci-row-top"], [1, "ci-row-name"], [1, "ci-row-ago"], [1, "ci-row-reason"], [1, "ci-pill"], [1, "ci-row-match"], [1, "fa-solid", "fa-hand-pointer"], [1, "ci-read-head"], [1, "ci-read-source"], [1, "ci-read-title"], [1, "ci-pill", "ci-pill-lg"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "ci-kv"], [1, "ci-k"], [1, "ci-v"], [1, "ci-muted"], [1, "ci-band"], [1, "ci-merge-picker"], [1, "ci-merge-label"], ["TextField", "Label", "ValueField", "ID", "Placeholder", "Choose a tag to merge into\u2026", 3, "ValueChange", "Data", "ValuePrimitive", "Filterable", "ngModel"], [1, "ci-note"], ["rows", "2", "placeholder", "Why this decision\u2026", 1, "mj-textarea", "ci-note-input", 3, "ngModelChange", "ngModel"], [1, "ci-actbar"], ["mjButton", "", "variant", "success", "size", "sm", 3, "click", "disabled"], [1, "fa-solid", "fa-code-merge"], ["mjButton", "", "variant", "primary", "size", "sm", 3, "click", "disabled"], [1, "fa-solid", "fa-plus"], [1, "ci-actbar-spacer"], ["mjButton", "", "variant", "danger", "size", "sm", 3, "click", "disabled"], [1, "fa-solid", "fa-xmark"], [1, "ci-v", "ci-link"], [1, "ci-v", "ci-source-text"], [1, "ci-bandbar"], [1, "ci-bandmark"], [1, "ci-bandmark-label"], [1, "ci-bandscore"], [1, "ci-bandlabels"]], template: function ClassifyInboxTabComponent_Template(rf, ctx) { if (rf & 1) {
686
+ i0.ɵɵelementStart(0, "mj-page-header-interior", 0)(1, "div", 1)(2, "span", 2);
687
+ i0.ɵɵelement(3, "i", 3);
688
+ i0.ɵɵtext(4);
689
+ i0.ɵɵelementEnd()();
690
+ i0.ɵɵelementStart(5, "div", 4)(6, "button", 5);
691
+ i0.ɵɵlistener("click", function ClassifyInboxTabComponent_Template_button_click_6_listener() { return ctx.Refresh(); });
692
+ i0.ɵɵconditionalCreate(7, ClassifyInboxTabComponent_Conditional_7_Template, 3, 0)(8, ClassifyInboxTabComponent_Conditional_8_Template, 3, 0);
693
+ i0.ɵɵelementEnd()()();
694
+ i0.ɵɵelementStart(9, "mj-page-body-interior", 6)(10, "div", 7);
695
+ i0.ɵɵconditionalCreate(11, ClassifyInboxTabComponent_Conditional_11_Template, 2, 0, "div", 8)(12, ClassifyInboxTabComponent_Conditional_12_Template, 27, 11, "div", 9);
696
+ i0.ɵɵelementEnd()();
697
+ } if (rf & 2) {
698
+ i0.ɵɵadvance(2);
699
+ i0.ɵɵclassProp("ci-status-pill-active", ctx.PendingCount > 0);
700
+ i0.ɵɵadvance(2);
701
+ i0.ɵɵtextInterpolate1(" ", ctx.PendingCount, " pending ");
702
+ i0.ɵɵadvance(2);
703
+ i0.ɵɵproperty("disabled", ctx.IsLoading);
704
+ i0.ɵɵadvance();
705
+ i0.ɵɵconditional(ctx.IsLoading ? 7 : 8);
706
+ i0.ɵɵadvance(2);
707
+ i0.ɵɵproperty("Padding", false)("Flex", true);
708
+ i0.ɵɵadvance(2);
709
+ i0.ɵɵconditional(ctx.IsLoading ? 11 : 12);
710
+ } }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel, i2.LoadingComponent, i3.MJButtonDirective, i3.MJComboboxComponent, i3.MJPageHeaderInteriorComponent, i3.MJPageBodyInteriorComponent, i4.LowerCasePipe], styles: ["\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.ci-inbox[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 180px 320px 1fr;\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n min-height: 460px;\n margin: 12px;\n background: var(--mj-bg-surface);\n}\n\n.ci-col[_ngcontent-%COMP%] {\n border-right: 1px solid var(--mj-border-default);\n overflow: auto;\n}\n.ci-col[_ngcontent-%COMP%]:last-child {\n border-right: 0;\n}\n\n\n\n.ci-filter[_ngcontent-%COMP%] {\n padding: 12px;\n background: var(--mj-bg-surface-card);\n}\n.ci-filter[_ngcontent-%COMP%] h5[_ngcontent-%COMP%] {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n margin: 0 0 8px;\n}\n.ci-section-gap[_ngcontent-%COMP%] {\n margin-top: 14px;\n}\n.ci-filter-link[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 8px;\n padding: 7px 9px;\n border-radius: 7px;\n color: var(--mj-text-secondary);\n font-size: 12.5px;\n font-weight: 600;\n cursor: pointer;\n margin-bottom: 2px;\n}\n.ci-filter-link[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n.ci-filter-link.ci-active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n box-shadow: inset 0 0 0 1px var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n.ci-n[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n\n\n.ci-list[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n}\n.ci-row[_ngcontent-%COMP%] {\n padding: 11px 13px;\n border-bottom: 1px solid var(--mj-border-subtle);\n cursor: pointer;\n}\n.ci-row[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n.ci-row.ci-sel[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n box-shadow: inset 3px 0 0 var(--mj-brand-primary);\n}\n.ci-row-top[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n gap: 8px;\n}\n.ci-row-name[_ngcontent-%COMP%] {\n font-weight: 700;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n.ci-row-ago[_ngcontent-%COMP%] {\n font-size: 10.5px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n.ci-row-reason[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n display: flex;\n align-items: center;\n gap: 6px;\n flex-wrap: wrap;\n}\n.ci-row-match[_ngcontent-%COMP%] b[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n}\n\n\n\n.ci-read[_ngcontent-%COMP%] {\n padding: 18px 20px;\n}\n.ci-read-head[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 12px;\n}\n.ci-read-source[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n font-family: var(--mj-font-mono, monospace);\n}\n.ci-read-title[_ngcontent-%COMP%] {\n font-size: 17px;\n margin: 4px 0 0;\n color: var(--mj-text-primary);\n}\n.ci-kv[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 130px 1fr;\n gap: 7px 12px;\n margin: 16px 0;\n font-size: 13px;\n}\n.ci-k[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n.ci-v[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n.ci-muted[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-weight: 400;\n}\n.ci-link[_ngcontent-%COMP%] {\n color: var(--mj-text-link);\n}\n.ci-source-text[_ngcontent-%COMP%] {\n font-weight: 400;\n color: var(--mj-text-secondary);\n max-height: 80px;\n overflow: auto;\n white-space: pre-wrap;\n}\n\n\n\n.ci-band[_ngcontent-%COMP%] {\n margin: 18px 0;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n padding: 14px;\n}\n.ci-band[_ngcontent-%COMP%] h5[_ngcontent-%COMP%] {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n margin: 0 0 30px;\n}\n.ci-bandbar[_ngcontent-%COMP%] {\n position: relative;\n height: 10px;\n border-radius: 6px;\n \n\n background: linear-gradient(90deg,\n color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-bg-surface)) 0%,\n color-mix(in srgb, var(--mj-status-warning) 30%, var(--mj-bg-surface)) 55%,\n color-mix(in srgb, var(--mj-status-success) 30%, var(--mj-bg-surface)) 78%,\n color-mix(in srgb, var(--mj-status-success) 45%, var(--mj-bg-surface)) 100%);\n}\n.ci-bandmark[_ngcontent-%COMP%] {\n position: absolute;\n top: -6px;\n width: 2px;\n height: 22px;\n background: var(--mj-text-primary);\n transform: translateX(-50%);\n}\n.ci-bandmark-label[_ngcontent-%COMP%] {\n position: absolute;\n top: -20px;\n transform: translateX(-50%);\n font-size: 9px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n.ci-bandscore[_ngcontent-%COMP%] {\n position: absolute;\n top: -30px;\n transform: translateX(-50%);\n font-size: 11px;\n font-weight: 800;\n background: var(--mj-text-primary);\n color: var(--mj-text-inverse);\n padding: 2px 7px;\n border-radius: 6px;\n}\n.ci-bandlabels[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n margin-top: 9px;\n font-size: 10.5px;\n color: var(--mj-text-muted);\n}\n\n\n\n.ci-merge-picker[_ngcontent-%COMP%], \n.ci-note[_ngcontent-%COMP%] {\n margin: 14px 0;\n}\n.ci-merge-label[_ngcontent-%COMP%] {\n display: block;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n margin-bottom: 6px;\n}\n.ci-note-input[_ngcontent-%COMP%] {\n width: 100%;\n resize: vertical;\n}\n\n\n\n.ci-actbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 9px;\n margin-top: 16px;\n padding-top: 16px;\n border-top: 1px solid var(--mj-border-default);\n}\n.ci-actbar-spacer[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n\n\n.ci-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 10px;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 999px;\n white-space: nowrap;\n}\n.ci-pill-lg[_ngcontent-%COMP%] {\n font-size: 12px;\n padding: 4px 12px;\n}\n.ci-pill-gray[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n.ci-pill-amber[_ngcontent-%COMP%] {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n}\n.ci-pill-red[_ngcontent-%COMP%] {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n}\n.ci-pill-blue[_ngcontent-%COMP%] {\n background: var(--mj-status-info-bg);\n color: var(--mj-status-info-text);\n}\n\n\n\n.ci-status-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n padding: 3px 10px;\n border-radius: 999px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n.ci-status-pill-active[_ngcontent-%COMP%] {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n}"] });
711
+ }
712
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ClassifyInboxTabComponent, [{
713
+ type: Component,
714
+ args: [{ standalone: false, selector: 'classify-inbox-tab', template: "<mj-page-header-interior\n Title=\"Suggestions Inbox\"\n Subtitle=\"Review classifications that landed in the ambiguous band\">\n <div meta>\n <span class=\"ci-status-pill\" [class.ci-status-pill-active]=\"PendingCount > 0\">\n <i class=\"fa-solid fa-inbox\"></i>\n {{ PendingCount }} pending\n </span>\n </div>\n <div actions>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"Refresh()\" [disabled]=\"IsLoading\">\n @if (IsLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> <span class=\"mj-action-label\">Refreshing\u2026</span>\n } @else {\n <i class=\"fa-solid fa-arrows-rotate\"></i> <span class=\"mj-action-label\">Refresh</span>\n }\n </button>\n </div>\n</mj-page-header-interior>\n\n<mj-page-body-interior [Padding]=\"false\" [Flex]=\"true\">\n <div class=\"at-main-area\">\n @if (IsLoading) {\n <div class=\"at-page-body\">\n <mj-loading text=\"Loading suggestions\u2026\"></mj-loading>\n </div>\n } @else {\n <div class=\"ci-inbox\">\n\n <!-- \u2500\u2500 (1) FILTER RAIL \u2500\u2500 -->\n <div class=\"ci-col ci-filter\">\n <h5>By reason</h5>\n <a class=\"ci-filter-link\" [class.ci-active]=\"ReasonFilter === ''\" (click)=\"SetReasonFilter('')\">\n All <span class=\"ci-n\">{{ TotalLoadedCount }}</span>\n </a>\n @for (rc of ReasonCounts; track rc.Reason) {\n <a class=\"ci-filter-link\" [class.ci-active]=\"ReasonFilter === rc.Reason\" (click)=\"SetReasonFilter(rc.Reason)\">\n {{ rc.Label }} <span class=\"ci-n\">{{ rc.Count }}</span>\n </a>\n }\n\n <h5 class=\"ci-section-gap\">Status</h5>\n @for (st of StatusOptions; track st) {\n <a class=\"ci-filter-link\" [class.ci-active]=\"StatusFilter === st\" (click)=\"SetStatusFilter(st)\">\n {{ st }}\n </a>\n }\n\n <h5 class=\"ci-section-gap\">Scope</h5>\n <a class=\"ci-filter-link\" [class.ci-active]=\"IncludeHealthReasons\" (click)=\"ToggleHealthReasons()\">\n <span><i class=\"fa-solid fa-heart-pulse\"></i> Include health reasons</span>\n <i class=\"fa-solid\" [class.fa-toggle-on]=\"IncludeHealthReasons\" [class.fa-toggle-off]=\"!IncludeHealthReasons\"></i>\n </a>\n </div>\n\n <!-- \u2500\u2500 (2) SUGGESTION LIST \u2500\u2500 -->\n <div class=\"ci-col ci-list\">\n @if (FilteredSuggestions.length === 0) {\n <div class=\"at-empty-state\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <p>No {{ StatusFilter | lowercase }} suggestions{{ ReasonFilter ? ' for this reason' : '' }}.</p>\n </div>\n } @else {\n @for (s of FilteredSuggestions; track s.ID) {\n <div class=\"ci-row\" [class.ci-sel]=\"Selected?.ID === s.ID\" (click)=\"SelectSuggestion(s)\">\n <div class=\"ci-row-top\">\n <span class=\"ci-row-name\">\"{{ s.ProposedName }}\"</span>\n <span class=\"ci-row-ago\">{{ formatShortDate(s.__mj_CreatedAt + '') }}</span>\n </div>\n <div class=\"ci-row-reason\">\n <span class=\"ci-pill\" [class]=\"'ci-pill-' + ReasonPill(s.Reason)\">{{ ReasonLabel(s.Reason) }}</span>\n @if (s.BestMatchTag) {\n <span class=\"ci-row-match\">\u2248 <b>{{ s.BestMatchTag }}</b> \u00B7 {{ FormatScore(s.BestMatchScore) }}</span>\n }\n </div>\n </div>\n }\n }\n </div>\n\n <!-- \u2500\u2500 (3) READING PANE \u2500\u2500 -->\n <div class=\"ci-col ci-read\">\n @if (!Selected) {\n <div class=\"at-empty-state\">\n <i class=\"fa-solid fa-hand-pointer\"></i>\n <p>Select a suggestion to review it.</p>\n </div>\n } @else {\n <div class=\"ci-read-head\">\n <div>\n <div class=\"ci-read-source\">\n Source \u00B7 {{ Selected.SourceContentSource ?? 'Unknown source' }}\n </div>\n <h4 class=\"ci-read-title\">\"{{ Selected.ProposedName }}\"</h4>\n </div>\n <span class=\"ci-pill ci-pill-lg\" [class]=\"'ci-pill-' + ReasonPill(Selected.Reason)\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i> {{ ReasonLabel(Selected.Reason) }}\n </span>\n </div>\n\n <div class=\"ci-kv\">\n <div class=\"ci-k\">Proposed parent</div>\n <div class=\"ci-v\">{{ Selected.ProposedParent ?? '\u2014 (root)' }}</div>\n\n <div class=\"ci-k\">Best match</div>\n <div class=\"ci-v\">\n @if (Selected.BestMatchTag) {\n {{ Selected.BestMatchTag }} <span class=\"ci-muted\">(existing tag)</span>\n } @else {\n <span class=\"ci-muted\">No close match</span>\n }\n </div>\n\n @if (Selected.SourceContentItem) {\n <div class=\"ci-k\">From content item</div>\n <div class=\"ci-v ci-link\">{{ Selected.SourceContentItem }}</div>\n }\n\n @if (Selected.SourceText) {\n <div class=\"ci-k\">Source text</div>\n <div class=\"ci-v ci-source-text\">{{ Selected.SourceText }}</div>\n }\n </div>\n\n <!-- Threshold band visualization -->\n @if (Selected.BestMatchScore != null) {\n <div class=\"ci-band\">\n <h5>Match confidence vs thresholds</h5>\n <div class=\"ci-bandbar\">\n <div class=\"ci-bandmark\" [style.left.%]=\"ScorePct(SuggestThreshold)\"></div>\n <div class=\"ci-bandmark-label\" [style.left.%]=\"ScorePct(SuggestThreshold)\">Suggest {{ FormatScore(SuggestThreshold) }}</div>\n <div class=\"ci-bandmark\" [style.left.%]=\"ScorePct(MatchThreshold)\"></div>\n <div class=\"ci-bandmark-label\" [style.left.%]=\"ScorePct(MatchThreshold)\">Match {{ FormatScore(MatchThreshold) }}</div>\n <div class=\"ci-bandscore\" [style.left.%]=\"ScorePct(Selected.BestMatchScore)\">{{ FormatScore(Selected.BestMatchScore) }}</div>\n </div>\n <div class=\"ci-bandlabels\">\n <span>reject / new</span>\n <span>review band</span>\n <span>auto-apply</span>\n </div>\n </div>\n }\n\n <!-- Merge target picker -->\n <div class=\"ci-merge-picker\">\n <label class=\"ci-merge-label\">Merge target</label>\n <mj-combobox\n [Data]=\"TagOptions\"\n TextField=\"Label\"\n ValueField=\"ID\"\n [ValuePrimitive]=\"true\"\n [Filterable]=\"true\"\n Placeholder=\"Choose a tag to merge into\u2026\"\n [ngModel]=\"MergeTargetID\"\n (ValueChange)=\"OnMergeTargetChange($event)\">\n </mj-combobox>\n </div>\n\n <!-- Reviewer note -->\n <div class=\"ci-note\">\n <label class=\"ci-merge-label\">Reviewer note (optional)</label>\n <textarea class=\"mj-textarea ci-note-input\" rows=\"2\"\n placeholder=\"Why this decision\u2026\"\n [(ngModel)]=\"ReviewerNotes\"></textarea>\n </div>\n\n <!-- Action bar: confirm/primary actions LEFT, reject RIGHT -->\n <div class=\"ci-actbar\">\n <button mjButton variant=\"success\" size=\"sm\" (click)=\"MergeIntoExisting()\"\n [disabled]=\"IsActing || !MergeTargetID\">\n <i class=\"fa-solid fa-code-merge\"></i> Merge into \"{{ MergeTargetLabel || '\u2026' }}\"\n </button>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"ApproveAsNewTag()\" [disabled]=\"IsActing\">\n <i class=\"fa-solid fa-plus\"></i> Approve as new tag\n </button>\n <span class=\"ci-actbar-spacer\"></span>\n <button mjButton variant=\"danger\" size=\"sm\" (click)=\"Reject()\" [disabled]=\"IsActing\">\n <i class=\"fa-solid fa-xmark\"></i> Reject\n </button>\n </div>\n }\n </div>\n </div>\n }\n </div>\n</mj-page-body-interior>\n", styles: ["/*\n * Suggestions Inbox tab styles.\n *\n * The host (AutotaggingPipelineResourceComponent) uses ViewEncapsulation.None,\n * so its `.at-*` utilities (.at-main-area, .at-page-body, .at-empty-state) are\n * global and style the shell markup. This component uses the default emulated\n * encapsulation, so the inbox-specific `.ci-*` classes below are scoped here.\n *\n * Design tokens only \u2014 no hardcoded hex. The band gradient is built from\n * semantic status tokens via color-mix so it adapts to dark mode.\n */\n\n/* \u2500\u2500 3-pane layout \u2500\u2500 */\n.ci-inbox {\n display: grid;\n grid-template-columns: 180px 320px 1fr;\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n min-height: 460px;\n margin: 12px;\n background: var(--mj-bg-surface);\n}\n\n.ci-col {\n border-right: 1px solid var(--mj-border-default);\n overflow: auto;\n}\n.ci-col:last-child {\n border-right: 0;\n}\n\n/* \u2500\u2500 (1) Filter rail \u2500\u2500 */\n.ci-filter {\n padding: 12px;\n background: var(--mj-bg-surface-card);\n}\n.ci-filter h5 {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n margin: 0 0 8px;\n}\n.ci-section-gap {\n margin-top: 14px;\n}\n.ci-filter-link {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 8px;\n padding: 7px 9px;\n border-radius: 7px;\n color: var(--mj-text-secondary);\n font-size: 12.5px;\n font-weight: 600;\n cursor: pointer;\n margin-bottom: 2px;\n}\n.ci-filter-link:hover {\n background: var(--mj-bg-surface-hover);\n}\n.ci-filter-link.ci-active {\n background: var(--mj-bg-surface);\n box-shadow: inset 0 0 0 1px var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n.ci-n {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n/* \u2500\u2500 (2) Suggestion list \u2500\u2500 */\n.ci-list {\n background: var(--mj-bg-surface);\n}\n.ci-row {\n padding: 11px 13px;\n border-bottom: 1px solid var(--mj-border-subtle);\n cursor: pointer;\n}\n.ci-row:hover {\n background: var(--mj-bg-surface-hover);\n}\n.ci-row.ci-sel {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n box-shadow: inset 3px 0 0 var(--mj-brand-primary);\n}\n.ci-row-top {\n display: flex;\n justify-content: space-between;\n gap: 8px;\n}\n.ci-row-name {\n font-weight: 700;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n.ci-row-ago {\n font-size: 10.5px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n.ci-row-reason {\n font-size: 11px;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n display: flex;\n align-items: center;\n gap: 6px;\n flex-wrap: wrap;\n}\n.ci-row-match b {\n color: var(--mj-text-primary);\n}\n\n/* \u2500\u2500 (3) Reading pane \u2500\u2500 */\n.ci-read {\n padding: 18px 20px;\n}\n.ci-read-head {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 12px;\n}\n.ci-read-source {\n font-size: 11px;\n color: var(--mj-text-muted);\n font-family: var(--mj-font-mono, monospace);\n}\n.ci-read-title {\n font-size: 17px;\n margin: 4px 0 0;\n color: var(--mj-text-primary);\n}\n.ci-kv {\n display: grid;\n grid-template-columns: 130px 1fr;\n gap: 7px 12px;\n margin: 16px 0;\n font-size: 13px;\n}\n.ci-k {\n color: var(--mj-text-muted);\n}\n.ci-v {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n.ci-muted {\n color: var(--mj-text-muted);\n font-weight: 400;\n}\n.ci-link {\n color: var(--mj-text-link);\n}\n.ci-source-text {\n font-weight: 400;\n color: var(--mj-text-secondary);\n max-height: 80px;\n overflow: auto;\n white-space: pre-wrap;\n}\n\n/* \u2500\u2500 Threshold band visualization \u2500\u2500 */\n.ci-band {\n margin: 18px 0;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n padding: 14px;\n}\n.ci-band h5 {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n margin: 0 0 30px;\n}\n.ci-bandbar {\n position: relative;\n height: 10px;\n border-radius: 6px;\n /* reject/new (red) \u2192 review band (amber) \u2192 auto-apply (green) */\n background: linear-gradient(90deg,\n color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-bg-surface)) 0%,\n color-mix(in srgb, var(--mj-status-warning) 30%, var(--mj-bg-surface)) 55%,\n color-mix(in srgb, var(--mj-status-success) 30%, var(--mj-bg-surface)) 78%,\n color-mix(in srgb, var(--mj-status-success) 45%, var(--mj-bg-surface)) 100%);\n}\n.ci-bandmark {\n position: absolute;\n top: -6px;\n width: 2px;\n height: 22px;\n background: var(--mj-text-primary);\n transform: translateX(-50%);\n}\n.ci-bandmark-label {\n position: absolute;\n top: -20px;\n transform: translateX(-50%);\n font-size: 9px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n.ci-bandscore {\n position: absolute;\n top: -30px;\n transform: translateX(-50%);\n font-size: 11px;\n font-weight: 800;\n background: var(--mj-text-primary);\n color: var(--mj-text-inverse);\n padding: 2px 7px;\n border-radius: 6px;\n}\n.ci-bandlabels {\n display: flex;\n justify-content: space-between;\n margin-top: 9px;\n font-size: 10.5px;\n color: var(--mj-text-muted);\n}\n\n/* \u2500\u2500 Merge picker + note \u2500\u2500 */\n.ci-merge-picker,\n.ci-note {\n margin: 14px 0;\n}\n.ci-merge-label {\n display: block;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n margin-bottom: 6px;\n}\n.ci-note-input {\n width: 100%;\n resize: vertical;\n}\n\n/* \u2500\u2500 Action bar \u2500\u2500 */\n.ci-actbar {\n display: flex;\n align-items: center;\n gap: 9px;\n margin-top: 16px;\n padding-top: 16px;\n border-top: 1px solid var(--mj-border-default);\n}\n.ci-actbar-spacer {\n flex: 1;\n}\n\n/* \u2500\u2500 Reason pills \u2500\u2500 */\n.ci-pill {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 10px;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 999px;\n white-space: nowrap;\n}\n.ci-pill-lg {\n font-size: 12px;\n padding: 4px 12px;\n}\n.ci-pill-gray {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n.ci-pill-amber {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n}\n.ci-pill-red {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n}\n.ci-pill-blue {\n background: var(--mj-status-info-bg);\n color: var(--mj-status-info-text);\n}\n\n/* \u2500\u2500 Pending status pill (header [meta]) \u2500\u2500 */\n.ci-status-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n padding: 3px 10px;\n border-radius: 999px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n.ci-status-pill-active {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n}\n"] }]
715
+ }], null, { Resolved: [{
716
+ type: Output
717
+ }] }); })();
718
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ClassifyInboxTabComponent, { className: "ClassifyInboxTabComponent", filePath: "src/AI/components/autotagging/tabs/inbox-tab.component.ts", lineNumber: 70 }); })();
719
+ //# sourceMappingURL=inbox-tab.component.js.map