@hotmeshio/long-tail 0.22.0 → 0.22.2

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 (356) hide show
  1. package/build/api/escalations/accumulate.d.ts +10 -1
  2. package/build/api/escalations/accumulate.js +121 -34
  3. package/build/api/escalations/metadata.d.ts +5 -0
  4. package/build/api/escalations/metadata.js +6 -2
  5. package/build/api/escalations/resolve-batch.js +18 -11
  6. package/build/api/roles.js +4 -0
  7. package/build/api/scan-codes/badge-policy.d.ts +10 -0
  8. package/build/api/scan-codes/badge-policy.js +72 -0
  9. package/build/api/scan-codes/choice.js +18 -11
  10. package/build/api/scan-codes/context.d.ts +45 -1
  11. package/build/api/scan-codes/context.js +51 -3
  12. package/build/api/scan-codes/execute.js +73 -35
  13. package/build/api/scan-codes/grant.d.ts +27 -0
  14. package/build/api/scan-codes/grant.js +67 -0
  15. package/build/api/scan-codes/hold.d.ts +10 -0
  16. package/build/api/scan-codes/hold.js +98 -0
  17. package/build/api/scan-codes/identity.d.ts +5 -2
  18. package/build/api/scan-codes/identity.js +26 -8
  19. package/build/api/scan-codes/subject.d.ts +15 -0
  20. package/build/api/scan-codes/subject.js +68 -0
  21. package/build/api/scan-codes/verb-accumulate.d.ts +24 -0
  22. package/build/api/scan-codes/verb-accumulate.js +147 -0
  23. package/build/api/scan-codes/verb-fill.d.ts +6 -0
  24. package/build/api/scan-codes/verb-fill.js +152 -0
  25. package/build/api/scan-codes/verbs-subject.d.ts +14 -0
  26. package/build/api/scan-codes/verbs-subject.js +270 -0
  27. package/build/api/scan-codes/verbs.d.ts +7 -22
  28. package/build/api/scan-codes/verbs.js +35 -114
  29. package/build/api/workflows/invocation.d.ts +8 -4
  30. package/build/api/workflows/invocation.js +26 -9
  31. package/build/index.d.ts +1 -0
  32. package/build/index.js +8 -2
  33. package/build/lib/cli/commands/workflows.js +9 -4
  34. package/build/lib/db/schemas/037_scan_gtin_and_subject_grants.sql +27 -0
  35. package/build/routes/escalations/accumulate.js +13 -6
  36. package/build/routes/escalations/acting.d.ts +5 -0
  37. package/build/routes/escalations/acting.js +8 -1
  38. package/build/routes/scan-codes.js +3 -0
  39. package/build/sdk/index.d.ts +3 -0
  40. package/build/services/escalation/crud.d.ts +2 -2
  41. package/build/services/escalation/crud.js +4 -2
  42. package/build/services/escalation/facet-sql.js +8 -0
  43. package/build/services/escalation/sql.d.ts +4 -2
  44. package/build/services/escalation/sql.js +10 -2
  45. package/build/services/export/index.d.ts +8 -3
  46. package/build/services/export/index.js +15 -21
  47. package/build/services/iam/acting-identity.d.ts +29 -4
  48. package/build/services/iam/acting-identity.js +60 -17
  49. package/build/services/iam/ephemeral.d.ts +21 -0
  50. package/build/services/iam/ephemeral.js +32 -1
  51. package/build/services/iam/sql.d.ts +10 -0
  52. package/build/services/iam/sql.js +32 -3
  53. package/build/services/pipelines/events.js +2 -1
  54. package/build/services/pipelines/execution-builder.js +2 -1
  55. package/build/services/pipelines/queries.js +2 -1
  56. package/build/services/role/badge-grant.d.ts +5 -0
  57. package/build/services/role/badge-grant.js +36 -0
  58. package/build/services/role/seed.js +5 -0
  59. package/build/services/role/types.d.ts +14 -0
  60. package/build/services/role/types.js +5 -0
  61. package/build/services/scan-code/index.d.ts +3 -2
  62. package/build/services/scan-code/index.js +7 -1
  63. package/build/services/scan-code/parse.d.ts +23 -20
  64. package/build/services/scan-code/parse.js +45 -90
  65. package/build/services/scan-code/read.js +1 -0
  66. package/build/services/scan-code/sql.d.ts +3 -3
  67. package/build/services/scan-code/sql.js +11 -8
  68. package/build/services/scan-code/validate-subject.d.ts +7 -0
  69. package/build/services/scan-code/validate-subject.js +158 -0
  70. package/build/services/scan-code/validate.d.ts +7 -0
  71. package/build/services/scan-code/validate.js +111 -16
  72. package/build/services/scan-code/write.d.ts +1 -0
  73. package/build/services/scan-code/write.js +9 -3
  74. package/build/services/workflow-state.d.ts +21 -0
  75. package/build/services/workflow-state.js +39 -0
  76. package/build/shared/form-validation/field-validator.js +4 -0
  77. package/build/shared/form-validation/index.d.ts +1 -0
  78. package/build/shared/form-validation/index.js +1 -0
  79. package/build/shared/form-validation/x-lt-scan.d.ts +52 -0
  80. package/build/shared/form-validation/x-lt-scan.js +166 -0
  81. package/build/shared/scan-code/gtin.d.ts +5 -0
  82. package/build/shared/scan-code/gtin.js +25 -0
  83. package/build/shared/scan-code/index.d.ts +2 -0
  84. package/build/shared/scan-code/index.js +10 -0
  85. package/build/shared/scan-code/parse.d.ts +46 -0
  86. package/build/shared/scan-code/parse.js +133 -0
  87. package/build/shared/workflow-state.d.ts +17 -0
  88. package/build/shared/workflow-state.js +29 -0
  89. package/build/system/mcp-servers/admin/escalations.js +8 -4
  90. package/build/system/mcp-servers/admin/scan-codes.js +10 -4
  91. package/build/system/mcp-servers/admin/schemas.d.ts +792 -23
  92. package/build/system/mcp-servers/admin/schemas.js +61 -4
  93. package/build/system/mcp-servers/admin/workflows.js +20 -31
  94. package/build/system/mcp-servers/human-queue-schemas.d.ts +6 -6
  95. package/build/system/seed/tool-manifests-admin.d.ts +94 -0
  96. package/build/system/seed/tool-manifests-admin.js +3 -3
  97. package/build/tsconfig.tsbuildinfo +1 -1
  98. package/build/types/escalation.d.ts +2 -0
  99. package/build/types/escalation.js +3 -1
  100. package/build/types/facets.d.ts +14 -0
  101. package/build/types/index.d.ts +3 -3
  102. package/build/types/index.js +8 -1
  103. package/build/types/scan-code/constants.d.ts +182 -0
  104. package/build/types/{scan-code.js → scan-code/constants.js} +62 -12
  105. package/build/types/scan-code/index.d.ts +3 -0
  106. package/build/types/scan-code/index.js +17 -0
  107. package/build/types/scan-code/response.d.ts +140 -0
  108. package/build/types/scan-code/response.js +2 -0
  109. package/build/types/scan-code/rule.d.ts +199 -0
  110. package/build/types/scan-code/rule.js +2 -0
  111. package/build/types/startup.d.ts +3 -1
  112. package/dashboard/dist/assets/{AdminDashboard-Covdam48.js → AdminDashboard-DBW12qQt.js} +2 -2
  113. package/dashboard/dist/assets/{AdminDashboard-Covdam48.js.map → AdminDashboard-DBW12qQt.js.map} +1 -1
  114. package/dashboard/dist/assets/{AgentConfigPage-CE1k6J5r.js → AgentConfigPage-CmHv8U9M.js} +2 -2
  115. package/dashboard/dist/assets/{AgentConfigPage-CE1k6J5r.js.map → AgentConfigPage-CmHv8U9M.js.map} +1 -1
  116. package/dashboard/dist/assets/{AgentDetailPage-CWJZIZP1.js → AgentDetailPage-D1scIbz-.js} +3 -3
  117. package/dashboard/dist/assets/{AgentDetailPage-CWJZIZP1.js.map → AgentDetailPage-D1scIbz-.js.map} +1 -1
  118. package/dashboard/dist/assets/{AgentsPage---Dg5ufF.js → AgentsPage-BA_ai9HJ.js} +2 -2
  119. package/dashboard/dist/assets/{AgentsPage---Dg5ufF.js.map → AgentsPage-BA_ai9HJ.js.map} +1 -1
  120. package/dashboard/dist/assets/AvailableEscalationsPage-C2_5aEFW.js +2 -0
  121. package/dashboard/dist/assets/AvailableEscalationsPage-C2_5aEFW.js.map +1 -0
  122. package/dashboard/dist/assets/{BotPicker-D3drO3-T.js → BotPicker-BZo4Kp4a.js} +2 -2
  123. package/dashboard/dist/assets/{BotPicker-D3drO3-T.js.map → BotPicker-BZo4Kp4a.js.map} +1 -1
  124. package/dashboard/dist/assets/{BulkAssignModal-BOAWsViq.js → BulkAssignModal-BFhyxY2T.js} +2 -2
  125. package/dashboard/dist/assets/{BulkAssignModal-BOAWsViq.js.map → BulkAssignModal-BFhyxY2T.js.map} +1 -1
  126. package/dashboard/dist/assets/CapabilitiesPage-CvOX6vAc.js +2 -0
  127. package/dashboard/dist/assets/{CapabilitiesPage-RGgD3YZO.js.map → CapabilitiesPage-CvOX6vAc.js.map} +1 -1
  128. package/dashboard/dist/assets/{CollapsibleSection-DNkZn87n.js → CollapsibleSection-GCJsV9Oq.js} +2 -2
  129. package/dashboard/dist/assets/{CollapsibleSection-DNkZn87n.js.map → CollapsibleSection-GCJsV9Oq.js.map} +1 -1
  130. package/dashboard/dist/assets/{ConfirmDeleteModal-BqzOwhPr.js → ConfirmDeleteModal-CAgYLcef.js} +2 -2
  131. package/dashboard/dist/assets/{ConfirmDeleteModal-BqzOwhPr.js.map → ConfirmDeleteModal-CAgYLcef.js.map} +1 -1
  132. package/dashboard/dist/assets/CountdownTimer-Dik2z0M_.js +2 -0
  133. package/dashboard/dist/assets/{CountdownTimer-BaexQMK6.js.map → CountdownTimer-Dik2z0M_.js.map} +1 -1
  134. package/dashboard/dist/assets/{CredentialsPage-D7abp0aS.js → CredentialsPage-twd2xCOW.js} +2 -2
  135. package/dashboard/dist/assets/{CredentialsPage-D7abp0aS.js.map → CredentialsPage-twd2xCOW.js.map} +1 -1
  136. package/dashboard/dist/assets/{CronLabel-DZiWmTwJ.js → CronLabel-DdnIuudX.js} +2 -2
  137. package/dashboard/dist/assets/{CronLabel-DZiWmTwJ.js.map → CronLabel-DdnIuudX.js.map} +1 -1
  138. package/dashboard/dist/assets/{DropZone-f1o-GLM8.js → DropZone-B1Tdfddc.js} +2 -2
  139. package/dashboard/dist/assets/{DropZone-f1o-GLM8.js.map → DropZone-B1Tdfddc.js.map} +1 -1
  140. package/dashboard/dist/assets/{ElapsedCell-BdGO_w4v.js → ElapsedCell-DCctVv5R.js} +2 -2
  141. package/dashboard/dist/assets/{ElapsedCell-BdGO_w4v.js.map → ElapsedCell-DCctVv5R.js.map} +1 -1
  142. package/dashboard/dist/assets/{EntityTimelinePanel-DIDcF5Yu.js → EntityTimelinePanel-CMnskyWv.js} +2 -2
  143. package/dashboard/dist/assets/{EntityTimelinePanel-DIDcF5Yu.js.map → EntityTimelinePanel-CMnskyWv.js.map} +1 -1
  144. package/dashboard/dist/assets/{EscalationListSchemaPage-C28rn9XC.js → EscalationListSchemaPage-VfCn6WDb.js} +3 -3
  145. package/dashboard/dist/assets/{EscalationListSchemaPage-C28rn9XC.js.map → EscalationListSchemaPage-VfCn6WDb.js.map} +1 -1
  146. package/dashboard/dist/assets/{EscalationListView-CkBnkpDJ.js → EscalationListView-CGQZxcC-.js} +2 -2
  147. package/dashboard/dist/assets/{EscalationListView-CkBnkpDJ.js.map → EscalationListView-CGQZxcC-.js.map} +1 -1
  148. package/dashboard/dist/assets/EscalationSchemaPage-BX0tx-PM.js +9 -0
  149. package/dashboard/dist/assets/EscalationSchemaPage-BX0tx-PM.js.map +1 -0
  150. package/dashboard/dist/assets/EscalationTimeline-DKoSM56J.js +2 -0
  151. package/dashboard/dist/assets/EscalationTimeline-DKoSM56J.js.map +1 -0
  152. package/dashboard/dist/assets/{EscalationTitleSelect-CzKfavri.js → EscalationTitleSelect-DWGLBOmS.js} +2 -2
  153. package/dashboard/dist/assets/{EscalationTitleSelect-CzKfavri.js.map → EscalationTitleSelect-DWGLBOmS.js.map} +1 -1
  154. package/dashboard/dist/assets/{EscalationsOverview-Tdu3Yx2c.js → EscalationsOverview-C2XoguaA.js} +2 -2
  155. package/dashboard/dist/assets/{EscalationsOverview-Tdu3Yx2c.js.map → EscalationsOverview-C2XoguaA.js.map} +1 -1
  156. package/dashboard/dist/assets/{EventTable-DiIxOJwO.js → EventTable-CBUWq7--.js} +2 -2
  157. package/dashboard/dist/assets/{EventTable-DiIxOJwO.js.map → EventTable-CBUWq7--.js.map} +1 -1
  158. package/dashboard/dist/assets/{FilterBar-CvMBCVIo.js → FilterBar-8IdbleZ9.js} +2 -2
  159. package/dashboard/dist/assets/{FilterBar-CvMBCVIo.js.map → FilterBar-8IdbleZ9.js.map} +1 -1
  160. package/dashboard/dist/assets/GrantScopeField-BzWGzBfA.js +2 -0
  161. package/dashboard/dist/assets/GrantScopeField-BzWGzBfA.js.map +1 -0
  162. package/dashboard/dist/assets/{GraphInvokePage-DO-yyhi6.js → GraphInvokePage-CUvoPzsW.js} +2 -2
  163. package/dashboard/dist/assets/{GraphInvokePage-DO-yyhi6.js.map → GraphInvokePage-CUvoPzsW.js.map} +1 -1
  164. package/dashboard/dist/assets/{HomePage-DSS3eHR2.js → HomePage-BP7v9GLJ.js} +2 -2
  165. package/dashboard/dist/assets/{HomePage-DSS3eHR2.js.map → HomePage-BP7v9GLJ.js.map} +1 -1
  166. package/dashboard/dist/assets/{ListToolbar-C3-Tqqub.js → ListToolbar-Cnacuwoy.js} +2 -2
  167. package/dashboard/dist/assets/{ListToolbar-C3-Tqqub.js.map → ListToolbar-Cnacuwoy.js.map} +1 -1
  168. package/dashboard/dist/assets/{McpOverview-DEJmsdVi.js → McpOverview-C2JoNoDA.js} +2 -2
  169. package/dashboard/dist/assets/{McpOverview-DEJmsdVi.js.map → McpOverview-C2JoNoDA.js.map} +1 -1
  170. package/dashboard/dist/assets/McpQueryDetailPage-C_nih0w-.js +5 -0
  171. package/dashboard/dist/assets/McpQueryDetailPage-C_nih0w-.js.map +1 -0
  172. package/dashboard/dist/assets/{McpQueryPage-BBcG_UuU.js → McpQueryPage-U_wNXow2.js} +2 -2
  173. package/dashboard/dist/assets/{McpQueryPage-BBcG_UuU.js.map → McpQueryPage-U_wNXow2.js.map} +1 -1
  174. package/dashboard/dist/assets/{McpRunDetailPage-C6xw0kBg.js → McpRunDetailPage-DtKoJq6J.js} +2 -2
  175. package/dashboard/dist/assets/{McpRunDetailPage-C6xw0kBg.js.map → McpRunDetailPage-DtKoJq6J.js.map} +1 -1
  176. package/dashboard/dist/assets/{McpRunsPage-CRQqrF4Q.js → McpRunsPage-CnYtfGhf.js} +2 -2
  177. package/dashboard/dist/assets/{McpRunsPage-CRQqrF4Q.js.map → McpRunsPage-CnYtfGhf.js.map} +1 -1
  178. package/dashboard/dist/assets/{NamespacePill-DADRJOUl.js → NamespacePill-DwM5pNA4.js} +2 -2
  179. package/dashboard/dist/assets/{NamespacePill-DADRJOUl.js.map → NamespacePill-DwM5pNA4.js.map} +1 -1
  180. package/dashboard/dist/assets/{OperationsPage-Dlfwzf-0.js → OperationsPage-C7hupIer.js} +2 -2
  181. package/dashboard/dist/assets/{OperationsPage-Dlfwzf-0.js.map → OperationsPage-C7hupIer.js.map} +1 -1
  182. package/dashboard/dist/assets/{OperatorDashboard-DoiDGZ9R.js → OperatorDashboard-fVuLn2D5.js} +2 -2
  183. package/dashboard/dist/assets/{OperatorDashboard-DoiDGZ9R.js.map → OperatorDashboard-fVuLn2D5.js.map} +1 -1
  184. package/dashboard/dist/assets/{PageHeader-Csq434-v.js → PageHeader-CMd3f4bz.js} +2 -2
  185. package/dashboard/dist/assets/{PageHeader-Csq434-v.js.map → PageHeader-CMd3f4bz.js.map} +1 -1
  186. package/dashboard/dist/assets/{PageHeaderWithStats-CSnk1p5A.js → PageHeaderWithStats-DHj8Mqox.js} +2 -2
  187. package/dashboard/dist/assets/{PageHeaderWithStats-CSnk1p5A.js.map → PageHeaderWithStats-DHj8Mqox.js.map} +1 -1
  188. package/dashboard/dist/assets/{PersonaDetailPage-BzbA4Prr.js → PersonaDetailPage-C-4o8lPw.js} +2 -2
  189. package/dashboard/dist/assets/{PersonaDetailPage-BzbA4Prr.js.map → PersonaDetailPage-C-4o8lPw.js.map} +1 -1
  190. package/dashboard/dist/assets/{PersonasPage-B36yn4hU.js → PersonasPage-BL1FwLmv.js} +2 -2
  191. package/dashboard/dist/assets/{PersonasPage-B36yn4hU.js.map → PersonasPage-BL1FwLmv.js.map} +1 -1
  192. package/dashboard/dist/assets/{PortalPage-BkD4YfDf.js → PortalPage-tJG5sgb1.js} +2 -2
  193. package/dashboard/dist/assets/{PortalPage-BkD4YfDf.js.map → PortalPage-tJG5sgb1.js.map} +1 -1
  194. package/dashboard/dist/assets/{ProcessDetailPage-BT0eiBWY.js → ProcessDetailPage-Dz_jY4Yt.js} +2 -2
  195. package/dashboard/dist/assets/{ProcessDetailPage-BT0eiBWY.js.map → ProcessDetailPage-Dz_jY4Yt.js.map} +1 -1
  196. package/dashboard/dist/assets/{ProcessesListPage-BEqeeNae.js → ProcessesListPage-Cbn9cter.js} +2 -2
  197. package/dashboard/dist/assets/{ProcessesListPage-BEqeeNae.js.map → ProcessesListPage-Cbn9cter.js.map} +1 -1
  198. package/dashboard/dist/assets/ResolverForm-Bk8iXQ6-.js +8 -0
  199. package/dashboard/dist/assets/ResolverForm-Bk8iXQ6-.js.map +1 -0
  200. package/dashboard/dist/assets/RoleDetailPage-owPi6gI9.js +8 -0
  201. package/dashboard/dist/assets/RoleDetailPage-owPi6gI9.js.map +1 -0
  202. package/dashboard/dist/assets/{RolePill-BafrASDX.js → RolePill-Di2CAHuD.js} +2 -2
  203. package/dashboard/dist/assets/{RolePill-BafrASDX.js.map → RolePill-Di2CAHuD.js.map} +1 -1
  204. package/dashboard/dist/assets/{RolesPage-80quJU5-.js → RolesPage-NwmMvZFa.js} +2 -2
  205. package/dashboard/dist/assets/{RolesPage-80quJU5-.js.map → RolesPage-NwmMvZFa.js.map} +1 -1
  206. package/dashboard/dist/assets/{RunAsSelector-BoePhWVD.js → RunAsSelector-tgEooTyU.js} +2 -2
  207. package/dashboard/dist/assets/{RunAsSelector-BoePhWVD.js.map → RunAsSelector-tgEooTyU.js.map} +1 -1
  208. package/dashboard/dist/assets/ScanCodesPage-CUv_8ic6.js +2 -0
  209. package/dashboard/dist/assets/ScanCodesPage-CUv_8ic6.js.map +1 -0
  210. package/dashboard/dist/assets/ScanSchemeDetailPage-YHqbu7oK.js +2 -0
  211. package/dashboard/dist/assets/ScanSchemeDetailPage-YHqbu7oK.js.map +1 -0
  212. package/dashboard/dist/assets/ScanStationPage-B275l6r_.js +2 -0
  213. package/dashboard/dist/assets/ScanStationPage-B275l6r_.js.map +1 -0
  214. package/dashboard/dist/assets/{ScopeBadge-b6MIBiYD.js → ScopeBadge-CSItPVOH.js} +2 -2
  215. package/dashboard/dist/assets/{ScopeBadge-b6MIBiYD.js.map → ScopeBadge-CSItPVOH.js.map} +1 -1
  216. package/dashboard/dist/assets/{StickyPagination-9ITrei_d.js → StickyPagination-CsTI_gvJ.js} +2 -2
  217. package/dashboard/dist/assets/{StickyPagination-9ITrei_d.js.map → StickyPagination-CsTI_gvJ.js.map} +1 -1
  218. package/dashboard/dist/assets/{StreamMessageDetail-BkYvEHFY.js → StreamMessageDetail-auRlvjTh.js} +2 -2
  219. package/dashboard/dist/assets/{StreamMessageDetail-BkYvEHFY.js.map → StreamMessageDetail-auRlvjTh.js.map} +1 -1
  220. package/dashboard/dist/assets/{SwimlaneTimeline-B1rotFix.js → SwimlaneTimeline-BLoVHYAd.js} +2 -2
  221. package/dashboard/dist/assets/{SwimlaneTimeline-B1rotFix.js.map → SwimlaneTimeline-BLoVHYAd.js.map} +1 -1
  222. package/dashboard/dist/assets/{TagInput-ZrIIrEUP.js → TagInput-CAgdLN_b.js} +2 -2
  223. package/dashboard/dist/assets/{TagInput-ZrIIrEUP.js.map → TagInput-CAgdLN_b.js.map} +1 -1
  224. package/dashboard/dist/assets/{TaskDetailPage-zhn_U_eC.js → TaskDetailPage-BPsZ1bK_.js} +2 -2
  225. package/dashboard/dist/assets/{TaskDetailPage-zhn_U_eC.js.map → TaskDetailPage-BPsZ1bK_.js.map} +1 -1
  226. package/dashboard/dist/assets/{TaskQueuePill-DkQ1uc6y.js → TaskQueuePill-h0oorVMe.js} +2 -2
  227. package/dashboard/dist/assets/{TaskQueuePill-DkQ1uc6y.js.map → TaskQueuePill-h0oorVMe.js.map} +1 -1
  228. package/dashboard/dist/assets/{TasksListPage-CNbNeagx.js → TasksListPage-BNGM74yT.js} +2 -2
  229. package/dashboard/dist/assets/{TasksListPage-CNbNeagx.js.map → TasksListPage-BNGM74yT.js.map} +1 -1
  230. package/dashboard/dist/assets/{TimeAgo-0YVMBwls.js → TimeAgo-BnAHXGK7.js} +2 -2
  231. package/dashboard/dist/assets/{TimeAgo-0YVMBwls.js.map → TimeAgo-BnAHXGK7.js.map} +1 -1
  232. package/dashboard/dist/assets/{TimestampCell-DB7r3np8.js → TimestampCell-J4yae6mc.js} +2 -2
  233. package/dashboard/dist/assets/{TimestampCell-DB7r3np8.js.map → TimestampCell-J4yae6mc.js.map} +1 -1
  234. package/dashboard/dist/assets/{ToolPill-Baxm02L6.js → ToolPill-CQCsVdzD.js} +2 -2
  235. package/dashboard/dist/assets/{ToolPill-Baxm02L6.js.map → ToolPill-CQCsVdzD.js.map} +1 -1
  236. package/dashboard/dist/assets/{ToolTestPanel-BLfA02wv.js → ToolTestPanel-BdzzgXDu.js} +2 -2
  237. package/dashboard/dist/assets/{ToolTestPanel-BLfA02wv.js.map → ToolTestPanel-BdzzgXDu.js.map} +1 -1
  238. package/dashboard/dist/assets/{TopicDetailPage-eAqPKShq.js → TopicDetailPage-DJKg8lb7.js} +4 -4
  239. package/dashboard/dist/assets/{TopicDetailPage-eAqPKShq.js.map → TopicDetailPage-DJKg8lb7.js.map} +1 -1
  240. package/dashboard/dist/assets/{TopicsPage-BNNWD-zl.js → TopicsPage-DQV0WxG6.js} +2 -2
  241. package/dashboard/dist/assets/{TopicsPage-BNNWD-zl.js.map → TopicsPage-DQV0WxG6.js.map} +1 -1
  242. package/dashboard/dist/assets/{UserName-Pw46tO_k.js → UserName-Ct09nGh5.js} +2 -2
  243. package/dashboard/dist/assets/{UserName-Pw46tO_k.js.map → UserName-Ct09nGh5.js.map} +1 -1
  244. package/dashboard/dist/assets/{WorkflowExecutionPage-DvA51lT3.js → WorkflowExecutionPage-B5WJOsee.js} +2 -2
  245. package/dashboard/dist/assets/{WorkflowExecutionPage-DvA51lT3.js.map → WorkflowExecutionPage-B5WJOsee.js.map} +1 -1
  246. package/dashboard/dist/assets/{WorkflowPill-ZepbO_ny.js → WorkflowPill-Dg7BDTyM.js} +2 -2
  247. package/dashboard/dist/assets/{WorkflowPill-ZepbO_ny.js.map → WorkflowPill-Dg7BDTyM.js.map} +1 -1
  248. package/dashboard/dist/assets/{WorkflowsDashboard-DFDTwnhn.js → WorkflowsDashboard-Hc87TRgD.js} +2 -2
  249. package/dashboard/dist/assets/{WorkflowsDashboard-DFDTwnhn.js.map → WorkflowsDashboard-Hc87TRgD.js.map} +1 -1
  250. package/dashboard/dist/assets/{WorkflowsOverview-5i2Tcy-p.js → WorkflowsOverview-CJQbyOj-.js} +2 -2
  251. package/dashboard/dist/assets/{WorkflowsOverview-5i2Tcy-p.js.map → WorkflowsOverview-CJQbyOj-.js.map} +1 -1
  252. package/dashboard/dist/assets/{YamlWorkflowDetailPage-p4VEYZS0.js → YamlWorkflowDetailPage-BMeED677.js} +8 -8
  253. package/dashboard/dist/assets/{YamlWorkflowDetailPage-p4VEYZS0.js.map → YamlWorkflowDetailPage-BMeED677.js.map} +1 -1
  254. package/dashboard/dist/assets/{YamlWorkflowsPage-Cq-hMVxl.js → YamlWorkflowsPage-BMMg0Id6.js} +2 -2
  255. package/dashboard/dist/assets/{YamlWorkflowsPage-Cq-hMVxl.js.map → YamlWorkflowsPage-BMMg0Id6.js.map} +1 -1
  256. package/dashboard/dist/assets/{agents-EyBPJMYa.js → agents-CdFkgFvg.js} +2 -2
  257. package/dashboard/dist/assets/{agents-EyBPJMYa.js.map → agents-CdFkgFvg.js.map} +1 -1
  258. package/dashboard/dist/assets/{bots-DX6jjqtF.js → bots-Mj3LHWWg.js} +2 -2
  259. package/dashboard/dist/assets/{bots-DX6jjqtF.js.map → bots-Mj3LHWWg.js.map} +1 -1
  260. package/dashboard/dist/assets/{capabilities-ZdLv9xBQ.js → capabilities-Dw1ObK2-.js} +2 -2
  261. package/dashboard/dist/assets/{capabilities-ZdLv9xBQ.js.map → capabilities-Dw1ObK2-.js.map} +1 -1
  262. package/dashboard/dist/assets/{controlplane-CpvZaJuw.js → controlplane-DcNE1APv.js} +2 -2
  263. package/dashboard/dist/assets/{controlplane-CpvZaJuw.js.map → controlplane-DcNE1APv.js.map} +1 -1
  264. package/dashboard/dist/assets/{escalation-columns-Mvsze5eV.js → escalation-columns-D364Trpy.js} +2 -2
  265. package/dashboard/dist/assets/{escalation-columns-Mvsze5eV.js.map → escalation-columns-D364Trpy.js.map} +1 -1
  266. package/dashboard/dist/assets/{index-Cn8uJsd7.js → index-B3veJ698.js} +2 -2
  267. package/dashboard/dist/assets/{index-Cn8uJsd7.js.map → index-B3veJ698.js.map} +1 -1
  268. package/dashboard/dist/assets/index-BQeHJHYN.js +67 -0
  269. package/dashboard/dist/assets/index-BQeHJHYN.js.map +1 -0
  270. package/dashboard/dist/assets/{index-D-Xs4rAW.js → index-BRGTmoYY.js} +2 -2
  271. package/dashboard/dist/assets/{index-D-Xs4rAW.js.map → index-BRGTmoYY.js.map} +1 -1
  272. package/dashboard/dist/assets/{index-DkrBFFSO.js → index-Bd6-KmBE.js} +3 -3
  273. package/dashboard/dist/assets/{index-DkrBFFSO.js.map → index-Bd6-KmBE.js.map} +1 -1
  274. package/dashboard/dist/assets/{index-Bhb89oHH.js → index-BiVce3n0.js} +2 -2
  275. package/dashboard/dist/assets/{index-Bhb89oHH.js.map → index-BiVce3n0.js.map} +1 -1
  276. package/dashboard/dist/assets/{index-z5Hpeidu.js → index-BmNAVd4s.js} +2 -2
  277. package/dashboard/dist/assets/{index-z5Hpeidu.js.map → index-BmNAVd4s.js.map} +1 -1
  278. package/dashboard/dist/assets/{index-BbCjGO3M.js → index-Bq5XNEzD.js} +2 -2
  279. package/dashboard/dist/assets/{index-BbCjGO3M.js.map → index-Bq5XNEzD.js.map} +1 -1
  280. package/dashboard/dist/assets/{index-DGmzBY9D.js → index-DPStdq4T.js} +2 -2
  281. package/dashboard/dist/assets/{index-DGmzBY9D.js.map → index-DPStdq4T.js.map} +1 -1
  282. package/dashboard/dist/assets/index-DcppjzP5.css +1 -0
  283. package/dashboard/dist/assets/{index-PfSRKerc.js → index-DkcI4V_H.js} +2 -2
  284. package/dashboard/dist/assets/{index-PfSRKerc.js.map → index-DkcI4V_H.js.map} +1 -1
  285. package/dashboard/dist/assets/{index-oFKUFGQL.js → index-Dyotfa_k.js} +2 -2
  286. package/dashboard/dist/assets/{index-oFKUFGQL.js.map → index-Dyotfa_k.js.map} +1 -1
  287. package/dashboard/dist/assets/{index-Eo-l3Lqo.js → index-MDD4JYtu.js} +2 -2
  288. package/dashboard/dist/assets/{index-Eo-l3Lqo.js.map → index-MDD4JYtu.js.map} +1 -1
  289. package/dashboard/dist/assets/index-WSm8bgE7.js +3 -0
  290. package/dashboard/dist/assets/index-WSm8bgE7.js.map +1 -0
  291. package/dashboard/dist/assets/{index-DZhtP2Ok.js → index-eDm6cz0F.js} +2 -2
  292. package/dashboard/dist/assets/{index-DZhtP2Ok.js.map → index-eDm6cz0F.js.map} +1 -1
  293. package/dashboard/dist/assets/{knowledge-CgloEkaf.js → knowledge-Bafewjxk.js} +2 -2
  294. package/dashboard/dist/assets/{knowledge-CgloEkaf.js.map → knowledge-Bafewjxk.js.map} +1 -1
  295. package/dashboard/dist/assets/{mcp-query-o-sGX2ST.js → mcp-query-BzTtIG90.js} +2 -2
  296. package/dashboard/dist/assets/{mcp-query-o-sGX2ST.js.map → mcp-query-BzTtIG90.js.map} +1 -1
  297. package/dashboard/dist/assets/{mcp-Bix7QYO7.js → mcp-vLIutbnc.js} +2 -2
  298. package/dashboard/dist/assets/{mcp-Bix7QYO7.js.map → mcp-vLIutbnc.js.map} +1 -1
  299. package/dashboard/dist/assets/{personas-30azkJ_s.js → personas-WD40EDS_.js} +2 -2
  300. package/dashboard/dist/assets/{personas-30azkJ_s.js.map → personas-WD40EDS_.js.map} +1 -1
  301. package/dashboard/dist/assets/{pipelines-Bfk2GFK7.js → pipelines-DFwULWs3.js} +2 -2
  302. package/dashboard/dist/assets/{pipelines-Bfk2GFK7.js.map → pipelines-DFwULWs3.js.map} +1 -1
  303. package/dashboard/dist/assets/{tasks-CpdopewW.js → tasks-La_-WAUn.js} +2 -2
  304. package/dashboard/dist/assets/{tasks-CpdopewW.js.map → tasks-La_-WAUn.js.map} +1 -1
  305. package/dashboard/dist/assets/{topics--bvCV9Yp.js → topics-CzYMlvqm.js} +2 -2
  306. package/dashboard/dist/assets/{topics--bvCV9Yp.js.map → topics-CzYMlvqm.js.map} +1 -1
  307. package/dashboard/dist/assets/{useDebouncedValue-Da0lPmj3.js → useDebouncedValue-C0FQyANW.js} +2 -2
  308. package/dashboard/dist/assets/{useDebouncedValue-Da0lPmj3.js.map → useDebouncedValue-C0FQyANW.js.map} +1 -1
  309. package/dashboard/dist/assets/{useNamespace-DD_Esl6n.js → useNamespace-WW_XjAb3.js} +2 -2
  310. package/dashboard/dist/assets/{useNamespace-DD_Esl6n.js.map → useNamespace-WW_XjAb3.js.map} +1 -1
  311. package/dashboard/dist/assets/{useYamlActivityEvents-AeAhZJJk.js → useYamlActivityEvents-B3YxPeFt.js} +2 -2
  312. package/dashboard/dist/assets/{useYamlActivityEvents-AeAhZJJk.js.map → useYamlActivityEvents-B3YxPeFt.js.map} +1 -1
  313. package/dashboard/dist/assets/{vendor-icons-B7OcUM6b.js → vendor-icons-CeVtUKyP.js} +2 -2
  314. package/dashboard/dist/assets/{vendor-icons-B7OcUM6b.js.map → vendor-icons-CeVtUKyP.js.map} +1 -1
  315. package/dashboard/dist/assets/{yaml-workflows-BHAOOGvn.js → yaml-workflows-COHOjdhF.js} +2 -2
  316. package/dashboard/dist/assets/{yaml-workflows-BHAOOGvn.js.map → yaml-workflows-COHOjdhF.js.map} +1 -1
  317. package/dashboard/dist/index.html +3 -3
  318. package/docs/accumulator.md +37 -1
  319. package/docs/api/mcp/admin.md +3 -2
  320. package/docs/api/sdk/escalations.md +6 -0
  321. package/docs/api/sdk/exports.md +1 -1
  322. package/docs/api/sdk/workflows.md +23 -4
  323. package/docs/cli.md +1 -1
  324. package/docs/dashboard.md +2 -2
  325. package/docs/faceted-routing.md +2 -0
  326. package/docs/hitl/x-lt-scan.md +51 -0
  327. package/docs/hitl/x-lt-widget.md +5 -0
  328. package/docs/hitl-guide.md +2 -0
  329. package/docs/scan-codes.md +252 -19
  330. package/package.json +1 -1
  331. package/build/types/scan-code.d.ts +0 -308
  332. package/dashboard/dist/assets/AvailableEscalationsPage-CpbC8oTN.js +0 -2
  333. package/dashboard/dist/assets/AvailableEscalationsPage-CpbC8oTN.js.map +0 -1
  334. package/dashboard/dist/assets/CapabilitiesPage-RGgD3YZO.js +0 -2
  335. package/dashboard/dist/assets/CountdownTimer-BaexQMK6.js +0 -2
  336. package/dashboard/dist/assets/EscalationSchemaPage-W5r0A1kj.js +0 -9
  337. package/dashboard/dist/assets/EscalationSchemaPage-W5r0A1kj.js.map +0 -1
  338. package/dashboard/dist/assets/EscalationTimeline-DKyTz6sM.js +0 -2
  339. package/dashboard/dist/assets/EscalationTimeline-DKyTz6sM.js.map +0 -1
  340. package/dashboard/dist/assets/McpQueryDetailPage-DYJr16l7.js +0 -5
  341. package/dashboard/dist/assets/McpQueryDetailPage-DYJr16l7.js.map +0 -1
  342. package/dashboard/dist/assets/ResolverForm-BwgjIX97.js +0 -7
  343. package/dashboard/dist/assets/ResolverForm-BwgjIX97.js.map +0 -1
  344. package/dashboard/dist/assets/RoleDetailPage-BFuLNJXa.js +0 -8
  345. package/dashboard/dist/assets/RoleDetailPage-BFuLNJXa.js.map +0 -1
  346. package/dashboard/dist/assets/ScanCodesPage-Cu1bKEix.js +0 -2
  347. package/dashboard/dist/assets/ScanCodesPage-Cu1bKEix.js.map +0 -1
  348. package/dashboard/dist/assets/ScanSchemeDetailPage-D9AbS6UY.js +0 -2
  349. package/dashboard/dist/assets/ScanSchemeDetailPage-D9AbS6UY.js.map +0 -1
  350. package/dashboard/dist/assets/ScanStationPage-gcZGefvT.js +0 -2
  351. package/dashboard/dist/assets/ScanStationPage-gcZGefvT.js.map +0 -1
  352. package/dashboard/dist/assets/index-B_GT23TE.js +0 -3
  353. package/dashboard/dist/assets/index-B_GT23TE.js.map +0 -1
  354. package/dashboard/dist/assets/index-CgUcYveM.js +0 -67
  355. package/dashboard/dist/assets/index-CgUcYveM.js.map +0 -1
  356. package/dashboard/dist/assets/index-Dh8MJl3L.css +0 -1
