@hotmeshio/long-tail 0.30.2 → 0.30.4

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 (282) hide show
  1. package/build/api/escalations/accumulate.d.ts +2 -1
  2. package/build/api/escalations/accumulate.js +2 -1
  3. package/build/api/escalations/metadata.d.ts +3 -2
  4. package/build/api/escalations/metadata.js +4 -3
  5. package/build/api/escalations/resolve-batch.d.ts +3 -1
  6. package/build/api/escalations/resolve-batch.js +14 -1
  7. package/build/api/scan-codes/choice.js +3 -2
  8. package/build/api/scan-codes/context.d.ts +6 -0
  9. package/build/api/scan-codes/context.js +10 -1
  10. package/build/api/scan-codes/locate.js +1 -0
  11. package/build/api/scan-codes/subject.js +32 -3
  12. package/build/api/scan-codes/verb-accumulate.js +1 -1
  13. package/build/api/scan-codes/verb-fill.js +2 -1
  14. package/build/api/scan-codes/verb-into-subject.js +1 -1
  15. package/build/api/scan-codes/verbs-subject.d.ts +3 -1
  16. package/build/api/scan-codes/verbs-subject.js +8 -5
  17. package/build/api/scan-codes/verbs.js +4 -4
  18. package/build/lib/db/schemas/043_scan_pattern_and_member_targets.sql +26 -0
  19. package/build/lib/facet-value.d.ts +3 -0
  20. package/build/lib/facet-value.js +9 -0
  21. package/build/routes/scan-codes.js +3 -0
  22. package/build/sdk/index.d.ts +3 -3
  23. package/build/services/escalation/batch.d.ts +4 -3
  24. package/build/services/escalation/batch.js +5 -3
  25. package/build/services/escalation/claim-asserted.d.ts +2 -1
  26. package/build/services/escalation/crud.d.ts +3 -2
  27. package/build/services/orchestrator/condition.d.ts +6 -0
  28. package/build/services/orchestrator/condition.js +6 -0
  29. package/build/services/scan-code/read.js +3 -0
  30. package/build/services/scan-code/sql.d.ts +3 -3
  31. package/build/services/scan-code/sql.js +19 -8
  32. package/build/services/scan-code/validate-scheme-pattern.d.ts +16 -0
  33. package/build/services/scan-code/validate-scheme-pattern.js +75 -0
  34. package/build/services/scan-code/validate.d.ts +3 -1
  35. package/build/services/scan-code/validate.js +6 -1
  36. package/build/services/scan-code/write.d.ts +3 -0
  37. package/build/services/scan-code/write.js +3 -0
  38. package/build/shared/scan-code/index.d.ts +2 -1
  39. package/build/shared/scan-code/index.js +8 -1
  40. package/build/shared/scan-code/parse.d.ts +22 -1
  41. package/build/shared/scan-code/parse.js +78 -0
  42. package/build/shared/scan-code/target.d.ts +4 -0
  43. package/build/shared/scan-code/target.js +14 -0
  44. package/build/system/mcp-servers/admin/schemas.d.ts +86 -77
  45. package/build/system/mcp-servers/admin/schemas.js +4 -1
  46. package/build/system/mcp-servers/human-queue-lookups.d.ts +7 -0
  47. package/build/system/mcp-servers/human-queue-lookups.js +31 -0
  48. package/build/system/mcp-servers/human-queue-schemas.d.ts +7 -0
  49. package/build/system/mcp-servers/human-queue-schemas.js +4 -1
  50. package/build/system/mcp-servers/human-queue.d.ts +1 -0
  51. package/build/system/mcp-servers/human-queue.js +3 -0
  52. package/build/system/seed/tool-manifests-admin.js +1 -1
  53. package/build/system/seed/tool-manifests-escalation.js +2 -2
  54. package/build/tsconfig.tsbuildinfo +1 -1
  55. package/build/types/escalation.d.ts +15 -0
  56. package/build/types/escalation.js +16 -1
  57. package/build/types/facets.d.ts +5 -0
  58. package/build/types/index.d.ts +3 -3
  59. package/build/types/index.js +5 -1
  60. package/build/types/scan-code/constants.d.ts +20 -0
  61. package/build/types/scan-code/constants.js +20 -1
  62. package/build/types/scan-code/response.d.ts +2 -1
  63. package/build/types/scan-code/rule.d.ts +12 -2
  64. package/dashboard/dist/assets/{AdminDashboard-NVtdLI4I.js → AdminDashboard-VQ1fhhJP.js} +2 -2
  65. package/dashboard/dist/assets/{AdminDashboard-NVtdLI4I.js.map → AdminDashboard-VQ1fhhJP.js.map} +1 -1
  66. package/dashboard/dist/assets/{AgentConfigPage-Db1Oi72V.js → AgentConfigPage-BOe_W2Ij.js} +2 -2
  67. package/dashboard/dist/assets/{AgentConfigPage-Db1Oi72V.js.map → AgentConfigPage-BOe_W2Ij.js.map} +1 -1
  68. package/dashboard/dist/assets/{AgentDetailPage-BF4mw1bD.js → AgentDetailPage-5ov5D9V2.js} +2 -2
  69. package/dashboard/dist/assets/{AgentDetailPage-BF4mw1bD.js.map → AgentDetailPage-5ov5D9V2.js.map} +1 -1
  70. package/dashboard/dist/assets/{AgentsPage-DmF0m3Ro.js → AgentsPage-DDFMKHhI.js} +2 -2
  71. package/dashboard/dist/assets/{AgentsPage-DmF0m3Ro.js.map → AgentsPage-DDFMKHhI.js.map} +1 -1
  72. package/dashboard/dist/assets/{AvailableEscalationsPage-jy2WKDjr.js → AvailableEscalationsPage-GFn8Sgg1.js} +2 -2
  73. package/dashboard/dist/assets/{AvailableEscalationsPage-jy2WKDjr.js.map → AvailableEscalationsPage-GFn8Sgg1.js.map} +1 -1
  74. package/dashboard/dist/assets/{BotPicker-HJtVHdNe.js → BotPicker-Dqpo36dM.js} +2 -2
  75. package/dashboard/dist/assets/{BotPicker-HJtVHdNe.js.map → BotPicker-Dqpo36dM.js.map} +1 -1
  76. package/dashboard/dist/assets/{BulkAssignModal-DsJJZ9X4.js → BulkAssignModal-CmLVxkz-.js} +2 -2
  77. package/dashboard/dist/assets/{BulkAssignModal-DsJJZ9X4.js.map → BulkAssignModal-CmLVxkz-.js.map} +1 -1
  78. package/dashboard/dist/assets/{CapabilitiesPage-iCn7PxDP.js → CapabilitiesPage-Dfkip6_b.js} +2 -2
  79. package/dashboard/dist/assets/{CapabilitiesPage-iCn7PxDP.js.map → CapabilitiesPage-Dfkip6_b.js.map} +1 -1
  80. package/dashboard/dist/assets/{CollapsibleSection-DFfVr_Ut.js → CollapsibleSection-CYNYMYSa.js} +2 -2
  81. package/dashboard/dist/assets/{CollapsibleSection-DFfVr_Ut.js.map → CollapsibleSection-CYNYMYSa.js.map} +1 -1
  82. package/dashboard/dist/assets/{ConfirmDeleteModal-D6TwO-yT.js → ConfirmDeleteModal-CpJNP-8w.js} +2 -2
  83. package/dashboard/dist/assets/{ConfirmDeleteModal-D6TwO-yT.js.map → ConfirmDeleteModal-CpJNP-8w.js.map} +1 -1
  84. package/dashboard/dist/assets/{ConnectedAppsPage-BOD-tgY0.js → ConnectedAppsPage-DXIp2Dpl.js} +2 -2
  85. package/dashboard/dist/assets/{ConnectedAppsPage-BOD-tgY0.js.map → ConnectedAppsPage-DXIp2Dpl.js.map} +1 -1
  86. package/dashboard/dist/assets/{CountdownTimer-u_o3OygV.js → CountdownTimer-CuPY7zkb.js} +2 -2
  87. package/dashboard/dist/assets/{CountdownTimer-u_o3OygV.js.map → CountdownTimer-CuPY7zkb.js.map} +1 -1
  88. package/dashboard/dist/assets/{CredentialsPage-C3dnRsMh.js → CredentialsPage-CtrnkHcj.js} +2 -2
  89. package/dashboard/dist/assets/{CredentialsPage-C3dnRsMh.js.map → CredentialsPage-CtrnkHcj.js.map} +1 -1
  90. package/dashboard/dist/assets/{CronLabel-BFh5TCsB.js → CronLabel-DVjTw5Ri.js} +2 -2
  91. package/dashboard/dist/assets/{CronLabel-BFh5TCsB.js.map → CronLabel-DVjTw5Ri.js.map} +1 -1
  92. package/dashboard/dist/assets/{ElapsedCell-D0jYuFKh.js → ElapsedCell-gY_mGMTF.js} +2 -2
  93. package/dashboard/dist/assets/{ElapsedCell-D0jYuFKh.js.map → ElapsedCell-gY_mGMTF.js.map} +1 -1
  94. package/dashboard/dist/assets/{EntityTimelinePanel-Ch-BsRu8.js → EntityTimelinePanel-DJN_ZEQa.js} +2 -2
  95. package/dashboard/dist/assets/{EntityTimelinePanel-Ch-BsRu8.js.map → EntityTimelinePanel-DJN_ZEQa.js.map} +1 -1
  96. package/dashboard/dist/assets/{EscalationListSchemaPage-DuSLiInU.js → EscalationListSchemaPage-A4KpTdJA.js} +3 -3
  97. package/dashboard/dist/assets/{EscalationListSchemaPage-DuSLiInU.js.map → EscalationListSchemaPage-A4KpTdJA.js.map} +1 -1
  98. package/dashboard/dist/assets/{EscalationSchemaPage-D_mYri6e.js → EscalationSchemaPage-nfCn42hT.js} +2 -2
  99. package/dashboard/dist/assets/{EscalationSchemaPage-D_mYri6e.js.map → EscalationSchemaPage-nfCn42hT.js.map} +1 -1
  100. package/dashboard/dist/assets/{EscalationTimeline-DiN8ImWF.js → EscalationTimeline-CLvSr1SD.js} +2 -2
  101. package/dashboard/dist/assets/{EscalationTimeline-DiN8ImWF.js.map → EscalationTimeline-CLvSr1SD.js.map} +1 -1
  102. package/dashboard/dist/assets/{EscalationTitleSelect-36tkc2TE.js → EscalationTitleSelect-CT7mYHkb.js} +2 -2
  103. package/dashboard/dist/assets/{EscalationTitleSelect-36tkc2TE.js.map → EscalationTitleSelect-CT7mYHkb.js.map} +1 -1
  104. package/dashboard/dist/assets/{EscalationsOverview-yHY6JKiV.js → EscalationsOverview-CKaGRh-E.js} +2 -2
  105. package/dashboard/dist/assets/{EscalationsOverview-yHY6JKiV.js.map → EscalationsOverview-CKaGRh-E.js.map} +1 -1
  106. package/dashboard/dist/assets/{EventTable-DTtu2iM_.js → EventTable-2ywJsOLy.js} +2 -2
  107. package/dashboard/dist/assets/{EventTable-DTtu2iM_.js.map → EventTable-2ywJsOLy.js.map} +1 -1
  108. package/dashboard/dist/assets/{FilterBar-ByZiD0ty.js → FilterBar-Dy0b7wwf.js} +2 -2
  109. package/dashboard/dist/assets/{FilterBar-ByZiD0ty.js.map → FilterBar-Dy0b7wwf.js.map} +1 -1
  110. package/dashboard/dist/assets/{GraphInvokePage-Cbn6igr_.js → GraphInvokePage-yOVpraAy.js} +2 -2
  111. package/dashboard/dist/assets/{GraphInvokePage-Cbn6igr_.js.map → GraphInvokePage-yOVpraAy.js.map} +1 -1
  112. package/dashboard/dist/assets/{HomePage-CtLKm_S4.js → HomePage-67xXjKjN.js} +2 -2
  113. package/dashboard/dist/assets/{HomePage-CtLKm_S4.js.map → HomePage-67xXjKjN.js.map} +1 -1
  114. package/dashboard/dist/assets/{LinePage-Q5Cgjd3N.js → LinePage-CMsYtukW.js} +3 -3
  115. package/dashboard/dist/assets/{LinePage-Q5Cgjd3N.js.map → LinePage-CMsYtukW.js.map} +1 -1
  116. package/dashboard/dist/assets/{LinesPage-BX3d-rj0.js → LinesPage-pwL46mOS.js} +3 -3
  117. package/dashboard/dist/assets/{LinesPage-BX3d-rj0.js.map → LinesPage-pwL46mOS.js.map} +1 -1
  118. package/dashboard/dist/assets/{ListToolbar-bj2sgAK4.js → ListToolbar-CJmvGy2B.js} +2 -2
  119. package/dashboard/dist/assets/{ListToolbar-bj2sgAK4.js.map → ListToolbar-CJmvGy2B.js.map} +1 -1
  120. package/dashboard/dist/assets/{McpOverview-BD3UWbcC.js → McpOverview-DA9LLvNG.js} +2 -2
  121. package/dashboard/dist/assets/{McpOverview-BD3UWbcC.js.map → McpOverview-DA9LLvNG.js.map} +1 -1
  122. package/dashboard/dist/assets/{McpQueryDetailPage-ISzY-BfT.js → McpQueryDetailPage-N7qLmfE8.js} +2 -2
  123. package/dashboard/dist/assets/{McpQueryDetailPage-ISzY-BfT.js.map → McpQueryDetailPage-N7qLmfE8.js.map} +1 -1
  124. package/dashboard/dist/assets/{McpQueryPage-t555QJ3m.js → McpQueryPage-CpsP3w7x.js} +2 -2
  125. package/dashboard/dist/assets/{McpQueryPage-t555QJ3m.js.map → McpQueryPage-CpsP3w7x.js.map} +1 -1
  126. package/dashboard/dist/assets/{McpRunDetailPage-C4jozQFh.js → McpRunDetailPage-qHRQ1pEY.js} +2 -2
  127. package/dashboard/dist/assets/{McpRunDetailPage-C4jozQFh.js.map → McpRunDetailPage-qHRQ1pEY.js.map} +1 -1
  128. package/dashboard/dist/assets/{McpRunsPage-Z-mtyRBp.js → McpRunsPage-BRDDYpTM.js} +2 -2
  129. package/dashboard/dist/assets/{McpRunsPage-Z-mtyRBp.js.map → McpRunsPage-BRDDYpTM.js.map} +1 -1
  130. package/dashboard/dist/assets/{OperationsPage-ClYilVyZ.js → OperationsPage-zUaab-CL.js} +3 -3
  131. package/dashboard/dist/assets/{OperationsPage-ClYilVyZ.js.map → OperationsPage-zUaab-CL.js.map} +1 -1
  132. package/dashboard/dist/assets/{OperatorDashboard-3Hi2IiHi.js → OperatorDashboard-el5BquXN.js} +2 -2
  133. package/dashboard/dist/assets/{OperatorDashboard-3Hi2IiHi.js.map → OperatorDashboard-el5BquXN.js.map} +1 -1
  134. package/dashboard/dist/assets/{PersonaDetailPage-xb7O3tn9.js → PersonaDetailPage-B_tb8gfl.js} +2 -2
  135. package/dashboard/dist/assets/{PersonaDetailPage-xb7O3tn9.js.map → PersonaDetailPage-B_tb8gfl.js.map} +1 -1
  136. package/dashboard/dist/assets/{PersonasPage-uCYVhRBB.js → PersonasPage-BPI7mqM8.js} +2 -2
  137. package/dashboard/dist/assets/{PersonasPage-uCYVhRBB.js.map → PersonasPage-BPI7mqM8.js.map} +1 -1
  138. package/dashboard/dist/assets/{PortalPage-D1MOMJ9Q.js → PortalPage-e_rBb1do.js} +2 -2
  139. package/dashboard/dist/assets/{PortalPage-D1MOMJ9Q.js.map → PortalPage-e_rBb1do.js.map} +1 -1
  140. package/dashboard/dist/assets/{ProcessDetailPage-Tf8FQCUm.js → ProcessDetailPage-D35RX1bB.js} +2 -2
  141. package/dashboard/dist/assets/{ProcessDetailPage-Tf8FQCUm.js.map → ProcessDetailPage-D35RX1bB.js.map} +1 -1
  142. package/dashboard/dist/assets/{ProcessesListPage-DPLRgznC.js → ProcessesListPage-CT81miI5.js} +2 -2
  143. package/dashboard/dist/assets/{ProcessesListPage-DPLRgznC.js.map → ProcessesListPage-CT81miI5.js.map} +1 -1
  144. package/dashboard/dist/assets/{ResolverForm-BXqJEPte.js → ResolverForm-BxJkoKAO.js} +2 -2
  145. package/dashboard/dist/assets/{ResolverForm-BXqJEPte.js.map → ResolverForm-BxJkoKAO.js.map} +1 -1
  146. package/dashboard/dist/assets/{RoleDetailPage-KJnZGPPY.js → RoleDetailPage-DtU7vsJm.js} +2 -2
  147. package/dashboard/dist/assets/{RoleDetailPage-KJnZGPPY.js.map → RoleDetailPage-DtU7vsJm.js.map} +1 -1
  148. package/dashboard/dist/assets/{RolesPage-C5f-3zcs.js → RolesPage-BE7RWt9q.js} +2 -2
  149. package/dashboard/dist/assets/{RolesPage-C5f-3zcs.js.map → RolesPage-BE7RWt9q.js.map} +1 -1
  150. package/dashboard/dist/assets/{RosterWidget-WCtpUEzc.js → RosterWidget-BJMx0a8Z.js} +2 -2
  151. package/dashboard/dist/assets/{RosterWidget-WCtpUEzc.js.map → RosterWidget-BJMx0a8Z.js.map} +1 -1
  152. package/dashboard/dist/assets/{RunAsSelector-CzabsFYU.js → RunAsSelector-Co6s9bqA.js} +2 -2
  153. package/dashboard/dist/assets/{RunAsSelector-CzabsFYU.js.map → RunAsSelector-Co6s9bqA.js.map} +1 -1
  154. package/dashboard/dist/assets/ScanCodesPage-C2TETaj5.js +2 -0
  155. package/dashboard/dist/assets/ScanCodesPage-C2TETaj5.js.map +1 -0
  156. package/dashboard/dist/assets/ScanSchemeDetailPage-C2UgU8l-.js +5 -0
  157. package/dashboard/dist/assets/ScanSchemeDetailPage-C2UgU8l-.js.map +1 -0
  158. package/dashboard/dist/assets/ScanStationPage-nWYz-OD3.js +2 -0
  159. package/dashboard/dist/assets/ScanStationPage-nWYz-OD3.js.map +1 -0
  160. package/dashboard/dist/assets/SchemeMatchFields-9H7SmbED.js +4 -0
  161. package/dashboard/dist/assets/SchemeMatchFields-9H7SmbED.js.map +1 -0
  162. package/dashboard/dist/assets/{StickyPagination-C2fzclxr.js → StickyPagination-miUdVAKw.js} +2 -2
  163. package/dashboard/dist/assets/{StickyPagination-C2fzclxr.js.map → StickyPagination-miUdVAKw.js.map} +1 -1
  164. package/dashboard/dist/assets/{StreamMessageDetail-wF4NM8gi.js → StreamMessageDetail-D5Rk7pn7.js} +2 -2
  165. package/dashboard/dist/assets/{StreamMessageDetail-wF4NM8gi.js.map → StreamMessageDetail-D5Rk7pn7.js.map} +1 -1
  166. package/dashboard/dist/assets/{SwimlaneTimeline-B4Hg97qO.js → SwimlaneTimeline-B1QY1ZzH.js} +2 -2
  167. package/dashboard/dist/assets/{SwimlaneTimeline-B4Hg97qO.js.map → SwimlaneTimeline-B1QY1ZzH.js.map} +1 -1
  168. package/dashboard/dist/assets/{TaskDetailPage-DAxxcFDD.js → TaskDetailPage-DKUM37o8.js} +2 -2
  169. package/dashboard/dist/assets/{TaskDetailPage-DAxxcFDD.js.map → TaskDetailPage-DKUM37o8.js.map} +1 -1
  170. package/dashboard/dist/assets/{TasksListPage-BmghuHbc.js → TasksListPage-CUulwvm-.js} +2 -2
  171. package/dashboard/dist/assets/{TasksListPage-BmghuHbc.js.map → TasksListPage-CUulwvm-.js.map} +1 -1
  172. package/dashboard/dist/assets/{TimeAgo-CFeB6U2O.js → TimeAgo-CHTelacB.js} +2 -2
  173. package/dashboard/dist/assets/{TimeAgo-CFeB6U2O.js.map → TimeAgo-CHTelacB.js.map} +1 -1
  174. package/dashboard/dist/assets/{TimestampCell-M_FD9JEc.js → TimestampCell-NanLWLKo.js} +2 -2
  175. package/dashboard/dist/assets/{TimestampCell-M_FD9JEc.js.map → TimestampCell-NanLWLKo.js.map} +1 -1
  176. package/dashboard/dist/assets/{ToolTestPanel-D7PihZG9.js → ToolTestPanel-CF1CHzgz.js} +2 -2
  177. package/dashboard/dist/assets/{ToolTestPanel-D7PihZG9.js.map → ToolTestPanel-CF1CHzgz.js.map} +1 -1
  178. package/dashboard/dist/assets/{TopicDetailPage-T0dLt7Ao.js → TopicDetailPage-CGO8XV_a.js} +2 -2
  179. package/dashboard/dist/assets/{TopicDetailPage-T0dLt7Ao.js.map → TopicDetailPage-CGO8XV_a.js.map} +1 -1
  180. package/dashboard/dist/assets/{TopicsPage-DP5ox5oX.js → TopicsPage-Bt8gOKYr.js} +2 -2
  181. package/dashboard/dist/assets/{TopicsPage-DP5ox5oX.js.map → TopicsPage-Bt8gOKYr.js.map} +1 -1
  182. package/dashboard/dist/assets/{UserName-ET3r3u-A.js → UserName-DKXnK7DD.js} +2 -2
  183. package/dashboard/dist/assets/{UserName-ET3r3u-A.js.map → UserName-DKXnK7DD.js.map} +1 -1
  184. package/dashboard/dist/assets/{WorkflowExecutionPage-DBq2lZ_C.js → WorkflowExecutionPage-Crf7AIFc.js} +2 -2
  185. package/dashboard/dist/assets/{WorkflowExecutionPage-DBq2lZ_C.js.map → WorkflowExecutionPage-Crf7AIFc.js.map} +1 -1
  186. package/dashboard/dist/assets/{WorkflowsDashboard-WO4cH8sU.js → WorkflowsDashboard--isjt06C.js} +2 -2
  187. package/dashboard/dist/assets/{WorkflowsDashboard-WO4cH8sU.js.map → WorkflowsDashboard--isjt06C.js.map} +1 -1
  188. package/dashboard/dist/assets/{WorkflowsOverview-CJfg0rQH.js → WorkflowsOverview-D7Oqf4-V.js} +2 -2
  189. package/dashboard/dist/assets/{WorkflowsOverview-CJfg0rQH.js.map → WorkflowsOverview-D7Oqf4-V.js.map} +1 -1
  190. package/dashboard/dist/assets/{YamlWorkflowDetailPage-C8rkvYCp.js → YamlWorkflowDetailPage-B0wxgrGP.js} +8 -8
  191. package/dashboard/dist/assets/{YamlWorkflowDetailPage-C8rkvYCp.js.map → YamlWorkflowDetailPage-B0wxgrGP.js.map} +1 -1
  192. package/dashboard/dist/assets/{YamlWorkflowsPage-DHQ4ZVzM.js → YamlWorkflowsPage-BVdLnm6K.js} +2 -2
  193. package/dashboard/dist/assets/{YamlWorkflowsPage-DHQ4ZVzM.js.map → YamlWorkflowsPage-BVdLnm6K.js.map} +1 -1
  194. package/dashboard/dist/assets/{agents-zulmHig2.js → agents-CHjbjHXA.js} +2 -2
  195. package/dashboard/dist/assets/{agents-zulmHig2.js.map → agents-CHjbjHXA.js.map} +1 -1
  196. package/dashboard/dist/assets/{bots-D4mtcPHB.js → bots-WrUhEPWs.js} +2 -2
  197. package/dashboard/dist/assets/{bots-D4mtcPHB.js.map → bots-WrUhEPWs.js.map} +1 -1
  198. package/dashboard/dist/assets/{capabilities-rFZDH0zF.js → capabilities-CunMmkj8.js} +2 -2
  199. package/dashboard/dist/assets/{capabilities-rFZDH0zF.js.map → capabilities-CunMmkj8.js.map} +1 -1
  200. package/dashboard/dist/assets/{controlplane-INfcW_9F.js → controlplane-D6IZIZoh.js} +2 -2
  201. package/dashboard/dist/assets/{controlplane-INfcW_9F.js.map → controlplane-D6IZIZoh.js.map} +1 -1
  202. package/dashboard/dist/assets/{escalation-columns-8ker-czW.js → escalation-columns-Bvo6JI4Z.js} +2 -2
  203. package/dashboard/dist/assets/{escalation-columns-8ker-czW.js.map → escalation-columns-Bvo6JI4Z.js.map} +1 -1
  204. package/dashboard/dist/assets/{escalation-items-B6eDMoTN.js → escalation-items-DFGRwo49.js} +2 -2
  205. package/dashboard/dist/assets/{escalation-items-B6eDMoTN.js.map → escalation-items-DFGRwo49.js.map} +1 -1
  206. package/dashboard/dist/assets/{index-Cfg4TFDb.js → index-B8qrHwp9.js} +2 -2
  207. package/dashboard/dist/assets/{index-Cfg4TFDb.js.map → index-B8qrHwp9.js.map} +1 -1
  208. package/dashboard/dist/assets/{index-D-Fd0gQ_.js → index-B95LbYhW.js} +2 -2
  209. package/dashboard/dist/assets/{index-D-Fd0gQ_.js.map → index-B95LbYhW.js.map} +1 -1
  210. package/dashboard/dist/assets/{index-BpillEP7.js → index-BZFSXEkr.js} +2 -2
  211. package/dashboard/dist/assets/{index-BpillEP7.js.map → index-BZFSXEkr.js.map} +1 -1
  212. package/dashboard/dist/assets/index-BmzscsXK.css +1 -0
  213. package/dashboard/dist/assets/{index-ChF-l2z9.js → index-Bo8QU31k.js} +2 -2
  214. package/dashboard/dist/assets/{index-ChF-l2z9.js.map → index-Bo8QU31k.js.map} +1 -1
  215. package/dashboard/dist/assets/{index-0LXkjZjt.js → index-C7EIu1mG.js} +2 -2
  216. package/dashboard/dist/assets/{index-0LXkjZjt.js.map → index-C7EIu1mG.js.map} +1 -1
  217. package/dashboard/dist/assets/{index-Cm6_Peh7.js → index-CpCchhQv.js} +2 -2
  218. package/dashboard/dist/assets/{index-Cm6_Peh7.js.map → index-CpCchhQv.js.map} +1 -1
  219. package/dashboard/dist/assets/{index-5XUBZtlv.js → index-DCJ483vt.js} +2 -2
  220. package/dashboard/dist/assets/{index-5XUBZtlv.js.map → index-DCJ483vt.js.map} +1 -1
  221. package/dashboard/dist/assets/{index-BcVkiaCv.js → index-DRK7M1_9.js} +2 -2
  222. package/dashboard/dist/assets/{index-BcVkiaCv.js.map → index-DRK7M1_9.js.map} +1 -1
  223. package/dashboard/dist/assets/{index-D-EVgGsm.js → index-DRw0FXdX.js} +2 -2
  224. package/dashboard/dist/assets/{index-D-EVgGsm.js.map → index-DRw0FXdX.js.map} +1 -1
  225. package/dashboard/dist/assets/{index-CV7KmPdF.js → index-OuKQ_0eB.js} +2 -2
  226. package/dashboard/dist/assets/{index-CV7KmPdF.js.map → index-OuKQ_0eB.js.map} +1 -1
  227. package/dashboard/dist/assets/index-P-DlgAWj.js +3 -0
  228. package/dashboard/dist/assets/index-P-DlgAWj.js.map +1 -0
  229. package/dashboard/dist/assets/{index-Cg9W61lM.js → index-boT612Jo.js} +2 -2
  230. package/dashboard/dist/assets/{index-Cg9W61lM.js.map → index-boT612Jo.js.map} +1 -1
  231. package/dashboard/dist/assets/index-ygxyAKcc.js +67 -0
  232. package/dashboard/dist/assets/index-ygxyAKcc.js.map +1 -0
  233. package/dashboard/dist/assets/{knowledge-_WaBsrbC.js → knowledge-BubJBTwg.js} +2 -2
  234. package/dashboard/dist/assets/{knowledge-_WaBsrbC.js.map → knowledge-BubJBTwg.js.map} +1 -1
  235. package/dashboard/dist/assets/{machines-D6ig2Q8z.js → machines-DSm5NFgs.js} +2 -2
  236. package/dashboard/dist/assets/{machines-D6ig2Q8z.js.map → machines-DSm5NFgs.js.map} +1 -1
  237. package/dashboard/dist/assets/{mcp-DtWRQM1G.js → mcp-D6MckqOV.js} +2 -2
  238. package/dashboard/dist/assets/{mcp-DtWRQM1G.js.map → mcp-D6MckqOV.js.map} +1 -1
  239. package/dashboard/dist/assets/{mcp-query-vQm92kTd.js → mcp-query-VyCdOag6.js} +2 -2
  240. package/dashboard/dist/assets/{mcp-query-vQm92kTd.js.map → mcp-query-VyCdOag6.js.map} +1 -1
  241. package/dashboard/dist/assets/{personas-BLxQpGNz.js → personas-CyJc10xe.js} +2 -2
  242. package/dashboard/dist/assets/{personas-BLxQpGNz.js.map → personas-CyJc10xe.js.map} +1 -1
  243. package/dashboard/dist/assets/{pipelines-ClmRtlkR.js → pipelines-B2inDtx3.js} +2 -2
  244. package/dashboard/dist/assets/{pipelines-ClmRtlkR.js.map → pipelines-B2inDtx3.js.map} +1 -1
  245. package/dashboard/dist/assets/{tasks-CVZT1pf0.js → tasks-DOP4d3M6.js} +2 -2
  246. package/dashboard/dist/assets/{tasks-CVZT1pf0.js.map → tasks-DOP4d3M6.js.map} +1 -1
  247. package/dashboard/dist/assets/{topics-rkG9-6El.js → topics-CNOjSWpX.js} +2 -2
  248. package/dashboard/dist/assets/{topics-rkG9-6El.js.map → topics-CNOjSWpX.js.map} +1 -1
  249. package/dashboard/dist/assets/{useDebouncedValue-D2aCC74y.js → useDebouncedValue-CgO0TGMd.js} +2 -2
  250. package/dashboard/dist/assets/{useDebouncedValue-D2aCC74y.js.map → useDebouncedValue-CgO0TGMd.js.map} +1 -1
  251. package/dashboard/dist/assets/{useNamespace-BGfkF4ej.js → useNamespace-BWHvUKtK.js} +2 -2
  252. package/dashboard/dist/assets/{useNamespace-BGfkF4ej.js.map → useNamespace-BWHvUKtK.js.map} +1 -1
  253. package/dashboard/dist/assets/{useYamlActivityEvents-DOU0_nfZ.js → useYamlActivityEvents-BZQ__ZGD.js} +2 -2
  254. package/dashboard/dist/assets/{useYamlActivityEvents-DOU0_nfZ.js.map → useYamlActivityEvents-BZQ__ZGD.js.map} +1 -1
  255. package/dashboard/dist/assets/{validate-bHZ917pZ.js → validate-CAin6WM_.js} +2 -2
  256. package/dashboard/dist/assets/{validate-bHZ917pZ.js.map → validate-CAin6WM_.js.map} +1 -1
  257. package/dashboard/dist/assets/{yaml-workflows-S7qlgdg6.js → yaml-workflows-Dyln3od-.js} +2 -2
  258. package/dashboard/dist/assets/{yaml-workflows-S7qlgdg6.js.map → yaml-workflows-Dyln3od-.js.map} +1 -1
  259. package/dashboard/dist/index.html +2 -2
  260. package/docs/accumulator.md +1 -1
  261. package/docs/api/http/escalations.md +1 -1
  262. package/docs/api/mcp/human-queue.md +5 -1
  263. package/docs/api/sdk/escalations.md +1 -1
  264. package/docs/dashboard.md +4 -2
  265. package/docs/hitl/escalation.md +16 -0
  266. package/docs/hitl/lookups.md +2 -0
  267. package/docs/mcp.md +2 -0
  268. package/docs/scan-codes.md +34 -11
  269. package/package.json +2 -2
  270. package/dashboard/dist/assets/GrantScopeField-BzWGzBfA.js +0 -2
  271. package/dashboard/dist/assets/GrantScopeField-BzWGzBfA.js.map +0 -1
  272. package/dashboard/dist/assets/ScanCodesPage-D51d17HH.js +0 -2
  273. package/dashboard/dist/assets/ScanCodesPage-D51d17HH.js.map +0 -1
  274. package/dashboard/dist/assets/ScanSchemeDetailPage-CUK6Skxj.js +0 -2
  275. package/dashboard/dist/assets/ScanSchemeDetailPage-CUK6Skxj.js.map +0 -1
  276. package/dashboard/dist/assets/ScanStationPage-7vK0ddiV.js +0 -2
  277. package/dashboard/dist/assets/ScanStationPage-7vK0ddiV.js.map +0 -1
  278. package/dashboard/dist/assets/index-BpJ77OST.js +0 -3
  279. package/dashboard/dist/assets/index-BpJ77OST.js.map +0 -1
  280. package/dashboard/dist/assets/index-C_dp4WgY.css +0 -1
  281. package/dashboard/dist/assets/index-xycFf66M.js +0 -67
  282. package/dashboard/dist/assets/index-xycFf66M.js.map +0 -1
