@hotmeshio/long-tail 0.30.1 → 0.30.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 (201) hide show
  1. package/build/api/scan-codes/verb-fill.js +1 -1
  2. package/build/api/scan-codes/verb-into-subject.js +1 -1
  3. package/build/api/scan-codes/verbs-subject.js +2 -2
  4. package/dashboard/dist/assets/{AdminDashboard-CZIeiLe0.js → AdminDashboard-NVtdLI4I.js} +2 -2
  5. package/dashboard/dist/assets/{AdminDashboard-CZIeiLe0.js.map → AdminDashboard-NVtdLI4I.js.map} +1 -1
  6. package/dashboard/dist/assets/{AgentConfigPage-DO3ATfCU.js → AgentConfigPage-Db1Oi72V.js} +2 -2
  7. package/dashboard/dist/assets/{AgentConfigPage-DO3ATfCU.js.map → AgentConfigPage-Db1Oi72V.js.map} +1 -1
  8. package/dashboard/dist/assets/{AgentDetailPage-BWAlHQfB.js → AgentDetailPage-BF4mw1bD.js} +3 -3
  9. package/dashboard/dist/assets/{AgentDetailPage-BWAlHQfB.js.map → AgentDetailPage-BF4mw1bD.js.map} +1 -1
  10. package/dashboard/dist/assets/{AgentsPage-Cs4IKeec.js → AgentsPage-DmF0m3Ro.js} +2 -2
  11. package/dashboard/dist/assets/{AgentsPage-Cs4IKeec.js.map → AgentsPage-DmF0m3Ro.js.map} +1 -1
  12. package/dashboard/dist/assets/{AvailableEscalationsPage-CiRxaing.js → AvailableEscalationsPage-jy2WKDjr.js} +2 -2
  13. package/dashboard/dist/assets/{AvailableEscalationsPage-CiRxaing.js.map → AvailableEscalationsPage-jy2WKDjr.js.map} +1 -1
  14. package/dashboard/dist/assets/{BotPicker-DGLkc9PQ.js → BotPicker-HJtVHdNe.js} +2 -2
  15. package/dashboard/dist/assets/{BotPicker-DGLkc9PQ.js.map → BotPicker-HJtVHdNe.js.map} +1 -1
  16. package/dashboard/dist/assets/{BulkAssignModal-C4LV8s0y.js → BulkAssignModal-DsJJZ9X4.js} +2 -2
  17. package/dashboard/dist/assets/{BulkAssignModal-C4LV8s0y.js.map → BulkAssignModal-DsJJZ9X4.js.map} +1 -1
  18. package/dashboard/dist/assets/{CapabilitiesPage-BLMMV3-W.js → CapabilitiesPage-iCn7PxDP.js} +2 -2
  19. package/dashboard/dist/assets/{CapabilitiesPage-BLMMV3-W.js.map → CapabilitiesPage-iCn7PxDP.js.map} +1 -1
  20. package/dashboard/dist/assets/{CollapsibleSection-BAizcNCt.js → CollapsibleSection-DFfVr_Ut.js} +2 -2
  21. package/dashboard/dist/assets/{CollapsibleSection-BAizcNCt.js.map → CollapsibleSection-DFfVr_Ut.js.map} +1 -1
  22. package/dashboard/dist/assets/{ConfirmDeleteModal-DlNWHVxi.js → ConfirmDeleteModal-D6TwO-yT.js} +2 -2
  23. package/dashboard/dist/assets/{ConfirmDeleteModal-DlNWHVxi.js.map → ConfirmDeleteModal-D6TwO-yT.js.map} +1 -1
  24. package/dashboard/dist/assets/{ConnectedAppsPage-D94kx0v3.js → ConnectedAppsPage-BOD-tgY0.js} +2 -2
  25. package/dashboard/dist/assets/{ConnectedAppsPage-D94kx0v3.js.map → ConnectedAppsPage-BOD-tgY0.js.map} +1 -1
  26. package/dashboard/dist/assets/{CountdownTimer-CSdAwgwZ.js → CountdownTimer-u_o3OygV.js} +2 -2
  27. package/dashboard/dist/assets/{CountdownTimer-CSdAwgwZ.js.map → CountdownTimer-u_o3OygV.js.map} +1 -1
  28. package/dashboard/dist/assets/{CredentialsPage-pOyC1GfC.js → CredentialsPage-C3dnRsMh.js} +2 -2
  29. package/dashboard/dist/assets/{CredentialsPage-pOyC1GfC.js.map → CredentialsPage-C3dnRsMh.js.map} +1 -1
  30. package/dashboard/dist/assets/{CronLabel-BVlOOcyo.js → CronLabel-BFh5TCsB.js} +2 -2
  31. package/dashboard/dist/assets/{CronLabel-BVlOOcyo.js.map → CronLabel-BFh5TCsB.js.map} +1 -1
  32. package/dashboard/dist/assets/{ElapsedCell-Bnjp3onG.js → ElapsedCell-D0jYuFKh.js} +2 -2
  33. package/dashboard/dist/assets/{ElapsedCell-Bnjp3onG.js.map → ElapsedCell-D0jYuFKh.js.map} +1 -1
  34. package/dashboard/dist/assets/{EntityTimelinePanel-D6Z7YXuY.js → EntityTimelinePanel-Ch-BsRu8.js} +2 -2
  35. package/dashboard/dist/assets/{EntityTimelinePanel-D6Z7YXuY.js.map → EntityTimelinePanel-Ch-BsRu8.js.map} +1 -1
  36. package/dashboard/dist/assets/{EscalationListSchemaPage-D2aa_arC.js → EscalationListSchemaPage-DuSLiInU.js} +2 -2
  37. package/dashboard/dist/assets/{EscalationListSchemaPage-D2aa_arC.js.map → EscalationListSchemaPage-DuSLiInU.js.map} +1 -1
  38. package/dashboard/dist/assets/{EscalationSchemaPage-DuOje0Ke.js → EscalationSchemaPage-D_mYri6e.js} +2 -2
  39. package/dashboard/dist/assets/{EscalationSchemaPage-DuOje0Ke.js.map → EscalationSchemaPage-D_mYri6e.js.map} +1 -1
  40. package/dashboard/dist/assets/{EscalationTimeline-DFkhU2Z2.js → EscalationTimeline-DiN8ImWF.js} +2 -2
  41. package/dashboard/dist/assets/{EscalationTimeline-DFkhU2Z2.js.map → EscalationTimeline-DiN8ImWF.js.map} +1 -1
  42. package/dashboard/dist/assets/{EscalationTitleSelect-CgYnMM_O.js → EscalationTitleSelect-36tkc2TE.js} +2 -2
  43. package/dashboard/dist/assets/{EscalationTitleSelect-CgYnMM_O.js.map → EscalationTitleSelect-36tkc2TE.js.map} +1 -1
  44. package/dashboard/dist/assets/{EscalationsOverview-BTkFoklS.js → EscalationsOverview-yHY6JKiV.js} +2 -2
  45. package/dashboard/dist/assets/{EscalationsOverview-BTkFoklS.js.map → EscalationsOverview-yHY6JKiV.js.map} +1 -1
  46. package/dashboard/dist/assets/{EventTable-MJmAbu6N.js → EventTable-DTtu2iM_.js} +2 -2
  47. package/dashboard/dist/assets/{EventTable-MJmAbu6N.js.map → EventTable-DTtu2iM_.js.map} +1 -1
  48. package/dashboard/dist/assets/{FilterBar-Blt7qcUc.js → FilterBar-ByZiD0ty.js} +2 -2
  49. package/dashboard/dist/assets/{FilterBar-Blt7qcUc.js.map → FilterBar-ByZiD0ty.js.map} +1 -1
  50. package/dashboard/dist/assets/{GraphInvokePage-B4K3mT_c.js → GraphInvokePage-Cbn6igr_.js} +2 -2
  51. package/dashboard/dist/assets/{GraphInvokePage-B4K3mT_c.js.map → GraphInvokePage-Cbn6igr_.js.map} +1 -1
  52. package/dashboard/dist/assets/{HomePage-BN5wXq6V.js → HomePage-CtLKm_S4.js} +2 -2
  53. package/dashboard/dist/assets/{HomePage-BN5wXq6V.js.map → HomePage-CtLKm_S4.js.map} +1 -1
  54. package/dashboard/dist/assets/{LinePage-CuHHHwBy.js → LinePage-Q5Cgjd3N.js} +3 -3
  55. package/dashboard/dist/assets/{LinePage-CuHHHwBy.js.map → LinePage-Q5Cgjd3N.js.map} +1 -1
  56. package/dashboard/dist/assets/{LinesPage-D9TRHWyt.js → LinesPage-BX3d-rj0.js} +2 -2
  57. package/dashboard/dist/assets/{LinesPage-D9TRHWyt.js.map → LinesPage-BX3d-rj0.js.map} +1 -1
  58. package/dashboard/dist/assets/{ListToolbar-GGj6X36p.js → ListToolbar-bj2sgAK4.js} +2 -2
  59. package/dashboard/dist/assets/{ListToolbar-GGj6X36p.js.map → ListToolbar-bj2sgAK4.js.map} +1 -1
  60. package/dashboard/dist/assets/{McpOverview-Do31A1jL.js → McpOverview-BD3UWbcC.js} +2 -2
  61. package/dashboard/dist/assets/{McpOverview-Do31A1jL.js.map → McpOverview-BD3UWbcC.js.map} +1 -1
  62. package/dashboard/dist/assets/{McpQueryDetailPage-D6FSB1bS.js → McpQueryDetailPage-ISzY-BfT.js} +2 -2
  63. package/dashboard/dist/assets/{McpQueryDetailPage-D6FSB1bS.js.map → McpQueryDetailPage-ISzY-BfT.js.map} +1 -1
  64. package/dashboard/dist/assets/{McpQueryPage-CyT2d0Y_.js → McpQueryPage-t555QJ3m.js} +2 -2
  65. package/dashboard/dist/assets/{McpQueryPage-CyT2d0Y_.js.map → McpQueryPage-t555QJ3m.js.map} +1 -1
  66. package/dashboard/dist/assets/{McpRunDetailPage-C3mmTl4Y.js → McpRunDetailPage-C4jozQFh.js} +2 -2
  67. package/dashboard/dist/assets/{McpRunDetailPage-C3mmTl4Y.js.map → McpRunDetailPage-C4jozQFh.js.map} +1 -1
  68. package/dashboard/dist/assets/{McpRunsPage-CTeFFUE2.js → McpRunsPage-Z-mtyRBp.js} +2 -2
  69. package/dashboard/dist/assets/{McpRunsPage-CTeFFUE2.js.map → McpRunsPage-Z-mtyRBp.js.map} +1 -1
  70. package/dashboard/dist/assets/{OperationsPage-BUtQP5dm.js → OperationsPage-ClYilVyZ.js} +2 -2
  71. package/dashboard/dist/assets/{OperationsPage-BUtQP5dm.js.map → OperationsPage-ClYilVyZ.js.map} +1 -1
  72. package/dashboard/dist/assets/{OperatorDashboard-BwYOXyUV.js → OperatorDashboard-3Hi2IiHi.js} +2 -2
  73. package/dashboard/dist/assets/{OperatorDashboard-BwYOXyUV.js.map → OperatorDashboard-3Hi2IiHi.js.map} +1 -1
  74. package/dashboard/dist/assets/{PersonaDetailPage-CkrKJLNv.js → PersonaDetailPage-xb7O3tn9.js} +2 -2
  75. package/dashboard/dist/assets/{PersonaDetailPage-CkrKJLNv.js.map → PersonaDetailPage-xb7O3tn9.js.map} +1 -1
  76. package/dashboard/dist/assets/{PersonasPage-BS8aBeOv.js → PersonasPage-uCYVhRBB.js} +2 -2
  77. package/dashboard/dist/assets/{PersonasPage-BS8aBeOv.js.map → PersonasPage-uCYVhRBB.js.map} +1 -1
  78. package/dashboard/dist/assets/{PortalPage-PEBk6VVu.js → PortalPage-D1MOMJ9Q.js} +2 -2
  79. package/dashboard/dist/assets/{PortalPage-PEBk6VVu.js.map → PortalPage-D1MOMJ9Q.js.map} +1 -1
  80. package/dashboard/dist/assets/{ProcessDetailPage-CJ71bxDs.js → ProcessDetailPage-Tf8FQCUm.js} +2 -2
  81. package/dashboard/dist/assets/{ProcessDetailPage-CJ71bxDs.js.map → ProcessDetailPage-Tf8FQCUm.js.map} +1 -1
  82. package/dashboard/dist/assets/{ProcessesListPage-ov_HLxz5.js → ProcessesListPage-DPLRgznC.js} +2 -2
  83. package/dashboard/dist/assets/{ProcessesListPage-ov_HLxz5.js.map → ProcessesListPage-DPLRgznC.js.map} +1 -1
  84. package/dashboard/dist/assets/{ResolverForm-BKiUY-lN.js → ResolverForm-BXqJEPte.js} +2 -2
  85. package/dashboard/dist/assets/{ResolverForm-BKiUY-lN.js.map → ResolverForm-BXqJEPte.js.map} +1 -1
  86. package/dashboard/dist/assets/{RoleDetailPage-CmfWwjtG.js → RoleDetailPage-KJnZGPPY.js} +2 -2
  87. package/dashboard/dist/assets/{RoleDetailPage-CmfWwjtG.js.map → RoleDetailPage-KJnZGPPY.js.map} +1 -1
  88. package/dashboard/dist/assets/{RolesPage-DvO5DJWY.js → RolesPage-C5f-3zcs.js} +2 -2
  89. package/dashboard/dist/assets/{RolesPage-DvO5DJWY.js.map → RolesPage-C5f-3zcs.js.map} +1 -1
  90. package/dashboard/dist/assets/{RosterWidget-Cs6OTbST.js → RosterWidget-WCtpUEzc.js} +2 -2
  91. package/dashboard/dist/assets/{RosterWidget-Cs6OTbST.js.map → RosterWidget-WCtpUEzc.js.map} +1 -1
  92. package/dashboard/dist/assets/{RunAsSelector-VNjUn9Zp.js → RunAsSelector-CzabsFYU.js} +2 -2
  93. package/dashboard/dist/assets/{RunAsSelector-VNjUn9Zp.js.map → RunAsSelector-CzabsFYU.js.map} +1 -1
  94. package/dashboard/dist/assets/{ScanCodesPage-Dbaud0fc.js → ScanCodesPage-D51d17HH.js} +2 -2
  95. package/dashboard/dist/assets/{ScanCodesPage-Dbaud0fc.js.map → ScanCodesPage-D51d17HH.js.map} +1 -1
  96. package/dashboard/dist/assets/{ScanSchemeDetailPage-BfDw_Eke.js → ScanSchemeDetailPage-CUK6Skxj.js} +2 -2
  97. package/dashboard/dist/assets/{ScanSchemeDetailPage-BfDw_Eke.js.map → ScanSchemeDetailPage-CUK6Skxj.js.map} +1 -1
  98. package/dashboard/dist/assets/ScanStationPage-7vK0ddiV.js +2 -0
  99. package/dashboard/dist/assets/ScanStationPage-7vK0ddiV.js.map +1 -0
  100. package/dashboard/dist/assets/{StickyPagination-CJ3jjlDX.js → StickyPagination-C2fzclxr.js} +2 -2
  101. package/dashboard/dist/assets/{StickyPagination-CJ3jjlDX.js.map → StickyPagination-C2fzclxr.js.map} +1 -1
  102. package/dashboard/dist/assets/{StreamMessageDetail-yOdyJGHR.js → StreamMessageDetail-wF4NM8gi.js} +2 -2
  103. package/dashboard/dist/assets/{StreamMessageDetail-yOdyJGHR.js.map → StreamMessageDetail-wF4NM8gi.js.map} +1 -1
  104. package/dashboard/dist/assets/{SwimlaneTimeline-DeFWNFrL.js → SwimlaneTimeline-B4Hg97qO.js} +2 -2
  105. package/dashboard/dist/assets/{SwimlaneTimeline-DeFWNFrL.js.map → SwimlaneTimeline-B4Hg97qO.js.map} +1 -1
  106. package/dashboard/dist/assets/{TaskDetailPage-BPL_Zx-L.js → TaskDetailPage-DAxxcFDD.js} +2 -2
  107. package/dashboard/dist/assets/{TaskDetailPage-BPL_Zx-L.js.map → TaskDetailPage-DAxxcFDD.js.map} +1 -1
  108. package/dashboard/dist/assets/{TasksListPage-Bc3S63_O.js → TasksListPage-BmghuHbc.js} +2 -2
  109. package/dashboard/dist/assets/{TasksListPage-Bc3S63_O.js.map → TasksListPage-BmghuHbc.js.map} +1 -1
  110. package/dashboard/dist/assets/{TimeAgo-DAtnJQwU.js → TimeAgo-CFeB6U2O.js} +2 -2
  111. package/dashboard/dist/assets/{TimeAgo-DAtnJQwU.js.map → TimeAgo-CFeB6U2O.js.map} +1 -1
  112. package/dashboard/dist/assets/{TimestampCell-CG0erHqq.js → TimestampCell-M_FD9JEc.js} +2 -2
  113. package/dashboard/dist/assets/{TimestampCell-CG0erHqq.js.map → TimestampCell-M_FD9JEc.js.map} +1 -1
  114. package/dashboard/dist/assets/{ToolTestPanel-c71yqZv7.js → ToolTestPanel-D7PihZG9.js} +2 -2
  115. package/dashboard/dist/assets/{ToolTestPanel-c71yqZv7.js.map → ToolTestPanel-D7PihZG9.js.map} +1 -1
  116. package/dashboard/dist/assets/{TopicDetailPage-BlUP0bb1.js → TopicDetailPage-T0dLt7Ao.js} +2 -2
  117. package/dashboard/dist/assets/{TopicDetailPage-BlUP0bb1.js.map → TopicDetailPage-T0dLt7Ao.js.map} +1 -1
  118. package/dashboard/dist/assets/{TopicsPage-lQ9HNzOq.js → TopicsPage-DP5ox5oX.js} +2 -2
  119. package/dashboard/dist/assets/{TopicsPage-lQ9HNzOq.js.map → TopicsPage-DP5ox5oX.js.map} +1 -1
  120. package/dashboard/dist/assets/{UserName-Vf97ofcW.js → UserName-ET3r3u-A.js} +2 -2
  121. package/dashboard/dist/assets/{UserName-Vf97ofcW.js.map → UserName-ET3r3u-A.js.map} +1 -1
  122. package/dashboard/dist/assets/{WorkflowExecutionPage-B195cnHb.js → WorkflowExecutionPage-DBq2lZ_C.js} +2 -2
  123. package/dashboard/dist/assets/{WorkflowExecutionPage-B195cnHb.js.map → WorkflowExecutionPage-DBq2lZ_C.js.map} +1 -1
  124. package/dashboard/dist/assets/{WorkflowsDashboard-gH-PGsKq.js → WorkflowsDashboard-WO4cH8sU.js} +2 -2
  125. package/dashboard/dist/assets/{WorkflowsDashboard-gH-PGsKq.js.map → WorkflowsDashboard-WO4cH8sU.js.map} +1 -1
  126. package/dashboard/dist/assets/{WorkflowsOverview-D_wYDqw3.js → WorkflowsOverview-CJfg0rQH.js} +2 -2
  127. package/dashboard/dist/assets/{WorkflowsOverview-D_wYDqw3.js.map → WorkflowsOverview-CJfg0rQH.js.map} +1 -1
  128. package/dashboard/dist/assets/{YamlWorkflowDetailPage-Imob5F8H.js → YamlWorkflowDetailPage-C8rkvYCp.js} +2 -2
  129. package/dashboard/dist/assets/{YamlWorkflowDetailPage-Imob5F8H.js.map → YamlWorkflowDetailPage-C8rkvYCp.js.map} +1 -1
  130. package/dashboard/dist/assets/{YamlWorkflowsPage-DVEVSKKJ.js → YamlWorkflowsPage-DHQ4ZVzM.js} +2 -2
  131. package/dashboard/dist/assets/{YamlWorkflowsPage-DVEVSKKJ.js.map → YamlWorkflowsPage-DHQ4ZVzM.js.map} +1 -1
  132. package/dashboard/dist/assets/{agents-B-8z_DV8.js → agents-zulmHig2.js} +2 -2
  133. package/dashboard/dist/assets/{agents-B-8z_DV8.js.map → agents-zulmHig2.js.map} +1 -1
  134. package/dashboard/dist/assets/{bots-Clm-wZeG.js → bots-D4mtcPHB.js} +2 -2
  135. package/dashboard/dist/assets/{bots-Clm-wZeG.js.map → bots-D4mtcPHB.js.map} +1 -1
  136. package/dashboard/dist/assets/{capabilities-CBwgv5tr.js → capabilities-rFZDH0zF.js} +2 -2
  137. package/dashboard/dist/assets/{capabilities-CBwgv5tr.js.map → capabilities-rFZDH0zF.js.map} +1 -1
  138. package/dashboard/dist/assets/{controlplane-B96o1-zT.js → controlplane-INfcW_9F.js} +2 -2
  139. package/dashboard/dist/assets/{controlplane-B96o1-zT.js.map → controlplane-INfcW_9F.js.map} +1 -1
  140. package/dashboard/dist/assets/{escalation-columns-CFoFILF1.js → escalation-columns-8ker-czW.js} +2 -2
  141. package/dashboard/dist/assets/{escalation-columns-CFoFILF1.js.map → escalation-columns-8ker-czW.js.map} +1 -1
  142. package/dashboard/dist/assets/{escalation-items-BCUiPsfS.js → escalation-items-B6eDMoTN.js} +2 -2
  143. package/dashboard/dist/assets/{escalation-items-BCUiPsfS.js.map → escalation-items-B6eDMoTN.js.map} +1 -1
  144. package/dashboard/dist/assets/{index-B_z-OFwk.js → index-0LXkjZjt.js} +2 -2
  145. package/dashboard/dist/assets/{index-B_z-OFwk.js.map → index-0LXkjZjt.js.map} +1 -1
  146. package/dashboard/dist/assets/{index-BXKDpLk5.js → index-5XUBZtlv.js} +2 -2
  147. package/dashboard/dist/assets/{index-BXKDpLk5.js.map → index-5XUBZtlv.js.map} +1 -1
  148. package/dashboard/dist/assets/{index-CnhNCVPc.js → index-BcVkiaCv.js} +2 -2
  149. package/dashboard/dist/assets/{index-CnhNCVPc.js.map → index-BcVkiaCv.js.map} +1 -1
  150. package/dashboard/dist/assets/{index-EZkdUZwM.js → index-BpJ77OST.js} +2 -2
  151. package/dashboard/dist/assets/{index-EZkdUZwM.js.map → index-BpJ77OST.js.map} +1 -1
  152. package/dashboard/dist/assets/{index-IedmSPp1.js → index-BpillEP7.js} +2 -2
  153. package/dashboard/dist/assets/{index-IedmSPp1.js.map → index-BpillEP7.js.map} +1 -1
  154. package/dashboard/dist/assets/{index-P22vmuEu.js → index-CV7KmPdF.js} +2 -2
  155. package/dashboard/dist/assets/{index-P22vmuEu.js.map → index-CV7KmPdF.js.map} +1 -1
  156. package/dashboard/dist/assets/{index-XS-6UjQd.js → index-Cfg4TFDb.js} +2 -2
  157. package/dashboard/dist/assets/{index-XS-6UjQd.js.map → index-Cfg4TFDb.js.map} +1 -1
  158. package/dashboard/dist/assets/{index-MGquOb7J.js → index-Cg9W61lM.js} +2 -2
  159. package/dashboard/dist/assets/{index-MGquOb7J.js.map → index-Cg9W61lM.js.map} +1 -1
  160. package/dashboard/dist/assets/{index-DvgjLvvn.js → index-ChF-l2z9.js} +2 -2
  161. package/dashboard/dist/assets/{index-DvgjLvvn.js.map → index-ChF-l2z9.js.map} +1 -1
  162. package/dashboard/dist/assets/{index-Czb9O4Ns.js → index-Cm6_Peh7.js} +2 -2
  163. package/dashboard/dist/assets/{index-Czb9O4Ns.js.map → index-Cm6_Peh7.js.map} +1 -1
  164. package/dashboard/dist/assets/{index-BOuGMe78.js → index-D-EVgGsm.js} +2 -2
  165. package/dashboard/dist/assets/{index-BOuGMe78.js.map → index-D-EVgGsm.js.map} +1 -1
  166. package/dashboard/dist/assets/{index-C1WJs6IZ.js → index-D-Fd0gQ_.js} +2 -2
  167. package/dashboard/dist/assets/{index-C1WJs6IZ.js.map → index-D-Fd0gQ_.js.map} +1 -1
  168. package/dashboard/dist/assets/{index-CXNh7LuG.js → index-xycFf66M.js} +3 -3
  169. package/dashboard/dist/assets/{index-CXNh7LuG.js.map → index-xycFf66M.js.map} +1 -1
  170. package/dashboard/dist/assets/{knowledge-d92ncKgf.js → knowledge-_WaBsrbC.js} +2 -2
  171. package/dashboard/dist/assets/{knowledge-d92ncKgf.js.map → knowledge-_WaBsrbC.js.map} +1 -1
  172. package/dashboard/dist/assets/{machines-BG9laURp.js → machines-D6ig2Q8z.js} +2 -2
  173. package/dashboard/dist/assets/{machines-BG9laURp.js.map → machines-D6ig2Q8z.js.map} +1 -1
  174. package/dashboard/dist/assets/{mcp-CsZdpCEf.js → mcp-DtWRQM1G.js} +2 -2
  175. package/dashboard/dist/assets/{mcp-CsZdpCEf.js.map → mcp-DtWRQM1G.js.map} +1 -1
  176. package/dashboard/dist/assets/{mcp-query-o2xqrZJv.js → mcp-query-vQm92kTd.js} +2 -2
  177. package/dashboard/dist/assets/{mcp-query-o2xqrZJv.js.map → mcp-query-vQm92kTd.js.map} +1 -1
  178. package/dashboard/dist/assets/{personas-EYROtAxm.js → personas-BLxQpGNz.js} +2 -2
  179. package/dashboard/dist/assets/{personas-EYROtAxm.js.map → personas-BLxQpGNz.js.map} +1 -1
  180. package/dashboard/dist/assets/{pipelines-C17xZZsa.js → pipelines-ClmRtlkR.js} +2 -2
  181. package/dashboard/dist/assets/{pipelines-C17xZZsa.js.map → pipelines-ClmRtlkR.js.map} +1 -1
  182. package/dashboard/dist/assets/{tasks-CUppIhu6.js → tasks-CVZT1pf0.js} +2 -2
  183. package/dashboard/dist/assets/{tasks-CUppIhu6.js.map → tasks-CVZT1pf0.js.map} +1 -1
  184. package/dashboard/dist/assets/{topics-B-lCJzVc.js → topics-rkG9-6El.js} +2 -2
  185. package/dashboard/dist/assets/{topics-B-lCJzVc.js.map → topics-rkG9-6El.js.map} +1 -1
  186. package/dashboard/dist/assets/{useDebouncedValue-C5mMbYoU.js → useDebouncedValue-D2aCC74y.js} +2 -2
  187. package/dashboard/dist/assets/{useDebouncedValue-C5mMbYoU.js.map → useDebouncedValue-D2aCC74y.js.map} +1 -1
  188. package/dashboard/dist/assets/{useNamespace-Bu42ipvu.js → useNamespace-BGfkF4ej.js} +2 -2
  189. package/dashboard/dist/assets/{useNamespace-Bu42ipvu.js.map → useNamespace-BGfkF4ej.js.map} +1 -1
  190. package/dashboard/dist/assets/{useYamlActivityEvents-C29uM9Qp.js → useYamlActivityEvents-DOU0_nfZ.js} +2 -2
  191. package/dashboard/dist/assets/{useYamlActivityEvents-C29uM9Qp.js.map → useYamlActivityEvents-DOU0_nfZ.js.map} +1 -1
  192. package/dashboard/dist/assets/{validate-Bt5QGwSc.js → validate-bHZ917pZ.js} +2 -2
  193. package/dashboard/dist/assets/{validate-Bt5QGwSc.js.map → validate-bHZ917pZ.js.map} +1 -1
  194. package/dashboard/dist/assets/{yaml-workflows-DgrmL_Kt.js → yaml-workflows-S7qlgdg6.js} +2 -2
  195. package/dashboard/dist/assets/{yaml-workflows-DgrmL_Kt.js.map → yaml-workflows-S7qlgdg6.js.map} +1 -1
  196. package/dashboard/dist/index.html +1 -1
  197. package/docs/dashboard.md +1 -1
  198. package/docs/scan-codes.md +17 -5
  199. package/package.json +1 -1
  200. package/dashboard/dist/assets/ScanStationPage-DE-zJTiD.js +0 -2
  201. package/dashboard/dist/assets/ScanStationPage-DE-zJTiD.js.map +0 -1
