@hotmeshio/long-tail 0.16.0 → 0.16.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 (184) hide show
  1. package/build/shared/form-validation/field-validator.d.ts +12 -0
  2. package/build/shared/form-validation/field-validator.js +31 -3
  3. package/build/shared/form-validation/x-lt-options.d.ts +7 -2
  4. package/build/shared/form-validation/x-lt-options.js +32 -10
  5. package/dashboard/dist/assets/{AdminDashboard-BVgjY4zN.js → AdminDashboard-BrOvvDHF.js} +2 -2
  6. package/dashboard/dist/assets/{AdminDashboard-BVgjY4zN.js.map → AdminDashboard-BrOvvDHF.js.map} +1 -1
  7. package/dashboard/dist/assets/{AgentConfigPage-ChL59YL5.js → AgentConfigPage-CtVq8J0L.js} +2 -2
  8. package/dashboard/dist/assets/{AgentConfigPage-ChL59YL5.js.map → AgentConfigPage-CtVq8J0L.js.map} +1 -1
  9. package/dashboard/dist/assets/{AgentDetailPage-IJfgCOIF.js → AgentDetailPage-DTfTQDug.js} +2 -2
  10. package/dashboard/dist/assets/{AgentDetailPage-IJfgCOIF.js.map → AgentDetailPage-DTfTQDug.js.map} +1 -1
  11. package/dashboard/dist/assets/{AgentsPage-C7PnPXz_.js → AgentsPage-vCTc3Qvj.js} +2 -2
  12. package/dashboard/dist/assets/{AgentsPage-C7PnPXz_.js.map → AgentsPage-vCTc3Qvj.js.map} +1 -1
  13. package/dashboard/dist/assets/{AvailableEscalationsPage-C5f2rqHa.js → AvailableEscalationsPage-DJODShd7.js} +2 -2
  14. package/dashboard/dist/assets/{AvailableEscalationsPage-C5f2rqHa.js.map → AvailableEscalationsPage-DJODShd7.js.map} +1 -1
  15. package/dashboard/dist/assets/{BotPicker-CBf6bHLV.js → BotPicker-GU44inXA.js} +2 -2
  16. package/dashboard/dist/assets/{BotPicker-CBf6bHLV.js.map → BotPicker-GU44inXA.js.map} +1 -1
  17. package/dashboard/dist/assets/{BulkAssignModal-CkxoPByA.js → BulkAssignModal-ChqzG6FY.js} +2 -2
  18. package/dashboard/dist/assets/{BulkAssignModal-CkxoPByA.js.map → BulkAssignModal-ChqzG6FY.js.map} +1 -1
  19. package/dashboard/dist/assets/{CapabilitiesPage-D7USh3F0.js → CapabilitiesPage-Y2hycdPY.js} +2 -2
  20. package/dashboard/dist/assets/{CapabilitiesPage-D7USh3F0.js.map → CapabilitiesPage-Y2hycdPY.js.map} +1 -1
  21. package/dashboard/dist/assets/{CollapsibleSection-DfPpAIxa.js → CollapsibleSection-CmCwt_Rs.js} +2 -2
  22. package/dashboard/dist/assets/{CollapsibleSection-DfPpAIxa.js.map → CollapsibleSection-CmCwt_Rs.js.map} +1 -1
  23. package/dashboard/dist/assets/{CountdownTimer-DVL7WIcE.js → CountdownTimer-Bx2XXJOd.js} +2 -2
  24. package/dashboard/dist/assets/{CountdownTimer-DVL7WIcE.js.map → CountdownTimer-Bx2XXJOd.js.map} +1 -1
  25. package/dashboard/dist/assets/{CredentialsPage-BHZ5SKIu.js → CredentialsPage-CoX_PNBe.js} +2 -2
  26. package/dashboard/dist/assets/{CredentialsPage-BHZ5SKIu.js.map → CredentialsPage-CoX_PNBe.js.map} +1 -1
  27. package/dashboard/dist/assets/{CronLabel-wE8Hms6c.js → CronLabel-CVYKRipP.js} +2 -2
  28. package/dashboard/dist/assets/{CronLabel-wE8Hms6c.js.map → CronLabel-CVYKRipP.js.map} +1 -1
  29. package/dashboard/dist/assets/{ElapsedCell-B4VxKHpw.js → ElapsedCell-jRURiCRW.js} +2 -2
  30. package/dashboard/dist/assets/{ElapsedCell-B4VxKHpw.js.map → ElapsedCell-jRURiCRW.js.map} +1 -1
  31. package/dashboard/dist/assets/{EntityTimelinePanel-CFbQDHOj.js → EntityTimelinePanel-G6nzvgpl.js} +2 -2
  32. package/dashboard/dist/assets/{EntityTimelinePanel-CFbQDHOj.js.map → EntityTimelinePanel-G6nzvgpl.js.map} +1 -1
  33. package/dashboard/dist/assets/{EscalationListSchemaPage-YTgexl4f.js → EscalationListSchemaPage-D-rVTQ1m.js} +2 -2
  34. package/dashboard/dist/assets/{EscalationListSchemaPage-YTgexl4f.js.map → EscalationListSchemaPage-D-rVTQ1m.js.map} +1 -1
  35. package/dashboard/dist/assets/{EscalationSchemaPage-Sjk05eHP.js → EscalationSchemaPage-CV0R_xY9.js} +2 -2
  36. package/dashboard/dist/assets/{EscalationSchemaPage-Sjk05eHP.js.map → EscalationSchemaPage-CV0R_xY9.js.map} +1 -1
  37. package/dashboard/dist/assets/{EscalationsOverview-gHWPjUpZ.js → EscalationsOverview-DMdx15CQ.js} +2 -2
  38. package/dashboard/dist/assets/{EscalationsOverview-gHWPjUpZ.js.map → EscalationsOverview-DMdx15CQ.js.map} +1 -1
  39. package/dashboard/dist/assets/{EventTable-C9lHQ57t.js → EventTable-CIvsdt-q.js} +2 -2
  40. package/dashboard/dist/assets/{EventTable-C9lHQ57t.js.map → EventTable-CIvsdt-q.js.map} +1 -1
  41. package/dashboard/dist/assets/{FilterBar-BY--ANxv.js → FilterBar-DWYGkVRH.js} +2 -2
  42. package/dashboard/dist/assets/{FilterBar-BY--ANxv.js.map → FilterBar-DWYGkVRH.js.map} +1 -1
  43. package/dashboard/dist/assets/{GraphInvokePage-B-Oo5s-W.js → GraphInvokePage-BGHlXh4r.js} +2 -2
  44. package/dashboard/dist/assets/{GraphInvokePage-B-Oo5s-W.js.map → GraphInvokePage-BGHlXh4r.js.map} +1 -1
  45. package/dashboard/dist/assets/{HomePage-BrcjKOaJ.js → HomePage-BHOnp8SK.js} +2 -2
  46. package/dashboard/dist/assets/{HomePage-BrcjKOaJ.js.map → HomePage-BHOnp8SK.js.map} +1 -1
  47. package/dashboard/dist/assets/{ListToolbar-D5TQ4X_M.js → ListToolbar-iOgn_db5.js} +2 -2
  48. package/dashboard/dist/assets/{ListToolbar-D5TQ4X_M.js.map → ListToolbar-iOgn_db5.js.map} +1 -1
  49. package/dashboard/dist/assets/{McpOverview-jlukVWQ7.js → McpOverview-Be9sMKCA.js} +2 -2
  50. package/dashboard/dist/assets/{McpOverview-jlukVWQ7.js.map → McpOverview-Be9sMKCA.js.map} +1 -1
  51. package/dashboard/dist/assets/{McpQueryDetailPage-BWKbvJSd.js → McpQueryDetailPage-BIgpmGJN.js} +2 -2
  52. package/dashboard/dist/assets/{McpQueryDetailPage-BWKbvJSd.js.map → McpQueryDetailPage-BIgpmGJN.js.map} +1 -1
  53. package/dashboard/dist/assets/{McpQueryPage-BH2Pon4M.js → McpQueryPage-Okcxw_Um.js} +2 -2
  54. package/dashboard/dist/assets/{McpQueryPage-BH2Pon4M.js.map → McpQueryPage-Okcxw_Um.js.map} +1 -1
  55. package/dashboard/dist/assets/{McpRunDetailPage-kUnq2QSO.js → McpRunDetailPage-DT8kOfih.js} +2 -2
  56. package/dashboard/dist/assets/{McpRunDetailPage-kUnq2QSO.js.map → McpRunDetailPage-DT8kOfih.js.map} +1 -1
  57. package/dashboard/dist/assets/{McpRunsPage-BTucgt64.js → McpRunsPage-BXhoP77D.js} +2 -2
  58. package/dashboard/dist/assets/{McpRunsPage-BTucgt64.js.map → McpRunsPage-BXhoP77D.js.map} +1 -1
  59. package/dashboard/dist/assets/{OperationsPage-Cp8WL-ld.js → OperationsPage-rVhC8JPv.js} +2 -2
  60. package/dashboard/dist/assets/{OperationsPage-Cp8WL-ld.js.map → OperationsPage-rVhC8JPv.js.map} +1 -1
  61. package/dashboard/dist/assets/{OperatorDashboard-wHyeLWzX.js → OperatorDashboard-CIt061hu.js} +2 -2
  62. package/dashboard/dist/assets/{OperatorDashboard-wHyeLWzX.js.map → OperatorDashboard-CIt061hu.js.map} +1 -1
  63. package/dashboard/dist/assets/{PersonaDetailPage-BXlTqLDK.js → PersonaDetailPage-r46uNF4E.js} +2 -2
  64. package/dashboard/dist/assets/{PersonaDetailPage-BXlTqLDK.js.map → PersonaDetailPage-r46uNF4E.js.map} +1 -1
  65. package/dashboard/dist/assets/{PersonasPage-DlmdJ3Dm.js → PersonasPage-CayYv9-j.js} +2 -2
  66. package/dashboard/dist/assets/{PersonasPage-DlmdJ3Dm.js.map → PersonasPage-CayYv9-j.js.map} +1 -1
  67. package/dashboard/dist/assets/{ProcessDetailPage-D88ocvmT.js → ProcessDetailPage-dn7lkM4c.js} +2 -2
  68. package/dashboard/dist/assets/{ProcessDetailPage-D88ocvmT.js.map → ProcessDetailPage-dn7lkM4c.js.map} +1 -1
  69. package/dashboard/dist/assets/{ProcessesListPage-DpXm-KtK.js → ProcessesListPage-DOp5J6Be.js} +2 -2
  70. package/dashboard/dist/assets/{ProcessesListPage-DpXm-KtK.js.map → ProcessesListPage-DOp5J6Be.js.map} +1 -1
  71. package/dashboard/dist/assets/{RoleDetailPage-DE2Rj2QE.js → RoleDetailPage-DOlNoiAK.js} +2 -2
  72. package/dashboard/dist/assets/{RoleDetailPage-DE2Rj2QE.js.map → RoleDetailPage-DOlNoiAK.js.map} +1 -1
  73. package/dashboard/dist/assets/{RolesPage-CZSvJlsz.js → RolesPage-DPppT6Zl.js} +2 -2
  74. package/dashboard/dist/assets/{RolesPage-CZSvJlsz.js.map → RolesPage-DPppT6Zl.js.map} +1 -1
  75. package/dashboard/dist/assets/{RunAsSelector-BawZcqAk.js → RunAsSelector-BgntKfSA.js} +2 -2
  76. package/dashboard/dist/assets/{RunAsSelector-BawZcqAk.js.map → RunAsSelector-BgntKfSA.js.map} +1 -1
  77. package/dashboard/dist/assets/{ScanCodesPage-DSlpA9kK.js → ScanCodesPage-DPm1lG79.js} +2 -2
  78. package/dashboard/dist/assets/{ScanCodesPage-DSlpA9kK.js.map → ScanCodesPage-DPm1lG79.js.map} +1 -1
  79. package/dashboard/dist/assets/{ScanSchemeDetailPage-BK4hisGD.js → ScanSchemeDetailPage-CuoG89q1.js} +2 -2
  80. package/dashboard/dist/assets/{ScanSchemeDetailPage-BK4hisGD.js.map → ScanSchemeDetailPage-CuoG89q1.js.map} +1 -1
  81. package/dashboard/dist/assets/{ScanStationPage-D3QjajFD.js → ScanStationPage-2SLXqqs0.js} +2 -2
  82. package/dashboard/dist/assets/{ScanStationPage-D3QjajFD.js.map → ScanStationPage-2SLXqqs0.js.map} +1 -1
  83. package/dashboard/dist/assets/{StickyPagination-BfZwU2NR.js → StickyPagination-Bc_Mzu_R.js} +2 -2
  84. package/dashboard/dist/assets/{StickyPagination-BfZwU2NR.js.map → StickyPagination-Bc_Mzu_R.js.map} +1 -1
  85. package/dashboard/dist/assets/{StreamMessageDetail-C7zIHX5D.js → StreamMessageDetail-S1cnLGkf.js} +2 -2
  86. package/dashboard/dist/assets/{StreamMessageDetail-C7zIHX5D.js.map → StreamMessageDetail-S1cnLGkf.js.map} +1 -1
  87. package/dashboard/dist/assets/{SwimlaneTimeline-DNSo8AT8.js → SwimlaneTimeline-BUu2sPmY.js} +2 -2
  88. package/dashboard/dist/assets/{SwimlaneTimeline-DNSo8AT8.js.map → SwimlaneTimeline-BUu2sPmY.js.map} +1 -1
  89. package/dashboard/dist/assets/{TaskDetailPage-BOJ8pwh3.js → TaskDetailPage-BMfNNtbN.js} +2 -2
  90. package/dashboard/dist/assets/{TaskDetailPage-BOJ8pwh3.js.map → TaskDetailPage-BMfNNtbN.js.map} +1 -1
  91. package/dashboard/dist/assets/{TasksListPage-C4CYqZf8.js → TasksListPage-BmNnopOU.js} +2 -2
  92. package/dashboard/dist/assets/{TasksListPage-C4CYqZf8.js.map → TasksListPage-BmNnopOU.js.map} +1 -1
  93. package/dashboard/dist/assets/{TimeAgo-JRPi9IEd.js → TimeAgo-Dip7gQQx.js} +2 -2
  94. package/dashboard/dist/assets/{TimeAgo-JRPi9IEd.js.map → TimeAgo-Dip7gQQx.js.map} +1 -1
  95. package/dashboard/dist/assets/{TimestampCell-BVYyU-nl.js → TimestampCell-DRAYnIrx.js} +2 -2
  96. package/dashboard/dist/assets/{TimestampCell-BVYyU-nl.js.map → TimestampCell-DRAYnIrx.js.map} +1 -1
  97. package/dashboard/dist/assets/{ToolTestPanel-IGrd44Au.js → ToolTestPanel-CQVYC3Ba.js} +2 -2
  98. package/dashboard/dist/assets/{ToolTestPanel-IGrd44Au.js.map → ToolTestPanel-CQVYC3Ba.js.map} +1 -1
  99. package/dashboard/dist/assets/{TopicDetailPage-DhianNey.js → TopicDetailPage-Bmtwuksg.js} +2 -2
  100. package/dashboard/dist/assets/{TopicDetailPage-DhianNey.js.map → TopicDetailPage-Bmtwuksg.js.map} +1 -1
  101. package/dashboard/dist/assets/{TopicsPage-Glhqz_Nv.js → TopicsPage-DIgF7-mJ.js} +2 -2
  102. package/dashboard/dist/assets/{TopicsPage-Glhqz_Nv.js.map → TopicsPage-DIgF7-mJ.js.map} +1 -1
  103. package/dashboard/dist/assets/{UserName-CD9OqhNI.js → UserName-DNKFz7X9.js} +2 -2
  104. package/dashboard/dist/assets/{UserName-CD9OqhNI.js.map → UserName-DNKFz7X9.js.map} +1 -1
  105. package/dashboard/dist/assets/{WorkflowExecutionPage-8Q2438Ry.js → WorkflowExecutionPage-DraIBNpl.js} +2 -2
  106. package/dashboard/dist/assets/{WorkflowExecutionPage-8Q2438Ry.js.map → WorkflowExecutionPage-DraIBNpl.js.map} +1 -1
  107. package/dashboard/dist/assets/{WorkflowsDashboard-CkAoYT86.js → WorkflowsDashboard-BH7kmFjM.js} +2 -2
  108. package/dashboard/dist/assets/{WorkflowsDashboard-CkAoYT86.js.map → WorkflowsDashboard-BH7kmFjM.js.map} +1 -1
  109. package/dashboard/dist/assets/{WorkflowsOverview-Zh_EidMp.js → WorkflowsOverview-C98pCjQX.js} +2 -2
  110. package/dashboard/dist/assets/{WorkflowsOverview-Zh_EidMp.js.map → WorkflowsOverview-C98pCjQX.js.map} +1 -1
  111. package/dashboard/dist/assets/{YamlWorkflowDetailPage-BKJbFT8C.js → YamlWorkflowDetailPage-BWQjXenZ.js} +2 -2
  112. package/dashboard/dist/assets/{YamlWorkflowDetailPage-BKJbFT8C.js.map → YamlWorkflowDetailPage-BWQjXenZ.js.map} +1 -1
  113. package/dashboard/dist/assets/{YamlWorkflowsPage-DK1z6iFt.js → YamlWorkflowsPage-BGTI_sdP.js} +2 -2
  114. package/dashboard/dist/assets/{YamlWorkflowsPage-DK1z6iFt.js.map → YamlWorkflowsPage-BGTI_sdP.js.map} +1 -1
  115. package/dashboard/dist/assets/{agents-BEASyYpg.js → agents-DfMrlw54.js} +2 -2
  116. package/dashboard/dist/assets/{agents-BEASyYpg.js.map → agents-DfMrlw54.js.map} +1 -1
  117. package/dashboard/dist/assets/{bots-CaXqSHat.js → bots-B9zS0z7D.js} +2 -2
  118. package/dashboard/dist/assets/{bots-CaXqSHat.js.map → bots-B9zS0z7D.js.map} +1 -1
  119. package/dashboard/dist/assets/{capabilities-Cijq-qev.js → capabilities-DkLM1xgH.js} +2 -2
  120. package/dashboard/dist/assets/{capabilities-Cijq-qev.js.map → capabilities-DkLM1xgH.js.map} +1 -1
  121. package/dashboard/dist/assets/{controlplane-HGuRC7AW.js → controlplane-SJK1yvbm.js} +2 -2
  122. package/dashboard/dist/assets/{controlplane-HGuRC7AW.js.map → controlplane-SJK1yvbm.js.map} +1 -1
  123. package/dashboard/dist/assets/{escalation-columns-BLVz8XCP.js → escalation-columns-BvAylNM1.js} +2 -2
  124. package/dashboard/dist/assets/{escalation-columns-BLVz8XCP.js.map → escalation-columns-BvAylNM1.js.map} +1 -1
  125. package/dashboard/dist/assets/{index-CEIp6WWg.js → index-CLxuBb17.js} +2 -2
  126. package/dashboard/dist/assets/{index-CEIp6WWg.js.map → index-CLxuBb17.js.map} +1 -1
  127. package/dashboard/dist/assets/{index-ClY0ihQ5.js → index-CXe2d5kg.js} +2 -2
  128. package/dashboard/dist/assets/{index-ClY0ihQ5.js.map → index-CXe2d5kg.js.map} +1 -1
  129. package/dashboard/dist/assets/{index-IkgBE7e_.js → index-ClVNU3G3.js} +2 -2
  130. package/dashboard/dist/assets/{index-IkgBE7e_.js.map → index-ClVNU3G3.js.map} +1 -1
  131. package/dashboard/dist/assets/{index-D2OU2MJb.js → index-Cw-V0VhS.js} +2 -2
  132. package/dashboard/dist/assets/{index-D2OU2MJb.js.map → index-Cw-V0VhS.js.map} +1 -1
  133. package/dashboard/dist/assets/{index-Xi3LO4Ye.js → index-D2IRxjSf.js} +2 -2
  134. package/dashboard/dist/assets/{index-Xi3LO4Ye.js.map → index-D2IRxjSf.js.map} +1 -1
  135. package/dashboard/dist/assets/{index-t1JXcmBG.js → index-DKXOIcO3.js} +2 -2
  136. package/dashboard/dist/assets/{index-t1JXcmBG.js.map → index-DKXOIcO3.js.map} +1 -1
  137. package/dashboard/dist/assets/{index-YMd3ZiPd.js → index-DSfY8oDp.js} +2 -2
  138. package/dashboard/dist/assets/{index-YMd3ZiPd.js.map → index-DSfY8oDp.js.map} +1 -1
  139. package/dashboard/dist/assets/index-DTZxHZJO.js +3 -0
  140. package/dashboard/dist/assets/index-DTZxHZJO.js.map +1 -0
  141. package/dashboard/dist/assets/{index-tCDjx1kF.js → index-DamcWcqG.js} +2 -2
  142. package/dashboard/dist/assets/{index-tCDjx1kF.js.map → index-DamcWcqG.js.map} +1 -1
  143. package/dashboard/dist/assets/{index-Cg0vCZng.js → index-DazfFRUx.js} +2 -2
  144. package/dashboard/dist/assets/{index-Cg0vCZng.js.map → index-DazfFRUx.js.map} +1 -1
  145. package/dashboard/dist/assets/{index-BJDAXUzO.js → index-DvmyIGeZ.js} +2 -2
  146. package/dashboard/dist/assets/{index-BJDAXUzO.js.map → index-DvmyIGeZ.js.map} +1 -1
  147. package/dashboard/dist/assets/{index-CLQ0HBHR.js → index-PjiXOVdw.js} +2 -2
  148. package/dashboard/dist/assets/{index-CLQ0HBHR.js.map → index-PjiXOVdw.js.map} +1 -1
  149. package/dashboard/dist/assets/{index-CgXVDPW-.js → index-zrTQcPjB.js} +3 -3
  150. package/dashboard/dist/assets/{index-CgXVDPW-.js.map → index-zrTQcPjB.js.map} +1 -1
  151. package/dashboard/dist/assets/{knowledge-DpaUJtVW.js → knowledge-BNp6MH-4.js} +2 -2
  152. package/dashboard/dist/assets/{knowledge-DpaUJtVW.js.map → knowledge-BNp6MH-4.js.map} +1 -1
  153. package/dashboard/dist/assets/{mcp-BkkLq6OE.js → mcp-Bb1k5rv-.js} +2 -2
  154. package/dashboard/dist/assets/{mcp-BkkLq6OE.js.map → mcp-Bb1k5rv-.js.map} +1 -1
  155. package/dashboard/dist/assets/{mcp-query-DeXu3La5.js → mcp-query-QVakMQnS.js} +2 -2
  156. package/dashboard/dist/assets/{mcp-query-DeXu3La5.js.map → mcp-query-QVakMQnS.js.map} +1 -1
  157. package/dashboard/dist/assets/{personas-BRbKVVko.js → personas-DV2JUjVj.js} +2 -2
  158. package/dashboard/dist/assets/{personas-BRbKVVko.js.map → personas-DV2JUjVj.js.map} +1 -1
  159. package/dashboard/dist/assets/{pipelines-B7xo92sK.js → pipelines-BkVB7Q0p.js} +2 -2
  160. package/dashboard/dist/assets/{pipelines-B7xo92sK.js.map → pipelines-BkVB7Q0p.js.map} +1 -1
  161. package/dashboard/dist/assets/{tasks-BGyqM1Ho.js → tasks-DvYWcASM.js} +2 -2
  162. package/dashboard/dist/assets/{tasks-BGyqM1Ho.js.map → tasks-DvYWcASM.js.map} +1 -1
  163. package/dashboard/dist/assets/{topics-I81rKc75.js → topics-B9zXFuVG.js} +2 -2
  164. package/dashboard/dist/assets/{topics-I81rKc75.js.map → topics-B9zXFuVG.js.map} +1 -1
  165. package/dashboard/dist/assets/{useEventHooks-CjV3uNxt.js → useEventHooks-JDpifqGZ.js} +2 -2
  166. package/dashboard/dist/assets/{useEventHooks-CjV3uNxt.js.map → useEventHooks-JDpifqGZ.js.map} +1 -1
  167. package/dashboard/dist/assets/{useNamespace-B-HMdRka.js → useNamespace-Bqr-LdWx.js} +2 -2
  168. package/dashboard/dist/assets/{useNamespace-B-HMdRka.js.map → useNamespace-Bqr-LdWx.js.map} +1 -1
  169. package/dashboard/dist/assets/{useYamlActivityEvents-CNsAlsgz.js → useYamlActivityEvents-n3naCEbw.js} +2 -2
  170. package/dashboard/dist/assets/{useYamlActivityEvents-CNsAlsgz.js.map → useYamlActivityEvents-n3naCEbw.js.map} +1 -1
  171. package/dashboard/dist/assets/{users-DiTqBepm.js → users-BNXLRVTS.js} +2 -2
  172. package/dashboard/dist/assets/{users-DiTqBepm.js.map → users-BNXLRVTS.js.map} +1 -1
  173. package/dashboard/dist/assets/{workflows-TA0p_3B8.js → workflows-D8uMBPvQ.js} +2 -2
  174. package/dashboard/dist/assets/{workflows-TA0p_3B8.js.map → workflows-D8uMBPvQ.js.map} +1 -1
  175. package/dashboard/dist/assets/{yaml-workflows-DN9-DBnQ.js → yaml-workflows-DVDOQM3Y.js} +2 -2
  176. package/dashboard/dist/assets/{yaml-workflows-DN9-DBnQ.js.map → yaml-workflows-DVDOQM3Y.js.map} +1 -1
  177. package/dashboard/dist/index.html +1 -1
  178. package/docs/hitl/lookups.md +13 -0
  179. package/docs/hitl/x-lt-validation.md +2 -1
  180. package/docs/hitl/x-lt-widget.md +8 -1
  181. package/docs/hitl-guide.md +2 -1
  182. package/package.json +1 -1
  183. package/dashboard/dist/assets/index-CK_ohh6Q.js +0 -3
  184. package/dashboard/dist/assets/index-CK_ohh6Q.js.map +0 -1