@@ -1,308 +0,0 @@
1
- /**
2
- * Scan-code types: schemes, rules, and execute outcomes.
3
- *
4
- * A scan code is a plain string from any input source (barcode scanner,
5
- * RFID reader, manual entry) encoding version:category:target. The scheme
6
- * (selected by the leading TWO digits, 10-99) declares which escalation
7
- * metadata facet the target resolves against and how the string parses.
8
- * The rule (selected by the single-digit category, 0-9) is an ordered list
9
- * of condition/action steps over the escalation surface plus a fallback.
10
- * Both indices are assigned automatically; operators name entries, not numbers.
11
- */
12
- import type { ScanChoice, ScanPresentedChoice } from './scan-choice';
13
- export declare const SCAN_ENCODINGS: {
14
- /** Digits only, fixed widths — fits UPC-A/EAN/ITF labels. */
15
- readonly FIXED: "fixed";
16
- /** Delimiter-separated text — Code 128 / QR / DataMatrix labels. */
17
- readonly DELIMITED: "delimited";
18
- };
19
- export type ScanEncoding = (typeof SCAN_ENCODINGS)[keyof typeof SCAN_ENCODINGS];
20
- export declare const SCAN_SCHEME_KINDS: {
21
- /** The ECA model: the target resolves against escalations; the rule's steps run. */
22
- readonly ACTION: "action";
23
- /**
24
- * A badge: the target resolves against users (target_facet names the
25
- * lt_users.metadata key it matches) and a match mints a short-lived
26
- * acting-identity grant. Identity schemes never walk steps.
27
- */
28
- readonly IDENTITY: "identity";
29
- };
30
- export type ScanSchemeKind = (typeof SCAN_SCHEME_KINDS)[keyof typeof SCAN_SCHEME_KINDS];
31
- export declare const SCAN_VERBS: {
32
- readonly SHOW_DETAIL: "show-detail";
33
- readonly SHOW_LIST: "show-list";
34
- readonly CLAIM: "claim";
35
- readonly CLAIM_SHOW_DETAIL: "claim-show-detail";
36
- readonly RELEASE: "release";
37
- readonly RESOLVE: "resolve";
38
- readonly ESCALATE: "escalate";
39
- readonly CANCEL: "cancel";
40
- /**
41
- * Add the scanned item to an accumulator escalation. With
42
- * `params.accumulate.containerFacet` the scan locates the ITEM's own row
43
- * and joins it to the container that shares that facet value, writing
44
- * both rows in one statement; without it the scan locates the CONTAINER
45
- * and adds `params.itemKey`.
46
- */
47
- readonly ACCUMULATE: "accumulate";
48
- /** Locate the row, then PRESENT its reality + the step's labeled choices. */
49
- readonly PRESENT: "present";
50
- };
51
- export type ScanVerb = (typeof SCAN_VERBS)[keyof typeof SCAN_VERBS];
52
- /** Verbs that change escalation state (may carry a confirm prompt). */
53
- export declare const SCAN_MUTATING_VERBS: readonly ScanVerb[];
54
- export declare const SCAN_OUTCOMES: {
55
- /** A step matched and its action ran (or the located item is returned for show verbs). */
56
- readonly EXECUTED: "executed";
57
- /** A show-list step matched multiple escalations. */
58
- readonly MATCHED_LIST: "matched_list";
59
- /** A confirm step located its target; the client must confirm before the per-id action runs. */
60
- readonly CONFIRM_REQUIRED: "confirm_required";
61
- /** No step matched; render the rule's fallback screen. */
62
- readonly NO_MATCH_FALLBACK: "no_match_fallback";
63
- /** Unknown/disabled scheme version or category. */
64
- readonly UNCONFIGURED: "unconfigured";
65
- /** The code string did not parse under the scheme. */
66
- readonly INVALID_CODE: "invalid_code";
67
- /** The caller's roles do not permit the matched action. */
68
- readonly FORBIDDEN: "forbidden";
69
- /** A concurrent actor won the row (double scan). */
70
- readonly CONFLICT: "conflict";
71
- /** An identity scan matched a user; the response carries the acting grant. */
72
- readonly IDENTITY_PRIMED: "identity_primed";
73
- /** An identity scan matched no user; render the rule's fallback screen. */
74
- readonly IDENTITY_UNKNOWN: "identity_unknown";
75
- /**
76
- * The step/choice requires an acting identity the request cannot satisfy
77
- * (no grant, a dead grant, or a write-incapable principal); render the
78
- * rule's notPrimed screen. Distinct from FORBIDDEN — the acting user's own
79
- * RBAC was never consulted.
80
- */
81
- readonly NOT_PRIMED: "not_primed";
82
- /** A PRESENT step located its row; the response carries reality + choices. */
83
- readonly CHOICES: "choices";
84
- /**
85
- * An accumulate step in item mode located the item's row, but no pending
86
- * container carries its facet: the previous container closed and its
87
- * successor has not parked yet. The response carries the item row and the
88
- * facet so the station can say "container closing, scan again".
89
- */
90
- readonly NO_OPEN_CONTAINER: "no_open_container";
91
- };
92
- export type ScanOutcome = (typeof SCAN_OUTCOMES)[keyof typeof SCAN_OUTCOMES];
93
- export declare const SCAN_AVAILABILITY: {
94
- readonly AVAILABLE: "available";
95
- readonly CLAIMED: "claimed";
96
- readonly MINE: "mine";
97
- readonly ANY: "any";
98
- };
99
- export type ScanAvailability = (typeof SCAN_AVAILABILITY)[keyof typeof SCAN_AVAILABILITY];
100
- export declare const SCAN_CARDINALITY: {
101
- readonly FIRST: "first";
102
- readonly MANY: "many";
103
- };
104
- export type ScanCardinality = (typeof SCAN_CARDINALITY)[keyof typeof SCAN_CARDINALITY];
105
- /** Metadata keys stamped onto escalations touched by a scan (provenance). */
106
- export declare const SCAN_PROVENANCE_KEYS: {
107
- readonly SCHEME: "scanScheme";
108
- readonly CATEGORY: "scanCategory";
109
- readonly ACTION_NAME: "scanActionName";
110
- readonly SCANNED_AT: "scannedAt";
111
- /** The authenticated device principal when a mutation ran under an acting identity. */
112
- readonly STATION: "scanStation";
113
- };
114
- /** The ephemeral-keystore label acting-identity grants are minted under. */
115
- export declare const ACTING_IDENTITY_LABEL = "acting_identity";
116
- /**
117
- * Template tokens usable inside step params (item key, resolver payload,
118
- * metadata). Beyond the three scan tokens, `{claim.<facet>}` reads the
119
- * acting user's single live claim and `{item.<facet>}` reads the row an
120
- * item-mode accumulate step located; a token that cannot resolve fails the
121
- * step instead of writing the literal.
122
- */
123
- export declare const SCAN_TEMPLATE_TOKENS: {
124
- readonly TARGET: "{scan.target}";
125
- readonly CATEGORY: "{scan.category}";
126
- readonly SCANNED_AT: "{scan.scannedAt}";
127
- };
128
- /** Facet-bag token prefixes: `{claim.orderId}`, `{item.binKey}`. */
129
- export declare const SCAN_TEMPLATE_BAGS: {
130
- readonly CLAIM: "claim";
131
- readonly ITEM: "item";
132
- };
133
- export type ScanTemplateBag = (typeof SCAN_TEMPLATE_BAGS)[keyof typeof SCAN_TEMPLATE_BAGS];
134
- export interface ScanScheme {
135
- version: number;
136
- name: string;
137
- description: string | null;
138
- /**
139
- * The metadata key the scanned target resolves against: an escalation
140
- * metadata key for action schemes, an lt_users.metadata key (e.g.
141
- * badge_id) for identity schemes.
142
- */
143
- target_facet: string;
144
- encoding: ScanEncoding;
145
- delimiter: string;
146
- target_length: number | null;
147
- kind: ScanSchemeKind;
148
- /** Identity kind only: how long a minted acting grant lives (1–86400 s). */
149
- grant_ttl_seconds: number | null;
150
- /** Identity kind only: 0 = TTL-bound; n = the grant covers n scan requests. */
151
- grant_max_uses: number;
152
- enabled: boolean;
153
- created_at?: string;
154
- updated_at?: string;
155
- }
156
- /** The Condition: a view over the escalation surface. */
157
- export interface ScanStepQuery {
158
- /** Expected queue(s). Empty/absent = any role visible to the caller. */
159
- roles?: string[];
160
- status?: 'pending' | 'resolved' | 'cancelled';
161
- availability?: ScanAvailability;
162
- /** Extra metadata guards beyond the scheme's target facet. */
163
- facets?: Record<string, any>;
164
- }
165
- export interface ScanStepParams {
166
- /** Canned resolver payload template (resolve). Values may use SCAN_TEMPLATE_TOKENS. */
167
- resolverPayload?: Record<string, any>;
168
- /** Metadata to merge/stamp (claim, resolve, escalate). */
169
- metadata?: Record<string, any>;
170
- /** Target role for escalate (a new escalation is created there). */
171
- targetRole?: string;
172
- /** Escalation type for the created escalation (escalate). */
173
- escalationType?: string;
174
- /** Description for the created escalation (escalate). */
175
- description?: string;
176
- /** How to close the located escalation before an escalate creates the next one. */
177
- closeCurrent?: 'resolve' | 'cancel';
178
- /** Claim window (claim verbs). */
179
- durationMinutes?: number;
180
- /** Item key template (accumulate, container-locate mode). Defaults to `{scan.target}`. */
181
- itemKey?: string;
182
- /** Accumulate verb options. */
183
- accumulate?: ScanAccumulateParams;
184
- }
185
- export interface ScanAccumulateParams {
186
- /**
187
- * Item-locate mode: the scanned target is the item's own escalation (found
188
- * by the scheme facet); the container is the pending accumulator whose
189
- * metadata carries this facet with the same value the item row holds.
190
- */
191
- containerFacet?: string;
192
- /** Expected container queue(s); intersects with the actor's write scope. */
193
- containerRoles?: string[];
194
- /** Item-locate mode: also write the item's row as the reciprocal (default true). */
195
- reciprocal?: boolean;
196
- }
197
- export interface ScanStep {
198
- query: ScanStepQuery;
199
- cardinality?: ScanCardinality;
200
- verb: ScanVerb;
201
- /** Present = two-phase: locate, then the client confirms before the per-id action runs. */
202
- confirm?: {
203
- prompt: string;
204
- };
205
- params?: ScanStepParams;
206
- /** PRESENT only: the labeled choice set rendered under the located reality. */
207
- choices?: ScanChoice[];
208
- /**
209
- * PRESENT only: when the step holds exactly ONE confirm-less choice, the
210
- * scan executes it directly instead of presenting — one scan, one action.
211
- * An unsatisfied identity requirement still stops over at the badge screen.
212
- */
213
- autoSelectSingle?: boolean;
214
- /** The step executes only under a real acting identity (badge or a write-capable login). */
215
- requireActingIdentity?: boolean;
216
- }
217
- export interface ScanRuleFallback {
218
- /** Markdown rendered on the fallback screen when no step matches. */
219
- markdown?: string;
220
- /** Optional dashboard route to land on instead of the default list. */
221
- route?: string;
222
- }
223
- export interface ScanRule {
224
- scheme_version: number;
225
- /** Single digit, '0'–'9' (auto-assigned). */
226
- category: string;
227
- /** Friendly label — this is what gets printed next to the physical code. */
228
- name: string;
229
- steps: ScanStep[];
230
- fallback: ScanRuleFallback;
231
- /** The "scan your badge" screen — rendered when an acting identity is required and absent. */
232
- notPrimed: ScanRuleFallback;
233
- enabled: boolean;
234
- created_at?: string;
235
- updated_at?: string;
236
- }
237
- export interface ParsedScanCode {
238
- version: number;
239
- category: string;
240
- target: string;
241
- }
242
- export interface ScanExecuteRequest {
243
- code: string;
244
- /** An acting-identity grant (eph:v1:acting_identity:*) — verbs run as that user. */
245
- actingToken?: string;
246
- /** The grant being replaced by an identity scan — best-effort revoked on mint. */
247
- previousActingToken?: string;
248
- }
249
- /** Action awaiting client-side confirmation (CONFIRM_REQUIRED). */
250
- export interface ScanPendingAction {
251
- escalationId: string;
252
- verb: ScanVerb;
253
- prompt: string;
254
- params?: ScanStepParams;
255
- }
256
- export interface ScanExecuteResponse {
257
- outcome: ScanOutcome;
258
- /** The parsed code, echoed for display/toasts. */
259
- parsed?: ParsedScanCode;
260
- /** Rule identity (name is the friendly label). */
261
- rule?: {
262
- schemeVersion: number;
263
- category: string;
264
- name: string;
265
- };
266
- /** Index of the step that matched. */
267
- stepIndex?: number;
268
- verb?: ScanVerb;
269
- /** Single matched escalation (show-detail, claim, resolve, escalate, cancel outcomes). */
270
- escalation?: Record<string, any>;
271
- /** Multiple matches (show-list). */
272
- escalations?: Record<string, any>[];
273
- total?: number;
274
- /** Query the client uses to build the list-page URL (show-list). */
275
- listQuery?: ScanStepQuery & {
276
- targetFacet: string;
277
- target: string;
278
- };
279
- pendingAction?: ScanPendingAction;
280
- fallback?: ScanRuleFallback;
281
- /** The "scan your badge" screen (NOT_PRIMED, or beside withheld choices). */
282
- notPrimed?: ScanRuleFallback;
283
- /** The labeled choice set (CHOICES). */
284
- choices?: ScanPresentedChoice[];
285
- /** NO_OPEN_CONTAINER: the facet the located item names and no pending container carries. */
286
- container?: {
287
- facet: string;
288
- value: string;
289
- };
290
- /** CHOICES: the step would auto-execute its single choice — only identity stopped it. */
291
- autoSelect?: boolean;
292
- /** The badged person (IDENTITY_PRIMED) — id lets the client recognize its own claims. */
293
- actor?: {
294
- id: string;
295
- displayName: string;
296
- };
297
- /** The minted acting grant (IDENTITY_PRIMED) — eph:v1:acting_identity:<uuid>. */
298
- actingToken?: string;
299
- /** Display copy of the grant's expiry (the keystore enforces it). */
300
- expiresAt?: string;
301
- /**
302
- * IDENTITY_PRIMED: the scheme's `grant_max_uses`. `1` is a single-shot
303
- * grant the client drops after the first request that carries it; `0`
304
- * lives until its TTL.
305
- */
306
- maxUses?: number;
307
- error?: string;
308
- }
@@ -1,2 +0,0 @@
1
- import{a as m,j as e}from"./vendor-query-DvWWuNIB.js";import{w as dt,x as ut,c as mt,y as xt,M as Ee,z as ht,A as gt,B as ft,E as pt,G as bt,H as yt,I as jt,K as vt,L as Ct,O as kt,Q as Nt,r as wt,R as Pt,T as St,U as Rt,V as Et,W as Tt,X as Bt,Y as At,Z as Ot,_ as Lt,$ as Mt,a0 as Ft,a1 as zt,a2 as It,a3 as Ut,a4 as $t,a5 as Vt,a6 as _t}from"./index-CgUcYveM.js";import{a as Te,u as Be,f as qt}from"./vendor-react-_9U4mKFr.js";import{i as Ht}from"./task-queues-7-sHKPsN.js";import{X as ce,aj as Kt,x as Dt,ak as Gt,al as Qt,_ as Wt,i as Yt,am as Xt,P as Jt,an as Zt}from"./vendor-icons-B7OcUM6b.js";import{u as Ae,C as es,r as ts,B as ss,a as as}from"./BulkAssignModal-BOAWsViq.js";import{E as ns}from"./EscalationTitleSelect-CzKfavri.js";import{u as is,E as ls,a as rs,t as os}from"./EscalationTimeline-DKyTz6sM.js";import{i as cs,E as ds}from"./EscalationListView-CkBnkpDJ.js";import{u as us}from"./useFilterParams-DBRw1Hcv.js";import{u as ms}from"./useDebouncedValue-Da0lPmj3.js";import{D as xs}from"./DataTable-spX1dFyb.js";import{S as hs}from"./StickyPagination-9ITrei_d.js";import{P as gs}from"./constants-CeBBTzf5.js";import{m as fs,E as ps}from"./escalation-columns-Mvsze5eV.js";import{R as bs,a as ys}from"./RowActions-Bdd7z4eB.js";import"./UserName-Pw46tO_k.js";import"./StatusBadge-DHVwxre2.js";import"./EmptyState-DgC_6njU.js";import"./useContainerWidth-DSLp1gEm.js";import"./EntityTimelinePanel-DIDcF5Yu.js";import"./FilterBar-CvMBCVIo.js";import"./PriorityBadge-r33mpDju.js";import"./RolePill-BafrASDX.js";import"./WorkflowPill-ZepbO_ny.js";import"./CountdownTimer-BaexQMK6.js";function js(){const{pathname:t,search:a}=Te(),u=Be(),{resolveUrl:l}=dt();m.useEffect(()=>{const g=t+a;if(ut(g).length===0)return;const p=l(g);p!==g&&u(p,{replace:!0})},[t,a,l,u])}const vs=["<","<=",">",">=","="],Cs=["priority","created_at","updated_at","status","role"],O="input text-xs py-1",Pe="select text-xs py-1",K="text-text-tertiary hover:text-text-primary transition-colors";function Se(t){return t==="true"?!0:t==="false"?!1:t.trim()!==""&&!Number.isNaN(Number(t))?Number(t):t}const ks=t=>Object.entries(t??{}).map(([a,u])=>({key:a,value:String(u)})),Ns=t=>(t??[]).map(a=>{const[u,l]=Object.entries(a)[0]??["",""];return{key:u,value:String(l)}});function B({title:t,hint:a,children:u}){return e.jsxs("div",{className:"border-t border-surface-border/50 py-3 first:border-t-0 first:pt-1",children:[e.jsxs("div",{className:"mb-1.5 flex items-baseline justify-between",children:[e.jsx("span",{className:"text-2xs font-medium uppercase tracking-wide text-text-tertiary",children:t}),a&&e.jsx("span",{className:"text-2xs font-mono text-text-tertiary/70",children:a})]}),u]})}function D({value:t,onChange:a,placeholder:u}){return e.jsx("input",{list:"lt-facet-keys",className:`${O} w-40`,placeholder:u,value:t,onChange:l=>a(l.target.value)})}function ws({value:t,onChange:a,facetKeys:u=[],search:l="",onSearchChange:g}){const p=ks(t.facets),b=Ns(t.block),f=t.range??[],r=t.exists??[],k=t.orderBy??[],P=n=>{const o={};for(const c of n)c.key&&(o[c.key]=Se(c.value));a({...t,facets:Object.keys(o).length?o:void 0})},E=n=>{const o=n.filter(c=>c.key).map(c=>({[c.key]:Se(c.value)}));a({...t,block:o.length?o:void 0})},T=n=>a({...t,range:n.length?n:void 0}),y=n=>a({...t,exists:n.length?n:void 0}),v=n=>a({...t,orderBy:n.length?n:void 0});return e.jsxs("div",{className:"text-xs",children:[e.jsx("datalist",{id:"lt-facet-keys",children:u.map(n=>e.jsx("option",{value:n},n))}),e.jsxs("datalist",{id:"lt-sort-fields",children:[Cs.map(n=>e.jsx("option",{value:n},n)),u.map(n=>e.jsx("option",{value:`metadata.${n}`},n))]}),g&&e.jsx(B,{title:"Match id",hint:"id · workflow · origin",children:e.jsx("input",{className:`${O} w-full`,placeholder:"Exact escalation, workflow, or origin id…",value:l,onChange:n=>g(n.target.value)})}),e.jsx(B,{title:"Has facet",hint:"metadata @>",children:[...p,{key:"",value:""}].map((n,o)=>e.jsxs("div",{className:"mb-1 flex items-center gap-1",children:[e.jsx(D,{value:n.key,placeholder:"key",onChange:c=>{const i=[...p];i[o]={...n,key:c},P(i)}}),e.jsx("span",{className:"text-text-tertiary",children:"="}),e.jsx("input",{className:`${O} w-40`,placeholder:"value",value:n.value,onChange:c=>{const i=[...p];i[o]={...n,value:c.target.value},P(i)}}),o<p.length&&e.jsx("button",{className:K,onClick:()=>P(p.filter((c,i)=>i!==o)),children:"×"})]},o))}),e.jsx(B,{title:"Range",hint:"numeric",children:[...f,{facet:"",op:"<=",value:0}].map((n,o)=>e.jsxs("div",{className:"mb-1 flex items-center gap-1",children:[e.jsx(D,{value:n.facet,placeholder:"numeric facet",onChange:c=>{const i=[...f];i[o]={...n,facet:c},T(i.filter(j=>j.facet))}}),e.jsx("select",{className:Pe,value:n.op,onChange:c=>{const i=[...f];i[o]={...n,op:c.target.value},T(i.filter(j=>j.facet))},children:vs.map(c=>e.jsx("option",{value:c,children:c},c))}),e.jsx("input",{type:"number",className:`${O} w-24`,value:n.value,onChange:c=>{const i=[...f];i[o]={...n,value:Number(c.target.value)},T(i.filter(j=>j.facet))}}),o<f.length&&e.jsx("button",{className:K,onClick:()=>T(f.filter((c,i)=>i!==o)),children:"×"})]},o))}),e.jsx(B,{title:"Has key",hint:"metadata ? key",children:e.jsxs("div",{className:"flex flex-wrap items-center gap-1",children:[r.map(n=>e.jsxs("span",{className:"flex items-center gap-1 rounded bg-accent/15 px-1.5 py-0.5 text-accent",children:[n,e.jsx("button",{className:"text-accent/70 hover:text-accent",onClick:()=>y(r.filter(o=>o!==n)),children:"×"})]},n)),e.jsx(D,{value:"",placeholder:"+ key",onChange:n=>{n&&!r.includes(n)&&y([...r,n])}})]})}),e.jsx(B,{title:"Exclude",hint:"NOT @>",children:[...b,{key:"",value:""}].map((n,o)=>e.jsxs("div",{className:"mb-1 flex items-center gap-1",children:[e.jsx(D,{value:n.key,placeholder:"key",onChange:c=>{const i=[...b];i[o]={...n,key:c},E(i)}}),e.jsx("span",{className:"text-text-tertiary",children:"="}),e.jsx("input",{className:`${O} w-40`,placeholder:"value",value:n.value,onChange:c=>{const i=[...b];i[o]={...n,value:c.target.value},E(i)}}),o<b.length&&e.jsx("button",{className:K,onClick:()=>E(b.filter((c,i)=>i!==o)),children:"×"})]},o))}),e.jsx(B,{title:"Sort by",children:[...k,{field:"",direction:"asc"}].map((n,o)=>e.jsxs("div",{className:"mb-1 flex items-center gap-1",children:[e.jsx("input",{list:"lt-sort-fields",className:`${O} w-44`,placeholder:"column or metadata.key",value:n.field,onChange:c=>{const i=[...k];i[o]={...n,field:c.target.value},v(i.filter(j=>j.field))}}),e.jsxs("select",{className:Pe,value:n.direction??"asc",onChange:c=>{const i=[...k];i[o]={...n,direction:c.target.value},v(i.filter(j=>j.field))},children:[e.jsx("option",{value:"asc",children:"asc"}),e.jsx("option",{value:"desc",children:"desc"})]}),e.jsxs("label",{className:"flex items-center gap-1 text-text-tertiary",children:[e.jsx("input",{type:"checkbox",checked:!!n.numeric,onChange:c=>{const i=[...k];i[o]={...n,numeric:c.target.checked},v(i.filter(j=>j.field))}}),"num"]}),o<k.length&&e.jsx("button",{className:K,onClick:()=>v(k.filter((c,i)=>i!==o)),children:"×"})]},o))})]})}function Ps({value:t,onChange:a,facetKeys:u,search:l,onSearchChange:g,activeFacetCount:p,onClear:b,onClose:f}){return e.jsxs("div",{className:"h-full overflow-y-auto",children:[e.jsxs("div",{className:"sticky top-0 z-10 flex items-center justify-between px-4 py-3 bg-surface-raised border-b border-surface-border/50",children:[e.jsx("span",{className:"text-xs font-semibold text-text-primary",children:"Faceted query"}),e.jsxs("div",{className:"flex items-center gap-2",children:[p>0&&e.jsx("button",{onClick:b,className:"text-2xs text-text-tertiary hover:text-text-primary transition-colors",children:"Clear"}),e.jsx("button",{onClick:f,className:"p-1 rounded hover:bg-surface-hover text-text-tertiary hover:text-text-primary transition-colors",title:"Close",children:e.jsx(ce,{className:"w-4 h-4"})})]})]}),e.jsxs("div",{className:"px-4 py-2",children:[e.jsxs("p",{className:"mb-2 text-2xs leading-snug text-text-tertiary",children:["Precise metadata facets plus exact correlation-id lookup — they compose in one SQL query. Facet keys are the ones that actually exist in your visible escalations. Set status to ",e.jsx("span",{className:"font-medium",children:"All"})," to find an order across every status; the whole query is shareable via the URL."]}),e.jsx(ws,{value:t,onChange:a,facetKeys:u,search:l,onSearchChange:g})]})]})}const Ss=t=>t.isPriorityPending||t.isClaimPending||t.isAssignPending||t.isUnassignPending||t.isTriagePending||t.isCancelPending,G="inline-flex items-center h-7 px-2.5 text-2xs font-medium text-text-secondary bg-surface border border-surface-border rounded-[4px] hover:border-accent/50 hover:text-text-primary transition-colors disabled:opacity-50 disabled:hover:border-surface-border",Re=`${G} appearance-none cursor-pointer`,Rs="inline-flex items-center h-7 px-2.5 text-2xs font-medium text-status-error bg-surface border border-status-error/30 rounded-[4px] hover:border-status-error hover:bg-status-error/5 transition-colors disabled:opacity-50";function Es(t){var f;const a=Ss(t),u=Ae(),{data:l}=mt(),g=xt(),p=g!==null?g:((f=l==null?void 0:l.ai)==null?void 0:f.enabled)===!0,b=t.selectedCount>0;return e.jsx("div",{className:`grid transition-all duration-200 ease-in-out ${b?"grid-rows-[1fr] opacity-100":"grid-rows-[0fr] opacity-0 pointer-events-none"}`,children:e.jsx("div",{className:"overflow-hidden",children:e.jsxs("div",{className:"flex flex-wrap items-center gap-2 py-2.5 pl-3 pr-2 mt-4 mb-3 bg-surface-sunken/60 border-l-2 border-l-accent",children:[e.jsxs("span",{className:"text-2xs font-semibold uppercase tracking-wider text-accent tabular-nums",children:[t.selectedCount," selected"]}),e.jsx("div",{className:"mx-1 h-4 w-px bg-surface-border"}),e.jsxs("select",{onChange:r=>{r.target.value&&(t.onSetPriority(parseInt(r.target.value)),r.target.value="")},disabled:a,className:Re,defaultValue:"",children:[e.jsx("option",{value:"",disabled:!0,children:"Priority…"}),gs.map(r=>e.jsx("option",{value:r.value,children:r.label},r.value))]}),e.jsxs("select",{onChange:r=>{r.target.value&&(t.onClaim(parseInt(r.target.value)),r.target.value="")},disabled:a,className:Re,defaultValue:"",children:[e.jsx("option",{value:"",disabled:!0,children:"Claim for…"}),u.map(r=>e.jsx("option",{value:r.value,children:r.label},r.value))]}),e.jsx("button",{onClick:t.onAssign,disabled:a,className:G,children:t.isAssignPending?"Assigning…":"Assign to…"}),e.jsx("button",{onClick:t.onUnassign,disabled:a,className:G,children:t.isUnassignPending?"Unassigning…":"Unassign"}),p&&e.jsx("button",{onClick:t.onTriage,disabled:a,className:G,children:t.isTriagePending?"Triaging…":"Triage"}),t.cancelLabel!==!1&&e.jsx("button",{onClick:t.onCancel,disabled:a,className:Rs,children:t.isCancelPending?t.cancelLabel?`${t.cancelLabel}…`:"Cancelling…":t.cancelLabel||"Cancel"}),e.jsx("div",{className:"flex-1"}),a&&e.jsx("span",{className:"text-2xs text-text-tertiary animate-pulse",children:"Processing…"}),e.jsx("button",{onClick:t.onClearSelection,className:"px-1 text-2xs font-medium text-text-tertiary hover:text-text-primary transition-colors",children:"Clear"})]})})})}function Ts({open:t,onClose:a,selectedCount:u,onSubmit:l,isPending:g}){const[p,b]=m.useState(""),f=()=>{l(p||void 0)};return e.jsx(Ee,{open:t,onClose:a,title:"Submit for AI Triage",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("p",{className:"text-sm text-text-secondary",children:["Submit ",e.jsx("span",{className:"font-medium text-text-primary",children:u})," escalation(s) for AI triage? The triage orchestrator will take over resolution."]}),e.jsxs("div",{children:[e.jsxs("label",{className:"text-xs font-medium text-text-secondary block mb-1",children:["Triage hint ",e.jsx("span",{className:"text-text-tertiary",children:"(optional)"})]}),e.jsx("input",{type:"text",value:p,onChange:r=>b(r.target.value),placeholder:"e.g., image_orientation",className:"input text-xs font-mono w-full"}),e.jsx("p",{className:"text-2xs text-text-tertiary mt-1",children:"Guides the triage workflow on what remediation to apply"})]}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{onClick:a,className:"btn-secondary text-xs",children:"Cancel"}),e.jsx("button",{onClick:f,disabled:g,className:"btn-primary text-xs",children:g?"Submitting...":"Submit for Triage"})]})]})})}function A(t,a,u){return l=>{t.mutate(l,{onSuccess:()=>{a(),u==null||u()}})}}function Bs(t){const a=()=>[...t.selectedIds];return{handleSetPriority:r=>{A(t.setPriority,t.clearSelection)({ids:a(),priority:r})},handleBulkClaim:r=>{A(t.bulkClaim,t.clearSelection)({ids:a(),durationMinutes:r})},handleBulkTriage:r=>{A(t.bulkTriage,t.clearSelection,t.closeTriageModal)({ids:a(),hint:r})},handleBulkAssign:(r,k,P)=>{A(t.bulkAssign,t.clearSelection,t.closeAssignModal)({ids:a(),targetUserId:r,durationMinutes:k,reassign:P})},handleBulkUnassign:()=>{A(t.bulkUnassign,t.clearSelection)({ids:a()})},handleBulkCancel:()=>{A(t.bulkCancel,t.clearSelection,t.closeCancelModal)({ids:a()})}}}function As({claimTarget:t,onClose:a,claimDuration:u,onDurationChange:l,claimDurations:g,onCustomClaimChange:p,onClaim:b,isPending:f}){return e.jsx(Ee,{open:!!t,onClose:a,title:"Claim Escalation",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("p",{className:"text-sm text-text-secondary",children:["Claim ",e.jsx("span",{className:"font-medium text-text-primary",children:t==null?void 0:t.type})," for:"]}),e.jsxs("select",{value:u,onChange:r=>{l(r.target.value)},className:"select w-full text-sm",children:[g.map(r=>e.jsx("option",{value:r.value,children:r.label},r.value)),e.jsx("option",{value:"custom",children:"Other..."})]}),u==="custom"&&e.jsx(es,{onChange:p,autoFocus:!0}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{onClick:a,className:"btn-secondary text-xs",children:"Cancel"}),e.jsx("button",{onClick:b,className:"btn-primary text-xs",disabled:f,children:f?"Claiming...":"Claim"})]})]})})}function ia(){var we;js();const t=Be(),{filters:a,setFilter:u,pagination:l}=us({filters:{role:"",type:"",priority:"",status:"available",search:""}});ht({role:a.role||null,verbs:["created","claimed"]});const g=ms(a.search),p=Ae(),[b,f]=m.useState(null),[r,k]=m.useState("30"),[P,E]=m.useState(0),T=m.useCallback(s=>E(s),[]),[y,v]=m.useState(new Set),n=m.useRef(null),o=m.useRef(null),c=m.useCallback(s=>{var x;if((x=o.current)==null||x.disconnect(),o.current=null,!s||typeof ResizeObserver>"u")return;const d=new ResizeObserver(()=>{var H;(H=n.current)==null||H.style.setProperty("--lt-sticky-top",`${s.offsetHeight-1}px`)});d.observe(s),o.current=d},[]),[i,j]=m.useState(!1),[L,M]=qt(),h=m.useMemo(()=>gt(L),[L]),N=m.useCallback(s=>{M(d=>{const x=new URLSearchParams(d);return ft(x,s),x.delete("page"),x})},[M]),{data:F}=pt(i),z=bt(h)+(a.search?1:0),Q="facet-query",{setPanel:de,closePanel:ue,open:Oe,ownerKey:Le}=yt();m.useEffect(()=>{if(!i){ue(Q);return}de(e.jsx(Ps,{value:h,onChange:N,facetKeys:(F==null?void 0:F.keys)??[],search:a.search??"",onSearchChange:s=>u("search",s),activeFacetCount:z,onClear:()=>{N({}),u("search","")},onClose:()=>j(!1)}),{width:420,key:Q})},[i,h,N,F,a.search,u,z,de,ue]);const me=Oe&&Le===Q,W=m.useRef(!1);m.useEffect(()=>{if(me){W.current=!0;return}W.current&&(W.current=!1,j(!1))},[me]);const[Me,Y]=m.useState(!1),[Fe,X]=m.useState(!1),[ze,J]=m.useState(!1),Ie=m.useCallback(s=>N({...h,orderBy:s}),[h,N]),I=Te(),{data:U}=jt(),xe=vt(),Ue=m.useCallback(()=>{var x;const s=window.prompt("Pin label:");if(!(s!=null&&s.trim()))return;const d=((x=U==null?void 0:U.preferences)==null?void 0:x.pinnedViews)??[];xe.mutate({pinnedViews:[...d,{id:Ct(),label:s.trim(),url:I.pathname+I.search,badge:!0}]})},[I.pathname,I.search,U,xe]),{canBulk:$e}=kt(),{kiosk:Z}=Nt(),he=h.facets?Object.keys(h.facets):[],$=L.get("view"),ee=L.get("layout"),Ve=m.useCallback(s=>{M(d=>{const x=new URLSearchParams(d);return s?x.set("view",s):x.delete("view"),x},{replace:!0})},[M]),te=$==="timeline",_e=m.useCallback(s=>{const{[s]:d,...x}=h.facets??{};N({...h,facets:Object.keys(x).length>0?x:void 0})},[h,N]),ge=wt(),fe=Pt(),pe=St(),se=Rt(),be=Et(),ae=Tt(),V=Bt(),{data:ne}=At(),{data:S}=Ot(),{data:ie}=Lt(),{user:_,isSuperAdmin:qe,hasRoleType:He}=Mt(),ye=qe||He("admin"),je=m.useMemo(()=>new Set(((_==null?void 0:_.roles)??[]).map(s=>s.role)),[_]),Ke=m.useMemo(()=>{const s=(S==null?void 0:S.roles)??[];return(ye?s:s.filter(x=>je.has(x.role)&&!Ht(x.role))).map(x=>({value:x.role,label:Ft(x)})).sort((x,H)=>x.label.localeCompare(H.label))},[S,ye,je]);m.useEffect(()=>{v(new Set)},[a.role,a.type,a.priority,a.status,g,l.page,l.pageSize]);const le=m.useMemo(()=>({statusFilter:a.status||"",role:a.role||void 0,type:a.type||void 0,priority:a.priority?parseInt(a.priority):void 0,search:g||void 0,facets:h,view:It($)?$:null,layout:zt(ee)?ee:null}),[a.status,a.role,a.type,a.priority,g,h,$,ee]),ve=100,{escalations:C,total:w,listSchema:De,singleRole:R,hasRichView:Ce,isLoading:Ge,isFetching:ke,error:q,refetch:Qe}=is(le,{limit:te?ve:l.pageSize,offset:l.offset}),We=Ut(R??"",void 0,!!R),re=R?ts((we=We.data)==null?void 0:we.form_schema).cancel:void 0,oe=$t(le.view,Ce),Ye=oe===_t.RICH,Ne=m.useMemo(()=>{if(!h.jeopardy||!R)return null;const s=((S==null?void 0:S.roles)??[]).find(x=>x.role===R),d=(s==null?void 0:s.priority_threshold_minutes)??(s==null?void 0:s.sla_minutes)??null;return d!=null?Vt(d*6e4):null},[h.jeopardy,R,S]),Xe=m.useMemo(()=>{const s=new Set;for(const d of C)y.has(d.id)&&s.add(d.role);return[...s]},[C,y]),Je=m.useMemo(()=>C.filter(s=>y.has(s.id)&&cs(s)).length,[C,y]),Ze=m.useCallback(()=>v(new Set),[]),et=()=>{if(!b)return;const s=r==="custom"?P:parseInt(r);!s||s<=0||ge.mutate({id:b.id,durationMinutes:s},{onSuccess:()=>{f(null),t(`/escalations/detail/${b.id}`)}})},{handleSetPriority:tt,handleBulkClaim:st,handleBulkTriage:at,handleBulkAssign:nt,handleBulkUnassign:it,handleBulkCancel:lt}=Bs({selectedIds:y,clearSelection:Ze,setPriority:fe,bulkClaim:pe,bulkTriage:ae,bulkAssign:se,bulkUnassign:be,bulkCancel:V,closeTriageModal:()=>Y(!1),closeAssignModal:()=>X(!1),closeCancelModal:()=>J(!1)}),rt=s=>{const d=new Set(y);d.has(s)?d.delete(s):d.add(s),v(d)},ot=()=>{y.size===C.length?v(new Set):v(new Set(C.map(s=>s.id)))},ct=[$e?{key:"select",label:e.jsx("input",{type:"checkbox",checked:C.length>0&&y.size===C.length,onChange:ot,className:"rounded"}),render:s=>e.jsx("input",{type:"checkbox",checked:y.has(s.id),onChange:d=>{d.stopPropagation(),rt(s.id)},onClick:d=>d.stopPropagation(),className:"rounded"}),className:"w-10",priority:1}:{key:"spacer",label:"",render:()=>null,className:"w-10",priority:3},...fs({highlightKeys:he}),{key:"actions",label:"",render:s=>e.jsx(bs,{children:e.jsx(ys,{icon:Kt,title:"Claim escalation",onClick:()=>f(s),alwaysVisible:!0,colorClass:"text-accent/40 hover:text-accent",size:"sm"})}),className:"w-10 text-right"}];return e.jsxs("div",{ref:n,children:[e.jsxs("div",{className:"flex items-center gap-2 mb-10 min-w-0",children:[e.jsx(ns,{role:a.role,options:Ke,onChange:s=>u("role",s),locked:Z}),!Z&&e.jsx("button",{onClick:()=>{window.location.hash="#docs:dashboard.md:all-escalations"},className:"text-text-quaternary hover:text-accent transition-colors mt-1 shrink-0",title:"Open docs for this page",children:e.jsx(Dt,{className:"w-4 h-4",strokeWidth:1.5})})]}),e.jsxs("div",{ref:c,className:"sticky top-0 z-20 bg-surface",children:[e.jsx(ps,{filters:a,setFilter:u,roles:(ne==null?void 0:ne.roles)??[],types:(ie==null?void 0:ie.types)??[],showStatus:!0,showSearch:!1,showRole:!Z,actions:e.jsxs(e.Fragment,{children:[te&&e.jsxs("span",{className:"text-2xs text-text-tertiary whitespace-nowrap",children:[w>100&&e.jsxs(e.Fragment,{children:[e.jsxs("span",{className:"font-medium text-text-secondary",children:[(l.page-1)*100+1,"–",Math.min(l.page*100,w)]})," of "]}),e.jsx("span",{className:"font-medium text-text-secondary",children:w})," ",w===1?"escalation":"escalations"]}),e.jsx(ls,{orderBy:h.orderBy,onChange:Ie}),e.jsx("div",{role:"radiogroup","aria-label":"List view",className:"flex items-center rounded overflow-hidden border border-surface-border",children:[{key:"table",title:"Table view",Icon:Gt},{key:"rich",title:"Rich view",Icon:Qt},{key:"timeline",title:"Timeline view",Icon:Wt}].filter(s=>s.key!=="rich"||Ce).map(({key:s,title:d,Icon:x})=>e.jsx("button",{role:"radio","aria-checked":oe===s,onClick:()=>Ve(s),className:`px-1.5 py-1 transition-colors ${oe===s?"bg-accent text-text-inverse":"icon-link hover:bg-surface-hover"}`,title:d,children:e.jsx(x,{className:"w-3.5 h-3.5"})},s))}),e.jsxs("button",{onClick:()=>j(s=>!s),"aria-pressed":i,className:`relative rounded border border-surface-border px-1.5 py-1 transition-colors ${i?"bg-accent text-text-inverse":"icon-link hover:bg-surface-hover"}`,title:"Faceted query",children:[e.jsx(Yt,{className:"w-3.5 h-3.5"}),z>0&&e.jsx("span",{className:"absolute -right-1 -top-1 flex h-3.5 min-w-[14px] items-center justify-center rounded-full bg-accent px-0.5 text-2xs font-medium text-text-inverse",children:z})]}),e.jsxs("div",{className:"flex items-center gap-0.5",children:[e.jsx("button",{onClick:()=>Qe(),disabled:ke,className:"inline-flex h-7 w-7 items-center justify-center rounded icon-link hover:bg-surface-hover disabled:opacity-50",title:"Refresh",children:e.jsx(Xt,{className:`w-4 h-4 ${ke?"animate-spin":""}`})}),e.jsx("button",{onClick:Ue,className:"inline-flex h-7 w-7 items-center justify-center rounded icon-link hover:bg-surface-hover",title:"Pin this view — save the current filters to your Pinned section","data-testid":"pin-current-view",children:e.jsx(Jt,{className:"w-4 h-4"})})]})]})}),e.jsx(Es,{selectedCount:y.size,onClearSelection:()=>v(new Set),onSetPriority:tt,onClaim:st,onAssign:()=>X(!0),onUnassign:it,onTriage:()=>Y(!0),onCancel:()=>J(!0),isPriorityPending:fe.isPending,isClaimPending:pe.isPending,isAssignPending:se.isPending,isUnassignPending:be.isPending,isTriagePending:ae.isPending,isCancelPending:V.isPending,cancelLabel:re}),(h.facets&&Object.keys(h.facets).length>0||h.jeopardy)&&e.jsxs("div",{className:"bg-surface/98 backdrop-blur-sm border-b border-surface-border/30 -mx-page-x px-page-x py-2 flex items-center gap-1.5 flex-wrap",children:[h.jeopardy&&e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full bg-status-error px-2.5 py-0.5 text-2xs font-semibold text-text-inverse",children:[e.jsx(Zt,{className:"w-2.5 h-2.5",strokeWidth:2.5}),"in jeopardy",Ne&&e.jsxs("span",{className:"font-mono font-normal opacity-90",children:["> ",Ne]}),e.jsx("button",{onClick:()=>N({...h,jeopardy:void 0}),className:"ml-0.5 -mr-0.5 flex items-center text-text-inverse/70 hover:text-text-inverse transition-colors","aria-label":"Clear jeopardy filter",children:e.jsx(ce,{className:"w-2.5 h-2.5"})})]}),Object.entries(h.facets??{}).map(([s,d])=>e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full border border-accent/25 bg-accent/8 px-2.5 py-0.5 text-2xs font-medium text-accent/90",children:[e.jsx("span",{className:"font-mono text-text-tertiary",children:s}),e.jsx("span",{className:"text-text-quaternary",children:"="}),e.jsx("span",{className:"font-mono max-w-[160px] truncate",title:String(d),children:String(d)}),e.jsx("button",{onClick:()=>_e(s),className:"ml-0.5 -mr-0.5 flex items-center text-text-quaternary hover:text-status-error transition-colors","aria-label":`Remove ${s} filter`,children:e.jsx(ce,{className:"w-2.5 h-2.5"})})]},s)),Object.keys(h.facets??{}).length>1&&e.jsx("button",{onClick:()=>N({...h,facets:void 0}),className:"text-2xs text-text-quaternary hover:text-text-secondary transition-colors px-1",children:"clear all"})]})]}),q&&e.jsx("div",{className:"mb-4 px-4 py-3 rounded-md bg-status-error/10 border border-status-error/20 text-xs text-status-error",children:q.message==="Session expired"?"Your session has expired. Please log in again.":`Failed to load escalations: ${q.message}`}),te?e.jsx(rs,{escalations:C,highlightKeys:he,onRowClick:s=>t(`/escalations/detail/${s.id}`,{state:{from:"/escalations/available"}}),total:w,page:l.page,totalPages:Math.ceil(w/ve),onPageChange:l.setPage}):Ye?e.jsx(ds,{role:R,listSchema:De,activeEscalations:C,onRowClick:s=>t(`/escalations/detail/${s.id}`,{state:{from:"/escalations/available"}}),onOpenGroup:s=>t(s),onAddFacet:(s,d)=>N({...h,facets:{...h.facets??{},[s]:typeof d=="object"&&d!==null?JSON.stringify(d):d}}),total:w,page:l.page,totalPages:l.totalPages(w),pageSize:l.pageSize,onPageChange:l.setPage,onPageSizeChange:l.setPageSize}):e.jsxs(e.Fragment,{children:[e.jsx(xs,{columns:ct,data:C,layout:"fixed",...os(le.layout),keyFn:s=>s.id,onRowClick:s=>t(`/escalations/detail/${s.id}`,{state:{from:"/escalations/available"}}),isLoading:Ge,emptyMessage:q?"Unable to load data":"No escalations"}),e.jsx(hs,{page:l.page,totalPages:l.totalPages(w),onPageChange:l.setPage,total:w,pageSize:l.pageSize,onPageSizeChange:l.setPageSize})]}),e.jsx(As,{claimTarget:b,onClose:()=>f(null),claimDuration:r,onDurationChange:s=>{k(s),E(0)},claimDurations:p,customClaimMinutes:P,onCustomClaimChange:T,onClaim:et,isPending:ge.isPending}),e.jsx(Ts,{open:Me,onClose:()=>Y(!1),selectedCount:y.size,onSubmit:at,isPending:ae.isPending}),e.jsx(ss,{open:Fe,onClose:()=>X(!1),selectedCount:y.size,selectedRoles:Xe,claimedCount:Je,onSubmit:nt,isPending:se.isPending}),e.jsx(as,{open:ze,onClose:()=>J(!1),onConfirm:lt,selectedCount:y.size,isPending:V.isPending,error:V.error,actionLabel:typeof re=="string"?re:void 0})]})}export{ia as AvailableEscalationsPage};
2
- //# sourceMappingURL=AvailableEscalationsPage-CpbC8oTN.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"AvailableEscalationsPage-CpbC8oTN.js","sources":["../../src/hooks/useResolveLinkVarUrl.ts","../../src/pages/operator/FacetedFilterPanel.tsx","../../src/pages/operator/FacetQueryPanel.tsx","../../src/components/common/modal/BulkActionBar.tsx","../../src/components/common/modal/BulkTriageModal.tsx","../../src/pages/operator/helpers.ts","../../src/pages/operator/ClaimModal.tsx","../../src/pages/operator/AvailableEscalationsPage.tsx"],"sourcesContent":["import { useEffect } from 'react';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport { extractLinkVarNames } from '../lib/link-vars';\nimport { useLinkVariables } from './useLinkVariables';\n\n/**\n * Guard for direct navigation carrying a raw `{lt:name}` placeholder (a\n * shared link, an old bookmark). Substitutes against this device's bindings\n * (or drops the facet) and rewrites the address bar with `replace` — the URL\n * never stays templated, and an unset variable simply widens the query.\n */\nexport function useResolveLinkVarUrl(): void {\n const { pathname, search } = useLocation();\n const navigate = useNavigate();\n const { resolveUrl } = useLinkVariables();\n\n useEffect(() => {\n const url = pathname + search;\n if (extractLinkVarNames(url).length === 0) return;\n const resolved = resolveUrl(url);\n if (resolved !== url) navigate(resolved, { replace: true });\n }, [pathname, search, resolveUrl, navigate]);\n}\n","import type { FacetFilters, FacetRange, FacetOrder } from '../../api/escalations';\n\nconst RANGE_OPS: FacetRange['op'][] = ['<', '<=', '>', '>=', '='];\nconst SORT_COLUMNS = ['priority', 'created_at', 'updated_at', 'status', 'role'];\n\n// Compact variants of the core field classes — the panel never invents its own\n// input styling; it dials the shared .input / .select down a size.\nconst inputCls = 'input text-xs py-1';\nconst selectCls = 'select text-xs py-1';\nconst xBtn = 'text-text-tertiary hover:text-text-primary transition-colors';\n\n/** A facet value is JSONB-containment-sensitive: 0.65 (number) ≠ \"0.65\" (string). */\nfunction coerce(v: string): unknown {\n if (v === 'true') return true;\n if (v === 'false') return false;\n if (v.trim() !== '' && !Number.isNaN(Number(v))) return Number(v);\n return v;\n}\n\ntype KV = { key: string; value: string };\nconst recordRows = (rec?: Record<string, unknown>): KV[] =>\n Object.entries(rec ?? {}).map(([key, value]) => ({ key, value: String(value) }));\nconst blockRows = (arr?: Record<string, unknown>[]): KV[] =>\n (arr ?? []).map((o) => {\n const [key, value] = Object.entries(o)[0] ?? ['', ''];\n return { key, value: String(value) };\n });\n\nfunction Section({ title, hint, children }: { title: string; hint?: string; children: React.ReactNode }) {\n return (\n <div className=\"border-t border-surface-border/50 py-3 first:border-t-0 first:pt-1\">\n <div className=\"mb-1.5 flex items-baseline justify-between\">\n <span className=\"text-2xs font-medium uppercase tracking-wide text-text-tertiary\">{title}</span>\n {hint && <span className=\"text-2xs font-mono text-text-tertiary/70\">{hint}</span>}\n </div>\n {children}\n </div>\n );\n}\n\nfunction KeyInput({ value, onChange, placeholder }: {\n value: string; onChange: (v: string) => void; placeholder: string;\n}) {\n return (\n <input\n list=\"lt-facet-keys\" className={`${inputCls} w-40`} placeholder={placeholder}\n value={value} onChange={(e) => onChange(e.target.value)}\n />\n );\n}\n\n/**\n * Faceted query editor — the advanced operations surface (rendered inside the\n * slide-out drawer). Controlled: edits a FacetFilters value. `facetKeys` are the\n * metadata keys that actually exist in the caller's rows (from listFacetKeys), so\n * the UI never offers a non-existent facet.\n */\nexport function FacetedFilterPanel({ value, onChange, facetKeys = [], search = '', onSearchChange }: {\n value: FacetFilters;\n onChange: (next: FacetFilters) => void;\n facetKeys?: string[];\n /** Correlation-id term — exact match on escalation id / workflow id / origin id, composed\n * with the facets in the same SQL query. Not a substring search; for values inside metadata\n * use a facet. */\n search?: string;\n onSearchChange?: (next: string) => void;\n}) {\n const facets = recordRows(value.facets);\n const exclude = blockRows(value.block);\n const ranges = value.range ?? [];\n const exists = value.exists ?? [];\n const sorts = value.orderBy ?? [];\n\n const setFacets = (rows: KV[]) => {\n const rec: Record<string, unknown> = {};\n for (const r of rows) if (r.key) rec[r.key] = coerce(r.value);\n onChange({ ...value, facets: Object.keys(rec).length ? rec : undefined });\n };\n const setBlock = (rows: KV[]) => {\n const arr = rows.filter((r) => r.key).map((r) => ({ [r.key]: coerce(r.value) }));\n onChange({ ...value, block: arr.length ? arr : undefined });\n };\n const setRange = (r: FacetRange[]) => onChange({ ...value, range: r.length ? r : undefined });\n const setExists = (e: string[]) => onChange({ ...value, exists: e.length ? e : undefined });\n const setSorts = (o: FacetOrder[]) => onChange({ ...value, orderBy: o.length ? o : undefined });\n\n return (\n <div className=\"text-xs\">\n {/* Autocomplete sources rendered once (shared by all rows). */}\n <datalist id=\"lt-facet-keys\">\n {facetKeys.map((k) => <option key={k} value={k} />)}\n </datalist>\n <datalist id=\"lt-sort-fields\">\n {SORT_COLUMNS.map((c) => <option key={c} value={c} />)}\n {facetKeys.map((k) => <option key={k} value={`metadata.${k}`} />)}\n </datalist>\n\n {onSearchChange && (\n <Section title=\"Match id\" hint=\"id · workflow · origin\">\n <input\n className={`${inputCls} w-full`}\n placeholder=\"Exact escalation, workflow, or origin id…\"\n value={search}\n onChange={(e) => onSearchChange(e.target.value)}\n />\n </Section>\n )}\n\n <Section title=\"Has facet\" hint=\"metadata @>\">\n {[...facets, { key: '', value: '' }].map((row, i) => (\n <div key={i} className=\"mb-1 flex items-center gap-1\">\n <KeyInput value={row.key} placeholder=\"key\"\n onChange={(k) => { const next = [...facets]; next[i] = { ...row, key: k }; setFacets(next); }} />\n <span className=\"text-text-tertiary\">=</span>\n <input className={`${inputCls} w-40`} placeholder=\"value\" value={row.value}\n onChange={(e) => { const next = [...facets]; next[i] = { ...row, value: e.target.value }; setFacets(next); }} />\n {i < facets.length && (\n <button className={xBtn} onClick={() => setFacets(facets.filter((_, j) => j !== i))}>×</button>\n )}\n </div>\n ))}\n </Section>\n\n <Section title=\"Range\" hint=\"numeric\">\n {[...ranges, { facet: '', op: '<=' as const, value: 0 }].map((r, i) => (\n <div key={i} className=\"mb-1 flex items-center gap-1\">\n <KeyInput value={r.facet} placeholder=\"numeric facet\"\n onChange={(f) => { const next = [...ranges]; next[i] = { ...r, facet: f }; setRange(next.filter((x) => x.facet)); }} />\n <select className={selectCls} value={r.op}\n onChange={(e) => { const next = [...ranges]; next[i] = { ...r, op: e.target.value as FacetRange['op'] }; setRange(next.filter((x) => x.facet)); }}>\n {RANGE_OPS.map((o) => <option key={o} value={o}>{o}</option>)}\n </select>\n <input type=\"number\" className={`${inputCls} w-24`} value={r.value}\n onChange={(e) => { const next = [...ranges]; next[i] = { ...r, value: Number(e.target.value) }; setRange(next.filter((x) => x.facet)); }} />\n {i < ranges.length && (\n <button className={xBtn} onClick={() => setRange(ranges.filter((_, j) => j !== i))}>×</button>\n )}\n </div>\n ))}\n </Section>\n\n <Section title=\"Has key\" hint=\"metadata ? key\">\n <div className=\"flex flex-wrap items-center gap-1\">\n {exists.map((k) => (\n <span key={k} className=\"flex items-center gap-1 rounded bg-accent/15 px-1.5 py-0.5 text-accent\">\n {k}<button className=\"text-accent/70 hover:text-accent\" onClick={() => setExists(exists.filter((x) => x !== k))}>×</button>\n </span>\n ))}\n <KeyInput value=\"\" placeholder=\"+ key\"\n onChange={(k) => { if (k && !exists.includes(k)) setExists([...exists, k]); }} />\n </div>\n </Section>\n\n <Section title=\"Exclude\" hint=\"NOT @>\">\n {[...exclude, { key: '', value: '' }].map((row, i) => (\n <div key={i} className=\"mb-1 flex items-center gap-1\">\n <KeyInput value={row.key} placeholder=\"key\"\n onChange={(k) => { const next = [...exclude]; next[i] = { ...row, key: k }; setBlock(next); }} />\n <span className=\"text-text-tertiary\">=</span>\n <input className={`${inputCls} w-40`} placeholder=\"value\" value={row.value}\n onChange={(e) => { const next = [...exclude]; next[i] = { ...row, value: e.target.value }; setBlock(next); }} />\n {i < exclude.length && (\n <button className={xBtn} onClick={() => setBlock(exclude.filter((_, j) => j !== i))}>×</button>\n )}\n </div>\n ))}\n </Section>\n\n <Section title=\"Sort by\">\n {[...sorts, { field: '', direction: 'asc' as const }].map((s, i) => (\n <div key={i} className=\"mb-1 flex items-center gap-1\">\n <input list=\"lt-sort-fields\" className={`${inputCls} w-44`} placeholder=\"column or metadata.key\"\n value={s.field}\n onChange={(e) => { const next = [...sorts]; next[i] = { ...s, field: e.target.value }; setSorts(next.filter((x) => x.field)); }} />\n <select className={selectCls} value={s.direction ?? 'asc'}\n onChange={(e) => { const next = [...sorts]; next[i] = { ...s, direction: e.target.value as 'asc' | 'desc' }; setSorts(next.filter((x) => x.field)); }}>\n <option value=\"asc\">asc</option><option value=\"desc\">desc</option>\n </select>\n <label className=\"flex items-center gap-1 text-text-tertiary\">\n <input type=\"checkbox\" checked={!!s.numeric}\n onChange={(e) => { const next = [...sorts]; next[i] = { ...s, numeric: e.target.checked }; setSorts(next.filter((x) => x.field)); }} />\n num\n </label>\n {i < sorts.length && (\n <button className={xBtn} onClick={() => setSorts(sorts.filter((_, j) => j !== i))}>×</button>\n )}\n </div>\n ))}\n </Section>\n </div>\n );\n}\n","import { X } from 'lucide-react';\nimport { FacetedFilterPanel } from './FacetedFilterPanel';\nimport type { FacetFilters } from '../../api/escalations';\n\n/**\n * Faceted metadata query — the body of the shell's global right panel on the\n * escalations master list. Precise metadata facets plus exact correlation-id\n * lookup, composed into one SQL query.\n */\nexport function FacetQueryPanel({\n value,\n onChange,\n facetKeys,\n search,\n onSearchChange,\n activeFacetCount,\n onClear,\n onClose,\n}: {\n value: FacetFilters;\n onChange: (v: FacetFilters) => void;\n facetKeys: string[];\n search: string;\n onSearchChange: (v: string) => void;\n activeFacetCount: number;\n onClear: () => void;\n onClose: () => void;\n}) {\n return (\n <div className=\"h-full overflow-y-auto\">\n <div className=\"sticky top-0 z-10 flex items-center justify-between px-4 py-3 bg-surface-raised border-b border-surface-border/50\">\n <span className=\"text-xs font-semibold text-text-primary\">Faceted query</span>\n <div className=\"flex items-center gap-2\">\n {activeFacetCount > 0 && (\n <button\n onClick={onClear}\n className=\"text-2xs text-text-tertiary hover:text-text-primary transition-colors\"\n >\n Clear\n </button>\n )}\n <button\n onClick={onClose}\n className=\"p-1 rounded hover:bg-surface-hover text-text-tertiary hover:text-text-primary transition-colors\"\n title=\"Close\"\n >\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n <div className=\"px-4 py-2\">\n <p className=\"mb-2 text-2xs leading-snug text-text-tertiary\">\n Precise metadata facets plus exact correlation-id lookup — they compose in one\n SQL query. Facet keys are the ones that actually exist in your visible escalations.\n Set status to <span className=\"font-medium\">All</span> to find an order across every\n status; the whole query is shareable via the URL.\n </p>\n <FacetedFilterPanel\n value={value}\n onChange={onChange}\n facetKeys={facetKeys}\n search={search}\n onSearchChange={onSearchChange}\n />\n </div>\n </div>\n );\n}\n","import { PRIORITY_OPTIONS } from '../../../lib/constants';\nimport { useClaimDurations } from '../../../hooks/useClaimDurations';\nimport { useSettings } from '../../../api/settings';\nimport { getAiOverride } from '../../../lib/view-as';\n\ninterface BulkActionBarProps {\n selectedCount: number;\n onClearSelection: () => void;\n onSetPriority: (priority: 1 | 2 | 3 | 4) => void;\n onClaim: (durationMinutes: number) => void;\n onAssign: () => void;\n onUnassign: () => void;\n onTriage: () => void;\n onCancel: () => void;\n /** The scoped role's x-lt-labels.cancel — renames the button; false hides it. */\n cancelLabel?: string | false;\n isPriorityPending: boolean;\n isClaimPending: boolean;\n isAssignPending: boolean;\n isUnassignPending: boolean;\n isTriagePending: boolean;\n isCancelPending: boolean;\n}\n\nconst anyPending = (props: BulkActionBarProps) =>\n props.isPriorityPending || props.isClaimPending || props.isAssignPending || props.isUnassignPending || props.isTriagePending || props.isCancelPending;\n\n// One control chrome for the whole bar — white pill-free buttons on the band,\n// hairline border, a barely-there 3px radius (square reads timeless, not dated),\n// definition on hover. Selects share it so the toolbar is one cohesive set.\nconst CTRL =\n 'inline-flex items-center h-7 px-2.5 text-2xs font-medium text-text-secondary bg-surface border border-surface-border rounded-[4px] hover:border-accent/50 hover:text-text-primary transition-colors disabled:opacity-50 disabled:hover:border-surface-border';\nconst SELECT = `${CTRL} appearance-none cursor-pointer`;\nconst DANGER =\n 'inline-flex items-center h-7 px-2.5 text-2xs font-medium text-status-error bg-surface border border-status-error/30 rounded-[4px] hover:border-status-error hover:bg-status-error/5 transition-colors disabled:opacity-50';\n\nexport function BulkActionBar(props: BulkActionBarProps) {\n const disabled = anyPending(props);\n const claimDurations = useClaimDurations();\n // Triage is an LLM action. `useSettings().ai.enabled` is the single source of\n // truth — it merges the server /settings flag with the persisted localStorage\n // override (lt_ai_override). Hide the button entirely when AI is off.\n const { data: settings } = useSettings();\n const aiOverride = getAiOverride();\n const aiEnabled = aiOverride !== null ? aiOverride : settings?.ai?.enabled === true;\n const open = props.selectedCount > 0;\n\n return (\n // Animated reveal — grows and opacity-fades in/out with ease-in-out as the\n // selection changes. Always mounted so it can animate on exit, not just enter.\n <div\n className={`grid transition-all duration-200 ease-in-out ${\n open ? 'grid-rows-[1fr] opacity-100' : 'grid-rows-[0fr] opacity-0 pointer-events-none'\n }`}\n >\n <div className=\"overflow-hidden\">\n {/* Contextual band: neutral fill + a 2px accent left rule anchors it as a\n distinct \"selection mode\" surface without a rounded card. */}\n <div className=\"flex flex-wrap items-center gap-2 py-2.5 pl-3 pr-2 mt-4 mb-3 bg-surface-sunken/60 border-l-2 border-l-accent\">\n <span className=\"text-2xs font-semibold uppercase tracking-wider text-accent tabular-nums\">\n {props.selectedCount} selected\n </span>\n\n <div className=\"mx-1 h-4 w-px bg-surface-border\" />\n\n {/* Priority */}\n <select\n onChange={(e) => {\n if (!e.target.value) return;\n props.onSetPriority(parseInt(e.target.value) as 1 | 2 | 3 | 4);\n e.target.value = '';\n }}\n disabled={disabled}\n className={SELECT}\n defaultValue=\"\"\n >\n <option value=\"\" disabled>Priority…</option>\n {PRIORITY_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>{opt.label}</option>\n ))}\n </select>\n\n {/* Claim */}\n <select\n onChange={(e) => {\n if (!e.target.value) return;\n props.onClaim(parseInt(e.target.value));\n e.target.value = '';\n }}\n disabled={disabled}\n className={SELECT}\n defaultValue=\"\"\n >\n <option value=\"\" disabled>Claim for…</option>\n {claimDurations.map((opt) => (\n <option key={opt.value} value={opt.value}>{opt.label}</option>\n ))}\n </select>\n\n {/* Assign */}\n <button onClick={props.onAssign} disabled={disabled} className={CTRL}>\n {props.isAssignPending ? 'Assigning…' : 'Assign to…'}\n </button>\n\n {/* Unassign — return claimed selections to the pool */}\n <button onClick={props.onUnassign} disabled={disabled} className={CTRL}>\n {props.isUnassignPending ? 'Unassigning…' : 'Unassign'}\n </button>\n\n {/* Triage — LLM-powered, shown only when AI is enabled */}\n {aiEnabled && (\n <button onClick={props.onTriage} disabled={disabled} className={CTRL}>\n {props.isTriagePending ? 'Triaging…' : 'Triage'}\n </button>\n )}\n\n {/* Cancel — speaks the scoped role's vocabulary when one is authored */}\n {props.cancelLabel !== false && (\n <button onClick={props.onCancel} disabled={disabled} className={DANGER}>\n {props.isCancelPending\n ? (props.cancelLabel ? `${props.cancelLabel}…` : 'Cancelling…')\n : (props.cancelLabel || 'Cancel')}\n </button>\n )}\n\n <div className=\"flex-1\" />\n\n {disabled && (\n <span className=\"text-2xs text-text-tertiary animate-pulse\">Processing…</span>\n )}\n\n {/* Clear */}\n <button\n onClick={props.onClearSelection}\n className=\"px-1 text-2xs font-medium text-text-tertiary hover:text-text-primary transition-colors\"\n >\n Clear\n </button>\n </div>\n </div>\n </div>\n );\n}\n","import { useState } from 'react';\nimport { Modal } from './Modal';\n\ninterface BulkTriageModalProps {\n open: boolean;\n onClose: () => void;\n selectedCount: number;\n onSubmit: (hint?: string) => void;\n isPending: boolean;\n}\n\nexport function BulkTriageModal({\n open,\n onClose,\n selectedCount,\n onSubmit,\n isPending,\n}: BulkTriageModalProps) {\n const [hint, setHint] = useState('');\n\n const handleSubmit = () => {\n onSubmit(hint || undefined);\n };\n\n return (\n <Modal open={open} onClose={onClose} title=\"Submit for AI Triage\">\n <div className=\"space-y-4\">\n <p className=\"text-sm text-text-secondary\">\n Submit <span className=\"font-medium text-text-primary\">{selectedCount}</span> escalation(s)\n for AI triage? The triage orchestrator will take over resolution.\n </p>\n\n <div>\n <label className=\"text-xs font-medium text-text-secondary block mb-1\">\n Triage hint <span className=\"text-text-tertiary\">(optional)</span>\n </label>\n <input\n type=\"text\"\n value={hint}\n onChange={(e) => setHint(e.target.value)}\n placeholder=\"e.g., image_orientation\"\n className=\"input text-xs font-mono w-full\"\n />\n <p className=\"text-2xs text-text-tertiary mt-1\">\n Guides the triage workflow on what remediation to apply\n </p>\n </div>\n\n <div className=\"flex justify-end gap-3 pt-2\">\n <button onClick={onClose} className=\"btn-secondary text-xs\">\n Cancel\n </button>\n <button\n onClick={handleSubmit}\n disabled={isPending}\n className=\"btn-primary text-xs\"\n >\n {isPending ? 'Submitting...' : 'Submit for Triage'}\n </button>\n </div>\n </div>\n </Modal>\n );\n}\n","import type { UseMutationResult } from '@tanstack/react-query';\n\n/**\n * Create a bulk-action handler that calls a mutation and clears selection on success.\n */\nfunction bulkHandler<TData, TVariables>(\n mutation: UseMutationResult<TData, Error, TVariables>,\n clearSelection: () => void,\n afterSuccess?: () => void,\n) {\n return (variables: TVariables) => {\n mutation.mutate(variables, {\n onSuccess: () => {\n clearSelection();\n afterSuccess?.();\n },\n });\n };\n}\n\nexport function createBulkHandlers(deps: {\n selectedIds: Set<string>;\n clearSelection: () => void;\n setPriority: UseMutationResult<{ updated: number }, Error, { ids: string[]; priority: 1 | 2 | 3 | 4 }>;\n bulkClaim: UseMutationResult<{ claimed: number; skipped: number }, Error, { ids: string[]; durationMinutes: number }>;\n bulkTriage: UseMutationResult<{ triaged: number }, Error, { ids: string[]; hint?: string }>;\n bulkAssign: UseMutationResult<{ assigned: number; skipped: number }, Error, { ids: string[]; targetUserId: string; durationMinutes: number; reassign?: boolean }>;\n bulkUnassign: UseMutationResult<{ unassigned: number; skipped: number }, Error, { ids: string[] }>;\n bulkCancel: UseMutationResult<{ cancelled: number; skipped: number }, Error, { ids: string[] }>;\n closeTriageModal: () => void;\n closeAssignModal: () => void;\n closeCancelModal: () => void;\n}) {\n const ids = () => [...deps.selectedIds];\n\n const handleSetPriority = (priority: 1 | 2 | 3 | 4) => {\n bulkHandler(\n deps.setPriority,\n deps.clearSelection,\n )({ ids: ids(), priority });\n };\n\n const handleBulkClaim = (durationMinutes: number) => {\n bulkHandler(\n deps.bulkClaim,\n deps.clearSelection,\n )({ ids: ids(), durationMinutes });\n };\n\n const handleBulkTriage = (hint?: string) => {\n bulkHandler(\n deps.bulkTriage,\n deps.clearSelection,\n deps.closeTriageModal,\n )({ ids: ids(), hint });\n };\n\n const handleBulkAssign = (targetUserId: string, durationMinutes: number, reassign?: boolean) => {\n bulkHandler(\n deps.bulkAssign,\n deps.clearSelection,\n deps.closeAssignModal,\n )({ ids: ids(), targetUserId, durationMinutes, reassign });\n };\n\n const handleBulkUnassign = () => {\n bulkHandler(\n deps.bulkUnassign,\n deps.clearSelection,\n )({ ids: ids() });\n };\n\n const handleBulkCancel = () => {\n bulkHandler(\n deps.bulkCancel,\n deps.clearSelection,\n deps.closeCancelModal,\n )({ ids: ids() });\n };\n\n return { handleSetPriority, handleBulkClaim, handleBulkTriage, handleBulkAssign, handleBulkUnassign, handleBulkCancel };\n}\n","import { Modal } from '../../components/common/modal/Modal';\nimport { CustomDurationPicker } from '../../components/common/form/CustomDurationPicker';\nimport type { LTEscalationRecord } from '../../api/types';\n\ninterface ClaimModalProps {\n claimTarget: LTEscalationRecord | null;\n onClose: () => void;\n claimDuration: string;\n onDurationChange: (value: string) => void;\n claimDurations: Array<{ value: string; label: string }>;\n customClaimMinutes: number;\n onCustomClaimChange: (minutes: number) => void;\n onClaim: () => void;\n isPending: boolean;\n}\n\nexport function ClaimModal({\n claimTarget,\n onClose,\n claimDuration,\n onDurationChange,\n claimDurations,\n onCustomClaimChange,\n onClaim,\n isPending,\n}: ClaimModalProps) {\n return (\n <Modal\n open={!!claimTarget}\n onClose={onClose}\n title=\"Claim Escalation\"\n >\n <div className=\"space-y-4\">\n <p className=\"text-sm text-text-secondary\">\n Claim <span className=\"font-medium text-text-primary\">{claimTarget?.type}</span> for:\n </p>\n <select\n value={claimDuration}\n onChange={(e) => { onDurationChange(e.target.value); }}\n className=\"select w-full text-sm\"\n >\n {claimDurations.map((opt) => (\n <option key={opt.value} value={opt.value}>{opt.label}</option>\n ))}\n <option value=\"custom\">Other...</option>\n </select>\n {claimDuration === 'custom' && (\n <CustomDurationPicker onChange={onCustomClaimChange} autoFocus />\n )}\n <div className=\"flex justify-end gap-3 pt-2\">\n <button onClick={onClose} className=\"btn-secondary text-xs\">\n Cancel\n </button>\n <button\n onClick={onClaim}\n className=\"btn-primary text-xs\"\n disabled={isPending}\n >\n {isPending ? 'Claiming...' : 'Claim'}\n </button>\n </div>\n </div>\n </Modal>\n );\n}\n","import { useState, useEffect, useMemo, useCallback, useRef } from 'react';\nimport { useNavigate, useSearchParams, useLocation } from 'react-router-dom';\nimport { parseFacetParams, writeFacetParams, facetCount } from '../../lib/facet-url';\nimport { useResolveLinkVarUrl } from '../../hooks/useResolveLinkVarUrl';\nimport { useAccess } from '../../hooks/useAccess';\nimport { useAuth } from '../../hooks/useAuth';\nimport { useKioskMode } from '../../hooks/useKioskMode';\nimport { isSystemTierRole } from '../../lib/task-queues';\nimport { useEscalationListEvents } from '../../hooks/useEventHooks';\nimport {\n useEscalationTypes,\n useFacetKeys,\n useClaimEscalation,\n useSetEscalationPriority,\n useBulkClaimEscalations,\n useBulkAssignEscalations,\n useBulkUnassignEscalations,\n useBulkTriageEscalations,\n useBulkCancelEscalations,\n type FacetFilters,\n type FacetOrder,\n} from '../../api/escalations';\nimport { FacetQueryPanel } from './FacetQueryPanel';\nimport { useShellPanel } from '../../hooks/useShellPanel';\nimport { ConfirmCancelModal } from '../../components/common/modal/ConfirmCancelModal';\nimport { readFooterLabels } from '../../lib/x-lt-labels';\nimport { useRoles, useRoleDetails, useRoleSchema } from '../../api/roles';\nimport { displayRoleTitle } from '../../lib/role-display';\nimport { EscalationTitleSelect } from './EscalationTitleSelect';\nimport { EscalationSortControl } from './EscalationSortControl';\nimport { EscalationListView } from '../../components/escalation/EscalationListView';\nimport { useFilterParams } from '../../hooks/useFilterParams';\nimport { useEscalationListQuery } from '../../hooks/useEscalationListQuery';\nimport { LIST_VIEWS, isListView, isListLayout, resolveListView, type EscalationListParams } from '../../lib/escalation-list-url';\nimport { tableLayoutProps } from '../../components/escalation/EscalationTableView';\nimport { useDebouncedValue } from '../../hooks/useDebouncedValue';\nimport { DataTable, type Column } from '../../components/common/data/DataTable';\nimport { StickyPagination } from '../../components/common/data/StickyPagination';\nimport { BulkActionBar } from '../../components/common/modal/BulkActionBar';\nimport { BulkAssignModal } from '../../components/common/modal/BulkAssignModal';\nimport { BulkTriageModal } from '../../components/common/modal/BulkTriageModal';\nimport { useClaimDurations } from '../../hooks/useClaimDurations';\nimport { Activity, Lock, SlidersHorizontal, X, LayoutList, Table, BookOpen, TriangleAlert, Pin, RefreshCw } from 'lucide-react';\nimport { usePatchPreferences, usePreferences } from '../../api/preferences';\nimport { newPinId } from '../../lib/pinned-views';\nimport { formatDurationCompact } from '../../lib/format';\nimport { makeEscalationColumns, EscalationFilterBar } from './escalation-columns';\nimport { RowAction, RowActionGroup } from '../../components/common/layout/RowActions';\nimport { createBulkHandlers } from './helpers';\nimport { isEffectivelyClaimed } from '../../lib/escalation';\nimport { ClaimModal } from './ClaimModal';\nimport { EscalationTimeline } from '../../components/escalation/EscalationTimeline';\nimport type { LTEscalationRecord } from '../../api/types';\n\nexport function AvailableEscalationsPage() {\n // Shared/bookmarked URLs may still carry raw {lt:name} placeholders —\n // resolve them against this device before the facets reach any query.\n useResolveLinkVarUrl();\n const navigate = useNavigate();\n const { filters, setFilter, pagination } = useFilterParams({\n filters: { role: '', type: '', priority: '', status: 'available', search: '' },\n });\n // The queue moves on arrivals and departures-into-work — created and\n // claimed. A role filter narrows the subscription to that queue's subject\n // token. Manual refresh covers the long tail of other lifecycle moments.\n useEscalationListEvents({ role: filters.role || null, verbs: ['created', 'claimed'] });\n // Debounce so server-side search fires once the user pauses, not per keystroke.\n const debouncedSearch = useDebouncedValue(filters.search);\n const claimDurations = useClaimDurations();\n const [claimTarget, setClaimTarget] = useState<LTEscalationRecord | null>(null);\n const [claimDuration, setClaimDuration] = useState('30');\n const [customClaimMinutes, setCustomClaimMinutes] = useState(0);\n const onCustomClaimChange = useCallback((m: number) => setCustomClaimMinutes(m), []);\n const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());\n // The pinned control band's height varies (selection bar, facet pills), so\n // its measured height feeds --lt-sticky-top for the table headers below.\n const rootRef = useRef<HTMLDivElement>(null);\n const bandObserver = useRef<ResizeObserver | null>(null);\n const bandRef = useCallback((el: HTMLDivElement | null) => {\n bandObserver.current?.disconnect();\n bandObserver.current = null;\n if (!el || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => {\n // 1px under the opaque band so fractional heights never leave a seam.\n rootRef.current?.style.setProperty('--lt-sticky-top', `${el.offsetHeight - 1}px`);\n });\n observer.observe(el);\n bandObserver.current = observer;\n }, []);\n // Faceted query — DEEP-LINKED in the URL (a shared link reproduces the exact query).\n // The drawer is the editor surface; fetched keys feed the autocomplete.\n const [facetDrawerOpen, setFacetDrawerOpen] = useState(false);\n const [searchParams, setSearchParams] = useSearchParams();\n const facetFilters = useMemo<FacetFilters>(() => parseFacetParams(searchParams), [searchParams]);\n const setFacetFilters = useCallback((next: FacetFilters) => {\n setSearchParams((prev) => {\n const p = new URLSearchParams(prev);\n writeFacetParams(p, next);\n p.delete('page');\n return p;\n });\n }, [setSearchParams]);\n const { data: facetKeysData } = useFacetKeys(facetDrawerOpen);\n // The free-text term now lives in the drawer alongside the facets, so it counts\n // toward the active-query badge and is cleared by the drawer's Clear.\n const activeFacetCount = facetCount(facetFilters) + (filters.search ? 1 : 0);\n\n // Faceted query editor rides the shell's global right panel. Re-invoked on\n // every dependency change so the panel content always reflects live state.\n // The slot is shared (the folded FilterBar claims it too), so every call is\n // keyed: claiming is intentional, closing only closes our own content.\n const FACET_PANEL_KEY = 'facet-query';\n const { setPanel, closePanel, open: panelOpen, ownerKey } = useShellPanel();\n useEffect(() => {\n if (!facetDrawerOpen) {\n closePanel(FACET_PANEL_KEY);\n return;\n }\n setPanel(\n <FacetQueryPanel\n value={facetFilters}\n onChange={setFacetFilters}\n facetKeys={facetKeysData?.keys ?? []}\n search={filters.search ?? ''}\n onSearchChange={(v) => setFilter('search', v)}\n activeFacetCount={activeFacetCount}\n onClear={() => { setFacetFilters({}); setFilter('search', ''); }}\n onClose={() => setFacetDrawerOpen(false)}\n />,\n { width: 420, key: FACET_PANEL_KEY },\n );\n }, [facetDrawerOpen, facetFilters, setFacetFilters, facetKeysData, filters.search, setFilter, activeFacetCount, setPanel, closePanel]);\n\n // Stand down when another claimant takes the slot — drop the drawer flag so\n // the live-update effect above doesn't reclaim on its next dependency change.\n const ownsFacetPanel = panelOpen && ownerKey === FACET_PANEL_KEY;\n const ownedFacetRef = useRef(false);\n useEffect(() => {\n if (ownsFacetPanel) {\n ownedFacetRef.current = true;\n return;\n }\n if (ownedFacetRef.current) {\n ownedFacetRef.current = false;\n setFacetDrawerOpen(false);\n }\n }, [ownsFacetPanel]);\n const [triageModalOpen, setTriageModalOpen] = useState(false);\n const [assignModalOpen, setAssignModalOpen] = useState(false);\n const [cancelModalOpen, setCancelModalOpen] = useState(false);\n\n // One sort model for every view: orderBy is deep-linked in the URL and routes\n // the request through the robust faceted path (hasFacetQuery is true whenever\n // orderBy is set). Default is created_at desc when no orderBy is present.\n const setOrderBy = useCallback(\n (next: FacetOrder[] | undefined) => setFacetFilters({ ...facetFilters, orderBy: next }),\n [facetFilters, setFacetFilters],\n );\n\n // Pin current view: capture the live URL (every filter — role, status,\n // facets, orderBy, view, jeopardy — is already deep-linked) as a pinned\n // view, prompting only for the label. Badged by default: a pinned query's\n // live count is its value.\n const location = useLocation();\n const { data: prefsData } = usePreferences();\n const patchPrefs = usePatchPreferences();\n const pinCurrentView = useCallback(() => {\n const label = window.prompt('Pin label:');\n if (!label?.trim()) return;\n const existing = prefsData?.preferences?.pinnedViews ?? [];\n patchPrefs.mutate({\n pinnedViews: [\n ...existing,\n { id: newPinId(), label: label.trim(), url: location.pathname + location.search, badge: true },\n ],\n });\n }, [location.pathname, location.search, prefsData, patchPrefs]);\n\n const { canBulk: canBulkManage } = useAccess();\n // Kiosk sessions ARE their role: the title is a plain heading and the role\n // filter disappears — there is no other queue to switch to.\n const { kiosk } = useKioskMode();\n const facetHighlightKeys = facetFilters.facets ? Object.keys(facetFilters.facets) : [];\n\n // View mode is DEEP-LINKED (?view=table|timeline|rich) and tied to the\n // filter-bar view radio — a shared link reproduces the exact presentation.\n // Each radio choice writes ?view= explicitly. Absent an explicit view the\n // role's rich list view shows when one exists, else the table: the dense,\n // scannable, countable presentation.\n const viewParam = searchParams.get('view');\n const layoutParam = searchParams.get('layout');\n const setViewParam = useCallback((v: 'table' | 'timeline' | 'rich' | null) => {\n setSearchParams((prev) => {\n const p = new URLSearchParams(prev);\n if (v) p.set('view', v); else p.delete('view');\n return p;\n }, { replace: true });\n }, [setSearchParams]);\n const showTimeline = viewParam === 'timeline';\n\n // Remove a single facet key from the active query.\n const removeFacet = useCallback((key: string) => {\n const { [key]: _removed, ...rest } = facetFilters.facets ?? {};\n setFacetFilters({ ...facetFilters, facets: Object.keys(rest).length > 0 ? rest : undefined });\n }, [facetFilters, setFacetFilters]);\n\n const claim = useClaimEscalation();\n const setPriority = useSetEscalationPriority();\n const bulkClaim = useBulkClaimEscalations();\n const bulkAssign = useBulkAssignEscalations();\n const bulkUnassign = useBulkUnassignEscalations();\n const bulkTriage = useBulkTriageEscalations();\n const bulkCancel = useBulkCancelEscalations();\n const { data: rolesData } = useRoles();\n const { data: roleDetails } = useRoleDetails();\n const { data: typesData } = useEscalationTypes();\n const { user, isSuperAdmin, hasRoleType } = useAuth();\n // Global viewers (superadmin / admin) can filter any queue; a scoped user sees\n // only the queues they belong to — the title menu never offers a role whose\n // escalations they can't read.\n const isGlobalViewer = isSuperAdmin || hasRoleType('admin');\n const memberRoleSet = useMemo(() => new Set((user?.roles ?? []).map((r) => r.role)), [user]);\n const roleOptions = useMemo(() => {\n const all = roleDetails?.roles ?? [];\n const visible = isGlobalViewer\n ? all\n : all.filter((r) => memberRoleSet.has(r.role) && !isSystemTierRole(r.role));\n return visible\n .map((r) => ({ value: r.role, label: displayRoleTitle(r) }))\n .sort((a, b) => a.label.localeCompare(b.label));\n }, [roleDetails, isGlobalViewer, memberRoleSet]);\n\n // Clear selections on filter/page changes\n useEffect(() => {\n setSelectedIds(new Set());\n }, [filters.role, filters.type, filters.priority, filters.status, debouncedSearch, pagination.page, pagination.pageSize]);\n\n // The list params in the shape the shared query takes; the same reader a\n // pinned view or a portal panel runs over a saved URL.\n const listParams = useMemo<EscalationListParams>(() => ({\n statusFilter: filters.status || '',\n role: filters.role || undefined,\n type: filters.type || undefined,\n priority: filters.priority ? parseInt(filters.priority) : undefined,\n search: debouncedSearch || undefined,\n facets: facetFilters,\n view: isListView(viewParam) ? viewParam : null,\n layout: isListLayout(layoutParam) ? layoutParam : null,\n }), [filters.status, filters.role, filters.type, filters.priority, debouncedSearch, facetFilters, viewParam, layoutParam]);\n\n // Timeline mode fetches 100 per page so the spine has enough story to tell.\n const timelinePageSize = 100;\n const {\n escalations, total, listSchema, singleRole, hasRichView,\n isLoading, isFetching, error: queryError, refetch,\n } = useEscalationListQuery(listParams, {\n limit: showTimeline ? timelinePageSize : pagination.pageSize,\n offset: pagination.offset,\n });\n // The queue's cancel vocabulary: when scoped to one role, the bulk Cancel\n // speaks the role form's x-lt-labels.cancel (false hides the verb).\n const roleSchemaQuery = useRoleSchema(singleRole ?? '', undefined, !!singleRole);\n const cancelLabel = singleRole\n ? readFooterLabels(roleSchemaQuery.data?.form_schema).cancel\n : undefined;\n const activeView = resolveListView(listParams.view, hasRichView);\n const useRichView = activeView === LIST_VIEWS.RICH;\n\n // The jeopardy pill names the role's limit so the red filter is self-explaining\n // (\"in jeopardy · > 15m\"): priority_threshold_minutes, falling back to SLA.\n const jeopardyThresholdLabel = useMemo(() => {\n if (!facetFilters.jeopardy || !singleRole) return null;\n const r = (roleDetails?.roles ?? []).find((x) => x.role === singleRole);\n const mins = r?.priority_threshold_minutes ?? r?.sla_minutes ?? null;\n return mins != null ? formatDurationCompact(mins * 60_000) : null;\n }, [facetFilters.jeopardy, singleRole, roleDetails]);\n\n const selectedRoles = useMemo(() => {\n const roles = new Set<string>();\n for (const esc of escalations) {\n if (selectedIds.has(esc.id)) roles.add(esc.role);\n }\n return [...roles];\n }, [escalations, selectedIds]);\n\n // Selected rows under a live claim — plain assign skips them; the modal\n // offers the explicit takeover when any are present.\n const selectedClaimedCount = useMemo(\n () => escalations.filter((esc) => selectedIds.has(esc.id) && isEffectivelyClaimed(esc)).length,\n [escalations, selectedIds],\n );\n\n const clearSelection = useCallback(() => setSelectedIds(new Set()), []);\n\n const handleClaim = () => {\n if (!claimTarget) return;\n const minutes = claimDuration === 'custom' ? customClaimMinutes : parseInt(claimDuration);\n if (!minutes || minutes <= 0) return;\n claim.mutate(\n { id: claimTarget.id, durationMinutes: minutes },\n {\n onSuccess: () => {\n setClaimTarget(null);\n navigate(`/escalations/detail/${claimTarget.id}`);\n },\n },\n );\n };\n\n const {\n handleSetPriority,\n handleBulkClaim,\n handleBulkTriage,\n handleBulkAssign,\n handleBulkUnassign,\n handleBulkCancel,\n } = createBulkHandlers({\n selectedIds,\n clearSelection,\n setPriority,\n bulkClaim,\n bulkTriage,\n bulkAssign,\n bulkUnassign,\n bulkCancel,\n closeTriageModal: () => setTriageModalOpen(false),\n closeAssignModal: () => setAssignModalOpen(false),\n closeCancelModal: () => setCancelModalOpen(false),\n });\n\n const toggleSelect = (id: string) => {\n const next = new Set(selectedIds);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n setSelectedIds(next);\n };\n\n const toggleAll = () => {\n if (selectedIds.size === escalations.length) {\n setSelectedIds(new Set());\n } else {\n setSelectedIds(new Set(escalations.map((e) => e.id)));\n }\n };\n\n const columns: Column<LTEscalationRecord>[] = [\n canBulkManage ? {\n key: 'select',\n label: (\n <input\n type=\"checkbox\"\n checked={escalations.length > 0 && selectedIds.size === escalations.length}\n onChange={toggleAll}\n className=\"rounded\"\n />\n ) as any,\n render: (row: LTEscalationRecord) => (\n <input\n type=\"checkbox\"\n checked={selectedIds.has(row.id)}\n onChange={(e) => {\n e.stopPropagation();\n toggleSelect(row.id);\n }}\n onClick={(e) => e.stopPropagation()}\n className=\"rounded\"\n />\n ),\n className: 'w-10',\n priority: 1,\n } : {\n key: 'spacer',\n label: '',\n render: () => null,\n className: 'w-10',\n priority: 3,\n },\n ...makeEscalationColumns({ highlightKeys: facetHighlightKeys }),\n {\n key: 'actions',\n label: '',\n render: (row) => (\n <RowActionGroup>\n <RowAction\n icon={Lock}\n title=\"Claim escalation\"\n onClick={() => setClaimTarget(row)}\n alwaysVisible\n colorClass=\"text-accent/40 hover:text-accent\"\n size=\"sm\"\n />\n </RowActionGroup>\n ),\n className: 'w-10 text-right',\n },\n ];\n\n return (\n <div ref={rootRef}>\n {/* The title IS the queue selector: it reads as the chosen role's title,\n or \"All Escalations\". The role filter therefore leaves the bar. */}\n <div className=\"flex items-center gap-2 mb-10 min-w-0\">\n <EscalationTitleSelect role={filters.role} options={roleOptions} onChange={(v) => setFilter('role', v)} locked={kiosk} />\n {!kiosk && (\n <button\n onClick={() => { window.location.hash = '#docs:dashboard.md:all-escalations'; }}\n className=\"text-text-quaternary hover:text-accent transition-colors mt-1 shrink-0\"\n title=\"Open docs for this page\"\n >\n <BookOpen className=\"w-4 h-4\" strokeWidth={1.5} />\n </button>\n )}\n </div>\n\n {/* Pinned control band — filters, selection actions, and active facet\n pills stick as one group so bulk actions stay reachable from any row.\n Its measured height feeds --lt-sticky-top so table headers stick\n right beneath it, whatever the band currently holds. */}\n <div ref={bandRef} className=\"sticky top-0 z-20 bg-surface\">\n <EscalationFilterBar\n filters={filters}\n setFilter={setFilter}\n roles={rolesData?.roles ?? []}\n types={typesData?.types ?? []}\n showStatus\n showSearch={false}\n showRole={!kiosk}\n actions={\n <>\n {showTimeline && (\n <span className=\"text-2xs text-text-tertiary whitespace-nowrap\">\n {total > 100 && (\n <><span className=\"font-medium text-text-secondary\">{(pagination.page - 1) * 100 + 1}–{Math.min(pagination.page * 100, total)}</span>{' of '}</>\n )}\n <span className=\"font-medium text-text-secondary\">{total}</span>{' '}\n {total === 1 ? 'escalation' : 'escalations'}\n </span>\n )}\n {/* Universal sort — one control for table, timeline, and rich views. */}\n <EscalationSortControl orderBy={facetFilters.orderBy} onChange={setOrderBy} />\n {/* View radio — one list, three presentations, bounded like the\n sort direction pair beside it. Rich appears only when the\n selected role owns a custom list template. */}\n <div\n role=\"radiogroup\"\n aria-label=\"List view\"\n className=\"flex items-center rounded overflow-hidden border border-surface-border\"\n >\n {[\n { key: 'table' as const, title: 'Table view', Icon: Table },\n { key: 'rich' as const, title: 'Rich view', Icon: LayoutList },\n { key: 'timeline' as const, title: 'Timeline view', Icon: Activity },\n ].filter((v) => v.key !== 'rich' || hasRichView).map(({ key, title, Icon }) => (\n <button\n key={key}\n role=\"radio\"\n aria-checked={activeView === key}\n onClick={() => setViewParam(key)}\n className={`px-1.5 py-1 transition-colors ${\n activeView === key\n ? 'bg-accent text-text-inverse'\n : 'icon-link hover:bg-surface-hover'\n }`}\n title={title}\n >\n <Icon className=\"w-3.5 h-3.5\" />\n </button>\n ))}\n </div>\n {/* Faceted-query toggle — the same bounded treatment as the radio\n sets beside it: the accent fill means the drawer is open. */}\n <button\n onClick={() => setFacetDrawerOpen((v) => !v)}\n aria-pressed={facetDrawerOpen}\n className={`relative rounded border border-surface-border px-1.5 py-1 transition-colors ${\n facetDrawerOpen\n ? 'bg-accent text-text-inverse'\n : 'icon-link hover:bg-surface-hover'\n }`}\n title=\"Faceted query\"\n >\n <SlidersHorizontal className=\"w-3.5 h-3.5\" />\n {activeFacetCount > 0 && (\n <span className=\"absolute -right-1 -top-1 flex h-3.5 min-w-[14px] items-center justify-center rounded-full bg-accent px-0.5 text-2xs font-medium text-text-inverse\">\n {activeFacetCount}\n </span>\n )}\n </button>\n {/* Plain actions last — refresh and pin act once, no toggle state. */}\n <div className=\"flex items-center gap-0.5\">\n <button\n onClick={() => refetch()}\n disabled={isFetching}\n className=\"inline-flex h-7 w-7 items-center justify-center rounded icon-link hover:bg-surface-hover disabled:opacity-50\"\n title=\"Refresh\"\n >\n <RefreshCw className={`w-4 h-4 ${isFetching ? 'animate-spin' : ''}`} />\n </button>\n <button\n onClick={pinCurrentView}\n className=\"inline-flex h-7 w-7 items-center justify-center rounded icon-link hover:bg-surface-hover\"\n title=\"Pin this view — save the current filters to your Pinned section\"\n data-testid=\"pin-current-view\"\n >\n <Pin className=\"w-4 h-4\" />\n </button>\n </div>\n </>\n }\n />\n\n {/* Always mounted so the bar can animate in AND out as the selection changes. */}\n <BulkActionBar\n selectedCount={selectedIds.size}\n onClearSelection={() => setSelectedIds(new Set())}\n onSetPriority={handleSetPriority}\n onClaim={handleBulkClaim}\n onAssign={() => setAssignModalOpen(true)}\n onUnassign={handleBulkUnassign}\n onTriage={() => setTriageModalOpen(true)}\n onCancel={() => setCancelModalOpen(true)}\n isPriorityPending={setPriority.isPending}\n isClaimPending={bulkClaim.isPending}\n isAssignPending={bulkAssign.isPending}\n isUnassignPending={bulkUnassign.isPending}\n isTriagePending={bulkTriage.isPending}\n isCancelPending={bulkCancel.isPending}\n cancelLabel={cancelLabel}\n />\n\n {/* Active facet pills — ride the pinned band, opaque so timeline scrolls beneath */}\n {((facetFilters.facets && Object.keys(facetFilters.facets).length > 0) || facetFilters.jeopardy) && (\n <div className=\"bg-surface/98 backdrop-blur-sm border-b border-surface-border/30 -mx-page-x px-page-x py-2 flex items-center gap-1.5 flex-wrap\">\n {facetFilters.jeopardy && (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-status-error px-2.5 py-0.5 text-2xs font-semibold text-text-inverse\">\n <TriangleAlert className=\"w-2.5 h-2.5\" strokeWidth={2.5} />\n in jeopardy\n {jeopardyThresholdLabel && <span className=\"font-mono font-normal opacity-90\">&gt; {jeopardyThresholdLabel}</span>}\n <button\n onClick={() => setFacetFilters({ ...facetFilters, jeopardy: undefined })}\n className=\"ml-0.5 -mr-0.5 flex items-center text-text-inverse/70 hover:text-text-inverse transition-colors\"\n aria-label=\"Clear jeopardy filter\"\n >\n <X className=\"w-2.5 h-2.5\" />\n </button>\n </span>\n )}\n {Object.entries(facetFilters.facets ?? {}).map(([k, v]) => (\n <span\n key={k}\n className=\"inline-flex items-center gap-1 rounded-full border border-accent/25 bg-accent/8 px-2.5 py-0.5 text-2xs font-medium text-accent/90\"\n >\n <span className=\"font-mono text-text-tertiary\">{k}</span>\n <span className=\"text-text-quaternary\">=</span>\n <span className=\"font-mono max-w-[160px] truncate\" title={String(v)}>{String(v)}</span>\n <button\n onClick={() => removeFacet(k)}\n className=\"ml-0.5 -mr-0.5 flex items-center text-text-quaternary hover:text-status-error transition-colors\"\n aria-label={`Remove ${k} filter`}\n >\n <X className=\"w-2.5 h-2.5\" />\n </button>\n </span>\n ))}\n {Object.keys(facetFilters.facets ?? {}).length > 1 && (\n <button\n onClick={() => setFacetFilters({ ...facetFilters, facets: undefined })}\n className=\"text-2xs text-text-quaternary hover:text-text-secondary transition-colors px-1\"\n >\n clear all\n </button>\n )}\n </div>\n )}\n </div>\n\n {queryError && (\n <div className=\"mb-4 px-4 py-3 rounded-md bg-status-error/10 border border-status-error/20 text-xs text-status-error\">\n {(queryError as Error).message === 'Session expired'\n ? 'Your session has expired. Please log in again.'\n : `Failed to load escalations: ${(queryError as Error).message}`}\n </div>\n )}\n\n {showTimeline ? (\n <EscalationTimeline\n escalations={escalations}\n highlightKeys={facetHighlightKeys}\n onRowClick={(row) => navigate(`/escalations/detail/${row.id}`, { state: { from: '/escalations/available' } })}\n total={total}\n page={pagination.page}\n totalPages={Math.ceil(total / timelinePageSize)}\n onPageChange={pagination.setPage}\n />\n ) : useRichView ? (\n <EscalationListView\n role={singleRole!}\n listSchema={listSchema!}\n activeEscalations={escalations}\n onRowClick={(row) => navigate(`/escalations/detail/${row.id}`, { state: { from: '/escalations/available' } })}\n onOpenGroup={(url) => navigate(url)}\n onAddFacet={(key, value) => setFacetFilters({\n ...facetFilters,\n // Same native-type handling as metadataFacetUrl: objects stringify,\n // primitives keep their type so JSONB containment stays type-correct.\n facets: {\n ...(facetFilters.facets ?? {}),\n [key]: typeof value === 'object' && value !== null ? JSON.stringify(value) : value,\n },\n })}\n total={total}\n page={pagination.page}\n totalPages={pagination.totalPages(total)}\n pageSize={pagination.pageSize}\n onPageChange={pagination.setPage}\n onPageSizeChange={pagination.setPageSize}\n />\n ) : (\n <>\n <DataTable\n columns={columns}\n data={escalations}\n layout=\"fixed\"\n {...tableLayoutProps(listParams.layout)}\n keyFn={(row) => row.id}\n onRowClick={(row) => navigate(`/escalations/detail/${row.id}`, { state: { from: '/escalations/available' } })}\n isLoading={isLoading}\n emptyMessage={queryError ? 'Unable to load data' : 'No escalations'}\n />\n\n <StickyPagination\n page={pagination.page}\n totalPages={pagination.totalPages(total)}\n onPageChange={pagination.setPage}\n total={total}\n pageSize={pagination.pageSize}\n onPageSizeChange={pagination.setPageSize}\n />\n </>\n )}\n\n <ClaimModal\n claimTarget={claimTarget}\n onClose={() => setClaimTarget(null)}\n claimDuration={claimDuration}\n onDurationChange={(v) => { setClaimDuration(v); setCustomClaimMinutes(0); }}\n claimDurations={claimDurations}\n customClaimMinutes={customClaimMinutes}\n onCustomClaimChange={onCustomClaimChange}\n onClaim={handleClaim}\n isPending={claim.isPending}\n />\n\n <BulkTriageModal\n open={triageModalOpen}\n onClose={() => setTriageModalOpen(false)}\n selectedCount={selectedIds.size}\n onSubmit={handleBulkTriage}\n isPending={bulkTriage.isPending}\n />\n\n <BulkAssignModal\n open={assignModalOpen}\n onClose={() => setAssignModalOpen(false)}\n selectedCount={selectedIds.size}\n selectedRoles={selectedRoles}\n claimedCount={selectedClaimedCount}\n onSubmit={handleBulkAssign}\n isPending={bulkAssign.isPending}\n />\n\n <ConfirmCancelModal\n open={cancelModalOpen}\n onClose={() => setCancelModalOpen(false)}\n onConfirm={handleBulkCancel}\n selectedCount={selectedIds.size}\n isPending={bulkCancel.isPending}\n error={bulkCancel.error as Error | null}\n actionLabel={typeof cancelLabel === 'string' ? cancelLabel : undefined}\n />\n </div>\n );\n}\n"],"names":["useResolveLinkVarUrl","pathname","search","useLocation","navigate","useNavigate","resolveUrl","useLinkVariables","useEffect","url","extractLinkVarNames","resolved","RANGE_OPS","SORT_COLUMNS","inputCls","selectCls","xBtn","coerce","v","recordRows","rec","key","value","blockRows","arr","o","Section","title","hint","children","jsxs","jsx","KeyInput","onChange","placeholder","e","FacetedFilterPanel","facetKeys","onSearchChange","facets","exclude","ranges","exists","sorts","setFacets","rows","r","setBlock","setRange","setExists","setSorts","k","c","row","i","next","_","j","f","x","s","FacetQueryPanel","activeFacetCount","onClear","onClose","X","anyPending","props","CTRL","SELECT","DANGER","BulkActionBar","disabled","claimDurations","useClaimDurations","settings","useSettings","aiOverride","getAiOverride","aiEnabled","_a","open","PRIORITY_OPTIONS","opt","BulkTriageModal","selectedCount","onSubmit","isPending","setHint","useState","handleSubmit","Modal","bulkHandler","mutation","clearSelection","afterSuccess","variables","createBulkHandlers","deps","ids","priority","durationMinutes","targetUserId","reassign","ClaimModal","claimTarget","claimDuration","onDurationChange","onCustomClaimChange","onClaim","CustomDurationPicker","AvailableEscalationsPage","filters","setFilter","pagination","useFilterParams","useEscalationListEvents","debouncedSearch","useDebouncedValue","setClaimTarget","setClaimDuration","customClaimMinutes","setCustomClaimMinutes","useCallback","m","selectedIds","setSelectedIds","rootRef","useRef","bandObserver","bandRef","el","observer","facetDrawerOpen","setFacetDrawerOpen","searchParams","setSearchParams","useSearchParams","facetFilters","useMemo","parseFacetParams","setFacetFilters","prev","p","writeFacetParams","facetKeysData","useFacetKeys","facetCount","FACET_PANEL_KEY","setPanel","closePanel","panelOpen","ownerKey","useShellPanel","ownsFacetPanel","ownedFacetRef","triageModalOpen","setTriageModalOpen","assignModalOpen","setAssignModalOpen","cancelModalOpen","setCancelModalOpen","setOrderBy","location","prefsData","usePreferences","patchPrefs","usePatchPreferences","pinCurrentView","label","existing","newPinId","canBulkManage","useAccess","kiosk","useKioskMode","facetHighlightKeys","viewParam","layoutParam","setViewParam","showTimeline","removeFacet","_removed","rest","claim","useClaimEscalation","setPriority","useSetEscalationPriority","bulkClaim","useBulkClaimEscalations","bulkAssign","useBulkAssignEscalations","bulkUnassign","useBulkUnassignEscalations","bulkTriage","useBulkTriageEscalations","bulkCancel","useBulkCancelEscalations","rolesData","useRoles","roleDetails","useRoleDetails","typesData","useEscalationTypes","user","isSuperAdmin","hasRoleType","useAuth","isGlobalViewer","memberRoleSet","roleOptions","all","isSystemTierRole","displayRoleTitle","a","b","listParams","isListView","isListLayout","timelinePageSize","escalations","total","listSchema","singleRole","hasRichView","isLoading","isFetching","queryError","refetch","useEscalationListQuery","roleSchemaQuery","useRoleSchema","cancelLabel","readFooterLabels","activeView","resolveListView","useRichView","LIST_VIEWS","jeopardyThresholdLabel","mins","formatDurationCompact","selectedRoles","roles","esc","selectedClaimedCount","isEffectivelyClaimed","handleClaim","minutes","handleSetPriority","handleBulkClaim","handleBulkTriage","handleBulkAssign","handleBulkUnassign","handleBulkCancel","toggleSelect","id","toggleAll","columns","makeEscalationColumns","RowActionGroup","RowAction","Lock","EscalationTitleSelect","BookOpen","EscalationFilterBar","Fragment","EscalationSortControl","Table","LayoutList","Activity","Icon","SlidersHorizontal","RefreshCw","Pin","TriangleAlert","EscalationTimeline","EscalationListView","DataTable","tableLayoutProps","StickyPagination","BulkAssignModal","ConfirmCancelModal"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{a as i,j as e}from"./vendor-query-DvWWuNIB.js";import{u as I}from"./capabilities-ZdLv9xBQ.js";import{T as w,S}from"./ToolTestPanel-BLfA02wv.js";import{T as k}from"./ToolPill-Baxm02L6.js";import{P}from"./PageHeader-Csq434-v.js";import{F as E,b as T,a as L}from"./FilterBar-CvMBCVIo.js";import{aK as R}from"./index-CgUcYveM.js";import{L as A,x as O,bY as K,l as $,bk as q,q as D,bb as F,E as Y,a2 as B,j as M}from"./vendor-icons-B7OcUM6b.js";import"./mcp-Bix7QYO7.js";import"./RunAsSelector-BoePhWVD.js";import"./BotPicker-D3drO3-T.js";import"./bots-DX6jjqtF.js";import"./vendor-react-_9U4mKFr.js";import"./helpers-DzO-OGPe.js";const y={Communication:B,Analysis:Y,Media:F,Data:D,Automation:q,Development:$,System:K,Reference:O,Other:A},p="capability-run";function ae(){const{data:n,isLoading:c}=I(),a=R(),[l,N]=i.useState(""),[m,g]=i.useState(null),[t,x]=i.useState(null),u=(n==null?void 0:n.categories)??[],C=(n==null?void 0:n.totalTools)??0,j=i.useMemo(()=>{let s=u;if(m&&(s=s.filter(r=>r.name===m)),!l.trim())return s;const o=l.toLowerCase();return s.map(r=>({...r,tools:r.tools.filter(v=>v.name.toLowerCase().includes(o)||v.description.toLowerCase().includes(o)||v.serverName.toLowerCase().includes(o))})).filter(r=>r.tools.length>0)},[u,l,m]),f=t?`${t.serverId}:${t.tool.name}`:null,h=i.useRef(null),d=i.useRef(!1);i.useEffect(()=>{a&&f!==h.current&&(h.current=f,t?a.setPanel(e.jsx("div",{className:"h-full overflow-y-auto",children:e.jsx(w,{serverId:t.serverId,serverName:t.serverName,tool:t.tool,onClose:()=>x(null)})}),{key:p,width:420}):(d.current=!1,a.closePanel(p)))},[t,f,a]),i.useEffect(()=>{if(!(!a||!t)){if(a.open&&a.ownerKey===p){d.current=!0;return}d.current&&(d.current=!1,x(null))}},[a,t]);const b=i.useRef(a);return b.current=a,i.useEffect(()=>()=>{var s;h.current&&((s=b.current)==null||s.closePanel(p))},[]),e.jsxs("div",{children:[e.jsx(P,{title:"Capabilities"}),!c&&u.length>0&&e.jsxs(E,{children:[e.jsx(T,{label:"Category",value:m??"",onChange:s=>g(s||null),options:u.map(s=>({value:s.name,label:s.name}))}),e.jsx(L,{label:"Search",value:l,onChange:N,placeholder:`${C} capabilities…`})]}),c?e.jsx("div",{className:"animate-pulse space-y-8",children:[1,2,3].map(s=>e.jsxs("div",{children:[e.jsx("div",{className:"h-4 bg-surface-sunken rounded w-28 mb-4"}),e.jsx("div",{className:"space-y-3",children:[1,2,3].map(o=>e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("div",{className:"h-4 bg-surface-sunken rounded w-36"}),e.jsx("div",{className:"h-3 bg-surface-sunken rounded w-full"})]},o))})]},s))}):j.length===0?e.jsx("p",{className:"text-sm text-text-tertiary mt-8",children:l||m?"No capabilities match your filter.":"No capabilities registered yet."}):e.jsx("div",{className:"space-y-10",children:j.map(s=>{const o=y[s.name]??y.Other;return e.jsxs("div",{children:[e.jsxs("div",{className:"sticky top-[60px] z-10 bg-surface flex items-center gap-2 py-2 mb-2 border-b border-surface-border",children:[e.jsx(o,{className:"w-3 h-3 text-accent",strokeWidth:1.5}),e.jsx("h2",{className:"section-h2",children:s.name}),e.jsx("span",{className:"text-xs text-text-quaternary",children:s.tools.length})]}),e.jsx("div",{className:"divide-y divide-surface-border/30",children:s.tools.map(r=>e.jsx(W,{tool:r,isSelected:(t==null?void 0:t.tool.name)===r.name&&(t==null?void 0:t.serverId)===r.serverId,onSelect:()=>x({serverId:r.serverId,serverName:r.serverName,tool:{name:r.name,description:r.description,inputSchema:r.inputSchema}})},`${r.serverId}-${r.name}`))})]},s.name)})})]})}function W({tool:n,isSelected:c,onSelect:a}){return e.jsxs("div",{role:"button",tabIndex:0,onClick:a,onKeyDown:l=>{(l.key==="Enter"||l.key===" ")&&a()},className:"group relative py-2 px-3 -mx-3 rounded-md cursor-pointer hover:bg-surface-hover/30 transition-colors text-left",children:[c&&e.jsx("span",{className:"absolute left-0 top-1 bottom-1 w-0.5 bg-accent rounded-full"}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(k,{name:n.name,size:"md"}),e.jsx("p",{className:"flex-1 min-w-0 truncate text-2xs text-text-tertiary group-hover:text-text-secondary transition-colors",children:n.description}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsx(S,{name:n.serverName,serverId:n.serverId}),e.jsx("span",{title:"Try it",children:e.jsx(M,{className:`w-3 h-3 transition-opacity ${c?"text-accent opacity-100":"text-accent opacity-0 group-hover:opacity-100"}`,strokeWidth:1.5})})]})]})]})}export{ae as CapabilitiesPage};
2
- //# sourceMappingURL=CapabilitiesPage-RGgD3YZO.js.map
@@ -1,2 +0,0 @@
1
- import{a as r,j as n}from"./vendor-query-DvWWuNIB.js";import{ba as c,az as m,bb as i}from"./index-CgUcYveM.js";const a=[{maxMs:0,color:"text-status-error"},{maxMs:300*1e3,color:"text-status-error"},{maxMs:900*1e3,color:"text-status-warning"},{maxMs:1/0,color:"text-text-secondary"}];function x(t){if(t<=0)return a[0].color;for(const e of a)if(t<e.maxMs)return e.color;return a[a.length-1].color}function M({until:t}){const[e,s]=r.useState(()=>new Date(t).getTime()-Date.now());r.useEffect(()=>{const o=setInterval(()=>{s(new Date(t).getTime()-Date.now())},1e3);return()=>clearInterval(o)},[t]);const l=r.useMemo(()=>{const o=new Date(t);return[{label:"ms",value:String(Math.max(0,e))},{label:"until",value:o.toISOString()},{label:"local",value:c(o,"MMM d, yyyy h:mm:ss a")}]},[t,e]);return n.jsx(m,{options:l,children:n.jsx("span",{className:`text-xs font-mono ${x(e)}`,children:i(e)})})}export{M as C};
2
- //# sourceMappingURL=CountdownTimer-BaexQMK6.js.map