@@ -1,3 +1,3 @@
1
- import{a as c,j as e}from"./vendor-query-DvWWuNIB.js";import{d as z,r as U,u as B,M as D,a as O,m as H,b as K}from"./machines-BG9laURp.js";import{D as P}from"./DataTable-FjFhx0SE.js";import{F as J,a as Q,b as T}from"./FilterBar-Blt7qcUc.js";import{S as V}from"./StickyPagination-CJ3jjlDX.js";import{P as X}from"./PageHeader-DiGWAQlR.js";import{ax as G,bi as W,O as Z,a_ as ee,j as R,b1 as te}from"./index-CXNh7LuG.js";import{u as se}from"./useDebouncedValue-C5mMbYoU.js";import{u as ne}from"./useFilterParams-DBRw1Hcv.js";import{X as ae,ac as ie,h as re}from"./vendor-icons-en0_uSRD.js";import{L as le,u as oe}from"./vendor-react-_9U4mKFr.js";import"./EmptyState-DgC_6njU.js";import"./useContainerWidth-DSLp1gEm.js";const ce={attention:"bg-status-warning",running:"bg-status-success-graphic",idle:"bg-text-quaternary"},de={attention:"needs attention",running:"running",idle:"idle"};function me(t){return t.health.attention?"attention":t.leading||t.health.handoff>0||t.health.command>0?"running":"idle"}const q=[{value:"attention",label:"Attention first"},{value:"site",label:"Site and line"},{value:"updated",label:"Recently changed"}];function ue(t){const i=new Map;for(const s of t){const n=i.get(s.siteId)??{siteId:s.siteId,lines:[],attention:0};n.lines.push(s),s.health.attention&&(n.attention+=1),i.set(s.siteId,n)}return[...i.values()]}const xe={siteId:"site-2",lineId:"line-1",machines:[{machineId:"print-01",process:"print",cycleSec:12},{machineId:"press-01",process:"bond",cycleSec:8},{machineId:"inspect-01",process:"inspect",cycleSec:5}]};function he(t){return`${JSON.stringify(t,null,2)}
1
+ import{a as c,j as e}from"./vendor-query-DvWWuNIB.js";import{d as z,r as U,u as B,M as D,a as O,m as H,b as K}from"./machines-D6ig2Q8z.js";import{D as P}from"./DataTable-FjFhx0SE.js";import{F as J,a as Q,b as T}from"./FilterBar-ByZiD0ty.js";import{S as V}from"./StickyPagination-C2fzclxr.js";import{P as X}from"./PageHeader-DiGWAQlR.js";import{ax as G,bi as W,O as Z,a_ as ee,j as R,b1 as te}from"./index-xycFf66M.js";import{u as se}from"./useDebouncedValue-D2aCC74y.js";import{u as ne}from"./useFilterParams-DBRw1Hcv.js";import{X as ae,ac as ie,h as re}from"./vendor-icons-en0_uSRD.js";import{L as le,u as oe}from"./vendor-react-_9U4mKFr.js";import"./EmptyState-DgC_6njU.js";import"./useContainerWidth-DSLp1gEm.js";const ce={attention:"bg-status-warning",running:"bg-status-success-graphic",idle:"bg-text-quaternary"},de={attention:"needs attention",running:"running",idle:"idle"};function me(t){return t.health.attention?"attention":t.leading||t.health.handoff>0||t.health.command>0?"running":"idle"}const q=[{value:"attention",label:"Attention first"},{value:"site",label:"Site and line"},{value:"updated",label:"Recently changed"}];function ue(t){const i=new Map;for(const s of t){const n=i.get(s.siteId)??{siteId:s.siteId,lines:[],attention:0};n.lines.push(s),s.health.attention&&(n.attention+=1),i.set(s.siteId,n)}return[...i.values()]}const xe={siteId:"site-2",lineId:"line-1",machines:[{machineId:"print-01",process:"print",cycleSec:12},{machineId:"press-01",process:"bond",cycleSec:8},{machineId:"inspect-01",process:"inspect",cycleSec:5}]};function he(t){return`${JSON.stringify(t,null,2)}
2
2
  `}function pe(t){return{siteId:t.siteId,lineId:t.lineId,machines:t.machines.map(i=>({machineId:i.machineId,process:i.process,...i.address?{address:i.address}:{}}))}}function fe(t){let i;try{i=JSON.parse(t)}catch(n){return{ok:!1,message:`The definition is not JSON: ${n.message}`}}if(!i||typeof i!="object"||Array.isArray(i))return{ok:!1,message:"The definition must be an object."};const s=i;if(typeof s.siteId!="string"||!s.siteId)return{ok:!1,message:"siteId is required."};if(typeof s.lineId!="string"||!s.lineId)return{ok:!1,message:"lineId is required."};if(!Array.isArray(s.machines)||s.machines.length===0)return{ok:!1,message:"machines must list at least one machine."};for(const n of s.machines)if(!n||typeof n!="object"||typeof n.machineId!="string"||typeof n.process!="string")return{ok:!1,message:"Every machine needs a machineId and a process."};return{ok:!0,definition:s}}const E="line-declare",ge=460;function ye({outcome:t}){return e.jsxs("div",{className:"min-w-0 space-y-1","data-testid":"declare-outcome",children:[e.jsx("div",{className:"text-xs font-mono text-text-secondary truncate",title:t.request,children:t.request}),e.jsx("div",{className:`text-xs font-medium ${t.ok?"text-status-success":"text-status-error"}`,children:t.message})]})}function _(t){return t instanceof G&&t.status===409?`Someone changed this line first: ${t.message}`:t.message}function be({initial:t,onClose:i,onDone:s}){const[n,N]=c.useState(()=>he(t?pe(t):xe)),[l,g]=c.useState(t?String(t.version):""),[o,u]=c.useState(!1),[x,p]=c.useState(!1),[j,r]=c.useState(null),S=async d=>{d.preventDefault();const m=fe(n);if(!m.ok){r({request:"definition",ok:!1,message:m.message});return}const{siteId:y,lineId:I}=m.definition,b=`PUT /machines/lines/${y}/${I}`;u(!0);try{const f=l.trim(),{line:h}=await z(y,I,{definition:m.definition,...f?{version:Number(f)}:{}});r({request:b,ok:!0,message:`declared · ${h.machines.length} machine${h.machines.length===1?"":"s"} · v${h.version}`}),s()}catch(f){r({request:b,ok:!1,message:_(f)})}finally{u(!1)}},v=async()=>{if(!t)return;const d=`DELETE /machines/lines/${t.siteId}/${t.lineId}`;u(!0);try{await U(t.siteId,t.lineId),r({request:d,ok:!0,message:"retired · its gateway stops on every replica"}),p(!1),s()}catch(m){r({request:d,ok:!1,message:_(m)})}finally{u(!1)}};return e.jsxs("div",{className:"h-full flex flex-col",children:[e.jsxs("div",{className:"flex items-start justify-between px-5 pt-5 pb-3 border-b border-surface-border/40",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"text-sm font-mono text-text-primary truncate",children:t?`${t.siteId} · ${t.lineId}`:"Declare a line"}),e.jsx("p",{className:"text-2xs text-text-tertiary mt-0.5",children:t?`${t.source} · v${t.version}`:"The registry keeps it; every replica starts its gateway."})]}),e.jsx("button",{onClick:i,className:"icon-link shrink-0 ml-2",title:"Close",children:e.jsx(ae,{className:"w-4 h-4"})})]}),e.jsxs("form",{onSubmit:S,className:"flex-1 overflow-y-auto px-5 py-4 space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{htmlFor:"line-definition",className:"text-2xs font-medium text-text-secondary uppercase tracking-wide",children:"Definition"}),e.jsx("textarea",{id:"line-definition",value:n,onChange:d=>N(d.target.value),spellCheck:!1,rows:16,className:"input w-full mt-1 font-mono text-2xs"}),e.jsx("p",{className:"text-2xs text-text-quaternary mt-1",children:"siteId, lineId and the machines in route order, each with a machineId and a process."})]}),t&&e.jsxs("div",{children:[e.jsx("label",{htmlFor:"line-version",className:"text-2xs font-medium text-text-secondary uppercase tracking-wide",children:"Version"}),e.jsx("input",{id:"line-version",value:l,onChange:d=>g(d.target.value),inputMode:"numeric",className:"input mt-1 font-mono text-2xs w-24"}),e.jsx("p",{className:"text-2xs text-text-quaternary mt-1",children:"The version you edited; a newer one on the server refuses the save."})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("button",{type:"submit",disabled:o,className:"btn-primary text-xs",children:t?"Save":"Declare"}),t&&!x&&e.jsx("button",{type:"button",disabled:o,onClick:()=>p(!0),className:"text-2xs text-status-error hover:underline",children:"Retire this line"})]}),t&&x&&e.jsxs("div",{className:"border-l-2 border-status-error pl-3 space-y-2","data-testid":"retire-confirm",children:[e.jsxs("p",{className:"text-xs text-text-secondary",children:["Retire ",t.siteId," · ",t.lineId,"? Its gateway stops on every replica. Rows and roles stay."]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("button",{type:"button",disabled:o,onClick:v,className:"text-xs font-medium text-status-error hover:underline",children:"Retire"}),e.jsx("button",{type:"button",disabled:o,onClick:()=>p(!1),className:"text-xs text-text-secondary hover:underline",children:"Keep"})]})]}),j&&e.jsx(ye,{outcome:j})]})]})}function F(t){return`/lines/${encodeURIComponent(t.siteId)}/${encodeURIComponent(t.lineId)}`}function $({value:t,tone:i,title:s}){return e.jsx("span",{className:`tabular-nums ${t>0?i??"text-text-primary":"text-text-quaternary"}`,title:s,children:t})}function Ie(t){const i=[{key:"line",label:"Line",priority:1,render:s=>{const n=me(s);return e.jsxs("span",{className:"flex items-center gap-2 min-w-0",children:[e.jsx("span",{className:`w-2.5 h-2.5 rounded-full dot-ring shrink-0 ${ce[n]}`,title:de[n]}),e.jsxs(le,{to:F(s),className:"text-xs font-mono text-accent hover:underline truncate",title:`${s.siteId} · ${s.lineId}`,children:[s.siteId," · ",s.lineId]})]})}},{key:"machines",label:"Machines",className:"w-28",render:s=>e.jsxs("span",{className:"text-2xs tabular-nums",children:[e.jsx("span",{className:"text-text-primary",children:s.health.machines}),s.health.offline>0&&e.jsxs("span",{className:"text-status-warning",children:[" · ",s.health.offline," offline"]}),s.health.quiet>0&&e.jsxs("span",{className:"text-status-warning",children:[" · ",s.health.quiet," quiet"]})]})},{key:"alarms",label:"Alarms",className:"w-16 text-right",render:s=>e.jsx($,{value:s.health.alarms,tone:"text-status-warning",title:"Active alarms"})},{key:"people",label:"People",className:"w-16 text-right",render:s=>e.jsx($,{value:s.health.people,tone:"text-status-warning",title:"Rows waiting on a person"})},{key:"inflight",label:"In flight",className:"w-20 text-right",render:s=>e.jsx($,{value:s.health.handoff+s.health.command,title:"Open handoff and command rows"})},{key:"led",label:"Led",className:"w-20",render:s=>e.jsx("span",{className:`text-2xs ${s.leading?"text-text-primary":"text-text-tertiary"}`,children:s.leading?"here":"elsewhere"})},{key:"chain",label:"Chain",showFrom:"wall",priority:3,render:s=>e.jsx("span",{className:"text-2xs font-mono text-text-tertiary truncate block",title:s.machines.map(n=>n.machineId).join(" → "),children:s.machines.map(n=>n.machineId).join(" → ")})},{key:"source",label:"Source",showFrom:"wall",className:"w-28",priority:3,render:s=>e.jsxs("span",{className:"text-2xs text-text-tertiary tabular-nums",title:`changed ${W(s.updatedAt)}`,children:[s.source," · v",s.version]})}];return t&&i.push({key:"manage",label:"",className:"w-10",priority:1,render:s=>e.jsx("button",{type:"button",onClick:n=>{n.stopPropagation(),t(s)},className:"icon-link",title:`Edit ${s.siteId} · ${s.lineId}`,"aria-label":`Edit ${s.siteId} · ${s.lineId}`,children:e.jsx(ie,{className:"w-3.5 h-3.5"})})}),i}const Ne=50,M="settings",A="true",je="attention",k={undeclared:"Lines appear here once the server declares them.",none:"No lines declared yet.",noMatch:"No line matches.",loading:"Loading lines…"};function ve(){const t=R("LIST"),i=c.useMemo(()=>[H(),K()],[]);te(i,()=>{t([[D],[O],[M]])})}function ke({group:t}){return e.jsxs("div",{className:"flex items-baseline gap-3 pt-5 pb-1.5","data-testid":"site-heading",children:[e.jsx("span",{className:"text-xs font-mono text-text-primary",children:t.siteId}),e.jsxs("span",{className:"text-2xs text-text-quaternary tabular-nums",children:[t.lines.length," line",t.lines.length===1?"":"s"]}),t.attention>0&&e.jsxs("span",{className:"text-2xs text-status-warning tabular-nums",children:[t.attention," need",t.attention===1?"s":""," attention"]})]})}function Re(){const t=oe(),{canAdminister:i}=Z(),s=i,n=ee(),N=R("LIST"),{filters:l,setFilter:g,pagination:o}=ne({filters:{q:"",site:"",attention:"",sort:""},pageSize:Ne}),u=se(l.q),x=l.attention===A,p=q.some(a=>a.value===l.sort)?l.sort:je,j=c.useMemo(()=>({q:u||void 0,site:l.site||void 0,attention:x||void 0,sort:p,limit:o.pageSize,offset:o.offset}),[u,l.site,x,p,o.pageSize,o.offset]),{data:r,isLoading:S,error:v}=B(j);ve();const d=c.useCallback(()=>{N([[D],[O],[M]])},[N]),m=c.useCallback(()=>n==null?void 0:n.closePanel(E),[n]),y=c.useCallback(a=>{n==null||n.setPanel(e.jsx(be,{initial:a,onClose:m,onDone:d}),{key:E,width:ge})},[n,m,d]);c.useEffect(()=>()=>n==null?void 0:n.closePanel(E),[n]);const I=c.useMemo(()=>Ie(s?a=>y(a):null),[s,y]),b=!u&&!l.site,f=c.useMemo(()=>b&&r?ue(r.lines):[],[b,r]),h=(r==null?void 0:r.total)??0,C=[l.q,l.site,l.attention].filter(Boolean).length,Y=r!=null&&r.declared?C>0?k.noMatch:k.none:k.undeclared,w=a=>t(F(a));return e.jsxs("div",{children:[e.jsx(X,{title:"Lines"}),e.jsxs(J,{activeFilterCount:C,actions:e.jsxs(e.Fragment,{children:[e.jsxs("span",{className:"text-2xs text-text-quaternary tabular-nums whitespace-nowrap",children:[h," line",h===1?"":"s"]}),s&&e.jsxs("button",{type:"button",onClick:()=>y(null),className:"inline-flex items-center gap-1 text-2xs icon-link whitespace-nowrap",children:[e.jsx(re,{className:"w-3 h-3"}),"Declare line"]})]}),children:[e.jsx(Q,{label:"Search",value:l.q,onChange:a=>g("q",a),placeholder:"site, line, machine, process, address"}),e.jsx(T,{label:"Site",value:l.site,onChange:a=>g("site",a),options:((r==null?void 0:r.sites)??[]).map(a=>({value:a.siteId,label:`${a.siteId} · ${a.lines} line${a.lines===1?"":"s"}`})),placeholder:"every site"}),e.jsx(T,{label:"Order",value:p,onChange:a=>g("sort",a),options:q,required:!0}),e.jsx("button",{type:"button","aria-pressed":x,onClick:()=>g("attention",x?"":A),className:`self-start px-2 py-1 text-2xs rounded border transition-colors whitespace-nowrap ${x?"border-status-warning text-status-warning":"border-surface-border text-text-secondary hover:text-text-primary"}`,children:"Needs attention"})]}),v&&e.jsx("p",{className:"text-2xs text-status-error mb-4",children:v.message}),S?e.jsx("p",{className:"text-2xs text-text-tertiary italic",children:k.loading}):b&&f.length>0?f.map(a=>e.jsxs("section",{"aria-label":a.siteId,children:[e.jsx(ke,{group:a}),e.jsx(P,{columns:I,data:a.lines,keyFn:L=>`${L.siteId}/${L.lineId}`,onRowClick:w,layout:"fixed",inline:!0})]},a.siteId)):e.jsx(P,{columns:I,data:(r==null?void 0:r.lines)??[],keyFn:a=>`${a.siteId}/${a.lineId}`,onRowClick:w,layout:"fixed",emptyMessage:Y}),e.jsx(V,{page:o.page,totalPages:o.totalPages(h),onPageChange:o.setPage,total:h,pageSize:o.pageSize,onPageSizeChange:o.setPageSize})]})}export{Re as LinesPage};
3
- //# sourceMappingURL=LinesPage-D9TRHWyt.js.map
3
+ //# sourceMappingURL=LinesPage-BX3d-rj0.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LinesPage-D9TRHWyt.js","sources":["../../src/pages/lines/line-index.ts","../../src/pages/lines/LineDeclarePanel.tsx","../../src/pages/lines/LineIndexColumns.tsx","../../src/pages/lines/LinesPage.tsx"],"sourcesContent":["import type { LineDefinition, LineIndexRow, LineSort } from '../../api/machines';\n\n/** The tone of a line at a glance: attention, running, or nothing led anywhere yet. */\nexport type LineTone = 'attention' | 'running' | 'idle';\n\nexport const LINE_TONE_DOT: Record<LineTone, string> = {\n attention: 'bg-status-warning',\n running: 'bg-status-success-graphic',\n idle: 'bg-text-quaternary',\n};\n\nexport const LINE_TONE_LABEL: Record<LineTone, string> = {\n attention: 'needs attention',\n running: 'running',\n idle: 'idle',\n};\n\n/** Attention wins; a line with work in flight or a leader is running; otherwise idle. */\nexport function lineTone(row: LineIndexRow): LineTone {\n if (row.health.attention) return 'attention';\n if (row.leading || row.health.handoff > 0 || row.health.command > 0) return 'running';\n return 'idle';\n}\n\nexport const SORT_OPTIONS: { value: LineSort; label: string }[] = [\n { value: 'attention', label: 'Attention first' },\n { value: 'site', label: 'Site and line' },\n { value: 'updated', label: 'Recently changed' },\n];\n\nexport interface SiteGroup {\n siteId: string;\n lines: LineIndexRow[];\n attention: number;\n}\n\n/** Rows grouped under their site, in the order the page delivered them. */\nexport function groupBySite(lines: LineIndexRow[]): SiteGroup[] {\n const groups = new Map<string, SiteGroup>();\n for (const line of lines) {\n const group = groups.get(line.siteId) ?? { siteId: line.siteId, lines: [], attention: 0 };\n group.lines.push(line);\n if (line.health.attention) group.attention += 1;\n groups.set(line.siteId, group);\n }\n return [...groups.values()];\n}\n\n/** The starting point for a new declaration: three stations, the fields a line needs. */\nexport const EXAMPLE_DEFINITION: LineDefinition = {\n siteId: 'site-2',\n lineId: 'line-1',\n machines: [\n { machineId: 'print-01', process: 'print', cycleSec: 12 },\n { machineId: 'press-01', process: 'bond', cycleSec: 8 },\n { machineId: 'inspect-01', process: 'inspect', cycleSec: 5 },\n ],\n};\n\n/** The definition the registry holds for a row, as text to edit. */\nexport function definitionText(def: LineDefinition): string {\n return `${JSON.stringify(def, null, 2)}\\n`;\n}\n\n/** A row carries its summary fields; the definition is what it declared. */\nexport function definitionOf(row: LineIndexRow): LineDefinition {\n return {\n siteId: row.siteId,\n lineId: row.lineId,\n machines: row.machines.map((m) => ({\n machineId: m.machineId,\n process: m.process,\n ...(m.address ? { address: m.address } : {}),\n })),\n };\n}\n\n/** Parse what was typed; a readable message names what is missing. */\nexport function parseDefinition(text: string): { ok: true; definition: LineDefinition } | { ok: false; message: string } {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch (err) {\n return { ok: false, message: `The definition is not JSON: ${(err as Error).message}` };\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return { ok: false, message: 'The definition must be an object.' };\n const def = parsed as Record<string, unknown>;\n if (typeof def.siteId !== 'string' || !def.siteId) return { ok: false, message: 'siteId is required.' };\n if (typeof def.lineId !== 'string' || !def.lineId) return { ok: false, message: 'lineId is required.' };\n if (!Array.isArray(def.machines) || def.machines.length === 0) return { ok: false, message: 'machines must list at least one machine.' };\n for (const m of def.machines) {\n if (!m || typeof m !== 'object' || typeof (m as { machineId?: unknown }).machineId !== 'string' || typeof (m as { process?: unknown }).process !== 'string') {\n return { ok: false, message: 'Every machine needs a machineId and a process.' };\n }\n }\n return { ok: true, definition: def as unknown as LineDefinition };\n}\n","import { useState, type FormEvent } from 'react';\nimport { X } from 'lucide-react';\nimport { ApiError } from '../../api/client';\nimport { declareLine, retireLine, type LineIndexRow } from '../../api/machines';\nimport { definitionOf, definitionText, EXAMPLE_DEFINITION, parseDefinition } from './line-index';\n\nexport const DECLARE_PANEL_KEY = 'line-declare';\nexport const DECLARE_PANEL_WIDTH = 460;\n\ntype Outcome =\n | { request: string; ok: true; message: string }\n | { request: string; ok: false; message: string };\n\nfunction OutcomeBody({ outcome }: { outcome: Outcome }) {\n return (\n <div className=\"min-w-0 space-y-1\" data-testid=\"declare-outcome\">\n <div className=\"text-xs font-mono text-text-secondary truncate\" title={outcome.request}>{outcome.request}</div>\n <div className={`text-xs font-medium ${outcome.ok ? 'text-status-success' : 'text-status-error'}`}>{outcome.message}</div>\n </div>\n );\n}\n\nfunction messageOf(err: unknown): string {\n if (err instanceof ApiError && err.status === 409) return `Someone changed this line first: ${err.message}`;\n return (err as Error).message;\n}\n\n/**\n * Declare a line to the registry, or edit and retire one already declared.\n * The definition is the JSON the server validates; a retire asks once more\n * before it goes.\n */\nexport function LineDeclarePanel({\n initial,\n onClose,\n onDone,\n}: {\n initial: LineIndexRow | null;\n onClose: () => void;\n onDone: () => void;\n}) {\n const [text, setText] = useState(() => definitionText(initial ? definitionOf(initial) : EXAMPLE_DEFINITION));\n const [version, setVersion] = useState(initial ? String(initial.version) : '');\n const [busy, setBusy] = useState(false);\n const [confirmRetire, setConfirmRetire] = useState(false);\n const [outcome, setOutcome] = useState<Outcome | null>(null);\n\n const submit = async (e: FormEvent) => {\n e.preventDefault();\n const parsed = parseDefinition(text);\n if (!parsed.ok) {\n setOutcome({ request: 'definition', ok: false, message: parsed.message });\n return;\n }\n const { siteId, lineId } = parsed.definition;\n const request = `PUT /machines/lines/${siteId}/${lineId}`;\n setBusy(true);\n try {\n const trimmed = version.trim();\n const { line } = await declareLine(siteId, lineId, {\n definition: parsed.definition,\n ...(trimmed ? { version: Number(trimmed) } : {}),\n });\n setOutcome({ request, ok: true, message: `declared · ${line.machines.length} machine${line.machines.length === 1 ? '' : 's'} · v${line.version}` });\n onDone();\n } catch (err) {\n setOutcome({ request, ok: false, message: messageOf(err) });\n } finally {\n setBusy(false);\n }\n };\n\n const retire = async () => {\n if (!initial) return;\n const request = `DELETE /machines/lines/${initial.siteId}/${initial.lineId}`;\n setBusy(true);\n try {\n await retireLine(initial.siteId, initial.lineId);\n setOutcome({ request, ok: true, message: 'retired · its gateway stops on every replica' });\n setConfirmRetire(false);\n onDone();\n } catch (err) {\n setOutcome({ request, ok: false, message: messageOf(err) });\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <div className=\"h-full flex flex-col\">\n <div className=\"flex items-start justify-between px-5 pt-5 pb-3 border-b border-surface-border/40\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-mono text-text-primary truncate\">{initial ? `${initial.siteId} · ${initial.lineId}` : 'Declare a line'}</p>\n <p className=\"text-2xs text-text-tertiary mt-0.5\">\n {initial ? `${initial.source} · v${initial.version}` : 'The registry keeps it; every replica starts its gateway.'}\n </p>\n </div>\n <button onClick={onClose} className=\"icon-link shrink-0 ml-2\" title=\"Close\">\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n\n <form onSubmit={submit} className=\"flex-1 overflow-y-auto px-5 py-4 space-y-4\">\n <div>\n <label htmlFor=\"line-definition\" className=\"text-2xs font-medium text-text-secondary uppercase tracking-wide\">Definition</label>\n <textarea\n id=\"line-definition\"\n value={text}\n onChange={(e) => setText(e.target.value)}\n spellCheck={false}\n rows={16}\n className=\"input w-full mt-1 font-mono text-2xs\"\n />\n <p className=\"text-2xs text-text-quaternary mt-1\">siteId, lineId and the machines in route order, each with a machineId and a process.</p>\n </div>\n {initial && (\n <div>\n <label htmlFor=\"line-version\" className=\"text-2xs font-medium text-text-secondary uppercase tracking-wide\">Version</label>\n <input\n id=\"line-version\"\n value={version}\n onChange={(e) => setVersion(e.target.value)}\n inputMode=\"numeric\"\n className=\"input mt-1 font-mono text-2xs w-24\"\n />\n <p className=\"text-2xs text-text-quaternary mt-1\">The version you edited; a newer one on the server refuses the save.</p>\n </div>\n )}\n <div className=\"flex items-center gap-3\">\n <button type=\"submit\" disabled={busy} className=\"btn-primary text-xs\">\n {initial ? 'Save' : 'Declare'}\n </button>\n {initial && !confirmRetire && (\n <button type=\"button\" disabled={busy} onClick={() => setConfirmRetire(true)} className=\"text-2xs text-status-error hover:underline\">\n Retire this line\n </button>\n )}\n </div>\n {initial && confirmRetire && (\n <div className=\"border-l-2 border-status-error pl-3 space-y-2\" data-testid=\"retire-confirm\">\n <p className=\"text-xs text-text-secondary\">\n Retire {initial.siteId} · {initial.lineId}? Its gateway stops on every replica. Rows and roles stay.\n </p>\n <div className=\"flex items-center gap-3\">\n <button type=\"button\" disabled={busy} onClick={retire} className=\"text-xs font-medium text-status-error hover:underline\">\n Retire\n </button>\n <button type=\"button\" disabled={busy} onClick={() => setConfirmRetire(false)} className=\"text-xs text-text-secondary hover:underline\">\n Keep\n </button>\n </div>\n </div>\n )}\n {outcome && <OutcomeBody outcome={outcome} />}\n </form>\n </div>\n );\n}\n","import { Link } from 'react-router-dom';\nimport { Pencil } from 'lucide-react';\nimport type { LineIndexRow } from '../../api/machines';\nimport type { Column } from '../../components/common/data/DataTable';\nimport { formatDateTime } from '../../lib/format';\nimport { LINE_TONE_DOT, LINE_TONE_LABEL, lineTone } from './line-index';\n\nexport function linePath(row: Pick<LineIndexRow, 'siteId' | 'lineId'>): string {\n return `/lines/${encodeURIComponent(row.siteId)}/${encodeURIComponent(row.lineId)}`;\n}\n\nfunction Count({ value, tone, title }: { value: number; tone?: string; title?: string }) {\n return (\n <span className={`tabular-nums ${value > 0 ? tone ?? 'text-text-primary' : 'text-text-quaternary'}`} title={title}>\n {value}\n </span>\n );\n}\n\n/** The index columns; `onEdit` adds the manage column for those who may declare. */\nexport function lineColumns(onEdit: ((row: LineIndexRow) => void) | null): Column<LineIndexRow>[] {\n const columns: Column<LineIndexRow>[] = [\n {\n key: 'line',\n label: 'Line',\n priority: 1,\n render: (row) => {\n const tone = lineTone(row);\n return (\n <span className=\"flex items-center gap-2 min-w-0\">\n <span className={`w-2.5 h-2.5 rounded-full dot-ring shrink-0 ${LINE_TONE_DOT[tone]}`} title={LINE_TONE_LABEL[tone]} />\n <Link to={linePath(row)} className=\"text-xs font-mono text-accent hover:underline truncate\" title={`${row.siteId} · ${row.lineId}`}>\n {row.siteId} · {row.lineId}\n </Link>\n </span>\n );\n },\n },\n {\n key: 'machines',\n label: 'Machines',\n className: 'w-28',\n render: (row) => (\n <span className=\"text-2xs tabular-nums\">\n <span className=\"text-text-primary\">{row.health.machines}</span>\n {row.health.offline > 0 && <span className=\"text-status-warning\"> · {row.health.offline} offline</span>}\n {row.health.quiet > 0 && <span className=\"text-status-warning\"> · {row.health.quiet} quiet</span>}\n </span>\n ),\n },\n {\n key: 'alarms',\n label: 'Alarms',\n className: 'w-16 text-right',\n render: (row) => <Count value={row.health.alarms} tone=\"text-status-warning\" title=\"Active alarms\" />,\n },\n {\n key: 'people',\n label: 'People',\n className: 'w-16 text-right',\n render: (row) => <Count value={row.health.people} tone=\"text-status-warning\" title=\"Rows waiting on a person\" />,\n },\n {\n key: 'inflight',\n label: 'In flight',\n className: 'w-20 text-right',\n render: (row) => <Count value={row.health.handoff + row.health.command} title=\"Open handoff and command rows\" />,\n },\n {\n key: 'led',\n label: 'Led',\n className: 'w-20',\n render: (row) => (\n <span className={`text-2xs ${row.leading ? 'text-text-primary' : 'text-text-tertiary'}`}>{row.leading ? 'here' : 'elsewhere'}</span>\n ),\n },\n {\n key: 'chain',\n label: 'Chain',\n showFrom: 'wall',\n priority: 3,\n render: (row) => (\n <span className=\"text-2xs font-mono text-text-tertiary truncate block\" title={row.machines.map((m) => m.machineId).join(' → ')}>\n {row.machines.map((m) => m.machineId).join(' → ')}\n </span>\n ),\n },\n {\n key: 'source',\n label: 'Source',\n showFrom: 'wall',\n className: 'w-28',\n priority: 3,\n render: (row) => (\n <span className=\"text-2xs text-text-tertiary tabular-nums\" title={`changed ${formatDateTime(row.updatedAt)}`}>\n {row.source} · v{row.version}\n </span>\n ),\n },\n ];\n if (onEdit) {\n columns.push({\n key: 'manage',\n label: '',\n className: 'w-10',\n priority: 1,\n render: (row) => (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onEdit(row);\n }}\n className=\"icon-link\"\n title={`Edit ${row.siteId} · ${row.lineId}`}\n aria-label={`Edit ${row.siteId} · ${row.lineId}`}\n >\n <Pencil className=\"w-3.5 h-3.5\" />\n </button>\n ),\n });\n }\n return columns;\n}\n","import { useCallback, useEffect, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Plus } from 'lucide-react';\nimport {\n MACHINE_LINE_INDEX_QUERY_KEY,\n MACHINE_LINES_QUERY_KEY,\n machineLinePattern,\n machineLogPattern,\n useLineIndex,\n type LineIndexRow,\n type LineSort,\n} from '../../api/machines';\nimport { DataTable } from '../../components/common/data/DataTable';\nimport { FilterBar, FilterInput, FilterSelect } from '../../components/common/data/FilterBar';\nimport { StickyPagination } from '../../components/common/data/StickyPagination';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { useAccess } from '../../hooks/useAccess';\nimport { useDebouncedValue } from '../../hooks/useDebouncedValue';\nimport { useEventSubscriptions } from '../../hooks/useEventContext';\nimport { useThrottledInvalidation } from '../../hooks/useEventHooks';\nimport { useFilterParams } from '../../hooks/useFilterParams';\nimport { useShellPanelOptional } from '../../hooks/useShellPanel';\nimport { LineDeclarePanel, DECLARE_PANEL_KEY, DECLARE_PANEL_WIDTH } from './LineDeclarePanel';\nimport { lineColumns, linePath } from './LineIndexColumns';\nimport { groupBySite, SORT_OPTIONS, type SiteGroup } from './line-index';\n\nconst PAGE_SIZE = 50;\nconst SETTINGS_QUERY_KEY = 'settings';\nconst ATTENTION_ON = 'true';\nconst DEFAULT_SORT: LineSort = 'attention';\n\nconst COPY = {\n undeclared: 'Lines appear here once the server declares them.',\n none: 'No lines declared yet.',\n noMatch: 'No line matches.',\n loading: 'Loading lines…',\n} as const;\n\n/** The index refreshes through the LIST tier when a line is declared or retired, or a gateway logs. */\nfunction useIndexRefresh() {\n const invalidate = useThrottledInvalidation('LIST');\n const patterns = useMemo(() => [machineLinePattern(), machineLogPattern()], []);\n useEventSubscriptions(patterns, () => {\n invalidate([[MACHINE_LINE_INDEX_QUERY_KEY], [MACHINE_LINES_QUERY_KEY], [SETTINGS_QUERY_KEY]]);\n });\n}\n\nfunction SiteHeading({ group }: { group: SiteGroup }) {\n return (\n <div className=\"flex items-baseline gap-3 pt-5 pb-1.5\" data-testid=\"site-heading\">\n <span className=\"text-xs font-mono text-text-primary\">{group.siteId}</span>\n <span className=\"text-2xs text-text-quaternary tabular-nums\">\n {group.lines.length} line{group.lines.length === 1 ? '' : 's'}\n </span>\n {group.attention > 0 && (\n <span className=\"text-2xs text-status-warning tabular-nums\">{group.attention} need{group.attention === 1 ? 's' : ''} attention</span>\n )}\n </div>\n );\n}\n\n/**\n * Every declared line across every site: searchable, paged on the server,\n * trouble first, grouped by site until a search or a site narrows the page.\n */\nexport function LinesPage() {\n const navigate = useNavigate();\n const { canAdminister } = useAccess();\n const canDeclare = canAdminister;\n const shell = useShellPanelOptional();\n const invalidate = useThrottledInvalidation('LIST');\n const { filters, setFilter, pagination } = useFilterParams({\n filters: { q: '', site: '', attention: '', sort: '' },\n pageSize: PAGE_SIZE,\n });\n const q = useDebouncedValue(filters.q);\n const attention = filters.attention === ATTENTION_ON;\n const sort = (SORT_OPTIONS.some((o) => o.value === filters.sort) ? filters.sort : DEFAULT_SORT) as LineSort;\n\n const params = useMemo(\n () => ({ q: q || undefined, site: filters.site || undefined, attention: attention || undefined, sort, limit: pagination.pageSize, offset: pagination.offset }),\n [q, filters.site, attention, sort, pagination.pageSize, pagination.offset],\n );\n const { data, isLoading, error } = useLineIndex(params);\n useIndexRefresh();\n\n const refresh = useCallback(() => {\n invalidate([[MACHINE_LINE_INDEX_QUERY_KEY], [MACHINE_LINES_QUERY_KEY], [SETTINGS_QUERY_KEY]]);\n }, [invalidate]);\n\n const closeDeclare = useCallback(() => shell?.closePanel(DECLARE_PANEL_KEY), [shell]);\n const openDeclare = useCallback(\n (initial: LineIndexRow | null) => {\n shell?.setPanel(\n <LineDeclarePanel initial={initial} onClose={closeDeclare} onDone={refresh} />,\n { key: DECLARE_PANEL_KEY, width: DECLARE_PANEL_WIDTH },\n );\n },\n [shell, closeDeclare, refresh],\n );\n useEffect(() => () => shell?.closePanel(DECLARE_PANEL_KEY), [shell]);\n\n const columns = useMemo(() => lineColumns(canDeclare ? (row) => openDeclare(row) : null), [canDeclare, openDeclare]);\n const grouped = !q && !filters.site;\n const groups = useMemo(() => (grouped && data ? groupBySite(data.lines) : []), [grouped, data]);\n const total = data?.total ?? 0;\n const activeFilters = [filters.q, filters.site, filters.attention].filter(Boolean).length;\n const emptyMessage = !data?.declared ? COPY.undeclared : activeFilters > 0 ? COPY.noMatch : COPY.none;\n const openRow = (row: LineIndexRow) => navigate(linePath(row));\n\n return (\n <div>\n <PageHeader title=\"Lines\" />\n <FilterBar\n activeFilterCount={activeFilters}\n actions={\n <>\n <span className=\"text-2xs text-text-quaternary tabular-nums whitespace-nowrap\">\n {total} line{total === 1 ? '' : 's'}\n </span>\n {canDeclare && (\n <button type=\"button\" onClick={() => openDeclare(null)} className=\"inline-flex items-center gap-1 text-2xs icon-link whitespace-nowrap\">\n <Plus className=\"w-3 h-3\" />\n Declare line\n </button>\n )}\n </>\n }\n >\n <FilterInput label=\"Search\" value={filters.q} onChange={(v) => setFilter('q', v)} placeholder=\"site, line, machine, process, address\" />\n <FilterSelect\n label=\"Site\"\n value={filters.site}\n onChange={(v) => setFilter('site', v)}\n options={(data?.sites ?? []).map((s) => ({ value: s.siteId, label: `${s.siteId} · ${s.lines} line${s.lines === 1 ? '' : 's'}` }))}\n placeholder=\"every site\"\n />\n <FilterSelect label=\"Order\" value={sort} onChange={(v) => setFilter('sort', v)} options={SORT_OPTIONS} required />\n <button\n type=\"button\"\n aria-pressed={attention}\n onClick={() => setFilter('attention', attention ? '' : ATTENTION_ON)}\n className={`self-start px-2 py-1 text-2xs rounded border transition-colors whitespace-nowrap ${\n attention ? 'border-status-warning text-status-warning' : 'border-surface-border text-text-secondary hover:text-text-primary'\n }`}\n >\n Needs attention\n </button>\n </FilterBar>\n\n {error && <p className=\"text-2xs text-status-error mb-4\">{(error as Error).message}</p>}\n {isLoading ? (\n <p className=\"text-2xs text-text-tertiary italic\">{COPY.loading}</p>\n ) : grouped && groups.length > 0 ? (\n groups.map((group) => (\n <section key={group.siteId} aria-label={group.siteId}>\n <SiteHeading group={group} />\n <DataTable columns={columns} data={group.lines} keyFn={(row) => `${row.siteId}/${row.lineId}`} onRowClick={openRow} layout=\"fixed\" inline />\n </section>\n ))\n ) : (\n <DataTable\n columns={columns}\n data={data?.lines ?? []}\n keyFn={(row) => `${row.siteId}/${row.lineId}`}\n onRowClick={openRow}\n layout=\"fixed\"\n emptyMessage={emptyMessage}\n />\n )}\n\n <StickyPagination\n page={pagination.page}\n totalPages={pagination.totalPages(total)}\n onPageChange={pagination.setPage}\n total={total}\n pageSize={pagination.pageSize}\n onPageSizeChange={pagination.setPageSize}\n />\n </div>\n );\n}\n"],"names":["LINE_TONE_DOT","LINE_TONE_LABEL","lineTone","row","SORT_OPTIONS","groupBySite","lines","groups","line","group","EXAMPLE_DEFINITION","definitionText","def","definitionOf","m","parseDefinition","text","parsed","err","DECLARE_PANEL_KEY","DECLARE_PANEL_WIDTH","OutcomeBody","outcome","jsxs","jsx","messageOf","ApiError","LineDeclarePanel","initial","onClose","onDone","setText","useState","version","setVersion","busy","setBusy","confirmRetire","setConfirmRetire","setOutcome","submit","e","siteId","lineId","request","trimmed","declareLine","retire","retireLine","X","linePath","Count","value","tone","title","lineColumns","onEdit","columns","Link","formatDateTime","Pencil","PAGE_SIZE","SETTINGS_QUERY_KEY","ATTENTION_ON","DEFAULT_SORT","COPY","useIndexRefresh","invalidate","useThrottledInvalidation","patterns","useMemo","machineLinePattern","machineLogPattern","useEventSubscriptions","MACHINE_LINE_INDEX_QUERY_KEY","MACHINE_LINES_QUERY_KEY","SiteHeading","LinesPage","navigate","useNavigate","canAdminister","useAccess","canDeclare","shell","useShellPanelOptional","filters","setFilter","pagination","useFilterParams","q","useDebouncedValue","attention","sort","o","params","data","isLoading","error","useLineIndex","refresh","useCallback","closeDeclare","openDeclare","useEffect","grouped","total","activeFilters","emptyMessage","openRow","PageHeader","FilterBar","Fragment","Plus","FilterInput","v","FilterSelect","s","DataTable","StickyPagination"],"mappings":"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"}
1
+ {"version":3,"file":"LinesPage-BX3d-rj0.js","sources":["../../src/pages/lines/line-index.ts","../../src/pages/lines/LineDeclarePanel.tsx","../../src/pages/lines/LineIndexColumns.tsx","../../src/pages/lines/LinesPage.tsx"],"sourcesContent":["import type { LineDefinition, LineIndexRow, LineSort } from '../../api/machines';\n\n/** The tone of a line at a glance: attention, running, or nothing led anywhere yet. */\nexport type LineTone = 'attention' | 'running' | 'idle';\n\nexport const LINE_TONE_DOT: Record<LineTone, string> = {\n attention: 'bg-status-warning',\n running: 'bg-status-success-graphic',\n idle: 'bg-text-quaternary',\n};\n\nexport const LINE_TONE_LABEL: Record<LineTone, string> = {\n attention: 'needs attention',\n running: 'running',\n idle: 'idle',\n};\n\n/** Attention wins; a line with work in flight or a leader is running; otherwise idle. */\nexport function lineTone(row: LineIndexRow): LineTone {\n if (row.health.attention) return 'attention';\n if (row.leading || row.health.handoff > 0 || row.health.command > 0) return 'running';\n return 'idle';\n}\n\nexport const SORT_OPTIONS: { value: LineSort; label: string }[] = [\n { value: 'attention', label: 'Attention first' },\n { value: 'site', label: 'Site and line' },\n { value: 'updated', label: 'Recently changed' },\n];\n\nexport interface SiteGroup {\n siteId: string;\n lines: LineIndexRow[];\n attention: number;\n}\n\n/** Rows grouped under their site, in the order the page delivered them. */\nexport function groupBySite(lines: LineIndexRow[]): SiteGroup[] {\n const groups = new Map<string, SiteGroup>();\n for (const line of lines) {\n const group = groups.get(line.siteId) ?? { siteId: line.siteId, lines: [], attention: 0 };\n group.lines.push(line);\n if (line.health.attention) group.attention += 1;\n groups.set(line.siteId, group);\n }\n return [...groups.values()];\n}\n\n/** The starting point for a new declaration: three stations, the fields a line needs. */\nexport const EXAMPLE_DEFINITION: LineDefinition = {\n siteId: 'site-2',\n lineId: 'line-1',\n machines: [\n { machineId: 'print-01', process: 'print', cycleSec: 12 },\n { machineId: 'press-01', process: 'bond', cycleSec: 8 },\n { machineId: 'inspect-01', process: 'inspect', cycleSec: 5 },\n ],\n};\n\n/** The definition the registry holds for a row, as text to edit. */\nexport function definitionText(def: LineDefinition): string {\n return `${JSON.stringify(def, null, 2)}\\n`;\n}\n\n/** A row carries its summary fields; the definition is what it declared. */\nexport function definitionOf(row: LineIndexRow): LineDefinition {\n return {\n siteId: row.siteId,\n lineId: row.lineId,\n machines: row.machines.map((m) => ({\n machineId: m.machineId,\n process: m.process,\n ...(m.address ? { address: m.address } : {}),\n })),\n };\n}\n\n/** Parse what was typed; a readable message names what is missing. */\nexport function parseDefinition(text: string): { ok: true; definition: LineDefinition } | { ok: false; message: string } {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch (err) {\n return { ok: false, message: `The definition is not JSON: ${(err as Error).message}` };\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return { ok: false, message: 'The definition must be an object.' };\n const def = parsed as Record<string, unknown>;\n if (typeof def.siteId !== 'string' || !def.siteId) return { ok: false, message: 'siteId is required.' };\n if (typeof def.lineId !== 'string' || !def.lineId) return { ok: false, message: 'lineId is required.' };\n if (!Array.isArray(def.machines) || def.machines.length === 0) return { ok: false, message: 'machines must list at least one machine.' };\n for (const m of def.machines) {\n if (!m || typeof m !== 'object' || typeof (m as { machineId?: unknown }).machineId !== 'string' || typeof (m as { process?: unknown }).process !== 'string') {\n return { ok: false, message: 'Every machine needs a machineId and a process.' };\n }\n }\n return { ok: true, definition: def as unknown as LineDefinition };\n}\n","import { useState, type FormEvent } from 'react';\nimport { X } from 'lucide-react';\nimport { ApiError } from '../../api/client';\nimport { declareLine, retireLine, type LineIndexRow } from '../../api/machines';\nimport { definitionOf, definitionText, EXAMPLE_DEFINITION, parseDefinition } from './line-index';\n\nexport const DECLARE_PANEL_KEY = 'line-declare';\nexport const DECLARE_PANEL_WIDTH = 460;\n\ntype Outcome =\n | { request: string; ok: true; message: string }\n | { request: string; ok: false; message: string };\n\nfunction OutcomeBody({ outcome }: { outcome: Outcome }) {\n return (\n <div className=\"min-w-0 space-y-1\" data-testid=\"declare-outcome\">\n <div className=\"text-xs font-mono text-text-secondary truncate\" title={outcome.request}>{outcome.request}</div>\n <div className={`text-xs font-medium ${outcome.ok ? 'text-status-success' : 'text-status-error'}`}>{outcome.message}</div>\n </div>\n );\n}\n\nfunction messageOf(err: unknown): string {\n if (err instanceof ApiError && err.status === 409) return `Someone changed this line first: ${err.message}`;\n return (err as Error).message;\n}\n\n/**\n * Declare a line to the registry, or edit and retire one already declared.\n * The definition is the JSON the server validates; a retire asks once more\n * before it goes.\n */\nexport function LineDeclarePanel({\n initial,\n onClose,\n onDone,\n}: {\n initial: LineIndexRow | null;\n onClose: () => void;\n onDone: () => void;\n}) {\n const [text, setText] = useState(() => definitionText(initial ? definitionOf(initial) : EXAMPLE_DEFINITION));\n const [version, setVersion] = useState(initial ? String(initial.version) : '');\n const [busy, setBusy] = useState(false);\n const [confirmRetire, setConfirmRetire] = useState(false);\n const [outcome, setOutcome] = useState<Outcome | null>(null);\n\n const submit = async (e: FormEvent) => {\n e.preventDefault();\n const parsed = parseDefinition(text);\n if (!parsed.ok) {\n setOutcome({ request: 'definition', ok: false, message: parsed.message });\n return;\n }\n const { siteId, lineId } = parsed.definition;\n const request = `PUT /machines/lines/${siteId}/${lineId}`;\n setBusy(true);\n try {\n const trimmed = version.trim();\n const { line } = await declareLine(siteId, lineId, {\n definition: parsed.definition,\n ...(trimmed ? { version: Number(trimmed) } : {}),\n });\n setOutcome({ request, ok: true, message: `declared · ${line.machines.length} machine${line.machines.length === 1 ? '' : 's'} · v${line.version}` });\n onDone();\n } catch (err) {\n setOutcome({ request, ok: false, message: messageOf(err) });\n } finally {\n setBusy(false);\n }\n };\n\n const retire = async () => {\n if (!initial) return;\n const request = `DELETE /machines/lines/${initial.siteId}/${initial.lineId}`;\n setBusy(true);\n try {\n await retireLine(initial.siteId, initial.lineId);\n setOutcome({ request, ok: true, message: 'retired · its gateway stops on every replica' });\n setConfirmRetire(false);\n onDone();\n } catch (err) {\n setOutcome({ request, ok: false, message: messageOf(err) });\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <div className=\"h-full flex flex-col\">\n <div className=\"flex items-start justify-between px-5 pt-5 pb-3 border-b border-surface-border/40\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-mono text-text-primary truncate\">{initial ? `${initial.siteId} · ${initial.lineId}` : 'Declare a line'}</p>\n <p className=\"text-2xs text-text-tertiary mt-0.5\">\n {initial ? `${initial.source} · v${initial.version}` : 'The registry keeps it; every replica starts its gateway.'}\n </p>\n </div>\n <button onClick={onClose} className=\"icon-link shrink-0 ml-2\" title=\"Close\">\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n\n <form onSubmit={submit} className=\"flex-1 overflow-y-auto px-5 py-4 space-y-4\">\n <div>\n <label htmlFor=\"line-definition\" className=\"text-2xs font-medium text-text-secondary uppercase tracking-wide\">Definition</label>\n <textarea\n id=\"line-definition\"\n value={text}\n onChange={(e) => setText(e.target.value)}\n spellCheck={false}\n rows={16}\n className=\"input w-full mt-1 font-mono text-2xs\"\n />\n <p className=\"text-2xs text-text-quaternary mt-1\">siteId, lineId and the machines in route order, each with a machineId and a process.</p>\n </div>\n {initial && (\n <div>\n <label htmlFor=\"line-version\" className=\"text-2xs font-medium text-text-secondary uppercase tracking-wide\">Version</label>\n <input\n id=\"line-version\"\n value={version}\n onChange={(e) => setVersion(e.target.value)}\n inputMode=\"numeric\"\n className=\"input mt-1 font-mono text-2xs w-24\"\n />\n <p className=\"text-2xs text-text-quaternary mt-1\">The version you edited; a newer one on the server refuses the save.</p>\n </div>\n )}\n <div className=\"flex items-center gap-3\">\n <button type=\"submit\" disabled={busy} className=\"btn-primary text-xs\">\n {initial ? 'Save' : 'Declare'}\n </button>\n {initial && !confirmRetire && (\n <button type=\"button\" disabled={busy} onClick={() => setConfirmRetire(true)} className=\"text-2xs text-status-error hover:underline\">\n Retire this line\n </button>\n )}\n </div>\n {initial && confirmRetire && (\n <div className=\"border-l-2 border-status-error pl-3 space-y-2\" data-testid=\"retire-confirm\">\n <p className=\"text-xs text-text-secondary\">\n Retire {initial.siteId} · {initial.lineId}? Its gateway stops on every replica. Rows and roles stay.\n </p>\n <div className=\"flex items-center gap-3\">\n <button type=\"button\" disabled={busy} onClick={retire} className=\"text-xs font-medium text-status-error hover:underline\">\n Retire\n </button>\n <button type=\"button\" disabled={busy} onClick={() => setConfirmRetire(false)} className=\"text-xs text-text-secondary hover:underline\">\n Keep\n </button>\n </div>\n </div>\n )}\n {outcome && <OutcomeBody outcome={outcome} />}\n </form>\n </div>\n );\n}\n","import { Link } from 'react-router-dom';\nimport { Pencil } from 'lucide-react';\nimport type { LineIndexRow } from '../../api/machines';\nimport type { Column } from '../../components/common/data/DataTable';\nimport { formatDateTime } from '../../lib/format';\nimport { LINE_TONE_DOT, LINE_TONE_LABEL, lineTone } from './line-index';\n\nexport function linePath(row: Pick<LineIndexRow, 'siteId' | 'lineId'>): string {\n return `/lines/${encodeURIComponent(row.siteId)}/${encodeURIComponent(row.lineId)}`;\n}\n\nfunction Count({ value, tone, title }: { value: number; tone?: string; title?: string }) {\n return (\n <span className={`tabular-nums ${value > 0 ? tone ?? 'text-text-primary' : 'text-text-quaternary'}`} title={title}>\n {value}\n </span>\n );\n}\n\n/** The index columns; `onEdit` adds the manage column for those who may declare. */\nexport function lineColumns(onEdit: ((row: LineIndexRow) => void) | null): Column<LineIndexRow>[] {\n const columns: Column<LineIndexRow>[] = [\n {\n key: 'line',\n label: 'Line',\n priority: 1,\n render: (row) => {\n const tone = lineTone(row);\n return (\n <span className=\"flex items-center gap-2 min-w-0\">\n <span className={`w-2.5 h-2.5 rounded-full dot-ring shrink-0 ${LINE_TONE_DOT[tone]}`} title={LINE_TONE_LABEL[tone]} />\n <Link to={linePath(row)} className=\"text-xs font-mono text-accent hover:underline truncate\" title={`${row.siteId} · ${row.lineId}`}>\n {row.siteId} · {row.lineId}\n </Link>\n </span>\n );\n },\n },\n {\n key: 'machines',\n label: 'Machines',\n className: 'w-28',\n render: (row) => (\n <span className=\"text-2xs tabular-nums\">\n <span className=\"text-text-primary\">{row.health.machines}</span>\n {row.health.offline > 0 && <span className=\"text-status-warning\"> · {row.health.offline} offline</span>}\n {row.health.quiet > 0 && <span className=\"text-status-warning\"> · {row.health.quiet} quiet</span>}\n </span>\n ),\n },\n {\n key: 'alarms',\n label: 'Alarms',\n className: 'w-16 text-right',\n render: (row) => <Count value={row.health.alarms} tone=\"text-status-warning\" title=\"Active alarms\" />,\n },\n {\n key: 'people',\n label: 'People',\n className: 'w-16 text-right',\n render: (row) => <Count value={row.health.people} tone=\"text-status-warning\" title=\"Rows waiting on a person\" />,\n },\n {\n key: 'inflight',\n label: 'In flight',\n className: 'w-20 text-right',\n render: (row) => <Count value={row.health.handoff + row.health.command} title=\"Open handoff and command rows\" />,\n },\n {\n key: 'led',\n label: 'Led',\n className: 'w-20',\n render: (row) => (\n <span className={`text-2xs ${row.leading ? 'text-text-primary' : 'text-text-tertiary'}`}>{row.leading ? 'here' : 'elsewhere'}</span>\n ),\n },\n {\n key: 'chain',\n label: 'Chain',\n showFrom: 'wall',\n priority: 3,\n render: (row) => (\n <span className=\"text-2xs font-mono text-text-tertiary truncate block\" title={row.machines.map((m) => m.machineId).join(' → ')}>\n {row.machines.map((m) => m.machineId).join(' → ')}\n </span>\n ),\n },\n {\n key: 'source',\n label: 'Source',\n showFrom: 'wall',\n className: 'w-28',\n priority: 3,\n render: (row) => (\n <span className=\"text-2xs text-text-tertiary tabular-nums\" title={`changed ${formatDateTime(row.updatedAt)}`}>\n {row.source} · v{row.version}\n </span>\n ),\n },\n ];\n if (onEdit) {\n columns.push({\n key: 'manage',\n label: '',\n className: 'w-10',\n priority: 1,\n render: (row) => (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onEdit(row);\n }}\n className=\"icon-link\"\n title={`Edit ${row.siteId} · ${row.lineId}`}\n aria-label={`Edit ${row.siteId} · ${row.lineId}`}\n >\n <Pencil className=\"w-3.5 h-3.5\" />\n </button>\n ),\n });\n }\n return columns;\n}\n","import { useCallback, useEffect, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Plus } from 'lucide-react';\nimport {\n MACHINE_LINE_INDEX_QUERY_KEY,\n MACHINE_LINES_QUERY_KEY,\n machineLinePattern,\n machineLogPattern,\n useLineIndex,\n type LineIndexRow,\n type LineSort,\n} from '../../api/machines';\nimport { DataTable } from '../../components/common/data/DataTable';\nimport { FilterBar, FilterInput, FilterSelect } from '../../components/common/data/FilterBar';\nimport { StickyPagination } from '../../components/common/data/StickyPagination';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { useAccess } from '../../hooks/useAccess';\nimport { useDebouncedValue } from '../../hooks/useDebouncedValue';\nimport { useEventSubscriptions } from '../../hooks/useEventContext';\nimport { useThrottledInvalidation } from '../../hooks/useEventHooks';\nimport { useFilterParams } from '../../hooks/useFilterParams';\nimport { useShellPanelOptional } from '../../hooks/useShellPanel';\nimport { LineDeclarePanel, DECLARE_PANEL_KEY, DECLARE_PANEL_WIDTH } from './LineDeclarePanel';\nimport { lineColumns, linePath } from './LineIndexColumns';\nimport { groupBySite, SORT_OPTIONS, type SiteGroup } from './line-index';\n\nconst PAGE_SIZE = 50;\nconst SETTINGS_QUERY_KEY = 'settings';\nconst ATTENTION_ON = 'true';\nconst DEFAULT_SORT: LineSort = 'attention';\n\nconst COPY = {\n undeclared: 'Lines appear here once the server declares them.',\n none: 'No lines declared yet.',\n noMatch: 'No line matches.',\n loading: 'Loading lines…',\n} as const;\n\n/** The index refreshes through the LIST tier when a line is declared or retired, or a gateway logs. */\nfunction useIndexRefresh() {\n const invalidate = useThrottledInvalidation('LIST');\n const patterns = useMemo(() => [machineLinePattern(), machineLogPattern()], []);\n useEventSubscriptions(patterns, () => {\n invalidate([[MACHINE_LINE_INDEX_QUERY_KEY], [MACHINE_LINES_QUERY_KEY], [SETTINGS_QUERY_KEY]]);\n });\n}\n\nfunction SiteHeading({ group }: { group: SiteGroup }) {\n return (\n <div className=\"flex items-baseline gap-3 pt-5 pb-1.5\" data-testid=\"site-heading\">\n <span className=\"text-xs font-mono text-text-primary\">{group.siteId}</span>\n <span className=\"text-2xs text-text-quaternary tabular-nums\">\n {group.lines.length} line{group.lines.length === 1 ? '' : 's'}\n </span>\n {group.attention > 0 && (\n <span className=\"text-2xs text-status-warning tabular-nums\">{group.attention} need{group.attention === 1 ? 's' : ''} attention</span>\n )}\n </div>\n );\n}\n\n/**\n * Every declared line across every site: searchable, paged on the server,\n * trouble first, grouped by site until a search or a site narrows the page.\n */\nexport function LinesPage() {\n const navigate = useNavigate();\n const { canAdminister } = useAccess();\n const canDeclare = canAdminister;\n const shell = useShellPanelOptional();\n const invalidate = useThrottledInvalidation('LIST');\n const { filters, setFilter, pagination } = useFilterParams({\n filters: { q: '', site: '', attention: '', sort: '' },\n pageSize: PAGE_SIZE,\n });\n const q = useDebouncedValue(filters.q);\n const attention = filters.attention === ATTENTION_ON;\n const sort = (SORT_OPTIONS.some((o) => o.value === filters.sort) ? filters.sort : DEFAULT_SORT) as LineSort;\n\n const params = useMemo(\n () => ({ q: q || undefined, site: filters.site || undefined, attention: attention || undefined, sort, limit: pagination.pageSize, offset: pagination.offset }),\n [q, filters.site, attention, sort, pagination.pageSize, pagination.offset],\n );\n const { data, isLoading, error } = useLineIndex(params);\n useIndexRefresh();\n\n const refresh = useCallback(() => {\n invalidate([[MACHINE_LINE_INDEX_QUERY_KEY], [MACHINE_LINES_QUERY_KEY], [SETTINGS_QUERY_KEY]]);\n }, [invalidate]);\n\n const closeDeclare = useCallback(() => shell?.closePanel(DECLARE_PANEL_KEY), [shell]);\n const openDeclare = useCallback(\n (initial: LineIndexRow | null) => {\n shell?.setPanel(\n <LineDeclarePanel initial={initial} onClose={closeDeclare} onDone={refresh} />,\n { key: DECLARE_PANEL_KEY, width: DECLARE_PANEL_WIDTH },\n );\n },\n [shell, closeDeclare, refresh],\n );\n useEffect(() => () => shell?.closePanel(DECLARE_PANEL_KEY), [shell]);\n\n const columns = useMemo(() => lineColumns(canDeclare ? (row) => openDeclare(row) : null), [canDeclare, openDeclare]);\n const grouped = !q && !filters.site;\n const groups = useMemo(() => (grouped && data ? groupBySite(data.lines) : []), [grouped, data]);\n const total = data?.total ?? 0;\n const activeFilters = [filters.q, filters.site, filters.attention].filter(Boolean).length;\n const emptyMessage = !data?.declared ? COPY.undeclared : activeFilters > 0 ? COPY.noMatch : COPY.none;\n const openRow = (row: LineIndexRow) => navigate(linePath(row));\n\n return (\n <div>\n <PageHeader title=\"Lines\" />\n <FilterBar\n activeFilterCount={activeFilters}\n actions={\n <>\n <span className=\"text-2xs text-text-quaternary tabular-nums whitespace-nowrap\">\n {total} line{total === 1 ? '' : 's'}\n </span>\n {canDeclare && (\n <button type=\"button\" onClick={() => openDeclare(null)} className=\"inline-flex items-center gap-1 text-2xs icon-link whitespace-nowrap\">\n <Plus className=\"w-3 h-3\" />\n Declare line\n </button>\n )}\n </>\n }\n >\n <FilterInput label=\"Search\" value={filters.q} onChange={(v) => setFilter('q', v)} placeholder=\"site, line, machine, process, address\" />\n <FilterSelect\n label=\"Site\"\n value={filters.site}\n onChange={(v) => setFilter('site', v)}\n options={(data?.sites ?? []).map((s) => ({ value: s.siteId, label: `${s.siteId} · ${s.lines} line${s.lines === 1 ? '' : 's'}` }))}\n placeholder=\"every site\"\n />\n <FilterSelect label=\"Order\" value={sort} onChange={(v) => setFilter('sort', v)} options={SORT_OPTIONS} required />\n <button\n type=\"button\"\n aria-pressed={attention}\n onClick={() => setFilter('attention', attention ? '' : ATTENTION_ON)}\n className={`self-start px-2 py-1 text-2xs rounded border transition-colors whitespace-nowrap ${\n attention ? 'border-status-warning text-status-warning' : 'border-surface-border text-text-secondary hover:text-text-primary'\n }`}\n >\n Needs attention\n </button>\n </FilterBar>\n\n {error && <p className=\"text-2xs text-status-error mb-4\">{(error as Error).message}</p>}\n {isLoading ? (\n <p className=\"text-2xs text-text-tertiary italic\">{COPY.loading}</p>\n ) : grouped && groups.length > 0 ? (\n groups.map((group) => (\n <section key={group.siteId} aria-label={group.siteId}>\n <SiteHeading group={group} />\n <DataTable columns={columns} data={group.lines} keyFn={(row) => `${row.siteId}/${row.lineId}`} onRowClick={openRow} layout=\"fixed\" inline />\n </section>\n ))\n ) : (\n <DataTable\n columns={columns}\n data={data?.lines ?? []}\n keyFn={(row) => `${row.siteId}/${row.lineId}`}\n onRowClick={openRow}\n layout=\"fixed\"\n emptyMessage={emptyMessage}\n />\n )}\n\n <StickyPagination\n page={pagination.page}\n totalPages={pagination.totalPages(total)}\n onPageChange={pagination.setPage}\n total={total}\n pageSize={pagination.pageSize}\n onPageSizeChange={pagination.setPageSize}\n />\n </div>\n );\n}\n"],"names":["LINE_TONE_DOT","LINE_TONE_LABEL","lineTone","row","SORT_OPTIONS","groupBySite","lines","groups","line","group","EXAMPLE_DEFINITION","definitionText","def","definitionOf","m","parseDefinition","text","parsed","err","DECLARE_PANEL_KEY","DECLARE_PANEL_WIDTH","OutcomeBody","outcome","jsxs","jsx","messageOf","ApiError","LineDeclarePanel","initial","onClose","onDone","setText","useState","version","setVersion","busy","setBusy","confirmRetire","setConfirmRetire","setOutcome","submit","e","siteId","lineId","request","trimmed","declareLine","retire","retireLine","X","linePath","Count","value","tone","title","lineColumns","onEdit","columns","Link","formatDateTime","Pencil","PAGE_SIZE","SETTINGS_QUERY_KEY","ATTENTION_ON","DEFAULT_SORT","COPY","useIndexRefresh","invalidate","useThrottledInvalidation","patterns","useMemo","machineLinePattern","machineLogPattern","useEventSubscriptions","MACHINE_LINE_INDEX_QUERY_KEY","MACHINE_LINES_QUERY_KEY","SiteHeading","LinesPage","navigate","useNavigate","canAdminister","useAccess","canDeclare","shell","useShellPanelOptional","filters","setFilter","pagination","useFilterParams","q","useDebouncedValue","attention","sort","o","params","data","isLoading","error","useLineIndex","refresh","useCallback","closeDeclare","openDeclare","useEffect","grouped","total","activeFilters","emptyMessage","openRow","PageHeader","FilterBar","Fragment","Plus","FilterInput","v","FilterSelect","s","DataTable","StickyPagination"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{a as C,j as s}from"./vendor-query-DvWWuNIB.js";import{b7 as u,b8 as b}from"./index-CXNh7LuG.js";import{ad as d,bE as j,bF as N,ao as h}from"./vendor-icons-en0_uSRD.js";function g({onRefresh:m,isFetching:a=!1,apiPath:t,standalone:x=!1}){const[c,r]=C.useState(null),i=(e,l)=>{navigator.clipboard.writeText(e).then(()=>{r(l),setTimeout(()=>r(null),2e3)})},p=()=>{if(!t)return;const e=`${window.location.origin}${u}/api${t}`;i(e,"url")},f=()=>{if(!t)return;const e=`${window.location.origin}${u}/api${t}`,l=b(),$=l?`curl -H "Authorization: Bearer ${l}" "${e}"`:`curl "${e}"`;i($,"curl")},n="p-1 icon-link rounded",o="w-2.5 h-2.5";return s.jsxs("div",{className:"flex items-center gap-0.5",children:[t&&s.jsxs("div",{className:x?"flex items-center gap-0.5":"hidden @filters/filters:flex items-center gap-0.5",children:[s.jsx("button",{onClick:p,className:n,title:"Copy API URL",children:c==="url"?s.jsx(d,{className:`${o} text-status-success`}):s.jsx(j,{className:o})}),s.jsx("button",{onClick:f,className:n,title:"Copy curl (includes auth token)",children:c==="curl"?s.jsx(d,{className:`${o} text-status-success`}):s.jsx(N,{className:o})})]}),s.jsx("button",{onClick:m,disabled:a,className:`${n} disabled:opacity-50`,title:"Refresh",children:s.jsx(h,{className:`${o} ${a?"animate-spin":""}`})})]})}export{g as L};
2
- //# sourceMappingURL=ListToolbar-GGj6X36p.js.map
1
+ import{a as C,j as s}from"./vendor-query-DvWWuNIB.js";import{b7 as u,b8 as b}from"./index-xycFf66M.js";import{ad as d,bE as j,bF as N,ao as h}from"./vendor-icons-en0_uSRD.js";function g({onRefresh:m,isFetching:a=!1,apiPath:t,standalone:x=!1}){const[c,r]=C.useState(null),i=(e,l)=>{navigator.clipboard.writeText(e).then(()=>{r(l),setTimeout(()=>r(null),2e3)})},p=()=>{if(!t)return;const e=`${window.location.origin}${u}/api${t}`;i(e,"url")},f=()=>{if(!t)return;const e=`${window.location.origin}${u}/api${t}`,l=b(),$=l?`curl -H "Authorization: Bearer ${l}" "${e}"`:`curl "${e}"`;i($,"curl")},n="p-1 icon-link rounded",o="w-2.5 h-2.5";return s.jsxs("div",{className:"flex items-center gap-0.5",children:[t&&s.jsxs("div",{className:x?"flex items-center gap-0.5":"hidden @filters/filters:flex items-center gap-0.5",children:[s.jsx("button",{onClick:p,className:n,title:"Copy API URL",children:c==="url"?s.jsx(d,{className:`${o} text-status-success`}):s.jsx(j,{className:o})}),s.jsx("button",{onClick:f,className:n,title:"Copy curl (includes auth token)",children:c==="curl"?s.jsx(d,{className:`${o} text-status-success`}):s.jsx(N,{className:o})})]}),s.jsx("button",{onClick:m,disabled:a,className:`${n} disabled:opacity-50`,title:"Refresh",children:s.jsx(h,{className:`${o} ${a?"animate-spin":""}`})})]})}export{g as L};
2
+ //# sourceMappingURL=ListToolbar-bj2sgAK4.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ListToolbar-GGj6X36p.js","sources":["../../src/components/common/data/ListToolbar.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { RefreshCw, Link2, Terminal, Check } from 'lucide-react';\nimport { getToken } from '../../../api/client';\nimport { LT_BASE } from '../../../lib/base-path';\n\ninterface ListToolbarProps {\n onRefresh: () => void;\n isFetching?: boolean;\n /** API path (e.g. \"/workflow-states/jobs?limit=50\") for URL/curl copy. */\n apiPath?: string;\n /**\n * Set when the toolbar renders outside a `@container/filters` ancestor\n * (e.g. a page header) — skips the narrow-container fold classes, which\n * would otherwise never match and hide the copy actions.\n */\n standalone?: boolean;\n}\n\ntype CopiedState = 'url' | 'curl' | null;\n\n/**\n * Toolbar for list pages: refresh, copy API URL, copy curl command.\n * Designed to sit in FilterBar `actions` slot.\n */\nexport function ListToolbar({ onRefresh, isFetching = false, apiPath, standalone = false }: ListToolbarProps) {\n const [copied, setCopied] = useState<CopiedState>(null);\n\n const copyToClipboard = (text: string, type: CopiedState) => {\n navigator.clipboard.writeText(text).then(() => {\n setCopied(type);\n setTimeout(() => setCopied(null), 2000);\n });\n };\n\n const handleCopyUrl = () => {\n if (!apiPath) return;\n const url = `${window.location.origin}${LT_BASE}/api${apiPath}`;\n copyToClipboard(url, 'url');\n };\n\n const handleCopyCurl = () => {\n if (!apiPath) return;\n const url = `${window.location.origin}${LT_BASE}/api${apiPath}`;\n const token = getToken();\n const cmd = token\n ? `curl -H \"Authorization: Bearer ${token}\" \"${url}\"`\n : `curl \"${url}\"`;\n copyToClipboard(cmd, 'curl');\n };\n\n const BTN = 'p-1 icon-link rounded';\n const ICON = 'w-2.5 h-2.5';\n\n return (\n <div className=\"flex items-center gap-0.5\">\n {apiPath && (\n // Developer copy actions yield first at narrow containers — refresh\n // is the affordance the floor actually uses.\n <div className={standalone ? 'flex items-center gap-0.5' : 'hidden @filters/filters:flex items-center gap-0.5'}>\n <button onClick={handleCopyUrl} className={BTN} title=\"Copy API URL\">\n {copied === 'url' ? <Check className={`${ICON} text-status-success`} /> : <Link2 className={ICON} />}\n </button>\n <button onClick={handleCopyCurl} className={BTN} title=\"Copy curl (includes auth token)\">\n {copied === 'curl' ? <Check className={`${ICON} text-status-success`} /> : <Terminal className={ICON} />}\n </button>\n </div>\n )}\n <button onClick={onRefresh} disabled={isFetching} className={`${BTN} disabled:opacity-50`} title=\"Refresh\">\n <RefreshCw className={`${ICON} ${isFetching ? 'animate-spin' : ''}`} />\n </button>\n </div>\n );\n}\n"],"names":["ListToolbar","onRefresh","isFetching","apiPath","standalone","copied","setCopied","useState","copyToClipboard","text","type","handleCopyUrl","url","LT_BASE","handleCopyCurl","token","getToken","cmd","BTN","ICON","jsxs","jsx","Check","Link2","Terminal","RefreshCw"],"mappings":"+KAwBO,SAASA,EAAY,CAAE,UAAAC,EAAW,WAAAC,EAAa,GAAO,QAAAC,EAAS,WAAAC,EAAa,IAA2B,CAC5G,KAAM,CAACC,EAAQC,CAAS,EAAIC,EAAAA,SAAsB,IAAI,EAEhDC,EAAkB,CAACC,EAAcC,IAAsB,CAC3D,UAAU,UAAU,UAAUD,CAAI,EAAE,KAAK,IAAM,CAC7CH,EAAUI,CAAI,EACd,WAAW,IAAMJ,EAAU,IAAI,EAAG,GAAI,CACxC,CAAC,CACH,EAEMK,EAAgB,IAAM,CAC1B,GAAI,CAACR,EAAS,OACd,MAAMS,EAAM,GAAG,OAAO,SAAS,MAAM,GAAGC,CAAO,OAAOV,CAAO,GAC7DK,EAAgBI,EAAK,KAAK,CAC5B,EAEME,EAAiB,IAAM,CAC3B,GAAI,CAACX,EAAS,OACd,MAAMS,EAAM,GAAG,OAAO,SAAS,MAAM,GAAGC,CAAO,OAAOV,CAAO,GACvDY,EAAQC,EAAA,EACRC,EAAMF,EACR,kCAAkCA,CAAK,MAAMH,CAAG,IAChD,SAASA,CAAG,IAChBJ,EAAgBS,EAAK,MAAM,CAC7B,EAEMC,EAAM,wBACNC,EAAO,cAEb,OACEC,EAAAA,KAAC,MAAA,CAAI,UAAU,4BACZ,SAAA,CAAAjB,GAGCiB,EAAAA,KAAC,MAAA,CAAI,UAAWhB,EAAa,4BAA8B,oDACzD,SAAA,CAAAiB,EAAAA,IAAC,SAAA,CAAO,QAASV,EAAe,UAAWO,EAAK,MAAM,eACnD,aAAW,MAAQG,EAAAA,IAACC,GAAM,UAAW,GAAGH,CAAI,sBAAA,CAAwB,QAAMI,EAAA,CAAM,UAAWJ,EAAM,CAAA,CACpG,EACAE,EAAAA,IAAC,UAAO,QAASP,EAAgB,UAAWI,EAAK,MAAM,kCACpD,SAAAb,IAAW,aAAUiB,EAAA,CAAM,UAAW,GAAGH,CAAI,sBAAA,CAAwB,EAAKE,EAAAA,IAACG,EAAA,CAAS,UAAWL,CAAA,CAAM,CAAA,CACxG,CAAA,EACF,EAEFE,EAAAA,IAAC,UAAO,QAASpB,EAAW,SAAUC,EAAY,UAAW,GAAGgB,CAAG,uBAAwB,MAAM,UAC/F,SAAAG,MAACI,EAAA,CAAU,UAAW,GAAGN,CAAI,IAAIjB,EAAa,eAAiB,EAAE,EAAA,CAAI,CAAA,CACvE,CAAA,EACF,CAEJ"}
1
+ {"version":3,"file":"ListToolbar-bj2sgAK4.js","sources":["../../src/components/common/data/ListToolbar.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { RefreshCw, Link2, Terminal, Check } from 'lucide-react';\nimport { getToken } from '../../../api/client';\nimport { LT_BASE } from '../../../lib/base-path';\n\ninterface ListToolbarProps {\n onRefresh: () => void;\n isFetching?: boolean;\n /** API path (e.g. \"/workflow-states/jobs?limit=50\") for URL/curl copy. */\n apiPath?: string;\n /**\n * Set when the toolbar renders outside a `@container/filters` ancestor\n * (e.g. a page header) — skips the narrow-container fold classes, which\n * would otherwise never match and hide the copy actions.\n */\n standalone?: boolean;\n}\n\ntype CopiedState = 'url' | 'curl' | null;\n\n/**\n * Toolbar for list pages: refresh, copy API URL, copy curl command.\n * Designed to sit in FilterBar `actions` slot.\n */\nexport function ListToolbar({ onRefresh, isFetching = false, apiPath, standalone = false }: ListToolbarProps) {\n const [copied, setCopied] = useState<CopiedState>(null);\n\n const copyToClipboard = (text: string, type: CopiedState) => {\n navigator.clipboard.writeText(text).then(() => {\n setCopied(type);\n setTimeout(() => setCopied(null), 2000);\n });\n };\n\n const handleCopyUrl = () => {\n if (!apiPath) return;\n const url = `${window.location.origin}${LT_BASE}/api${apiPath}`;\n copyToClipboard(url, 'url');\n };\n\n const handleCopyCurl = () => {\n if (!apiPath) return;\n const url = `${window.location.origin}${LT_BASE}/api${apiPath}`;\n const token = getToken();\n const cmd = token\n ? `curl -H \"Authorization: Bearer ${token}\" \"${url}\"`\n : `curl \"${url}\"`;\n copyToClipboard(cmd, 'curl');\n };\n\n const BTN = 'p-1 icon-link rounded';\n const ICON = 'w-2.5 h-2.5';\n\n return (\n <div className=\"flex items-center gap-0.5\">\n {apiPath && (\n // Developer copy actions yield first at narrow containers — refresh\n // is the affordance the floor actually uses.\n <div className={standalone ? 'flex items-center gap-0.5' : 'hidden @filters/filters:flex items-center gap-0.5'}>\n <button onClick={handleCopyUrl} className={BTN} title=\"Copy API URL\">\n {copied === 'url' ? <Check className={`${ICON} text-status-success`} /> : <Link2 className={ICON} />}\n </button>\n <button onClick={handleCopyCurl} className={BTN} title=\"Copy curl (includes auth token)\">\n {copied === 'curl' ? <Check className={`${ICON} text-status-success`} /> : <Terminal className={ICON} />}\n </button>\n </div>\n )}\n <button onClick={onRefresh} disabled={isFetching} className={`${BTN} disabled:opacity-50`} title=\"Refresh\">\n <RefreshCw className={`${ICON} ${isFetching ? 'animate-spin' : ''}`} />\n </button>\n </div>\n );\n}\n"],"names":["ListToolbar","onRefresh","isFetching","apiPath","standalone","copied","setCopied","useState","copyToClipboard","text","type","handleCopyUrl","url","LT_BASE","handleCopyCurl","token","getToken","cmd","BTN","ICON","jsxs","jsx","Check","Link2","Terminal","RefreshCw"],"mappings":"+KAwBO,SAASA,EAAY,CAAE,UAAAC,EAAW,WAAAC,EAAa,GAAO,QAAAC,EAAS,WAAAC,EAAa,IAA2B,CAC5G,KAAM,CAACC,EAAQC,CAAS,EAAIC,EAAAA,SAAsB,IAAI,EAEhDC,EAAkB,CAACC,EAAcC,IAAsB,CAC3D,UAAU,UAAU,UAAUD,CAAI,EAAE,KAAK,IAAM,CAC7CH,EAAUI,CAAI,EACd,WAAW,IAAMJ,EAAU,IAAI,EAAG,GAAI,CACxC,CAAC,CACH,EAEMK,EAAgB,IAAM,CAC1B,GAAI,CAACR,EAAS,OACd,MAAMS,EAAM,GAAG,OAAO,SAAS,MAAM,GAAGC,CAAO,OAAOV,CAAO,GAC7DK,EAAgBI,EAAK,KAAK,CAC5B,EAEME,EAAiB,IAAM,CAC3B,GAAI,CAACX,EAAS,OACd,MAAMS,EAAM,GAAG,OAAO,SAAS,MAAM,GAAGC,CAAO,OAAOV,CAAO,GACvDY,EAAQC,EAAA,EACRC,EAAMF,EACR,kCAAkCA,CAAK,MAAMH,CAAG,IAChD,SAASA,CAAG,IAChBJ,EAAgBS,EAAK,MAAM,CAC7B,EAEMC,EAAM,wBACNC,EAAO,cAEb,OACEC,EAAAA,KAAC,MAAA,CAAI,UAAU,4BACZ,SAAA,CAAAjB,GAGCiB,EAAAA,KAAC,MAAA,CAAI,UAAWhB,EAAa,4BAA8B,oDACzD,SAAA,CAAAiB,EAAAA,IAAC,SAAA,CAAO,QAASV,EAAe,UAAWO,EAAK,MAAM,eACnD,aAAW,MAAQG,EAAAA,IAACC,GAAM,UAAW,GAAGH,CAAI,sBAAA,CAAwB,QAAMI,EAAA,CAAM,UAAWJ,EAAM,CAAA,CACpG,EACAE,EAAAA,IAAC,UAAO,QAASP,EAAgB,UAAWI,EAAK,MAAM,kCACpD,SAAAb,IAAW,aAAUiB,EAAA,CAAM,UAAW,GAAGH,CAAI,sBAAA,CAAwB,EAAKE,EAAAA,IAACG,EAAA,CAAS,UAAWL,CAAA,CAAM,CAAA,CACxG,CAAA,EACF,EAEFE,EAAAA,IAAC,UAAO,QAASpB,EAAW,SAAUC,EAAY,UAAW,GAAGgB,CAAG,uBAAwB,MAAM,UAC/F,SAAAG,MAACI,EAAA,CAAU,UAAW,GAAGN,CAAI,IAAIjB,EAAa,eAAiB,EAAE,EAAA,CAAI,CAAA,CACvE,CAAA,EACF,CAEJ"}
@@ -1,2 +1,2 @@
1
- import{a as o,j as e}from"./vendor-query-DvWWuNIB.js";import{u as A}from"./mcp-CsZdpCEf.js";import{u as F}from"./pipelines-C17xZZsa.js";import{u as I}from"./yaml-workflows-DgrmL_Kt.js";import{u as W}from"./controlplane-B96o1-zT.js";import{P as z}from"./PageHeader-DiGWAQlR.js";import{S as b}from"./StatCard-nWY4sndl.js";import{Q as E,W as O}from"./vendor-icons-en0_uSRD.js";import{u as U}from"./vendor-react-_9U4mKFr.js";import"./index-CXNh7LuG.js";const T=[{label:"1h",ms:36e5},{label:"24h",ms:864e5},{label:"7d",ms:6048e5},{label:"30d",ms:2592e6}];function q(r){return r<1e3?`${Math.round(r)}ms`:r<6e4?`${(r/1e3).toFixed(1)}s`:r<36e5?`${(r/6e4).toFixed(1)}m`:`${(r/36e5).toFixed(1)}h`}function j({value:r,colorClass:c,onClick:v}){return r===0?e.jsx("span",{className:"text-text-tertiary",children:"0"}):e.jsx("button",{onClick:v,className:`${c} hover:underline tabular-nums font-medium`,children:r})}function ee(){const r=U(),[c,v]=o.useState("24h"),[D,P]=o.useState(""),{data:d}=W(),k=o.useMemo(()=>((d==null?void 0:d.apps)??[]).map(t=>t.appId).sort(),[d==null?void 0:d.apps]),u=D||k[0]||"",{data:m}=F({limit:500,app_id:u}),{data:N,isLoading:L}=A(),{data:y,isLoading:_}=I({limit:200}),w=k,p=(N==null?void 0:N.servers)??[],h=(y==null?void 0:y.workflows)??[],M=o.useMemo(()=>p.reduce((t,l)=>t+(Array.isArray(l.tool_manifest)?l.tool_manifest.length:0),0),[p]),S=o.useMemo(()=>new Set(h.map(l=>l.app_id)).size,[h]),$=o.useMemo(()=>{const t=T.find(l=>l.label===c);return Date.now()-t.ms},[c]),i=o.useMemo(()=>((m==null?void 0:m.jobs)??[]).filter(t=>new Date(t.created_at).getTime()>=$),[m==null?void 0:m.jobs,$]),C=o.useMemo(()=>{const t=new Map;for(const s of i){const a=t.get(s.entity)??{total:0,running:0,completed:0,failed:0,durations:[]};if(a.total++,s.status==="running"&&a.running++,s.status==="completed"){a.completed++;const g=new Date(s.updated_at).getTime()-new Date(s.created_at).getTime();g>0&&a.durations.push(g)}s.status==="failed"&&a.failed++,t.set(s.entity,a)}const l=[];for(const[s,a]of t)l.push({pipeline:s,...a,avgDuration:a.durations.length>0?a.durations.reduce((g,R)=>g+R,0)/a.durations.length:null});return l.sort((s,a)=>a.total-s.total)},[i]),f=o.useMemo(()=>({total:i.length,running:i.filter(t=>t.status==="running").length,completed:i.filter(t=>t.status==="completed").length,failed:i.filter(t=>t.status==="failed").length}),[i]),n=(t,l)=>{const s=new URLSearchParams;u&&s.set("namespace",u),t&&s.set("entity",t),l&&s.set("status",l);const a=s.toString();r(`/mcp/executions${a?`?${a}`:""}`)},x="pb-2 text-2xs font-semibold uppercase tracking-widest text-text-tertiary";return e.jsxs("div",{children:[e.jsx(z,{title:"Discovered"}),e.jsxs("div",{className:"flex items-center gap-4 mb-6",children:[e.jsx("div",{className:"flex items-center gap-1",children:T.map(t=>e.jsx("button",{onClick:()=>v(t.label),className:`px-3 py-1 text-xs rounded-full transition-colors ${c===t.label?"bg-accent text-text-inverse":"text-text-tertiary hover:text-text-primary hover:bg-surface-hover"}`,children:t.label},t.label))}),w.length>1&&e.jsx("select",{value:u,onChange:t=>P(t.target.value),className:"select text-xs py-1 px-2",children:w.map(t=>e.jsx("option",{value:t,children:t},t))})]}),e.jsxs("div",{className:"grid grid-cols-4 gap-4 mb-8",children:[e.jsx(b,{label:"Total Runs",value:f.total,onClick:()=>n()}),e.jsx(b,{label:"Running",value:f.running,colorClass:"text-status-active",onClick:()=>n(void 0,"running")}),e.jsx(b,{label:"Completed",value:f.completed,colorClass:"text-status-success",onClick:()=>n(void 0,"completed")}),e.jsx(b,{label:"Failed",value:f.failed,colorClass:"text-status-error",onClick:()=>n(void 0,"failed")})]}),C.length>0&&e.jsxs("table",{className:"w-full text-left mb-10",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-surface-border",children:[e.jsx("th",{className:x,children:"Tool"}),e.jsx("th",{className:`${x} text-right w-20`,children:"Total"}),e.jsx("th",{className:`${x} text-right w-20`,children:"Running"}),e.jsx("th",{className:`${x} text-right w-24`,children:"Completed"}),e.jsx("th",{className:`${x} text-right w-20`,children:"Failed"}),e.jsx("th",{className:`${x} text-right w-28`,children:"Avg Duration"})]})}),e.jsx("tbody",{children:C.map(t=>e.jsxs("tr",{className:"border-b border-surface-border last:border-b-0",children:[e.jsx("td",{className:"py-3 text-sm font-mono text-text-primary",children:e.jsx("button",{onClick:()=>n(t.pipeline),className:"hover:text-accent hover:underline",children:t.pipeline})}),e.jsx("td",{className:"py-3 text-sm text-right",children:e.jsx(j,{value:t.total,colorClass:"text-text-secondary",onClick:()=>n(t.pipeline)})}),e.jsx("td",{className:"py-3 text-sm text-right",children:e.jsx(j,{value:t.running,colorClass:"text-status-active",onClick:()=>n(t.pipeline,"running")})}),e.jsx("td",{className:"py-3 text-sm text-right",children:e.jsx(j,{value:t.completed,colorClass:"text-status-success",onClick:()=>n(t.pipeline,"completed")})}),e.jsx("td",{className:"py-3 text-sm text-right",children:e.jsx(j,{value:t.failed,colorClass:"text-status-error",onClick:()=>n(t.pipeline,"failed")})}),e.jsx("td",{className:"py-3 text-sm font-mono text-text-secondary text-right",children:t.avgDuration!==null?q(t.avgDuration):"—"})]},t.pipeline))})]}),C.length===0&&e.jsx("div",{className:"py-12 text-center mb-8",children:e.jsxs("p",{className:"text-sm text-text-tertiary",children:["No MCP tool activity in the last ",c]})}),e.jsxs("div",{className:"grid grid-cols-1 @form-cols:grid-cols-2 gap-4",children:[e.jsxs("button",{onClick:()=>r("/mcp/servers"),className:"bg-surface-raised border border-surface-border rounded-md p-5 text-left hover:border-accent/40 transition-colors",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-3",children:[e.jsx(E,{size:16,className:"text-accent shrink-0"}),e.jsx("span",{className:"text-sm font-medium text-text-primary",children:"Tool Servers"})]}),e.jsxs("p",{className:"text-2xl font-light tabular-nums text-text-primary mb-1",children:[L?"—":p.length,e.jsxs("span",{className:"text-sm text-text-tertiary font-normal ml-2",children:["server",p.length!==1?"s":""," · ",M," tool",M!==1?"s":""]})]}),e.jsx("p",{className:"text-2xs text-text-tertiary leading-relaxed mt-2",children:"Built-in and external MCP servers. Each server exposes tools that workflows and agents can call."})]}),e.jsxs("button",{onClick:()=>r("/mcp/workflows"),className:"bg-surface-raised border border-surface-border rounded-md p-5 text-left hover:border-accent/40 transition-colors",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-3",children:[e.jsx(O,{size:16,className:"text-purple-400 shrink-0"}),e.jsx("span",{className:"text-sm font-medium text-text-primary",children:"Pipeline Registry"})]}),e.jsxs("p",{className:"text-2xl font-light tabular-nums text-text-primary mb-1",children:[_?"—":h.length,e.jsxs("span",{className:"text-sm text-text-tertiary font-normal ml-2",children:["workflow",h.length!==1?"s":""," · ",S," server",S!==1?"s":""]})]}),e.jsx("p",{className:"text-2xs text-text-tertiary leading-relaxed mt-2",children:"Compiled from discovery runs. Deterministic tool-to-tool pipelines — no LLM, no token costs."})]})]})]})}export{ee as McpOverview};
2
- //# sourceMappingURL=McpOverview-Do31A1jL.js.map
1
+ import{a as o,j as e}from"./vendor-query-DvWWuNIB.js";import{u as A}from"./mcp-DtWRQM1G.js";import{u as F}from"./pipelines-ClmRtlkR.js";import{u as I}from"./yaml-workflows-S7qlgdg6.js";import{u as W}from"./controlplane-INfcW_9F.js";import{P as z}from"./PageHeader-DiGWAQlR.js";import{S as b}from"./StatCard-nWY4sndl.js";import{Q as E,W as O}from"./vendor-icons-en0_uSRD.js";import{u as U}from"./vendor-react-_9U4mKFr.js";import"./index-xycFf66M.js";const T=[{label:"1h",ms:36e5},{label:"24h",ms:864e5},{label:"7d",ms:6048e5},{label:"30d",ms:2592e6}];function q(r){return r<1e3?`${Math.round(r)}ms`:r<6e4?`${(r/1e3).toFixed(1)}s`:r<36e5?`${(r/6e4).toFixed(1)}m`:`${(r/36e5).toFixed(1)}h`}function j({value:r,colorClass:c,onClick:v}){return r===0?e.jsx("span",{className:"text-text-tertiary",children:"0"}):e.jsx("button",{onClick:v,className:`${c} hover:underline tabular-nums font-medium`,children:r})}function ee(){const r=U(),[c,v]=o.useState("24h"),[D,P]=o.useState(""),{data:d}=W(),k=o.useMemo(()=>((d==null?void 0:d.apps)??[]).map(t=>t.appId).sort(),[d==null?void 0:d.apps]),u=D||k[0]||"",{data:m}=F({limit:500,app_id:u}),{data:N,isLoading:L}=A(),{data:y,isLoading:_}=I({limit:200}),w=k,p=(N==null?void 0:N.servers)??[],h=(y==null?void 0:y.workflows)??[],M=o.useMemo(()=>p.reduce((t,l)=>t+(Array.isArray(l.tool_manifest)?l.tool_manifest.length:0),0),[p]),S=o.useMemo(()=>new Set(h.map(l=>l.app_id)).size,[h]),$=o.useMemo(()=>{const t=T.find(l=>l.label===c);return Date.now()-t.ms},[c]),i=o.useMemo(()=>((m==null?void 0:m.jobs)??[]).filter(t=>new Date(t.created_at).getTime()>=$),[m==null?void 0:m.jobs,$]),C=o.useMemo(()=>{const t=new Map;for(const s of i){const a=t.get(s.entity)??{total:0,running:0,completed:0,failed:0,durations:[]};if(a.total++,s.status==="running"&&a.running++,s.status==="completed"){a.completed++;const g=new Date(s.updated_at).getTime()-new Date(s.created_at).getTime();g>0&&a.durations.push(g)}s.status==="failed"&&a.failed++,t.set(s.entity,a)}const l=[];for(const[s,a]of t)l.push({pipeline:s,...a,avgDuration:a.durations.length>0?a.durations.reduce((g,R)=>g+R,0)/a.durations.length:null});return l.sort((s,a)=>a.total-s.total)},[i]),f=o.useMemo(()=>({total:i.length,running:i.filter(t=>t.status==="running").length,completed:i.filter(t=>t.status==="completed").length,failed:i.filter(t=>t.status==="failed").length}),[i]),n=(t,l)=>{const s=new URLSearchParams;u&&s.set("namespace",u),t&&s.set("entity",t),l&&s.set("status",l);const a=s.toString();r(`/mcp/executions${a?`?${a}`:""}`)},x="pb-2 text-2xs font-semibold uppercase tracking-widest text-text-tertiary";return e.jsxs("div",{children:[e.jsx(z,{title:"Discovered"}),e.jsxs("div",{className:"flex items-center gap-4 mb-6",children:[e.jsx("div",{className:"flex items-center gap-1",children:T.map(t=>e.jsx("button",{onClick:()=>v(t.label),className:`px-3 py-1 text-xs rounded-full transition-colors ${c===t.label?"bg-accent text-text-inverse":"text-text-tertiary hover:text-text-primary hover:bg-surface-hover"}`,children:t.label},t.label))}),w.length>1&&e.jsx("select",{value:u,onChange:t=>P(t.target.value),className:"select text-xs py-1 px-2",children:w.map(t=>e.jsx("option",{value:t,children:t},t))})]}),e.jsxs("div",{className:"grid grid-cols-4 gap-4 mb-8",children:[e.jsx(b,{label:"Total Runs",value:f.total,onClick:()=>n()}),e.jsx(b,{label:"Running",value:f.running,colorClass:"text-status-active",onClick:()=>n(void 0,"running")}),e.jsx(b,{label:"Completed",value:f.completed,colorClass:"text-status-success",onClick:()=>n(void 0,"completed")}),e.jsx(b,{label:"Failed",value:f.failed,colorClass:"text-status-error",onClick:()=>n(void 0,"failed")})]}),C.length>0&&e.jsxs("table",{className:"w-full text-left mb-10",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-surface-border",children:[e.jsx("th",{className:x,children:"Tool"}),e.jsx("th",{className:`${x} text-right w-20`,children:"Total"}),e.jsx("th",{className:`${x} text-right w-20`,children:"Running"}),e.jsx("th",{className:`${x} text-right w-24`,children:"Completed"}),e.jsx("th",{className:`${x} text-right w-20`,children:"Failed"}),e.jsx("th",{className:`${x} text-right w-28`,children:"Avg Duration"})]})}),e.jsx("tbody",{children:C.map(t=>e.jsxs("tr",{className:"border-b border-surface-border last:border-b-0",children:[e.jsx("td",{className:"py-3 text-sm font-mono text-text-primary",children:e.jsx("button",{onClick:()=>n(t.pipeline),className:"hover:text-accent hover:underline",children:t.pipeline})}),e.jsx("td",{className:"py-3 text-sm text-right",children:e.jsx(j,{value:t.total,colorClass:"text-text-secondary",onClick:()=>n(t.pipeline)})}),e.jsx("td",{className:"py-3 text-sm text-right",children:e.jsx(j,{value:t.running,colorClass:"text-status-active",onClick:()=>n(t.pipeline,"running")})}),e.jsx("td",{className:"py-3 text-sm text-right",children:e.jsx(j,{value:t.completed,colorClass:"text-status-success",onClick:()=>n(t.pipeline,"completed")})}),e.jsx("td",{className:"py-3 text-sm text-right",children:e.jsx(j,{value:t.failed,colorClass:"text-status-error",onClick:()=>n(t.pipeline,"failed")})}),e.jsx("td",{className:"py-3 text-sm font-mono text-text-secondary text-right",children:t.avgDuration!==null?q(t.avgDuration):"—"})]},t.pipeline))})]}),C.length===0&&e.jsx("div",{className:"py-12 text-center mb-8",children:e.jsxs("p",{className:"text-sm text-text-tertiary",children:["No MCP tool activity in the last ",c]})}),e.jsxs("div",{className:"grid grid-cols-1 @form-cols:grid-cols-2 gap-4",children:[e.jsxs("button",{onClick:()=>r("/mcp/servers"),className:"bg-surface-raised border border-surface-border rounded-md p-5 text-left hover:border-accent/40 transition-colors",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-3",children:[e.jsx(E,{size:16,className:"text-accent shrink-0"}),e.jsx("span",{className:"text-sm font-medium text-text-primary",children:"Tool Servers"})]}),e.jsxs("p",{className:"text-2xl font-light tabular-nums text-text-primary mb-1",children:[L?"—":p.length,e.jsxs("span",{className:"text-sm text-text-tertiary font-normal ml-2",children:["server",p.length!==1?"s":""," · ",M," tool",M!==1?"s":""]})]}),e.jsx("p",{className:"text-2xs text-text-tertiary leading-relaxed mt-2",children:"Built-in and external MCP servers. Each server exposes tools that workflows and agents can call."})]}),e.jsxs("button",{onClick:()=>r("/mcp/workflows"),className:"bg-surface-raised border border-surface-border rounded-md p-5 text-left hover:border-accent/40 transition-colors",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-3",children:[e.jsx(O,{size:16,className:"text-purple-400 shrink-0"}),e.jsx("span",{className:"text-sm font-medium text-text-primary",children:"Pipeline Registry"})]}),e.jsxs("p",{className:"text-2xl font-light tabular-nums text-text-primary mb-1",children:[_?"—":h.length,e.jsxs("span",{className:"text-sm text-text-tertiary font-normal ml-2",children:["workflow",h.length!==1?"s":""," · ",S," server",S!==1?"s":""]})]}),e.jsx("p",{className:"text-2xs text-text-tertiary leading-relaxed mt-2",children:"Compiled from discovery runs. Deterministic tool-to-tool pipelines — no LLM, no token costs."})]})]})]})}export{ee as McpOverview};
2
+ //# sourceMappingURL=McpOverview-BD3UWbcC.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"McpOverview-Do31A1jL.js","sources":["../../src/pages/mcp/McpOverview.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Server, Workflow } from 'lucide-react';\nimport { useMcpServers } from '../../api/mcp';\nimport { useMcpRuns } from '../../api/pipelines';\nimport { useYamlWorkflows } from '../../api/yaml-workflows';\nimport { useControlPlaneApps } from '../../api/controlplane';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { StatCard } from '../../components/common/data/StatCard';\nimport type { McpToolManifest } from '../../api/types';\n\n// ── Duration filter ──────────────────────────────────────────────────────────\n\nconst DURATIONS = [\n { label: '1h', ms: 3_600_000 },\n { label: '24h', ms: 86_400_000 },\n { label: '7d', ms: 604_800_000 },\n { label: '30d', ms: 2_592_000_000 },\n] as const;\n\ntype DurationLabel = (typeof DURATIONS)[number]['label'];\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${Math.round(ms)}ms`;\n if (ms < 60_000) return `${(ms / 1000).toFixed(1)}s`;\n if (ms < 3_600_000) return `${(ms / 60_000).toFixed(1)}m`;\n return `${(ms / 3_600_000).toFixed(1)}h`;\n}\n\ninterface PipelineStats {\n pipeline: string;\n total: number;\n running: number;\n completed: number;\n failed: number;\n avgDuration: number | null;\n}\n\n// ── Reusable components ──────────────────────────────────────────────────────\n\nfunction StatCell({\n value,\n colorClass,\n onClick,\n}: {\n value: number;\n colorClass: string;\n onClick: () => void;\n}) {\n if (value === 0) {\n return <span className=\"text-text-tertiary\">0</span>;\n }\n return (\n <button\n onClick={onClick}\n className={`${colorClass} hover:underline tabular-nums font-medium`}\n >\n {value}\n </button>\n );\n}\n\n// ── Page ─────────────────────────────────────────────────────────────────────\n\nexport function McpOverview() {\n const navigate = useNavigate();\n const [duration, setDuration] = useState<DurationLabel>('24h');\n const [namespace, setNamespace] = useState('');\n\n const { data: appsData } = useControlPlaneApps();\n\n // Auto-select the first namespace when available\n const nsNames = useMemo(() => (appsData?.apps ?? []).map((a: any) => a.appId).sort(), [appsData?.apps]);\n const effectiveNamespace = namespace || nsNames[0] || '';\n\n const { data: allRuns } = useMcpRuns({ limit: 500, app_id: effectiveNamespace });\n const { data: serverData, isLoading: serversLoading } = useMcpServers();\n const { data: yamlData, isLoading: yamlLoading } = useYamlWorkflows({ limit: 200 });\n\n const namespaces = nsNames;\n\n // ── Server counts ────────────────────────────────────────────\n const servers = serverData?.servers ?? [];\n const yamlWorkflows = yamlData?.workflows ?? [];\n\n const serverToolCount = useMemo(\n () => servers.reduce((sum, s) => sum + (Array.isArray(s.tool_manifest) ? (s.tool_manifest as McpToolManifest[]).length : 0), 0),\n [servers],\n );\n\n const workflowServerCount = useMemo(() => {\n const appIds = new Set(yamlWorkflows.map((wf) => wf.app_id));\n return appIds.size;\n }, [yamlWorkflows]);\n\n // ── Run stats ──────────────────────────────────────────────────\n const cutoff = useMemo(() => {\n const d = DURATIONS.find((d) => d.label === duration)!;\n return Date.now() - d.ms;\n }, [duration]);\n\n const runs = useMemo(\n () => (allRuns?.jobs ?? []).filter((j) => new Date(j.created_at).getTime() >= cutoff),\n [allRuns?.jobs, cutoff],\n );\n\n const byPipeline = useMemo(() => {\n const map = new Map<string, { total: number; running: number; completed: number; failed: number; durations: number[] }>();\n for (const j of runs) {\n const entry = map.get(j.entity) ?? { total: 0, running: 0, completed: 0, failed: 0, durations: [] };\n entry.total++;\n if (j.status === 'running') entry.running++;\n if (j.status === 'completed') {\n entry.completed++;\n const dur = new Date(j.updated_at).getTime() - new Date(j.created_at).getTime();\n if (dur > 0) entry.durations.push(dur);\n }\n if (j.status === 'failed') entry.failed++;\n map.set(j.entity, entry);\n }\n\n const result: PipelineStats[] = [];\n for (const [pipeline, stats] of map) {\n result.push({\n pipeline,\n ...stats,\n avgDuration: stats.durations.length > 0\n ? stats.durations.reduce((a, b) => a + b, 0) / stats.durations.length\n : null,\n });\n }\n return result.sort((a, b) => b.total - a.total);\n }, [runs]);\n\n const totals = useMemo(() => ({\n total: runs.length,\n running: runs.filter((j) => j.status === 'running').length,\n completed: runs.filter((j) => j.status === 'completed').length,\n failed: runs.filter((j) => j.status === 'failed').length,\n }), [runs]);\n\n const goToRuns = (entity?: string, status?: string) => {\n const params = new URLSearchParams();\n if (effectiveNamespace) params.set('namespace', effectiveNamespace);\n if (entity) params.set('entity', entity);\n if (status) params.set('status', status);\n const qs = params.toString();\n navigate(`/mcp/executions${qs ? `?${qs}` : ''}`);\n };\n\n const thCls = 'pb-2 text-2xs font-semibold uppercase tracking-widest text-text-tertiary';\n\n return (\n <div>\n <PageHeader title=\"Discovered\" />\n\n {/* ── Duration tabs + namespace ────────────────────────── */}\n <div className=\"flex items-center gap-4 mb-6\">\n <div className=\"flex items-center gap-1\">\n {DURATIONS.map((d) => (\n <button\n key={d.label}\n onClick={() => setDuration(d.label)}\n className={`px-3 py-1 text-xs rounded-full transition-colors ${\n duration === d.label\n ? 'bg-accent text-text-inverse'\n : 'text-text-tertiary hover:text-text-primary hover:bg-surface-hover'\n }`}\n >\n {d.label}\n </button>\n ))}\n </div>\n {namespaces.length > 1 && (\n <select\n value={effectiveNamespace}\n onChange={(e) => setNamespace(e.target.value)}\n className=\"select text-xs py-1 px-2\"\n >\n {namespaces.map((ns) => (\n <option key={ns} value={ns}>{ns}</option>\n ))}\n </select>\n )}\n </div>\n\n {/* ── Summary cards ────────────────────────────────────── */}\n <div className=\"grid grid-cols-4 gap-4 mb-8\">\n <StatCard label=\"Total Runs\" value={totals.total} onClick={() => goToRuns()} />\n <StatCard label=\"Running\" value={totals.running} colorClass=\"text-status-active\" onClick={() => goToRuns(undefined, 'running')} />\n <StatCard label=\"Completed\" value={totals.completed} colorClass=\"text-status-success\" onClick={() => goToRuns(undefined, 'completed')} />\n <StatCard label=\"Failed\" value={totals.failed} colorClass=\"text-status-error\" onClick={() => goToRuns(undefined, 'failed')} />\n </div>\n\n {/* ── By-pipeline table ────────────────────────────────── */}\n {byPipeline.length > 0 && (\n <table className=\"w-full text-left mb-10\">\n <thead>\n <tr className=\"border-b border-surface-border\">\n <th className={thCls}>Tool</th>\n <th className={`${thCls} text-right w-20`}>Total</th>\n <th className={`${thCls} text-right w-20`}>Running</th>\n <th className={`${thCls} text-right w-24`}>Completed</th>\n <th className={`${thCls} text-right w-20`}>Failed</th>\n <th className={`${thCls} text-right w-28`}>Avg Duration</th>\n </tr>\n </thead>\n <tbody>\n {byPipeline.map((row) => (\n <tr key={row.pipeline} className=\"border-b border-surface-border last:border-b-0\">\n <td className=\"py-3 text-sm font-mono text-text-primary\">\n <button\n onClick={() => goToRuns(row.pipeline)}\n className=\"hover:text-accent hover:underline\"\n >\n {row.pipeline}\n </button>\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.total} colorClass=\"text-text-secondary\" onClick={() => goToRuns(row.pipeline)} />\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.running} colorClass=\"text-status-active\" onClick={() => goToRuns(row.pipeline, 'running')} />\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.completed} colorClass=\"text-status-success\" onClick={() => goToRuns(row.pipeline, 'completed')} />\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.failed} colorClass=\"text-status-error\" onClick={() => goToRuns(row.pipeline, 'failed')} />\n </td>\n <td className=\"py-3 text-sm font-mono text-text-secondary text-right\">\n {row.avgDuration !== null ? formatDuration(row.avgDuration) : '—'}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n )}\n\n {byPipeline.length === 0 && (\n <div className=\"py-12 text-center mb-8\">\n <p className=\"text-sm text-text-tertiary\">\n No MCP tool activity in the last {duration}\n </p>\n </div>\n )}\n\n {/* ── Server inventory (compact cards) ─────────────────── */}\n <div className=\"grid grid-cols-1 @form-cols:grid-cols-2 gap-4\">\n <button\n onClick={() => navigate('/mcp/servers')}\n className=\"bg-surface-raised border border-surface-border rounded-md p-5 text-left hover:border-accent/40 transition-colors\"\n >\n <div className=\"flex items-center gap-3 mb-3\">\n <Server size={16} className=\"text-accent shrink-0\" />\n <span className=\"text-sm font-medium text-text-primary\">Tool Servers</span>\n </div>\n <p className=\"text-2xl font-light tabular-nums text-text-primary mb-1\">\n {serversLoading ? '—' : servers.length}\n <span className=\"text-sm text-text-tertiary font-normal ml-2\">\n server{servers.length !== 1 ? 's' : ''} · {serverToolCount} tool{serverToolCount !== 1 ? 's' : ''}\n </span>\n </p>\n <p className=\"text-2xs text-text-tertiary leading-relaxed mt-2\">\n Built-in and external MCP servers. Each server exposes tools that workflows and agents can call.\n </p>\n </button>\n\n <button\n onClick={() => navigate('/mcp/workflows')}\n className=\"bg-surface-raised border border-surface-border rounded-md p-5 text-left hover:border-accent/40 transition-colors\"\n >\n <div className=\"flex items-center gap-3 mb-3\">\n <Workflow size={16} className=\"text-purple-400 shrink-0\" />\n <span className=\"text-sm font-medium text-text-primary\">Pipeline Registry</span>\n </div>\n <p className=\"text-2xl font-light tabular-nums text-text-primary mb-1\">\n {yamlLoading ? '—' : yamlWorkflows.length}\n <span className=\"text-sm text-text-tertiary font-normal ml-2\">\n workflow{yamlWorkflows.length !== 1 ? 's' : ''} · {workflowServerCount} server{workflowServerCount !== 1 ? 's' : ''}\n </span>\n </p>\n <p className=\"text-2xs text-text-tertiary leading-relaxed mt-2\">\n Compiled from discovery runs. Deterministic tool-to-tool pipelines — no LLM, no token costs.\n </p>\n </button>\n </div>\n </div>\n );\n}\n"],"names":["DURATIONS","formatDuration","ms","StatCell","value","colorClass","onClick","jsx","McpOverview","navigate","useNavigate","duration","setDuration","useState","namespace","setNamespace","appsData","useControlPlaneApps","nsNames","useMemo","a","effectiveNamespace","allRuns","useMcpRuns","serverData","serversLoading","useMcpServers","yamlData","yamlLoading","useYamlWorkflows","namespaces","servers","yamlWorkflows","serverToolCount","sum","s","workflowServerCount","wf","cutoff","d","runs","j","byPipeline","map","entry","dur","result","pipeline","stats","b","totals","goToRuns","entity","status","params","qs","thCls","PageHeader","jsxs","e","ns","StatCard","row","Server","Workflow"],"mappings":"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"}
1
+ {"version":3,"file":"McpOverview-BD3UWbcC.js","sources":["../../src/pages/mcp/McpOverview.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Server, Workflow } from 'lucide-react';\nimport { useMcpServers } from '../../api/mcp';\nimport { useMcpRuns } from '../../api/pipelines';\nimport { useYamlWorkflows } from '../../api/yaml-workflows';\nimport { useControlPlaneApps } from '../../api/controlplane';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { StatCard } from '../../components/common/data/StatCard';\nimport type { McpToolManifest } from '../../api/types';\n\n// ── Duration filter ──────────────────────────────────────────────────────────\n\nconst DURATIONS = [\n { label: '1h', ms: 3_600_000 },\n { label: '24h', ms: 86_400_000 },\n { label: '7d', ms: 604_800_000 },\n { label: '30d', ms: 2_592_000_000 },\n] as const;\n\ntype DurationLabel = (typeof DURATIONS)[number]['label'];\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${Math.round(ms)}ms`;\n if (ms < 60_000) return `${(ms / 1000).toFixed(1)}s`;\n if (ms < 3_600_000) return `${(ms / 60_000).toFixed(1)}m`;\n return `${(ms / 3_600_000).toFixed(1)}h`;\n}\n\ninterface PipelineStats {\n pipeline: string;\n total: number;\n running: number;\n completed: number;\n failed: number;\n avgDuration: number | null;\n}\n\n// ── Reusable components ──────────────────────────────────────────────────────\n\nfunction StatCell({\n value,\n colorClass,\n onClick,\n}: {\n value: number;\n colorClass: string;\n onClick: () => void;\n}) {\n if (value === 0) {\n return <span className=\"text-text-tertiary\">0</span>;\n }\n return (\n <button\n onClick={onClick}\n className={`${colorClass} hover:underline tabular-nums font-medium`}\n >\n {value}\n </button>\n );\n}\n\n// ── Page ─────────────────────────────────────────────────────────────────────\n\nexport function McpOverview() {\n const navigate = useNavigate();\n const [duration, setDuration] = useState<DurationLabel>('24h');\n const [namespace, setNamespace] = useState('');\n\n const { data: appsData } = useControlPlaneApps();\n\n // Auto-select the first namespace when available\n const nsNames = useMemo(() => (appsData?.apps ?? []).map((a: any) => a.appId).sort(), [appsData?.apps]);\n const effectiveNamespace = namespace || nsNames[0] || '';\n\n const { data: allRuns } = useMcpRuns({ limit: 500, app_id: effectiveNamespace });\n const { data: serverData, isLoading: serversLoading } = useMcpServers();\n const { data: yamlData, isLoading: yamlLoading } = useYamlWorkflows({ limit: 200 });\n\n const namespaces = nsNames;\n\n // ── Server counts ────────────────────────────────────────────\n const servers = serverData?.servers ?? [];\n const yamlWorkflows = yamlData?.workflows ?? [];\n\n const serverToolCount = useMemo(\n () => servers.reduce((sum, s) => sum + (Array.isArray(s.tool_manifest) ? (s.tool_manifest as McpToolManifest[]).length : 0), 0),\n [servers],\n );\n\n const workflowServerCount = useMemo(() => {\n const appIds = new Set(yamlWorkflows.map((wf) => wf.app_id));\n return appIds.size;\n }, [yamlWorkflows]);\n\n // ── Run stats ──────────────────────────────────────────────────\n const cutoff = useMemo(() => {\n const d = DURATIONS.find((d) => d.label === duration)!;\n return Date.now() - d.ms;\n }, [duration]);\n\n const runs = useMemo(\n () => (allRuns?.jobs ?? []).filter((j) => new Date(j.created_at).getTime() >= cutoff),\n [allRuns?.jobs, cutoff],\n );\n\n const byPipeline = useMemo(() => {\n const map = new Map<string, { total: number; running: number; completed: number; failed: number; durations: number[] }>();\n for (const j of runs) {\n const entry = map.get(j.entity) ?? { total: 0, running: 0, completed: 0, failed: 0, durations: [] };\n entry.total++;\n if (j.status === 'running') entry.running++;\n if (j.status === 'completed') {\n entry.completed++;\n const dur = new Date(j.updated_at).getTime() - new Date(j.created_at).getTime();\n if (dur > 0) entry.durations.push(dur);\n }\n if (j.status === 'failed') entry.failed++;\n map.set(j.entity, entry);\n }\n\n const result: PipelineStats[] = [];\n for (const [pipeline, stats] of map) {\n result.push({\n pipeline,\n ...stats,\n avgDuration: stats.durations.length > 0\n ? stats.durations.reduce((a, b) => a + b, 0) / stats.durations.length\n : null,\n });\n }\n return result.sort((a, b) => b.total - a.total);\n }, [runs]);\n\n const totals = useMemo(() => ({\n total: runs.length,\n running: runs.filter((j) => j.status === 'running').length,\n completed: runs.filter((j) => j.status === 'completed').length,\n failed: runs.filter((j) => j.status === 'failed').length,\n }), [runs]);\n\n const goToRuns = (entity?: string, status?: string) => {\n const params = new URLSearchParams();\n if (effectiveNamespace) params.set('namespace', effectiveNamespace);\n if (entity) params.set('entity', entity);\n if (status) params.set('status', status);\n const qs = params.toString();\n navigate(`/mcp/executions${qs ? `?${qs}` : ''}`);\n };\n\n const thCls = 'pb-2 text-2xs font-semibold uppercase tracking-widest text-text-tertiary';\n\n return (\n <div>\n <PageHeader title=\"Discovered\" />\n\n {/* ── Duration tabs + namespace ────────────────────────── */}\n <div className=\"flex items-center gap-4 mb-6\">\n <div className=\"flex items-center gap-1\">\n {DURATIONS.map((d) => (\n <button\n key={d.label}\n onClick={() => setDuration(d.label)}\n className={`px-3 py-1 text-xs rounded-full transition-colors ${\n duration === d.label\n ? 'bg-accent text-text-inverse'\n : 'text-text-tertiary hover:text-text-primary hover:bg-surface-hover'\n }`}\n >\n {d.label}\n </button>\n ))}\n </div>\n {namespaces.length > 1 && (\n <select\n value={effectiveNamespace}\n onChange={(e) => setNamespace(e.target.value)}\n className=\"select text-xs py-1 px-2\"\n >\n {namespaces.map((ns) => (\n <option key={ns} value={ns}>{ns}</option>\n ))}\n </select>\n )}\n </div>\n\n {/* ── Summary cards ────────────────────────────────────── */}\n <div className=\"grid grid-cols-4 gap-4 mb-8\">\n <StatCard label=\"Total Runs\" value={totals.total} onClick={() => goToRuns()} />\n <StatCard label=\"Running\" value={totals.running} colorClass=\"text-status-active\" onClick={() => goToRuns(undefined, 'running')} />\n <StatCard label=\"Completed\" value={totals.completed} colorClass=\"text-status-success\" onClick={() => goToRuns(undefined, 'completed')} />\n <StatCard label=\"Failed\" value={totals.failed} colorClass=\"text-status-error\" onClick={() => goToRuns(undefined, 'failed')} />\n </div>\n\n {/* ── By-pipeline table ────────────────────────────────── */}\n {byPipeline.length > 0 && (\n <table className=\"w-full text-left mb-10\">\n <thead>\n <tr className=\"border-b border-surface-border\">\n <th className={thCls}>Tool</th>\n <th className={`${thCls} text-right w-20`}>Total</th>\n <th className={`${thCls} text-right w-20`}>Running</th>\n <th className={`${thCls} text-right w-24`}>Completed</th>\n <th className={`${thCls} text-right w-20`}>Failed</th>\n <th className={`${thCls} text-right w-28`}>Avg Duration</th>\n </tr>\n </thead>\n <tbody>\n {byPipeline.map((row) => (\n <tr key={row.pipeline} className=\"border-b border-surface-border last:border-b-0\">\n <td className=\"py-3 text-sm font-mono text-text-primary\">\n <button\n onClick={() => goToRuns(row.pipeline)}\n className=\"hover:text-accent hover:underline\"\n >\n {row.pipeline}\n </button>\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.total} colorClass=\"text-text-secondary\" onClick={() => goToRuns(row.pipeline)} />\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.running} colorClass=\"text-status-active\" onClick={() => goToRuns(row.pipeline, 'running')} />\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.completed} colorClass=\"text-status-success\" onClick={() => goToRuns(row.pipeline, 'completed')} />\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.failed} colorClass=\"text-status-error\" onClick={() => goToRuns(row.pipeline, 'failed')} />\n </td>\n <td className=\"py-3 text-sm font-mono text-text-secondary text-right\">\n {row.avgDuration !== null ? formatDuration(row.avgDuration) : '—'}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n )}\n\n {byPipeline.length === 0 && (\n <div className=\"py-12 text-center mb-8\">\n <p className=\"text-sm text-text-tertiary\">\n No MCP tool activity in the last {duration}\n </p>\n </div>\n )}\n\n {/* ── Server inventory (compact cards) ─────────────────── */}\n <div className=\"grid grid-cols-1 @form-cols:grid-cols-2 gap-4\">\n <button\n onClick={() => navigate('/mcp/servers')}\n className=\"bg-surface-raised border border-surface-border rounded-md p-5 text-left hover:border-accent/40 transition-colors\"\n >\n <div className=\"flex items-center gap-3 mb-3\">\n <Server size={16} className=\"text-accent shrink-0\" />\n <span className=\"text-sm font-medium text-text-primary\">Tool Servers</span>\n </div>\n <p className=\"text-2xl font-light tabular-nums text-text-primary mb-1\">\n {serversLoading ? '—' : servers.length}\n <span className=\"text-sm text-text-tertiary font-normal ml-2\">\n server{servers.length !== 1 ? 's' : ''} · {serverToolCount} tool{serverToolCount !== 1 ? 's' : ''}\n </span>\n </p>\n <p className=\"text-2xs text-text-tertiary leading-relaxed mt-2\">\n Built-in and external MCP servers. Each server exposes tools that workflows and agents can call.\n </p>\n </button>\n\n <button\n onClick={() => navigate('/mcp/workflows')}\n className=\"bg-surface-raised border border-surface-border rounded-md p-5 text-left hover:border-accent/40 transition-colors\"\n >\n <div className=\"flex items-center gap-3 mb-3\">\n <Workflow size={16} className=\"text-purple-400 shrink-0\" />\n <span className=\"text-sm font-medium text-text-primary\">Pipeline Registry</span>\n </div>\n <p className=\"text-2xl font-light tabular-nums text-text-primary mb-1\">\n {yamlLoading ? '—' : yamlWorkflows.length}\n <span className=\"text-sm text-text-tertiary font-normal ml-2\">\n workflow{yamlWorkflows.length !== 1 ? 's' : ''} · {workflowServerCount} server{workflowServerCount !== 1 ? 's' : ''}\n </span>\n </p>\n <p className=\"text-2xs text-text-tertiary leading-relaxed mt-2\">\n Compiled from discovery runs. Deterministic tool-to-tool pipelines — no LLM, no token costs.\n </p>\n </button>\n </div>\n </div>\n );\n}\n"],"names":["DURATIONS","formatDuration","ms","StatCell","value","colorClass","onClick","jsx","McpOverview","navigate","useNavigate","duration","setDuration","useState","namespace","setNamespace","appsData","useControlPlaneApps","nsNames","useMemo","a","effectiveNamespace","allRuns","useMcpRuns","serverData","serversLoading","useMcpServers","yamlData","yamlLoading","useYamlWorkflows","namespaces","servers","yamlWorkflows","serverToolCount","sum","s","workflowServerCount","wf","cutoff","d","runs","j","byPipeline","map","entry","dur","result","pipeline","stats","b","totals","goToRuns","entity","status","params","qs","thCls","PageHeader","jsxs","e","ns","StatCard","row","Server","Workflow"],"mappings":"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"}