@hotmeshio/long-tail 0.10.0 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/build/api/me.d.ts +16 -0
  2. package/build/api/me.js +79 -0
  3. package/build/api/roles.d.ts +6 -0
  4. package/build/api/roles.js +10 -0
  5. package/build/lib/db/schemas/022_user_preferences.sql +18 -0
  6. package/build/routes/index.js +2 -0
  7. package/build/routes/me.d.ts +2 -0
  8. package/build/routes/me.js +57 -0
  9. package/build/sdk/index.d.ts +6 -0
  10. package/build/sdk/index.js +11 -0
  11. package/build/services/role/index.js +1 -0
  12. package/build/services/role/sql.d.ts +5 -2
  13. package/build/services/role/sql.js +7 -1
  14. package/build/services/role/types.d.ts +16 -0
  15. package/build/services/user/index.d.ts +1 -0
  16. package/build/services/user/index.js +5 -1
  17. package/build/services/user/preferences.d.ts +15 -0
  18. package/build/services/user/preferences.js +38 -0
  19. package/build/system/mcp-servers/admin/schemas.d.ts +26 -0
  20. package/build/system/mcp-servers/admin/schemas.js +6 -0
  21. package/build/system/mcp-servers/admin/users.js +6 -3
  22. package/build/system/seed/tool-manifests-admin.d.ts +167 -0
  23. package/build/system/seed/tool-manifests-admin.js +1 -1
  24. package/build/tsconfig.tsbuildinfo +1 -1
  25. package/dashboard/dist/assets/{AdminDashboard-DQS74RL0.js → AdminDashboard-Dy031e9g.js} +2 -2
  26. package/dashboard/dist/assets/{AdminDashboard-DQS74RL0.js.map → AdminDashboard-Dy031e9g.js.map} +1 -1
  27. package/dashboard/dist/assets/{AgentConfigPage-CSMCrFR4.js → AgentConfigPage-CqmtYBbC.js} +6 -6
  28. package/dashboard/dist/assets/{AgentConfigPage-CSMCrFR4.js.map → AgentConfigPage-CqmtYBbC.js.map} +1 -1
  29. package/dashboard/dist/assets/{AgentDetailPage-CDiopQ7D.js → AgentDetailPage-oYLBrN74.js} +3 -3
  30. package/dashboard/dist/assets/{AgentDetailPage-CDiopQ7D.js.map → AgentDetailPage-oYLBrN74.js.map} +1 -1
  31. package/dashboard/dist/assets/{AgentsPage-CyUXe9n4.js → AgentsPage-CHczRx5N.js} +2 -2
  32. package/dashboard/dist/assets/{AgentsPage-CyUXe9n4.js.map → AgentsPage-CHczRx5N.js.map} +1 -1
  33. package/dashboard/dist/assets/AvailableEscalationsPage-DDVuivEE.js +2 -0
  34. package/dashboard/dist/assets/AvailableEscalationsPage-DDVuivEE.js.map +1 -0
  35. package/dashboard/dist/assets/BotPicker-2QEIpc-K.js +2 -0
  36. package/dashboard/dist/assets/{BotPicker-BuCGvEed.js.map → BotPicker-2QEIpc-K.js.map} +1 -1
  37. package/dashboard/dist/assets/{CapabilitiesPage-nTv4STcG.js → CapabilitiesPage-lQJGZ_-t.js} +2 -2
  38. package/dashboard/dist/assets/{CapabilitiesPage-nTv4STcG.js.map → CapabilitiesPage-lQJGZ_-t.js.map} +1 -1
  39. package/dashboard/dist/assets/{CollapsibleSection-CkOks9Cf.js → CollapsibleSection-CHWP0WI6.js} +2 -2
  40. package/dashboard/dist/assets/{CollapsibleSection-CkOks9Cf.js.map → CollapsibleSection-CHWP0WI6.js.map} +1 -1
  41. package/dashboard/dist/assets/CountdownTimer-TXsRlTU4.js +2 -0
  42. package/dashboard/dist/assets/CountdownTimer-TXsRlTU4.js.map +1 -0
  43. package/dashboard/dist/assets/{CredentialsPage-BwA7k9Cb.js → CredentialsPage-BKxS-1sA.js} +2 -2
  44. package/dashboard/dist/assets/{CredentialsPage-BwA7k9Cb.js.map → CredentialsPage-BKxS-1sA.js.map} +1 -1
  45. package/dashboard/dist/assets/{CronLabel-jC_i-Lh9.js → CronLabel-Bd2G0Rap.js} +2 -2
  46. package/dashboard/dist/assets/{CronLabel-jC_i-Lh9.js.map → CronLabel-Bd2G0Rap.js.map} +1 -1
  47. package/dashboard/dist/assets/{CustomDurationPicker-F6bR2Q5A.js → CustomDurationPicker-j4bBrDJ6.js} +2 -2
  48. package/dashboard/dist/assets/{CustomDurationPicker-F6bR2Q5A.js.map → CustomDurationPicker-j4bBrDJ6.js.map} +1 -1
  49. package/dashboard/dist/assets/{DropZone-zxH-9B8c.js → DropZone-DNDEgMpJ.js} +2 -2
  50. package/dashboard/dist/assets/{DropZone-zxH-9B8c.js.map → DropZone-DNDEgMpJ.js.map} +1 -1
  51. package/dashboard/dist/assets/{ElapsedCell-DZ3RTZFc.js → ElapsedCell-g7GO7f8L.js} +2 -2
  52. package/dashboard/dist/assets/{ElapsedCell-DZ3RTZFc.js.map → ElapsedCell-g7GO7f8L.js.map} +1 -1
  53. package/dashboard/dist/assets/{EscalationListSchemaPage-CaMydHIO.js → EscalationListSchemaPage-CIJ-OgVC.js} +3 -3
  54. package/dashboard/dist/assets/{EscalationListSchemaPage-CaMydHIO.js.map → EscalationListSchemaPage-CIJ-OgVC.js.map} +1 -1
  55. package/dashboard/dist/assets/{EscalationSchemaPage-BlMx2WE6.js → EscalationSchemaPage-C7dHgG8e.js} +3 -3
  56. package/dashboard/dist/assets/{EscalationSchemaPage-BlMx2WE6.js.map → EscalationSchemaPage-C7dHgG8e.js.map} +1 -1
  57. package/dashboard/dist/assets/{EscalationsOverview-DcMkbiSo.js → EscalationsOverview-D8NrATg2.js} +2 -2
  58. package/dashboard/dist/assets/{EscalationsOverview-DcMkbiSo.js.map → EscalationsOverview-D8NrATg2.js.map} +1 -1
  59. package/dashboard/dist/assets/{EventTable-CuZ2Q_wH.js → EventTable-DBV1P2ME.js} +2 -2
  60. package/dashboard/dist/assets/{EventTable-CuZ2Q_wH.js.map → EventTable-DBV1P2ME.js.map} +1 -1
  61. package/dashboard/dist/assets/{GraphInvokePage-CXElQqcV.js → GraphInvokePage-DbHvggQ_.js} +2 -2
  62. package/dashboard/dist/assets/{GraphInvokePage-CXElQqcV.js.map → GraphInvokePage-DbHvggQ_.js.map} +1 -1
  63. package/dashboard/dist/assets/{HomePage-DcWfjZA-.js → HomePage-BpexnDO_.js} +2 -2
  64. package/dashboard/dist/assets/{HomePage-DcWfjZA-.js.map → HomePage-BpexnDO_.js.map} +1 -1
  65. package/dashboard/dist/assets/ListToolbar-KC6LGtKP.js +2 -0
  66. package/dashboard/dist/assets/{ListToolbar-Dmd1UiM-.js.map → ListToolbar-KC6LGtKP.js.map} +1 -1
  67. package/dashboard/dist/assets/{McpOverview-Cul2LFEw.js → McpOverview-BDZC9Hvl.js} +2 -2
  68. package/dashboard/dist/assets/{McpOverview-Cul2LFEw.js.map → McpOverview-BDZC9Hvl.js.map} +1 -1
  69. package/dashboard/dist/assets/{McpQueryDetailPage-BVlQ0WBa.js → McpQueryDetailPage-CXhgX1pS.js} +2 -2
  70. package/dashboard/dist/assets/{McpQueryDetailPage-BVlQ0WBa.js.map → McpQueryDetailPage-CXhgX1pS.js.map} +1 -1
  71. package/dashboard/dist/assets/{McpQueryPage-B7PmO_V-.js → McpQueryPage-CsKNXUhb.js} +2 -2
  72. package/dashboard/dist/assets/{McpQueryPage-B7PmO_V-.js.map → McpQueryPage-CsKNXUhb.js.map} +1 -1
  73. package/dashboard/dist/assets/{McpRunDetailPage-B1RhxxlU.js → McpRunDetailPage-BM3mUSlH.js} +2 -2
  74. package/dashboard/dist/assets/{McpRunDetailPage-B1RhxxlU.js.map → McpRunDetailPage-BM3mUSlH.js.map} +1 -1
  75. package/dashboard/dist/assets/{McpRunsPage-DlSrpxiv.js → McpRunsPage-f5hDbpLo.js} +2 -2
  76. package/dashboard/dist/assets/{McpRunsPage-DlSrpxiv.js.map → McpRunsPage-f5hDbpLo.js.map} +1 -1
  77. package/dashboard/dist/assets/{NamespacePill-BQNMfY0m.js → NamespacePill-C4u6Go1W.js} +2 -2
  78. package/dashboard/dist/assets/{NamespacePill-BQNMfY0m.js.map → NamespacePill-C4u6Go1W.js.map} +1 -1
  79. package/dashboard/dist/assets/OperationsPage-D37cZ8Qh.js +2 -0
  80. package/dashboard/dist/assets/{OperationsPage-vm_ByX41.js.map → OperationsPage-D37cZ8Qh.js.map} +1 -1
  81. package/dashboard/dist/assets/OperatorDashboard-_axS17fp.js +2 -0
  82. package/dashboard/dist/assets/{OperatorDashboard-zviIxH-0.js.map → OperatorDashboard-_axS17fp.js.map} +1 -1
  83. package/dashboard/dist/assets/{PageHeader-BIY1YvKR.js → PageHeader-Bxa1XFz0.js} +2 -2
  84. package/dashboard/dist/assets/{PageHeader-BIY1YvKR.js.map → PageHeader-Bxa1XFz0.js.map} +1 -1
  85. package/dashboard/dist/assets/{PageHeaderWithStats-TUyglVW0.js → PageHeaderWithStats-D_sO0MqJ.js} +2 -2
  86. package/dashboard/dist/assets/{PageHeaderWithStats-TUyglVW0.js.map → PageHeaderWithStats-D_sO0MqJ.js.map} +1 -1
  87. package/dashboard/dist/assets/{ProcessDetailPage-txiMHbMI.js → ProcessDetailPage-D8pAWUXx.js} +2 -2
  88. package/dashboard/dist/assets/{ProcessDetailPage-txiMHbMI.js.map → ProcessDetailPage-D8pAWUXx.js.map} +1 -1
  89. package/dashboard/dist/assets/{ProcessesListPage-CRttlU3L.js → ProcessesListPage-CoQEi_Su.js} +2 -2
  90. package/dashboard/dist/assets/{ProcessesListPage-CRttlU3L.js.map → ProcessesListPage-CoQEi_Su.js.map} +1 -1
  91. package/dashboard/dist/assets/RoleDetailPage-ufbypNNR.js +8 -0
  92. package/dashboard/dist/assets/RoleDetailPage-ufbypNNR.js.map +1 -0
  93. package/dashboard/dist/assets/{RolePill-4LO_CuO3.js → RolePill-DLwmVMam.js} +2 -2
  94. package/dashboard/dist/assets/{RolePill-4LO_CuO3.js.map → RolePill-DLwmVMam.js.map} +1 -1
  95. package/dashboard/dist/assets/RolesPage-CxpXm4Sw.js +2 -0
  96. package/dashboard/dist/assets/{RolesPage-DzrSv6m-.js.map → RolesPage-CxpXm4Sw.js.map} +1 -1
  97. package/dashboard/dist/assets/RunAsSelector-BebF8Lib.js +2 -0
  98. package/dashboard/dist/assets/{RunAsSelector-CiLjlmIE.js.map → RunAsSelector-BebF8Lib.js.map} +1 -1
  99. package/dashboard/dist/assets/{SlidePanel-DK4sWXmp.js → SlidePanel-BDVDuwIf.js} +2 -2
  100. package/dashboard/dist/assets/{SlidePanel-DK4sWXmp.js.map → SlidePanel-BDVDuwIf.js.map} +1 -1
  101. package/dashboard/dist/assets/{StickyPagination-Di6b2GDE.js → StickyPagination-Cd83AHd_.js} +2 -2
  102. package/dashboard/dist/assets/{StickyPagination-Di6b2GDE.js.map → StickyPagination-Cd83AHd_.js.map} +1 -1
  103. package/dashboard/dist/assets/{StreamMessageDetail-BbkU45X_.js → StreamMessageDetail-BIXbrZM0.js} +2 -2
  104. package/dashboard/dist/assets/{StreamMessageDetail-BbkU45X_.js.map → StreamMessageDetail-BIXbrZM0.js.map} +1 -1
  105. package/dashboard/dist/assets/{SwimlaneTimeline-BzsvdstG.js → SwimlaneTimeline-CC5qZjYo.js} +2 -2
  106. package/dashboard/dist/assets/{SwimlaneTimeline-BzsvdstG.js.map → SwimlaneTimeline-CC5qZjYo.js.map} +1 -1
  107. package/dashboard/dist/assets/{TagInput-CK-JhBG2.js → TagInput-C2gi47M8.js} +2 -2
  108. package/dashboard/dist/assets/{TagInput-CK-JhBG2.js.map → TagInput-C2gi47M8.js.map} +1 -1
  109. package/dashboard/dist/assets/{TaskDetailPage-Biikk9o_.js → TaskDetailPage-DnjhW7qv.js} +2 -2
  110. package/dashboard/dist/assets/{TaskDetailPage-Biikk9o_.js.map → TaskDetailPage-DnjhW7qv.js.map} +1 -1
  111. package/dashboard/dist/assets/{TaskQueuePill-C_Vo2Clc.js → TaskQueuePill-BPP0Almh.js} +2 -2
  112. package/dashboard/dist/assets/{TaskQueuePill-C_Vo2Clc.js.map → TaskQueuePill-BPP0Almh.js.map} +1 -1
  113. package/dashboard/dist/assets/{TasksListPage-t9WAft9-.js → TasksListPage-DySfZFgs.js} +2 -2
  114. package/dashboard/dist/assets/{TasksListPage-t9WAft9-.js.map → TasksListPage-DySfZFgs.js.map} +1 -1
  115. package/dashboard/dist/assets/{TimeAgo-I7X6jdne.js → TimeAgo-BKOl-7Tt.js} +2 -2
  116. package/dashboard/dist/assets/{TimeAgo-I7X6jdne.js.map → TimeAgo-BKOl-7Tt.js.map} +1 -1
  117. package/dashboard/dist/assets/{TimestampCell-Cex9nr0t.js → TimestampCell-DGOsba-A.js} +2 -2
  118. package/dashboard/dist/assets/{TimestampCell-Cex9nr0t.js.map → TimestampCell-DGOsba-A.js.map} +1 -1
  119. package/dashboard/dist/assets/ToolPill-D74TkYB-.js +2 -0
  120. package/dashboard/dist/assets/{ToolPill-BCi101Jh.js.map → ToolPill-D74TkYB-.js.map} +1 -1
  121. package/dashboard/dist/assets/{ToolTestPanel--MGaDY-1.js → ToolTestPanel-Bez6OyRL.js} +2 -2
  122. package/dashboard/dist/assets/{ToolTestPanel--MGaDY-1.js.map → ToolTestPanel-Bez6OyRL.js.map} +1 -1
  123. package/dashboard/dist/assets/{TopicDetailPage-B8pHHweA.js → TopicDetailPage-BHccgkU_.js} +2 -2
  124. package/dashboard/dist/assets/{TopicDetailPage-B8pHHweA.js.map → TopicDetailPage-BHccgkU_.js.map} +1 -1
  125. package/dashboard/dist/assets/{TopicsPage-tiOEQz2m.js → TopicsPage-5yW63ELl.js} +2 -2
  126. package/dashboard/dist/assets/{TopicsPage-tiOEQz2m.js.map → TopicsPage-5yW63ELl.js.map} +1 -1
  127. package/dashboard/dist/assets/{UserName-Cdhyuv5K.js → UserName-DcXhOSVm.js} +2 -2
  128. package/dashboard/dist/assets/{UserName-Cdhyuv5K.js.map → UserName-DcXhOSVm.js.map} +1 -1
  129. package/dashboard/dist/assets/{WorkflowExecutionPage-DD1BKj5k.js → WorkflowExecutionPage-CDDLled5.js} +2 -2
  130. package/dashboard/dist/assets/{WorkflowExecutionPage-DD1BKj5k.js.map → WorkflowExecutionPage-CDDLled5.js.map} +1 -1
  131. package/dashboard/dist/assets/WorkflowPill-Fjc2q9U9.js +2 -0
  132. package/dashboard/dist/assets/{WorkflowPill-DHxrAkp3.js.map → WorkflowPill-Fjc2q9U9.js.map} +1 -1
  133. package/dashboard/dist/assets/{WorkflowsDashboard-BeWjDHYW.js → WorkflowsDashboard-C0Bbrd5M.js} +2 -2
  134. package/dashboard/dist/assets/{WorkflowsDashboard-BeWjDHYW.js.map → WorkflowsDashboard-C0Bbrd5M.js.map} +1 -1
  135. package/dashboard/dist/assets/{WorkflowsOverview-CkI-Pmj7.js → WorkflowsOverview-D8MkSMex.js} +2 -2
  136. package/dashboard/dist/assets/{WorkflowsOverview-CkI-Pmj7.js.map → WorkflowsOverview-D8MkSMex.js.map} +1 -1
  137. package/dashboard/dist/assets/{YamlWorkflowDetailPage-BQnO8-PQ.js → YamlWorkflowDetailPage-BcbrYhDI.js} +11 -11
  138. package/dashboard/dist/assets/{YamlWorkflowDetailPage-BQnO8-PQ.js.map → YamlWorkflowDetailPage-BcbrYhDI.js.map} +1 -1
  139. package/dashboard/dist/assets/{YamlWorkflowsPage-DjmNTQ5r.js → YamlWorkflowsPage-9Ki54d-9.js} +2 -2
  140. package/dashboard/dist/assets/{YamlWorkflowsPage-DjmNTQ5r.js.map → YamlWorkflowsPage-9Ki54d-9.js.map} +1 -1
  141. package/dashboard/dist/assets/{agents-2DaoprdB.js → agents-CopQ3t5o.js} +2 -2
  142. package/dashboard/dist/assets/{agents-2DaoprdB.js.map → agents-CopQ3t5o.js.map} +1 -1
  143. package/dashboard/dist/assets/{bots-BdwLwMUg.js → bots-CAYJYL9E.js} +2 -2
  144. package/dashboard/dist/assets/{bots-BdwLwMUg.js.map → bots-CAYJYL9E.js.map} +1 -1
  145. package/dashboard/dist/assets/{capabilities-BsuFeK9J.js → capabilities-5JRieYUy.js} +2 -2
  146. package/dashboard/dist/assets/{capabilities-BsuFeK9J.js.map → capabilities-5JRieYUy.js.map} +1 -1
  147. package/dashboard/dist/assets/{controlplane-CxKOrcFO.js → controlplane-B4rT6tIw.js} +2 -2
  148. package/dashboard/dist/assets/{controlplane-CxKOrcFO.js.map → controlplane-B4rT6tIw.js.map} +1 -1
  149. package/dashboard/dist/assets/{escalation-columns-y5SQ2Ulh.js → escalation-columns-BbS5X61l.js} +2 -2
  150. package/dashboard/dist/assets/{escalation-columns-y5SQ2Ulh.js.map → escalation-columns-BbS5X61l.js.map} +1 -1
  151. package/dashboard/dist/assets/{index-BVZINC_p.js → index-B68A3v-S.js} +2 -2
  152. package/dashboard/dist/assets/{index-BVZINC_p.js.map → index-B68A3v-S.js.map} +1 -1
  153. package/dashboard/dist/assets/{index-CRBXgMsh.js → index-BAi89Xpm.js} +2 -2
  154. package/dashboard/dist/assets/{index-CRBXgMsh.js.map → index-BAi89Xpm.js.map} +1 -1
  155. package/dashboard/dist/assets/index-BJ0jjFsI.js +5 -0
  156. package/dashboard/dist/assets/index-BJ0jjFsI.js.map +1 -0
  157. package/dashboard/dist/assets/index-BOJMUk4F.js +2 -0
  158. package/dashboard/dist/assets/{index-BYEkfaUq.js.map → index-BOJMUk4F.js.map} +1 -1
  159. package/dashboard/dist/assets/{index-DyS2DHqy.js → index-BrgYykPV.js} +2 -2
  160. package/dashboard/dist/assets/{index-DyS2DHqy.js.map → index-BrgYykPV.js.map} +1 -1
  161. package/dashboard/dist/assets/{index-DJ5nhcGB.js → index-BxgtIqvl.js} +2 -2
  162. package/dashboard/dist/assets/{index-DJ5nhcGB.js.map → index-BxgtIqvl.js.map} +1 -1
  163. package/dashboard/dist/assets/index-C0cHXaX-.css +1 -0
  164. package/dashboard/dist/assets/{index-DVLBkcoD.js → index-CDHDoHYz.js} +2 -2
  165. package/dashboard/dist/assets/{index-DVLBkcoD.js.map → index-CDHDoHYz.js.map} +1 -1
  166. package/dashboard/dist/assets/index-CUZJHXew.js +2 -0
  167. package/dashboard/dist/assets/{index-H6Vp-gPG.js.map → index-CUZJHXew.js.map} +1 -1
  168. package/dashboard/dist/assets/index-D5n_e59T.js +2 -0
  169. package/dashboard/dist/assets/{index-BC1NxetR.js.map → index-D5n_e59T.js.map} +1 -1
  170. package/dashboard/dist/assets/index-DIgiIoou.js +63 -0
  171. package/dashboard/dist/assets/index-DIgiIoou.js.map +1 -0
  172. package/dashboard/dist/assets/{index-Cfq3UKd8.js → index-Dd1RxGNw.js} +2 -2
  173. package/dashboard/dist/assets/{index-Cfq3UKd8.js.map → index-Dd1RxGNw.js.map} +1 -1
  174. package/dashboard/dist/assets/index-iOb3sGsC.js +5 -0
  175. package/dashboard/dist/assets/{index-DjI2AUbn.js.map → index-iOb3sGsC.js.map} +1 -1
  176. package/dashboard/dist/assets/{index-BXbt5NHG.js → index-mcAkQblr.js} +2 -2
  177. package/dashboard/dist/assets/{index-BXbt5NHG.js.map → index-mcAkQblr.js.map} +1 -1
  178. package/dashboard/dist/assets/{knowledge-CLnYcq0Y.js → knowledge-B9bmoXOe.js} +2 -2
  179. package/dashboard/dist/assets/{knowledge-CLnYcq0Y.js.map → knowledge-B9bmoXOe.js.map} +1 -1
  180. package/dashboard/dist/assets/{mcp-C1-iXkg7.js → mcp-DYMFBOFz.js} +2 -2
  181. package/dashboard/dist/assets/{mcp-C1-iXkg7.js.map → mcp-DYMFBOFz.js.map} +1 -1
  182. package/dashboard/dist/assets/{mcp-query-DcyDxuGY.js → mcp-query-wloSpyPM.js} +2 -2
  183. package/dashboard/dist/assets/{mcp-query-DcyDxuGY.js.map → mcp-query-wloSpyPM.js.map} +1 -1
  184. package/dashboard/dist/assets/{pipelines-BvG5D6bV.js → pipelines-DBXX6TEi.js} +2 -2
  185. package/dashboard/dist/assets/{pipelines-BvG5D6bV.js.map → pipelines-DBXX6TEi.js.map} +1 -1
  186. package/dashboard/dist/assets/{tasks-qwh8q5q7.js → tasks-CD3-C7tP.js} +2 -2
  187. package/dashboard/dist/assets/{tasks-qwh8q5q7.js.map → tasks-CD3-C7tP.js.map} +1 -1
  188. package/dashboard/dist/assets/{topics-MLKKA-Ql.js → topics-D8pKi6zA.js} +2 -2
  189. package/dashboard/dist/assets/{topics-MLKKA-Ql.js.map → topics-D8pKi6zA.js.map} +1 -1
  190. package/dashboard/dist/assets/{useEventHooks-B8uNFB-l.js → useEventHooks-DV9pLDOW.js} +2 -2
  191. package/dashboard/dist/assets/{useEventHooks-B8uNFB-l.js.map → useEventHooks-DV9pLDOW.js.map} +1 -1
  192. package/dashboard/dist/assets/{useNamespace-DjZmztJM.js → useNamespace-DykYhZY9.js} +2 -2
  193. package/dashboard/dist/assets/{useNamespace-DjZmztJM.js.map → useNamespace-DykYhZY9.js.map} +1 -1
  194. package/dashboard/dist/assets/{useYamlActivityEvents-DIvK20uI.js → useYamlActivityEvents-By044UAv.js} +2 -2
  195. package/dashboard/dist/assets/{useYamlActivityEvents-DIvK20uI.js.map → useYamlActivityEvents-By044UAv.js.map} +1 -1
  196. package/dashboard/dist/assets/{users-CVjajeDg.js → users-mI9goDjj.js} +2 -2
  197. package/dashboard/dist/assets/{users-CVjajeDg.js.map → users-mI9goDjj.js.map} +1 -1
  198. package/dashboard/dist/assets/{vendor-icons-Qk9qLjF_.js → vendor-icons-ihWGa7_d.js} +147 -132
  199. package/dashboard/dist/assets/vendor-icons-ihWGa7_d.js.map +1 -0
  200. package/dashboard/dist/assets/{workflows-BziTcJNq.js → workflows-DCUilz68.js} +2 -2
  201. package/dashboard/dist/assets/{workflows-BziTcJNq.js.map → workflows-DCUilz68.js.map} +1 -1
  202. package/dashboard/dist/assets/{yaml-workflows-Dr-ZcE_0.js → yaml-workflows-DWNMP1PT.js} +2 -2
  203. package/dashboard/dist/assets/{yaml-workflows-Dr-ZcE_0.js.map → yaml-workflows-DWNMP1PT.js.map} +1 -1
  204. package/dashboard/dist/index.html +3 -3
  205. package/docs/api/http/escalations.md +1 -0
  206. package/docs/api/http/roles.md +2 -0
  207. package/docs/api/http/users.md +39 -0
  208. package/docs/api/sdk/roles.md +5 -0
  209. package/docs/api/sdk/users.md +39 -0
  210. package/docs/hitl/pinned-views.md +45 -0
  211. package/docs/hitl/x-lt-list-schema.md +30 -2
  212. package/docs/hitl/x-lt-show-if.md +11 -0
  213. package/docs/hitl/x-lt-validation.md +27 -0
  214. package/docs/hitl/x-lt-widget.md +33 -1
  215. package/docs/hitl-guide.md +7 -3
  216. package/package.json +1 -1
  217. package/dashboard/dist/assets/AvailableEscalationsPage-AiuiLcz-.js +0 -2
  218. package/dashboard/dist/assets/AvailableEscalationsPage-AiuiLcz-.js.map +0 -1
  219. package/dashboard/dist/assets/BotPicker-BuCGvEed.js +0 -2
  220. package/dashboard/dist/assets/CountdownTimer-DdKL8Ryt.js +0 -2
  221. package/dashboard/dist/assets/CountdownTimer-DdKL8Ryt.js.map +0 -1
  222. package/dashboard/dist/assets/ListToolbar-Dmd1UiM-.js +0 -2
  223. package/dashboard/dist/assets/OperationsPage-vm_ByX41.js +0 -2
  224. package/dashboard/dist/assets/OperatorDashboard-zviIxH-0.js +0 -2
  225. package/dashboard/dist/assets/RoleDetailPage-DBIl_mhK.js +0 -8
  226. package/dashboard/dist/assets/RoleDetailPage-DBIl_mhK.js.map +0 -1
  227. package/dashboard/dist/assets/RolesPage-DzrSv6m-.js +0 -2
  228. package/dashboard/dist/assets/RunAsSelector-CiLjlmIE.js +0 -2
  229. package/dashboard/dist/assets/ToolPill-BCi101Jh.js +0 -2
  230. package/dashboard/dist/assets/WorkflowPill-DHxrAkp3.js +0 -2
  231. package/dashboard/dist/assets/index-BC1NxetR.js +0 -2
  232. package/dashboard/dist/assets/index-BYEkfaUq.js +0 -2
  233. package/dashboard/dist/assets/index-B_68lp-B.js +0 -5
  234. package/dashboard/dist/assets/index-B_68lp-B.js.map +0 -1
  235. package/dashboard/dist/assets/index-BeivyVtT.css +0 -1
  236. package/dashboard/dist/assets/index-DjI2AUbn.js +0 -5
  237. package/dashboard/dist/assets/index-H6Vp-gPG.js +0 -2
  238. package/dashboard/dist/assets/index-YPLTjeli.js +0 -63
  239. package/dashboard/dist/assets/index-YPLTjeli.js.map +0 -1
  240. package/dashboard/dist/assets/vendor-icons-Qk9qLjF_.js.map +0 -1