@@ -1,2 +1,2 @@
1
- import{j as d}from"./vendor-query-DvWWuNIB.js";import{b0 as M,bg as C,g as F}from"./index-xycFf66M.js";import{U as H}from"./UserName-ET3r3u-A.js";const $={LINK:"link",ESCALATION:"escalation",ESCALATION_LIST:"escalation-list",INVOKE:"invoke",ROSTER:"roster"},G=new Set(Object.values($));function U(t){return typeof t=="string"&&G.has(t)}function Y(t){return U(t==null?void 0:t["x-lt-widget"])}const w=new Set(["__proto__","constructor","prototype"]);function O(t){const n=[];for(const r of t.split(".")){const e=r.match(/^([^[\]]*)((?:\[\d+\])*)$/);if(!e)throw new Error(`invalid x-lt-bind path segment: "${r}"`);const[,s,i]=e;if(s){if(w.has(s))throw new Error(`x-lt-bind path may not target "${s}"`);n.push({key:s})}for(const o of i.match(/\d+/g)??[])n.push({index:Number(o)})}if(n.length===0)throw new Error(`empty x-lt-bind path: "${t}"`);return n}function B(t,n,r){const e=O(n);let s=t;for(let o=0;o<e.length-1;o++){const a=e[o],l=e[o+1],c="key"in a?a.key:a.index,u="index"in l;(s[c]==null||typeof s[c]!="object")&&(s[c]=u?[]:{}),s=s[c]}const i=e[e.length-1];s["key"in i?i.key:i.index]=r}function m(t,n){let r=t;for(const e of O(n)){if(r==null||typeof r!="object")return;r=r["key"in e?e.key:e.index]}return r}function k(t,n){const r=n==null?void 0:n["x-lt-bind"];return typeof r=="string"&&r.length>0?r:t}function v(t,n){const r=n==null?void 0:n.properties;if(!r)return{...t};const e={};for(const[s,i]of Object.entries(r))s in t&&(Y(i)||B(e,k(s,i),t[s]));return e}function tt(t,n){const r=n==null?void 0:n.properties;if(!r)return t?{...t}:{};const e={};for(const[s,i]of Object.entries(r)){const o=m(t,k(s,i));o!==void 0&&(e[s]=o)}return e}const R=["escalation","metadata","envelope","payload","resolver","lookup","input","roster"],K=/\{\{\s*([^{}]+?)\s*\}\}/g,p="—";function A(t){if(t==null)return p;if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return String(t);try{return JSON.stringify(t)}catch{return p}}function S(t,n){return t.replace(K,(r,e)=>{const s=e.indexOf("."),i=s===-1?e:e.slice(0,s);if(!R.includes(i))return p;const o=n[i];if(s===-1)return A(o);try{return A(m(o,e.slice(s+1)))}catch{return p}})}function P(t){const n=t==null?void 0:t["x-lt-help"];if(typeof n=="string"&&n.trim().length>0)return n;const r=t==null?void 0:t["x-lt-context"];return typeof r=="string"&&r.trim().length>0?r:null}function nt(t,n){const r=P(t);return r?S(r,n):null}function rt({isTerminal:t,status:n,claimed:r,claimedByMe:e}){return t?n==="cancelled"?"This escalation was cancelled. The record is shown for reference.":"This escalation has been resolved. The submitted form is shown for reference.":e?"You have claimed this escalation. Fill out the form and submit to resolve it.":r?"Another user has claimed this escalation. It unlocks if their claim expires or is released.":"Claim this escalation to enable the form."}const E=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/,_="—",y={AGE:"age",AGO:"ago",DATE:"date",USER:"user"};function h(t){return t===y.AGE||t===y.AGO}function et({raw:t,format:n}){if(!t||t===_)return d.jsx("span",{className:"text-text-quaternary",children:_});if(n===y.USER)return d.jsx(H,{userId:t,className:"block truncate"});const r=E.test(t)||!Number.isNaN(new Date(t).getTime())&&(h(n)||n===y.DATE);return h(n)&&r?d.jsx("span",{title:C(t),className:"tabular-nums whitespace-nowrap",children:M(t)}):r&&(n===y.DATE||E.test(t))?d.jsx(F,{date:t,format:"datetime",className:"text-text-primary whitespace-nowrap"}):d.jsx(d.Fragment,{children:t})}function st(t){if(!t)return!1;try{const n=JSON.stringify(t);return n.includes("envelope.")||n.includes("payload.")}catch{return!1}}const V="accumulate_items",J="accumulate_max",T="batch_items",x="batch_filled_at",I="batch_filled_by",W="batch_keys",q="batch_pending";function f(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function N(t,n){return t.at.localeCompare(n.at)||t.itemKey.localeCompare(n.itemKey)}function it(t,n){const r=t.metadata??{},e=n==null?void 0:n[V];if(f(e)){const i=Object.entries(e).map(([a,l])=>{const c=f(l)?l:{};return{itemKey:a,at:typeof c.at=="string"?c.at:"",...f(c.payload)?{payload:c.payload}:{},...typeof c.actor=="string"?{actor:c.actor}:{},...typeof c.reciprocalId=="string"?{reciprocalId:c.reciprocalId}:{}}}).sort(N),o=r[J];return{kind:"accumulate",count:i.length,max:typeof o=="number"?o:null,items:i,pending:[]}}const s=r[q];if(Array.isArray(s)){const i=f(n==null?void 0:n[T])?n[T]:{},o=f(n==null?void 0:n[x])?n[x]:{},a=f(n==null?void 0:n[I])?n[I]:{},l=Object.entries(i).map(([u,b])=>({itemKey:u,at:typeof o[u]=="string"?o[u]:"",...f(b)?{payload:b}:{},...typeof a[u]=="string"?{actor:a[u]}:{}})).sort(N),c=r[W];return{kind:"batch",count:l.length,max:Array.isArray(c)?c.length:null,items:l,pending:s.filter(u=>typeof u=="string")}}return null}function ot(t){if(!t)return"";const n=Object.entries(t).slice(0,3).map(([e,s])=>{const i=typeof s=="object"&&s!==null?JSON.stringify(s):String(s);return`${e}: ${i.length>24?`${i.slice(0,23)}…`:i}`}),r=Object.keys(t).length-n.length;return r>0?`${n.join(" · ")} · +${r}`:n.join(" · ")}const ct="x-lt-item-label",j=/\{\{\s*([^{}]+?)\s*\}\}/g,D="item",g="—";function z(t){if(t==null||t==="")return null;if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return String(t);try{return JSON.stringify(t)}catch{return null}}function L(t,n,r){const e=t.indexOf(".");if((e===-1?t:t.slice(0,e))===D)try{return z(e===-1?n:m(n,t.slice(e+1)))}catch{return null}const i=S(`{{${t}}}`,r);return i===g?null:i}function at(t,n,r={}){if(typeof t!="string"||!t.trim())return null;let e=0,s=0;const i=t.replace(j,(o,a)=>{s+=1;const l=L(a,n,r);return l===null?g:(e+=1,l)}).trim();return s>0&&e===0?null:i||null}function lt(t,n,r={}){return t.replace(j,(e,s)=>!n&&s.split(".")[0]===D?g:L(s,n??{},r)??g)}export{_ as E,et as F,R as H,ct as I,S as a,nt as b,v as c,rt as d,it as e,st as f,m as g,U as h,at as i,lt as j,h as k,tt as m,ot as s};
2
- //# sourceMappingURL=escalation-items-B6eDMoTN.js.map
1
+ import{j as d}from"./vendor-query-DvWWuNIB.js";import{a$ as M,bf as C,g as F}from"./index-ygxyAKcc.js";import{U as H}from"./UserName-DKXnK7DD.js";const $={LINK:"link",ESCALATION:"escalation",ESCALATION_LIST:"escalation-list",INVOKE:"invoke",ROSTER:"roster"},G=new Set(Object.values($));function U(t){return typeof t=="string"&&G.has(t)}function Y(t){return U(t==null?void 0:t["x-lt-widget"])}const w=new Set(["__proto__","constructor","prototype"]);function O(t){const n=[];for(const r of t.split(".")){const e=r.match(/^([^[\]]*)((?:\[\d+\])*)$/);if(!e)throw new Error(`invalid x-lt-bind path segment: "${r}"`);const[,s,i]=e;if(s){if(w.has(s))throw new Error(`x-lt-bind path may not target "${s}"`);n.push({key:s})}for(const o of i.match(/\d+/g)??[])n.push({index:Number(o)})}if(n.length===0)throw new Error(`empty x-lt-bind path: "${t}"`);return n}function B(t,n,r){const e=O(n);let s=t;for(let o=0;o<e.length-1;o++){const a=e[o],l=e[o+1],c="key"in a?a.key:a.index,u="index"in l;(s[c]==null||typeof s[c]!="object")&&(s[c]=u?[]:{}),s=s[c]}const i=e[e.length-1];s["key"in i?i.key:i.index]=r}function m(t,n){let r=t;for(const e of O(n)){if(r==null||typeof r!="object")return;r=r["key"in e?e.key:e.index]}return r}function k(t,n){const r=n==null?void 0:n["x-lt-bind"];return typeof r=="string"&&r.length>0?r:t}function v(t,n){const r=n==null?void 0:n.properties;if(!r)return{...t};const e={};for(const[s,i]of Object.entries(r))s in t&&(Y(i)||B(e,k(s,i),t[s]));return e}function tt(t,n){const r=n==null?void 0:n.properties;if(!r)return t?{...t}:{};const e={};for(const[s,i]of Object.entries(r)){const o=m(t,k(s,i));o!==void 0&&(e[s]=o)}return e}const R=["escalation","metadata","envelope","payload","resolver","lookup","input","roster"],K=/\{\{\s*([^{}]+?)\s*\}\}/g,p="—";function A(t){if(t==null)return p;if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return String(t);try{return JSON.stringify(t)}catch{return p}}function S(t,n){return t.replace(K,(r,e)=>{const s=e.indexOf("."),i=s===-1?e:e.slice(0,s);if(!R.includes(i))return p;const o=n[i];if(s===-1)return A(o);try{return A(m(o,e.slice(s+1)))}catch{return p}})}function P(t){const n=t==null?void 0:t["x-lt-help"];if(typeof n=="string"&&n.trim().length>0)return n;const r=t==null?void 0:t["x-lt-context"];return typeof r=="string"&&r.trim().length>0?r:null}function nt(t,n){const r=P(t);return r?S(r,n):null}function rt({isTerminal:t,status:n,claimed:r,claimedByMe:e}){return t?n==="cancelled"?"This escalation was cancelled. The record is shown for reference.":"This escalation has been resolved. The submitted form is shown for reference.":e?"You have claimed this escalation. Fill out the form and submit to resolve it.":r?"Another user has claimed this escalation. It unlocks if their claim expires or is released.":"Claim this escalation to enable the form."}const E=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/,_="—",y={AGE:"age",AGO:"ago",DATE:"date",USER:"user"};function h(t){return t===y.AGE||t===y.AGO}function et({raw:t,format:n}){if(!t||t===_)return d.jsx("span",{className:"text-text-quaternary",children:_});if(n===y.USER)return d.jsx(H,{userId:t,className:"block truncate"});const r=E.test(t)||!Number.isNaN(new Date(t).getTime())&&(h(n)||n===y.DATE);return h(n)&&r?d.jsx("span",{title:C(t),className:"tabular-nums whitespace-nowrap",children:M(t)}):r&&(n===y.DATE||E.test(t))?d.jsx(F,{date:t,format:"datetime",className:"text-text-primary whitespace-nowrap"}):d.jsx(d.Fragment,{children:t})}function st(t){if(!t)return!1;try{const n=JSON.stringify(t);return n.includes("envelope.")||n.includes("payload.")}catch{return!1}}const V="accumulate_items",J="accumulate_max",T="batch_items",x="batch_filled_at",I="batch_filled_by",W="batch_keys",q="batch_pending";function f(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function N(t,n){return t.at.localeCompare(n.at)||t.itemKey.localeCompare(n.itemKey)}function it(t,n){const r=t.metadata??{},e=n==null?void 0:n[V];if(f(e)){const i=Object.entries(e).map(([a,l])=>{const c=f(l)?l:{};return{itemKey:a,at:typeof c.at=="string"?c.at:"",...f(c.payload)?{payload:c.payload}:{},...typeof c.actor=="string"?{actor:c.actor}:{},...typeof c.reciprocalId=="string"?{reciprocalId:c.reciprocalId}:{}}}).sort(N),o=r[J];return{kind:"accumulate",count:i.length,max:typeof o=="number"?o:null,items:i,pending:[]}}const s=r[q];if(Array.isArray(s)){const i=f(n==null?void 0:n[T])?n[T]:{},o=f(n==null?void 0:n[x])?n[x]:{},a=f(n==null?void 0:n[I])?n[I]:{},l=Object.entries(i).map(([u,b])=>({itemKey:u,at:typeof o[u]=="string"?o[u]:"",...f(b)?{payload:b}:{},...typeof a[u]=="string"?{actor:a[u]}:{}})).sort(N),c=r[W];return{kind:"batch",count:l.length,max:Array.isArray(c)?c.length:null,items:l,pending:s.filter(u=>typeof u=="string")}}return null}function ot(t){if(!t)return"";const n=Object.entries(t).slice(0,3).map(([e,s])=>{const i=typeof s=="object"&&s!==null?JSON.stringify(s):String(s);return`${e}: ${i.length>24?`${i.slice(0,23)}…`:i}`}),r=Object.keys(t).length-n.length;return r>0?`${n.join(" · ")} · +${r}`:n.join(" · ")}const ct="x-lt-item-label",j=/\{\{\s*([^{}]+?)\s*\}\}/g,D="item",g="—";function z(t){if(t==null||t==="")return null;if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return String(t);try{return JSON.stringify(t)}catch{return null}}function L(t,n,r){const e=t.indexOf(".");if((e===-1?t:t.slice(0,e))===D)try{return z(e===-1?n:m(n,t.slice(e+1)))}catch{return null}const i=S(`{{${t}}}`,r);return i===g?null:i}function at(t,n,r={}){if(typeof t!="string"||!t.trim())return null;let e=0,s=0;const i=t.replace(j,(o,a)=>{s+=1;const l=L(a,n,r);return l===null?g:(e+=1,l)}).trim();return s>0&&e===0?null:i||null}function lt(t,n,r={}){return t.replace(j,(e,s)=>!n&&s.split(".")[0]===D?g:L(s,n??{},r)??g)}export{_ as E,et as F,R as H,ct as I,S as a,nt as b,v as c,rt as d,it as e,st as f,m as g,U as h,at as i,lt as j,h as k,tt as m,ot as s};
2
+ //# sourceMappingURL=escalation-items-DFGRwo49.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"escalation-items-B6eDMoTN.js","sources":["../../../shared/form-validation/display-only-widgets.ts","../../../shared/form-validation/x-lt-bind.ts","../../../shared/form-validation/x-lt-help.ts","../../src/components/common/display/FormattedValue.tsx","../../src/lib/schema-needs-envelope.ts","../../src/lib/escalation-items.ts"],"sourcesContent":["/**\n * Widgets that render from the escalation context and produce no answer of\n * their own: navigation links, embedded records and lists, and invoke\n * controls. Their form slot exists only to place them in the layout, so\n * the payload mapper drops them and the server never sees a value.\n */\nexport const DISPLAY_ONLY_WIDGET_NAMES = {\n LINK: 'link',\n ESCALATION: 'escalation',\n ESCALATION_LIST: 'escalation-list',\n INVOKE: 'invoke',\n ROSTER: 'roster',\n} as const;\n\nexport const DISPLAY_ONLY_WIDGETS: ReadonlySet<string> = new Set(Object.values(DISPLAY_ONLY_WIDGET_NAMES));\n\nexport function isDisplayOnlyWidget(name: unknown): boolean {\n return typeof name === 'string' && DISPLAY_ONLY_WIDGETS.has(name);\n}\n\n/** Whether a property definition renders a display-only widget. */\nexport function isDisplayOnlyField(def: Record<string, unknown> | null | undefined): boolean {\n return isDisplayOnlyWidget(def?.['x-lt-widget']);\n}\n","/**\n * x-lt-bind — maps the escalation FORM (flat field values the user edits) to and\n * from the PAYLOAD (the nested JSON the workflow consumes). A form_schema property\n * may declare `x-lt-bind: \"a.b[0].c\"`, the path its value occupies in the payload;\n * a property with no bind sits at its own name at the root (1:1). This module is\n * isomorphic — the dashboard renders forms with it, and the API layer inverts a\n * submitted payload through it to validate against the form contract. One\n * implementation, both sides.\n *\n * mapPayloadToForm — payload → flat form values, to PREFILL/display the form\n * (server-side: to validate a submitted payload)\n * mapFormToPayload — flat form values → payload, the shape submitted/stored\n */\nimport { isDisplayOnlyField } from './display-only-widgets';\n\ntype PathSeg = { key: string } | { index: number };\n\nconst BLOCKED_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/** Parse a bind path — dot keys with optional `[n]` indices. Rejects pollution keys. */\nexport function parsePath(path: string): PathSeg[] {\n const segs: PathSeg[] = [];\n for (const raw of path.split('.')) {\n const m = raw.match(/^([^[\\]]*)((?:\\[\\d+\\])*)$/);\n if (!m) throw new Error(`invalid x-lt-bind path segment: \"${raw}\"`);\n const [, name, brackets] = m;\n if (name) {\n if (BLOCKED_KEYS.has(name)) throw new Error(`x-lt-bind path may not target \"${name}\"`);\n segs.push({ key: name });\n }\n for (const b of brackets.match(/\\d+/g) ?? []) segs.push({ index: Number(b) });\n }\n if (segs.length === 0) throw new Error(`empty x-lt-bind path: \"${path}\"`);\n return segs;\n}\n\n/** Set `value` at `path` inside `root`, creating intermediate objects/arrays. */\nexport function setDeep(root: Record<string, any>, path: string, value: unknown): void {\n const segs = parsePath(path);\n let node: any = root;\n for (let i = 0; i < segs.length - 1; i++) {\n const seg = segs[i];\n const next = segs[i + 1];\n const childKey = 'key' in seg ? seg.key : seg.index;\n const wantArray = 'index' in next;\n if (node[childKey] == null || typeof node[childKey] !== 'object') {\n node[childKey] = wantArray ? [] : {};\n }\n node = node[childKey];\n }\n const last = segs[segs.length - 1];\n node['key' in last ? last.key : last.index] = value;\n}\n\n/** Read the value at `path` inside `root` (undefined if any segment is missing). */\nexport function getDeep(root: unknown, path: string): unknown {\n let node: any = root;\n for (const seg of parsePath(path)) {\n if (node == null || typeof node !== 'object') return undefined;\n node = node['key' in seg ? seg.key : seg.index];\n }\n return node;\n}\n\n/** The bind path for a form property (its `x-lt-bind`, or the property name). */\nexport function bindPathFor(propName: string, propDef: Record<string, any> | undefined): string {\n const bind = propDef?.['x-lt-bind'];\n return typeof bind === 'string' && bind.length > 0 ? bind : propName;\n}\n\n/**\n * Assemble the payload from the form's flat values. A field absent from\n * `formValues` is omitted (so clearing/deleting a field drops it from the\n * payload). Unknown keys not declared in the schema are dropped, and so are\n * display-only widget fields, which carry no answer. With no schema\n * properties, values pass through unchanged.\n */\nexport function mapFormToPayload(\n formValues: Record<string, any>,\n formSchema: Record<string, any> | null | undefined,\n): Record<string, any> {\n const props = formSchema?.properties as Record<string, any> | undefined;\n if (!props) return { ...formValues };\n const payload: Record<string, any> = {};\n for (const [name, def] of Object.entries(props)) {\n if (!(name in formValues)) continue;\n if (isDisplayOnlyField(def as Record<string, unknown>)) continue;\n setDeep(payload, bindPathFor(name, def as Record<string, any>), formValues[name]);\n }\n return payload;\n}\n\n/**\n * Reverse of {@link mapFormToPayload}: pull each form field's value out of the\n * payload via its bind path, to prefill/display the form. A field whose bound\n * path is missing from the payload is omitted (the caller falls back to the\n * schema default).\n */\nexport function mapPayloadToForm(\n payload: Record<string, any> | null | undefined,\n formSchema: Record<string, any> | null | undefined,\n): Record<string, any> {\n const props = formSchema?.properties as Record<string, any> | undefined;\n if (!props) return payload ? { ...payload } : {};\n const form: Record<string, any> = {};\n for (const [name, def] of Object.entries(props)) {\n const v = getDeep(payload, bindPathFor(name, def as Record<string, any>));\n if (v !== undefined) form[name] = v;\n }\n return form;\n}\n","/**\n * x-lt-help — the form's guidance content, rendered in the side panel beside\n * the resolve form. A form_schema may declare schema-level `x-lt-help`: a\n * markdown string whose `{{domain.path}}` tokens interpolate values from the\n * escalation surface, so help text can reference the live record:\n *\n * {{escalation.role}} — any column on the escalation row\n * {{metadata.schema_version}} — the row's metadata dict\n * {{envelope.formDefaults.customer.name}} — the workflow-sent input envelope\n * {{payload.category}} — the escalation context payload\n * {{resolver.notes}} — the submitted resolver payload\n * {{lookup.materials.items}} — versioned knowledge lookups pinned on the row\n * {{roster.orders.outstanding}} (a roster field's counts, x-lt-roster.ts)\n *\n * Paths reuse the x-lt-bind syntax (`a.b[0].c`). A missing value renders as an\n * em dash. `x-lt-context` is accepted as the plain-text fallback source when\n * `x-lt-help` is absent.\n */\nimport { getDeep } from './x-lt-bind';\n\n/** The token domains a help template may reference. `input` is the invoke-form name for the live values `resolver` also carries. */\nexport const HELP_DOMAINS = ['escalation', 'metadata', 'envelope', 'payload', 'resolver', 'lookup', 'input', 'roster'] as const;\nexport type HelpDomain = (typeof HELP_DOMAINS)[number];\n\nexport type HelpTokenContext = Partial<Record<HelpDomain, Record<string, unknown> | null>>;\n\nconst TOKEN_PATTERN = /\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g;\nconst MISSING_VALUE = '—';\n\nfunction formatTokenValue(value: unknown): string {\n if (value === undefined || value === null) return MISSING_VALUE;\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n try {\n return JSON.stringify(value);\n } catch {\n return MISSING_VALUE;\n }\n}\n\n/** Replace every `{{domain.path}}` token with its value from the context. */\nexport function interpolateHelp(template: string, ctx: HelpTokenContext): string {\n return template.replace(TOKEN_PATTERN, (_match, rawPath: string) => {\n const dot = rawPath.indexOf('.');\n const domain = (dot === -1 ? rawPath : rawPath.slice(0, dot)) as HelpDomain;\n if (!HELP_DOMAINS.includes(domain)) return MISSING_VALUE;\n const root = ctx[domain];\n if (dot === -1) return formatTokenValue(root);\n try {\n return formatTokenValue(getDeep(root, rawPath.slice(dot + 1)));\n } catch {\n return MISSING_VALUE;\n }\n });\n}\n\n/** The schema's help source: `x-lt-help` first, `x-lt-context` as fallback. */\nexport function resolveHelpSource(schema: Record<string, unknown> | null | undefined): string | null {\n const help = schema?.['x-lt-help'];\n if (typeof help === 'string' && help.trim().length > 0) return help;\n const context = schema?.['x-lt-context'];\n if (typeof context === 'string' && context.trim().length > 0) return context;\n return null;\n}\n\n/** The schema's help content, interpolated. Null when the schema declares none. */\nexport function buildHelpMarkdown(\n schema: Record<string, unknown> | null | undefined,\n ctx: HelpTokenContext,\n): string | null {\n const source = resolveHelpSource(schema);\n return source ? interpolateHelp(source, ctx) : null;\n}\n\nexport interface HelpStateHint {\n isTerminal: boolean;\n status?: string;\n claimed: boolean;\n claimedByMe: boolean;\n}\n\n/**\n * State-aware guidance shown when the schema carries no help content — the\n * panel always tells the user what this page expects of them right now.\n */\nexport function defaultHelpMarkdown({ isTerminal, status, claimed, claimedByMe }: HelpStateHint): string {\n if (isTerminal) {\n return status === 'cancelled'\n ? 'This escalation was cancelled. The record is shown for reference.'\n : 'This escalation has been resolved. The submitted form is shown for reference.';\n }\n if (claimedByMe) return 'You have claimed this escalation. Fill out the form and submit to resolve it.';\n if (claimed) return 'Another user has claimed this escalation. It unlocks if their claim expires or is released.';\n return 'Claim this escalation to enable the form.';\n}\n","import { DateValue } from './DateValue';\nimport { UserName } from './UserName';\nimport { formatAgoCompact } from '../../../lib/format';\nimport { formatDisplayDateTime } from '../../../lib/display-zone';\n\nconst ISO_DATETIME = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}/;\nexport const EM_DASH = '—';\n\n/** Value formats an author may name on a column, card field, or fact. `ago` is the spoken form of `age`. */\nexport const FIELD_FORMATS = {\n AGE: 'age',\n AGO: 'ago',\n DATE: 'date',\n USER: 'user',\n} as const;\n\n/** True when the format renders as an age that ages with the clock. */\nexport function isAgeFormat(format?: string): boolean {\n return format === FIELD_FORMATS.AGE || format === FIELD_FORMATS.AGO;\n}\n\n/**\n * Render a value with a little care: `age`/`ago` turns a timestamp into a\n * compact age (\"12m\", \"3h\") with the absolute time as its tooltip; `date`\n * renders the full date, hoverable, and so does any ISO datetime with no\n * format; `user` resolves a user id to a display name; an empty value a quiet\n * em dash; anything else plain text.\n */\nexport function FormattedValue({ raw, format }: { raw: string; format?: string }) {\n if (!raw || raw === EM_DASH) return <span className=\"text-text-quaternary\">{EM_DASH}</span>;\n if (format === FIELD_FORMATS.USER) return <UserName userId={raw} className=\"block truncate\" />;\n const isDate = ISO_DATETIME.test(raw) || !Number.isNaN(new Date(raw).getTime()) && (isAgeFormat(format) || format === FIELD_FORMATS.DATE);\n if (isAgeFormat(format) && isDate) {\n return <span title={formatDisplayDateTime(raw)} className=\"tabular-nums whitespace-nowrap\">{formatAgoCompact(raw)}</span>;\n }\n if (isDate && (format === FIELD_FORMATS.DATE || ISO_DATETIME.test(raw))) {\n return <DateValue date={raw} format=\"datetime\" className=\"text-text-primary whitespace-nowrap\" />;\n }\n return <>{raw}</>;\n}\n","/**\n * List rows arrive without the heavyweight `envelope`/`escalation_payload`\n * columns by default. A surface driven by an x-lt schema fragment opts back in\n * only when the fragment actually interpolates those domains — `envelope.` or\n * `payload.` in any token, condition, or source path. `metadata.` and\n * `resolver.` ride the slim rows and never trigger the opt-in.\n */\nexport function schemaNeedsEnvelope(fragment: unknown): boolean {\n if (!fragment) return false;\n try {\n const s = JSON.stringify(fragment);\n return s.includes('envelope.') || s.includes('payload.');\n } catch {\n return false;\n }\n}\n","import type { LTEscalationRecord } from '../api/types';\nimport { interpolateHelp, type HelpTokenContext } from './x-lt-help';\nimport { getDeep } from './x-lt-bind';\n\n/** One held item of an accumulator or batch row, in the shape the workflow receives. */\nexport interface EscalationItem {\n itemKey: string;\n payload?: Record<string, unknown>;\n /** ISO-8601 from the database clock; empty for a batch item with no stamp. */\n at: string;\n actor?: string;\n reciprocalId?: string;\n}\n\nexport interface EscalationItems {\n kind: 'accumulate' | 'batch';\n count: number;\n /** The count trigger (accumulate) or the declared size (batch); null when unbounded. */\n max: number | null;\n items: EscalationItem[];\n /** Batch only: declared keys still awaiting submission. */\n pending: string[];\n}\n\nconst ACCUMULATE_ITEMS = 'accumulate_items';\nconst ACCUMULATE_MAX = 'accumulate_max';\nconst BATCH_ITEMS = 'batch_items';\nconst BATCH_FILLED_AT = 'batch_filled_at';\nconst BATCH_FILLED_BY = 'batch_filled_by';\nconst BATCH_KEYS = 'batch_keys';\nconst BATCH_PENDING = 'batch_pending';\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return !!v && typeof v === 'object' && !Array.isArray(v);\n}\n\nfunction byArrival(a: EscalationItem, b: EscalationItem): number {\n return a.at.localeCompare(b.at) || a.itemKey.localeCompare(b.itemKey);\n}\n\n/**\n * The held items of a row, or null when the row is neither an accumulator\n * nor a batch. Mirrors the server's items view so the panel and the API\n * agree on order (arrival, then key).\n */\nexport function escalationItems(\n esc: Pick<LTEscalationRecord, 'metadata'>,\n envelope: Record<string, unknown> | null,\n): EscalationItems | null {\n const metadata = (esc.metadata ?? {}) as Record<string, unknown>;\n const store = envelope?.[ACCUMULATE_ITEMS];\n if (isRecord(store)) {\n const items = Object.entries(store).map(([itemKey, entry]) => {\n const e = isRecord(entry) ? entry : {};\n return {\n itemKey,\n at: typeof e.at === 'string' ? e.at : '',\n ...(isRecord(e.payload) ? { payload: e.payload } : {}),\n ...(typeof e.actor === 'string' ? { actor: e.actor } : {}),\n ...(typeof e.reciprocalId === 'string' ? { reciprocalId: e.reciprocalId } : {}),\n } as EscalationItem;\n }).sort(byArrival);\n const max = metadata[ACCUMULATE_MAX];\n return { kind: 'accumulate', count: items.length, max: typeof max === 'number' ? max : null, items, pending: [] };\n }\n const pending = metadata[BATCH_PENDING];\n if (Array.isArray(pending)) {\n const filled = isRecord(envelope?.[BATCH_ITEMS]) ? (envelope![BATCH_ITEMS] as Record<string, unknown>) : {};\n const stamps = isRecord(envelope?.[BATCH_FILLED_AT]) ? (envelope![BATCH_FILLED_AT] as Record<string, unknown>) : {};\n const actors = isRecord(envelope?.[BATCH_FILLED_BY]) ? (envelope![BATCH_FILLED_BY] as Record<string, unknown>) : {};\n const items = Object.entries(filled).map(([itemKey, payload]) => ({\n itemKey,\n at: typeof stamps[itemKey] === 'string' ? (stamps[itemKey] as string) : '',\n ...(isRecord(payload) ? { payload } : {}),\n ...(typeof actors[itemKey] === 'string' ? { actor: actors[itemKey] as string } : {}),\n } as EscalationItem)).sort(byArrival);\n const keys = metadata[BATCH_KEYS];\n return {\n kind: 'batch',\n count: items.length,\n max: Array.isArray(keys) ? keys.length : null,\n items,\n pending: pending.filter((k): k is string => typeof k === 'string'),\n };\n }\n return null;\n}\n\n/** A one-line summary of an item payload for the list row. */\nexport function summarizePayload(payload: Record<string, unknown> | undefined): string {\n if (!payload) return '';\n const parts = Object.entries(payload).slice(0, 3).map(([k, v]) => {\n const text = typeof v === 'object' && v !== null ? JSON.stringify(v) : String(v);\n return `${k}: ${text.length > 24 ? `${text.slice(0, 23)}…` : text}`;\n });\n const more = Object.keys(payload).length - parts.length;\n return more > 0 ? `${parts.join(' · ')} · +${more}` : parts.join(' · ');\n}\n\n/** The container role's form-schema key naming how each held item displays. */\nexport const ITEM_LABEL_KEY = 'x-lt-item-label';\n\nconst TOKEN = /\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g;\nconst ITEM_DOMAIN = 'item';\nconst MISSING = '—';\n\nfunction formatValue(value: unknown): string | null {\n if (value === undefined || value === null || value === '') return null;\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n try {\n return JSON.stringify(value);\n } catch {\n return null;\n }\n}\n\n/** One token's value: `item.*` from the held item, every other domain as help tokens resolve it. */\nfunction tokenValue(path: string, item: EscalationItem, ctx: HelpTokenContext): string | null {\n const dot = path.indexOf('.');\n const domain = dot === -1 ? path : path.slice(0, dot);\n if (domain === ITEM_DOMAIN) {\n try {\n return formatValue(dot === -1 ? item : getDeep(item, path.slice(dot + 1)));\n } catch {\n return null;\n }\n }\n const value = interpolateHelp(`{{${path}}}`, ctx);\n return value === MISSING ? null : value;\n}\n\n/**\n * An item's display label from the role's `x-lt-item-label` template, whose\n * `{{item.*}}` tokens read the held item (itemKey, payload, actor, at) beside\n * the usual escalation domains. Null when there is no template or every token\n * it names is missing, so the caller falls back to the item key.\n */\nexport function itemLabel(\n template: unknown,\n item: EscalationItem,\n ctx: HelpTokenContext = {},\n): string | null {\n if (typeof template !== 'string' || !template.trim()) return null;\n let resolved = 0;\n let tokens = 0;\n const label = template.replace(TOKEN, (_match, rawPath: string) => {\n tokens += 1;\n const value = tokenValue(rawPath, item, ctx);\n if (value === null) return MISSING;\n resolved += 1;\n return value;\n }).trim();\n if (tokens > 0 && resolved === 0) return null;\n return label || null;\n}\n\n/** A template over `{{item.*}}` and the escalation domains; missing tokens read as an em dash. */\nexport function interpolateItemTemplate(template: string, item: EscalationItem | undefined, ctx: HelpTokenContext = {}): string {\n return template.replace(TOKEN, (_match, rawPath: string) => {\n if (!item && rawPath.split('.')[0] === ITEM_DOMAIN) return MISSING;\n return tokenValue(rawPath, item ?? ({} as EscalationItem), ctx) ?? MISSING;\n });\n}\n"],"names":["DISPLAY_ONLY_WIDGET_NAMES","DISPLAY_ONLY_WIDGETS","isDisplayOnlyWidget","name","isDisplayOnlyField","def","BLOCKED_KEYS","parsePath","path","segs","raw","m","brackets","b","setDeep","root","value","node","i","seg","next","childKey","wantArray","last","getDeep","bindPathFor","propName","propDef","bind","mapFormToPayload","formValues","formSchema","props","payload","mapPayloadToForm","form","v","HELP_DOMAINS","TOKEN_PATTERN","MISSING_VALUE","formatTokenValue","interpolateHelp","template","ctx","_match","rawPath","dot","domain","resolveHelpSource","schema","help","context","buildHelpMarkdown","source","defaultHelpMarkdown","isTerminal","status","claimed","claimedByMe","ISO_DATETIME","EM_DASH","FIELD_FORMATS","isAgeFormat","format","FormattedValue","jsx","UserName","isDate","formatDisplayDateTime","formatAgoCompact","DateValue","schemaNeedsEnvelope","fragment","s","ACCUMULATE_ITEMS","ACCUMULATE_MAX","BATCH_ITEMS","BATCH_FILLED_AT","BATCH_FILLED_BY","BATCH_KEYS","BATCH_PENDING","isRecord","byArrival","a","escalationItems","esc","envelope","metadata","store","items","itemKey","entry","e","max","pending","filled","stamps","actors","keys","k","summarizePayload","parts","text","more","ITEM_LABEL_KEY","TOKEN","ITEM_DOMAIN","MISSING","formatValue","tokenValue","item","itemLabel","resolved","tokens","label","interpolateItemTemplate"],"mappings":"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"}
1
+ {"version":3,"file":"escalation-items-DFGRwo49.js","sources":["../../../shared/form-validation/display-only-widgets.ts","../../../shared/form-validation/x-lt-bind.ts","../../../shared/form-validation/x-lt-help.ts","../../src/components/common/display/FormattedValue.tsx","../../src/lib/schema-needs-envelope.ts","../../src/lib/escalation-items.ts"],"sourcesContent":["/**\n * Widgets that render from the escalation context and produce no answer of\n * their own: navigation links, embedded records and lists, and invoke\n * controls. Their form slot exists only to place them in the layout, so\n * the payload mapper drops them and the server never sees a value.\n */\nexport const DISPLAY_ONLY_WIDGET_NAMES = {\n LINK: 'link',\n ESCALATION: 'escalation',\n ESCALATION_LIST: 'escalation-list',\n INVOKE: 'invoke',\n ROSTER: 'roster',\n} as const;\n\nexport const DISPLAY_ONLY_WIDGETS: ReadonlySet<string> = new Set(Object.values(DISPLAY_ONLY_WIDGET_NAMES));\n\nexport function isDisplayOnlyWidget(name: unknown): boolean {\n return typeof name === 'string' && DISPLAY_ONLY_WIDGETS.has(name);\n}\n\n/** Whether a property definition renders a display-only widget. */\nexport function isDisplayOnlyField(def: Record<string, unknown> | null | undefined): boolean {\n return isDisplayOnlyWidget(def?.['x-lt-widget']);\n}\n","/**\n * x-lt-bind — maps the escalation FORM (flat field values the user edits) to and\n * from the PAYLOAD (the nested JSON the workflow consumes). A form_schema property\n * may declare `x-lt-bind: \"a.b[0].c\"`, the path its value occupies in the payload;\n * a property with no bind sits at its own name at the root (1:1). This module is\n * isomorphic — the dashboard renders forms with it, and the API layer inverts a\n * submitted payload through it to validate against the form contract. One\n * implementation, both sides.\n *\n * mapPayloadToForm — payload → flat form values, to PREFILL/display the form\n * (server-side: to validate a submitted payload)\n * mapFormToPayload — flat form values → payload, the shape submitted/stored\n */\nimport { isDisplayOnlyField } from './display-only-widgets';\n\ntype PathSeg = { key: string } | { index: number };\n\nconst BLOCKED_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/** Parse a bind path — dot keys with optional `[n]` indices. Rejects pollution keys. */\nexport function parsePath(path: string): PathSeg[] {\n const segs: PathSeg[] = [];\n for (const raw of path.split('.')) {\n const m = raw.match(/^([^[\\]]*)((?:\\[\\d+\\])*)$/);\n if (!m) throw new Error(`invalid x-lt-bind path segment: \"${raw}\"`);\n const [, name, brackets] = m;\n if (name) {\n if (BLOCKED_KEYS.has(name)) throw new Error(`x-lt-bind path may not target \"${name}\"`);\n segs.push({ key: name });\n }\n for (const b of brackets.match(/\\d+/g) ?? []) segs.push({ index: Number(b) });\n }\n if (segs.length === 0) throw new Error(`empty x-lt-bind path: \"${path}\"`);\n return segs;\n}\n\n/** Set `value` at `path` inside `root`, creating intermediate objects/arrays. */\nexport function setDeep(root: Record<string, any>, path: string, value: unknown): void {\n const segs = parsePath(path);\n let node: any = root;\n for (let i = 0; i < segs.length - 1; i++) {\n const seg = segs[i];\n const next = segs[i + 1];\n const childKey = 'key' in seg ? seg.key : seg.index;\n const wantArray = 'index' in next;\n if (node[childKey] == null || typeof node[childKey] !== 'object') {\n node[childKey] = wantArray ? [] : {};\n }\n node = node[childKey];\n }\n const last = segs[segs.length - 1];\n node['key' in last ? last.key : last.index] = value;\n}\n\n/** Read the value at `path` inside `root` (undefined if any segment is missing). */\nexport function getDeep(root: unknown, path: string): unknown {\n let node: any = root;\n for (const seg of parsePath(path)) {\n if (node == null || typeof node !== 'object') return undefined;\n node = node['key' in seg ? seg.key : seg.index];\n }\n return node;\n}\n\n/** The bind path for a form property (its `x-lt-bind`, or the property name). */\nexport function bindPathFor(propName: string, propDef: Record<string, any> | undefined): string {\n const bind = propDef?.['x-lt-bind'];\n return typeof bind === 'string' && bind.length > 0 ? bind : propName;\n}\n\n/**\n * Assemble the payload from the form's flat values. A field absent from\n * `formValues` is omitted (so clearing/deleting a field drops it from the\n * payload). Unknown keys not declared in the schema are dropped, and so are\n * display-only widget fields, which carry no answer. With no schema\n * properties, values pass through unchanged.\n */\nexport function mapFormToPayload(\n formValues: Record<string, any>,\n formSchema: Record<string, any> | null | undefined,\n): Record<string, any> {\n const props = formSchema?.properties as Record<string, any> | undefined;\n if (!props) return { ...formValues };\n const payload: Record<string, any> = {};\n for (const [name, def] of Object.entries(props)) {\n if (!(name in formValues)) continue;\n if (isDisplayOnlyField(def as Record<string, unknown>)) continue;\n setDeep(payload, bindPathFor(name, def as Record<string, any>), formValues[name]);\n }\n return payload;\n}\n\n/**\n * Reverse of {@link mapFormToPayload}: pull each form field's value out of the\n * payload via its bind path, to prefill/display the form. A field whose bound\n * path is missing from the payload is omitted (the caller falls back to the\n * schema default).\n */\nexport function mapPayloadToForm(\n payload: Record<string, any> | null | undefined,\n formSchema: Record<string, any> | null | undefined,\n): Record<string, any> {\n const props = formSchema?.properties as Record<string, any> | undefined;\n if (!props) return payload ? { ...payload } : {};\n const form: Record<string, any> = {};\n for (const [name, def] of Object.entries(props)) {\n const v = getDeep(payload, bindPathFor(name, def as Record<string, any>));\n if (v !== undefined) form[name] = v;\n }\n return form;\n}\n","/**\n * x-lt-help — the form's guidance content, rendered in the side panel beside\n * the resolve form. A form_schema may declare schema-level `x-lt-help`: a\n * markdown string whose `{{domain.path}}` tokens interpolate values from the\n * escalation surface, so help text can reference the live record:\n *\n * {{escalation.role}} — any column on the escalation row\n * {{metadata.schema_version}} — the row's metadata dict\n * {{envelope.formDefaults.customer.name}} — the workflow-sent input envelope\n * {{payload.category}} — the escalation context payload\n * {{resolver.notes}} — the submitted resolver payload\n * {{lookup.materials.items}} — versioned knowledge lookups pinned on the row\n * {{roster.orders.outstanding}} (a roster field's counts, x-lt-roster.ts)\n *\n * Paths reuse the x-lt-bind syntax (`a.b[0].c`). A missing value renders as an\n * em dash. `x-lt-context` is accepted as the plain-text fallback source when\n * `x-lt-help` is absent.\n */\nimport { getDeep } from './x-lt-bind';\n\n/** The token domains a help template may reference. `input` is the invoke-form name for the live values `resolver` also carries. */\nexport const HELP_DOMAINS = ['escalation', 'metadata', 'envelope', 'payload', 'resolver', 'lookup', 'input', 'roster'] as const;\nexport type HelpDomain = (typeof HELP_DOMAINS)[number];\n\nexport type HelpTokenContext = Partial<Record<HelpDomain, Record<string, unknown> | null>>;\n\nconst TOKEN_PATTERN = /\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g;\nconst MISSING_VALUE = '—';\n\nfunction formatTokenValue(value: unknown): string {\n if (value === undefined || value === null) return MISSING_VALUE;\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n try {\n return JSON.stringify(value);\n } catch {\n return MISSING_VALUE;\n }\n}\n\n/** Replace every `{{domain.path}}` token with its value from the context. */\nexport function interpolateHelp(template: string, ctx: HelpTokenContext): string {\n return template.replace(TOKEN_PATTERN, (_match, rawPath: string) => {\n const dot = rawPath.indexOf('.');\n const domain = (dot === -1 ? rawPath : rawPath.slice(0, dot)) as HelpDomain;\n if (!HELP_DOMAINS.includes(domain)) return MISSING_VALUE;\n const root = ctx[domain];\n if (dot === -1) return formatTokenValue(root);\n try {\n return formatTokenValue(getDeep(root, rawPath.slice(dot + 1)));\n } catch {\n return MISSING_VALUE;\n }\n });\n}\n\n/** The schema's help source: `x-lt-help` first, `x-lt-context` as fallback. */\nexport function resolveHelpSource(schema: Record<string, unknown> | null | undefined): string | null {\n const help = schema?.['x-lt-help'];\n if (typeof help === 'string' && help.trim().length > 0) return help;\n const context = schema?.['x-lt-context'];\n if (typeof context === 'string' && context.trim().length > 0) return context;\n return null;\n}\n\n/** The schema's help content, interpolated. Null when the schema declares none. */\nexport function buildHelpMarkdown(\n schema: Record<string, unknown> | null | undefined,\n ctx: HelpTokenContext,\n): string | null {\n const source = resolveHelpSource(schema);\n return source ? interpolateHelp(source, ctx) : null;\n}\n\nexport interface HelpStateHint {\n isTerminal: boolean;\n status?: string;\n claimed: boolean;\n claimedByMe: boolean;\n}\n\n/**\n * State-aware guidance shown when the schema carries no help content — the\n * panel always tells the user what this page expects of them right now.\n */\nexport function defaultHelpMarkdown({ isTerminal, status, claimed, claimedByMe }: HelpStateHint): string {\n if (isTerminal) {\n return status === 'cancelled'\n ? 'This escalation was cancelled. The record is shown for reference.'\n : 'This escalation has been resolved. The submitted form is shown for reference.';\n }\n if (claimedByMe) return 'You have claimed this escalation. Fill out the form and submit to resolve it.';\n if (claimed) return 'Another user has claimed this escalation. It unlocks if their claim expires or is released.';\n return 'Claim this escalation to enable the form.';\n}\n","import { DateValue } from './DateValue';\nimport { UserName } from './UserName';\nimport { formatAgoCompact } from '../../../lib/format';\nimport { formatDisplayDateTime } from '../../../lib/display-zone';\n\nconst ISO_DATETIME = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}/;\nexport const EM_DASH = '—';\n\n/** Value formats an author may name on a column, card field, or fact. `ago` is the spoken form of `age`. */\nexport const FIELD_FORMATS = {\n AGE: 'age',\n AGO: 'ago',\n DATE: 'date',\n USER: 'user',\n} as const;\n\n/** True when the format renders as an age that ages with the clock. */\nexport function isAgeFormat(format?: string): boolean {\n return format === FIELD_FORMATS.AGE || format === FIELD_FORMATS.AGO;\n}\n\n/**\n * Render a value with a little care: `age`/`ago` turns a timestamp into a\n * compact age (\"12m\", \"3h\") with the absolute time as its tooltip; `date`\n * renders the full date, hoverable, and so does any ISO datetime with no\n * format; `user` resolves a user id to a display name; an empty value a quiet\n * em dash; anything else plain text.\n */\nexport function FormattedValue({ raw, format }: { raw: string; format?: string }) {\n if (!raw || raw === EM_DASH) return <span className=\"text-text-quaternary\">{EM_DASH}</span>;\n if (format === FIELD_FORMATS.USER) return <UserName userId={raw} className=\"block truncate\" />;\n const isDate = ISO_DATETIME.test(raw) || !Number.isNaN(new Date(raw).getTime()) && (isAgeFormat(format) || format === FIELD_FORMATS.DATE);\n if (isAgeFormat(format) && isDate) {\n return <span title={formatDisplayDateTime(raw)} className=\"tabular-nums whitespace-nowrap\">{formatAgoCompact(raw)}</span>;\n }\n if (isDate && (format === FIELD_FORMATS.DATE || ISO_DATETIME.test(raw))) {\n return <DateValue date={raw} format=\"datetime\" className=\"text-text-primary whitespace-nowrap\" />;\n }\n return <>{raw}</>;\n}\n","/**\n * List rows arrive without the heavyweight `envelope`/`escalation_payload`\n * columns by default. A surface driven by an x-lt schema fragment opts back in\n * only when the fragment actually interpolates those domains — `envelope.` or\n * `payload.` in any token, condition, or source path. `metadata.` and\n * `resolver.` ride the slim rows and never trigger the opt-in.\n */\nexport function schemaNeedsEnvelope(fragment: unknown): boolean {\n if (!fragment) return false;\n try {\n const s = JSON.stringify(fragment);\n return s.includes('envelope.') || s.includes('payload.');\n } catch {\n return false;\n }\n}\n","import type { LTEscalationRecord } from '../api/types';\nimport { interpolateHelp, type HelpTokenContext } from './x-lt-help';\nimport { getDeep } from './x-lt-bind';\n\n/** One held item of an accumulator or batch row, in the shape the workflow receives. */\nexport interface EscalationItem {\n itemKey: string;\n payload?: Record<string, unknown>;\n /** ISO-8601 from the database clock; empty for a batch item with no stamp. */\n at: string;\n actor?: string;\n reciprocalId?: string;\n}\n\nexport interface EscalationItems {\n kind: 'accumulate' | 'batch';\n count: number;\n /** The count trigger (accumulate) or the declared size (batch); null when unbounded. */\n max: number | null;\n items: EscalationItem[];\n /** Batch only: declared keys still awaiting submission. */\n pending: string[];\n}\n\nconst ACCUMULATE_ITEMS = 'accumulate_items';\nconst ACCUMULATE_MAX = 'accumulate_max';\nconst BATCH_ITEMS = 'batch_items';\nconst BATCH_FILLED_AT = 'batch_filled_at';\nconst BATCH_FILLED_BY = 'batch_filled_by';\nconst BATCH_KEYS = 'batch_keys';\nconst BATCH_PENDING = 'batch_pending';\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return !!v && typeof v === 'object' && !Array.isArray(v);\n}\n\nfunction byArrival(a: EscalationItem, b: EscalationItem): number {\n return a.at.localeCompare(b.at) || a.itemKey.localeCompare(b.itemKey);\n}\n\n/**\n * The held items of a row, or null when the row is neither an accumulator\n * nor a batch. Mirrors the server's items view so the panel and the API\n * agree on order (arrival, then key).\n */\nexport function escalationItems(\n esc: Pick<LTEscalationRecord, 'metadata'>,\n envelope: Record<string, unknown> | null,\n): EscalationItems | null {\n const metadata = (esc.metadata ?? {}) as Record<string, unknown>;\n const store = envelope?.[ACCUMULATE_ITEMS];\n if (isRecord(store)) {\n const items = Object.entries(store).map(([itemKey, entry]) => {\n const e = isRecord(entry) ? entry : {};\n return {\n itemKey,\n at: typeof e.at === 'string' ? e.at : '',\n ...(isRecord(e.payload) ? { payload: e.payload } : {}),\n ...(typeof e.actor === 'string' ? { actor: e.actor } : {}),\n ...(typeof e.reciprocalId === 'string' ? { reciprocalId: e.reciprocalId } : {}),\n } as EscalationItem;\n }).sort(byArrival);\n const max = metadata[ACCUMULATE_MAX];\n return { kind: 'accumulate', count: items.length, max: typeof max === 'number' ? max : null, items, pending: [] };\n }\n const pending = metadata[BATCH_PENDING];\n if (Array.isArray(pending)) {\n const filled = isRecord(envelope?.[BATCH_ITEMS]) ? (envelope![BATCH_ITEMS] as Record<string, unknown>) : {};\n const stamps = isRecord(envelope?.[BATCH_FILLED_AT]) ? (envelope![BATCH_FILLED_AT] as Record<string, unknown>) : {};\n const actors = isRecord(envelope?.[BATCH_FILLED_BY]) ? (envelope![BATCH_FILLED_BY] as Record<string, unknown>) : {};\n const items = Object.entries(filled).map(([itemKey, payload]) => ({\n itemKey,\n at: typeof stamps[itemKey] === 'string' ? (stamps[itemKey] as string) : '',\n ...(isRecord(payload) ? { payload } : {}),\n ...(typeof actors[itemKey] === 'string' ? { actor: actors[itemKey] as string } : {}),\n } as EscalationItem)).sort(byArrival);\n const keys = metadata[BATCH_KEYS];\n return {\n kind: 'batch',\n count: items.length,\n max: Array.isArray(keys) ? keys.length : null,\n items,\n pending: pending.filter((k): k is string => typeof k === 'string'),\n };\n }\n return null;\n}\n\n/** A one-line summary of an item payload for the list row. */\nexport function summarizePayload(payload: Record<string, unknown> | undefined): string {\n if (!payload) return '';\n const parts = Object.entries(payload).slice(0, 3).map(([k, v]) => {\n const text = typeof v === 'object' && v !== null ? JSON.stringify(v) : String(v);\n return `${k}: ${text.length > 24 ? `${text.slice(0, 23)}…` : text}`;\n });\n const more = Object.keys(payload).length - parts.length;\n return more > 0 ? `${parts.join(' · ')} · +${more}` : parts.join(' · ');\n}\n\n/** The container role's form-schema key naming how each held item displays. */\nexport const ITEM_LABEL_KEY = 'x-lt-item-label';\n\nconst TOKEN = /\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g;\nconst ITEM_DOMAIN = 'item';\nconst MISSING = '—';\n\nfunction formatValue(value: unknown): string | null {\n if (value === undefined || value === null || value === '') return null;\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n try {\n return JSON.stringify(value);\n } catch {\n return null;\n }\n}\n\n/** One token's value: `item.*` from the held item, every other domain as help tokens resolve it. */\nfunction tokenValue(path: string, item: EscalationItem, ctx: HelpTokenContext): string | null {\n const dot = path.indexOf('.');\n const domain = dot === -1 ? path : path.slice(0, dot);\n if (domain === ITEM_DOMAIN) {\n try {\n return formatValue(dot === -1 ? item : getDeep(item, path.slice(dot + 1)));\n } catch {\n return null;\n }\n }\n const value = interpolateHelp(`{{${path}}}`, ctx);\n return value === MISSING ? null : value;\n}\n\n/**\n * An item's display label from the role's `x-lt-item-label` template, whose\n * `{{item.*}}` tokens read the held item (itemKey, payload, actor, at) beside\n * the usual escalation domains. Null when there is no template or every token\n * it names is missing, so the caller falls back to the item key.\n */\nexport function itemLabel(\n template: unknown,\n item: EscalationItem,\n ctx: HelpTokenContext = {},\n): string | null {\n if (typeof template !== 'string' || !template.trim()) return null;\n let resolved = 0;\n let tokens = 0;\n const label = template.replace(TOKEN, (_match, rawPath: string) => {\n tokens += 1;\n const value = tokenValue(rawPath, item, ctx);\n if (value === null) return MISSING;\n resolved += 1;\n return value;\n }).trim();\n if (tokens > 0 && resolved === 0) return null;\n return label || null;\n}\n\n/** A template over `{{item.*}}` and the escalation domains; missing tokens read as an em dash. */\nexport function interpolateItemTemplate(template: string, item: EscalationItem | undefined, ctx: HelpTokenContext = {}): string {\n return template.replace(TOKEN, (_match, rawPath: string) => {\n if (!item && rawPath.split('.')[0] === ITEM_DOMAIN) return MISSING;\n return tokenValue(rawPath, item ?? ({} as EscalationItem), ctx) ?? MISSING;\n });\n}\n"],"names":["DISPLAY_ONLY_WIDGET_NAMES","DISPLAY_ONLY_WIDGETS","isDisplayOnlyWidget","name","isDisplayOnlyField","def","BLOCKED_KEYS","parsePath","path","segs","raw","m","brackets","b","setDeep","root","value","node","i","seg","next","childKey","wantArray","last","getDeep","bindPathFor","propName","propDef","bind","mapFormToPayload","formValues","formSchema","props","payload","mapPayloadToForm","form","v","HELP_DOMAINS","TOKEN_PATTERN","MISSING_VALUE","formatTokenValue","interpolateHelp","template","ctx","_match","rawPath","dot","domain","resolveHelpSource","schema","help","context","buildHelpMarkdown","source","defaultHelpMarkdown","isTerminal","status","claimed","claimedByMe","ISO_DATETIME","EM_DASH","FIELD_FORMATS","isAgeFormat","format","FormattedValue","jsx","UserName","isDate","formatDisplayDateTime","formatAgoCompact","DateValue","schemaNeedsEnvelope","fragment","s","ACCUMULATE_ITEMS","ACCUMULATE_MAX","BATCH_ITEMS","BATCH_FILLED_AT","BATCH_FILLED_BY","BATCH_KEYS","BATCH_PENDING","isRecord","byArrival","a","escalationItems","esc","envelope","metadata","store","items","itemKey","entry","e","max","pending","filled","stamps","actors","keys","k","summarizePayload","parts","text","more","ITEM_LABEL_KEY","TOKEN","ITEM_DOMAIN","MISSING","formatValue","tokenValue","item","itemLabel","resolved","tokens","label","interpolateItemTemplate"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{a as n,j as s}from"./vendor-query-DvWWuNIB.js";import{aI as h,e as g}from"./index-xycFf66M.js";import{D as y}from"./DataTable-FjFhx0SE.js";import{F as C,b as j}from"./FilterBar-ByZiD0ty.js";import{R as q,a as u}from"./RowActions-Bdd7z4eB.js";import{u as R}from"./useFilterParams-DBRw1Hcv.js";import{P as b}from"./PageHeader-DiGWAQlR.js";import{T as _}from"./TaskQueuePill-sUA1nZe-.js";import{W as N}from"./WorkflowPill-CKHip3hH.js";import{aB as v,E as I,h as S}from"./vendor-icons-en0_uSRD.js";import{u as E}from"./vendor-react-_9U4mKFr.js";import"./EmptyState-DgC_6njU.js";import"./useContainerWidth-DSLp1gEm.js";function G(){const r=E(),{data:c,isLoading:m}=h(),{filters:t,setFilter:i}=R({filters:{search:"",queue:""}}),[a,p]=n.useState(t.search);n.useEffect(()=>{if(a===t.search)return;const e=setTimeout(()=>i("search",a),g);return()=>clearTimeout(e)},[a,i,t.search]);const o=c??[],d=n.useMemo(()=>[...new Set(o.map(e=>e.task_queue).filter(Boolean))].sort(),[o]),f=n.useMemo(()=>{let e=o;if(t.search){const l=t.search.toLowerCase();e=e.filter(w=>w.name.toLowerCase().includes(l))}return t.queue&&(e=e.filter(l=>l.task_queue===t.queue)),e},[o,t]),k=[{key:"name",label:"Workflow",render:e=>s.jsx(N,{type:e.name})},{key:"task_queue",label:"Queue",render:e=>s.jsx(_,{queue:e.task_queue}),className:"whitespace-nowrap"},{key:"registered",label:"Status",render:e=>e.registered?s.jsxs("span",{className:"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-2xs font-medium bg-accent/10 text-accent",children:[s.jsx(v,{className:"w-3 h-3"}),"Certified"]}):s.jsx("span",{className:"inline-flex items-center px-1.5 py-0.5 rounded text-2xs font-medium bg-surface-sunken text-text-tertiary",children:"Durable"}),className:"whitespace-nowrap"},{key:"actions",label:"",render:e=>s.jsx(q,{children:e.registered?s.jsx(u,{icon:I,title:"View config",onClick:()=>r(`/workflows/registry/${encodeURIComponent(e.name)}`)}):s.jsx(u,{icon:S,title:"Register workflow",onClick:()=>r(`/workflows/registry/new?workflow_type=${encodeURIComponent(e.name)}&task_queue=${encodeURIComponent(e.task_queue)}`)})}),className:"w-16 text-right"}],x=e=>{e.registered?r(`/workflows/registry/${encodeURIComponent(e.name)}`):r(`/workflows/registry/new?workflow_type=${encodeURIComponent(e.name)}&task_queue=${encodeURIComponent(e.task_queue)}`)};return s.jsxs("div",{children:[s.jsx(b,{title:"Workers",docsHash:"#docs:dashboard.md:task-queues"}),s.jsxs(C,{children:[s.jsx("input",{type:"text",placeholder:"Search workers...",value:a,onChange:e=>p(e.target.value),className:"input text-2xs py-1 px-2 w-56"}),s.jsx(j,{label:"Queue",value:t.queue,onChange:e=>i("queue",e),options:d.map(e=>({value:e,label:e}))})]}),s.jsx(y,{columns:k,data:f,keyFn:e=>e.name,onRowClick:x,isLoading:m,emptyMessage:"No active workers"})]})}export{G as WorkersPage};
2
- //# sourceMappingURL=index-Cfg4TFDb.js.map
1
+ import{a as n,j as s}from"./vendor-query-DvWWuNIB.js";import{aH as h,e as g}from"./index-ygxyAKcc.js";import{D as y}from"./DataTable-FjFhx0SE.js";import{F as C,b as j}from"./FilterBar-Dy0b7wwf.js";import{R as q,a as u}from"./RowActions-Bdd7z4eB.js";import{u as R}from"./useFilterParams-DBRw1Hcv.js";import{P as b}from"./PageHeader-DiGWAQlR.js";import{T as _}from"./TaskQueuePill-sUA1nZe-.js";import{W as N}from"./WorkflowPill-CKHip3hH.js";import{aB as v,E as S,h as E}from"./vendor-icons-en0_uSRD.js";import{u as I}from"./vendor-react-_9U4mKFr.js";import"./EmptyState-DgC_6njU.js";import"./useContainerWidth-DSLp1gEm.js";function G(){const r=I(),{data:c,isLoading:m}=h(),{filters:t,setFilter:i}=R({filters:{search:"",queue:""}}),[a,p]=n.useState(t.search);n.useEffect(()=>{if(a===t.search)return;const e=setTimeout(()=>i("search",a),g);return()=>clearTimeout(e)},[a,i,t.search]);const o=c??[],d=n.useMemo(()=>[...new Set(o.map(e=>e.task_queue).filter(Boolean))].sort(),[o]),f=n.useMemo(()=>{let e=o;if(t.search){const l=t.search.toLowerCase();e=e.filter(w=>w.name.toLowerCase().includes(l))}return t.queue&&(e=e.filter(l=>l.task_queue===t.queue)),e},[o,t]),k=[{key:"name",label:"Workflow",render:e=>s.jsx(N,{type:e.name})},{key:"task_queue",label:"Queue",render:e=>s.jsx(_,{queue:e.task_queue}),className:"whitespace-nowrap"},{key:"registered",label:"Status",render:e=>e.registered?s.jsxs("span",{className:"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-2xs font-medium bg-accent/10 text-accent",children:[s.jsx(v,{className:"w-3 h-3"}),"Certified"]}):s.jsx("span",{className:"inline-flex items-center px-1.5 py-0.5 rounded text-2xs font-medium bg-surface-sunken text-text-tertiary",children:"Durable"}),className:"whitespace-nowrap"},{key:"actions",label:"",render:e=>s.jsx(q,{children:e.registered?s.jsx(u,{icon:S,title:"View config",onClick:()=>r(`/workflows/registry/${encodeURIComponent(e.name)}`)}):s.jsx(u,{icon:E,title:"Register workflow",onClick:()=>r(`/workflows/registry/new?workflow_type=${encodeURIComponent(e.name)}&task_queue=${encodeURIComponent(e.task_queue)}`)})}),className:"w-16 text-right"}],x=e=>{e.registered?r(`/workflows/registry/${encodeURIComponent(e.name)}`):r(`/workflows/registry/new?workflow_type=${encodeURIComponent(e.name)}&task_queue=${encodeURIComponent(e.task_queue)}`)};return s.jsxs("div",{children:[s.jsx(b,{title:"Workers",docsHash:"#docs:dashboard.md:task-queues"}),s.jsxs(C,{children:[s.jsx("input",{type:"text",placeholder:"Search workers...",value:a,onChange:e=>p(e.target.value),className:"input text-2xs py-1 px-2 w-56"}),s.jsx(j,{label:"Queue",value:t.queue,onChange:e=>i("queue",e),options:d.map(e=>({value:e,label:e}))})]}),s.jsx(y,{columns:k,data:f,keyFn:e=>e.name,onRowClick:x,isLoading:m,emptyMessage:"No active workers"})]})}export{G as WorkersPage};
2
+ //# sourceMappingURL=index-B8qrHwp9.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-Cfg4TFDb.js","sources":["../../src/pages/workflows/workers/WorkersPage.tsx"],"sourcesContent":["import { SEARCH_DEBOUNCE_MS } from '../../../lib/realtime-refresh';\nimport { useState, useEffect, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Plus, Eye, ShieldCheck } from 'lucide-react';\nimport { useActiveWorkers } from '../../../api/workflows';\nimport { DataTable, type Column } from '../../../components/common/data/DataTable';\nimport { FilterBar, FilterSelect } from '../../../components/common/data/FilterBar';\nimport { RowAction, RowActionGroup } from '../../../components/common/layout/RowActions';\nimport { useFilterParams } from '../../../hooks/useFilterParams';\nimport type { ActiveWorker } from '../../../api/types';\nimport { PageHeader } from '../../../components/common/layout/PageHeader';\nimport { TaskQueuePill } from '../../../components/common/display/TaskQueuePill';\nimport { WorkflowPill } from '../../../components/common/display/WorkflowPill';\n\n// ── Page ──────────────────────────────────────────────────────────────────────\n\nexport function WorkersPage() {\n const navigate = useNavigate();\n const { data, isLoading } = useActiveWorkers();\n const { filters, setFilter } = useFilterParams({\n filters: { search: '', queue: '' },\n });\n\n const [searchInput, setSearchInput] = useState(filters.search);\n\n useEffect(() => {\n if (searchInput === filters.search) return;\n const timer = setTimeout(() => setFilter('search', searchInput), SEARCH_DEBOUNCE_MS);\n return () => clearTimeout(timer);\n }, [searchInput, setFilter, filters.search]);\n\n const allWorkers = data ?? [];\n\n const queues = useMemo(\n () => [...new Set(allWorkers.map((w) => w.task_queue).filter(Boolean))].sort(),\n [allWorkers],\n );\n\n const workers = useMemo(() => {\n let result = allWorkers;\n if (filters.search) {\n const q = filters.search.toLowerCase();\n result = result.filter((w) => w.name.toLowerCase().includes(q));\n }\n if (filters.queue) result = result.filter((w) => w.task_queue === filters.queue);\n return result;\n }, [allWorkers, filters]);\n\n const columns: Column<ActiveWorker>[] = [\n {\n key: 'name',\n label: 'Workflow',\n render: (row) => <WorkflowPill type={row.name} />,\n },\n {\n key: 'task_queue',\n label: 'Queue',\n render: (row) => <TaskQueuePill queue={row.task_queue} />,\n className: 'whitespace-nowrap',\n },\n {\n key: 'registered',\n label: 'Status',\n render: (row) => row.registered\n ? <span className=\"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-2xs font-medium bg-accent/10 text-accent\"><ShieldCheck className=\"w-3 h-3\" />Certified</span>\n : <span className=\"inline-flex items-center px-1.5 py-0.5 rounded text-2xs font-medium bg-surface-sunken text-text-tertiary\">Durable</span>,\n className: 'whitespace-nowrap',\n },\n {\n key: 'actions',\n label: '',\n render: (row) => (\n <RowActionGroup>\n {row.registered ? (\n <RowAction\n icon={Eye}\n title=\"View config\"\n onClick={() => navigate(`/workflows/registry/${encodeURIComponent(row.name)}`)}\n />\n ) : (\n <RowAction\n icon={Plus}\n title=\"Register workflow\"\n onClick={() => navigate(`/workflows/registry/new?workflow_type=${encodeURIComponent(row.name)}&task_queue=${encodeURIComponent(row.task_queue)}`)}\n />\n )}\n </RowActionGroup>\n ),\n className: 'w-16 text-right',\n },\n ];\n\n const handleRowClick = (row: ActiveWorker) => {\n if (row.registered) {\n navigate(`/workflows/registry/${encodeURIComponent(row.name)}`);\n } else {\n navigate(`/workflows/registry/new?workflow_type=${encodeURIComponent(row.name)}&task_queue=${encodeURIComponent(row.task_queue)}`);\n }\n };\n\n return (\n <div>\n <PageHeader title=\"Workers\" docsHash=\"#docs:dashboard.md:task-queues\" />\n\n <FilterBar>\n <input\n type=\"text\"\n placeholder=\"Search workers...\"\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n className=\"input text-2xs py-1 px-2 w-56\"\n />\n <FilterSelect\n label=\"Queue\"\n value={filters.queue}\n onChange={(v) => setFilter('queue', v)}\n options={queues.map((q) => ({ value: q, label: q }))}\n />\n </FilterBar>\n\n <DataTable\n columns={columns}\n data={workers}\n keyFn={(row) => row.name}\n onRowClick={handleRowClick}\n isLoading={isLoading}\n emptyMessage=\"No active workers\"\n />\n </div>\n );\n}\n"],"names":["WorkersPage","navigate","useNavigate","data","isLoading","useActiveWorkers","filters","setFilter","useFilterParams","searchInput","setSearchInput","useState","useEffect","timer","SEARCH_DEBOUNCE_MS","allWorkers","queues","useMemo","w","workers","result","q","columns","row","WorkflowPill","TaskQueuePill","jsxs","jsx","ShieldCheck","RowActionGroup","RowAction","Eye","Plus","handleRowClick","PageHeader","FilterBar","FilterSelect","v","DataTable"],"mappings":"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"}
1
+ {"version":3,"file":"index-B8qrHwp9.js","sources":["../../src/pages/workflows/workers/WorkersPage.tsx"],"sourcesContent":["import { SEARCH_DEBOUNCE_MS } from '../../../lib/realtime-refresh';\nimport { useState, useEffect, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Plus, Eye, ShieldCheck } from 'lucide-react';\nimport { useActiveWorkers } from '../../../api/workflows';\nimport { DataTable, type Column } from '../../../components/common/data/DataTable';\nimport { FilterBar, FilterSelect } from '../../../components/common/data/FilterBar';\nimport { RowAction, RowActionGroup } from '../../../components/common/layout/RowActions';\nimport { useFilterParams } from '../../../hooks/useFilterParams';\nimport type { ActiveWorker } from '../../../api/types';\nimport { PageHeader } from '../../../components/common/layout/PageHeader';\nimport { TaskQueuePill } from '../../../components/common/display/TaskQueuePill';\nimport { WorkflowPill } from '../../../components/common/display/WorkflowPill';\n\n// ── Page ──────────────────────────────────────────────────────────────────────\n\nexport function WorkersPage() {\n const navigate = useNavigate();\n const { data, isLoading } = useActiveWorkers();\n const { filters, setFilter } = useFilterParams({\n filters: { search: '', queue: '' },\n });\n\n const [searchInput, setSearchInput] = useState(filters.search);\n\n useEffect(() => {\n if (searchInput === filters.search) return;\n const timer = setTimeout(() => setFilter('search', searchInput), SEARCH_DEBOUNCE_MS);\n return () => clearTimeout(timer);\n }, [searchInput, setFilter, filters.search]);\n\n const allWorkers = data ?? [];\n\n const queues = useMemo(\n () => [...new Set(allWorkers.map((w) => w.task_queue).filter(Boolean))].sort(),\n [allWorkers],\n );\n\n const workers = useMemo(() => {\n let result = allWorkers;\n if (filters.search) {\n const q = filters.search.toLowerCase();\n result = result.filter((w) => w.name.toLowerCase().includes(q));\n }\n if (filters.queue) result = result.filter((w) => w.task_queue === filters.queue);\n return result;\n }, [allWorkers, filters]);\n\n const columns: Column<ActiveWorker>[] = [\n {\n key: 'name',\n label: 'Workflow',\n render: (row) => <WorkflowPill type={row.name} />,\n },\n {\n key: 'task_queue',\n label: 'Queue',\n render: (row) => <TaskQueuePill queue={row.task_queue} />,\n className: 'whitespace-nowrap',\n },\n {\n key: 'registered',\n label: 'Status',\n render: (row) => row.registered\n ? <span className=\"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-2xs font-medium bg-accent/10 text-accent\"><ShieldCheck className=\"w-3 h-3\" />Certified</span>\n : <span className=\"inline-flex items-center px-1.5 py-0.5 rounded text-2xs font-medium bg-surface-sunken text-text-tertiary\">Durable</span>,\n className: 'whitespace-nowrap',\n },\n {\n key: 'actions',\n label: '',\n render: (row) => (\n <RowActionGroup>\n {row.registered ? (\n <RowAction\n icon={Eye}\n title=\"View config\"\n onClick={() => navigate(`/workflows/registry/${encodeURIComponent(row.name)}`)}\n />\n ) : (\n <RowAction\n icon={Plus}\n title=\"Register workflow\"\n onClick={() => navigate(`/workflows/registry/new?workflow_type=${encodeURIComponent(row.name)}&task_queue=${encodeURIComponent(row.task_queue)}`)}\n />\n )}\n </RowActionGroup>\n ),\n className: 'w-16 text-right',\n },\n ];\n\n const handleRowClick = (row: ActiveWorker) => {\n if (row.registered) {\n navigate(`/workflows/registry/${encodeURIComponent(row.name)}`);\n } else {\n navigate(`/workflows/registry/new?workflow_type=${encodeURIComponent(row.name)}&task_queue=${encodeURIComponent(row.task_queue)}`);\n }\n };\n\n return (\n <div>\n <PageHeader title=\"Workers\" docsHash=\"#docs:dashboard.md:task-queues\" />\n\n <FilterBar>\n <input\n type=\"text\"\n placeholder=\"Search workers...\"\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n className=\"input text-2xs py-1 px-2 w-56\"\n />\n <FilterSelect\n label=\"Queue\"\n value={filters.queue}\n onChange={(v) => setFilter('queue', v)}\n options={queues.map((q) => ({ value: q, label: q }))}\n />\n </FilterBar>\n\n <DataTable\n columns={columns}\n data={workers}\n keyFn={(row) => row.name}\n onRowClick={handleRowClick}\n isLoading={isLoading}\n emptyMessage=\"No active workers\"\n />\n </div>\n );\n}\n"],"names":["WorkersPage","navigate","useNavigate","data","isLoading","useActiveWorkers","filters","setFilter","useFilterParams","searchInput","setSearchInput","useState","useEffect","timer","SEARCH_DEBOUNCE_MS","allWorkers","queues","useMemo","w","workers","result","q","columns","row","WorkflowPill","TaskQueuePill","jsxs","jsx","ShieldCheck","RowActionGroup","RowAction","Eye","Plus","handleRowClick","PageHeader","FilterBar","FilterSelect","v","DataTable"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{a as d,j as e}from"./vendor-query-DvWWuNIB.js";import{aL as le,M as A,aM as re,Y as G,g as V,aN as ie,aO as ce,aP as oe,aQ as de,O as q,aR as xe,ay as me}from"./index-xycFf66M.js";import{u as J}from"./useFilterParams-DBRw1Hcv.js";import{D as H}from"./DataTable-FjFhx0SE.js";import{S as Y}from"./StickyPagination-C2fzclxr.js";import{F as Q,a as W,b as X}from"./FilterBar-ByZiD0ty.js";import{C as I}from"./ConfirmDeleteModal-D6TwO-yT.js";import{R as Z,a as R}from"./RowActions-Bdd7z4eB.js";import{P as ee}from"./PageHeader-DiGWAQlR.js";import{R as E}from"./RolePill-D3hkAdKf.js";import{u as ue,a as pe,b as he,c as je,d as fe,e as ve,f as ge,g as ye,h as be}from"./bots-D4mtcPHB.js";import{T as Ne}from"./TimeAgo-CFeB6U2O.js";import{ad as we,ae as ke,aN as Se,H as F,h as Ce,ac as te,av as Pe,D as se,U as _e,g as Re}from"./vendor-icons-en0_uSRD.js";import{u as Ae,a as Ee,b as Ue,c as Be}from"./personas-BLxQpGNz.js";import{S as De}from"./ScopeBadge-DGz79rmG.js";import{L as Te,f as Ke}from"./vendor-react-_9U4mKFr.js";import{S as Ie}from"./SegmentedTabs-BpJh4Hwn.js";import"./EmptyState-DgC_6njU.js";import"./useContainerWidth-DSLp1gEm.js";function Fe({open:a,onClose:r}){const t=le(),[n,i]=d.useState({external_id:"",email:"",display_name:"",password:""}),[m,f]=d.useState(a);a!==m&&(f(a),a&&i({external_id:"",email:"",display_name:"",password:""}));const h=()=>{n.external_id.trim()&&t.mutate({external_id:n.external_id.trim(),email:n.email.trim()||void 0,display_name:n.display_name.trim()||void 0,password:n.password||void 0},{onSuccess:r})},u=(s,j)=>i(p=>({...p,[s]:j}));return e.jsx(A,{open:a,onClose:r,title:"Create User",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"External ID (required)"}),e.jsx("input",{type:"text",value:n.external_id,onChange:s=>u("external_id",s.target.value),placeholder:"e.g., john.doe",className:"input text-xs w-full"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Display Name"}),e.jsx("input",{type:"text",value:n.display_name,onChange:s=>u("display_name",s.target.value),placeholder:"John Doe",className:"input text-xs w-full"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Email"}),e.jsx("input",{type:"text",value:n.email,onChange:s=>u("email",s.target.value),placeholder:"john@example.com",className:"input text-xs w-full"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Password"}),e.jsx("input",{type:"password",value:n.password,onChange:s=>u("password",s.target.value),placeholder:"Leave blank for no password",className:"input text-xs w-full"})]}),t.error&&e.jsx("p",{className:"text-xs text-status-error",children:t.error.message}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{onClick:r,className:"btn-secondary text-xs",children:"Cancel"}),e.jsx("button",{onClick:h,disabled:!n.external_id.trim()||t.isPending,className:"btn-primary text-xs",children:t.isPending?"Creating...":"Create"})]})]})})}function Me({open:a,onClose:r,user:t}){const n=re(),[i,m]=d.useState({display_name:"",email:"",status:"active"}),[f,h]=d.useState(t);t!==f&&(h(t),t&&m({display_name:t.display_name??"",email:t.email??"",status:t.status}));const u=()=>{t&&n.mutate({id:t.id,display_name:i.display_name.trim()||void 0,email:i.email.trim()||void 0,status:i.status},{onSuccess:r})};return e.jsx(A,{open:a,onClose:r,title:`Edit — ${(t==null?void 0:t.display_name)||(t==null?void 0:t.external_id)||""}`,children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Display Name"}),e.jsx("input",{type:"text",value:i.display_name,onChange:s=>m(j=>({...j,display_name:s.target.value})),className:"input text-xs w-full"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Email"}),e.jsx("input",{type:"text",value:i.email,onChange:s=>m(j=>({...j,email:s.target.value})),className:"input text-xs w-full"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Status"}),e.jsxs("select",{value:i.status,onChange:s=>m(j=>({...j,status:s.target.value})),className:"select text-xs w-full",children:[e.jsx("option",{value:"active",children:"Active"}),e.jsx("option",{value:"inactive",children:"Inactive"}),e.jsx("option",{value:"suspended",children:"Suspended"})]})]}),n.error&&e.jsx("p",{className:"text-xs text-status-error",children:n.error.message}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{onClick:r,className:"btn-secondary text-xs",children:"Cancel"}),e.jsx("button",{onClick:u,disabled:n.isPending,className:"btn-primary text-xs",children:n.isPending?"Saving...":"Save"})]})]})})}function Oe({open:a,onClose:r}){const t=ue(),[n,i]=d.useState({name:"",display_name:"",description:""}),[m,f]=d.useState(a);a!==m&&(f(a),a&&i({name:"",display_name:"",description:""}));const h=()=>{n.name.trim()&&t.mutate({name:n.name.trim(),display_name:n.display_name.trim()||void 0,description:n.description.trim()||void 0},{onSuccess:r})},u=(s,j)=>i(p=>({...p,[s]:j}));return e.jsx(A,{open:a,onClose:r,title:"Create Service Account",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Name (required)"}),e.jsx("input",{type:"text",value:n.name,onChange:s=>u("name",s.target.value.replace(/\s+/g,"-").toLowerCase()),placeholder:"e.g., ci-bot",className:"input text-xs w-full font-mono"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Display Name"}),e.jsx("input",{type:"text",value:n.display_name,onChange:s=>u("display_name",s.target.value),placeholder:"CI Bot",className:"input text-xs w-full"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Description"}),e.jsx("input",{type:"text",value:n.description,onChange:s=>u("description",s.target.value),placeholder:"Runs scheduled workflows",className:"input text-xs w-full"})]}),t.error&&e.jsx("p",{className:"text-xs text-status-error",children:t.error.message}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{onClick:r,className:"btn-secondary text-xs",children:"Cancel"}),e.jsx("button",{onClick:h,disabled:!n.name.trim()||t.isPending,className:"btn-primary text-xs",children:t.isPending?"Creating...":"Create"})]})]})})}function $e({open:a,onClose:r,bot:t}){const n=pe(),[i,m]=d.useState({display_name:"",description:"",status:"active"}),[f,h]=d.useState(t);t!==f&&(h(t),t&&m({display_name:t.display_name??"",description:t.description??"",status:t.status}));const u=()=>{t&&n.mutate({id:t.id,display_name:i.display_name.trim()||void 0,description:i.description.trim()||void 0,status:i.status},{onSuccess:r})};return e.jsx(A,{open:a,onClose:r,title:`Edit — ${(t==null?void 0:t.display_name)||(t==null?void 0:t.external_id)||""}`,children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Display Name"}),e.jsx("input",{type:"text",value:i.display_name,onChange:s=>m(j=>({...j,display_name:s.target.value})),className:"input text-xs w-full"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Description"}),e.jsx("input",{type:"text",value:i.description,onChange:s=>m(j=>({...j,description:s.target.value})),className:"input text-xs w-full"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Status"}),e.jsxs("select",{value:i.status,onChange:s=>m(j=>({...j,status:s.target.value})),className:"select text-xs w-full",children:[e.jsx("option",{value:"active",children:"Active"}),e.jsx("option",{value:"inactive",children:"Inactive"}),e.jsx("option",{value:"suspended",children:"Suspended"})]})]}),n.error&&e.jsx("p",{className:"text-xs text-status-error",children:n.error.message}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{onClick:r,className:"btn-secondary text-xs",children:"Cancel"}),e.jsx("button",{onClick:u,disabled:n.isPending,className:"btn-primary text-xs",children:n.isPending?"Saving...":"Save"})]})]})})}function ze({botId:a}){const{data:r}=he(a),t=je(),n=fe(),[i,m]=d.useState(""),[f,h]=d.useState("read"),[u,s]=d.useState(null),[j,p]=d.useState(!1),[v,x]=d.useState(null),y=(r==null?void 0:r.keys)??[],o={read:{label:"Read only",scopes:["mcp:read"],hint:"Discovery and monitoring — read-safe tools only"},full:{label:"Full access",scopes:["mcp:read","mcp:full"],hint:"All tools — can modify state"}},b=()=>{i.trim()&&t.mutate({botId:a,name:i.trim(),scopes:o[f].scopes},{onSuccess:g=>{s(g.rawKey),m("")}})},N=()=>{u&&(navigator.clipboard.writeText(u),p(!0),setTimeout(()=>p(!1),2e3))},k=()=>{v&&n.mutate({botId:a,keyId:v.id},{onSuccess:()=>x(null)})};return e.jsxs("div",{children:[e.jsx("p",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-3",children:"API Keys"}),u&&e.jsxs("div",{className:"mb-3 p-3 bg-status-success/10 border border-status-success/30 rounded-md",children:[e.jsx("p",{className:"text-2xs font-semibold text-status-success mb-1",children:"Key generated — copy now, it won't be shown again"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("code",{className:"text-2xs font-mono text-text-primary bg-surface-sunken px-2 py-1 rounded flex-1 min-w-0 overflow-hidden text-ellipsis whitespace-nowrap",children:u}),e.jsx("button",{onClick:N,className:"text-text-tertiary hover:text-text-primary shrink-0",title:"Copy to clipboard",children:j?e.jsx(we,{className:"w-3.5 h-3.5 text-status-success"}):e.jsx(ke,{className:"w-3.5 h-3.5"})})]})]}),y.length===0?e.jsx("p",{className:"text-xs text-text-tertiary mb-3",children:"No API keys."}):e.jsx("div",{className:"space-y-1.5 mb-3",children:y.map(g=>e.jsxs("div",{className:"group/key flex items-center justify-between px-2.5 py-1.5 bg-surface-sunken rounded text-xs",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx(Se,{className:"w-3 h-3 text-text-tertiary"}),e.jsx("span",{className:"text-text-primary font-mono",children:g.name}),(g.scopes??[]).map(l=>e.jsx("span",{className:`px-1.5 py-0.5 rounded text-2xs font-mono ${l.includes("full")?"bg-status-warning/15 text-status-warning":"bg-accent/10 text-accent"}`,children:l},l)),g.last_used_at&&e.jsxs("span",{className:"text-2xs text-text-tertiary",children:["used ",e.jsx(Ne,{date:g.last_used_at})]})]}),e.jsx("button",{onClick:()=>x(g),className:"opacity-0 group-hover/key:opacity-100 transition-opacity text-text-tertiary hover:text-status-error",title:"Revoke key",children:e.jsx(F,{className:"w-3 h-3"})})]},g.id))}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("input",{type:"text",value:i,onChange:g=>m(g.target.value),placeholder:"Key name...",className:"input text-xs font-mono"}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("div",{className:"flex rounded-md border border-surface-border overflow-hidden shrink-0",children:Object.entries(o).map(([g,l])=>e.jsx("button",{type:"button",onClick:()=>h(g),title:l.hint,className:`px-2.5 py-1 text-2xs font-medium transition-colors ${f===g?"bg-accent text-text-inverse":"bg-surface text-text-secondary hover:bg-surface-hover"}`,children:l.label},g))}),e.jsxs("button",{onClick:b,disabled:!i.trim()||t.isPending,className:"btn-primary text-xs inline-flex items-center gap-1 shrink-0",children:[e.jsx(Ce,{className:"w-3 h-3"}),t.isPending?"...":"Generate"]})]})]}),t.error&&e.jsx("p",{className:"text-2xs text-status-error mt-1",children:t.error.message}),e.jsx(I,{open:!!v,onClose:()=>x(null),onConfirm:k,title:"Revoke API Key",description:e.jsxs(e.Fragment,{children:["Revoke API key"," ",e.jsx("span",{className:"font-medium text-text-primary font-mono",children:v==null?void 0:v.name}),"? This bot will no longer be able to authenticate with this key."]}),isPending:n.isPending,error:n.error})]})}function Le({bot:a}){const{data:r}=G(),t=ve(),n=ge(),[i,m]=d.useState(""),[f,h]=d.useState("member"),u=(r==null?void 0:r.roles)??[],s=a.roles??[],j=d.useMemo(()=>{const x=new Set(s.map(y=>y.role));return u.filter(y=>!x.has(y))},[u,s]),p=()=>{i.trim()&&t.mutate({botId:a.id,role:i.trim(),type:f},{onSuccess:()=>{m(""),h("member")}})},v=x=>{n.mutate({botId:a.id,role:x})};return e.jsxs("div",{children:[e.jsx("p",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-3",children:"Roles"}),s.length===0?e.jsx("p",{className:"text-xs text-text-tertiary mb-3",children:"No roles assigned."}):e.jsx("div",{className:"flex flex-wrap gap-2 mb-3",children:s.map(x=>e.jsxs("span",{className:"inline-flex items-center gap-1.5 px-2.5 py-1 text-xs bg-surface-sunken rounded-full text-text-secondary",children:[e.jsx(E,{role:x.role}),e.jsx("span",{className:"text-2xs text-text-tertiary",children:x.type}),e.jsx("button",{onClick:()=>v(x.role),className:"text-text-tertiary hover:text-status-error transition-colors ml-0.5",title:`Remove ${x.role}`,children:"×"})]},x.role))}),j.length>0&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs("select",{value:i,onChange:x=>m(x.target.value),className:"select text-xs font-mono w-full min-w-0","aria-label":"Role",children:[e.jsx("option",{value:"",children:"Select a role..."}),j.map(x=>e.jsx("option",{value:x,children:x},x))]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2 items-end",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("label",{className:"block text-2xs text-text-tertiary mb-1",children:"Type"}),e.jsxs("select",{value:f,onChange:x=>h(x.target.value),className:"select text-xs w-full min-w-0","aria-label":"Role type",children:[e.jsx("option",{value:"member",children:"member"}),e.jsx("option",{value:"admin",children:"admin"}),e.jsx("option",{value:"superadmin",children:"superadmin"})]})]}),e.jsx("div",{className:"flex justify-end",children:e.jsx("button",{onClick:p,disabled:!i||t.isPending,className:"btn-primary text-xs",children:t.isPending?"...":"Add Role"})})]})]}),t.error&&e.jsx("p",{className:"text-2xs text-status-error mt-1",children:t.error.message})]})}function Ge({bot:a}){return a?e.jsxs("div",{className:"border-l border-surface-border pl-6 pt-4 min-h-[300px] space-y-6",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-text-primary",children:a.display_name||a.external_id}),a.description&&e.jsx("p",{className:"text-xs text-text-tertiary mt-0.5",children:a.description})]}),e.jsx(ze,{botId:a.id}),e.jsx(Le,{bot:a})]}):e.jsx("div",{className:"border-l border-surface-border pl-6 pt-4 min-h-[300px]",children:e.jsx("p",{className:"text-xs text-text-tertiary",children:"Select a service account to manage its API keys and roles."})})}const Ve={active:"bg-status-success",inactive:"bg-text-tertiary",suspended:"bg-status-error"},qe=[{value:"active",label:"Active"},{value:"inactive",label:"Inactive"},{value:"suspended",label:"Suspended"}];function Je({embedded:a=!1}){const{filters:r,setFilter:t,pagination:n}=J({filters:{status:"",search:""}}),i=ye(),[m,f]=d.useState(!1),[h,u]=d.useState(null),[s,j]=d.useState(null),[p,v]=d.useState(null),{data:x,isLoading:y}=be({status:r.status||void 0,search:r.search||void 0,limit:n.pageSize,offset:n.offset}),o=(x==null?void 0:x.total)??0,b=(x==null?void 0:x.bots)??[],N=d.useMemo(()=>s?b.find(l=>l.id===s.id)??s:null,[b,s]),k=[{key:"display_name",label:"Service Account",render:l=>e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx("span",{className:`w-2.5 h-2.5 rounded-full dot-ring shrink-0 ${Ve[l.status]??"bg-status-pending"}`,title:l.status}),e.jsx("span",{className:"text-sm text-text-primary whitespace-nowrap",children:l.display_name||l.external_id})]})},{key:"description",label:"Description",render:l=>e.jsx("span",{className:"block max-w-[32rem] truncate text-xs text-text-tertiary",title:l.description??void 0,children:l.description??""})},{key:"roles",label:"Roles",render:l=>e.jsx("div",{className:"flex gap-1 flex-wrap",children:(l.roles??[]).map(S=>e.jsx(E,{role:S.role},S.role))})},{key:"created_at",label:"Created",render:l=>e.jsx(V,{date:l.created_at}),className:"w-36 whitespace-nowrap"},{key:"actions",label:"",render:l=>e.jsxs(Z,{children:[e.jsx(R,{icon:te,title:"Edit service account",onClick:()=>u(l)}),e.jsx(R,{icon:F,title:"Delete service account",onClick:()=>v(l),colorClass:"text-text-tertiary hover:text-status-error"})]}),className:"w-16 text-right"}],g=()=>{p&&i.mutate(p.id,{onSuccess:()=>{v(null),(s==null?void 0:s.id)===p.id&&j(null)}})};return e.jsxs("div",{children:[a?e.jsx("div",{className:"flex justify-end mb-4",children:e.jsx("button",{onClick:()=>f(!0),className:"btn-primary text-xs",children:"Add Service Account"})}):e.jsx(ee,{title:"Service Accounts",actions:e.jsx("button",{onClick:()=>f(!0),className:"btn-primary text-xs",children:"Add Service Account"})}),e.jsxs(Q,{children:[e.jsx(W,{label:"Search",value:r.search,onChange:l=>t("search",l),placeholder:"name, id, description…"}),e.jsx(X,{label:"Status",value:r.status,onChange:l=>t("status",l),options:qe})]}),e.jsxs("div",{className:"grid grid-cols-1 @split:grid-cols-[1fr_360px] gap-6 items-start",children:[e.jsxs("div",{className:"overflow-x-clip",children:[e.jsx(H,{columns:k,data:b,keyFn:l=>l.id,isLoading:y,emptyMessage:"No service accounts yet",onRowClick:l=>j(l),activeRowKey:(N==null?void 0:N.id)??null}),e.jsx(Y,{page:n.page,totalPages:n.totalPages(o),onPageChange:n.setPage,total:o,pageSize:n.pageSize,onPageSizeChange:n.setPageSize})]}),e.jsx("div",{className:"sticky top-4",children:e.jsx(Ge,{bot:N})})]}),e.jsx(Oe,{open:m,onClose:()=>f(!1)}),e.jsx($e,{open:!!h,onClose:()=>u(null),bot:h}),e.jsx(I,{open:!!p,onClose:()=>v(null),onConfirm:g,title:"Delete Service Account",description:e.jsxs(e.Fragment,{children:["Delete"," ",e.jsx("span",{className:"font-medium text-text-primary",children:(p==null?void 0:p.display_name)||(p==null?void 0:p.external_id)}),"? This will also revoke all API keys. This action cannot be undone."]}),isPending:i.isPending,error:i.error})]})}function He({value:a,systemKeys:r=[],pending:t=!1,error:n,onPatch:i}){const m=Object.entries(a??{}),f=new Set(r),[h,u]=d.useState(null),[s,j]=d.useState(""),[p,v]=d.useState(""),[x,y]=d.useState(null),[o,b]=d.useState(null),[N,k]=d.useState(""),[g,l]=d.useState(""),[S,C]=d.useState(null),P=c=>typeof c=="string"?c:JSON.stringify(c),O=c=>{const w=c.trim();try{return JSON.parse(w)}catch{return w}};function $(c){if(f.has(c)&&o!==c){b(c);return}b(null),u(c),j(c),v(P((a??{})[c])),y(null),C(null)}function ae(){if(h===null)return;const c=s.trim();if(!c){C("Property name is required");return}if(c!==h&&m.some(([B])=>B===c)){C(`"${c}" already exists`);return}const w={};c!==h&&(w.rename={[h]:c});const _=O(p);if((P(_)!==P((a??{})[h])||c!==h)&&P(_)!==P((a??{})[h])&&(w.set={[c]:_}),!w.set&&!w.rename){U();return}i(w),U()}function U(){u(null),j(""),v(""),C(null)}function z(){const c=N.trim();if(!c){C("Property name is required");return}if(m.some(([w])=>w===c)){C(`"${c}" already exists`);return}i({set:{[c]:O(g)}}),k(""),l(""),C(null)}return e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary",children:"Properties"}),m.length===0&&e.jsx("p",{className:"text-xs text-text-tertiary italic",children:"No properties — add one below."}),m.map(([c,w])=>{const _=f.has(c),B=h===c,ne=x===c;return e.jsx("div",{className:"group text-xs",children:B?e.jsxs("div",{className:"space-y-1.5 border-l-2 border-l-accent pl-2",children:[e.jsx("input",{value:s,onChange:D=>j(D.target.value),"aria-label":"Property name",className:"input text-xs w-full min-w-0 font-mono"}),e.jsx("input",{value:p,onChange:D=>v(D.target.value),"aria-label":"Property value",placeholder:"value (string or JSON)",className:"input text-xs w-full min-w-0"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{onClick:ae,disabled:t,className:"text-2xs font-medium text-accent hover:text-accent-hover",children:t?"Saving...":"Save"}),e.jsx("button",{onClick:U,className:"text-2xs text-text-tertiary hover:text-text-secondary",children:"Cancel"}),e.jsx("button",{onClick:()=>{y(c),u(null)},className:"text-2xs text-status-error/50 hover:text-status-error ml-auto",children:"Remove"})]})]}):ne?e.jsxs("span",{className:"flex items-center gap-2 text-2xs",children:[e.jsxs("span",{className:"text-status-error",children:["Remove ",e.jsx("span",{className:"font-medium font-mono",children:c}),"?"]}),e.jsx("button",{onClick:()=>{i({remove:[c]}),y(null)},disabled:t,className:"font-medium text-status-error hover:text-status-error/80",children:t?"...":"Yes"}),e.jsx("button",{onClick:()=>y(null),className:"text-text-tertiary hover:text-text-secondary",children:"No"})]}):o===c?e.jsxs("span",{className:"flex items-center gap-2 text-2xs",children:[e.jsxs("span",{className:"text-text-secondary",children:[e.jsx("span",{className:"font-mono font-medium",children:c})," is a system property — the platform resolves identities with it. Edit?"]}),e.jsx("button",{onClick:()=>$(c),className:"font-medium text-accent hover:text-accent-hover",children:"Edit"}),e.jsx("button",{onClick:()=>b(null),className:"text-text-tertiary hover:text-text-secondary",children:"Cancel"})]}):e.jsxs("button",{onClick:()=>$(c),className:"flex items-center gap-2 w-full min-w-0 text-left rounded px-1 py-0.5 -mx-1 hover:bg-surface-hover transition-colors",title:`Edit ${c}`,children:[e.jsx("span",{className:"font-mono font-medium text-text-secondary shrink-0",children:c}),_&&e.jsx("span",{className:"shrink-0 text-accent/80",title:"system",children:e.jsx(Pe,{className:"w-3 h-3","aria-label":"system"})}),e.jsx("span",{className:"flex-1 min-w-0 truncate text-right text-text-primary tabular-nums",children:P(w)})]})},c)}),e.jsxs("div",{className:"pt-1.5 border-t border-surface-border space-y-1.5",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsx("input",{value:N,onChange:c=>k(c.target.value),placeholder:"property","aria-label":"New property name",className:"input text-xs w-full min-w-0 font-mono"}),e.jsx("input",{value:g,onChange:c=>l(c.target.value),onKeyDown:c=>{c.key==="Enter"&&z()},placeholder:"value","aria-label":"New property value",className:"input text-xs w-full min-w-0"})]}),N.trim()&&e.jsx("div",{className:"flex justify-end",children:e.jsx("button",{onClick:z,disabled:t,className:"btn-primary text-xs",children:t?"...":"Add Property"})})]}),(S||n)&&e.jsx("p",{role:"alert",className:"text-2xs text-status-error",children:S||n})]})}const K=[{value:"all|all",label:"See all · act on all",read_scope:"all",write_scope:"all"},{value:"all|self",label:"See all · act on self",read_scope:"all",write_scope:"self"},{value:"self|self",label:"See self · act on self",read_scope:"self",write_scope:"self"},{value:"all|none",label:"See all · read-only",read_scope:"all",write_scope:"none"},{value:"self|none",label:"See self · read-only",read_scope:"self",write_scope:"none"}],T="all|all";function L(a){return K.find(r=>r.value===a)??K[0]}function M({children:a}){return e.jsx("div",{className:"border border-surface-border bg-surface-sunken rounded-[var(--lt-radius-section)] p-4",children:a})}function Ye({user:a}){const r=oe(),{data:t}=de();return e.jsx(M,{children:e.jsx(He,{value:a.metadata??{},systemKeys:(t==null?void 0:t.keys)??[],pending:r.isPending,error:r.error?r.error.message:null,onPatch:n=>r.mutate({id:a.id,ops:n})})})}function Qe({user:a}){const{data:r}=Ae(),{data:t}=Ee(a.id),n=Ue(),i=Be(),[m,f]=d.useState(""),h=(t==null?void 0:t.personas)??[],u=d.useMemo(()=>{const s=new Set(h.map(j=>j.key));return((r==null?void 0:r.personas)??[]).filter(j=>!s.has(j.key))},[r,h]);return h.length===0&&u.length===0?null:e.jsx(M,{children:e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary",children:"Personas"}),h.length>0&&e.jsx("div",{className:"flex flex-col gap-2",children:h.map(s=>e.jsxs("span",{className:"flex items-center gap-2.5 w-full min-w-0 pl-2.5 pr-2 py-1 text-xs bg-surface-sunken rounded-full text-text-secondary",children:[e.jsx(se,{className:"w-3 h-3 shrink-0 text-text-tertiary","aria-hidden":!0}),e.jsx(Te,{to:`/admin/personas/${encodeURIComponent(s.key)}`,className:"flex-1 min-w-0 truncate transition-colors hover:text-accent",title:s.key,children:s.title||s.key}),e.jsxs("span",{className:"shrink-0 text-2xs text-text-tertiary tabular-nums",children:[s.roles.length," role",s.roles.length===1?"":"s"]}),e.jsx("button",{onClick:()=>i.mutate({userId:a.id,key:s.key}),className:"shrink-0 text-text-tertiary hover:text-status-error transition-colors ml-1",title:`Unassign ${s.title||s.key}`,children:"×"})]},s.key))}),u.length>0&&e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("select",{value:m,onChange:s=>f(s.target.value),className:"select text-xs w-full min-w-0","aria-label":"Persona",children:[e.jsx("option",{value:"",children:"Assign a persona..."}),u.map(s=>e.jsx("option",{value:s.key,children:s.title||s.key},s.key))]}),e.jsx("button",{onClick:()=>{m&&n.mutate({userId:a.id,key:m},{onSuccess:()=>f("")})},disabled:!m||n.isPending,className:"btn-primary text-xs shrink-0",children:n.isPending?"...":"Assign"})]}),(n.error||i.error)&&e.jsx("p",{className:"text-2xs text-status-error",children:(n.error||i.error).message})]})})}function We({user:a}){const{data:r}=G(),t=ie(),n=ce(),[i,m]=d.useState(""),[f,h]=d.useState("member"),[u,s]=d.useState(T),j=(r==null?void 0:r.roles)??[],p=(a==null?void 0:a.roles)??[],v=d.useMemo(()=>{const o=new Set(p.map(b=>b.role));return j.filter(b=>!o.has(b))},[j,p]),x=()=>{if(!a||!i.trim())return;const o=L(f==="member"?u:T);t.mutate({userId:a.id,role:i.trim(),type:f,read_scope:o.read_scope,write_scope:o.write_scope},{onSuccess:()=>{m(""),h("member"),s(T)}})},y=o=>{a&&n.mutate({userId:a.id,role:o})};return e.jsxs("div",{className:"border-l border-surface-border pl-6 pt-4 pb-8 min-h-[300px]",children:[e.jsx("p",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-4",children:"Role Membership"}),a?e.jsxs("div",{className:"space-y-6",children:[e.jsx("div",{children:e.jsx("p",{className:"text-sm text-text-primary",children:a.display_name||a.external_id})}),e.jsx(Qe,{user:a}),e.jsx(M,{children:e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary",children:"Roles"}),p.length===0?e.jsx("p",{className:"text-xs text-text-tertiary",children:"No roles assigned."}):e.jsx("div",{className:"flex flex-col gap-2",children:p.map(o=>e.jsxs("span",{className:"flex items-center gap-2.5 w-full min-w-0 pl-2.5 pr-2 py-1 text-xs bg-surface-sunken rounded-full text-text-secondary",children:[e.jsx("span",{className:"flex-1 min-w-0 truncate",title:o.role,children:e.jsx(E,{role:o.role,tone:"inherit"})}),e.jsx("span",{className:"w-14 shrink-0 text-2xs uppercase tracking-wide text-text-tertiary",children:o.type}),o.type==="member"&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"w-px h-3 bg-surface-border shrink-0","aria-hidden":!0}),e.jsx(De,{read:o.read_scope,write:o.write_scope,className:"shrink-0"})]}),o.granted_by_persona&&e.jsx("span",{className:"shrink-0",title:`Granted by persona ${o.granted_by_persona}`,children:e.jsx(se,{className:"w-3 h-3 text-text-tertiary","aria-hidden":!0})}),e.jsx("button",{onClick:()=>y(o.role),className:"shrink-0 text-text-tertiary hover:text-status-error transition-colors ml-1",title:`Remove ${o.role}`,children:"×"})]},o.role))}),v.length>0&&e.jsxs("div",{className:"pt-3 border-t border-surface-border space-y-2",children:[e.jsx("p",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary",children:"Add Role"}),e.jsxs("select",{value:i,onChange:o=>m(o.target.value),className:"select text-xs font-mono w-full min-w-0","aria-label":"Role",children:[e.jsx("option",{value:"",children:"Select a role..."}),v.map(o=>e.jsx("option",{value:o,children:o},o))]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("label",{className:"block text-2xs text-text-tertiary mb-1",children:"Type"}),e.jsxs("select",{value:f,onChange:o=>h(o.target.value),className:"select text-xs w-full min-w-0","aria-label":"Role type",children:[e.jsx("option",{value:"member",children:"member"}),e.jsx("option",{value:"admin",children:"admin"}),e.jsx("option",{value:"superadmin",children:"superadmin"})]})]}),f==="member"&&e.jsxs("div",{className:"min-w-0",children:[e.jsx("label",{className:"block text-2xs text-text-tertiary mb-1",children:"Scope"}),e.jsx("select",{value:u,onChange:o=>s(o.target.value),className:"select text-xs w-full min-w-0","aria-label":"Work-surface scope",children:K.map(o=>e.jsx("option",{value:o.value,children:o.label},o.value))})]})]}),e.jsx("div",{className:"flex justify-end pt-1",children:e.jsx("button",{onClick:x,disabled:!i||t.isPending,className:"btn-primary text-xs",children:t.isPending?"...":"Add Role"})}),t.error&&e.jsx("p",{className:"text-2xs text-status-error",children:t.error.message})]})]})}),e.jsx(Ye,{user:a})]}):e.jsx("p",{className:"text-xs text-text-tertiary",children:"Select a user to manage their roles."})]})}function Xe({active:a,onChange:r}){return e.jsx(Ie,{"aria-label":"Account kind",active:a,onChange:r,tabs:[{key:"users",label:"User Accounts",icon:e.jsx(_e,{className:"w-3.5 h-3.5"})},{key:"service-accounts",label:"Service Accounts",icon:e.jsx(Re,{className:"w-3.5 h-3.5"})}]})}const Ze=[{value:"active",label:"Active"},{value:"inactive",label:"Inactive"},{value:"suspended",label:"Suspended"}],et={active:"bg-status-success",inactive:"bg-text-tertiary",suspended:"bg-status-error"};function bt(){const{isBuilder:a}=q(),[r,t]=Ke(),n=r.get("tab"),i=a&&n==="service-accounts"?"service-accounts":"users",m=f=>{t(f==="users"?{}:{tab:f})};return e.jsxs("div",{children:[e.jsx(ee,{title:"Accounts",docsHash:"#docs:dashboard.md:accounts",actions:a?e.jsx(Xe,{active:i,onChange:m}):void 0}),i==="users"?e.jsx(tt,{}):e.jsx(Je,{embedded:!0})]})}function tt(){const{isBuilder:a}=q(),{filters:r,setFilter:t,pagination:n}=J({filters:{status:"",search:""}}),i=xe(),[m,f]=d.useState(!1),[h,u]=d.useState(null),[s,j]=d.useState(null),[p,v]=d.useState(null),{data:x,isLoading:y}=me({status:r.status||void 0,search:r.search||void 0,limit:n.pageSize,offset:n.offset}),o=(x==null?void 0:x.total)??0,b=(x==null?void 0:x.users)??[],N=d.useMemo(()=>s?b.find(l=>l.id===s.id)??s:null,[b,s]),k=[{key:"display_name",label:"User",render:l=>e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx("span",{className:`w-2.5 h-2.5 rounded-full dot-ring shrink-0 ${et[l.status]??"bg-status-pending"}`,title:l.status}),e.jsx("span",{className:"text-xs text-text-primary whitespace-nowrap",children:l.display_name||l.external_id})]})},{key:"email",label:"Email",render:l=>l.email?e.jsx("span",{className:"text-xs text-text-secondary whitespace-nowrap",children:l.email}):e.jsx("span",{className:"text-xs text-text-quaternary",children:"—"})},{key:"roles",label:"Roles",render:l=>e.jsx("div",{className:"flex gap-2 flex-wrap",children:(l.roles??[]).map(S=>e.jsx(E,{role:S.role,size:"md"},S.role))})},{key:"created_at",label:"Created",render:l=>e.jsx(V,{date:l.created_at}),className:"w-36 whitespace-nowrap"},...a?[{key:"actions",label:"",render:l=>e.jsxs(Z,{children:[e.jsx(R,{icon:te,title:"Edit user",onClick:()=>u(l)}),e.jsx(R,{icon:F,title:"Delete user",onClick:()=>v(l),colorClass:"text-text-tertiary hover:text-status-error"})]}),className:"w-16 text-right"}]:[]],g=()=>{p&&i.mutate(p.id,{onSuccess:()=>v(null)})};return e.jsxs("div",{children:[a&&e.jsx("div",{className:"flex justify-end mb-4",children:e.jsx("button",{onClick:()=>f(!0),className:"btn-primary text-xs",children:"Add User"})}),e.jsxs(Q,{children:[e.jsx(W,{label:"Search",value:r.search,onChange:l=>t("search",l),placeholder:"name, email, id…"}),e.jsx(X,{label:"Status",value:r.status,onChange:l=>t("status",l),options:Ze})]}),e.jsxs("div",{className:"grid grid-cols-1 @split:grid-cols-[1fr_460px] gap-6 items-start",children:[e.jsxs("div",{className:"overflow-x-clip",children:[e.jsx(H,{columns:k,data:b,keyFn:l=>l.id,isLoading:y,emptyMessage:"No users found",onRowClick:l=>j(l),activeRowKey:(N==null?void 0:N.id)??null}),e.jsx(Y,{page:n.page,totalPages:n.totalPages(o),onPageChange:n.setPage,total:o,pageSize:n.pageSize,onPageSizeChange:n.setPageSize})]}),e.jsx("div",{className:"sticky top-4",children:e.jsx(We,{user:N})})]}),e.jsx(Fe,{open:m,onClose:()=>f(!1)}),e.jsx(Me,{open:!!h,onClose:()=>u(null),user:h}),e.jsx(I,{open:!!p,onClose:()=>v(null),onConfirm:g,title:"Delete User",description:e.jsxs(e.Fragment,{children:["Delete"," ",e.jsx("span",{className:"font-medium text-text-primary",children:(p==null?void 0:p.display_name)||(p==null?void 0:p.external_id)}),"? This action cannot be undone."]}),isPending:i.isPending,error:i.error})]})}export{bt as UsersPage};
2
- //# sourceMappingURL=index-D-Fd0gQ_.js.map
1
+ import{a as d,j as e}from"./vendor-query-DvWWuNIB.js";import{aK as le,M as A,aL as re,Y as G,g as V,aM as ie,aN as ce,aO as oe,aP as de,O as q,aQ as xe,ax as me}from"./index-ygxyAKcc.js";import{u as J}from"./useFilterParams-DBRw1Hcv.js";import{D as H}from"./DataTable-FjFhx0SE.js";import{S as Y}from"./StickyPagination-miUdVAKw.js";import{F as Q,a as W,b as X}from"./FilterBar-Dy0b7wwf.js";import{C as I}from"./ConfirmDeleteModal-CpJNP-8w.js";import{R as Z,a as R}from"./RowActions-Bdd7z4eB.js";import{P as ee}from"./PageHeader-DiGWAQlR.js";import{R as E}from"./RolePill-D3hkAdKf.js";import{u as ue,a as pe,b as he,c as je,d as fe,e as ve,f as ge,g as ye,h as be}from"./bots-WrUhEPWs.js";import{T as Ne}from"./TimeAgo-CHTelacB.js";import{ad as we,ae as ke,aN as Se,H as F,h as Ce,ac as te,av as Pe,D as se,U as _e,g as Re}from"./vendor-icons-en0_uSRD.js";import{u as Ae,a as Ee,b as Ue,c as Be}from"./personas-CyJc10xe.js";import{S as De}from"./ScopeBadge-DGz79rmG.js";import{L as Ke,f as Te}from"./vendor-react-_9U4mKFr.js";import{S as Ie}from"./SegmentedTabs-BpJh4Hwn.js";import"./EmptyState-DgC_6njU.js";import"./useContainerWidth-DSLp1gEm.js";function Fe({open:a,onClose:r}){const t=le(),[n,i]=d.useState({external_id:"",email:"",display_name:"",password:""}),[m,f]=d.useState(a);a!==m&&(f(a),a&&i({external_id:"",email:"",display_name:"",password:""}));const h=()=>{n.external_id.trim()&&t.mutate({external_id:n.external_id.trim(),email:n.email.trim()||void 0,display_name:n.display_name.trim()||void 0,password:n.password||void 0},{onSuccess:r})},u=(s,j)=>i(p=>({...p,[s]:j}));return e.jsx(A,{open:a,onClose:r,title:"Create User",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"External ID (required)"}),e.jsx("input",{type:"text",value:n.external_id,onChange:s=>u("external_id",s.target.value),placeholder:"e.g., john.doe",className:"input text-xs w-full"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Display Name"}),e.jsx("input",{type:"text",value:n.display_name,onChange:s=>u("display_name",s.target.value),placeholder:"John Doe",className:"input text-xs w-full"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Email"}),e.jsx("input",{type:"text",value:n.email,onChange:s=>u("email",s.target.value),placeholder:"john@example.com",className:"input text-xs w-full"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Password"}),e.jsx("input",{type:"password",value:n.password,onChange:s=>u("password",s.target.value),placeholder:"Leave blank for no password",className:"input text-xs w-full"})]}),t.error&&e.jsx("p",{className:"text-xs text-status-error",children:t.error.message}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{onClick:r,className:"btn-secondary text-xs",children:"Cancel"}),e.jsx("button",{onClick:h,disabled:!n.external_id.trim()||t.isPending,className:"btn-primary text-xs",children:t.isPending?"Creating...":"Create"})]})]})})}function Me({open:a,onClose:r,user:t}){const n=re(),[i,m]=d.useState({display_name:"",email:"",status:"active"}),[f,h]=d.useState(t);t!==f&&(h(t),t&&m({display_name:t.display_name??"",email:t.email??"",status:t.status}));const u=()=>{t&&n.mutate({id:t.id,display_name:i.display_name.trim()||void 0,email:i.email.trim()||void 0,status:i.status},{onSuccess:r})};return e.jsx(A,{open:a,onClose:r,title:`Edit — ${(t==null?void 0:t.display_name)||(t==null?void 0:t.external_id)||""}`,children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Display Name"}),e.jsx("input",{type:"text",value:i.display_name,onChange:s=>m(j=>({...j,display_name:s.target.value})),className:"input text-xs w-full"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Email"}),e.jsx("input",{type:"text",value:i.email,onChange:s=>m(j=>({...j,email:s.target.value})),className:"input text-xs w-full"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Status"}),e.jsxs("select",{value:i.status,onChange:s=>m(j=>({...j,status:s.target.value})),className:"select text-xs w-full",children:[e.jsx("option",{value:"active",children:"Active"}),e.jsx("option",{value:"inactive",children:"Inactive"}),e.jsx("option",{value:"suspended",children:"Suspended"})]})]}),n.error&&e.jsx("p",{className:"text-xs text-status-error",children:n.error.message}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{onClick:r,className:"btn-secondary text-xs",children:"Cancel"}),e.jsx("button",{onClick:u,disabled:n.isPending,className:"btn-primary text-xs",children:n.isPending?"Saving...":"Save"})]})]})})}function Oe({open:a,onClose:r}){const t=ue(),[n,i]=d.useState({name:"",display_name:"",description:""}),[m,f]=d.useState(a);a!==m&&(f(a),a&&i({name:"",display_name:"",description:""}));const h=()=>{n.name.trim()&&t.mutate({name:n.name.trim(),display_name:n.display_name.trim()||void 0,description:n.description.trim()||void 0},{onSuccess:r})},u=(s,j)=>i(p=>({...p,[s]:j}));return e.jsx(A,{open:a,onClose:r,title:"Create Service Account",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Name (required)"}),e.jsx("input",{type:"text",value:n.name,onChange:s=>u("name",s.target.value.replace(/\s+/g,"-").toLowerCase()),placeholder:"e.g., ci-bot",className:"input text-xs w-full font-mono"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Display Name"}),e.jsx("input",{type:"text",value:n.display_name,onChange:s=>u("display_name",s.target.value),placeholder:"CI Bot",className:"input text-xs w-full"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Description"}),e.jsx("input",{type:"text",value:n.description,onChange:s=>u("description",s.target.value),placeholder:"Runs scheduled workflows",className:"input text-xs w-full"})]}),t.error&&e.jsx("p",{className:"text-xs text-status-error",children:t.error.message}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{onClick:r,className:"btn-secondary text-xs",children:"Cancel"}),e.jsx("button",{onClick:h,disabled:!n.name.trim()||t.isPending,className:"btn-primary text-xs",children:t.isPending?"Creating...":"Create"})]})]})})}function $e({open:a,onClose:r,bot:t}){const n=pe(),[i,m]=d.useState({display_name:"",description:"",status:"active"}),[f,h]=d.useState(t);t!==f&&(h(t),t&&m({display_name:t.display_name??"",description:t.description??"",status:t.status}));const u=()=>{t&&n.mutate({id:t.id,display_name:i.display_name.trim()||void 0,description:i.description.trim()||void 0,status:i.status},{onSuccess:r})};return e.jsx(A,{open:a,onClose:r,title:`Edit — ${(t==null?void 0:t.display_name)||(t==null?void 0:t.external_id)||""}`,children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Display Name"}),e.jsx("input",{type:"text",value:i.display_name,onChange:s=>m(j=>({...j,display_name:s.target.value})),className:"input text-xs w-full"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Description"}),e.jsx("input",{type:"text",value:i.description,onChange:s=>m(j=>({...j,description:s.target.value})),className:"input text-xs w-full"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Status"}),e.jsxs("select",{value:i.status,onChange:s=>m(j=>({...j,status:s.target.value})),className:"select text-xs w-full",children:[e.jsx("option",{value:"active",children:"Active"}),e.jsx("option",{value:"inactive",children:"Inactive"}),e.jsx("option",{value:"suspended",children:"Suspended"})]})]}),n.error&&e.jsx("p",{className:"text-xs text-status-error",children:n.error.message}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{onClick:r,className:"btn-secondary text-xs",children:"Cancel"}),e.jsx("button",{onClick:u,disabled:n.isPending,className:"btn-primary text-xs",children:n.isPending?"Saving...":"Save"})]})]})})}function ze({botId:a}){const{data:r}=he(a),t=je(),n=fe(),[i,m]=d.useState(""),[f,h]=d.useState("read"),[u,s]=d.useState(null),[j,p]=d.useState(!1),[v,x]=d.useState(null),y=(r==null?void 0:r.keys)??[],o={read:{label:"Read only",scopes:["mcp:read"],hint:"Discovery and monitoring — read-safe tools only"},full:{label:"Full access",scopes:["mcp:read","mcp:full"],hint:"All tools — can modify state"}},b=()=>{i.trim()&&t.mutate({botId:a,name:i.trim(),scopes:o[f].scopes},{onSuccess:g=>{s(g.rawKey),m("")}})},N=()=>{u&&(navigator.clipboard.writeText(u),p(!0),setTimeout(()=>p(!1),2e3))},k=()=>{v&&n.mutate({botId:a,keyId:v.id},{onSuccess:()=>x(null)})};return e.jsxs("div",{children:[e.jsx("p",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-3",children:"API Keys"}),u&&e.jsxs("div",{className:"mb-3 p-3 bg-status-success/10 border border-status-success/30 rounded-md",children:[e.jsx("p",{className:"text-2xs font-semibold text-status-success mb-1",children:"Key generated — copy now, it won't be shown again"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("code",{className:"text-2xs font-mono text-text-primary bg-surface-sunken px-2 py-1 rounded flex-1 min-w-0 overflow-hidden text-ellipsis whitespace-nowrap",children:u}),e.jsx("button",{onClick:N,className:"text-text-tertiary hover:text-text-primary shrink-0",title:"Copy to clipboard",children:j?e.jsx(we,{className:"w-3.5 h-3.5 text-status-success"}):e.jsx(ke,{className:"w-3.5 h-3.5"})})]})]}),y.length===0?e.jsx("p",{className:"text-xs text-text-tertiary mb-3",children:"No API keys."}):e.jsx("div",{className:"space-y-1.5 mb-3",children:y.map(g=>e.jsxs("div",{className:"group/key flex items-center justify-between px-2.5 py-1.5 bg-surface-sunken rounded text-xs",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx(Se,{className:"w-3 h-3 text-text-tertiary"}),e.jsx("span",{className:"text-text-primary font-mono",children:g.name}),(g.scopes??[]).map(l=>e.jsx("span",{className:`px-1.5 py-0.5 rounded text-2xs font-mono ${l.includes("full")?"bg-status-warning/15 text-status-warning":"bg-accent/10 text-accent"}`,children:l},l)),g.last_used_at&&e.jsxs("span",{className:"text-2xs text-text-tertiary",children:["used ",e.jsx(Ne,{date:g.last_used_at})]})]}),e.jsx("button",{onClick:()=>x(g),className:"opacity-0 group-hover/key:opacity-100 transition-opacity text-text-tertiary hover:text-status-error",title:"Revoke key",children:e.jsx(F,{className:"w-3 h-3"})})]},g.id))}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("input",{type:"text",value:i,onChange:g=>m(g.target.value),placeholder:"Key name...",className:"input text-xs font-mono"}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("div",{className:"flex rounded-md border border-surface-border overflow-hidden shrink-0",children:Object.entries(o).map(([g,l])=>e.jsx("button",{type:"button",onClick:()=>h(g),title:l.hint,className:`px-2.5 py-1 text-2xs font-medium transition-colors ${f===g?"bg-accent text-text-inverse":"bg-surface text-text-secondary hover:bg-surface-hover"}`,children:l.label},g))}),e.jsxs("button",{onClick:b,disabled:!i.trim()||t.isPending,className:"btn-primary text-xs inline-flex items-center gap-1 shrink-0",children:[e.jsx(Ce,{className:"w-3 h-3"}),t.isPending?"...":"Generate"]})]})]}),t.error&&e.jsx("p",{className:"text-2xs text-status-error mt-1",children:t.error.message}),e.jsx(I,{open:!!v,onClose:()=>x(null),onConfirm:k,title:"Revoke API Key",description:e.jsxs(e.Fragment,{children:["Revoke API key"," ",e.jsx("span",{className:"font-medium text-text-primary font-mono",children:v==null?void 0:v.name}),"? This bot will no longer be able to authenticate with this key."]}),isPending:n.isPending,error:n.error})]})}function Le({bot:a}){const{data:r}=G(),t=ve(),n=ge(),[i,m]=d.useState(""),[f,h]=d.useState("member"),u=(r==null?void 0:r.roles)??[],s=a.roles??[],j=d.useMemo(()=>{const x=new Set(s.map(y=>y.role));return u.filter(y=>!x.has(y))},[u,s]),p=()=>{i.trim()&&t.mutate({botId:a.id,role:i.trim(),type:f},{onSuccess:()=>{m(""),h("member")}})},v=x=>{n.mutate({botId:a.id,role:x})};return e.jsxs("div",{children:[e.jsx("p",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-3",children:"Roles"}),s.length===0?e.jsx("p",{className:"text-xs text-text-tertiary mb-3",children:"No roles assigned."}):e.jsx("div",{className:"flex flex-wrap gap-2 mb-3",children:s.map(x=>e.jsxs("span",{className:"inline-flex items-center gap-1.5 px-2.5 py-1 text-xs bg-surface-sunken rounded-full text-text-secondary",children:[e.jsx(E,{role:x.role}),e.jsx("span",{className:"text-2xs text-text-tertiary",children:x.type}),e.jsx("button",{onClick:()=>v(x.role),className:"text-text-tertiary hover:text-status-error transition-colors ml-0.5",title:`Remove ${x.role}`,children:"×"})]},x.role))}),j.length>0&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs("select",{value:i,onChange:x=>m(x.target.value),className:"select text-xs font-mono w-full min-w-0","aria-label":"Role",children:[e.jsx("option",{value:"",children:"Select a role..."}),j.map(x=>e.jsx("option",{value:x,children:x},x))]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2 items-end",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("label",{className:"block text-2xs text-text-tertiary mb-1",children:"Type"}),e.jsxs("select",{value:f,onChange:x=>h(x.target.value),className:"select text-xs w-full min-w-0","aria-label":"Role type",children:[e.jsx("option",{value:"member",children:"member"}),e.jsx("option",{value:"admin",children:"admin"}),e.jsx("option",{value:"superadmin",children:"superadmin"})]})]}),e.jsx("div",{className:"flex justify-end",children:e.jsx("button",{onClick:p,disabled:!i||t.isPending,className:"btn-primary text-xs",children:t.isPending?"...":"Add Role"})})]})]}),t.error&&e.jsx("p",{className:"text-2xs text-status-error mt-1",children:t.error.message})]})}function Ge({bot:a}){return a?e.jsxs("div",{className:"border-l border-surface-border pl-6 pt-4 min-h-[300px] space-y-6",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-text-primary",children:a.display_name||a.external_id}),a.description&&e.jsx("p",{className:"text-xs text-text-tertiary mt-0.5",children:a.description})]}),e.jsx(ze,{botId:a.id}),e.jsx(Le,{bot:a})]}):e.jsx("div",{className:"border-l border-surface-border pl-6 pt-4 min-h-[300px]",children:e.jsx("p",{className:"text-xs text-text-tertiary",children:"Select a service account to manage its API keys and roles."})})}const Ve={active:"bg-status-success",inactive:"bg-text-tertiary",suspended:"bg-status-error"},qe=[{value:"active",label:"Active"},{value:"inactive",label:"Inactive"},{value:"suspended",label:"Suspended"}];function Je({embedded:a=!1}){const{filters:r,setFilter:t,pagination:n}=J({filters:{status:"",search:""}}),i=ye(),[m,f]=d.useState(!1),[h,u]=d.useState(null),[s,j]=d.useState(null),[p,v]=d.useState(null),{data:x,isLoading:y}=be({status:r.status||void 0,search:r.search||void 0,limit:n.pageSize,offset:n.offset}),o=(x==null?void 0:x.total)??0,b=(x==null?void 0:x.bots)??[],N=d.useMemo(()=>s?b.find(l=>l.id===s.id)??s:null,[b,s]),k=[{key:"display_name",label:"Service Account",render:l=>e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx("span",{className:`w-2.5 h-2.5 rounded-full dot-ring shrink-0 ${Ve[l.status]??"bg-status-pending"}`,title:l.status}),e.jsx("span",{className:"text-sm text-text-primary whitespace-nowrap",children:l.display_name||l.external_id})]})},{key:"description",label:"Description",render:l=>e.jsx("span",{className:"block max-w-[32rem] truncate text-xs text-text-tertiary",title:l.description??void 0,children:l.description??""})},{key:"roles",label:"Roles",render:l=>e.jsx("div",{className:"flex gap-1 flex-wrap",children:(l.roles??[]).map(S=>e.jsx(E,{role:S.role},S.role))})},{key:"created_at",label:"Created",render:l=>e.jsx(V,{date:l.created_at}),className:"w-36 whitespace-nowrap"},{key:"actions",label:"",render:l=>e.jsxs(Z,{children:[e.jsx(R,{icon:te,title:"Edit service account",onClick:()=>u(l)}),e.jsx(R,{icon:F,title:"Delete service account",onClick:()=>v(l),colorClass:"text-text-tertiary hover:text-status-error"})]}),className:"w-16 text-right"}],g=()=>{p&&i.mutate(p.id,{onSuccess:()=>{v(null),(s==null?void 0:s.id)===p.id&&j(null)}})};return e.jsxs("div",{children:[a?e.jsx("div",{className:"flex justify-end mb-4",children:e.jsx("button",{onClick:()=>f(!0),className:"btn-primary text-xs",children:"Add Service Account"})}):e.jsx(ee,{title:"Service Accounts",actions:e.jsx("button",{onClick:()=>f(!0),className:"btn-primary text-xs",children:"Add Service Account"})}),e.jsxs(Q,{children:[e.jsx(W,{label:"Search",value:r.search,onChange:l=>t("search",l),placeholder:"name, id, description…"}),e.jsx(X,{label:"Status",value:r.status,onChange:l=>t("status",l),options:qe})]}),e.jsxs("div",{className:"grid grid-cols-1 @split:grid-cols-[1fr_360px] gap-6 items-start",children:[e.jsxs("div",{className:"overflow-x-clip",children:[e.jsx(H,{columns:k,data:b,keyFn:l=>l.id,isLoading:y,emptyMessage:"No service accounts yet",onRowClick:l=>j(l),activeRowKey:(N==null?void 0:N.id)??null}),e.jsx(Y,{page:n.page,totalPages:n.totalPages(o),onPageChange:n.setPage,total:o,pageSize:n.pageSize,onPageSizeChange:n.setPageSize})]}),e.jsx("div",{className:"sticky top-4",children:e.jsx(Ge,{bot:N})})]}),e.jsx(Oe,{open:m,onClose:()=>f(!1)}),e.jsx($e,{open:!!h,onClose:()=>u(null),bot:h}),e.jsx(I,{open:!!p,onClose:()=>v(null),onConfirm:g,title:"Delete Service Account",description:e.jsxs(e.Fragment,{children:["Delete"," ",e.jsx("span",{className:"font-medium text-text-primary",children:(p==null?void 0:p.display_name)||(p==null?void 0:p.external_id)}),"? This will also revoke all API keys. This action cannot be undone."]}),isPending:i.isPending,error:i.error})]})}function He({value:a,systemKeys:r=[],pending:t=!1,error:n,onPatch:i}){const m=Object.entries(a??{}),f=new Set(r),[h,u]=d.useState(null),[s,j]=d.useState(""),[p,v]=d.useState(""),[x,y]=d.useState(null),[o,b]=d.useState(null),[N,k]=d.useState(""),[g,l]=d.useState(""),[S,C]=d.useState(null),P=c=>typeof c=="string"?c:JSON.stringify(c),O=c=>{const w=c.trim();try{return JSON.parse(w)}catch{return w}};function $(c){if(f.has(c)&&o!==c){b(c);return}b(null),u(c),j(c),v(P((a??{})[c])),y(null),C(null)}function ae(){if(h===null)return;const c=s.trim();if(!c){C("Property name is required");return}if(c!==h&&m.some(([B])=>B===c)){C(`"${c}" already exists`);return}const w={};c!==h&&(w.rename={[h]:c});const _=O(p);if((P(_)!==P((a??{})[h])||c!==h)&&P(_)!==P((a??{})[h])&&(w.set={[c]:_}),!w.set&&!w.rename){U();return}i(w),U()}function U(){u(null),j(""),v(""),C(null)}function z(){const c=N.trim();if(!c){C("Property name is required");return}if(m.some(([w])=>w===c)){C(`"${c}" already exists`);return}i({set:{[c]:O(g)}}),k(""),l(""),C(null)}return e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary",children:"Properties"}),m.length===0&&e.jsx("p",{className:"text-xs text-text-tertiary italic",children:"No properties — add one below."}),m.map(([c,w])=>{const _=f.has(c),B=h===c,ne=x===c;return e.jsx("div",{className:"group text-xs",children:B?e.jsxs("div",{className:"space-y-1.5 border-l-2 border-l-accent pl-2",children:[e.jsx("input",{value:s,onChange:D=>j(D.target.value),"aria-label":"Property name",className:"input text-xs w-full min-w-0 font-mono"}),e.jsx("input",{value:p,onChange:D=>v(D.target.value),"aria-label":"Property value",placeholder:"value (string or JSON)",className:"input text-xs w-full min-w-0"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{onClick:ae,disabled:t,className:"text-2xs font-medium text-accent hover:text-accent-hover",children:t?"Saving...":"Save"}),e.jsx("button",{onClick:U,className:"text-2xs text-text-tertiary hover:text-text-secondary",children:"Cancel"}),e.jsx("button",{onClick:()=>{y(c),u(null)},className:"text-2xs text-status-error/50 hover:text-status-error ml-auto",children:"Remove"})]})]}):ne?e.jsxs("span",{className:"flex items-center gap-2 text-2xs",children:[e.jsxs("span",{className:"text-status-error",children:["Remove ",e.jsx("span",{className:"font-medium font-mono",children:c}),"?"]}),e.jsx("button",{onClick:()=>{i({remove:[c]}),y(null)},disabled:t,className:"font-medium text-status-error hover:text-status-error/80",children:t?"...":"Yes"}),e.jsx("button",{onClick:()=>y(null),className:"text-text-tertiary hover:text-text-secondary",children:"No"})]}):o===c?e.jsxs("span",{className:"flex items-center gap-2 text-2xs",children:[e.jsxs("span",{className:"text-text-secondary",children:[e.jsx("span",{className:"font-mono font-medium",children:c})," is a system property — the platform resolves identities with it. Edit?"]}),e.jsx("button",{onClick:()=>$(c),className:"font-medium text-accent hover:text-accent-hover",children:"Edit"}),e.jsx("button",{onClick:()=>b(null),className:"text-text-tertiary hover:text-text-secondary",children:"Cancel"})]}):e.jsxs("button",{onClick:()=>$(c),className:"flex items-center gap-2 w-full min-w-0 text-left rounded px-1 py-0.5 -mx-1 hover:bg-surface-hover transition-colors",title:`Edit ${c}`,children:[e.jsx("span",{className:"font-mono font-medium text-text-secondary shrink-0",children:c}),_&&e.jsx("span",{className:"shrink-0 text-accent/80",title:"system",children:e.jsx(Pe,{className:"w-3 h-3","aria-label":"system"})}),e.jsx("span",{className:"flex-1 min-w-0 truncate text-right text-text-primary tabular-nums",children:P(w)})]})},c)}),e.jsxs("div",{className:"pt-1.5 border-t border-surface-border space-y-1.5",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsx("input",{value:N,onChange:c=>k(c.target.value),placeholder:"property","aria-label":"New property name",className:"input text-xs w-full min-w-0 font-mono"}),e.jsx("input",{value:g,onChange:c=>l(c.target.value),onKeyDown:c=>{c.key==="Enter"&&z()},placeholder:"value","aria-label":"New property value",className:"input text-xs w-full min-w-0"})]}),N.trim()&&e.jsx("div",{className:"flex justify-end",children:e.jsx("button",{onClick:z,disabled:t,className:"btn-primary text-xs",children:t?"...":"Add Property"})})]}),(S||n)&&e.jsx("p",{role:"alert",className:"text-2xs text-status-error",children:S||n})]})}const T=[{value:"all|all",label:"See all · act on all",read_scope:"all",write_scope:"all"},{value:"all|self",label:"See all · act on self",read_scope:"all",write_scope:"self"},{value:"self|self",label:"See self · act on self",read_scope:"self",write_scope:"self"},{value:"all|none",label:"See all · read-only",read_scope:"all",write_scope:"none"},{value:"self|none",label:"See self · read-only",read_scope:"self",write_scope:"none"}],K="all|all";function L(a){return T.find(r=>r.value===a)??T[0]}function M({children:a}){return e.jsx("div",{className:"border border-surface-border bg-surface-sunken rounded-[var(--lt-radius-section)] p-4",children:a})}function Ye({user:a}){const r=oe(),{data:t}=de();return e.jsx(M,{children:e.jsx(He,{value:a.metadata??{},systemKeys:(t==null?void 0:t.keys)??[],pending:r.isPending,error:r.error?r.error.message:null,onPatch:n=>r.mutate({id:a.id,ops:n})})})}function Qe({user:a}){const{data:r}=Ae(),{data:t}=Ee(a.id),n=Ue(),i=Be(),[m,f]=d.useState(""),h=(t==null?void 0:t.personas)??[],u=d.useMemo(()=>{const s=new Set(h.map(j=>j.key));return((r==null?void 0:r.personas)??[]).filter(j=>!s.has(j.key))},[r,h]);return h.length===0&&u.length===0?null:e.jsx(M,{children:e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary",children:"Personas"}),h.length>0&&e.jsx("div",{className:"flex flex-col gap-2",children:h.map(s=>e.jsxs("span",{className:"flex items-center gap-2.5 w-full min-w-0 pl-2.5 pr-2 py-1 text-xs bg-surface-sunken rounded-full text-text-secondary",children:[e.jsx(se,{className:"w-3 h-3 shrink-0 text-text-tertiary","aria-hidden":!0}),e.jsx(Ke,{to:`/admin/personas/${encodeURIComponent(s.key)}`,className:"flex-1 min-w-0 truncate transition-colors hover:text-accent",title:s.key,children:s.title||s.key}),e.jsxs("span",{className:"shrink-0 text-2xs text-text-tertiary tabular-nums",children:[s.roles.length," role",s.roles.length===1?"":"s"]}),e.jsx("button",{onClick:()=>i.mutate({userId:a.id,key:s.key}),className:"shrink-0 text-text-tertiary hover:text-status-error transition-colors ml-1",title:`Unassign ${s.title||s.key}`,children:"×"})]},s.key))}),u.length>0&&e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("select",{value:m,onChange:s=>f(s.target.value),className:"select text-xs w-full min-w-0","aria-label":"Persona",children:[e.jsx("option",{value:"",children:"Assign a persona..."}),u.map(s=>e.jsx("option",{value:s.key,children:s.title||s.key},s.key))]}),e.jsx("button",{onClick:()=>{m&&n.mutate({userId:a.id,key:m},{onSuccess:()=>f("")})},disabled:!m||n.isPending,className:"btn-primary text-xs shrink-0",children:n.isPending?"...":"Assign"})]}),(n.error||i.error)&&e.jsx("p",{className:"text-2xs text-status-error",children:(n.error||i.error).message})]})})}function We({user:a}){const{data:r}=G(),t=ie(),n=ce(),[i,m]=d.useState(""),[f,h]=d.useState("member"),[u,s]=d.useState(K),j=(r==null?void 0:r.roles)??[],p=(a==null?void 0:a.roles)??[],v=d.useMemo(()=>{const o=new Set(p.map(b=>b.role));return j.filter(b=>!o.has(b))},[j,p]),x=()=>{if(!a||!i.trim())return;const o=L(f==="member"?u:K);t.mutate({userId:a.id,role:i.trim(),type:f,read_scope:o.read_scope,write_scope:o.write_scope},{onSuccess:()=>{m(""),h("member"),s(K)}})},y=o=>{a&&n.mutate({userId:a.id,role:o})};return e.jsxs("div",{className:"border-l border-surface-border pl-6 pt-4 pb-8 min-h-[300px]",children:[e.jsx("p",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-4",children:"Role Membership"}),a?e.jsxs("div",{className:"space-y-6",children:[e.jsx("div",{children:e.jsx("p",{className:"text-sm text-text-primary",children:a.display_name||a.external_id})}),e.jsx(Qe,{user:a}),e.jsx(M,{children:e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary",children:"Roles"}),p.length===0?e.jsx("p",{className:"text-xs text-text-tertiary",children:"No roles assigned."}):e.jsx("div",{className:"flex flex-col gap-2",children:p.map(o=>e.jsxs("span",{className:"flex items-center gap-2.5 w-full min-w-0 pl-2.5 pr-2 py-1 text-xs bg-surface-sunken rounded-full text-text-secondary",children:[e.jsx("span",{className:"flex-1 min-w-0 truncate",title:o.role,children:e.jsx(E,{role:o.role,tone:"inherit"})}),e.jsx("span",{className:"w-14 shrink-0 text-2xs uppercase tracking-wide text-text-tertiary",children:o.type}),o.type==="member"&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"w-px h-3 bg-surface-border shrink-0","aria-hidden":!0}),e.jsx(De,{read:o.read_scope,write:o.write_scope,className:"shrink-0"})]}),o.granted_by_persona&&e.jsx("span",{className:"shrink-0",title:`Granted by persona ${o.granted_by_persona}`,children:e.jsx(se,{className:"w-3 h-3 text-text-tertiary","aria-hidden":!0})}),e.jsx("button",{onClick:()=>y(o.role),className:"shrink-0 text-text-tertiary hover:text-status-error transition-colors ml-1",title:`Remove ${o.role}`,children:"×"})]},o.role))}),v.length>0&&e.jsxs("div",{className:"pt-3 border-t border-surface-border space-y-2",children:[e.jsx("p",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary",children:"Add Role"}),e.jsxs("select",{value:i,onChange:o=>m(o.target.value),className:"select text-xs font-mono w-full min-w-0","aria-label":"Role",children:[e.jsx("option",{value:"",children:"Select a role..."}),v.map(o=>e.jsx("option",{value:o,children:o},o))]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("label",{className:"block text-2xs text-text-tertiary mb-1",children:"Type"}),e.jsxs("select",{value:f,onChange:o=>h(o.target.value),className:"select text-xs w-full min-w-0","aria-label":"Role type",children:[e.jsx("option",{value:"member",children:"member"}),e.jsx("option",{value:"admin",children:"admin"}),e.jsx("option",{value:"superadmin",children:"superadmin"})]})]}),f==="member"&&e.jsxs("div",{className:"min-w-0",children:[e.jsx("label",{className:"block text-2xs text-text-tertiary mb-1",children:"Scope"}),e.jsx("select",{value:u,onChange:o=>s(o.target.value),className:"select text-xs w-full min-w-0","aria-label":"Work-surface scope",children:T.map(o=>e.jsx("option",{value:o.value,children:o.label},o.value))})]})]}),e.jsx("div",{className:"flex justify-end pt-1",children:e.jsx("button",{onClick:x,disabled:!i||t.isPending,className:"btn-primary text-xs",children:t.isPending?"...":"Add Role"})}),t.error&&e.jsx("p",{className:"text-2xs text-status-error",children:t.error.message})]})]})}),e.jsx(Ye,{user:a})]}):e.jsx("p",{className:"text-xs text-text-tertiary",children:"Select a user to manage their roles."})]})}function Xe({active:a,onChange:r}){return e.jsx(Ie,{"aria-label":"Account kind",active:a,onChange:r,tabs:[{key:"users",label:"User Accounts",icon:e.jsx(_e,{className:"w-3.5 h-3.5"})},{key:"service-accounts",label:"Service Accounts",icon:e.jsx(Re,{className:"w-3.5 h-3.5"})}]})}const Ze=[{value:"active",label:"Active"},{value:"inactive",label:"Inactive"},{value:"suspended",label:"Suspended"}],et={active:"bg-status-success",inactive:"bg-text-tertiary",suspended:"bg-status-error"};function bt(){const{isBuilder:a}=q(),[r,t]=Te(),n=r.get("tab"),i=a&&n==="service-accounts"?"service-accounts":"users",m=f=>{t(f==="users"?{}:{tab:f})};return e.jsxs("div",{children:[e.jsx(ee,{title:"Accounts",docsHash:"#docs:dashboard.md:accounts",actions:a?e.jsx(Xe,{active:i,onChange:m}):void 0}),i==="users"?e.jsx(tt,{}):e.jsx(Je,{embedded:!0})]})}function tt(){const{isBuilder:a}=q(),{filters:r,setFilter:t,pagination:n}=J({filters:{status:"",search:""}}),i=xe(),[m,f]=d.useState(!1),[h,u]=d.useState(null),[s,j]=d.useState(null),[p,v]=d.useState(null),{data:x,isLoading:y}=me({status:r.status||void 0,search:r.search||void 0,limit:n.pageSize,offset:n.offset}),o=(x==null?void 0:x.total)??0,b=(x==null?void 0:x.users)??[],N=d.useMemo(()=>s?b.find(l=>l.id===s.id)??s:null,[b,s]),k=[{key:"display_name",label:"User",render:l=>e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx("span",{className:`w-2.5 h-2.5 rounded-full dot-ring shrink-0 ${et[l.status]??"bg-status-pending"}`,title:l.status}),e.jsx("span",{className:"text-xs text-text-primary whitespace-nowrap",children:l.display_name||l.external_id})]})},{key:"email",label:"Email",render:l=>l.email?e.jsx("span",{className:"text-xs text-text-secondary whitespace-nowrap",children:l.email}):e.jsx("span",{className:"text-xs text-text-quaternary",children:"—"})},{key:"roles",label:"Roles",render:l=>e.jsx("div",{className:"flex gap-2 flex-wrap",children:(l.roles??[]).map(S=>e.jsx(E,{role:S.role,size:"md"},S.role))})},{key:"created_at",label:"Created",render:l=>e.jsx(V,{date:l.created_at}),className:"w-36 whitespace-nowrap"},...a?[{key:"actions",label:"",render:l=>e.jsxs(Z,{children:[e.jsx(R,{icon:te,title:"Edit user",onClick:()=>u(l)}),e.jsx(R,{icon:F,title:"Delete user",onClick:()=>v(l),colorClass:"text-text-tertiary hover:text-status-error"})]}),className:"w-16 text-right"}]:[]],g=()=>{p&&i.mutate(p.id,{onSuccess:()=>v(null)})};return e.jsxs("div",{children:[a&&e.jsx("div",{className:"flex justify-end mb-4",children:e.jsx("button",{onClick:()=>f(!0),className:"btn-primary text-xs",children:"Add User"})}),e.jsxs(Q,{children:[e.jsx(W,{label:"Search",value:r.search,onChange:l=>t("search",l),placeholder:"name, email, id…"}),e.jsx(X,{label:"Status",value:r.status,onChange:l=>t("status",l),options:Ze})]}),e.jsxs("div",{className:"grid grid-cols-1 @split:grid-cols-[1fr_460px] gap-6 items-start",children:[e.jsxs("div",{className:"overflow-x-clip",children:[e.jsx(H,{columns:k,data:b,keyFn:l=>l.id,isLoading:y,emptyMessage:"No users found",onRowClick:l=>j(l),activeRowKey:(N==null?void 0:N.id)??null}),e.jsx(Y,{page:n.page,totalPages:n.totalPages(o),onPageChange:n.setPage,total:o,pageSize:n.pageSize,onPageSizeChange:n.setPageSize})]}),e.jsx("div",{className:"sticky top-4",children:e.jsx(We,{user:N})})]}),e.jsx(Fe,{open:m,onClose:()=>f(!1)}),e.jsx(Me,{open:!!h,onClose:()=>u(null),user:h}),e.jsx(I,{open:!!p,onClose:()=>v(null),onConfirm:g,title:"Delete User",description:e.jsxs(e.Fragment,{children:["Delete"," ",e.jsx("span",{className:"font-medium text-text-primary",children:(p==null?void 0:p.display_name)||(p==null?void 0:p.external_id)}),"? This action cannot be undone."]}),isPending:i.isPending,error:i.error})]})}export{bt as UsersPage};
2
+ //# sourceMappingURL=index-B95LbYhW.js.map