@@ -1,2 +1,2 @@
1
- import{a as m,j as e}from"./vendor-query-RUZdMvN6.js";import{h as j}from"./bots-CaXqSHat.js";import{e as d,X as N,aD as u,s as y,a8 as p}from"./vendor-icons-h-jlRSb9.js";function v({selected:s,onChange:r,placeholder:h}){const{data:l}=j({limit:100}),c=((l==null?void 0:l.bots)??[]).filter(t=>t.status==="active"),[i,a]=m.useState(!1),o=m.useRef(null);m.useEffect(()=>{const t=n=>{o.current&&!o.current.contains(n.target)&&a(!1)};return document.addEventListener("mousedown",t),()=>document.removeEventListener("mousedown",t)},[]);const x=c.find(t=>t.external_id===s),f=h??"Invoking user (default)";return e.jsxs("div",{ref:o,className:"relative",children:[e.jsxs("button",{type:"button",onClick:()=>a(!i),className:"field flex items-center gap-1.5 text-left cursor-pointer hover:border-accent",children:[s&&x?e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 rounded-lg bg-accent/[0.08] text-text-secondary text-2xs",children:[e.jsx(d,{className:"w-2.5 h-2.5 shrink-0 text-accent/75"}),x.display_name||x.external_id,e.jsx("span",{role:"button",onClick:t=>{t.stopPropagation(),r("")},className:"ml-0.5 hover:text-status-error transition-colors",children:e.jsx(N,{className:"w-2.5 h-2.5"})})]}):e.jsxs("span",{className:"inline-flex items-center gap-1 text-xs text-text-tertiary",children:[e.jsx(u,{className:"w-3 h-3 shrink-0"}),f]}),e.jsx(y,{className:`w-3.5 h-3.5 ml-auto shrink-0 text-text-tertiary transition-transform ${i?"rotate-180":""}`})]}),i&&e.jsxs("div",{className:"absolute z-[100] mt-1 w-full bg-surface-raised border border-surface-border rounded-md shadow-lg max-h-48 overflow-y-auto",children:[e.jsxs("button",{type:"button",onClick:()=>{r(""),a(!1)},className:`flex items-center gap-2 w-full px-3 py-1.5 text-left text-xs transition-colors ${s?"text-text-primary hover:bg-surface-sunken":"bg-accent/[0.06] text-accent"}`,children:[e.jsx(u,{className:"w-3 h-3 shrink-0 text-text-tertiary"}),e.jsx("span",{className:"flex-1",children:"Invoking user"}),!s&&e.jsx(p,{className:"w-3 h-3 shrink-0"})]}),c.length===0?e.jsx("p",{className:"px-3 py-2 text-xs text-text-tertiary",children:"No bot accounts"}):c.map(t=>{const n=s===t.external_id;return e.jsxs("button",{type:"button",onClick:()=>{r(t.external_id),a(!1)},className:`flex items-center gap-2 w-full px-3 py-1.5 text-left text-xs transition-colors ${n?"bg-accent/[0.06] text-accent":"text-text-primary hover:bg-surface-sunken"}`,children:[e.jsx(d,{className:"w-3 h-3 shrink-0 text-accent/60"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("span",{children:t.display_name||t.external_id}),t.display_name&&t.display_name!==t.external_id&&e.jsx("span",{className:"ml-1 text-text-tertiary font-mono",children:t.external_id})]}),n&&e.jsx(p,{className:"w-3 h-3 shrink-0"})]},t.id)})]})]})}export{v as B};
2
- //# sourceMappingURL=BotPicker-CBf6bHLV.js.map
1
+ import{a as m,j as e}from"./vendor-query-RUZdMvN6.js";import{h as j}from"./bots-B9zS0z7D.js";import{e as d,X as N,aD as u,s as y,a8 as p}from"./vendor-icons-h-jlRSb9.js";function v({selected:s,onChange:r,placeholder:h}){const{data:l}=j({limit:100}),c=((l==null?void 0:l.bots)??[]).filter(t=>t.status==="active"),[i,a]=m.useState(!1),o=m.useRef(null);m.useEffect(()=>{const t=n=>{o.current&&!o.current.contains(n.target)&&a(!1)};return document.addEventListener("mousedown",t),()=>document.removeEventListener("mousedown",t)},[]);const x=c.find(t=>t.external_id===s),f=h??"Invoking user (default)";return e.jsxs("div",{ref:o,className:"relative",children:[e.jsxs("button",{type:"button",onClick:()=>a(!i),className:"field flex items-center gap-1.5 text-left cursor-pointer hover:border-accent",children:[s&&x?e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 rounded-lg bg-accent/[0.08] text-text-secondary text-2xs",children:[e.jsx(d,{className:"w-2.5 h-2.5 shrink-0 text-accent/75"}),x.display_name||x.external_id,e.jsx("span",{role:"button",onClick:t=>{t.stopPropagation(),r("")},className:"ml-0.5 hover:text-status-error transition-colors",children:e.jsx(N,{className:"w-2.5 h-2.5"})})]}):e.jsxs("span",{className:"inline-flex items-center gap-1 text-xs text-text-tertiary",children:[e.jsx(u,{className:"w-3 h-3 shrink-0"}),f]}),e.jsx(y,{className:`w-3.5 h-3.5 ml-auto shrink-0 text-text-tertiary transition-transform ${i?"rotate-180":""}`})]}),i&&e.jsxs("div",{className:"absolute z-[100] mt-1 w-full bg-surface-raised border border-surface-border rounded-md shadow-lg max-h-48 overflow-y-auto",children:[e.jsxs("button",{type:"button",onClick:()=>{r(""),a(!1)},className:`flex items-center gap-2 w-full px-3 py-1.5 text-left text-xs transition-colors ${s?"text-text-primary hover:bg-surface-sunken":"bg-accent/[0.06] text-accent"}`,children:[e.jsx(u,{className:"w-3 h-3 shrink-0 text-text-tertiary"}),e.jsx("span",{className:"flex-1",children:"Invoking user"}),!s&&e.jsx(p,{className:"w-3 h-3 shrink-0"})]}),c.length===0?e.jsx("p",{className:"px-3 py-2 text-xs text-text-tertiary",children:"No bot accounts"}):c.map(t=>{const n=s===t.external_id;return e.jsxs("button",{type:"button",onClick:()=>{r(t.external_id),a(!1)},className:`flex items-center gap-2 w-full px-3 py-1.5 text-left text-xs transition-colors ${n?"bg-accent/[0.06] text-accent":"text-text-primary hover:bg-surface-sunken"}`,children:[e.jsx(d,{className:"w-3 h-3 shrink-0 text-accent/60"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("span",{children:t.display_name||t.external_id}),t.display_name&&t.display_name!==t.external_id&&e.jsx("span",{className:"ml-1 text-text-tertiary font-mono",children:t.external_id})]}),n&&e.jsx(p,{className:"w-3 h-3 shrink-0"})]},t.id)})]})]})}export{v as B};
2
+ //# sourceMappingURL=BotPicker-GU44inXA.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BotPicker-CBf6bHLV.js","sources":["../../src/components/common/form/BotPicker.tsx"],"sourcesContent":["import { useState, useRef, useEffect } from 'react';\nimport { Bot, X, ChevronDown, Check, UserCircle } from 'lucide-react';\nimport { useBots } from '../../../api/bots';\n\ninterface BotPickerProps {\n selected: string;\n onChange: (botExternalId: string) => void;\n placeholder?: string;\n}\n\nexport function BotPicker({ selected, onChange, placeholder }: BotPickerProps) {\n const { data } = useBots({ limit: 100 });\n const bots = (data?.bots ?? []).filter((b) => b.status === 'active');\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, []);\n\n const selectedBot = bots.find((b) => b.external_id === selected);\n const placeholderText = placeholder ?? 'Invoking user (default)';\n\n return (\n <div ref={ref} className=\"relative\">\n <button\n type=\"button\"\n onClick={() => setOpen(!open)}\n className=\"field flex items-center gap-1.5 text-left cursor-pointer hover:border-accent\"\n >\n {selected && selectedBot ? (\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 rounded-lg bg-accent/[0.08] text-text-secondary text-2xs\">\n <Bot className=\"w-2.5 h-2.5 shrink-0 text-accent/75\" />\n {selectedBot.display_name || selectedBot.external_id}\n <span\n role=\"button\"\n onClick={(e) => { e.stopPropagation(); onChange(''); }}\n className=\"ml-0.5 hover:text-status-error transition-colors\"\n >\n <X className=\"w-2.5 h-2.5\" />\n </span>\n </span>\n ) : (\n <span className=\"inline-flex items-center gap-1 text-xs text-text-tertiary\">\n <UserCircle className=\"w-3 h-3 shrink-0\" />\n {placeholderText}\n </span>\n )}\n <ChevronDown className={`w-3.5 h-3.5 ml-auto shrink-0 text-text-tertiary transition-transform ${open ? 'rotate-180' : ''}`} />\n </button>\n\n {open && (\n <div className=\"absolute z-[100] mt-1 w-full bg-surface-raised border border-surface-border rounded-md shadow-lg max-h-48 overflow-y-auto\">\n {/* Default: invoking user */}\n <button\n type=\"button\"\n onClick={() => { onChange(''); setOpen(false); }}\n className={`flex items-center gap-2 w-full px-3 py-1.5 text-left text-xs transition-colors ${\n !selected ? 'bg-accent/[0.06] text-accent' : 'text-text-primary hover:bg-surface-sunken'\n }`}\n >\n <UserCircle className=\"w-3 h-3 shrink-0 text-text-tertiary\" />\n <span className=\"flex-1\">Invoking user</span>\n {!selected && <Check className=\"w-3 h-3 shrink-0\" />}\n </button>\n\n {bots.length === 0 ? (\n <p className=\"px-3 py-2 text-xs text-text-tertiary\">No bot accounts</p>\n ) : (\n bots.map((bot) => {\n const isSelected = selected === bot.external_id;\n return (\n <button\n key={bot.id}\n type=\"button\"\n onClick={() => { onChange(bot.external_id); setOpen(false); }}\n className={`flex items-center gap-2 w-full px-3 py-1.5 text-left text-xs transition-colors ${\n isSelected\n ? 'bg-accent/[0.06] text-accent'\n : 'text-text-primary hover:bg-surface-sunken'\n }`}\n >\n <Bot className=\"w-3 h-3 shrink-0 text-accent/60\" />\n <div className=\"flex-1 min-w-0\">\n <span>{bot.display_name || bot.external_id}</span>\n {bot.display_name && bot.display_name !== bot.external_id && (\n <span className=\"ml-1 text-text-tertiary font-mono\">{bot.external_id}</span>\n )}\n </div>\n {isSelected && <Check className=\"w-3 h-3 shrink-0\" />}\n </button>\n );\n })\n )}\n </div>\n )}\n </div>\n );\n}\n"],"names":["BotPicker","selected","onChange","placeholder","data","useBots","bots","b","open","setOpen","useState","ref","useRef","useEffect","handler","e","selectedBot","placeholderText","jsxs","jsx","Bot","X","UserCircle","ChevronDown","Check","bot","isSelected"],"mappings":"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"}
1
+ {"version":3,"file":"BotPicker-GU44inXA.js","sources":["../../src/components/common/form/BotPicker.tsx"],"sourcesContent":["import { useState, useRef, useEffect } from 'react';\nimport { Bot, X, ChevronDown, Check, UserCircle } from 'lucide-react';\nimport { useBots } from '../../../api/bots';\n\ninterface BotPickerProps {\n selected: string;\n onChange: (botExternalId: string) => void;\n placeholder?: string;\n}\n\nexport function BotPicker({ selected, onChange, placeholder }: BotPickerProps) {\n const { data } = useBots({ limit: 100 });\n const bots = (data?.bots ?? []).filter((b) => b.status === 'active');\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, []);\n\n const selectedBot = bots.find((b) => b.external_id === selected);\n const placeholderText = placeholder ?? 'Invoking user (default)';\n\n return (\n <div ref={ref} className=\"relative\">\n <button\n type=\"button\"\n onClick={() => setOpen(!open)}\n className=\"field flex items-center gap-1.5 text-left cursor-pointer hover:border-accent\"\n >\n {selected && selectedBot ? (\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 rounded-lg bg-accent/[0.08] text-text-secondary text-2xs\">\n <Bot className=\"w-2.5 h-2.5 shrink-0 text-accent/75\" />\n {selectedBot.display_name || selectedBot.external_id}\n <span\n role=\"button\"\n onClick={(e) => { e.stopPropagation(); onChange(''); }}\n className=\"ml-0.5 hover:text-status-error transition-colors\"\n >\n <X className=\"w-2.5 h-2.5\" />\n </span>\n </span>\n ) : (\n <span className=\"inline-flex items-center gap-1 text-xs text-text-tertiary\">\n <UserCircle className=\"w-3 h-3 shrink-0\" />\n {placeholderText}\n </span>\n )}\n <ChevronDown className={`w-3.5 h-3.5 ml-auto shrink-0 text-text-tertiary transition-transform ${open ? 'rotate-180' : ''}`} />\n </button>\n\n {open && (\n <div className=\"absolute z-[100] mt-1 w-full bg-surface-raised border border-surface-border rounded-md shadow-lg max-h-48 overflow-y-auto\">\n {/* Default: invoking user */}\n <button\n type=\"button\"\n onClick={() => { onChange(''); setOpen(false); }}\n className={`flex items-center gap-2 w-full px-3 py-1.5 text-left text-xs transition-colors ${\n !selected ? 'bg-accent/[0.06] text-accent' : 'text-text-primary hover:bg-surface-sunken'\n }`}\n >\n <UserCircle className=\"w-3 h-3 shrink-0 text-text-tertiary\" />\n <span className=\"flex-1\">Invoking user</span>\n {!selected && <Check className=\"w-3 h-3 shrink-0\" />}\n </button>\n\n {bots.length === 0 ? (\n <p className=\"px-3 py-2 text-xs text-text-tertiary\">No bot accounts</p>\n ) : (\n bots.map((bot) => {\n const isSelected = selected === bot.external_id;\n return (\n <button\n key={bot.id}\n type=\"button\"\n onClick={() => { onChange(bot.external_id); setOpen(false); }}\n className={`flex items-center gap-2 w-full px-3 py-1.5 text-left text-xs transition-colors ${\n isSelected\n ? 'bg-accent/[0.06] text-accent'\n : 'text-text-primary hover:bg-surface-sunken'\n }`}\n >\n <Bot className=\"w-3 h-3 shrink-0 text-accent/60\" />\n <div className=\"flex-1 min-w-0\">\n <span>{bot.display_name || bot.external_id}</span>\n {bot.display_name && bot.display_name !== bot.external_id && (\n <span className=\"ml-1 text-text-tertiary font-mono\">{bot.external_id}</span>\n )}\n </div>\n {isSelected && <Check className=\"w-3 h-3 shrink-0\" />}\n </button>\n );\n })\n )}\n </div>\n )}\n </div>\n );\n}\n"],"names":["BotPicker","selected","onChange","placeholder","data","useBots","bots","b","open","setOpen","useState","ref","useRef","useEffect","handler","e","selectedBot","placeholderText","jsxs","jsx","Bot","X","UserCircle","ChevronDown","Check","bot","isSelected"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{j as e,a as u}from"./vendor-query-RUZdMvN6.js";import{M as L}from"./Modal-BU7No9NH.js";import{a as U}from"./users-DiTqBepm.js";import{u as B,L as I}from"./index-CgXVDPW-.js";import{D as q,f as O}from"./constants-BHkpVaqx.js";import{u as R}from"./useDebouncedValue-C4P2jQuh.js";function P({open:a,onClose:i,onConfirm:l,selectedCount:s,isPending:r,error:c,actionLabel:d}){const x=!!s&&s>1,o=d||"Cancel",m=x?`${o} ${s} Items`:o==="Cancel"?"Cancel Item":o,n=x?`Are you sure you want to ${o}? This removes ${s} items from the work queue.`:`Are you sure you want to ${o}? This removes the item from the work queue.`;return e.jsx(L,{open:a,onClose:i,title:m,children:e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-sm text-text-secondary",children:n}),e.jsx("p",{className:"text-xs text-text-tertiary",children:"This action cannot be undone."}),c&&e.jsx("p",{className:"text-xs text-status-error",children:c.message}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{onClick:i,disabled:r,className:"btn-secondary text-xs",children:"Keep"}),e.jsx("button",{onClick:l,disabled:r,className:"bg-status-error text-text-inverse px-3 py-1.5 rounded-md text-xs hover:opacity-90 transition-opacity disabled:opacity-50",children:r?"Working...":`Yes, ${o}`})]})]})})}const W="x-lt-labels",z=["claim","cancel","submit","escalate","release"];function ee(a){const i=a==null?void 0:a[W];if(!i||typeof i!="object"||Array.isArray(i))return{};const l=i,s={};l.cancel===!1&&(s.cancel=!1);for(const r of z){const c=l[r];typeof c=="string"&&c.trim().length>0&&(s[r]=c.trim())}return s}function G(){const{data:a}=B();return u.useMemo(()=>{var l;return(((l=a==null?void 0:a.escalation)==null?void 0:l.claimDurations)??q).map(s=>({value:String(s),label:O(s)}))},[a])}const K=[{value:1,label:"minutes"},{value:60,label:"hours"}];function Q({onChange:a,compact:i,autoFocus:l,"data-testid":s="custom-duration-input"}){const[r,c]=u.useState(""),[d,x]=u.useState(1);u.useEffect(()=>{const n=parseInt(r);a(n>0?n*d:0)},[r,d,a]);const o=i?"text-xs":"text-sm",m=i?"w-16":"w-20";return e.jsxs("div",{className:"flex items-center gap-2","data-testid":s,children:[e.jsx("input",{type:"number",min:1,max:d===60?24:1440,value:r,onChange:n=>c(n.target.value),placeholder:d===60?"hrs":"min",className:`input ${o} ${m} text-center`,autoFocus:l,"data-testid":`${s}-quantity`}),e.jsx("select",{value:d,onChange:n=>x(parseInt(n.target.value)),className:`select ${o} py-1`,"data-testid":`${s}-unit`,children:K.map(n=>e.jsx("option",{value:n.value,children:n.label},n.value))})]})}function te({open:a,onClose:i,selectedCount:l,selectedRoles:s,onSubmit:r,isPending:c,claimedCount:d=0,result:x=null}){const{isSuperAdmin:o}=I(),m=G(),[n,f]=u.useState("user"),[p,g]=u.useState(null),[b,v]=u.useState(""),[h,N]=u.useState("30"),[$,j]=u.useState(0),[k,S]=u.useState(!1),T=u.useCallback(t=>j(t),[]),_=!o&&s.length===1?s[0]:void 0,D=R(b,250),{data:y,isLoading:C}=U({role:_,status:"active",search:D.trim()||void 0,limit:200}),A=(y==null?void 0:y.users)??[],w=()=>{f("user"),g(null),v(""),N("30"),j(0),S(!1),i()},E=t=>{g(t),f("duration")},M=()=>{f("user")},F=()=>{if(!p)return;const t=h==="custom"?$:parseInt(h);!t||t<=0||r(p.id,t,k)};return e.jsx(L,{open:a,onClose:w,title:"Assign Escalations",children:e.jsxs("div",{className:"space-y-4",children:[n==="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:b,onChange:t=>v(t.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:[C&&e.jsx("p",{className:"text-xs text-text-tertiary p-3",children:"Loading users..."}),!C&&A.length===0&&e.jsx("p",{className:"text-xs text-text-tertiary p-3",children:"No users found"}),A.map(t=>e.jsxs("button",{onClick:()=>E(t),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:t.display_name||t.external_id}),t.email&&e.jsx("p",{className:"text-2xs text-text-tertiary",children:t.email})]},t.id))]}),e.jsx("div",{className:"flex justify-end pt-2",children:e.jsx("button",{onClick:w,className:"btn-secondary text-xs",children:"Cancel"})})]}),n==="duration"&&p&&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:p.display_name||p.external_id})," ","for:"]}),e.jsxs("select",{value:h,onChange:t=>{N(t.target.value),j(0)},className:"select w-full text-sm",children:[m.map(t=>e.jsx("option",{value:t.value,children:t.label},t.value)),e.jsx("option",{value:"custom",children:"Other..."})]}),h==="custom"&&e.jsx(Q,{onChange:T,autoFocus:!0}),d>0&&e.jsxs("label",{className:"flex items-start gap-2 text-xs text-text-secondary",children:[e.jsx("input",{type:"checkbox",checked:k,onChange:t=>S(t.target.checked),className:"mt-0.5"}),e.jsxs("span",{children:["Also reassign ",e.jsx("span",{className:"font-medium text-text-primary",children:d})," ","item(s) with a live claim — the current holder loses the item. Unchecked, those are skipped."]})]}),x&&x.skipped>0&&e.jsxs("p",{className:"text-xs text-status-warning","data-testid":"assign-skip-note",children:["Assigned ",x.assigned," · skipped ",x.skipped," with live claims."]}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{onClick:M,className:"btn-secondary text-xs",children:"Back"}),e.jsx("button",{onClick:F,disabled:c,className:"btn-primary text-xs",children:c?"Assigning...":"Assign"})]})]})]})})}export{te as B,Q as C,P as a,ee as r,G as u};
2
- //# sourceMappingURL=BulkAssignModal-CkxoPByA.js.map
1
+ import{j as e,a as u}from"./vendor-query-RUZdMvN6.js";import{M as L}from"./Modal-BU7No9NH.js";import{a as U}from"./users-BNXLRVTS.js";import{u as B,L as I}from"./index-zrTQcPjB.js";import{D as q,f as O}from"./constants-BHkpVaqx.js";import{u as R}from"./useDebouncedValue-C4P2jQuh.js";function P({open:a,onClose:i,onConfirm:l,selectedCount:s,isPending:r,error:c,actionLabel:d}){const x=!!s&&s>1,o=d||"Cancel",m=x?`${o} ${s} Items`:o==="Cancel"?"Cancel Item":o,n=x?`Are you sure you want to ${o}? This removes ${s} items from the work queue.`:`Are you sure you want to ${o}? This removes the item from the work queue.`;return e.jsx(L,{open:a,onClose:i,title:m,children:e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-sm text-text-secondary",children:n}),e.jsx("p",{className:"text-xs text-text-tertiary",children:"This action cannot be undone."}),c&&e.jsx("p",{className:"text-xs text-status-error",children:c.message}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{onClick:i,disabled:r,className:"btn-secondary text-xs",children:"Keep"}),e.jsx("button",{onClick:l,disabled:r,className:"bg-status-error text-text-inverse px-3 py-1.5 rounded-md text-xs hover:opacity-90 transition-opacity disabled:opacity-50",children:r?"Working...":`Yes, ${o}`})]})]})})}const W="x-lt-labels",z=["claim","cancel","submit","escalate","release"];function ee(a){const i=a==null?void 0:a[W];if(!i||typeof i!="object"||Array.isArray(i))return{};const l=i,s={};l.cancel===!1&&(s.cancel=!1);for(const r of z){const c=l[r];typeof c=="string"&&c.trim().length>0&&(s[r]=c.trim())}return s}function G(){const{data:a}=B();return u.useMemo(()=>{var l;return(((l=a==null?void 0:a.escalation)==null?void 0:l.claimDurations)??q).map(s=>({value:String(s),label:O(s)}))},[a])}const K=[{value:1,label:"minutes"},{value:60,label:"hours"}];function Q({onChange:a,compact:i,autoFocus:l,"data-testid":s="custom-duration-input"}){const[r,c]=u.useState(""),[d,x]=u.useState(1);u.useEffect(()=>{const n=parseInt(r);a(n>0?n*d:0)},[r,d,a]);const o=i?"text-xs":"text-sm",m=i?"w-16":"w-20";return e.jsxs("div",{className:"flex items-center gap-2","data-testid":s,children:[e.jsx("input",{type:"number",min:1,max:d===60?24:1440,value:r,onChange:n=>c(n.target.value),placeholder:d===60?"hrs":"min",className:`input ${o} ${m} text-center`,autoFocus:l,"data-testid":`${s}-quantity`}),e.jsx("select",{value:d,onChange:n=>x(parseInt(n.target.value)),className:`select ${o} py-1`,"data-testid":`${s}-unit`,children:K.map(n=>e.jsx("option",{value:n.value,children:n.label},n.value))})]})}function te({open:a,onClose:i,selectedCount:l,selectedRoles:s,onSubmit:r,isPending:c,claimedCount:d=0,result:x=null}){const{isSuperAdmin:o}=I(),m=G(),[n,f]=u.useState("user"),[p,g]=u.useState(null),[b,v]=u.useState(""),[h,N]=u.useState("30"),[$,j]=u.useState(0),[k,S]=u.useState(!1),T=u.useCallback(t=>j(t),[]),_=!o&&s.length===1?s[0]:void 0,D=R(b,250),{data:y,isLoading:C}=U({role:_,status:"active",search:D.trim()||void 0,limit:200}),A=(y==null?void 0:y.users)??[],w=()=>{f("user"),g(null),v(""),N("30"),j(0),S(!1),i()},E=t=>{g(t),f("duration")},M=()=>{f("user")},F=()=>{if(!p)return;const t=h==="custom"?$:parseInt(h);!t||t<=0||r(p.id,t,k)};return e.jsx(L,{open:a,onClose:w,title:"Assign Escalations",children:e.jsxs("div",{className:"space-y-4",children:[n==="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:b,onChange:t=>v(t.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:[C&&e.jsx("p",{className:"text-xs text-text-tertiary p-3",children:"Loading users..."}),!C&&A.length===0&&e.jsx("p",{className:"text-xs text-text-tertiary p-3",children:"No users found"}),A.map(t=>e.jsxs("button",{onClick:()=>E(t),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:t.display_name||t.external_id}),t.email&&e.jsx("p",{className:"text-2xs text-text-tertiary",children:t.email})]},t.id))]}),e.jsx("div",{className:"flex justify-end pt-2",children:e.jsx("button",{onClick:w,className:"btn-secondary text-xs",children:"Cancel"})})]}),n==="duration"&&p&&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:p.display_name||p.external_id})," ","for:"]}),e.jsxs("select",{value:h,onChange:t=>{N(t.target.value),j(0)},className:"select w-full text-sm",children:[m.map(t=>e.jsx("option",{value:t.value,children:t.label},t.value)),e.jsx("option",{value:"custom",children:"Other..."})]}),h==="custom"&&e.jsx(Q,{onChange:T,autoFocus:!0}),d>0&&e.jsxs("label",{className:"flex items-start gap-2 text-xs text-text-secondary",children:[e.jsx("input",{type:"checkbox",checked:k,onChange:t=>S(t.target.checked),className:"mt-0.5"}),e.jsxs("span",{children:["Also reassign ",e.jsx("span",{className:"font-medium text-text-primary",children:d})," ","item(s) with a live claim — the current holder loses the item. Unchecked, those are skipped."]})]}),x&&x.skipped>0&&e.jsxs("p",{className:"text-xs text-status-warning","data-testid":"assign-skip-note",children:["Assigned ",x.assigned," · skipped ",x.skipped," with live claims."]}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{onClick:M,className:"btn-secondary text-xs",children:"Back"}),e.jsx("button",{onClick:F,disabled:c,className:"btn-primary text-xs",children:c?"Assigning...":"Assign"})]})]})]})})}export{te as B,Q as C,P as a,ee as r,G as u};
2
+ //# sourceMappingURL=BulkAssignModal-ChqzG6FY.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BulkAssignModal-CkxoPByA.js","sources":["../../src/components/common/modal/ConfirmCancelModal.tsx","../../../shared/form-validation/x-lt-labels.ts","../../src/hooks/useClaimDurations.ts","../../src/components/common/form/CustomDurationPicker.tsx","../../src/components/common/modal/BulkAssignModal.tsx"],"sourcesContent":["import { Modal } from './Modal';\n\ninterface ConfirmCancelModalProps {\n open: boolean;\n onClose: () => void;\n onConfirm: () => void;\n selectedCount?: number;\n isPending?: boolean;\n error?: Error | null;\n /** Replacement label from x-lt-labels.cancel — the challenge speaks it. */\n actionLabel?: string;\n}\n\nexport function ConfirmCancelModal({\n open,\n onClose,\n onConfirm,\n selectedCount,\n isPending,\n error,\n actionLabel,\n}: ConfirmCancelModalProps) {\n // One template for every vocabulary: the title carries the verb (the\n // pressed button's label), the body states the intent in general terms.\n const isBulk = !!selectedCount && selectedCount > 1;\n const label = actionLabel || 'Cancel';\n const title = isBulk ? `${label} ${selectedCount} Items` : label === 'Cancel' ? 'Cancel Item' : label;\n\n const body = isBulk\n ? `Are you sure you want to ${label}? This removes ${selectedCount} items from the work queue.`\n : `Are you sure you want to ${label}? This removes the item from the work queue.`;\n\n return (\n <Modal open={open} onClose={onClose} title={title}>\n <div className=\"space-y-4\">\n <p className=\"text-sm text-text-secondary\">{body}</p>\n <p className=\"text-xs text-text-tertiary\">This action cannot be undone.</p>\n {error && <p className=\"text-xs text-status-error\">{error.message}</p>}\n <div className=\"flex justify-end gap-3 pt-2\">\n <button onClick={onClose} disabled={isPending} className=\"btn-secondary text-xs\">\n Keep\n </button>\n <button\n onClick={onConfirm}\n disabled={isPending}\n className=\"bg-status-error text-text-inverse px-3 py-1.5 rounded-md text-xs hover:opacity-90 transition-opacity disabled:opacity-50\"\n >\n {isPending ? 'Working...' : `Yes, ${label}`}\n </button>\n </div>\n </div>\n </Modal>\n );\n}\n","/**\n * x-lt-labels — configurable copy for the standard escalation footer. A\n * form_schema may declare, at its schema root, an object that renames the\n * footer's action controls. Each key is a standard target; its value is the\n * label to render in place of the default.\n *\n * x-lt-labels object — { claim, cancel, submit, escalate, release }\n *\n * ```jsonc\n * { \"x-lt-labels\": { \"claim\": \"Claim and Submit\", \"submit\": \"Approve\" } }\n * ```\n *\n * `cancel` additionally accepts `false` to remove the control entirely —\n * for roles where cancelling is not part of the process (\"Send to Service\"\n * flows escalate instead). The other targets are rename-only: hiding\n * claim/submit/release would strand the footer.\n *\n * Only the five known targets are read; unknown keys and non-string values\n * (except `cancel: false`) are ignored. Any target the schema omits keeps its\n * default label, so a schema overrides just the controls it cares about.\n */\n\nexport const X_LT_LABELS = 'x-lt-labels';\n\n/** The footer controls a schema may rename. */\nexport const FOOTER_LABEL_TARGETS = ['claim', 'cancel', 'submit', 'escalate', 'release'] as const;\n\nexport type FooterLabelTarget = (typeof FOOTER_LABEL_TARGETS)[number];\n\n/**\n * A partial map of target → override label. Absent targets keep their\n * default. `cancel: false` removes the cancel control from the footer.\n */\nexport type FooterLabels = Partial<Record<Exclude<FooterLabelTarget, 'cancel'>, string>> & {\n cancel?: string | false;\n};\n\n/**\n * The schema's footer label overrides, or an empty map when none are declared.\n * Reads only the known targets; a non-object `x-lt-labels`, unknown keys, and\n * blank or non-string values are dropped — except `cancel: false`, which is\n * preserved as the hide instruction.\n */\nexport function readFooterLabels(\n schema: Record<string, unknown> | null | undefined,\n): FooterLabels {\n const raw = schema?.[X_LT_LABELS];\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return {};\n const source = raw as Record<string, unknown>;\n const labels: FooterLabels = {};\n if (source.cancel === false) labels.cancel = false;\n for (const target of FOOTER_LABEL_TARGETS) {\n const value = source[target];\n if (typeof value === 'string' && value.trim().length > 0) {\n labels[target] = value.trim();\n }\n }\n return labels;\n}\n","import { useMemo } from 'react';\nimport { useSettings } from '../api/settings';\nimport { DEFAULT_CLAIM_DURATIONS, formatClaimDuration } from '../lib/constants';\n\nexport interface ClaimDurationOption {\n value: string;\n label: string;\n}\n\n/**\n * Returns claim duration presets from server settings (with fallback).\n * Options are formatted for use in selects and tab rows.\n */\nexport function useClaimDurations(): ClaimDurationOption[] {\n const { data: settings } = useSettings();\n\n return useMemo(() => {\n const minutes = settings?.escalation?.claimDurations ?? DEFAULT_CLAIM_DURATIONS;\n return minutes.map((m) => ({\n value: String(m),\n label: formatClaimDuration(m),\n }));\n }, [settings]);\n}\n","import { useState, useEffect } from 'react';\n\nconst UNITS = [\n { value: 1, label: 'minutes' },\n { value: 60, label: 'hours' },\n] as const;\n\ninterface CustomDurationPickerProps {\n /** Called with the computed duration in minutes whenever quantity or unit changes */\n onChange: (minutes: number) => void;\n /** Compact variant for inline use (e.g. action bars) */\n compact?: boolean;\n /** Auto-focus the quantity input */\n autoFocus?: boolean;\n 'data-testid'?: string;\n}\n\nexport function CustomDurationPicker({\n onChange,\n compact,\n autoFocus,\n 'data-testid': testId = 'custom-duration-input',\n}: CustomDurationPickerProps) {\n const [quantity, setQuantity] = useState('');\n const [multiplier, setMultiplier] = useState(1);\n\n useEffect(() => {\n const q = parseInt(quantity);\n onChange(q > 0 ? q * multiplier : 0);\n }, [quantity, multiplier, onChange]);\n\n const textSize = compact ? 'text-xs' : 'text-sm';\n const inputWidth = compact ? 'w-16' : 'w-20';\n\n return (\n <div className=\"flex items-center gap-2\" data-testid={testId}>\n <input\n type=\"number\"\n min={1}\n max={multiplier === 60 ? 24 : 1440}\n value={quantity}\n onChange={(e) => setQuantity(e.target.value)}\n placeholder={multiplier === 60 ? 'hrs' : 'min'}\n className={`input ${textSize} ${inputWidth} text-center`}\n autoFocus={autoFocus}\n data-testid={`${testId}-quantity`}\n />\n <select\n value={multiplier}\n onChange={(e) => setMultiplier(parseInt(e.target.value))}\n className={`select ${textSize} py-1`}\n data-testid={`${testId}-unit`}\n >\n {UNITS.map((u) => (\n <option key={u.value} value={u.value}>{u.label}</option>\n ))}\n </select>\n </div>\n );\n}\n","import { useState, useCallback } from 'react';\nimport { Modal } from './Modal';\nimport { CustomDurationPicker } from '../form/CustomDurationPicker';\nimport { useUsers } from '../../../api/users';\nimport { useAuth } from '../../../hooks/useAuth';\nimport { useClaimDurations } from '../../../hooks/useClaimDurations';\nimport { useDebouncedValue } from '../../../hooks/useDebouncedValue';\nimport type { LTUserRecord } from '../../../api/types';\n\ninterface BulkAssignModalProps {\n open: boolean;\n onClose: () => void;\n selectedCount: number;\n /** Distinct roles of the selected escalations; scopes user list for admins */\n selectedRoles: string[];\n onSubmit: (targetUserId: string, durationMinutes: number, reassign: boolean) => void;\n isPending: boolean;\n /**\n * Selected rows currently under a LIVE claim. Plain assign skips them;\n * when > 0 the duration step offers the explicit takeover.\n */\n claimedCount?: number;\n /** Assignment outcome from the last submit; skipped > 0 keeps the modal open to say so. */\n result?: { assigned: number; skipped: number } | null;\n}\n\nexport function BulkAssignModal({\n open,\n onClose,\n selectedCount,\n selectedRoles,\n onSubmit,\n isPending,\n claimedCount = 0,\n result = null,\n}: BulkAssignModalProps) {\n const { isSuperAdmin } = useAuth();\n const claimDurations = useClaimDurations();\n const [step, setStep] = useState<'user' | 'duration'>('user');\n const [selectedUser, setSelectedUser] = useState<LTUserRecord | null>(null);\n const [search, setSearch] = useState('');\n const [duration, setDuration] = useState('30');\n const [customMinutes, setCustomMinutes] = useState(0);\n const [reassign, setReassign] = useState(false);\n const onCustomChange = useCallback((m: number) => setCustomMinutes(m), []);\n\n // Admins with a single role: scope to that role. Otherwise show all active users.\n const roleFilter =\n !isSuperAdmin && selectedRoles.length === 1 ? selectedRoles[0] : undefined;\n\n // Search is resolved server-side (ILIKE on name/email/external_id) so it matches\n // every user, not just a fetched slice — no client-side filtering over a cap.\n const debouncedSearch = useDebouncedValue(search, 250);\n const { data: usersData, isLoading: usersLoading } = useUsers({\n role: roleFilter,\n status: 'active',\n search: debouncedSearch.trim() || undefined,\n limit: 200,\n });\n\n const users = usersData?.users ?? [];\n\n const handleClose = () => {\n setStep('user');\n setSelectedUser(null);\n setSearch('');\n setDuration('30');\n setCustomMinutes(0);\n setReassign(false);\n onClose();\n };\n\n const handleSelectUser = (user: LTUserRecord) => {\n setSelectedUser(user);\n setStep('duration');\n };\n\n const handleBack = () => {\n setStep('user');\n };\n\n const handleSubmit = () => {\n if (!selectedUser) return;\n const minutes = duration === 'custom' ? customMinutes : parseInt(duration);\n if (!minutes || minutes <= 0) return;\n onSubmit(selectedUser.id, minutes, reassign);\n };\n\n return (\n <Modal open={open} onClose={handleClose} title=\"Assign Escalations\">\n <div className=\"space-y-4\">\n {step === 'user' && (\n <>\n <p className=\"text-sm text-text-secondary\">\n Select a user to assign{' '}\n <span className=\"font-medium text-text-primary\">\n {selectedCount}\n </span>{' '}\n escalation(s) to:\n </p>\n\n <input\n type=\"text\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"Search by name or email...\"\n className=\"input text-xs w-full\"\n autoFocus\n />\n\n <div className=\"max-h-60 overflow-y-auto border border-surface-border rounded-lg divide-y divide-surface-border\">\n {usersLoading && (\n <p className=\"text-xs text-text-tertiary p-3\">\n Loading users...\n </p>\n )}\n {!usersLoading && users.length === 0 && (\n <p className=\"text-xs text-text-tertiary p-3\">\n No users found\n </p>\n )}\n {users.map((user) => (\n <button\n key={user.id}\n onClick={() => handleSelectUser(user)}\n className=\"w-full text-left px-3 py-2 hover:bg-surface-hover transition-colors\"\n >\n <p className=\"text-xs font-medium text-text-primary\">\n {user.display_name || user.external_id}\n </p>\n {user.email && (\n <p className=\"text-2xs text-text-tertiary\">\n {user.email}\n </p>\n )}\n </button>\n ))}\n </div>\n\n <div className=\"flex justify-end pt-2\">\n <button onClick={handleClose} className=\"btn-secondary text-xs\">\n Cancel\n </button>\n </div>\n </>\n )}\n\n {step === 'duration' && selectedUser && (\n <>\n <p className=\"text-sm text-text-secondary\">\n Assign to{' '}\n <span className=\"font-medium text-text-primary\">\n {selectedUser.display_name || selectedUser.external_id}\n </span>{' '}\n for:\n </p>\n\n <select\n value={duration}\n onChange={(e) => { setDuration(e.target.value); setCustomMinutes(0); }}\n className=\"select w-full text-sm\"\n >\n {claimDurations.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n <option value=\"custom\">Other...</option>\n </select>\n {duration === 'custom' && (\n <CustomDurationPicker onChange={onCustomChange} autoFocus />\n )}\n\n {claimedCount > 0 && (\n <label className=\"flex items-start gap-2 text-xs text-text-secondary\">\n <input\n type=\"checkbox\"\n checked={reassign}\n onChange={(e) => setReassign(e.target.checked)}\n className=\"mt-0.5\"\n />\n <span>\n Also reassign <span className=\"font-medium text-text-primary\">{claimedCount}</span>{' '}\n item(s) with a live claim — the current holder loses the item.\n Unchecked, those are skipped.\n </span>\n </label>\n )}\n\n {result && result.skipped > 0 && (\n <p className=\"text-xs text-status-warning\" data-testid=\"assign-skip-note\">\n Assigned {result.assigned} · skipped {result.skipped} with live claims.\n </p>\n )}\n\n <div className=\"flex justify-end gap-3 pt-2\">\n <button onClick={handleBack} className=\"btn-secondary text-xs\">\n Back\n </button>\n <button\n onClick={handleSubmit}\n disabled={isPending}\n className=\"btn-primary text-xs\"\n >\n {isPending ? 'Assigning...' : 'Assign'}\n </button>\n </div>\n </>\n )}\n </div>\n </Modal>\n );\n}\n"],"names":["ConfirmCancelModal","open","onClose","onConfirm","selectedCount","isPending","error","actionLabel","isBulk","label","title","body","jsx","Modal","jsxs","X_LT_LABELS","FOOTER_LABEL_TARGETS","readFooterLabels","schema","raw","source","labels","target","value","useClaimDurations","settings","useSettings","useMemo","_a","DEFAULT_CLAIM_DURATIONS","m","formatClaimDuration","UNITS","CustomDurationPicker","onChange","compact","autoFocus","testId","quantity","setQuantity","useState","multiplier","setMultiplier","useEffect","q","textSize","inputWidth","e","u","BulkAssignModal","selectedRoles","onSubmit","claimedCount","result","isSuperAdmin","useAuth","claimDurations","step","setStep","selectedUser","setSelectedUser","search","setSearch","duration","setDuration","customMinutes","setCustomMinutes","reassign","setReassign","onCustomChange","useCallback","roleFilter","debouncedSearch","useDebouncedValue","usersData","usersLoading","useUsers","users","handleClose","handleSelectUser","user","handleBack","handleSubmit","minutes","Fragment","opt"],"mappings":"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"}
1
+ {"version":3,"file":"BulkAssignModal-ChqzG6FY.js","sources":["../../src/components/common/modal/ConfirmCancelModal.tsx","../../../shared/form-validation/x-lt-labels.ts","../../src/hooks/useClaimDurations.ts","../../src/components/common/form/CustomDurationPicker.tsx","../../src/components/common/modal/BulkAssignModal.tsx"],"sourcesContent":["import { Modal } from './Modal';\n\ninterface ConfirmCancelModalProps {\n open: boolean;\n onClose: () => void;\n onConfirm: () => void;\n selectedCount?: number;\n isPending?: boolean;\n error?: Error | null;\n /** Replacement label from x-lt-labels.cancel — the challenge speaks it. */\n actionLabel?: string;\n}\n\nexport function ConfirmCancelModal({\n open,\n onClose,\n onConfirm,\n selectedCount,\n isPending,\n error,\n actionLabel,\n}: ConfirmCancelModalProps) {\n // One template for every vocabulary: the title carries the verb (the\n // pressed button's label), the body states the intent in general terms.\n const isBulk = !!selectedCount && selectedCount > 1;\n const label = actionLabel || 'Cancel';\n const title = isBulk ? `${label} ${selectedCount} Items` : label === 'Cancel' ? 'Cancel Item' : label;\n\n const body = isBulk\n ? `Are you sure you want to ${label}? This removes ${selectedCount} items from the work queue.`\n : `Are you sure you want to ${label}? This removes the item from the work queue.`;\n\n return (\n <Modal open={open} onClose={onClose} title={title}>\n <div className=\"space-y-4\">\n <p className=\"text-sm text-text-secondary\">{body}</p>\n <p className=\"text-xs text-text-tertiary\">This action cannot be undone.</p>\n {error && <p className=\"text-xs text-status-error\">{error.message}</p>}\n <div className=\"flex justify-end gap-3 pt-2\">\n <button onClick={onClose} disabled={isPending} className=\"btn-secondary text-xs\">\n Keep\n </button>\n <button\n onClick={onConfirm}\n disabled={isPending}\n className=\"bg-status-error text-text-inverse px-3 py-1.5 rounded-md text-xs hover:opacity-90 transition-opacity disabled:opacity-50\"\n >\n {isPending ? 'Working...' : `Yes, ${label}`}\n </button>\n </div>\n </div>\n </Modal>\n );\n}\n","/**\n * x-lt-labels — configurable copy for the standard escalation footer. A\n * form_schema may declare, at its schema root, an object that renames the\n * footer's action controls. Each key is a standard target; its value is the\n * label to render in place of the default.\n *\n * x-lt-labels object — { claim, cancel, submit, escalate, release }\n *\n * ```jsonc\n * { \"x-lt-labels\": { \"claim\": \"Claim and Submit\", \"submit\": \"Approve\" } }\n * ```\n *\n * `cancel` additionally accepts `false` to remove the control entirely —\n * for roles where cancelling is not part of the process (\"Send to Service\"\n * flows escalate instead). The other targets are rename-only: hiding\n * claim/submit/release would strand the footer.\n *\n * Only the five known targets are read; unknown keys and non-string values\n * (except `cancel: false`) are ignored. Any target the schema omits keeps its\n * default label, so a schema overrides just the controls it cares about.\n */\n\nexport const X_LT_LABELS = 'x-lt-labels';\n\n/** The footer controls a schema may rename. */\nexport const FOOTER_LABEL_TARGETS = ['claim', 'cancel', 'submit', 'escalate', 'release'] as const;\n\nexport type FooterLabelTarget = (typeof FOOTER_LABEL_TARGETS)[number];\n\n/**\n * A partial map of target → override label. Absent targets keep their\n * default. `cancel: false` removes the cancel control from the footer.\n */\nexport type FooterLabels = Partial<Record<Exclude<FooterLabelTarget, 'cancel'>, string>> & {\n cancel?: string | false;\n};\n\n/**\n * The schema's footer label overrides, or an empty map when none are declared.\n * Reads only the known targets; a non-object `x-lt-labels`, unknown keys, and\n * blank or non-string values are dropped — except `cancel: false`, which is\n * preserved as the hide instruction.\n */\nexport function readFooterLabels(\n schema: Record<string, unknown> | null | undefined,\n): FooterLabels {\n const raw = schema?.[X_LT_LABELS];\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return {};\n const source = raw as Record<string, unknown>;\n const labels: FooterLabels = {};\n if (source.cancel === false) labels.cancel = false;\n for (const target of FOOTER_LABEL_TARGETS) {\n const value = source[target];\n if (typeof value === 'string' && value.trim().length > 0) {\n labels[target] = value.trim();\n }\n }\n return labels;\n}\n","import { useMemo } from 'react';\nimport { useSettings } from '../api/settings';\nimport { DEFAULT_CLAIM_DURATIONS, formatClaimDuration } from '../lib/constants';\n\nexport interface ClaimDurationOption {\n value: string;\n label: string;\n}\n\n/**\n * Returns claim duration presets from server settings (with fallback).\n * Options are formatted for use in selects and tab rows.\n */\nexport function useClaimDurations(): ClaimDurationOption[] {\n const { data: settings } = useSettings();\n\n return useMemo(() => {\n const minutes = settings?.escalation?.claimDurations ?? DEFAULT_CLAIM_DURATIONS;\n return minutes.map((m) => ({\n value: String(m),\n label: formatClaimDuration(m),\n }));\n }, [settings]);\n}\n","import { useState, useEffect } from 'react';\n\nconst UNITS = [\n { value: 1, label: 'minutes' },\n { value: 60, label: 'hours' },\n] as const;\n\ninterface CustomDurationPickerProps {\n /** Called with the computed duration in minutes whenever quantity or unit changes */\n onChange: (minutes: number) => void;\n /** Compact variant for inline use (e.g. action bars) */\n compact?: boolean;\n /** Auto-focus the quantity input */\n autoFocus?: boolean;\n 'data-testid'?: string;\n}\n\nexport function CustomDurationPicker({\n onChange,\n compact,\n autoFocus,\n 'data-testid': testId = 'custom-duration-input',\n}: CustomDurationPickerProps) {\n const [quantity, setQuantity] = useState('');\n const [multiplier, setMultiplier] = useState(1);\n\n useEffect(() => {\n const q = parseInt(quantity);\n onChange(q > 0 ? q * multiplier : 0);\n }, [quantity, multiplier, onChange]);\n\n const textSize = compact ? 'text-xs' : 'text-sm';\n const inputWidth = compact ? 'w-16' : 'w-20';\n\n return (\n <div className=\"flex items-center gap-2\" data-testid={testId}>\n <input\n type=\"number\"\n min={1}\n max={multiplier === 60 ? 24 : 1440}\n value={quantity}\n onChange={(e) => setQuantity(e.target.value)}\n placeholder={multiplier === 60 ? 'hrs' : 'min'}\n className={`input ${textSize} ${inputWidth} text-center`}\n autoFocus={autoFocus}\n data-testid={`${testId}-quantity`}\n />\n <select\n value={multiplier}\n onChange={(e) => setMultiplier(parseInt(e.target.value))}\n className={`select ${textSize} py-1`}\n data-testid={`${testId}-unit`}\n >\n {UNITS.map((u) => (\n <option key={u.value} value={u.value}>{u.label}</option>\n ))}\n </select>\n </div>\n );\n}\n","import { useState, useCallback } from 'react';\nimport { Modal } from './Modal';\nimport { CustomDurationPicker } from '../form/CustomDurationPicker';\nimport { useUsers } from '../../../api/users';\nimport { useAuth } from '../../../hooks/useAuth';\nimport { useClaimDurations } from '../../../hooks/useClaimDurations';\nimport { useDebouncedValue } from '../../../hooks/useDebouncedValue';\nimport type { LTUserRecord } from '../../../api/types';\n\ninterface BulkAssignModalProps {\n open: boolean;\n onClose: () => void;\n selectedCount: number;\n /** Distinct roles of the selected escalations; scopes user list for admins */\n selectedRoles: string[];\n onSubmit: (targetUserId: string, durationMinutes: number, reassign: boolean) => void;\n isPending: boolean;\n /**\n * Selected rows currently under a LIVE claim. Plain assign skips them;\n * when > 0 the duration step offers the explicit takeover.\n */\n claimedCount?: number;\n /** Assignment outcome from the last submit; skipped > 0 keeps the modal open to say so. */\n result?: { assigned: number; skipped: number } | null;\n}\n\nexport function BulkAssignModal({\n open,\n onClose,\n selectedCount,\n selectedRoles,\n onSubmit,\n isPending,\n claimedCount = 0,\n result = null,\n}: BulkAssignModalProps) {\n const { isSuperAdmin } = useAuth();\n const claimDurations = useClaimDurations();\n const [step, setStep] = useState<'user' | 'duration'>('user');\n const [selectedUser, setSelectedUser] = useState<LTUserRecord | null>(null);\n const [search, setSearch] = useState('');\n const [duration, setDuration] = useState('30');\n const [customMinutes, setCustomMinutes] = useState(0);\n const [reassign, setReassign] = useState(false);\n const onCustomChange = useCallback((m: number) => setCustomMinutes(m), []);\n\n // Admins with a single role: scope to that role. Otherwise show all active users.\n const roleFilter =\n !isSuperAdmin && selectedRoles.length === 1 ? selectedRoles[0] : undefined;\n\n // Search is resolved server-side (ILIKE on name/email/external_id) so it matches\n // every user, not just a fetched slice — no client-side filtering over a cap.\n const debouncedSearch = useDebouncedValue(search, 250);\n const { data: usersData, isLoading: usersLoading } = useUsers({\n role: roleFilter,\n status: 'active',\n search: debouncedSearch.trim() || undefined,\n limit: 200,\n });\n\n const users = usersData?.users ?? [];\n\n const handleClose = () => {\n setStep('user');\n setSelectedUser(null);\n setSearch('');\n setDuration('30');\n setCustomMinutes(0);\n setReassign(false);\n onClose();\n };\n\n const handleSelectUser = (user: LTUserRecord) => {\n setSelectedUser(user);\n setStep('duration');\n };\n\n const handleBack = () => {\n setStep('user');\n };\n\n const handleSubmit = () => {\n if (!selectedUser) return;\n const minutes = duration === 'custom' ? customMinutes : parseInt(duration);\n if (!minutes || minutes <= 0) return;\n onSubmit(selectedUser.id, minutes, reassign);\n };\n\n return (\n <Modal open={open} onClose={handleClose} title=\"Assign Escalations\">\n <div className=\"space-y-4\">\n {step === 'user' && (\n <>\n <p className=\"text-sm text-text-secondary\">\n Select a user to assign{' '}\n <span className=\"font-medium text-text-primary\">\n {selectedCount}\n </span>{' '}\n escalation(s) to:\n </p>\n\n <input\n type=\"text\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"Search by name or email...\"\n className=\"input text-xs w-full\"\n autoFocus\n />\n\n <div className=\"max-h-60 overflow-y-auto border border-surface-border rounded-lg divide-y divide-surface-border\">\n {usersLoading && (\n <p className=\"text-xs text-text-tertiary p-3\">\n Loading users...\n </p>\n )}\n {!usersLoading && users.length === 0 && (\n <p className=\"text-xs text-text-tertiary p-3\">\n No users found\n </p>\n )}\n {users.map((user) => (\n <button\n key={user.id}\n onClick={() => handleSelectUser(user)}\n className=\"w-full text-left px-3 py-2 hover:bg-surface-hover transition-colors\"\n >\n <p className=\"text-xs font-medium text-text-primary\">\n {user.display_name || user.external_id}\n </p>\n {user.email && (\n <p className=\"text-2xs text-text-tertiary\">\n {user.email}\n </p>\n )}\n </button>\n ))}\n </div>\n\n <div className=\"flex justify-end pt-2\">\n <button onClick={handleClose} className=\"btn-secondary text-xs\">\n Cancel\n </button>\n </div>\n </>\n )}\n\n {step === 'duration' && selectedUser && (\n <>\n <p className=\"text-sm text-text-secondary\">\n Assign to{' '}\n <span className=\"font-medium text-text-primary\">\n {selectedUser.display_name || selectedUser.external_id}\n </span>{' '}\n for:\n </p>\n\n <select\n value={duration}\n onChange={(e) => { setDuration(e.target.value); setCustomMinutes(0); }}\n className=\"select w-full text-sm\"\n >\n {claimDurations.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n <option value=\"custom\">Other...</option>\n </select>\n {duration === 'custom' && (\n <CustomDurationPicker onChange={onCustomChange} autoFocus />\n )}\n\n {claimedCount > 0 && (\n <label className=\"flex items-start gap-2 text-xs text-text-secondary\">\n <input\n type=\"checkbox\"\n checked={reassign}\n onChange={(e) => setReassign(e.target.checked)}\n className=\"mt-0.5\"\n />\n <span>\n Also reassign <span className=\"font-medium text-text-primary\">{claimedCount}</span>{' '}\n item(s) with a live claim — the current holder loses the item.\n Unchecked, those are skipped.\n </span>\n </label>\n )}\n\n {result && result.skipped > 0 && (\n <p className=\"text-xs text-status-warning\" data-testid=\"assign-skip-note\">\n Assigned {result.assigned} · skipped {result.skipped} with live claims.\n </p>\n )}\n\n <div className=\"flex justify-end gap-3 pt-2\">\n <button onClick={handleBack} className=\"btn-secondary text-xs\">\n Back\n </button>\n <button\n onClick={handleSubmit}\n disabled={isPending}\n className=\"btn-primary text-xs\"\n >\n {isPending ? 'Assigning...' : 'Assign'}\n </button>\n </div>\n </>\n )}\n </div>\n </Modal>\n );\n}\n"],"names":["ConfirmCancelModal","open","onClose","onConfirm","selectedCount","isPending","error","actionLabel","isBulk","label","title","body","jsx","Modal","jsxs","X_LT_LABELS","FOOTER_LABEL_TARGETS","readFooterLabels","schema","raw","source","labels","target","value","useClaimDurations","settings","useSettings","useMemo","_a","DEFAULT_CLAIM_DURATIONS","m","formatClaimDuration","UNITS","CustomDurationPicker","onChange","compact","autoFocus","testId","quantity","setQuantity","useState","multiplier","setMultiplier","useEffect","q","textSize","inputWidth","e","u","BulkAssignModal","selectedRoles","onSubmit","claimedCount","result","isSuperAdmin","useAuth","claimDurations","step","setStep","selectedUser","setSelectedUser","search","setSearch","duration","setDuration","customMinutes","setCustomMinutes","reassign","setReassign","onCustomChange","useCallback","roleFilter","debouncedSearch","useDebouncedValue","usersData","usersLoading","useUsers","users","handleClose","handleSelectUser","user","handleBack","handleSubmit","minutes","Fragment","opt"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{a as i,j as e}from"./vendor-query-RUZdMvN6.js";import{u as I}from"./capabilities-Cijq-qev.js";import{T as w,S}from"./ToolTestPanel-IGrd44Au.js";import{T as k}from"./ToolPill-C6hkOqPx.js";import{P}from"./PageHeader-CFVw67M6.js";import{F as E,b as T,a as L}from"./FilterBar-BY--ANxv.js";import{Y as R}from"./index-CgXVDPW-.js";import{bc as A,B as O,bd as $,k as K,be as B,p as D,b1 as F,E as Y,$ as q,i as M}from"./vendor-icons-h-jlRSb9.js";import"./mcp-BkkLq6OE.js";import"./RunAsSelector-BawZcqAk.js";import"./BotPicker-CBf6bHLV.js";import"./bots-CaXqSHat.js";import"./vendor-react-CdqEC2zv.js";import"./helpers-DzO-OGPe.js";const y={Communication:q,Analysis:Y,Media:F,Data:D,Automation:B,Development:K,System:$,Reference:O,Other:A},p="capability-run";function ae(){const{data:n,isLoading:c}=I(),a=R(),[l,N]=i.useState(""),[m,g]=i.useState(null),[t,x]=i.useState(null),u=(n==null?void 0:n.categories)??[],C=(n==null?void 0:n.totalTools)??0,j=i.useMemo(()=>{let s=u;if(m&&(s=s.filter(r=>r.name===m)),!l.trim())return s;const o=l.toLowerCase();return s.map(r=>({...r,tools:r.tools.filter(v=>v.name.toLowerCase().includes(o)||v.description.toLowerCase().includes(o)||v.serverName.toLowerCase().includes(o))})).filter(r=>r.tools.length>0)},[u,l,m]),f=t?`${t.serverId}:${t.tool.name}`:null,h=i.useRef(null),d=i.useRef(!1);i.useEffect(()=>{a&&f!==h.current&&(h.current=f,t?a.setPanel(e.jsx("div",{className:"h-full overflow-y-auto",children:e.jsx(w,{serverId:t.serverId,serverName:t.serverName,tool:t.tool,onClose:()=>x(null)})}),{key:p,width:420}):(d.current=!1,a.closePanel(p)))},[t,f,a]),i.useEffect(()=>{if(!(!a||!t)){if(a.open&&a.ownerKey===p){d.current=!0;return}d.current&&(d.current=!1,x(null))}},[a,t]);const b=i.useRef(a);return b.current=a,i.useEffect(()=>()=>{var s;h.current&&((s=b.current)==null||s.closePanel(p))},[]),e.jsxs("div",{children:[e.jsx(P,{title:"Capabilities"}),!c&&u.length>0&&e.jsxs(E,{children:[e.jsx(T,{label:"Category",value:m??"",onChange:s=>g(s||null),options:u.map(s=>({value:s.name,label:s.name}))}),e.jsx(L,{label:"Search",value:l,onChange:N,placeholder:`${C} capabilities…`})]}),c?e.jsx("div",{className:"animate-pulse space-y-8",children:[1,2,3].map(s=>e.jsxs("div",{children:[e.jsx("div",{className:"h-4 bg-surface-sunken rounded w-28 mb-4"}),e.jsx("div",{className:"space-y-3",children:[1,2,3].map(o=>e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("div",{className:"h-4 bg-surface-sunken rounded w-36"}),e.jsx("div",{className:"h-3 bg-surface-sunken rounded w-full"})]},o))})]},s))}):j.length===0?e.jsx("p",{className:"text-sm text-text-tertiary mt-8",children:l||m?"No capabilities match your filter.":"No capabilities registered yet."}):e.jsx("div",{className:"space-y-10",children:j.map(s=>{const o=y[s.name]??y.Other;return e.jsxs("div",{children:[e.jsxs("div",{className:"sticky top-[60px] z-10 bg-surface flex items-center gap-2 py-2 mb-2 border-b border-surface-border",children:[e.jsx(o,{className:"w-3 h-3 text-accent",strokeWidth:1.5}),e.jsx("h2",{className:"section-h2",children:s.name}),e.jsx("span",{className:"text-xs text-text-quaternary",children:s.tools.length})]}),e.jsx("div",{className:"divide-y divide-surface-border/30",children:s.tools.map(r=>e.jsx(W,{tool:r,isSelected:(t==null?void 0:t.tool.name)===r.name&&(t==null?void 0:t.serverId)===r.serverId,onSelect:()=>x({serverId:r.serverId,serverName:r.serverName,tool:{name:r.name,description:r.description,inputSchema:r.inputSchema}})},`${r.serverId}-${r.name}`))})]},s.name)})})]})}function W({tool:n,isSelected:c,onSelect:a}){return e.jsxs("div",{role:"button",tabIndex:0,onClick:a,onKeyDown:l=>{(l.key==="Enter"||l.key===" ")&&a()},className:"group relative py-2 px-3 -mx-3 rounded-md cursor-pointer hover:bg-surface-hover/30 transition-colors text-left",children:[c&&e.jsx("span",{className:"absolute left-0 top-1 bottom-1 w-0.5 bg-accent rounded-full"}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(k,{name:n.name,size:"md"}),e.jsx("p",{className:"flex-1 min-w-0 truncate text-2xs text-text-tertiary group-hover:text-text-secondary transition-colors",children:n.description}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsx(S,{name:n.serverName,serverId:n.serverId}),e.jsx("span",{title:"Try it",children:e.jsx(M,{className:`w-3 h-3 transition-opacity ${c?"text-accent opacity-100":"text-accent opacity-0 group-hover:opacity-100"}`,strokeWidth:1.5})})]})]})]})}export{ae as CapabilitiesPage};
2
- //# sourceMappingURL=CapabilitiesPage-D7USh3F0.js.map
1
+ import{a as i,j as e}from"./vendor-query-RUZdMvN6.js";import{u as I}from"./capabilities-DkLM1xgH.js";import{T as w,S}from"./ToolTestPanel-CQVYC3Ba.js";import{T as k}from"./ToolPill-C6hkOqPx.js";import{P}from"./PageHeader-CFVw67M6.js";import{F as E,b as T,a as L}from"./FilterBar-DWYGkVRH.js";import{Y as R}from"./index-zrTQcPjB.js";import{bc as A,B as O,bd as $,k as K,be as B,p as D,b1 as F,E as Y,$ as q,i as M}from"./vendor-icons-h-jlRSb9.js";import"./mcp-Bb1k5rv-.js";import"./RunAsSelector-BgntKfSA.js";import"./BotPicker-GU44inXA.js";import"./bots-B9zS0z7D.js";import"./vendor-react-CdqEC2zv.js";import"./helpers-DzO-OGPe.js";const y={Communication:q,Analysis:Y,Media:F,Data:D,Automation:B,Development:K,System:$,Reference:O,Other:A},p="capability-run";function ae(){const{data:n,isLoading:c}=I(),a=R(),[l,N]=i.useState(""),[m,g]=i.useState(null),[t,x]=i.useState(null),u=(n==null?void 0:n.categories)??[],C=(n==null?void 0:n.totalTools)??0,j=i.useMemo(()=>{let s=u;if(m&&(s=s.filter(r=>r.name===m)),!l.trim())return s;const o=l.toLowerCase();return s.map(r=>({...r,tools:r.tools.filter(v=>v.name.toLowerCase().includes(o)||v.description.toLowerCase().includes(o)||v.serverName.toLowerCase().includes(o))})).filter(r=>r.tools.length>0)},[u,l,m]),f=t?`${t.serverId}:${t.tool.name}`:null,h=i.useRef(null),d=i.useRef(!1);i.useEffect(()=>{a&&f!==h.current&&(h.current=f,t?a.setPanel(e.jsx("div",{className:"h-full overflow-y-auto",children:e.jsx(w,{serverId:t.serverId,serverName:t.serverName,tool:t.tool,onClose:()=>x(null)})}),{key:p,width:420}):(d.current=!1,a.closePanel(p)))},[t,f,a]),i.useEffect(()=>{if(!(!a||!t)){if(a.open&&a.ownerKey===p){d.current=!0;return}d.current&&(d.current=!1,x(null))}},[a,t]);const b=i.useRef(a);return b.current=a,i.useEffect(()=>()=>{var s;h.current&&((s=b.current)==null||s.closePanel(p))},[]),e.jsxs("div",{children:[e.jsx(P,{title:"Capabilities"}),!c&&u.length>0&&e.jsxs(E,{children:[e.jsx(T,{label:"Category",value:m??"",onChange:s=>g(s||null),options:u.map(s=>({value:s.name,label:s.name}))}),e.jsx(L,{label:"Search",value:l,onChange:N,placeholder:`${C} capabilities…`})]}),c?e.jsx("div",{className:"animate-pulse space-y-8",children:[1,2,3].map(s=>e.jsxs("div",{children:[e.jsx("div",{className:"h-4 bg-surface-sunken rounded w-28 mb-4"}),e.jsx("div",{className:"space-y-3",children:[1,2,3].map(o=>e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("div",{className:"h-4 bg-surface-sunken rounded w-36"}),e.jsx("div",{className:"h-3 bg-surface-sunken rounded w-full"})]},o))})]},s))}):j.length===0?e.jsx("p",{className:"text-sm text-text-tertiary mt-8",children:l||m?"No capabilities match your filter.":"No capabilities registered yet."}):e.jsx("div",{className:"space-y-10",children:j.map(s=>{const o=y[s.name]??y.Other;return e.jsxs("div",{children:[e.jsxs("div",{className:"sticky top-[60px] z-10 bg-surface flex items-center gap-2 py-2 mb-2 border-b border-surface-border",children:[e.jsx(o,{className:"w-3 h-3 text-accent",strokeWidth:1.5}),e.jsx("h2",{className:"section-h2",children:s.name}),e.jsx("span",{className:"text-xs text-text-quaternary",children:s.tools.length})]}),e.jsx("div",{className:"divide-y divide-surface-border/30",children:s.tools.map(r=>e.jsx(W,{tool:r,isSelected:(t==null?void 0:t.tool.name)===r.name&&(t==null?void 0:t.serverId)===r.serverId,onSelect:()=>x({serverId:r.serverId,serverName:r.serverName,tool:{name:r.name,description:r.description,inputSchema:r.inputSchema}})},`${r.serverId}-${r.name}`))})]},s.name)})})]})}function W({tool:n,isSelected:c,onSelect:a}){return e.jsxs("div",{role:"button",tabIndex:0,onClick:a,onKeyDown:l=>{(l.key==="Enter"||l.key===" ")&&a()},className:"group relative py-2 px-3 -mx-3 rounded-md cursor-pointer hover:bg-surface-hover/30 transition-colors text-left",children:[c&&e.jsx("span",{className:"absolute left-0 top-1 bottom-1 w-0.5 bg-accent rounded-full"}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(k,{name:n.name,size:"md"}),e.jsx("p",{className:"flex-1 min-w-0 truncate text-2xs text-text-tertiary group-hover:text-text-secondary transition-colors",children:n.description}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsx(S,{name:n.serverName,serverId:n.serverId}),e.jsx("span",{title:"Try it",children:e.jsx(M,{className:`w-3 h-3 transition-opacity ${c?"text-accent opacity-100":"text-accent opacity-0 group-hover:opacity-100"}`,strokeWidth:1.5})})]})]})]})}export{ae as CapabilitiesPage};
2
+ //# sourceMappingURL=CapabilitiesPage-Y2hycdPY.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CapabilitiesPage-D7USh3F0.js","sources":["../../src/pages/capabilities/CapabilitiesPage.tsx"],"sourcesContent":["import { useState, useMemo, useEffect, useRef } from 'react';\nimport {\n Play,\n MessageSquare, Eye, Database, Cog, Code2, Shield, BookOpen,\n LayoutGrid, Image,\n} from 'lucide-react';\nimport { useCapabilities, type CapabilityTool } from '../../api/capabilities';\nimport { ToolTestPanel } from '../../components/common/test/ToolTestPanel';\nimport { ToolPill } from '../../components/common/display/ToolPill';\nimport { ServerName } from '../../components/common/display/ServerName';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { FilterBar, FilterSelect, FilterInput } from '../../components/common/data/FilterBar';\nimport { useShellPanelOptional } from '../../hooks/useShellPanel';\nimport type { LucideIcon } from 'lucide-react';\n\n// ── Category meta ─────────────────────────────────────────────────────────────\n\nconst CATEGORY_ICONS: Record<string, LucideIcon> = {\n Communication: MessageSquare,\n Analysis: Eye,\n Media: Image,\n Data: Database,\n Automation: Cog,\n Development: Code2,\n System: Shield,\n Reference: BookOpen,\n Other: LayoutGrid,\n};\n\n// Shell-panel ownership key — the tool run panel claims/releases this slot.\nconst CAPABILITY_PANEL_KEY = 'capability-run';\n\ninterface SelectedTool {\n serverId: string;\n serverName: string;\n tool: { name: string; description: string; inputSchema: Record<string, any> };\n}\n\n// ── Page ─────────────────────────────────────────────────────────────────────\n\nexport function CapabilitiesPage() {\n const { data, isLoading } = useCapabilities();\n const shell = useShellPanelOptional();\n const [search, setSearch] = useState('');\n const [activeCategory, setActiveCategory] = useState<string | null>(null);\n const [selected, setSelected] = useState<SelectedTool | null>(null);\n\n const categories = data?.categories ?? [];\n const totalTools = data?.totalTools ?? 0;\n\n const filtered = useMemo(() => {\n let cats = categories;\n if (activeCategory) cats = cats.filter((c) => c.name === activeCategory);\n if (!search.trim()) return cats;\n const q = search.toLowerCase();\n return cats\n .map((cat) => ({\n ...cat,\n tools: cat.tools.filter(\n (t) =>\n t.name.toLowerCase().includes(q) ||\n t.description.toLowerCase().includes(q) ||\n t.serverName.toLowerCase().includes(q),\n ),\n }))\n .filter((cat) => cat.tools.length > 0);\n }, [categories, search, activeCategory]);\n\n // ── Selection ↔ shell panel sync ────────────────────────────────────────────\n // Selecting a tool opens the run panel in the shell's right slot; an\n // external close (the panel's X, slot takeover) clears the selection. The\n // applied-key ref guards against re-setting the panel on unrelated renders.\n const selectedKey = selected ? `${selected.serverId}:${selected.tool.name}` : null;\n const appliedKey = useRef<string | null>(null);\n const panelWasOpen = useRef(false);\n useEffect(() => {\n if (!shell) return;\n if (selectedKey === appliedKey.current) return;\n appliedKey.current = selectedKey;\n if (selected) {\n shell.setPanel(\n <div className=\"h-full overflow-y-auto\">\n <ToolTestPanel\n serverId={selected.serverId}\n serverName={selected.serverName}\n tool={selected.tool}\n onClose={() => setSelected(null)}\n />\n </div>,\n { key: CAPABILITY_PANEL_KEY, width: 420 },\n );\n } else {\n panelWasOpen.current = false;\n shell.closePanel(CAPABILITY_PANEL_KEY);\n }\n }, [selected, selectedKey, shell]);\n useEffect(() => {\n if (!shell || !selected) return;\n if (shell.open && shell.ownerKey === CAPABILITY_PANEL_KEY) {\n panelWasOpen.current = true;\n return;\n }\n if (panelWasOpen.current) {\n panelWasOpen.current = false;\n setSelected(null);\n }\n }, [shell, selected]);\n // Unmount with the panel open releases the slot (keyed — never yanks\n // another claimant's panel).\n const shellRef = useRef(shell);\n shellRef.current = shell;\n useEffect(\n () => () => {\n if (appliedKey.current) shellRef.current?.closePanel(CAPABILITY_PANEL_KEY);\n },\n [],\n );\n\n return (\n <div>\n <PageHeader title=\"Capabilities\" />\n\n {/* The standard full-width sticky filter band — above the list, like\n every other master list page. */}\n {!isLoading && categories.length > 0 && (\n <FilterBar>\n <FilterSelect\n label=\"Category\"\n value={activeCategory ?? ''}\n onChange={(v) => setActiveCategory(v || null)}\n options={categories.map((c) => ({ value: c.name, label: c.name }))}\n />\n <FilterInput\n label=\"Search\"\n value={search}\n onChange={setSearch}\n placeholder={`${totalTools} capabilities…`}\n />\n </FilterBar>\n )}\n\n {/* The list IS the page — selecting a row opens the run panel in the\n shell's right panel. */}\n {isLoading ? (\n <div className=\"animate-pulse space-y-8\">\n {[1, 2, 3].map((i) => (\n <div key={i}>\n <div className=\"h-4 bg-surface-sunken rounded w-28 mb-4\" />\n <div className=\"space-y-3\">\n {[1, 2, 3].map((j) => (\n <div key={j} className=\"space-y-1.5\">\n <div className=\"h-4 bg-surface-sunken rounded w-36\" />\n <div className=\"h-3 bg-surface-sunken rounded w-full\" />\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n ) : filtered.length === 0 ? (\n <p className=\"text-sm text-text-tertiary mt-8\">\n {search || activeCategory ? 'No capabilities match your filter.' : 'No capabilities registered yet.'}\n </p>\n ) : (\n <div className=\"space-y-10\">\n {filtered.map((category) => {\n const Icon = CATEGORY_ICONS[category.name] ?? CATEGORY_ICONS.Other;\n return (\n <div key={category.name}>\n <div className=\"sticky top-[60px] z-10 bg-surface flex items-center gap-2 py-2 mb-2 border-b border-surface-border\">\n <Icon className=\"w-3 h-3 text-accent\" strokeWidth={1.5} />\n <h2 className=\"section-h2\">{category.name}</h2>\n <span className=\"text-xs text-text-quaternary\">{category.tools.length}</span>\n </div>\n <div className=\"divide-y divide-surface-border/30\">\n {category.tools.map((tool) => (\n <ToolRow\n key={`${tool.serverId}-${tool.name}`}\n tool={tool}\n isSelected={selected?.tool.name === tool.name && selected?.serverId === tool.serverId}\n onSelect={() =>\n setSelected({\n serverId: tool.serverId,\n serverName: tool.serverName,\n tool: { name: tool.name, description: tool.description, inputSchema: tool.inputSchema },\n })\n }\n />\n ))}\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n\n// ── Tool row ─────────────────────────────────────────────────────────────────\n\nfunction ToolRow({\n tool,\n isSelected,\n onSelect,\n}: {\n tool: CapabilityTool;\n isSelected: boolean;\n onSelect: () => void;\n}) {\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={onSelect}\n onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') onSelect(); }}\n className=\"group relative py-2 px-3 -mx-3 rounded-md cursor-pointer hover:bg-surface-hover/30 transition-colors text-left\"\n >\n {isSelected && <span className=\"absolute left-0 top-1 bottom-1 w-0.5 bg-accent rounded-full\" />}\n <div className=\"flex items-center gap-3\">\n <ToolPill name={tool.name} size=\"md\" />\n <p className=\"flex-1 min-w-0 truncate text-2xs text-text-tertiary group-hover:text-text-secondary transition-colors\">\n {tool.description}\n </p>\n <div className=\"flex items-center gap-2 shrink-0\">\n <ServerName name={tool.serverName} serverId={tool.serverId} />\n {/* Trailing action icon — quiet until row hover, visible on the\n selected row. Selecting opens the run panel in the shell panel. */}\n <span title=\"Try it\">\n <Play\n className={`w-3 h-3 transition-opacity ${isSelected ? 'text-accent opacity-100' : 'text-accent opacity-0 group-hover:opacity-100'}`}\n strokeWidth={1.5}\n />\n </span>\n </div>\n </div>\n </div>\n );\n}\n"],"names":["CATEGORY_ICONS","MessageSquare","Eye","Image","Database","Cog","Code2","Shield","BookOpen","LayoutGrid","CAPABILITY_PANEL_KEY","CapabilitiesPage","data","isLoading","useCapabilities","shell","useShellPanelOptional","search","setSearch","useState","activeCategory","setActiveCategory","selected","setSelected","categories","totalTools","filtered","useMemo","cats","c","q","cat","t","selectedKey","appliedKey","useRef","panelWasOpen","useEffect","jsx","ToolTestPanel","shellRef","_a","PageHeader","FilterBar","FilterSelect","v","FilterInput","i","j","jsxs","category","Icon","tool","ToolRow","isSelected","onSelect","e","ToolPill","ServerName","Play"],"mappings":"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"}
1
+ {"version":3,"file":"CapabilitiesPage-Y2hycdPY.js","sources":["../../src/pages/capabilities/CapabilitiesPage.tsx"],"sourcesContent":["import { useState, useMemo, useEffect, useRef } from 'react';\nimport {\n Play,\n MessageSquare, Eye, Database, Cog, Code2, Shield, BookOpen,\n LayoutGrid, Image,\n} from 'lucide-react';\nimport { useCapabilities, type CapabilityTool } from '../../api/capabilities';\nimport { ToolTestPanel } from '../../components/common/test/ToolTestPanel';\nimport { ToolPill } from '../../components/common/display/ToolPill';\nimport { ServerName } from '../../components/common/display/ServerName';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { FilterBar, FilterSelect, FilterInput } from '../../components/common/data/FilterBar';\nimport { useShellPanelOptional } from '../../hooks/useShellPanel';\nimport type { LucideIcon } from 'lucide-react';\n\n// ── Category meta ─────────────────────────────────────────────────────────────\n\nconst CATEGORY_ICONS: Record<string, LucideIcon> = {\n Communication: MessageSquare,\n Analysis: Eye,\n Media: Image,\n Data: Database,\n Automation: Cog,\n Development: Code2,\n System: Shield,\n Reference: BookOpen,\n Other: LayoutGrid,\n};\n\n// Shell-panel ownership key — the tool run panel claims/releases this slot.\nconst CAPABILITY_PANEL_KEY = 'capability-run';\n\ninterface SelectedTool {\n serverId: string;\n serverName: string;\n tool: { name: string; description: string; inputSchema: Record<string, any> };\n}\n\n// ── Page ─────────────────────────────────────────────────────────────────────\n\nexport function CapabilitiesPage() {\n const { data, isLoading } = useCapabilities();\n const shell = useShellPanelOptional();\n const [search, setSearch] = useState('');\n const [activeCategory, setActiveCategory] = useState<string | null>(null);\n const [selected, setSelected] = useState<SelectedTool | null>(null);\n\n const categories = data?.categories ?? [];\n const totalTools = data?.totalTools ?? 0;\n\n const filtered = useMemo(() => {\n let cats = categories;\n if (activeCategory) cats = cats.filter((c) => c.name === activeCategory);\n if (!search.trim()) return cats;\n const q = search.toLowerCase();\n return cats\n .map((cat) => ({\n ...cat,\n tools: cat.tools.filter(\n (t) =>\n t.name.toLowerCase().includes(q) ||\n t.description.toLowerCase().includes(q) ||\n t.serverName.toLowerCase().includes(q),\n ),\n }))\n .filter((cat) => cat.tools.length > 0);\n }, [categories, search, activeCategory]);\n\n // ── Selection ↔ shell panel sync ────────────────────────────────────────────\n // Selecting a tool opens the run panel in the shell's right slot; an\n // external close (the panel's X, slot takeover) clears the selection. The\n // applied-key ref guards against re-setting the panel on unrelated renders.\n const selectedKey = selected ? `${selected.serverId}:${selected.tool.name}` : null;\n const appliedKey = useRef<string | null>(null);\n const panelWasOpen = useRef(false);\n useEffect(() => {\n if (!shell) return;\n if (selectedKey === appliedKey.current) return;\n appliedKey.current = selectedKey;\n if (selected) {\n shell.setPanel(\n <div className=\"h-full overflow-y-auto\">\n <ToolTestPanel\n serverId={selected.serverId}\n serverName={selected.serverName}\n tool={selected.tool}\n onClose={() => setSelected(null)}\n />\n </div>,\n { key: CAPABILITY_PANEL_KEY, width: 420 },\n );\n } else {\n panelWasOpen.current = false;\n shell.closePanel(CAPABILITY_PANEL_KEY);\n }\n }, [selected, selectedKey, shell]);\n useEffect(() => {\n if (!shell || !selected) return;\n if (shell.open && shell.ownerKey === CAPABILITY_PANEL_KEY) {\n panelWasOpen.current = true;\n return;\n }\n if (panelWasOpen.current) {\n panelWasOpen.current = false;\n setSelected(null);\n }\n }, [shell, selected]);\n // Unmount with the panel open releases the slot (keyed — never yanks\n // another claimant's panel).\n const shellRef = useRef(shell);\n shellRef.current = shell;\n useEffect(\n () => () => {\n if (appliedKey.current) shellRef.current?.closePanel(CAPABILITY_PANEL_KEY);\n },\n [],\n );\n\n return (\n <div>\n <PageHeader title=\"Capabilities\" />\n\n {/* The standard full-width sticky filter band — above the list, like\n every other master list page. */}\n {!isLoading && categories.length > 0 && (\n <FilterBar>\n <FilterSelect\n label=\"Category\"\n value={activeCategory ?? ''}\n onChange={(v) => setActiveCategory(v || null)}\n options={categories.map((c) => ({ value: c.name, label: c.name }))}\n />\n <FilterInput\n label=\"Search\"\n value={search}\n onChange={setSearch}\n placeholder={`${totalTools} capabilities…`}\n />\n </FilterBar>\n )}\n\n {/* The list IS the page — selecting a row opens the run panel in the\n shell's right panel. */}\n {isLoading ? (\n <div className=\"animate-pulse space-y-8\">\n {[1, 2, 3].map((i) => (\n <div key={i}>\n <div className=\"h-4 bg-surface-sunken rounded w-28 mb-4\" />\n <div className=\"space-y-3\">\n {[1, 2, 3].map((j) => (\n <div key={j} className=\"space-y-1.5\">\n <div className=\"h-4 bg-surface-sunken rounded w-36\" />\n <div className=\"h-3 bg-surface-sunken rounded w-full\" />\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n ) : filtered.length === 0 ? (\n <p className=\"text-sm text-text-tertiary mt-8\">\n {search || activeCategory ? 'No capabilities match your filter.' : 'No capabilities registered yet.'}\n </p>\n ) : (\n <div className=\"space-y-10\">\n {filtered.map((category) => {\n const Icon = CATEGORY_ICONS[category.name] ?? CATEGORY_ICONS.Other;\n return (\n <div key={category.name}>\n <div className=\"sticky top-[60px] z-10 bg-surface flex items-center gap-2 py-2 mb-2 border-b border-surface-border\">\n <Icon className=\"w-3 h-3 text-accent\" strokeWidth={1.5} />\n <h2 className=\"section-h2\">{category.name}</h2>\n <span className=\"text-xs text-text-quaternary\">{category.tools.length}</span>\n </div>\n <div className=\"divide-y divide-surface-border/30\">\n {category.tools.map((tool) => (\n <ToolRow\n key={`${tool.serverId}-${tool.name}`}\n tool={tool}\n isSelected={selected?.tool.name === tool.name && selected?.serverId === tool.serverId}\n onSelect={() =>\n setSelected({\n serverId: tool.serverId,\n serverName: tool.serverName,\n tool: { name: tool.name, description: tool.description, inputSchema: tool.inputSchema },\n })\n }\n />\n ))}\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n\n// ── Tool row ─────────────────────────────────────────────────────────────────\n\nfunction ToolRow({\n tool,\n isSelected,\n onSelect,\n}: {\n tool: CapabilityTool;\n isSelected: boolean;\n onSelect: () => void;\n}) {\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={onSelect}\n onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') onSelect(); }}\n className=\"group relative py-2 px-3 -mx-3 rounded-md cursor-pointer hover:bg-surface-hover/30 transition-colors text-left\"\n >\n {isSelected && <span className=\"absolute left-0 top-1 bottom-1 w-0.5 bg-accent rounded-full\" />}\n <div className=\"flex items-center gap-3\">\n <ToolPill name={tool.name} size=\"md\" />\n <p className=\"flex-1 min-w-0 truncate text-2xs text-text-tertiary group-hover:text-text-secondary transition-colors\">\n {tool.description}\n </p>\n <div className=\"flex items-center gap-2 shrink-0\">\n <ServerName name={tool.serverName} serverId={tool.serverId} />\n {/* Trailing action icon — quiet until row hover, visible on the\n selected row. Selecting opens the run panel in the shell panel. */}\n <span title=\"Try it\">\n <Play\n className={`w-3 h-3 transition-opacity ${isSelected ? 'text-accent opacity-100' : 'text-accent opacity-0 group-hover:opacity-100'}`}\n strokeWidth={1.5}\n />\n </span>\n </div>\n </div>\n </div>\n );\n}\n"],"names":["CATEGORY_ICONS","MessageSquare","Eye","Image","Database","Cog","Code2","Shield","BookOpen","LayoutGrid","CAPABILITY_PANEL_KEY","CapabilitiesPage","data","isLoading","useCapabilities","shell","useShellPanelOptional","search","setSearch","useState","activeCategory","setActiveCategory","selected","setSelected","categories","totalTools","filtered","useMemo","cats","c","q","cat","t","selectedKey","appliedKey","useRef","panelWasOpen","useEffect","jsx","ToolTestPanel","shellRef","_a","PageHeader","FilterBar","FilterSelect","v","FilterInput","i","j","jsxs","category","Icon","tool","ToolRow","isSelected","onSelect","e","ToolPill","ServerName","Play"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{j as t}from"./vendor-query-RUZdMvN6.js";import{C as a}from"./index-CgXVDPW-.js";function c({title:r,sectionKey:s,isCollapsed:e,onToggle:o,contentClassName:n,children:i}){return t.jsxs("div",{children:[t.jsxs("button",{onClick:()=>o(s),className:"flex items-center gap-3 w-full group/section",children:[t.jsx("svg",{className:`w-4 h-4 shrink-0 text-text-tertiary/40 group-hover/section:text-text-tertiary transition-all duration-200 ${e?"":"rotate-90"}`,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:t.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9 5l7 7-7 7"})}),t.jsx("span",{className:`text-xs font-semibold uppercase tracking-widest transition-colors duration-200 ${e?"text-text-tertiary":"text-text-secondary"}`,children:r}),t.jsx("span",{className:"flex-1 border-b border-surface-border"})]}),t.jsx(a,{open:!e,children:t.jsx("div",{className:n??"mt-4 ml-7",children:i})})]})}export{c as C};
2
- //# sourceMappingURL=CollapsibleSection-DfPpAIxa.js.map
1
+ import{j as t}from"./vendor-query-RUZdMvN6.js";import{C as a}from"./index-zrTQcPjB.js";function c({title:r,sectionKey:s,isCollapsed:e,onToggle:o,contentClassName:n,children:i}){return t.jsxs("div",{children:[t.jsxs("button",{onClick:()=>o(s),className:"flex items-center gap-3 w-full group/section",children:[t.jsx("svg",{className:`w-4 h-4 shrink-0 text-text-tertiary/40 group-hover/section:text-text-tertiary transition-all duration-200 ${e?"":"rotate-90"}`,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:t.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9 5l7 7-7 7"})}),t.jsx("span",{className:`text-xs font-semibold uppercase tracking-widest transition-colors duration-200 ${e?"text-text-tertiary":"text-text-secondary"}`,children:r}),t.jsx("span",{className:"flex-1 border-b border-surface-border"})]}),t.jsx(a,{open:!e,children:t.jsx("div",{className:n??"mt-4 ml-7",children:i})})]})}export{c as C};
2
+ //# sourceMappingURL=CollapsibleSection-CmCwt_Rs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CollapsibleSection-DfPpAIxa.js","sources":["../../src/components/common/layout/CollapsibleSection.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { Collapsible } from './Collapsible';\n\n/**\n * Shared collapsible section with chevron toggle and horizontal rule.\n * Used by WorkflowExecutionPage, McpRunDetailPage, and YamlWorkflowDetailPage.\n */\nexport function CollapsibleSection({\n title,\n sectionKey,\n isCollapsed,\n onToggle,\n contentClassName,\n children,\n}: {\n title: string;\n sectionKey: string;\n isCollapsed: boolean;\n onToggle: (key: string) => void;\n /** Optional class override for the content wrapper (default: \"mt-4 ml-7\") */\n contentClassName?: string;\n children: ReactNode;\n}) {\n return (\n <div>\n <button\n onClick={() => onToggle(sectionKey)}\n className=\"flex items-center gap-3 w-full group/section\"\n >\n <svg\n className={`w-4 h-4 shrink-0 text-text-tertiary/40 group-hover/section:text-text-tertiary transition-all duration-200 ${!isCollapsed ? 'rotate-90' : ''}`}\n fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M9 5l7 7-7 7\" />\n </svg>\n <span className={`text-xs font-semibold uppercase tracking-widest transition-colors duration-200 ${isCollapsed ? 'text-text-tertiary' : 'text-text-secondary'}`}>\n {title}\n </span>\n <span className=\"flex-1 border-b border-surface-border\" />\n </button>\n <Collapsible open={!isCollapsed}>\n <div className={contentClassName ?? 'mt-4 ml-7'}>{children}</div>\n </Collapsible>\n </div>\n );\n}\n"],"names":["CollapsibleSection","title","sectionKey","isCollapsed","onToggle","contentClassName","children","jsxs","jsx","Collapsible"],"mappings":"uFAOO,SAASA,EAAmB,CACjC,MAAAC,EACA,WAAAC,EACA,YAAAC,EACA,SAAAC,EACA,iBAAAC,EACA,SAAAC,CACF,EAQG,CACD,cACG,MAAA,CACC,SAAA,CAAAC,EAAAA,KAAC,SAAA,CACC,QAAS,IAAMH,EAASF,CAAU,EAClC,UAAU,+CAEV,SAAA,CAAAM,EAAAA,IAAC,MAAA,CACC,UAAW,6GAA8GL,EAA4B,GAAd,WAAgB,GACvJ,KAAK,OAAO,QAAQ,YAAY,OAAO,eAAe,YAAa,EAEnE,eAAC,OAAA,CAAK,cAAc,QAAQ,eAAe,QAAQ,EAAE,cAAA,CAAe,CAAA,CAAA,EAEtEK,EAAAA,IAAC,QAAK,UAAW,kFAAkFL,EAAc,qBAAuB,qBAAqB,GAC1J,SAAAF,CAAA,CACH,EACAO,EAAAA,IAAC,OAAA,CAAK,UAAU,uCAAA,CAAwC,CAAA,CAAA,CAAA,EAE1DA,EAAAA,IAACC,EAAA,CAAY,KAAM,CAACN,EAClB,SAAAK,EAAAA,IAAC,MAAA,CAAI,UAAWH,GAAoB,YAAc,SAAAC,CAAA,CAAS,CAAA,CAC7D,CAAA,EACF,CAEJ"}
1
+ {"version":3,"file":"CollapsibleSection-CmCwt_Rs.js","sources":["../../src/components/common/layout/CollapsibleSection.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { Collapsible } from './Collapsible';\n\n/**\n * Shared collapsible section with chevron toggle and horizontal rule.\n * Used by WorkflowExecutionPage, McpRunDetailPage, and YamlWorkflowDetailPage.\n */\nexport function CollapsibleSection({\n title,\n sectionKey,\n isCollapsed,\n onToggle,\n contentClassName,\n children,\n}: {\n title: string;\n sectionKey: string;\n isCollapsed: boolean;\n onToggle: (key: string) => void;\n /** Optional class override for the content wrapper (default: \"mt-4 ml-7\") */\n contentClassName?: string;\n children: ReactNode;\n}) {\n return (\n <div>\n <button\n onClick={() => onToggle(sectionKey)}\n className=\"flex items-center gap-3 w-full group/section\"\n >\n <svg\n className={`w-4 h-4 shrink-0 text-text-tertiary/40 group-hover/section:text-text-tertiary transition-all duration-200 ${!isCollapsed ? 'rotate-90' : ''}`}\n fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M9 5l7 7-7 7\" />\n </svg>\n <span className={`text-xs font-semibold uppercase tracking-widest transition-colors duration-200 ${isCollapsed ? 'text-text-tertiary' : 'text-text-secondary'}`}>\n {title}\n </span>\n <span className=\"flex-1 border-b border-surface-border\" />\n </button>\n <Collapsible open={!isCollapsed}>\n <div className={contentClassName ?? 'mt-4 ml-7'}>{children}</div>\n </Collapsible>\n </div>\n );\n}\n"],"names":["CollapsibleSection","title","sectionKey","isCollapsed","onToggle","contentClassName","children","jsxs","jsx","Collapsible"],"mappings":"uFAOO,SAASA,EAAmB,CACjC,MAAAC,EACA,WAAAC,EACA,YAAAC,EACA,SAAAC,EACA,iBAAAC,EACA,SAAAC,CACF,EAQG,CACD,cACG,MAAA,CACC,SAAA,CAAAC,EAAAA,KAAC,SAAA,CACC,QAAS,IAAMH,EAASF,CAAU,EAClC,UAAU,+CAEV,SAAA,CAAAM,EAAAA,IAAC,MAAA,CACC,UAAW,6GAA8GL,EAA4B,GAAd,WAAgB,GACvJ,KAAK,OAAO,QAAQ,YAAY,OAAO,eAAe,YAAa,EAEnE,eAAC,OAAA,CAAK,cAAc,QAAQ,eAAe,QAAQ,EAAE,cAAA,CAAe,CAAA,CAAA,EAEtEK,EAAAA,IAAC,QAAK,UAAW,kFAAkFL,EAAc,qBAAuB,qBAAqB,GAC1J,SAAAF,CAAA,CACH,EACAO,EAAAA,IAAC,OAAA,CAAK,UAAU,uCAAA,CAAwC,CAAA,CAAA,CAAA,EAE1DA,EAAAA,IAACC,EAAA,CAAY,KAAM,CAACN,EAClB,SAAAK,EAAAA,IAAC,MAAA,CAAI,UAAWH,GAAoB,YAAc,SAAAC,CAAA,CAAS,CAAA,CAC7D,CAAA,EACF,CAEJ"}
@@ -1,2 +1,2 @@
1
- import{a as j,j as s}from"./vendor-query-RUZdMvN6.js";import{D as Z}from"./DataTable-DFPMeqyQ.js";import{a8 as H,$ as O,T as Q,b as W,X as tt,i as et,a9 as st,aa as nt,ab as rt}from"./index-CgXVDPW-.js";import{a as at}from"./StatusBadge-BDeUwPtb.js";import{S as F}from"./StickyPagination-BfZwU2NR.js";import{M as it}from"./Modal-BU7No9NH.js";import{a8 as ot,aj as lt}from"./vendor-icons-h-jlRSb9.js";import{u as I,a as ct}from"./vendor-react-CdqEC2zv.js";const dt=new Set(["__proto__","constructor","prototype"]);function G(t){const e=[];for(const n of t.split(".")){const r=n.match(/^([^[\]]*)((?:\[\d+\])*)$/);if(!r)throw new Error(`invalid x-lt-bind path segment: "${n}"`);const[,a,o]=r;if(a){if(dt.has(a))throw new Error(`x-lt-bind path may not target "${a}"`);e.push({key:a})}for(const i of o.match(/\d+/g)??[])e.push({index:Number(i)})}if(e.length===0)throw new Error(`empty x-lt-bind path: "${t}"`);return e}function ut(t,e,n){const r=G(e);let a=t;for(let i=0;i<r.length-1;i++){const c=r[i],l=r[i+1],d="key"in c?c.key:c.index,h="index"in l;(a[d]==null||typeof a[d]!="object")&&(a[d]=h?[]:{}),a=a[d]}const o=r[r.length-1];a["key"in o?o.key:o.index]=n}function L(t,e){let n=t;for(const r of G(e)){if(n==null||typeof n!="object")return;n=n["key"in r?r.key:r.index]}return n}function J(t,e){const n=e==null?void 0:e["x-lt-bind"];return typeof n=="string"&&n.length>0?n:t}function Ht(t,e){const n=e==null?void 0:e.properties;if(!n)return{...t};const r={};for(const[a,o]of Object.entries(n))a in t&&ut(r,J(a,o),t[a]);return r}function Ft(t,e){const n=e==null?void 0:e.properties;if(!n)return t?{...t}:{};const r={};for(const[a,o]of Object.entries(n)){const i=L(t,J(a,o));i!==void 0&&(r[a]=i)}return r}const xt=["escalation","metadata","envelope","payload","resolver","lookup"],ft=/\{\{\s*([^{}]+?)\s*\}\}/g,A="—";function K(t){if(t==null)return A;if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return String(t);try{return JSON.stringify(t)}catch{return A}}function v(t,e){return t.replace(ft,(n,r)=>{const a=r.indexOf("."),o=a===-1?r:r.slice(0,a);if(!xt.includes(o))return A;const i=e[o];if(a===-1)return K(i);try{return K(L(i,r.slice(a+1)))}catch{return A}})}function mt(t){const e=t==null?void 0:t["x-lt-help"];if(typeof e=="string"&&e.trim().length>0)return e;const n=t==null?void 0:t["x-lt-context"];return typeof n=="string"&&n.trim().length>0?n:null}function Kt(t,e){const n=mt(t);return n?v(n,e):null}function Ut({isTerminal:t,status:e,claimed:n,claimedByMe:r}){return t?e==="cancelled"?"This escalation was cancelled. The record is shown for reference.":"This escalation has been resolved. The submitted form is shown for reference.":r?"You have claimed this escalation. Fill out the form and submit to resolve it.":n?"Another user has claimed this escalation. It unlocks if their claim expires or is released.":"Claim this escalation to enable the form."}function bt(t){if(!t)return!1;try{const e=JSON.stringify(t);return e.includes("envelope.")||e.includes("payload.")}catch{return!1}}function R(t){return!!(t.assigned_to&&t.assigned_until&&new Date(t.assigned_until)>new Date)}function qt(t){return!t.workflow_type}const U=[{text:"text-rose-400",bg:"bg-rose-400/[0.08]"},{text:"text-pink-400",bg:"bg-pink-400/[0.08]"},{text:"text-fuchsia-400",bg:"bg-fuchsia-400/[0.08]"},{text:"text-purple-400",bg:"bg-purple-400/[0.08]"},{text:"text-violet-400",bg:"bg-violet-400/[0.08]"},{text:"text-indigo-400",bg:"bg-indigo-400/[0.08]"},{text:"text-blue-400",bg:"bg-blue-400/[0.08]"},{text:"text-sky-400",bg:"bg-sky-400/[0.08]"},{text:"text-cyan-400",bg:"bg-cyan-400/[0.08]"},{text:"text-teal-400",bg:"bg-teal-400/[0.08]"},{text:"text-emerald-400",bg:"bg-emerald-400/[0.08]"},{text:"text-green-400",bg:"bg-green-400/[0.08]"},{text:"text-lime-400",bg:"bg-lime-400/[0.08]"},{text:"text-yellow-400",bg:"bg-yellow-400/[0.08]"},{text:"text-amber-400",bg:"bg-amber-400/[0.08]"},{text:"text-orange-400",bg:"bg-orange-400/[0.08]"},{text:"text-red-400",bg:"bg-red-400/[0.08]"},{text:"text-stone-400",bg:"bg-stone-400/[0.08]"},{text:"text-rose-300",bg:"bg-rose-300/[0.08]"},{text:"text-violet-300",bg:"bg-violet-300/[0.08]"},{text:"text-sky-300",bg:"bg-sky-300/[0.08]"},{text:"text-teal-300",bg:"bg-teal-300/[0.08]"},{text:"text-amber-300",bg:"bg-amber-300/[0.08]"},{text:"text-pink-300",bg:"bg-pink-300/[0.08]"}];function pt(t){let e=0;for(let n=0;n<t.length;n++)e=(e<<5)-e+t.charCodeAt(n)|0;return Math.abs(e)}function ht(t){return U[pt(t)%U.length]}function Y({open:t,onClose:e,role:n,pairs:r,onNavigate:a,onAddFacet:o}){const[i,c]=j.useState(new Set),[l,d]=j.useState(t);t!==l&&(d(t),t&&c(new Set(r.length===1?[r[0].key]:[])));const h=m=>{c(u=>{const p=new Set(u);return p.has(m)?p.delete(m):p.add(m),p})},f=r.filter(m=>i.has(m.key)),x=Object.fromEntries(f.map(m=>[m.key,m.value])),b=f.length===0,y=m=>{e(),a(m)};return s.jsx(it,{open:t,onClose:e,title:"Refine",children:s.jsxs("div",{className:"space-y-4",children:[s.jsx("p",{className:"text-2xs text-text-tertiary",children:"Pick the facts to match — several combine into one narrower query."}),s.jsx("div",{className:"divide-y divide-surface-border/40 -mx-1",children:r.map(m=>{const u=i.has(m.key);return s.jsxs("button",{type:"button",onClick:()=>h(m.key),"aria-pressed":u,className:"w-full flex items-center gap-3 px-1 py-2.5 text-left group min-w-0","data-testid":"refine-pair",children:[s.jsx("span",{className:`w-4 h-4 rounded-[3px] border flex items-center justify-center shrink-0 transition-colors ${u?"bg-accent border-accent":"border-surface-border group-hover:border-accent/50"}`,"aria-hidden":!0,children:u&&s.jsx(ot,{className:"w-3 h-3 text-text-inverse",strokeWidth:3})}),s.jsx("span",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary w-28 shrink-0 truncate",title:m.key,children:m.label}),s.jsx("span",{className:"text-xs text-text-primary truncate flex-1 min-w-0",title:String(m.value),children:String(m.value)})]},m.key)})}),s.jsxs("div",{className:"flex items-center justify-end gap-3 pt-2 flex-wrap",children:[o&&s.jsx("button",{onClick:()=>{f.forEach(m=>o(m.key,m.value)),e()},disabled:b,className:"text-xs text-text-secondary hover:text-accent transition-colors disabled:opacity-40 disabled:cursor-not-allowed mr-auto","data-testid":"refine-add-filters",children:"Add to filters"}),s.jsx("button",{onClick:()=>y(H(x)),disabled:b,className:"btn-secondary text-xs disabled:opacity-40 disabled:cursor-not-allowed","data-testid":"refine-search-all",children:"Search everywhere"}),s.jsxs("button",{onClick:()=>y(H(x,n)),disabled:b,className:"btn-primary text-xs disabled:opacity-40 disabled:cursor-not-allowed","data-testid":"refine-filter-role",children:["Filter ",n]})]})]})})}function V(t){return t.status==="pending"?R(t)?"bg-status-claimed-graphic":"bg-status-active":at[t.status]??"bg-status-active"}function gt(t){const[,e]=j.useState(0);j.useEffect(()=>{if(!t)return;const n=window.setInterval(()=>e(r=>r+1),6e4);return()=>window.clearInterval(n)},[t])}function yt(t){var e;return[...t["x-lt-columns"]??[],...((e=t["x-lt-card"])==null?void 0:e.fields)??[]].some(n=>n.format==="age")}function _(t){const e=n=>{if(!n)return null;try{const r=JSON.parse(n);return r&&typeof r=="object"?r:null}catch{return null}};return{escalation:t,metadata:t.metadata??null,envelope:e(t.envelope),payload:e(t.escalation_payload),resolver:e(t.resolver_payload)}}const vt=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/,D="—";function C({raw:t,format:e}){if(!t||t===D)return s.jsx("span",{className:"text-text-quaternary",children:D});if(e==="age"){const n=new Date(t);if(!Number.isNaN(n.getTime()))return s.jsx("span",{title:n.toLocaleString(),className:"tabular-nums whitespace-nowrap",children:tt(t)})}return vt.test(t)?s.jsx(W,{date:t,format:"datetime",className:"text-text-primary"}):s.jsx(s.Fragment,{children:t})}const jt=30;function wt(t){return t.status==="pending"&&!R(t)}function $({row:t,def:e,onView:n,prominent:r,forceView:a}){const o=(e==null?void 0:e.action)??"claim",i=a?"view":o,c=o===i&&(e!=null&&e.label)?e.label:i==="claim"?"Claim":"View",l=et(),d=I(),h=ct(),[f,x]=j.useState(""),b=i==="claim"&&!wt(t),y=u=>{if(u.stopPropagation(),i==="view"){n==null||n();return}if(e!=null&&e.submitOnClaim){d(`/escalations/detail/${t.id}`,{state:{autoStart:!0,durationMinutes:e==null?void 0:e.durationMinutes,from:h.pathname}});return}x(""),l.mutate({id:t.id,durationMinutes:(e==null?void 0:e.durationMinutes)??jt},{onSuccess:()=>n==null?void 0:n(),onError:p=>x(p.message)})},m=r?"btn-primary text-xs shrink-0 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-accent":"px-2 py-0.5 rounded text-2xs font-medium text-accent/70 border border-accent/30 enabled:hover:text-accent enabled:hover:border-accent/60 enabled:hover:bg-accent/5 transition-colors disabled:opacity-50 disabled:cursor-not-allowed whitespace-nowrap";return s.jsxs("span",{className:"inline-flex flex-col items-end gap-0.5",children:[s.jsx("button",{type:"button",onClick:y,disabled:l.isPending||b,title:b?t.status==="pending"?"claimed":t.status:void 0,className:m,"data-testid":"row-action-button",children:l.isPending?"Claiming…":c}),f&&s.jsx("span",{className:"text-2xs text-status-error","data-testid":"row-action-error",children:f})]})}function Nt({esc:t,card:e,rowAction:n,onOpen:r,forceView:a}){const o=_(t),i=e.title?v(e.title,o):t.type;return s.jsxs("div",{children:[s.jsxs("div",{className:"flex items-start justify-between gap-6",children:[s.jsxs("button",{onClick:r,className:"text-left group min-w-0",children:[s.jsx("h3",{className:"heading-2 group-hover:text-accent transition-colors leading-tight",children:i}),e.subtitle&&s.jsx("p",{className:"text-xs text-text-tertiary mt-1.5",children:v(e.subtitle,o)})]}),s.jsx($,{row:t,def:n,onView:r,prominent:!0,forceView:a})]}),e.fields&&e.fields.length>0&&s.jsx("dl",{className:"flex flex-wrap gap-x-10 gap-y-4 mt-6",children:e.fields.map((c,l)=>s.jsxs("div",{children:[s.jsx("dt",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary",children:c.label}),s.jsx("dd",{className:"text-xs text-text-primary mt-1",children:s.jsx(C,{raw:v(c.value,o)})})]},l))}),e.body&&s.jsx("div",{className:"mt-7 pt-6 border-t border-surface-border/50",children:s.jsx(O,{content:v(e.body,o)})})]})}function kt({role:t,def:e,onRowClick:n}){var d,h;const[r,a]=j.useState(!1),o=Q({role:t,status:e.status??"resolved",sort_by:"resolved_at",order:"desc",limit:e.limit??25,enabled:r,include:bt(e)?"envelope":void 0}),i=((d=o.data)==null?void 0:d.escalations)??[],c=((h=o.data)==null?void 0:h.total)??0,l=e.row??{};return r?o.isLoading?s.jsx("p",{className:"text-xs text-text-tertiary italic",children:"Loading history…"}):i.length===0?s.jsx("p",{className:"text-xs text-text-tertiary italic",children:"No past revisions."}):s.jsxs("div",{children:[s.jsx("div",{className:"divide-y divide-surface-border/40",children:i.map(f=>{const x=_(f);return s.jsxs("button",{onClick:()=>n==null?void 0:n(f),className:"w-full text-left py-2.5 group flex items-center gap-3",children:[s.jsx("span",{className:`w-2.5 h-2.5 shrink-0 rounded-full dot-ring ${V(f)}`,title:f.status}),s.jsxs("span",{className:"min-w-0 flex-1",children:[s.jsx("span",{className:"block text-xs text-text-primary group-hover:text-accent transition-colors truncate",children:l.title?v(l.title,x):f.type}),l.subtitle&&s.jsx("span",{className:"block text-2xs text-text-tertiary truncate",children:v(l.subtitle,x)})]}),l.meta?s.jsx("span",{className:"text-2xs text-text-tertiary shrink-0",children:v(l.meta,x)}):f.resolved_at&&s.jsx(W,{date:f.resolved_at,format:"relative",className:"text-2xs text-text-tertiary shrink-0 whitespace-nowrap"})]},f.id)})}),c>i.length&&s.jsxs("p",{className:"text-2xs text-text-quaternary mt-3",children:["Showing ",i.length," of ",c,"."]})]}):s.jsx("button",{onClick:()=>a(!0),className:"text-xs text-accent hover:underline","data-testid":"load-history",children:"Load full history →"})}function q(t,e){var a,o;const n=[],r=new Set;for(const i of e){const c=(a=i.value.match(B))==null?void 0:a[1];if(!c||r.has(c))continue;const l=(o=t.metadata)==null?void 0:o[c];l==null||l===""||(r.add(c),n.push({key:c,label:i.label,value:l}))}return n}function z({onOpen:t,className:e=""}){return s.jsx("button",{type:"button",onClick:n=>{n.stopPropagation(),t()},className:`p-1.5 rounded text-text-quaternary/70 hover:text-accent hover:bg-surface-hover transition-colors ${e}`,title:"Refine — filter or search by this row's values","aria-label":"Refine — filter or search by this row's values","data-testid":"row-refine",children:s.jsx(lt,{className:"w-3.5 h-3.5",strokeWidth:1.5})})}function Tt({schema:t,rows:e,role:n,onRowClick:r,onAddFacet:a,forceView:o}){const i=I(),c=t["x-lt-columns"]??[],l=t["x-lt-row-action"],[d,h]=j.useState(null),f=[{key:"_status",label:"",priority:1,className:"w-10",render:x=>s.jsx("span",{className:`w-2.5 h-2.5 inline-block rounded-full dot-ring ${V(x)}`,title:x.status})},...c.map((x,b)=>({key:`col-${b}`,label:x.label,priority:x.priority??(b===0?1:2),width:x.width??(b===0&&!c.some(y=>y.width)?"40%":void 0),render:y=>{const m=_(y),u=v(x.value,m);return s.jsx("span",{className:"block truncate",title:u&&u!==D?u:void 0,children:s.jsx(C,{raw:u,format:x.format})})}})),{key:"_refine",label:"",priority:1,className:"w-9",render:x=>q(x,c).length>0?s.jsx(z,{onOpen:()=>h(x)}):null},{key:"_action",label:"",priority:1,className:"w-44 text-right whitespace-nowrap",render:x=>s.jsx($,{row:x,def:l,onView:()=>r==null?void 0:r(x),forceView:o})}];return s.jsxs(s.Fragment,{children:[s.jsx(Z,{columns:f,data:e,layout:"fixed",keyFn:x=>x.id,onRowClick:r,emptyMessage:"No pending items."}),s.jsx(Y,{open:!!d,onClose:()=>h(null),role:n,pairs:d?q(d,c):[],onNavigate:i,onAddFacet:a})]})}function P({children:t}){return s.jsx("p",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-3",children:t})}function St(t,e){var o;const n=e.indexOf("."),r=e.startsWith("metadata.")?e.slice(9):null,a=new Map;for(const i of t){const c=_(i);let l;try{l=n===-1?c[e]:L(c[e.slice(0,n)],e.slice(n+1))}catch{l=void 0}if(l==null||l==="")continue;const d=String(l),h=r?((o=i.metadata)==null?void 0:o[r])??l:l,f=a.get(d);f?(f.count+=1,new Date(i.created_at)>new Date(f.latest.created_at)&&(f.latest=i)):a.set(d,{key:d,rawValue:h,latest:i,count:1})}return[...a.values()].sort((i,c)=>i.key.localeCompare(c.key))}const B=/^\{\{\s*metadata\.([a-zA-Z0-9_]+)\s*\}\}$/;function _t({schema:t,rows:e,role:n,onOpenDetail:r,onOpenGroup:a,onAddFacet:o,forceView:i}){const c=I(),l=t["x-lt-group-by"],d=t["x-lt-card"]??{},h=t["x-lt-row-action"],[f,x]=j.useState(null);if(!l)return s.jsx("p",{className:"text-xs text-text-tertiary italic",children:"facet-board needs an x-lt-group-by path."});const b=l.startsWith("metadata.")?l.slice(9):null,y=St(e,l);if(y.length===0)return s.jsx("p",{className:"text-xs text-text-tertiary italic",children:"No entities in scope."});const m=u=>{var w,T;const p=[];b&&p.push({key:b,label:b,value:u.rawValue});const k=new Set(p.map(S=>S.key));for(const S of d.fields??[]){const N=(w=S.value.match(B))==null?void 0:w[1];if(!N||k.has(N))continue;const g=(T=u.latest.metadata)==null?void 0:T[N];g==null||g===""||(k.add(N),p.push({key:N,label:S.label,value:g}))}return p};return s.jsxs("div",{className:"grid grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] gap-4","data-testid":"facet-board",children:[y.map(u=>{const p=_(u.latest),k=d.title?v(d.title,p):u.key,w=d.state?v(d.state,p):u.latest.subtype||u.latest.status,T=ht(w),S=m(u).length>0,N=g=>{if(g.shiftKey&&b&&o){o(b,u.rawValue);return}r==null||r(u.latest)};return s.jsxs("div",{role:"button",tabIndex:0,onClick:N,onKeyDown:g=>{(g.key==="Enter"||g.key===" ")&&(g.preventDefault(),N(g))},title:b?"Open the latest item · ⇧ click to filter the board":"Open the latest item",className:"group/card border-l-2 border-accent/30 bg-surface-sunken/40 rounded-[0.125em] px-4 py-3.5 cursor-pointer transition-colors hover:bg-surface-sunken/70 focus:outline-none focus-visible:ring-1 focus-visible:ring-accent/40","data-testid":"facet-board-card",children:[s.jsxs("div",{className:"flex items-center justify-between gap-2 mb-2.5",children:[s.jsx("span",{className:"text-2xs font-semibold uppercase tracking-wider text-text-secondary truncate",children:k}),s.jsxs("span",{className:"flex items-center gap-1 shrink-0",children:[s.jsx("span",{className:"px-1.5 py-0.5 rounded text-2xs font-mono font-medium",style:{color:T.text,backgroundColor:T.bg},title:w,children:w}),S&&s.jsx(z,{onOpen:()=>x(u),className:"-my-1 -mr-1"})]})]}),d.fields&&d.fields.length>0&&s.jsx("dl",{className:"space-y-1",children:d.fields.map((g,X)=>{const E=v(g.value,p);return s.jsxs("div",{className:"flex items-baseline justify-between gap-3",children:[s.jsx("dt",{className:"text-2xs uppercase tracking-wider text-text-quaternary shrink-0",children:g.label}),s.jsx("dd",{className:"min-w-0 truncate text-2xs text-text-primary",title:E&&E!==D?E:void 0,children:s.jsx(C,{raw:E,format:g.format})})]},X)})}),s.jsx("div",{className:"mt-3 flex justify-end",children:s.jsx($,{row:u.latest,def:h,onView:()=>r==null?void 0:r(u.latest),forceView:i})})]},u.key)}),s.jsx(Y,{open:!!f,onClose:()=>x(null),role:n,pairs:f?m(f):[],onNavigate:a??c,onAddFacet:o})]})}function Pt({role:t,listSchema:e,activeEscalations:n,onRowClick:r,onOpenGroup:a,onAddFacet:o,forceViewAction:i,total:c,page:l,totalPages:d,pageSize:h,onPageChange:f,onPageSizeChange:x}){const b=e["x-lt-layout"],y=e["x-lt-active"]??{},m=e["x-lt-row-action"],u=n[0],p=e["x-lt-help"];gt(yt(e));const k=s.jsxs("div",{className:"border border-surface-border/60 bg-surface-sunken rounded-[0.25em] p-4",children:[s.jsx(P,{children:"Active"}),u?s.jsx(Nt,{esc:u,card:y,rowAction:m,onOpen:()=>r==null?void 0:r(u),forceView:i}):s.jsx("p",{className:"text-xs text-text-tertiary italic",children:"No active item right now."})]}),w=p&&u?s.jsx("div",{className:"mb-8",children:s.jsx(O,{content:v(p,_(u))})}):p?s.jsx("div",{className:"mb-8",children:s.jsx(O,{content:p})}):null;if(b==="facet-table"){const T=c??n.length;return s.jsxs("div",{children:[s.jsx(Tt,{schema:e,rows:n,role:t,onRowClick:r,onAddFacet:o,forceView:i}),l!==void 0&&d!==void 0&&f&&s.jsx(F,{page:l,totalPages:d,onPageChange:f,total:T,pageSize:h??25,onPageSizeChange:x})]})}return b==="facet-board"?s.jsxs("div",{children:[w,s.jsx(_t,{schema:e,rows:n,role:t,onOpenDetail:r,onOpenGroup:a,onAddFacet:o,forceView:i}),l!==void 0&&d!==void 0&&f&&d>1&&s.jsx(F,{page:l,totalPages:d,onPageChange:f,total:c??n.length,pageSize:h??25,onPageSizeChange:x})]}):b==="active-history"?s.jsxs("div",{children:[w,s.jsxs("div",{className:"grid grid-cols-1 @split:grid-cols-[1.6fr_1fr] gap-8 @split:gap-12 items-start",children:[k,s.jsxs("div",{className:"@split:pt-4",children:[s.jsx(P,{children:"History"}),s.jsx(kt,{role:t,def:e["x-lt-history"]??{},onRowClick:r})]})]})]}):s.jsxs("div",{children:[w,k]})}const M=[{maxMs:0,color:"text-status-error"},{maxMs:300*1e3,color:"text-status-error"},{maxMs:900*1e3,color:"text-status-warning"},{maxMs:1/0,color:"text-text-secondary"}];function Et(t){if(t<=0)return M[0].color;for(const e of M)if(t<e.maxMs)return e.color;return M[M.length-1].color}function Wt({until:t}){const[e,n]=j.useState(()=>new Date(t).getTime()-Date.now());j.useEffect(()=>{const a=setInterval(()=>{n(new Date(t).getTime()-Date.now())},1e3);return()=>clearInterval(a)},[t]);const r=j.useMemo(()=>{const a=new Date(t);return[{label:"ms",value:String(Math.max(0,e))},{label:"until",value:a.toISOString()},{label:"local",value:st(a,"MMM d, yyyy h:mm:ss a")}]},[t,e]);return s.jsx(nt,{options:r,children:s.jsx("span",{className:`text-xs font-mono ${Et(e)}`,children:rt(e)})})}export{Wt as C,Pt as E,xt as H,qt as a,Kt as b,v as c,Ut as d,Ft as e,L as g,R as i,Ht as m,_ as r,bt as s};
2
- //# sourceMappingURL=CountdownTimer-DVL7WIcE.js.map
1
+ import{a as j,j as s}from"./vendor-query-RUZdMvN6.js";import{D as Z}from"./DataTable-DFPMeqyQ.js";import{a8 as H,$ as O,T as Q,b as W,X as tt,i as et,a9 as st,aa as nt,ab as rt}from"./index-zrTQcPjB.js";import{a as at}from"./StatusBadge-BDeUwPtb.js";import{S as F}from"./StickyPagination-Bc_Mzu_R.js";import{M as it}from"./Modal-BU7No9NH.js";import{a8 as ot,aj as lt}from"./vendor-icons-h-jlRSb9.js";import{u as I,a as ct}from"./vendor-react-CdqEC2zv.js";const dt=new Set(["__proto__","constructor","prototype"]);function G(t){const e=[];for(const n of t.split(".")){const r=n.match(/^([^[\]]*)((?:\[\d+\])*)$/);if(!r)throw new Error(`invalid x-lt-bind path segment: "${n}"`);const[,a,o]=r;if(a){if(dt.has(a))throw new Error(`x-lt-bind path may not target "${a}"`);e.push({key:a})}for(const i of o.match(/\d+/g)??[])e.push({index:Number(i)})}if(e.length===0)throw new Error(`empty x-lt-bind path: "${t}"`);return e}function ut(t,e,n){const r=G(e);let a=t;for(let i=0;i<r.length-1;i++){const c=r[i],l=r[i+1],d="key"in c?c.key:c.index,h="index"in l;(a[d]==null||typeof a[d]!="object")&&(a[d]=h?[]:{}),a=a[d]}const o=r[r.length-1];a["key"in o?o.key:o.index]=n}function L(t,e){let n=t;for(const r of G(e)){if(n==null||typeof n!="object")return;n=n["key"in r?r.key:r.index]}return n}function J(t,e){const n=e==null?void 0:e["x-lt-bind"];return typeof n=="string"&&n.length>0?n:t}function Ht(t,e){const n=e==null?void 0:e.properties;if(!n)return{...t};const r={};for(const[a,o]of Object.entries(n))a in t&&ut(r,J(a,o),t[a]);return r}function Ft(t,e){const n=e==null?void 0:e.properties;if(!n)return t?{...t}:{};const r={};for(const[a,o]of Object.entries(n)){const i=L(t,J(a,o));i!==void 0&&(r[a]=i)}return r}const xt=["escalation","metadata","envelope","payload","resolver","lookup"],ft=/\{\{\s*([^{}]+?)\s*\}\}/g,A="—";function K(t){if(t==null)return A;if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return String(t);try{return JSON.stringify(t)}catch{return A}}function v(t,e){return t.replace(ft,(n,r)=>{const a=r.indexOf("."),o=a===-1?r:r.slice(0,a);if(!xt.includes(o))return A;const i=e[o];if(a===-1)return K(i);try{return K(L(i,r.slice(a+1)))}catch{return A}})}function mt(t){const e=t==null?void 0:t["x-lt-help"];if(typeof e=="string"&&e.trim().length>0)return e;const n=t==null?void 0:t["x-lt-context"];return typeof n=="string"&&n.trim().length>0?n:null}function Kt(t,e){const n=mt(t);return n?v(n,e):null}function Ut({isTerminal:t,status:e,claimed:n,claimedByMe:r}){return t?e==="cancelled"?"This escalation was cancelled. The record is shown for reference.":"This escalation has been resolved. The submitted form is shown for reference.":r?"You have claimed this escalation. Fill out the form and submit to resolve it.":n?"Another user has claimed this escalation. It unlocks if their claim expires or is released.":"Claim this escalation to enable the form."}function bt(t){if(!t)return!1;try{const e=JSON.stringify(t);return e.includes("envelope.")||e.includes("payload.")}catch{return!1}}function R(t){return!!(t.assigned_to&&t.assigned_until&&new Date(t.assigned_until)>new Date)}function qt(t){return!t.workflow_type}const U=[{text:"text-rose-400",bg:"bg-rose-400/[0.08]"},{text:"text-pink-400",bg:"bg-pink-400/[0.08]"},{text:"text-fuchsia-400",bg:"bg-fuchsia-400/[0.08]"},{text:"text-purple-400",bg:"bg-purple-400/[0.08]"},{text:"text-violet-400",bg:"bg-violet-400/[0.08]"},{text:"text-indigo-400",bg:"bg-indigo-400/[0.08]"},{text:"text-blue-400",bg:"bg-blue-400/[0.08]"},{text:"text-sky-400",bg:"bg-sky-400/[0.08]"},{text:"text-cyan-400",bg:"bg-cyan-400/[0.08]"},{text:"text-teal-400",bg:"bg-teal-400/[0.08]"},{text:"text-emerald-400",bg:"bg-emerald-400/[0.08]"},{text:"text-green-400",bg:"bg-green-400/[0.08]"},{text:"text-lime-400",bg:"bg-lime-400/[0.08]"},{text:"text-yellow-400",bg:"bg-yellow-400/[0.08]"},{text:"text-amber-400",bg:"bg-amber-400/[0.08]"},{text:"text-orange-400",bg:"bg-orange-400/[0.08]"},{text:"text-red-400",bg:"bg-red-400/[0.08]"},{text:"text-stone-400",bg:"bg-stone-400/[0.08]"},{text:"text-rose-300",bg:"bg-rose-300/[0.08]"},{text:"text-violet-300",bg:"bg-violet-300/[0.08]"},{text:"text-sky-300",bg:"bg-sky-300/[0.08]"},{text:"text-teal-300",bg:"bg-teal-300/[0.08]"},{text:"text-amber-300",bg:"bg-amber-300/[0.08]"},{text:"text-pink-300",bg:"bg-pink-300/[0.08]"}];function pt(t){let e=0;for(let n=0;n<t.length;n++)e=(e<<5)-e+t.charCodeAt(n)|0;return Math.abs(e)}function ht(t){return U[pt(t)%U.length]}function Y({open:t,onClose:e,role:n,pairs:r,onNavigate:a,onAddFacet:o}){const[i,c]=j.useState(new Set),[l,d]=j.useState(t);t!==l&&(d(t),t&&c(new Set(r.length===1?[r[0].key]:[])));const h=m=>{c(u=>{const p=new Set(u);return p.has(m)?p.delete(m):p.add(m),p})},f=r.filter(m=>i.has(m.key)),x=Object.fromEntries(f.map(m=>[m.key,m.value])),b=f.length===0,y=m=>{e(),a(m)};return s.jsx(it,{open:t,onClose:e,title:"Refine",children:s.jsxs("div",{className:"space-y-4",children:[s.jsx("p",{className:"text-2xs text-text-tertiary",children:"Pick the facts to match — several combine into one narrower query."}),s.jsx("div",{className:"divide-y divide-surface-border/40 -mx-1",children:r.map(m=>{const u=i.has(m.key);return s.jsxs("button",{type:"button",onClick:()=>h(m.key),"aria-pressed":u,className:"w-full flex items-center gap-3 px-1 py-2.5 text-left group min-w-0","data-testid":"refine-pair",children:[s.jsx("span",{className:`w-4 h-4 rounded-[3px] border flex items-center justify-center shrink-0 transition-colors ${u?"bg-accent border-accent":"border-surface-border group-hover:border-accent/50"}`,"aria-hidden":!0,children:u&&s.jsx(ot,{className:"w-3 h-3 text-text-inverse",strokeWidth:3})}),s.jsx("span",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary w-28 shrink-0 truncate",title:m.key,children:m.label}),s.jsx("span",{className:"text-xs text-text-primary truncate flex-1 min-w-0",title:String(m.value),children:String(m.value)})]},m.key)})}),s.jsxs("div",{className:"flex items-center justify-end gap-3 pt-2 flex-wrap",children:[o&&s.jsx("button",{onClick:()=>{f.forEach(m=>o(m.key,m.value)),e()},disabled:b,className:"text-xs text-text-secondary hover:text-accent transition-colors disabled:opacity-40 disabled:cursor-not-allowed mr-auto","data-testid":"refine-add-filters",children:"Add to filters"}),s.jsx("button",{onClick:()=>y(H(x)),disabled:b,className:"btn-secondary text-xs disabled:opacity-40 disabled:cursor-not-allowed","data-testid":"refine-search-all",children:"Search everywhere"}),s.jsxs("button",{onClick:()=>y(H(x,n)),disabled:b,className:"btn-primary text-xs disabled:opacity-40 disabled:cursor-not-allowed","data-testid":"refine-filter-role",children:["Filter ",n]})]})]})})}function V(t){return t.status==="pending"?R(t)?"bg-status-claimed-graphic":"bg-status-active":at[t.status]??"bg-status-active"}function gt(t){const[,e]=j.useState(0);j.useEffect(()=>{if(!t)return;const n=window.setInterval(()=>e(r=>r+1),6e4);return()=>window.clearInterval(n)},[t])}function yt(t){var e;return[...t["x-lt-columns"]??[],...((e=t["x-lt-card"])==null?void 0:e.fields)??[]].some(n=>n.format==="age")}function _(t){const e=n=>{if(!n)return null;try{const r=JSON.parse(n);return r&&typeof r=="object"?r:null}catch{return null}};return{escalation:t,metadata:t.metadata??null,envelope:e(t.envelope),payload:e(t.escalation_payload),resolver:e(t.resolver_payload)}}const vt=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/,D="—";function C({raw:t,format:e}){if(!t||t===D)return s.jsx("span",{className:"text-text-quaternary",children:D});if(e==="age"){const n=new Date(t);if(!Number.isNaN(n.getTime()))return s.jsx("span",{title:n.toLocaleString(),className:"tabular-nums whitespace-nowrap",children:tt(t)})}return vt.test(t)?s.jsx(W,{date:t,format:"datetime",className:"text-text-primary"}):s.jsx(s.Fragment,{children:t})}const jt=30;function wt(t){return t.status==="pending"&&!R(t)}function $({row:t,def:e,onView:n,prominent:r,forceView:a}){const o=(e==null?void 0:e.action)??"claim",i=a?"view":o,c=o===i&&(e!=null&&e.label)?e.label:i==="claim"?"Claim":"View",l=et(),d=I(),h=ct(),[f,x]=j.useState(""),b=i==="claim"&&!wt(t),y=u=>{if(u.stopPropagation(),i==="view"){n==null||n();return}if(e!=null&&e.submitOnClaim){d(`/escalations/detail/${t.id}`,{state:{autoStart:!0,durationMinutes:e==null?void 0:e.durationMinutes,from:h.pathname}});return}x(""),l.mutate({id:t.id,durationMinutes:(e==null?void 0:e.durationMinutes)??jt},{onSuccess:()=>n==null?void 0:n(),onError:p=>x(p.message)})},m=r?"btn-primary text-xs shrink-0 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-accent":"px-2 py-0.5 rounded text-2xs font-medium text-accent/70 border border-accent/30 enabled:hover:text-accent enabled:hover:border-accent/60 enabled:hover:bg-accent/5 transition-colors disabled:opacity-50 disabled:cursor-not-allowed whitespace-nowrap";return s.jsxs("span",{className:"inline-flex flex-col items-end gap-0.5",children:[s.jsx("button",{type:"button",onClick:y,disabled:l.isPending||b,title:b?t.status==="pending"?"claimed":t.status:void 0,className:m,"data-testid":"row-action-button",children:l.isPending?"Claiming…":c}),f&&s.jsx("span",{className:"text-2xs text-status-error","data-testid":"row-action-error",children:f})]})}function Nt({esc:t,card:e,rowAction:n,onOpen:r,forceView:a}){const o=_(t),i=e.title?v(e.title,o):t.type;return s.jsxs("div",{children:[s.jsxs("div",{className:"flex items-start justify-between gap-6",children:[s.jsxs("button",{onClick:r,className:"text-left group min-w-0",children:[s.jsx("h3",{className:"heading-2 group-hover:text-accent transition-colors leading-tight",children:i}),e.subtitle&&s.jsx("p",{className:"text-xs text-text-tertiary mt-1.5",children:v(e.subtitle,o)})]}),s.jsx($,{row:t,def:n,onView:r,prominent:!0,forceView:a})]}),e.fields&&e.fields.length>0&&s.jsx("dl",{className:"flex flex-wrap gap-x-10 gap-y-4 mt-6",children:e.fields.map((c,l)=>s.jsxs("div",{children:[s.jsx("dt",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary",children:c.label}),s.jsx("dd",{className:"text-xs text-text-primary mt-1",children:s.jsx(C,{raw:v(c.value,o)})})]},l))}),e.body&&s.jsx("div",{className:"mt-7 pt-6 border-t border-surface-border/50",children:s.jsx(O,{content:v(e.body,o)})})]})}function kt({role:t,def:e,onRowClick:n}){var d,h;const[r,a]=j.useState(!1),o=Q({role:t,status:e.status??"resolved",sort_by:"resolved_at",order:"desc",limit:e.limit??25,enabled:r,include:bt(e)?"envelope":void 0}),i=((d=o.data)==null?void 0:d.escalations)??[],c=((h=o.data)==null?void 0:h.total)??0,l=e.row??{};return r?o.isLoading?s.jsx("p",{className:"text-xs text-text-tertiary italic",children:"Loading history…"}):i.length===0?s.jsx("p",{className:"text-xs text-text-tertiary italic",children:"No past revisions."}):s.jsxs("div",{children:[s.jsx("div",{className:"divide-y divide-surface-border/40",children:i.map(f=>{const x=_(f);return s.jsxs("button",{onClick:()=>n==null?void 0:n(f),className:"w-full text-left py-2.5 group flex items-center gap-3",children:[s.jsx("span",{className:`w-2.5 h-2.5 shrink-0 rounded-full dot-ring ${V(f)}`,title:f.status}),s.jsxs("span",{className:"min-w-0 flex-1",children:[s.jsx("span",{className:"block text-xs text-text-primary group-hover:text-accent transition-colors truncate",children:l.title?v(l.title,x):f.type}),l.subtitle&&s.jsx("span",{className:"block text-2xs text-text-tertiary truncate",children:v(l.subtitle,x)})]}),l.meta?s.jsx("span",{className:"text-2xs text-text-tertiary shrink-0",children:v(l.meta,x)}):f.resolved_at&&s.jsx(W,{date:f.resolved_at,format:"relative",className:"text-2xs text-text-tertiary shrink-0 whitespace-nowrap"})]},f.id)})}),c>i.length&&s.jsxs("p",{className:"text-2xs text-text-quaternary mt-3",children:["Showing ",i.length," of ",c,"."]})]}):s.jsx("button",{onClick:()=>a(!0),className:"text-xs text-accent hover:underline","data-testid":"load-history",children:"Load full history →"})}function q(t,e){var a,o;const n=[],r=new Set;for(const i of e){const c=(a=i.value.match(B))==null?void 0:a[1];if(!c||r.has(c))continue;const l=(o=t.metadata)==null?void 0:o[c];l==null||l===""||(r.add(c),n.push({key:c,label:i.label,value:l}))}return n}function z({onOpen:t,className:e=""}){return s.jsx("button",{type:"button",onClick:n=>{n.stopPropagation(),t()},className:`p-1.5 rounded text-text-quaternary/70 hover:text-accent hover:bg-surface-hover transition-colors ${e}`,title:"Refine — filter or search by this row's values","aria-label":"Refine — filter or search by this row's values","data-testid":"row-refine",children:s.jsx(lt,{className:"w-3.5 h-3.5",strokeWidth:1.5})})}function Tt({schema:t,rows:e,role:n,onRowClick:r,onAddFacet:a,forceView:o}){const i=I(),c=t["x-lt-columns"]??[],l=t["x-lt-row-action"],[d,h]=j.useState(null),f=[{key:"_status",label:"",priority:1,className:"w-10",render:x=>s.jsx("span",{className:`w-2.5 h-2.5 inline-block rounded-full dot-ring ${V(x)}`,title:x.status})},...c.map((x,b)=>({key:`col-${b}`,label:x.label,priority:x.priority??(b===0?1:2),width:x.width??(b===0&&!c.some(y=>y.width)?"40%":void 0),render:y=>{const m=_(y),u=v(x.value,m);return s.jsx("span",{className:"block truncate",title:u&&u!==D?u:void 0,children:s.jsx(C,{raw:u,format:x.format})})}})),{key:"_refine",label:"",priority:1,className:"w-9",render:x=>q(x,c).length>0?s.jsx(z,{onOpen:()=>h(x)}):null},{key:"_action",label:"",priority:1,className:"w-44 text-right whitespace-nowrap",render:x=>s.jsx($,{row:x,def:l,onView:()=>r==null?void 0:r(x),forceView:o})}];return s.jsxs(s.Fragment,{children:[s.jsx(Z,{columns:f,data:e,layout:"fixed",keyFn:x=>x.id,onRowClick:r,emptyMessage:"No pending items."}),s.jsx(Y,{open:!!d,onClose:()=>h(null),role:n,pairs:d?q(d,c):[],onNavigate:i,onAddFacet:a})]})}function P({children:t}){return s.jsx("p",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-3",children:t})}function St(t,e){var o;const n=e.indexOf("."),r=e.startsWith("metadata.")?e.slice(9):null,a=new Map;for(const i of t){const c=_(i);let l;try{l=n===-1?c[e]:L(c[e.slice(0,n)],e.slice(n+1))}catch{l=void 0}if(l==null||l==="")continue;const d=String(l),h=r?((o=i.metadata)==null?void 0:o[r])??l:l,f=a.get(d);f?(f.count+=1,new Date(i.created_at)>new Date(f.latest.created_at)&&(f.latest=i)):a.set(d,{key:d,rawValue:h,latest:i,count:1})}return[...a.values()].sort((i,c)=>i.key.localeCompare(c.key))}const B=/^\{\{\s*metadata\.([a-zA-Z0-9_]+)\s*\}\}$/;function _t({schema:t,rows:e,role:n,onOpenDetail:r,onOpenGroup:a,onAddFacet:o,forceView:i}){const c=I(),l=t["x-lt-group-by"],d=t["x-lt-card"]??{},h=t["x-lt-row-action"],[f,x]=j.useState(null);if(!l)return s.jsx("p",{className:"text-xs text-text-tertiary italic",children:"facet-board needs an x-lt-group-by path."});const b=l.startsWith("metadata.")?l.slice(9):null,y=St(e,l);if(y.length===0)return s.jsx("p",{className:"text-xs text-text-tertiary italic",children:"No entities in scope."});const m=u=>{var w,T;const p=[];b&&p.push({key:b,label:b,value:u.rawValue});const k=new Set(p.map(S=>S.key));for(const S of d.fields??[]){const N=(w=S.value.match(B))==null?void 0:w[1];if(!N||k.has(N))continue;const g=(T=u.latest.metadata)==null?void 0:T[N];g==null||g===""||(k.add(N),p.push({key:N,label:S.label,value:g}))}return p};return s.jsxs("div",{className:"grid grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] gap-4","data-testid":"facet-board",children:[y.map(u=>{const p=_(u.latest),k=d.title?v(d.title,p):u.key,w=d.state?v(d.state,p):u.latest.subtype||u.latest.status,T=ht(w),S=m(u).length>0,N=g=>{if(g.shiftKey&&b&&o){o(b,u.rawValue);return}r==null||r(u.latest)};return s.jsxs("div",{role:"button",tabIndex:0,onClick:N,onKeyDown:g=>{(g.key==="Enter"||g.key===" ")&&(g.preventDefault(),N(g))},title:b?"Open the latest item · ⇧ click to filter the board":"Open the latest item",className:"group/card border-l-2 border-accent/30 bg-surface-sunken/40 rounded-[0.125em] px-4 py-3.5 cursor-pointer transition-colors hover:bg-surface-sunken/70 focus:outline-none focus-visible:ring-1 focus-visible:ring-accent/40","data-testid":"facet-board-card",children:[s.jsxs("div",{className:"flex items-center justify-between gap-2 mb-2.5",children:[s.jsx("span",{className:"text-2xs font-semibold uppercase tracking-wider text-text-secondary truncate",children:k}),s.jsxs("span",{className:"flex items-center gap-1 shrink-0",children:[s.jsx("span",{className:"px-1.5 py-0.5 rounded text-2xs font-mono font-medium",style:{color:T.text,backgroundColor:T.bg},title:w,children:w}),S&&s.jsx(z,{onOpen:()=>x(u),className:"-my-1 -mr-1"})]})]}),d.fields&&d.fields.length>0&&s.jsx("dl",{className:"space-y-1",children:d.fields.map((g,X)=>{const E=v(g.value,p);return s.jsxs("div",{className:"flex items-baseline justify-between gap-3",children:[s.jsx("dt",{className:"text-2xs uppercase tracking-wider text-text-quaternary shrink-0",children:g.label}),s.jsx("dd",{className:"min-w-0 truncate text-2xs text-text-primary",title:E&&E!==D?E:void 0,children:s.jsx(C,{raw:E,format:g.format})})]},X)})}),s.jsx("div",{className:"mt-3 flex justify-end",children:s.jsx($,{row:u.latest,def:h,onView:()=>r==null?void 0:r(u.latest),forceView:i})})]},u.key)}),s.jsx(Y,{open:!!f,onClose:()=>x(null),role:n,pairs:f?m(f):[],onNavigate:a??c,onAddFacet:o})]})}function Pt({role:t,listSchema:e,activeEscalations:n,onRowClick:r,onOpenGroup:a,onAddFacet:o,forceViewAction:i,total:c,page:l,totalPages:d,pageSize:h,onPageChange:f,onPageSizeChange:x}){const b=e["x-lt-layout"],y=e["x-lt-active"]??{},m=e["x-lt-row-action"],u=n[0],p=e["x-lt-help"];gt(yt(e));const k=s.jsxs("div",{className:"border border-surface-border/60 bg-surface-sunken rounded-[0.25em] p-4",children:[s.jsx(P,{children:"Active"}),u?s.jsx(Nt,{esc:u,card:y,rowAction:m,onOpen:()=>r==null?void 0:r(u),forceView:i}):s.jsx("p",{className:"text-xs text-text-tertiary italic",children:"No active item right now."})]}),w=p&&u?s.jsx("div",{className:"mb-8",children:s.jsx(O,{content:v(p,_(u))})}):p?s.jsx("div",{className:"mb-8",children:s.jsx(O,{content:p})}):null;if(b==="facet-table"){const T=c??n.length;return s.jsxs("div",{children:[s.jsx(Tt,{schema:e,rows:n,role:t,onRowClick:r,onAddFacet:o,forceView:i}),l!==void 0&&d!==void 0&&f&&s.jsx(F,{page:l,totalPages:d,onPageChange:f,total:T,pageSize:h??25,onPageSizeChange:x})]})}return b==="facet-board"?s.jsxs("div",{children:[w,s.jsx(_t,{schema:e,rows:n,role:t,onOpenDetail:r,onOpenGroup:a,onAddFacet:o,forceView:i}),l!==void 0&&d!==void 0&&f&&d>1&&s.jsx(F,{page:l,totalPages:d,onPageChange:f,total:c??n.length,pageSize:h??25,onPageSizeChange:x})]}):b==="active-history"?s.jsxs("div",{children:[w,s.jsxs("div",{className:"grid grid-cols-1 @split:grid-cols-[1.6fr_1fr] gap-8 @split:gap-12 items-start",children:[k,s.jsxs("div",{className:"@split:pt-4",children:[s.jsx(P,{children:"History"}),s.jsx(kt,{role:t,def:e["x-lt-history"]??{},onRowClick:r})]})]})]}):s.jsxs("div",{children:[w,k]})}const M=[{maxMs:0,color:"text-status-error"},{maxMs:300*1e3,color:"text-status-error"},{maxMs:900*1e3,color:"text-status-warning"},{maxMs:1/0,color:"text-text-secondary"}];function Et(t){if(t<=0)return M[0].color;for(const e of M)if(t<e.maxMs)return e.color;return M[M.length-1].color}function Wt({until:t}){const[e,n]=j.useState(()=>new Date(t).getTime()-Date.now());j.useEffect(()=>{const a=setInterval(()=>{n(new Date(t).getTime()-Date.now())},1e3);return()=>clearInterval(a)},[t]);const r=j.useMemo(()=>{const a=new Date(t);return[{label:"ms",value:String(Math.max(0,e))},{label:"until",value:a.toISOString()},{label:"local",value:st(a,"MMM d, yyyy h:mm:ss a")}]},[t,e]);return s.jsx(nt,{options:r,children:s.jsx("span",{className:`text-xs font-mono ${Et(e)}`,children:rt(e)})})}export{Wt as C,Pt as E,xt as H,qt as a,Kt as b,v as c,Ut as d,Ft as e,L as g,R as i,Ht as m,_ as r,bt as s};
2
+ //# sourceMappingURL=CountdownTimer-Bx2XXJOd.js.map