@@ -187,3 +187,42 @@ Deletes the user and all associated role assignments (cascade).
187
187
  ```json
188
188
  { "error": "User not found" }
189
189
  ```
190
+
191
+ ---
192
+
193
+ ## Self-Service — `/api/me`
194
+
195
+ Operations on the **authenticated caller** — no ids, no admin gates. Any signed-in user (or service account) may call them.
196
+
197
+ ### GET /api/me/preferences
198
+
199
+ The caller's preferences document — a generic per-user JSON store for presentation state (pinned views are the first tenant). Reads `{}` when unset.
200
+
201
+ **Response 200:**
202
+
203
+ ```json
204
+ {
205
+ "preferences": {
206
+ "pinnedViews": [
207
+ { "id": "pin-x1", "label": "Needs harvesting", "url": "/escalations/available?role=fleet-servicer&jeopardy=1&view=table", "badge": true }
208
+ ],
209
+ "hiddenRolePins": ["My machines"]
210
+ }
211
+ }
212
+ ```
213
+
214
+ ### PATCH /api/me/preferences
215
+
216
+ Shallow-merge the body into the caller's preferences: top-level keys overwrite whole, a `null` value deletes its key. The merge is a single guarded statement (no read-then-write) and the stored document is size-capped (~32 KB). Preferences carry presentation state only — URLs and UI choices, never data and never authorization.
217
+
218
+ **Request body** — any JSON object of preference keys:
219
+
220
+ ```json
221
+ { "pinnedViews": [ { "id": "pin-x1", "label": "Needs harvesting", "url": "/escalations/available?role=fleet-servicer&jeopardy=1", "badge": true } ], "theme": null }
222
+ ```
223
+
224
+ **Response 200:** the merged document, `{ "preferences": { ... } }`.
225
+
226
+ **Response 400:** body is not a JSON object. **Response 413:** the patch or the merged document would exceed the size cap (nothing is written).
227
+
228
+ See the [Pinned Views guide](../../hitl/pinned-views.md) for how the dashboard uses this store.
@@ -32,6 +32,9 @@ interface RoleDetail {
32
32
  worker_count: number | null;
33
33
  priority_threshold_minutes: number | null;
34
34
  priority_facet: string | null;
35
+ list_schema: Record<string, any> | null;
36
+ default_pins: { label: string; url: string; badge?: boolean }[] | null;
37
+ upstream_roles: string[];
35
38
  user_count: number;
36
39
  chain_count: number;
37
40
  workflow_count: number;
@@ -276,6 +279,8 @@ const result = await lt.roles.update({
276
279
  | `priority_threshold_minutes` | `number \| null` | No | Priority age threshold in minutes; falls back to `sla_minutes` |
277
280
  | `priority_facet` | `string \| null` | No | Metadata key for the priority age origin; falls back to `created_at` |
278
281
  | `upstream_roles` | `string[] \| null` | No | Replace the set of roles this station draws input from across other Operations sequences (omitted = preserve; `null` or `[]` = clear). Distinct from `parent_role`, which places the role in its own sequence |
282
+ | `list_schema` | `object \| null` | No | Rich formatting (x-lt-* markup) for this role's escalation LIST page; versions independently of `form_schema` |
283
+ | `default_pins` | `array \| null` | No | Pinned-view seeds for members: `[{ label, url, badge? }]` with dashboard-relative `url`s. Members promote, hide, or reorder via their own preferences (`lt.me`) |
279
284
  | `change_summary` | `string` | No | Label recorded on the schema version snapshot when this update changes a schema field |
280
285
 
281
286
  When the update changes `form_schema` or `metadata_schema`, the new pair is snapshotted into the role's version history and `current_schema_version` advances.
@@ -219,3 +219,42 @@ const result = await lt.users.removeRole({
219
219
  **Returns:** `LTApiResult<{ removed: true }>` -- returns 404 if role not found.
220
220
 
221
221
  **Auth:** Not required
222
+
223
+ ---
224
+
225
+ ## me — the authenticated caller
226
+
227
+ Self-service operations bound to the client's auth context (no ids, no admin gates).
228
+
229
+ ### me.getPreferences
230
+
231
+ ```typescript
232
+ const result = await lt.me.getPreferences();
233
+ // { status: 200, data: { preferences: { pinnedViews: [...] } } }
234
+ ```
235
+
236
+ **Returns:** `LTApiResult<{ preferences: Record<string, unknown> }>` — `{}` when unset.
237
+
238
+ ### me.patchPreferences
239
+
240
+ Shallow-merge a patch into the caller's preferences: top-level keys overwrite whole, `null` deletes a key. The merge is one guarded statement; the stored document is size-capped (~32 KB → 413).
241
+
242
+ ```typescript
243
+ const result = await lt.me.patchPreferences({
244
+ patch: {
245
+ pinnedViews: [
246
+ { id: 'pin-x1', label: 'Needs harvesting', url: '/escalations/available?role=fleet-servicer&jeopardy=1', badge: true },
247
+ ],
248
+ },
249
+ });
250
+ ```
251
+
252
+ **Parameters:**
253
+
254
+ | Field | Type | Required | Description |
255
+ |-------|------|----------|-------------|
256
+ | `patch` | `object` | Yes | Preference keys to merge; a `null` value deletes its key |
257
+
258
+ **Returns:** `LTApiResult<{ preferences: Record<string, unknown> }>` — the merged document.
259
+
260
+ **Auth:** Required (the operation targets the caller).
@@ -0,0 +1,45 @@
1
+ # Pinned Views
2
+
3
+ Task-queue personas live in a handful of exact queries — "pending harvest rows, oldest first," "everything about serial X." Every filter on the escalations list is already deep-linked in the URL (`role`, `status`, `facets`, `range`, `orderBy`, `view`, `jeopardy`); pinned views add persistence and placement: the right queries sit in the right person's nav from first login.
4
+
5
+ ---
6
+
7
+ ## User Preferences
8
+
9
+ Pins live in a per-user preferences store — a generic JSON document on the user record (pinned views are its first tenant, not its schema):
10
+
11
+ ```
12
+ GET /api/me/preferences → { preferences }
13
+ PATCH /api/me/preferences shallow top-level merge; null deletes a key
14
+ ```
15
+
16
+ The merge is a single guarded statement (no read-then-write) and the document is size-capped (~32 KB → 413). Preferences carry presentation state only — URLs and UI choices, never data and never authorization. A pin to a query the user cannot read simply renders that query's normal empty state; read-scope enforcement stays where it already lives.
17
+
18
+ ```json
19
+ {
20
+ "pinnedViews": [
21
+ { "id": "pin-x1", "label": "Needs harvesting", "url": "/escalations/available?role=fleet-servicer&facets=%7B%22machineState%22%3A%22finished%22%7D&view=table", "badge": true }
22
+ ],
23
+ "hiddenRolePins": ["My machines"]
24
+ }
25
+ ```
26
+
27
+ ## The Pinned Section
28
+
29
+ Pins render as a **Pinned** nav section: the user's own pins first, in stored order (drag to reorder, ✕ to remove), then role-provided defaults. **Pin this view** on the escalations list captures the live filter set into a new pin, prompting only for a label.
30
+
31
+ `badge: true` renders a live count beside the label using the same server-side predicate the pin opens onto (the pin's URL is parsed back into its query and counted with `limit: 1`) — so the badge and the list always agree, including `jeopardy=1` pins. Counts refresh on escalation events, and a pin whose URL isn't a countable escalations list renders without a badge.
32
+
33
+ ## Role Default Pins
34
+
35
+ A role may declare `default_pins: [{ label, url, badge? }]` (edited on Role Detail → Default Pins). Members see them in their Pinned section from first login, marked as role-provided, and may:
36
+
37
+ - **Promote** — copy into their own pins (an own pin with the same label supersedes the role default)
38
+ - **Hide** — dismiss it (recorded in `hiddenRolePins`)
39
+ - **Reorder** — promote first, then drag among their own pins
40
+
41
+ Membership *is* the persona's bookmark set — no per-user setup. Duplicate labels across a user's roles collapse to the first role's pin.
42
+
43
+ ## Reference Example
44
+
45
+ The `fleet-servicer` seed (`examples/seed-fleet-sim.ts`) ships a facet-board list schema, jeopardy dials, and three default pins — the board, a badged "Needs harvesting" facet query, and a badged jeopardy view — so the whole persona story is exercisable from the dashboard. The seeded `reviewer` user is a member.
@@ -12,11 +12,15 @@ Every string is a markdown/text template run through the same `{{domain.path}}`
12
12
 
13
13
  | Key | Level | Purpose |
14
14
  |-----|-------|---------|
15
- | `x-lt-layout` | schema | `"active-history"`, `"active"`, `"facet-table"`, or `"table"` |
15
+ | `x-lt-layout` | schema | `"active-history"`, `"active"`, `"facet-table"`, `"facet-board"`, or `"table"` |
16
16
  | `x-lt-help` | schema | Optional markdown header, interpolated with the active row |
17
17
  | `x-lt-active` | schema | The live item card: `{ title, subtitle?, body?, fields?: [{ label, value }] }` |
18
18
  | `x-lt-history` | schema | History column: `{ row: { title, subtitle?, meta? }, limit?, status? }` |
19
- | `x-lt-columns` | schema | Column definitions for `facet-table` layout: `[{ label: string, value: string }]` |
19
+ | `x-lt-columns` | schema | Column definitions for `facet-table` layout: `[{ label, value, format? }]` |
20
+ | `x-lt-group-by` | schema | `facet-board`: the `"domain.path"` whose value identifies each entity |
21
+ | `x-lt-card` | schema | `facet-board`: the per-entity card — `{ title, state?, fields?: [{ label, value, format? }] }` |
22
+
23
+ `format: "age"` on a `facet-table` column or `facet-board` field renders a timestamp as a compact age (`12m`, `3h`, `2d`) with the absolute time as its tooltip, repainted each minute — aging interim states are scannable at a glance.
20
24
 
21
25
  The **active** item is the first non-terminal escalation. The **history** column is lazy-loaded — a "Load full history" link fetches resolved items on demand (`status` defaults to `"resolved"`, `limit` to 25). Unknown or absent `x-lt-layout` is a safe no-op that falls back to the table.
22
26
 
@@ -73,3 +77,27 @@ Use when the queue contains many concurrent rows and the role's context is best
73
77
  ```
74
78
 
75
79
  A status dot precedes the first column automatically. ISO datetime values render as a readable relative date with a full-timestamp tooltip. Missing token values render as an em dash. Clicking any row navigates to the detail page. `x-lt-help` and `x-lt-active` are ignored in this layout.
80
+
81
+ ### `"facet-board"` — entity board
82
+
83
+ Use when the rows describe **entities** (machines, stations) rather than a queue: within the current filter scope, rows group by the resolved `x-lt-group-by` value and each group renders one card from its most recent row (by `created_at`). The board reflects the scope — groups with no matching rows simply don't render.
84
+
85
+ ```json
86
+ {
87
+ "x-lt-layout": "facet-board",
88
+ "x-lt-group-by": "metadata.fleetMachine",
89
+ "x-lt-card": {
90
+ "title": "{{metadata.fleetMachine}}",
91
+ "state": "{{metadata.machineState}}",
92
+ "fields": [
93
+ { "label": "PO", "value": "{{metadata.po}}" },
94
+ { "label": "Order", "value": "{{metadata.orderId}}" },
95
+ { "label": "Since", "value": "{{escalation.created_at}}", "format": "age" }
96
+ ]
97
+ }
98
+ }
99
+ ```
100
+
101
+ The card's `state` renders as a status chip (a stable hue per token — commonly a subtype or a metadata state facet). The grid wraps to the viewport (wall-screen friendly). Clicking a card opens the entity's history: the table view filtered to that facet value (`x-lt-group-by` should therefore be a `metadata.*` path). `x-lt-help` renders above the board as in `facet-table`. In the digital-twin pattern — each machine advertising one live pending row — the board is exact by construction; for wider scopes it groups the fetched page, with standard pagination beyond it.
102
+
103
+ The reference: `examples/seed-fleet-sim.ts` — one advert per machine, a `format: "age"` "Since" field, and role default pins (see [pinned-views.md](pinned-views.md)).
@@ -10,6 +10,17 @@ A field can be shown or hidden based on a value in the escalation context. Apply
10
10
 
11
11
  The value at `domain.path` is evaluated for truthiness. If truthy, the field shows; if absent, null, false, or an empty string, it is hidden. Prefix `!` to invert — show when the value is absent or falsy.
12
12
 
13
+ ### Equality forms
14
+
15
+ Compare the resolved value's string form against a literal:
16
+
17
+ ```json
18
+ "x-lt-showIf": "resolver.designatedStation=DRAFT"
19
+ "x-lt-showIf": "resolver.designatedStation!=DRAFT"
20
+ ```
21
+
22
+ The expected value is the raw remainder after the operator (trimmed; no quoting). Numbers and booleans compare via their string form (`metadata.count=3`, `metadata.live=true`). An absent value compares as the empty string — so `=X` is false and `!=X` is true when the path is missing. `resolver.` conditions react live as the user edits, exactly like the truthy form — this is what drives per-designation sub-surfaces on verdict forms (different fields for send-to-design vs send-to-printing).
23
+
13
24
  ### Domains
14
25
 
15
26
  | Domain | Resolves against |
@@ -93,6 +93,33 @@ When `envelope.min_score` is `60`, submitting a score of `45` blocks with "Minim
93
93
 
94
94
  ---
95
95
 
96
+ ## Checklist Completion (`x-lt-require-all`)
97
+
98
+ A checklist-widget field can require every item to be checked before submission:
99
+
100
+ ```json
101
+ {
102
+ "properties": {
103
+ "checks": {
104
+ "type": "object",
105
+ "x-lt-widget": "checklist",
106
+ "x-lt-source": "envelope.checklist_items",
107
+ "x-lt-require-all": true
108
+ }
109
+ }
110
+ }
111
+ ```
112
+
113
+ With `"x-lt-require-all": true`, the pre-submission pass fails unless every rendered item is checked — except items whose definition carries `required: false`, the explicit opt-out (e.g. an optional photos step). An item with `required: true` or no `required` key at all must be checked.
114
+
115
+ - A field hidden by `x-lt-showIf` at submit time is skipped entirely (the same rule as `required`).
116
+ - When `x-lt-source` resolves to a missing or empty array, the guard is vacuous — zero items never block.
117
+ - Composes with the `required` array: listing the field in `required` remains lawful and means at-least-one; `x-lt-require-all` is the stricter check and wins when both are present.
118
+
119
+ On a blocked submit, each unchecked mandatory item highlights red inline, and the error panel reads `N of M checks incomplete` with click-to-focus landing on the first unchecked item. Errors clear in real time as items are checked. The group carries `aria-invalid` and the message is announced as an alert, consistent with the rest of the validation wiring.
120
+
121
+ ---
122
+
96
123
  ## Pattern Guard
97
124
 
98
125
  Apply a regular expression guard with `pattern`. If the input does not match, the field blocks submission. Provide `x-lt-pattern-error` for a human-readable error message; otherwise the generic "Invalid format" is shown.
@@ -10,6 +10,7 @@ For rich inputs beyond standard HTML types, set `x-lt-widget` on any field:
10
10
  | `"rich-text"` | Tall textarea for formatted text input. |
11
11
  | `"markdown"` | Markdown source rendered with headings, tables, lists, code blocks. Editable by default; set `readOnly: true` for a pure content block. |
12
12
  | `"checklist"` | Dynamic labeled checkboxes driven by runtime data. Items come from a `"domain.path"` declared in `x-lt-source`. |
13
+ | `"attachment"` | ReadOnly display of a captured binary (data URL or fetchable URL): images inline with click-to-full-size, everything else as a safe open/download link. `"image"` is an accepted alias. |
13
14
 
14
15
  ---
15
16
 
@@ -75,6 +76,27 @@ The submitted value is a PNG data URL of the canvas drawing.
75
76
 
76
77
  ---
77
78
 
79
+ ## Attachment
80
+
81
+ ReadOnly display of a binary captured earlier — typically by the `file-upload` widget on a prior form. The reporting form uploads the evidence (a defect photo, a signed PDF, a scan); the review form shows it:
82
+
83
+ ```json
84
+ {
85
+ "properties": {
86
+ "defect_evidence": {
87
+ "type": "string",
88
+ "readOnly": true,
89
+ "x-lt-widget": "attachment",
90
+ "description": "Uploaded by the reporting form"
91
+ }
92
+ }
93
+ }
94
+ ```
95
+
96
+ The value is a data URL or a fetchable URL. Rendering dispatches on content type: `image/*` renders inline (constrained, click for full size); everything else — PDFs, scans, arbitrary binaries — renders as a labeled open/download affordance and is never embedded as a document (inlining arbitrary `data:` content is an XSS vector; the image context is script-inert). `"image"` is an accepted alias when the schema wants to name the constrained intent. An empty value reads as a quiet "No attachment".
97
+
98
+ ---
99
+
78
100
  ## Markdown
79
101
 
80
102
  Without `readOnly`, the field is a markdown editor — the resolver writes source in a Write/Preview toggle and the submitted value is the markdown text.
@@ -122,7 +144,17 @@ The field type must be `"object"`. The submitted value is `Record<string, boolea
122
144
  - `"envelope"` — for item definitions that are render data only (no query cost). The workflow puts them in `conditionLT`'s `envelope` parameter.
123
145
  - `"metadata"` — only when items need to be GIN-indexed and searchable as facets. Adds index cost.
124
146
 
125
- Marking an item `required: true` flags it with an asterisk in the UI. A `required` checklist field is blocked from submission until at least one item is checked. When no items are checked after a submission attempt, every unchecked item that is individually required (or all unchecked items when the field itself is required) highlights in red. Once any item is checked — satisfying the group requirement — all per-item highlights clear.
147
+ A checklist enforces one of three completion levels:
148
+
149
+ | Level | Declaration | Blocks submission until |
150
+ |-------|-------------|------------------------|
151
+ | None | field absent from `required` | Never — items are informational |
152
+ | At least one | field listed in `required` | Any one item is checked |
153
+ | All | `"x-lt-require-all": true` on the field | Every item is checked, except items declared `required: false` |
154
+
155
+ Marking an item `required: true` flags it with an asterisk in the UI. In at-least-one mode, unchecked items highlight red after a submission attempt only while zero are checked; once any item is checked the group requirement is met and all highlights clear.
156
+
157
+ `x-lt-require-all` is the completion guard for station forms where every check is a confirmation: every item must be checked before submit — except items whose definition carries `required: false`, the explicit opt-out. Unchecked mandatory items highlight red after a submission attempt and clear live as they are checked; the error panel reads `N of M checks incomplete`. It composes with the `required` array (at-least-one stays lawful; require-all is stricter and wins), and it is vacuous when the source resolves to no items. See [x-lt-validation.md](x-lt-validation.md#checklist-completion-x-lt-require-all).
126
158
 
127
159
  **Workflow side:**
128
160
 
@@ -86,6 +86,7 @@ Ordered as a learning path — each file adds one capability to the same form:
86
86
  | Iframe viewport protocol | [iframe.md](hitl/iframe.md) |
87
87
  | Claim lifecycle, resolving from system code, outcome recording, cancellation | [resolution.md](hitl/resolution.md) |
88
88
  | Role routing, RBAC, scope, chains | [roles.md](hitl/roles.md) |
89
+ | Pinned views, user preferences, role default pins | [pinned-views.md](hitl/pinned-views.md) |
89
90
 
90
91
  ---
91
92
 
@@ -93,13 +94,14 @@ Ordered as a learning path — each file adds one capability to the same form:
93
94
 
94
95
  | Keyword | Level | Purpose |
95
96
  |---------|-------|---------|
96
- | `x-lt-widget` | field | Rich control: `file-upload`, `code-editor`, `signature`, `rich-text`, `markdown`, `checklist` |
97
+ | `x-lt-widget` | field | Rich control: `file-upload`, `code-editor`, `signature`, `rich-text`, `markdown`, `checklist`, `attachment` (alias `image`) |
97
98
  | `x-lt-source` | field | Data path for context-driven widgets: `"domain.path"` |
99
+ | `x-lt-require-all` | field | Checklist completion guard — every item must be checked, except items declared `required: false` |
98
100
  | `x-lt-language` | field | Syntax hint for the `code-editor` widget |
99
101
  | `accept` | field | File-type filter for `file-upload` (e.g. `".pdf,.png"`) |
100
102
  | `x-lt-bind` | field | Path in the resolver payload (e.g. `"customer.email"`) |
101
103
  | `x-lt-span` | field | Column span in a `two-column` layout (`2` = full width) |
102
- | `x-lt-showIf` | field | Show field when a value is truthy at `domain.path`; prefix `!` to invert |
104
+ | `x-lt-showIf` | field | Show field when a value is truthy at `domain.path`; prefix `!` to invert; `=VALUE` / `!=VALUE` compare the string form |
103
105
  | `x-lt-hide-if-empty` | field | `true` — suppress the field when its value is null, `""`, `false`, or `0` |
104
106
  | `x-lt-section` | field | Section group label |
105
107
  | `x-lt-minimum` | field | Dynamic lower bound — resolves a `"domain.path"` from the escalation context |
@@ -108,7 +110,9 @@ Ordered as a learning path — each file adds one capability to the same form:
108
110
  | `x-lt-max-length` | field | Dynamic maximum string length — resolves a `"domain.path"` |
109
111
  | `x-lt-pattern-error` | field | Human-readable label for a `pattern` validation failure |
110
112
  | `x-lt-order` | schema | Field render sequence |
111
- | `x-lt-layout` | schema | `"two-column"` grid layout (form) or `"active-history"` / `"facet-table"` (list) |
113
+ | `x-lt-layout` | schema | `"two-column"` grid layout (form) or `"active-history"` / `"facet-table"` / `"facet-board"` (list) |
114
+ | `x-lt-group-by` | schema (list) | `facet-board`: the `"domain.path"` identifying each entity |
115
+ | `x-lt-card` | schema (list) | `facet-board`: per-entity card — `{ title, state?, fields? }`; fields accept `format: "age"` |
112
116
  | `x-lt-help` | schema | Markdown guidance for the side panel's Help view |
113
117
  | `x-lt-context` | schema | Plain-text fallback for the Help view when `x-lt-help` is absent |
114
118
  | `x-lt-viewport` | schema | Replace the generated form with a custom iframe UI |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hotmeshio/long-tail",
3
- "version": "0.10.0",
3
+ "version": "0.10.2",
4
4
  "description": "Long Tail Workflows — Durable AI workflows with human-in-the-loop escalation. Powered by PostgreSQL.",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",
@@ -1,2 +0,0 @@
1
- import{j as e,a as g}from"./vendor-query-B2UbickB.js";import{L as Fe,c as Tt,f as At,a as Ot}from"./vendor-react-CXumBFUA.js";import{i as Je,m as $e,p as _t,w as Ft,f as $t}from"./CountdownTimer-DdKL8Ryt.js";import{j as Lt,M as de,k as Qe,b as We,u as Bt,l as zt,m as Xe,n as Dt,o as Rt,g as It,p as qt,q as Ut,r as Gt,s as Ht,t as Vt,v as Jt,w as Qt,x as Wt,y as Xt,z as Yt,A as Kt,B as Zt,E as es,G as ts}from"./index-YPLTjeli.js";import{f as ss}from"./useEventHooks-B8uNFB-l.js";import{i as F,u as ue,C as Ye,a as as}from"./CustomDurationPicker-F6bR2Q5A.js";import{k as Ke,X as se,a7 as ns,a8 as ls,a9 as rs,q as is,r as os,aa as cs,ab as ds,l as xs,ac as us,B as ms,ad as Le,ae as hs,af as ps,c as fs,ag as gs}from"./vendor-icons-Qk9qLjF_.js";import{a as Ze}from"./StatusBadge-CEQMRmSQ.js";import{S as et}from"./StickyPagination-Di6b2GDE.js";import{u as bs}from"./useFilterParams-x-Dg0Vgz.js";import{u as tt}from"./useDebouncedValue-BA5S7V54.js";import{b as js}from"./api-path-u2Jf9QXS.js";import{D as vs}from"./DataTable-Byn3oyT9.js";import{P as ys}from"./constants-BHkpVaqx.js";import{M as me}from"./Modal-D4afnAjc.js";import{u as Ns}from"./users-CVjajeDg.js";import{m as Cs,E as ws}from"./escalation-columns-y5SQ2Ulh.js";import{R as ks,a as Ss}from"./RowActions-BA9L9djf.js";import{L as Ps}from"./ListToolbar-Dmd1UiM-.js";import"./EmptyState-BcsfPq9T.js";import"./FilterBar-B5Vk5tBF.js";import"./PriorityBadge-B4ykBH7f.js";import"./RolePill-4LO_CuO3.js";import"./WorkflowPill-DHxrAkp3.js";const Ms=["<","<=",">",">=","="],Es=["priority","created_at","updated_at","status","role"],G="input text-xs py-1",Be="select text-xs py-1",ee="text-text-tertiary hover:text-text-primary transition-colors";function ze(t){return t==="true"?!0:t==="false"?!1:t.trim()!==""&&!Number.isNaN(Number(t))?Number(t):t}const Ts=t=>Object.entries(t??{}).map(([s,l])=>({key:s,value:String(l)})),As=t=>(t??[]).map(s=>{const[l,a]=Object.entries(s)[0]??["",""];return{key:l,value:String(a)}});function q({title:t,hint:s,children:l}){return e.jsxs("div",{className:"border-t border-surface-border/50 py-3 first:border-t-0 first:pt-1",children:[e.jsxs("div",{className:"mb-1.5 flex items-baseline justify-between",children:[e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-text-tertiary",children:t}),s&&e.jsx("span",{className:"text-[10px] font-mono text-text-tertiary/70",children:s})]}),l]})}function te({value:t,onChange:s,placeholder:l}){return e.jsx("input",{list:"lt-facet-keys",className:`${G} w-40`,placeholder:l,value:t,onChange:a=>s(a.target.value)})}function Os({value:t,onChange:s,facetKeys:l=[],search:a="",onSearchChange:x}){const d=Ts(t.facets),u=As(t.block),f=t.range??[],r=t.exists??[],c=t.orderBy??[],b=i=>{const p={};for(const m of i)m.key&&(p[m.key]=ze(m.value));s({...t,facets:Object.keys(p).length?p:void 0})},j=i=>{const p=i.filter(m=>m.key).map(m=>({[m.key]:ze(m.value)}));s({...t,block:p.length?p:void 0})},N=i=>s({...t,range:i.length?i:void 0}),v=i=>s({...t,exists:i.length?i:void 0}),w=i=>s({...t,orderBy:i.length?i:void 0});return e.jsxs("div",{className:"text-xs",children:[e.jsx("datalist",{id:"lt-facet-keys",children:l.map(i=>e.jsx("option",{value:i},i))}),e.jsxs("datalist",{id:"lt-sort-fields",children:[Es.map(i=>e.jsx("option",{value:i},i)),l.map(i=>e.jsx("option",{value:`metadata.${i}`},i))]}),x&&e.jsx(q,{title:"Match id",hint:"id · workflow · origin",children:e.jsx("input",{className:`${G} w-full`,placeholder:"Exact escalation, workflow, or origin id…",value:a,onChange:i=>x(i.target.value)})}),e.jsx(q,{title:"Has facet",hint:"metadata @>",children:[...d,{key:"",value:""}].map((i,p)=>e.jsxs("div",{className:"mb-1 flex items-center gap-1",children:[e.jsx(te,{value:i.key,placeholder:"key",onChange:m=>{const h=[...d];h[p]={...i,key:m},b(h)}}),e.jsx("span",{className:"text-text-tertiary",children:"="}),e.jsx("input",{className:`${G} w-40`,placeholder:"value",value:i.value,onChange:m=>{const h=[...d];h[p]={...i,value:m.target.value},b(h)}}),p<d.length&&e.jsx("button",{className:ee,onClick:()=>b(d.filter((m,h)=>h!==p)),children:"×"})]},p))}),e.jsx(q,{title:"Range",hint:"numeric",children:[...f,{facet:"",op:"<=",value:0}].map((i,p)=>e.jsxs("div",{className:"mb-1 flex items-center gap-1",children:[e.jsx(te,{value:i.facet,placeholder:"numeric facet",onChange:m=>{const h=[...f];h[p]={...i,facet:m},N(h.filter(n=>n.facet))}}),e.jsx("select",{className:Be,value:i.op,onChange:m=>{const h=[...f];h[p]={...i,op:m.target.value},N(h.filter(n=>n.facet))},children:Ms.map(m=>e.jsx("option",{value:m,children:m},m))}),e.jsx("input",{type:"number",className:`${G} w-24`,value:i.value,onChange:m=>{const h=[...f];h[p]={...i,value:Number(m.target.value)},N(h.filter(n=>n.facet))}}),p<f.length&&e.jsx("button",{className:ee,onClick:()=>N(f.filter((m,h)=>h!==p)),children:"×"})]},p))}),e.jsx(q,{title:"Has key",hint:"metadata ? key",children:e.jsxs("div",{className:"flex flex-wrap items-center gap-1",children:[r.map(i=>e.jsxs("span",{className:"flex items-center gap-1 rounded bg-accent/15 px-1.5 py-0.5 text-accent",children:[i,e.jsx("button",{className:"text-accent/70 hover:text-accent",onClick:()=>v(r.filter(p=>p!==i)),children:"×"})]},i)),e.jsx(te,{value:"",placeholder:"+ key",onChange:i=>{i&&!r.includes(i)&&v([...r,i])}})]})}),e.jsx(q,{title:"Exclude",hint:"NOT @>",children:[...u,{key:"",value:""}].map((i,p)=>e.jsxs("div",{className:"mb-1 flex items-center gap-1",children:[e.jsx(te,{value:i.key,placeholder:"key",onChange:m=>{const h=[...u];h[p]={...i,key:m},j(h)}}),e.jsx("span",{className:"text-text-tertiary",children:"="}),e.jsx("input",{className:`${G} w-40`,placeholder:"value",value:i.value,onChange:m=>{const h=[...u];h[p]={...i,value:m.target.value},j(h)}}),p<u.length&&e.jsx("button",{className:ee,onClick:()=>j(u.filter((m,h)=>h!==p)),children:"×"})]},p))}),e.jsx(q,{title:"Sort by",children:[...c,{field:"",direction:"asc"}].map((i,p)=>e.jsxs("div",{className:"mb-1 flex items-center gap-1",children:[e.jsx("input",{list:"lt-sort-fields",className:`${G} w-44`,placeholder:"column or metadata.key",value:i.field,onChange:m=>{const h=[...c];h[p]={...i,field:m.target.value},w(h.filter(n=>n.field))}}),e.jsxs("select",{className:Be,value:i.direction??"asc",onChange:m=>{const h=[...c];h[p]={...i,direction:m.target.value},w(h.filter(n=>n.field))},children:[e.jsx("option",{value:"asc",children:"asc"}),e.jsx("option",{value:"desc",children:"desc"})]}),e.jsxs("label",{className:"flex items-center gap-1 text-text-tertiary",children:[e.jsx("input",{type:"checkbox",checked:!!i.numeric,onChange:m=>{const h=[...c];h[p]={...i,numeric:m.target.checked},w(h.filter(n=>n.field))}}),"num"]}),p<c.length&&e.jsx("button",{className:ee,onClick:()=>w(c.filter((m,h)=>h!==p)),children:"×"})]},p))})]})}function _s({role:t,options:s,onChange:l}){var r;const[a,x]=g.useState(!1),d=g.useRef(null);g.useEffect(()=>{if(!a)return;const c=j=>{d.current&&!d.current.contains(j.target)&&x(!1)},b=j=>{j.key==="Escape"&&x(!1)};return document.addEventListener("mousedown",c),document.addEventListener("keydown",b),()=>{document.removeEventListener("mousedown",c),document.removeEventListener("keydown",b)}},[a]);const u=t?((r=s.find(c=>c.value===t))==null?void 0:r.label)??Lt(t):"All Escalations",f=c=>`w-full text-left px-3 py-1.5 text-sm flex items-baseline gap-2 transition-colors ${c?"text-accent bg-accent/5":"text-text-primary hover:bg-surface-hover"}`;return e.jsxs("div",{ref:d,className:"relative min-w-0",children:[e.jsxs("button",{type:"button",onClick:()=>x(c=>!c),className:"group flex items-center gap-2 min-w-0 text-3xl font-light text-text-primary hover:text-accent transition-colors",children:[e.jsx("span",{className:"truncate",children:u}),e.jsx(Ke,{className:`w-6 h-6 shrink-0 text-text-tertiary group-hover:text-accent transition-transform ${a?"rotate-180":""}`,strokeWidth:1.5})]}),a&&e.jsxs("div",{className:"absolute z-30 top-full left-0 mt-2 min-w-[16rem] max-h-80 overflow-y-auto bg-surface-raised border border-surface-border rounded-md shadow-lg py-1",children:[e.jsx("button",{type:"button",onClick:()=>{l(""),x(!1)},className:f(!t),children:"All Escalations"}),s.length>0&&e.jsx("div",{className:"h-px bg-surface-border my-1"}),s.map(c=>e.jsxs("button",{type:"button",onClick:()=>{l(c.value),x(!1)},className:f(t===c.value),children:[e.jsx("span",{className:"truncate",children:c.label}),c.label!==c.value&&e.jsx("span",{className:"text-[10px] font-mono text-text-quaternary shrink-0",children:c.value})]},c.value))]})]})}const De="created_at";function oe(t){return t.replace(/^metadata\./,"")}function Fs({orderBy:t,onChange:s}){const l=t==null?void 0:t[0],a=(l==null?void 0:l.field)??De,x=(l==null?void 0:l.direction)??"desc",d=a===De,u=f=>s([{...l??{},field:a,direction:f}]);return e.jsxs("div",{className:"flex items-center gap-1.5",children:[!d&&e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full border border-accent/25 bg-accent/8 px-2 py-0.5 text-[10px] font-medium text-accent/90",children:[e.jsx("span",{className:"text-text-quaternary",children:"sort"}),e.jsx("span",{className:"font-mono max-w-[120px] truncate",title:a,children:oe(a)}),e.jsx("button",{onClick:()=>s(void 0),className:"ml-0.5 -mr-0.5 flex items-center text-text-quaternary hover:text-status-error transition-colors","aria-label":"Reset sort to created date",children:e.jsx(se,{className:"w-2.5 h-2.5"})})]}),e.jsxs("div",{className:"flex items-center rounded overflow-hidden border border-surface-border",role:"radiogroup","aria-label":"Sort direction",children:[e.jsx("button",{type:"button",role:"radio","aria-checked":x==="desc",onClick:()=>u("desc"),className:`px-1.5 py-1 transition-colors ${x==="desc"?"bg-accent text-white":"text-text-tertiary hover:bg-surface-hover"}`,title:d?"Newest first":`${oe(a)} descending`,children:e.jsx(ns,{className:"w-3.5 h-3.5"})}),e.jsx("button",{type:"button",role:"radio","aria-checked":x==="asc",onClick:()=>u("asc"),className:`px-1.5 py-1 border-l border-surface-border transition-colors ${x==="asc"?"bg-accent text-white":"text-text-tertiary hover:bg-surface-hover"}`,title:d?"Oldest first":`${oe(a)} ascending`,children:e.jsx(ls,{className:"w-3.5 h-3.5"})})]})]})}function ae(t){const s=l=>{if(!l)return null;try{const a=JSON.parse(l);return a&&typeof a=="object"?a:null}catch{return null}};return{escalation:t,metadata:t.metadata??null,envelope:s(t.envelope),payload:s(t.escalation_payload),resolver:s(t.resolver_payload)}}const $s=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/,Re="—";function st({raw:t}){return!t||t===Re?e.jsx("span",{className:"text-text-quaternary",children:Re}):$s.test(t)?e.jsx(We,{date:t,format:"datetime",className:"text-text-primary"}):e.jsx(e.Fragment,{children:t})}function Ls({esc:t,card:s,onOpen:l}){const a=ae(t),x=s.title?F(s.title,a):t.type,d=t.status==="pending"&&!Je(t);return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-start justify-between gap-6",children:[e.jsxs("button",{onClick:l,className:"text-left group min-w-0",children:[e.jsx("h3",{className:"text-2xl font-light text-text-primary group-hover:text-accent transition-colors leading-tight",children:x}),s.subtitle&&e.jsx("p",{className:"text-xs text-text-tertiary mt-1.5",children:F(s.subtitle,a)})]}),d&&e.jsxs("button",{onClick:l,className:"inline-flex items-center gap-1.5 px-4 py-2 rounded-md bg-accent text-text-inverse text-xs font-medium hover:bg-accent-hover transition-colors shrink-0",children:["Claim",e.jsx(rs,{className:"w-3.5 h-3.5"})]})]}),s.fields&&s.fields.length>0&&e.jsx("dl",{className:"flex flex-wrap gap-x-10 gap-y-4 mt-6",children:s.fields.map((u,f)=>e.jsxs("div",{children:[e.jsx("dt",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:u.label}),e.jsx("dd",{className:"text-xs text-text-primary mt-1",children:e.jsx(st,{raw:F(u.value,a)})})]},f))}),s.body&&e.jsx("div",{className:"mt-7 pt-6 border-t border-surface-border/50",children:e.jsx(de,{content:F(s.body,a)})})]})}function Bs({role:t,def:s,onRowClick:l}){var c,b;const[a,x]=g.useState(!1),d=Qe({role:t,status:s.status??"resolved",sort_by:"resolved_at",order:"desc",limit:s.limit??25,enabled:a}),u=((c=d.data)==null?void 0:c.escalations)??[],f=((b=d.data)==null?void 0:b.total)??0,r=s.row??{};return a?d.isLoading?e.jsx("p",{className:"text-xs text-text-tertiary italic",children:"Loading history…"}):u.length===0?e.jsx("p",{className:"text-xs text-text-tertiary italic",children:"No past revisions."}):e.jsxs("div",{children:[e.jsx("div",{className:"divide-y divide-surface-border/40",children:u.map(j=>{const N=ae(j);return e.jsxs("button",{onClick:()=>l==null?void 0:l(j),className:"w-full text-left py-2.5 group flex items-center gap-3",children:[e.jsx("span",{className:`w-1.5 h-1.5 shrink-0 rounded-full dot-ring ${Ze[j.status]??"bg-status-pending"}`,title:j.status}),e.jsxs("span",{className:"min-w-0 flex-1",children:[e.jsx("span",{className:"block text-xs text-text-primary group-hover:text-accent transition-colors truncate",children:r.title?F(r.title,N):j.type}),r.subtitle&&e.jsx("span",{className:"block text-[10px] text-text-tertiary truncate",children:F(r.subtitle,N)})]}),r.meta?e.jsx("span",{className:"text-[10px] text-text-tertiary shrink-0",children:F(r.meta,N)}):j.resolved_at&&e.jsx(We,{date:j.resolved_at,format:"relative",className:"text-[10px] text-text-tertiary shrink-0 whitespace-nowrap"})]},j.id)})}),f>u.length&&e.jsxs("p",{className:"text-[10px] text-text-quaternary mt-3",children:["Showing ",u.length," of ",f,"."]})]}):e.jsx("button",{onClick:()=>x(!0),className:"text-xs text-accent hover:underline","data-testid":"load-history",children:"Load full history →"})}function zs({schema:t,rows:s,onRowClick:l}){const a=t["x-lt-columns"]??[];return s.length===0?e.jsx("p",{className:"text-xs text-text-tertiary italic",children:"No pending items."}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-xs",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-surface-border/60",children:[e.jsx("th",{className:"w-4 pb-2 pr-3","aria-label":"Status"}),a.map((x,d)=>e.jsx("th",{className:"text-left pb-2 pr-8 text-[10px] font-semibold uppercase tracking-widest text-text-tertiary whitespace-nowrap",children:x.label},d))]})}),e.jsx("tbody",{className:"divide-y divide-surface-border/30",children:s.map(x=>{const d=ae(x);return e.jsxs("tr",{onClick:()=>l==null?void 0:l(x),className:l?"group cursor-pointer hover:bg-surface-hover":"group","data-testid":"facet-table-row",children:[e.jsx("td",{className:"py-2.5 pr-3",children:e.jsx("span",{className:`w-1.5 h-1.5 inline-block rounded-full dot-ring ${Ze[x.status]??"bg-status-pending"}`,title:x.status})}),a.map((u,f)=>e.jsx("td",{className:"py-2.5 pr-8 text-text-secondary group-hover:text-text-primary transition-colors",children:e.jsx(st,{raw:F(u.value,d)})},f))]},x.id)})})]})})}function Ie({children:t}){return e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-3",children:t})}function Ds({role:t,listSchema:s,activeEscalations:l,onRowClick:a,total:x,page:d,totalPages:u,pageSize:f,onPageChange:r,onPageSizeChange:c}){const b=s["x-lt-layout"],j=s["x-lt-active"]??{},N=l[0],v=s["x-lt-help"],w=N?e.jsx(Ls,{esc:N,card:j,onOpen:()=>a==null?void 0:a(N)}):e.jsx("p",{className:"text-xs text-text-tertiary italic",children:"No active item right now."}),i=v&&N?e.jsx("div",{className:"mb-8",children:e.jsx(de,{content:F(v,ae(N))})}):v?e.jsx("div",{className:"mb-8",children:e.jsx(de,{content:v})}):null;if(b==="facet-table"){const p=x??l.length;return e.jsxs("div",{children:[i,p>0&&e.jsxs("p",{className:"text-[11px] text-text-tertiary mb-3 tabular-nums",children:[p.toLocaleString()," result",p!==1?"s":""]}),e.jsx(zs,{schema:s,rows:l,onRowClick:a}),d!==void 0&&u!==void 0&&r&&e.jsx(et,{page:d,totalPages:u,onPageChange:r,total:p,pageSize:f??25,onPageSizeChange:c})]})}return b==="active-history"?e.jsxs("div",{children:[i,e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-[1.6fr_1fr] gap-12 items-start",children:[e.jsxs("div",{children:[e.jsx(Ie,{children:"Active"}),w]}),e.jsxs("div",{children:[e.jsx(Ie,{children:"History"}),e.jsx(Bs,{role:t,def:s["x-lt-history"]??{},onRowClick:a})]})]})]}):e.jsxs("div",{children:[i,w]})}const Rs=t=>t.isPriorityPending||t.isClaimPending||t.isAssignPending||t.isEscalatePending||t.isTriagePending||t.isCancelPending,xe="inline-flex items-center h-7 px-2.5 text-[11px] font-medium text-text-secondary bg-surface border border-surface-border rounded-[4px] hover:border-accent/50 hover:text-text-primary transition-colors disabled:opacity-50 disabled:hover:border-surface-border",ce=`${xe} appearance-none cursor-pointer`,Is="inline-flex items-center h-7 px-2.5 text-[11px] font-medium text-status-error bg-surface border border-status-error/30 rounded-[4px] hover:border-status-error hover:bg-status-error/5 transition-colors disabled:opacity-50";function qs(t){var f;const s=Rs(t),l=ue(),{data:a}=Bt(),x=zt(),d=x!==null?x:((f=a==null?void 0:a.ai)==null?void 0:f.enabled)===!0,u=t.selectedCount>0;return e.jsx("div",{className:`grid transition-all duration-200 ease-in-out ${u?"grid-rows-[1fr] opacity-100":"grid-rows-[0fr] opacity-0 pointer-events-none"}`,children:e.jsx("div",{className:"overflow-hidden",children:e.jsxs("div",{className:"flex flex-wrap items-center gap-2 py-2.5 pl-3 pr-2 mt-4 mb-3 bg-surface-sunken/60 border-l-2 border-l-accent",children:[e.jsxs("span",{className:"text-[11px] font-semibold uppercase tracking-wider text-accent tabular-nums",children:[t.selectedCount," selected"]}),e.jsx("div",{className:"mx-1 h-4 w-px bg-surface-border"}),e.jsxs("select",{onChange:r=>{r.target.value&&(t.onSetPriority(parseInt(r.target.value)),r.target.value="")},disabled:s,className:ce,defaultValue:"",children:[e.jsx("option",{value:"",disabled:!0,children:"Priority…"}),ys.map(r=>e.jsx("option",{value:r.value,children:r.label},r.value))]}),e.jsxs("select",{onChange:r=>{r.target.value&&(t.onClaim(parseInt(r.target.value)),r.target.value="")},disabled:s,className:ce,defaultValue:"",children:[e.jsx("option",{value:"",disabled:!0,children:"Claim for…"}),l.map(r=>e.jsx("option",{value:r.value,children:r.label},r.value))]}),e.jsx("button",{onClick:t.onAssign,disabled:s,className:xe,children:t.isAssignPending?"Assigning…":"Assign to…"}),t.availableRoles.length>0&&e.jsxs("select",{onChange:r=>{r.target.value&&(t.onEscalate(r.target.value),r.target.value="")},disabled:s,className:ce,defaultValue:"",children:[e.jsx("option",{value:"",disabled:!0,children:"Escalate to…"}),t.availableRoles.map(r=>e.jsx("option",{value:r,children:r},r))]}),d&&e.jsx("button",{onClick:t.onTriage,disabled:s,className:xe,children:t.isTriagePending?"Triaging…":"Triage"}),e.jsx("button",{onClick:t.onCancel,disabled:s,className:Is,children:t.isCancelPending?"Cancelling…":"Cancel"}),e.jsx("div",{className:"flex-1"}),s&&e.jsx("span",{className:"text-[11px] text-text-tertiary animate-pulse",children:"Processing…"}),e.jsx("button",{onClick:t.onClearSelection,className:"px-1 text-[11px] font-medium text-text-tertiary hover:text-text-primary transition-colors",children:"Clear"})]})})})}function Us({open:t,onClose:s,selectedCount:l,selectedRoles:a,onSubmit:x,isPending:d}){const{isSuperAdmin:u}=Xe(),f=ue(),[r,c]=g.useState("user"),[b,j]=g.useState(null),[N,v]=g.useState(""),[w,i]=g.useState("30"),[p,m]=g.useState(0),h=g.useCallback(y=>m(y),[]),n=!u&&a.length===1?a[0]:void 0,k=tt(N,250),{data:P,isLoading:M}=Ns({role:n,status:"active",search:k.trim()||void 0,limit:200}),A=(P==null?void 0:P.users)??[],E=()=>{c("user"),j(null),v(""),i("30"),m(0),s()},O=y=>{j(y),c("duration")},B=()=>{c("user")},D=()=>{if(!b)return;const y=w==="custom"?p:parseInt(w);!y||y<=0||x(b.id,y)};return e.jsx(me,{open:t,onClose:E,title:"Assign Escalations",children:e.jsxs("div",{className:"space-y-4",children:[r==="user"&&e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"text-sm text-text-secondary",children:["Select a user to assign"," ",e.jsx("span",{className:"font-medium text-text-primary",children:l})," ","escalation(s) to:"]}),e.jsx("input",{type:"text",value:N,onChange:y=>v(y.target.value),placeholder:"Search by name or email...",className:"input text-xs w-full",autoFocus:!0}),e.jsxs("div",{className:"max-h-60 overflow-y-auto border border-surface-border rounded-lg divide-y divide-surface-border",children:[M&&e.jsx("p",{className:"text-xs text-text-tertiary p-3",children:"Loading users..."}),!M&&A.length===0&&e.jsx("p",{className:"text-xs text-text-tertiary p-3",children:"No users found"}),A.map(y=>e.jsxs("button",{onClick:()=>O(y),className:"w-full text-left px-3 py-2 hover:bg-surface-hover transition-colors",children:[e.jsx("p",{className:"text-xs font-medium text-text-primary",children:y.display_name||y.external_id}),y.email&&e.jsx("p",{className:"text-[10px] text-text-tertiary",children:y.email})]},y.id))]}),e.jsx("div",{className:"flex justify-end pt-2",children:e.jsx("button",{onClick:E,className:"btn-secondary text-xs",children:"Cancel"})})]}),r==="duration"&&b&&e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"text-sm text-text-secondary",children:["Assign to"," ",e.jsx("span",{className:"font-medium text-text-primary",children:b.display_name||b.external_id})," ","for:"]}),e.jsxs("select",{value:w,onChange:y=>{i(y.target.value),m(0)},className:"select w-full text-sm",children:[f.map(y=>e.jsx("option",{value:y.value,children:y.label},y.value)),e.jsx("option",{value:"custom",children:"Other..."})]}),w==="custom"&&e.jsx(Ye,{onChange:h,autoFocus:!0}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{onClick:B,className:"btn-secondary text-xs",children:"Back"}),e.jsx("button",{onClick:D,disabled:d,className:"btn-primary text-xs",children:d?"Assigning...":"Assign"})]})]})]})})}function Gs({open:t,onClose:s,selectedCount:l,onSubmit:a,isPending:x}){const[d,u]=g.useState(""),f=()=>{a(d||void 0)};return e.jsx(me,{open:t,onClose:s,title:"Submit for AI Triage",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("p",{className:"text-sm text-text-secondary",children:["Submit ",e.jsx("span",{className:"font-medium text-text-primary",children:l})," escalation(s) for AI triage? The triage orchestrator will take over resolution."]}),e.jsxs("div",{children:[e.jsxs("label",{className:"text-xs font-medium text-text-secondary block mb-1",children:["Triage hint ",e.jsx("span",{className:"text-text-tertiary",children:"(optional)"})]}),e.jsx("input",{type:"text",value:d,onChange:r=>u(r.target.value),placeholder:"e.g., image_orientation",className:"input text-xs font-mono w-full"}),e.jsx("p",{className:"text-[10px] text-text-tertiary mt-1",children:"Guides the triage workflow on what remediation to apply"})]}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{onClick:s,className:"btn-secondary text-xs",children:"Cancel"}),e.jsx("button",{onClick:f,disabled:x,className:"btn-primary text-xs",children:x?"Submitting...":"Submit for Triage"})]})]})})}function U(t,s,l){return a=>{t.mutate(a,{onSuccess:()=>{s(),l==null||l()}})}}function Hs(t){const s=()=>[...t.selectedIds];return{handleSetPriority:r=>{U(t.setPriority,t.clearSelection)({ids:s(),priority:r})},handleBulkClaim:r=>{U(t.bulkClaim,t.clearSelection)({ids:s(),durationMinutes:r})},handleBulkEscalate:r=>{U(t.bulkEscalate,t.clearSelection)({ids:s(),targetRole:r})},handleBulkTriage:r=>{U(t.bulkTriage,t.clearSelection,t.closeTriageModal)({ids:s(),hint:r})},handleBulkAssign:(r,c)=>{U(t.bulkAssign,t.clearSelection,t.closeAssignModal)({ids:s(),targetUserId:r,durationMinutes:c})},handleBulkCancel:()=>{U(t.bulkCancel,t.clearSelection,t.closeCancelModal)({ids:s()})}}}function Vs({claimTarget:t,onClose:s,claimDuration:l,onDurationChange:a,claimDurations:x,onCustomClaimChange:d,onClaim:u,isPending:f}){return e.jsx(me,{open:!!t,onClose:s,title:"Claim Escalation",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("p",{className:"text-sm text-text-secondary",children:["Claim ",e.jsx("span",{className:"font-medium text-text-primary",children:t==null?void 0:t.type})," for:"]}),e.jsxs("select",{value:l,onChange:r=>{a(r.target.value)},className:"select w-full text-sm",children:[x.map(r=>e.jsx("option",{value:r.value,children:r.label},r.value)),e.jsx("option",{value:"custom",children:"Other..."})]}),l==="custom"&&e.jsx(Ye,{onChange:d,autoFocus:!0}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{onClick:s,className:"btn-secondary text-xs",children:"Cancel"}),e.jsx("button",{onClick:u,className:"btn-primary text-xs",disabled:f,children:f?"Claiming...":"Claim"})]})]})})}const H={pending:"#0ea5e9",claimed:"#f97316",resolved:"#16a34a",cancelled:"#94a3b8",expired:"#64748b"},qe=40,Js=64,Qs=24,Ue=3;function at(t){return t<6e4?`${Math.round(t/1e3)}s`:t<36e5?`${Math.round(t/6e4)}m`:t<864e5?`${(t/36e5).toFixed(1)}h`:`${(t/864e5).toFixed(1)}d`}function Ge(t){const s=Date.now()-t;return s<6e4?"just now":s<36e5?`${Math.round(s/6e4)}m ago`:s<864e5?`${Math.round(s/36e5)}h ago`:`${Math.round(s/864e5)}d ago`}function He(t){return t.replace(/-/g," ").replace(/\b\w/g,s=>s.toUpperCase())}function Ws(t,s){return t?[...s.filter(a=>a in t),...Object.keys(t).filter(a=>!s.includes(a))].map(a=>[a,t[a]]):[]}function Xs({e:t}){const s=t.endMs-t.startMs;if(s<=0)return null;const l=H.pending,a=H.claimed,x=t.status==="cancelled"||t.status==="expired"?H.cancelled:H.resolved;let d=100,u=0,f=0;return t.claimedMs!==null?(d=Math.max(0,Math.min(100,(t.claimedMs-t.startMs)/s*100)),t.isOpen?u=100-d:(u=Math.max(0,Math.min(100-d,(t.endMs-t.claimedMs)/s*100)),f=Math.max(0,100-d-u))):t.isOpen||(f=100,d=0),e.jsxs("div",{className:"mt-2 h-0.5 rounded-full overflow-hidden flex bg-slate-100",children:[d>0&&e.jsx("div",{style:{width:`${d}%`,backgroundColor:l,opacity:.6}}),u>0&&e.jsx("div",{style:{width:`${u}%`,backgroundColor:a,opacity:.6}}),f>0&&e.jsx("div",{style:{width:`${f}%`,backgroundColor:x,opacity:.6}})]})}function Ys({gapMs:t,heightPx:s}){return e.jsx("div",{className:"relative flex items-center justify-center",style:{height:s},children:t>=6e4&&e.jsx("span",{className:"text-[9px] text-slate-300 font-mono bg-white px-2 relative z-10",children:at(t)})})}function Ve({e:t,highlightKeys:s,onRowClick:l}){const[a,x]=g.useState(!1),d=H[t.displayStatus]??"#94a3b8",u=Ws(t.metadata,s),f=a?u:u.slice(0,Ue),r=u.length-Ue;return e.jsxs("div",{className:"cursor-pointer max-w-[460px] min-w-[260px] w-full bg-white rounded-lg shadow-sm border border-slate-200/60 px-3.5 pt-2.5 pb-2 hover:shadow-md hover:border-slate-300/60 transition-all duration-150",style:{borderTopWidth:"3px",borderTopColor:d},onClick:()=>l==null?void 0:l(t),children:[e.jsxs("div",{className:"flex items-baseline gap-2 mb-1.5",children:[e.jsx("span",{className:"text-[9px] font-bold uppercase tracking-widest text-slate-400 shrink-0",children:He(t.role)}),e.jsxs("span",{className:"text-[12px] font-semibold text-slate-800 truncate",title:t.type,children:[t.type,t.subtype&&t.subtype!==t.type&&t.subtype!==""&&e.jsxs("span",{className:"font-normal text-slate-500",children:[" · ",t.subtype]})]})]}),f.length>0&&e.jsxs("div",{className:"border-t border-slate-100 pt-1 space-y-px",children:[f.map(([c,b])=>{const j=String(b),N=s.includes(c);return e.jsxs("div",{className:"group/row flex items-center gap-1.5 -mx-1 px-1 py-[2px] rounded",children:[e.jsx("span",{className:`shrink-0 w-[60px] text-[9px] font-mono uppercase tracking-wide truncate ${N?"text-accent":"text-slate-400"}`,title:c,children:c}),e.jsx("span",{className:`flex-1 min-w-0 text-[11px] font-medium truncate ${N?"text-slate-800":"text-slate-600"}`,title:j,children:j}),e.jsxs("span",{className:"flex items-center gap-px shrink-0 opacity-0 group-hover/row:opacity-100 transition-opacity",children:[e.jsx(Fe,{to:$e(c,b,t.role),className:"p-0.5 rounded text-slate-300 hover:text-accent transition-colors",title:`Filter ${He(t.role)}: ${c} = ${j}`,onClick:v=>v.stopPropagation(),children:e.jsx(cs,{className:"w-2.5 h-2.5"})}),e.jsx(Fe,{to:$e(c,b),className:"p-0.5 rounded text-slate-300 hover:text-accent transition-colors",title:`Search all: ${c} = ${j}`,onClick:v=>v.stopPropagation(),children:e.jsx(ds,{className:"w-2.5 h-2.5"})})]})]},c)}),r>0&&e.jsx("button",{className:"flex items-center gap-0.5 text-[9px] text-slate-400 hover:text-accent transition-colors mt-0.5 -mx-1 px-1 py-px",onClick:c=>{c.stopPropagation(),x(b=>!b)},children:a?e.jsxs(e.Fragment,{children:[e.jsx(xs,{className:"w-2.5 h-2.5"})," less"]}):e.jsxs(e.Fragment,{children:[e.jsx(Ke,{className:"w-2.5 h-2.5"})," ",r," more"]})})]}),e.jsx(Xs,{e:t})]})}function Ks({escalations:t,highlightKeys:s=[],onRowClick:l,total:a,page:x,totalPages:d,onPageChange:u}){var m,h;const f=Date.now(),c=t.map(n=>{const k=new Date(n.created_at).getTime(),P=n.resolved_at?new Date(n.resolved_at).getTime():null,M=n.claimed_at?new Date(n.claimed_at).getTime():null,A=!P&&n.status!=="cancelled"&&n.status!=="expired",E=P??(A?f:k+3e4),O=n.status==="pending"&&Je(n)?"claimed":n.status;return{...n,startMs:k,claimedMs:M,endMs:E,isOpen:A,displayStatus:O}});if(c.length===0)return e.jsx("p",{className:"mt-12 text-center text-sm text-text-tertiary",children:"No escalations matched."});const b=c.length,N=Math.max(Math.abs((((m=c[b-1])==null?void 0:m.startMs)??0)-(((h=c[0])==null?void 0:h.startMs)??0)),1)/Math.max(b-1,1),v=Js/Math.max(N,1),i=new Set(c.map(n=>new Date(n.startMs).toDateString())).size>1;function p(n){const k=new Date(n),P=k.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});return i?k.toLocaleDateString([],{month:"short",day:"numeric"})+" "+P:P}return e.jsxs("div",{className:"mt-4 pb-24",children:[e.jsxs("div",{className:"relative",children:[e.jsx("div",{className:"absolute left-1/2 -translate-x-px inset-y-0 w-px bg-slate-200/80"}),c.map((n,k)=>{const P=c[k-1],M=P?Math.abs(n.startMs-P.startMs):null,A=M!==null?Math.max(Qs,Math.round(M*v)):0,E=k%2===0,O=H[n.displayStatus]??"#94a3b8",B=n.endMs-n.startMs,D=n.isOpen?Ge(n.startMs):`${Ge(n.startMs)} · ${at(B)}`;return e.jsxs("div",{children:[k>0&&e.jsx(Ys,{gapMs:M,heightPx:A}),e.jsxs("div",{className:"flex items-center",children:[e.jsx("div",{className:"flex-1 flex justify-end items-center",children:E?e.jsxs("div",{className:"flex items-center",children:[e.jsx(Ve,{e:n,highlightKeys:s,onRowClick:l}),e.jsx("div",{className:"flex-shrink-0 h-px bg-slate-200/70",style:{width:qe}})]}):e.jsx("span",{className:"text-[10px] text-slate-400 font-mono tabular-nums pr-3",children:D})}),e.jsx("div",{className:"relative z-10 flex-shrink-0 w-3.5 h-3.5 rounded-full border-2 border-white cursor-pointer transition-all duration-150 hover:scale-[1.5]",style:{backgroundColor:O,boxShadow:`0 0 0 3px ${O}28, 0 1px 3px ${O}30`},onClick:()=>l==null?void 0:l(n)}),e.jsx("div",{className:"flex-1 flex justify-start items-center",children:E?e.jsx("span",{className:"text-[10px] text-slate-400 font-mono tabular-nums pl-3",children:D}):e.jsxs("div",{className:"flex items-center",children:[e.jsx("div",{className:"flex-shrink-0 h-px bg-slate-200/70",style:{width:qe}}),e.jsx(Ve,{e:n,highlightKeys:s,onRowClick:l})]})})]}),e.jsx("div",{className:"flex justify-center relative z-10 mt-0.5",children:e.jsx("span",{className:"text-[9px] text-slate-400 font-mono tabular-nums bg-white px-1.5",children:p(n.startMs)})})]},n.id)})]}),d>1&&e.jsxs("div",{className:"sticky bottom-0 z-20 bg-surface/95 backdrop-blur-sm border-t border-surface-border -mx-10 px-10 pt-2 pb-4 flex items-center justify-between mt-10",children:[e.jsxs("span",{className:"text-[11px] text-text-tertiary",children:["Page ",e.jsx("span",{className:"font-medium text-text-secondary",children:x})," ","of ",e.jsx("span",{className:"font-medium text-text-secondary",children:d})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{onClick:()=>u(x-1),disabled:x<=1,className:"p-1.5 rounded hover:bg-surface-hover disabled:opacity-30 text-text-tertiary hover:text-text-primary transition-colors disabled:cursor-not-allowed",children:e.jsx(is,{className:"w-4 h-4"})}),e.jsx("button",{onClick:()=>u(x+1),disabled:x>=d,className:"p-1.5 rounded hover:bg-surface-hover disabled:opacity-30 text-text-tertiary hover:text-text-primary transition-colors disabled:cursor-not-allowed",children:e.jsx(os,{className:"w-4 h-4"})})]})]})]})}function wa(){var Pe,Me,Ee,Te,Ae,Oe,_e;ss();const t=Tt(),{filters:s,setFilter:l,pagination:a}=bs({filters:{role:"",type:"",priority:"",status:"available",search:""}}),x=tt(s.search,300),d=ue(),[u,f]=g.useState(null),[r,c]=g.useState("30"),[b,j]=g.useState(0),N=g.useCallback(o=>j(o),[]),[v,w]=g.useState(new Set),[i,p]=g.useState(!1),[m,h]=At(),n=g.useMemo(()=>_t(m),[m]),k=g.useCallback(o=>{h(C=>{const S=new URLSearchParams(C);return Ft(S,o),S.delete("page"),S})},[h]),{data:P}=Dt(i),M=$t(n)+(s.search?1:0),[A,E]=g.useState(!1),[O,B]=g.useState(!1),[D,y]=g.useState(!1),nt=g.useCallback(o=>k({...n,orderBy:o}),[n,k]),{canBulk:lt}=Rt(),he=n.facets?Object.keys(n.facets):[],Q=m.get("view"),pe=g.useCallback(o=>{h(C=>{const S=new URLSearchParams(C);return o?S.set("view",o):S.delete("view"),S},{replace:!0})},[h]),$=Q?Q==="timeline":M>0,rt=g.useCallback(o=>{const{[o]:C,...S}=n.facets??{};k({...n,facets:Object.keys(S).length>0?S:void 0})},[n,k]),fe=It(),ge=qt(),be=Ut(),ne=Gt(),je=Ht(),le=Vt(),W=Jt(),{data:R}=Qt(),{data:L}=Wt(),{data:re}=Xt(),{user:X,isSuperAdmin:it,hasRoleType:ot}=Xe(),ve=it||ot("admin"),ye=g.useMemo(()=>new Set(((X==null?void 0:X.roles)??[]).map(o=>o.role)),[X]),ct=g.useMemo(()=>{const o=(L==null?void 0:L.roles)??[];return(ve?o:o.filter(S=>ye.has(S.role)&&!Yt(S.role))).map(S=>({value:S.role,label:Kt(S)})).sort((S,Et)=>S.label.localeCompare(Et.label))},[L,ve,ye]);g.useEffect(()=>{w(new Set)},[s.role,s.type,s.priority,s.status,x,a.page,a.pageSize]);const V=s.status||"",J=V==="available",ie=V==="claimed",Ne=ie?"pending":V==="resolved"?"resolved":V==="cancelled"?"cancelled":V==="expired"?"expired":void 0,Ce=100,we={role:s.role||void 0,type:s.type||void 0,priority:s.priority?parseInt(s.priority):void 0,limit:$?Ce:a.pageSize,offset:a.offset,sort_by:"created_at",order:"desc",search:x||void 0,...n},dt=Zt({...we,enabled:J}),xt=Qe({status:Ne,claimed:ie||void 0,...we,enabled:!J}),ut=J?dt:xt,{data:I,isLoading:mt,error:Y,refetch:ht,isFetching:pt}=ut,ft=js(`/escalations${J?"/available":""}`,{status:Ne,claimed:ie||void 0,role:s.role||void 0,type:s.type||void 0,priority:s.priority||void 0,search:x||void 0,sort_by:"created_at",order:"desc",limit:a.pageSize,offset:a.offset,facets:n.facets&&Object.keys(n.facets).length?JSON.stringify(n.facets):void 0,block:(Pe=n.block)!=null&&Pe.length?JSON.stringify(n.block):void 0,range:(Me=n.range)!=null&&Me.length?JSON.stringify(n.range):void 0,exists:(Ee=n.exists)!=null&&Ee.length?JSON.stringify(n.exists):void 0,roles:(Te=n.roles)!=null&&Te.length?JSON.stringify(n.roles):void 0,orderBy:(Ae=n.orderBy)!=null&&Ae.length?JSON.stringify(n.orderBy):void 0,available:n.available!=null?String(n.available):void 0}),_=(I==null?void 0:I.escalations)??[],T=(I==null?void 0:I.total)??0,z=s.role||(((Oe=n.roles)==null?void 0:Oe.length)===1?n.roles[0]:null),K=((_e=es(z??"",void 0,!!z).data)==null?void 0:_e.list_schema)??null,ke=!!z&&!!K&&!!K["x-lt-layout"]&&K["x-lt-layout"]!=="table",Z=ke&&!$&&(Q?Q==="rich":!0),Se=g.useMemo(()=>{if(!n.jeopardy||!z)return null;const o=((L==null?void 0:L.roles)??[]).find(S=>S.role===z),C=(o==null?void 0:o.priority_threshold_minutes)??(o==null?void 0:o.sla_minutes)??null;return C!=null?ts(C*6e4):null},[n.jeopardy,z,L]),gt=g.useMemo(()=>{const o=new Set;for(const C of _)v.has(C.id)&&o.add(C.role);return[...o]},[_,v]),bt=g.useCallback(()=>w(new Set),[]),jt=()=>{if(!u)return;const o=r==="custom"?b:parseInt(r);!o||o<=0||fe.mutate({id:u.id,durationMinutes:o},{onSuccess:()=>{f(null),t(`/escalations/detail/${u.id}`)}})},{handleSetPriority:vt,handleBulkClaim:yt,handleBulkEscalate:Nt,handleBulkTriage:Ct,handleBulkAssign:wt,handleBulkCancel:kt}=Hs({selectedIds:v,clearSelection:bt,setPriority:ge,bulkClaim:be,bulkEscalate:je,bulkTriage:le,bulkAssign:ne,bulkCancel:W,closeTriageModal:()=>E(!1),closeAssignModal:()=>B(!1),closeCancelModal:()=>y(!1)}),St=o=>{const C=new Set(v);C.has(o)?C.delete(o):C.add(o),w(C)},Pt=()=>{v.size===_.length?w(new Set):w(new Set(_.map(o=>o.id)))},Mt=[lt?{key:"select",label:e.jsx("input",{type:"checkbox",checked:_.length>0&&v.size===_.length,onChange:Pt,className:"rounded"}),render:o=>e.jsx("input",{type:"checkbox",checked:v.has(o.id),onChange:C=>{C.stopPropagation(),St(o.id)},onClick:C=>C.stopPropagation(),className:"rounded"}),className:"w-10"}:{key:"spacer",label:"",render:()=>null,className:"w-10"},...Cs({highlightKeys:he}),{key:"actions",label:"",render:o=>e.jsx(ks,{children:e.jsx(Ss,{icon:us,title:"Claim escalation",onClick:()=>f(o),colorClass:"text-accent/75 hover:text-accent",size:"sm"})}),className:"w-10 text-right"}];return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2 mb-10 min-w-0",children:[e.jsx(_s,{role:s.role,options:ct,onChange:o=>l("role",o)}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:dashboard.md:all-escalations"},className:"text-text-quaternary hover:text-accent transition-colors mt-1 shrink-0",title:"Open docs for this page",children:e.jsx(ms,{className:"w-4 h-4",strokeWidth:1.5})})]}),e.jsx(ws,{filters:s,setFilter:l,roles:(R==null?void 0:R.roles)??[],types:(re==null?void 0:re.types)??[],showStatus:!0,showRole:!1,showSearch:!1,actions:e.jsxs(e.Fragment,{children:[$&&e.jsxs("span",{className:"text-[11px] text-text-tertiary whitespace-nowrap",children:[T>100&&e.jsxs(e.Fragment,{children:[e.jsxs("span",{className:"font-medium text-text-secondary",children:[(a.page-1)*100+1,"–",Math.min(a.page*100,T)]})," of "]}),e.jsx("span",{className:"font-medium text-text-secondary",children:T})," ",T===1?"escalation":"escalations"]}),e.jsx(Fs,{orderBy:n.orderBy,onChange:nt}),e.jsx("span",{className:"h-3.5 w-px bg-surface-border shrink-0"}),e.jsx(Ps,{onRefresh:()=>ht(),isFetching:pt,apiPath:ft}),ke&&!$&&e.jsx("button",{onClick:()=>pe(Z?"table":"rich"),className:"ml-2 inline-flex h-7 w-7 items-center justify-center rounded text-text-tertiary hover:bg-surface-hover hover:text-text-primary transition-colors",title:Z?"Table view":"Rich view",children:Z?e.jsx(Le,{className:"w-4 h-4"}):e.jsx(hs,{className:"w-4 h-4"})}),M>0&&e.jsx("button",{onClick:()=>pe($?"table":"timeline"),className:"ml-2 inline-flex h-7 w-7 items-center justify-center rounded text-text-tertiary hover:bg-surface-hover hover:text-text-primary transition-colors",title:$?"Table view":"Timeline view",children:$?e.jsx(Le,{className:"w-4 h-4"}):e.jsx(ps,{className:"w-4 h-4"})}),e.jsxs("button",{onClick:()=>p(o=>!o),className:"relative ml-2 inline-flex h-7 w-7 items-center justify-center rounded text-text-tertiary hover:bg-surface-hover hover:text-text-primary transition-colors",title:"Faceted query",children:[e.jsx(fs,{className:"w-4 h-4"}),M>0&&e.jsx("span",{className:"absolute -right-1 -top-1 flex h-3.5 min-w-[14px] items-center justify-center rounded-full bg-accent px-0.5 text-[9px] font-medium text-white",children:M})]})]})}),Ot.createPortal(e.jsxs("div",{className:`fixed right-0 bottom-0 w-[420px] z-40 border-l border-surface-border bg-surface overflow-y-auto shadow-lg transition-transform duration-200 ease-out ${i?"translate-x-0":"pointer-events-none translate-x-full"}`,style:{top:"3.5rem"},"aria-hidden":!i,children:[e.jsxs("div",{className:"sticky top-0 z-10 flex items-center justify-between px-4 py-3 bg-surface border-b border-surface-border/50",children:[e.jsx("span",{className:"text-xs font-medium text-text-primary",children:"Faceted query"}),e.jsxs("div",{className:"flex items-center gap-2",children:[M>0&&e.jsx("button",{onClick:()=>{k({}),l("search","")},className:"text-[11px] text-text-tertiary hover:text-text-primary transition-colors",children:"Clear"}),e.jsx("button",{onClick:()=>p(!1),className:"p-1 rounded hover:bg-surface-hover text-text-tertiary hover:text-text-primary transition-colors",title:"Close",children:e.jsx(se,{className:"w-4 h-4"})})]})]}),e.jsxs("div",{className:"px-4 py-2",children:[e.jsxs("p",{className:"mb-2 text-[11px] leading-snug text-text-tertiary",children:["Precise metadata facets plus exact correlation-id lookup — they compose in one SQL query. Facet keys are the ones that actually exist in your visible escalations. Set status to ",e.jsx("span",{className:"font-medium",children:"All"})," to find an order across every status; the whole query is shareable via the URL."]}),e.jsx(Os,{value:n,onChange:k,facetKeys:(P==null?void 0:P.keys)??[],search:s.search??"",onSearchChange:o=>l("search",o)})]})]}),document.body),e.jsx(qs,{selectedCount:v.size,onClearSelection:()=>w(new Set),onSetPriority:vt,onClaim:yt,onAssign:()=>B(!0),onEscalate:Nt,onTriage:()=>E(!0),onCancel:()=>y(!0),isPriorityPending:ge.isPending,isClaimPending:be.isPending,isAssignPending:ne.isPending,isEscalatePending:je.isPending,isTriagePending:le.isPending,isCancelPending:W.isPending,availableRoles:(R==null?void 0:R.roles)??[]}),(n.facets&&Object.keys(n.facets).length>0||n.jeopardy)&&e.jsxs("div",{className:"sticky top-14 z-30 bg-surface/98 backdrop-blur-sm border-b border-surface-border/30 -mx-10 px-10 py-2 flex items-center gap-1.5 flex-wrap",children:[n.jeopardy&&e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full bg-status-error px-2.5 py-0.5 text-[10px] font-semibold text-white",children:[e.jsx(gs,{className:"w-2.5 h-2.5",strokeWidth:2.5}),"in jeopardy",Se&&e.jsxs("span",{className:"font-mono font-normal opacity-90",children:["> ",Se]}),e.jsx("button",{onClick:()=>k({...n,jeopardy:void 0}),className:"ml-0.5 -mr-0.5 flex items-center text-white/70 hover:text-white transition-colors","aria-label":"Clear jeopardy filter",children:e.jsx(se,{className:"w-2.5 h-2.5"})})]}),Object.entries(n.facets??{}).map(([o,C])=>e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full border border-accent/25 bg-accent/8 px-2.5 py-0.5 text-[10px] font-medium text-accent/90",children:[e.jsx("span",{className:"font-mono text-text-tertiary",children:o}),e.jsx("span",{className:"text-text-quaternary",children:"="}),e.jsx("span",{className:"font-mono max-w-[160px] truncate",title:String(C),children:String(C)}),e.jsx("button",{onClick:()=>rt(o),className:"ml-0.5 -mr-0.5 flex items-center text-text-quaternary hover:text-status-error transition-colors","aria-label":`Remove ${o} filter`,children:e.jsx(se,{className:"w-2.5 h-2.5"})})]},o)),Object.keys(n.facets??{}).length>1&&e.jsx("button",{onClick:()=>k({...n,facets:void 0}),className:"text-[10px] text-text-quaternary hover:text-text-secondary transition-colors px-1",children:"clear all"})]}),Y&&e.jsx("div",{className:"mb-4 px-4 py-3 rounded-md bg-status-error/10 border border-status-error/20 text-xs text-status-error",children:Y.message==="Session expired"?"Your session has expired. Please log in again.":`Failed to load escalations: ${Y.message}`}),$?e.jsx(Ks,{escalations:_,highlightKeys:he,onRowClick:o=>t(`/escalations/detail/${o.id}`,{state:{from:"/escalations/available"}}),total:T,page:a.page,totalPages:Math.ceil(T/Ce),onPageChange:a.setPage}):Z?e.jsx(Ds,{role:z,listSchema:K,activeEscalations:_,onRowClick:o=>t(`/escalations/detail/${o.id}`,{state:{from:"/escalations/available"}}),total:T,page:a.page,totalPages:a.totalPages(T),pageSize:a.pageSize,onPageChange:a.setPage,onPageSizeChange:a.setPageSize}):e.jsxs(e.Fragment,{children:[e.jsx(vs,{columns:Mt,data:_,keyFn:o=>o.id,onRowClick:o=>t(`/escalations/detail/${o.id}`,{state:{from:"/escalations/available"}}),isLoading:mt,emptyMessage:Y?"Unable to load data":"No escalations"}),e.jsx(et,{page:a.page,totalPages:a.totalPages(T),onPageChange:a.setPage,total:T,pageSize:a.pageSize,onPageSizeChange:a.setPageSize})]}),e.jsx(Vs,{claimTarget:u,onClose:()=>f(null),claimDuration:r,onDurationChange:o=>{c(o),j(0)},claimDurations:d,customClaimMinutes:b,onCustomClaimChange:N,onClaim:jt,isPending:fe.isPending}),e.jsx(Gs,{open:A,onClose:()=>E(!1),selectedCount:v.size,onSubmit:Ct,isPending:le.isPending}),e.jsx(Us,{open:O,onClose:()=>B(!1),selectedCount:v.size,selectedRoles:gt,onSubmit:wt,isPending:ne.isPending}),e.jsx(as,{open:D,onClose:()=>y(!1),onConfirm:kt,selectedCount:v.size,isPending:W.isPending,error:W.error})]})}export{wa as AvailableEscalationsPage};
2
- //# sourceMappingURL=AvailableEscalationsPage-AiuiLcz-.js.map