@hotmeshio/long-tail 0.7.2 → 0.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dashboard/dist/assets/{AdminDashboard-rZDVS2G_.js → AdminDashboard-C9eE1VEp.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-rZDVS2G_.js.map → AdminDashboard-C9eE1VEp.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-CbyyCjCT.js → AgentConfigPage-Ba8QfXM2.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-CbyyCjCT.js.map → AgentConfigPage-Ba8QfXM2.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-DMeHvidT.js → AgentDetailPage-DVmec0CP.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-DMeHvidT.js.map → AgentDetailPage-DVmec0CP.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-C8fKLxh-.js → AgentsPage-DNiCYMh3.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-C8fKLxh-.js.map → AgentsPage-DNiCYMh3.js.map} +1 -1
- package/dashboard/dist/assets/{AvailableEscalationsPage-CUHcybKU.js → AvailableEscalationsPage-gDIF8ocC.js} +2 -2
- package/dashboard/dist/assets/{AvailableEscalationsPage-CUHcybKU.js.map → AvailableEscalationsPage-gDIF8ocC.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-DGhniNcy.js → BotPicker-3wBcBavT.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-DGhniNcy.js.map → BotPicker-3wBcBavT.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-ClfuW4ya.js → CapabilitiesPage-WoPkND2y.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-ClfuW4ya.js.map → CapabilitiesPage-WoPkND2y.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-DnECdKEY.js → CollapsibleSection-Cx99mqNN.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-DnECdKEY.js.map → CollapsibleSection-Cx99mqNN.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-DdZ-jyyc.js → CredentialsPage-DbNaoPbF.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-DdZ-jyyc.js.map → CredentialsPage-DbNaoPbF.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-CymxLvY0.js → CronLabel-DLW4_Zg4.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-CymxLvY0.js.map → CronLabel-DLW4_Zg4.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-8JHvVWD2.js → CustomDurationPicker-BRUFjkiu.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-8JHvVWD2.js.map → CustomDurationPicker-BRUFjkiu.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-BRZfw_Af.js → ElapsedCell-BtmDQaym.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-BRZfw_Af.js.map → ElapsedCell-BtmDQaym.js.map} +1 -1
- package/dashboard/dist/assets/EscalationSchemaPage-Bm4yBEGN.js +9 -0
- package/dashboard/dist/assets/EscalationSchemaPage-Bm4yBEGN.js.map +1 -0
- package/dashboard/dist/assets/{EscalationsOverview-CiQO3ntf.js → EscalationsOverview-B3xZwTQA.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-CiQO3ntf.js.map → EscalationsOverview-B3xZwTQA.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-CLuAbba_.js → EventTable-Bh9FKXLI.js} +2 -2
- package/dashboard/dist/assets/{EventTable-CLuAbba_.js.map → EventTable-Bh9FKXLI.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-BFRi6Nny.js → GraphInvokePage-ov_ANlaE.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-BFRi6Nny.js.map → GraphInvokePage-ov_ANlaE.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-m1pnxilb.js → HomePage-D0DV6izb.js} +2 -2
- package/dashboard/dist/assets/{HomePage-m1pnxilb.js.map → HomePage-D0DV6izb.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-D4Y-M7wN.js → ListToolbar-FpcvqNkN.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-D4Y-M7wN.js.map → ListToolbar-FpcvqNkN.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-mfJpETsW.js → McpOverview-DcuRiAff.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-mfJpETsW.js.map → McpOverview-DcuRiAff.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-Cb99vI7v.js → McpQueryDetailPage-BcYl67KP.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-Cb99vI7v.js.map → McpQueryDetailPage-BcYl67KP.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-CKKOxks0.js → McpQueryPage-C3GDzqZM.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-CKKOxks0.js.map → McpQueryPage-C3GDzqZM.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-CyTbHs0J.js → McpRunDetailPage-SzOyhDBW.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-CyTbHs0J.js.map → McpRunDetailPage-SzOyhDBW.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-MIwmK-Ky.js → McpRunsPage-BwgB6mRV.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-MIwmK-Ky.js.map → McpRunsPage-BwgB6mRV.js.map} +1 -1
- package/dashboard/dist/assets/{OperationsPage-DPesph0U.js → OperationsPage-BCr21p8I.js} +2 -2
- package/dashboard/dist/assets/{OperationsPage-DPesph0U.js.map → OperationsPage-BCr21p8I.js.map} +1 -1
- package/dashboard/dist/assets/{OperatorDashboard-K1gzULr7.js → OperatorDashboard-DSXh-yYw.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-K1gzULr7.js.map → OperatorDashboard-DSXh-yYw.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-DBIrY6Vd.js → ProcessDetailPage-iIB1rwEt.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-DBIrY6Vd.js.map → ProcessDetailPage-iIB1rwEt.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-CrLGDCAD.js → ProcessesListPage-BrqWR2zr.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-CrLGDCAD.js.map → ProcessesListPage-BrqWR2zr.js.map} +1 -1
- package/dashboard/dist/assets/RoleDetailPage-DS37tJhq.js +11 -0
- package/dashboard/dist/assets/RoleDetailPage-DS37tJhq.js.map +1 -0
- package/dashboard/dist/assets/RolesPage-Bzp9FhAl.js +2 -0
- package/dashboard/dist/assets/{RolesPage-B0ZgjB2V.js.map → RolesPage-Bzp9FhAl.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-DA0h41ml.js → RunAsSelector-DXbHRxQs.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-DA0h41ml.js.map → RunAsSelector-DXbHRxQs.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-t5B71hwd.js → StickyPagination-D8XuMSWD.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-t5B71hwd.js.map → StickyPagination-D8XuMSWD.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-CYFnZsYA.js → StreamMessageDetail-D5v95pmz.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-CYFnZsYA.js.map → StreamMessageDetail-D5v95pmz.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-CY18gBek.js → SwimlaneTimeline-CUEf2R5R.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-CY18gBek.js.map → SwimlaneTimeline-CUEf2R5R.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-B9owzuhV.js → TaskDetailPage-BJvKNwEe.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-B9owzuhV.js.map → TaskDetailPage-BJvKNwEe.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-Dlsu7cWG.js → TasksListPage-CM7BWh_h.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-Dlsu7cWG.js.map → TasksListPage-CM7BWh_h.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-CSzifQXB.js → TimeAgo-D1K7xKq5.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-CSzifQXB.js.map → TimeAgo-D1K7xKq5.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-CIxgN57O.js → TimestampCell-7G0echgP.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-CIxgN57O.js.map → TimestampCell-7G0echgP.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-Bw844EW3.js → ToolTestPanel-LxuJvURK.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-Bw844EW3.js.map → ToolTestPanel-LxuJvURK.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-HuDx2oAW.js → TopicDetailPage-JvAX6rrR.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-HuDx2oAW.js.map → TopicDetailPage-JvAX6rrR.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-CAG0RhAK.js → TopicsPage-tFT2AcTz.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-CAG0RhAK.js.map → TopicsPage-tFT2AcTz.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-CoGYeig8.js → UserName-Djz0nmaZ.js} +2 -2
- package/dashboard/dist/assets/{UserName-CoGYeig8.js.map → UserName-Djz0nmaZ.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-Dhb9EWgI.js → WorkflowExecutionPage-f53hilbI.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-Dhb9EWgI.js.map → WorkflowExecutionPage-f53hilbI.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-bJ6Zebfv.js → WorkflowsDashboard-DM9Xe665.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-bJ6Zebfv.js.map → WorkflowsDashboard-DM9Xe665.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-B8262fVx.js → WorkflowsOverview-CUGSrx9N.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-B8262fVx.js.map → WorkflowsOverview-CUGSrx9N.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-DhW3q2cO.js → YamlWorkflowDetailPage-B1_yqxAw.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-DhW3q2cO.js.map → YamlWorkflowDetailPage-B1_yqxAw.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-C8hBjSn_.js → YamlWorkflowsPage-NtGvqiu7.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-C8hBjSn_.js.map → YamlWorkflowsPage-NtGvqiu7.js.map} +1 -1
- package/dashboard/dist/assets/{agents-j2YErVp4.js → agents-tML6AjDj.js} +2 -2
- package/dashboard/dist/assets/{agents-j2YErVp4.js.map → agents-tML6AjDj.js.map} +1 -1
- package/dashboard/dist/assets/{bots-CD8Bl5pL.js → bots-Cb0WTwhY.js} +2 -2
- package/dashboard/dist/assets/{bots-CD8Bl5pL.js.map → bots-Cb0WTwhY.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-Dz190EAa.js → capabilities-BGZogsi_.js} +2 -2
- package/dashboard/dist/assets/{capabilities-Dz190EAa.js.map → capabilities-BGZogsi_.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-CkUHGPA3.js → controlplane-B7VJTlZD.js} +2 -2
- package/dashboard/dist/assets/{controlplane-CkUHGPA3.js.map → controlplane-B7VJTlZD.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-BXTwi4J1.js → escalation-Bl-SQV_u.js} +2 -2
- package/dashboard/dist/assets/{escalation-BXTwi4J1.js.map → escalation-Bl-SQV_u.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-GxxwSbDk.js → escalation-columns-BlJOswRx.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-GxxwSbDk.js.map → escalation-columns-BlJOswRx.js.map} +1 -1
- package/dashboard/dist/assets/{index-NfVWOFbF.js → index--WeZDfeN.js} +2 -2
- package/dashboard/dist/assets/{index-NfVWOFbF.js.map → index--WeZDfeN.js.map} +1 -1
- package/dashboard/dist/assets/{index-BK3PVYcd.js → index-0o71lRuY.js} +2 -2
- package/dashboard/dist/assets/{index-BK3PVYcd.js.map → index-0o71lRuY.js.map} +1 -1
- package/dashboard/dist/assets/{index-DGKgXObc.js → index-3A_5CL81.js} +2 -2
- package/dashboard/dist/assets/{index-DGKgXObc.js.map → index-3A_5CL81.js.map} +1 -1
- package/dashboard/dist/assets/{index-DTrcYOM2.js → index-BorpZbZA.js} +2 -2
- package/dashboard/dist/assets/{index-DTrcYOM2.js.map → index-BorpZbZA.js.map} +1 -1
- package/dashboard/dist/assets/{index-BkwsJ-0v.js → index-CBv3UxF2.js} +2 -2
- package/dashboard/dist/assets/{index-BkwsJ-0v.js.map → index-CBv3UxF2.js.map} +1 -1
- package/dashboard/dist/assets/{index-CkL8bpdH.js → index-D0-8byNu.js} +2 -2
- package/dashboard/dist/assets/{index-CkL8bpdH.js.map → index-D0-8byNu.js.map} +1 -1
- package/dashboard/dist/assets/{index-qT7eB_Hk.js → index-DcbEIXit.js} +2 -2
- package/dashboard/dist/assets/{index-qT7eB_Hk.js.map → index-DcbEIXit.js.map} +1 -1
- package/dashboard/dist/assets/{index-YliQ4kW_.js → index-DfDfJivY.js} +2 -2
- package/dashboard/dist/assets/{index-YliQ4kW_.js.map → index-DfDfJivY.js.map} +1 -1
- package/dashboard/dist/assets/{index-D-7W2AHB.js → index-Dgw1KKpq.js} +3 -3
- package/dashboard/dist/assets/{index-D-7W2AHB.js.map → index-Dgw1KKpq.js.map} +1 -1
- package/dashboard/dist/assets/{index-CoGkgm9-.js → index-Il_g7kw5.js} +2 -2
- package/dashboard/dist/assets/{index-CoGkgm9-.js.map → index-Il_g7kw5.js.map} +1 -1
- package/dashboard/dist/assets/{index-CaMVn0kW.js → index-SCrD3l-K.js} +2 -2
- package/dashboard/dist/assets/{index-CaMVn0kW.js.map → index-SCrD3l-K.js.map} +1 -1
- package/dashboard/dist/assets/{index-n-lZY5S6.js → index-TiKh2Ctj.js} +2 -2
- package/dashboard/dist/assets/{index-n-lZY5S6.js.map → index-TiKh2Ctj.js.map} +1 -1
- package/dashboard/dist/assets/{index-eLRh-2NW.js → index-e97M6GoI.js} +2 -2
- package/dashboard/dist/assets/{index-eLRh-2NW.js.map → index-e97M6GoI.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-CSAbLtk7.js → knowledge-CDzw4E6q.js} +2 -2
- package/dashboard/dist/assets/{knowledge-CSAbLtk7.js.map → knowledge-CDzw4E6q.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-D0Ha3aEo.js → mcp-D_-NQtnG.js} +2 -2
- package/dashboard/dist/assets/{mcp-D0Ha3aEo.js.map → mcp-D_-NQtnG.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-BySmvmuS.js → mcp-query-BqZXdf9A.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-BySmvmuS.js.map → mcp-query-BqZXdf9A.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-DiqWgxJd.js → pipelines-CNLhgj8b.js} +2 -2
- package/dashboard/dist/assets/{pipelines-DiqWgxJd.js.map → pipelines-CNLhgj8b.js.map} +1 -1
- package/dashboard/dist/assets/{roles-BdtnzLsL.js → roles-CFD2eYap.js} +2 -2
- package/dashboard/dist/assets/{roles-BdtnzLsL.js.map → roles-CFD2eYap.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-DYCUi5nZ.js → tasks-DcSvF636.js} +2 -2
- package/dashboard/dist/assets/{tasks-DYCUi5nZ.js.map → tasks-DcSvF636.js.map} +1 -1
- package/dashboard/dist/assets/{topics-CA7i8ymr.js → topics-DI8TFSZv.js} +2 -2
- package/dashboard/dist/assets/{topics-CA7i8ymr.js.map → topics-DI8TFSZv.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-SfWdyc5L.js → useEventHooks-DcIgMDh3.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-SfWdyc5L.js.map → useEventHooks-DcIgMDh3.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-CZUsk5Vv.js → useNamespace-C88ZxGoX.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-CZUsk5Vv.js.map → useNamespace-C88ZxGoX.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-DKQ5dREx.js → useYamlActivityEvents-D2-yVjJ7.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-DKQ5dREx.js.map → useYamlActivityEvents-D2-yVjJ7.js.map} +1 -1
- package/dashboard/dist/assets/{users-BxKf5dAX.js → users-C0WV36X8.js} +2 -2
- package/dashboard/dist/assets/{users-BxKf5dAX.js.map → users-C0WV36X8.js.map} +1 -1
- package/dashboard/dist/assets/{workflows-DNPQ-j-7.js → workflows-CkPv7xk-.js} +2 -2
- package/dashboard/dist/assets/{workflows-DNPQ-j-7.js.map → workflows-CkPv7xk-.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-CA8BrFxc.js → yaml-workflows-BjrMQLTK.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-CA8BrFxc.js.map → yaml-workflows-BjrMQLTK.js.map} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/docs/dashboard.md +65 -23
- package/package.json +2 -2
- package/dashboard/dist/assets/EscalationSchemaPage-Do2iPKUl.js +0 -9
- package/dashboard/dist/assets/EscalationSchemaPage-Do2iPKUl.js.map +0 -1
- package/dashboard/dist/assets/RoleDetailPage-7j6Mk780.js +0 -11
- package/dashboard/dist/assets/RoleDetailPage-7j6Mk780.js.map +0 -1
- package/dashboard/dist/assets/RolesPage-B0ZgjB2V.js +0 -2
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as e}from"./vendor-query-B2UbickB.js";import{P as j}from"./PageHeader-BhaWTWcM.js";import{D as _}from"./DataTable-ZWgVQg7F.js";import{F as v,b as f}from"./FilterBar-BQ2JGg8U.js";import{S as P}from"./StickyPagination-
|
|
2
|
-
//# sourceMappingURL=McpQueryPage-
|
|
1
|
+
import{j as e}from"./vendor-query-B2UbickB.js";import{P as j}from"./PageHeader-BhaWTWcM.js";import{D as _}from"./DataTable-ZWgVQg7F.js";import{F as v,b as f}from"./FilterBar-BQ2JGg8U.js";import{S as P}from"./StickyPagination-D8XuMSWD.js";import{L as N}from"./ListToolbar-FpcvqNkN.js";import{b as C}from"./api-path-u2Jf9QXS.js";import{T as h}from"./TimestampCell-7G0echgP.js";import{E as $}from"./ElapsedCell-BtmDQaym.js";import{W}from"./WorkflowPill-IDjTRfQ8.js";import{E as S}from"./EmptyState-BcsfPq9T.js";import{R as c}from"./RowActions-BA9L9djf.js";import{u as q}from"./useFilterParams-x-Dg0Vgz.js";import{b as T}from"./useEventHooks-DcIgMDh3.js";import{u as D}from"./mcp-query-BqZXdf9A.js";import{c as y,v as B,w as g,x as k,y as F,z as L}from"./vendor-icons-CEWCGPeJ.js";import{c as M}from"./vendor-react-CXumBFUA.js";import"./index-Dgw1KKpq.js";const z={in_progress:"bg-status-active",completed:"bg-status-success",failed:"bg-status-error"};function p(s){return s.status==="completed"||Number(s.status)===0?"completed":s.is_live?"in_progress":"failed"}function E(s){return[{key:"workflow_id",label:"Workflow ID / Type",render:t=>{const o=p(t),a=z[o]??"bg-status-pending",l=o==="in_progress"?" animate-pulse":"";return e.jsxs("div",{className:"flex items-start gap-2 min-w-0",children:[e.jsx("span",{className:`w-[9px] h-[9px] shrink-0 rounded-full mt-1 ${a}${l}`,title:o}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("span",{className:"font-mono text-xs text-text-primary truncate block",children:t.workflow_id}),e.jsx("div",{className:"mt-0.5",children:e.jsx(W,{type:t.entity||"unknown"})})]})]})}},{key:"created_at",label:"Created",render:t=>e.jsx(h,{date:t.created_at}),className:"w-40",sortable:!0},{key:"updated_at",label:"Updated",render:t=>e.jsx(h,{date:t.updated_at}),className:"w-40",sortable:!0},{key:"duration",label:"Duration",render:t=>{const o=p(t);return e.jsx($,{startDate:t.created_at,endDate:o==="in_progress"?null:t.updated_at,isLive:o==="in_progress"})},className:"w-28"},{key:"actions",label:"",className:"w-28",render:t=>{const a=p(t)==="completed",l=t.entity==="mcpWorkflowBuilder";if(t.entity==="mcpWorkflowPlanner"){const r=t.set_id?`/mcp/queries/${t.workflow_id}?mode=plan&set_id=${t.set_id}`:`/mcp/queries/${t.workflow_id}?mode=plan`;return e.jsxs(c,{children:[e.jsx("button",{onClick:n=>{n.stopPropagation(),s(`${r}&step=1`)},className:"opacity-0 group-hover/row:opacity-100 text-text-tertiary hover:text-accent transition-all",title:"Plan",children:e.jsx(B,{className:"w-3.5 h-3.5",strokeWidth:1.5})}),e.jsx("button",{onClick:n=>{n.stopPropagation(),s(`${r}&step=2`)},className:`opacity-0 group-hover/row:opacity-100 transition-all ${a?"text-text-tertiary hover:text-status-success":"text-text-tertiary/30 cursor-not-allowed"}`,title:a?"Build":"Planning...",disabled:!a,children:e.jsx(g,{className:"w-3.5 h-3.5",strokeWidth:1.5})})]})}return l?e.jsxs(c,{children:[e.jsx("button",{onClick:r=>{r.stopPropagation(),s(`/mcp/queries/${t.workflow_id}?mode=builder&step=1`)},className:"opacity-0 group-hover/row:opacity-100 text-text-tertiary hover:text-accent transition-all",title:"Describe",children:e.jsx(k,{className:"w-3.5 h-3.5",strokeWidth:1.5})}),e.jsx("button",{onClick:r=>{r.stopPropagation(),s(`/mcp/queries/${t.workflow_id}?mode=builder&step=2`)},className:`opacity-0 group-hover/row:opacity-100 transition-all ${a?"text-text-tertiary hover:text-status-success":"text-text-tertiary/30 cursor-not-allowed"}`,title:a?"Profile":"Building...",disabled:!a,children:e.jsx(F,{className:"w-3.5 h-3.5",strokeWidth:1.5})})]}):e.jsxs(c,{children:[e.jsx("button",{onClick:r=>{r.stopPropagation(),s(`/mcp/queries/${t.workflow_id}?step=1`)},className:"opacity-0 group-hover/row:opacity-100 text-text-tertiary hover:text-accent transition-all",title:"Describe",children:e.jsx(k,{className:"w-3.5 h-3.5",strokeWidth:1.5})}),e.jsx("button",{onClick:r=>{r.stopPropagation(),s(`/mcp/queries/${t.workflow_id}?step=2`)},className:"opacity-0 group-hover/row:opacity-100 text-text-tertiary hover:text-status-warning transition-all",title:"Discover",children:e.jsx(L,{className:"w-3.5 h-3.5",strokeWidth:1.5})}),e.jsx("button",{onClick:r=>{r.stopPropagation(),s(`/mcp/queries/${t.workflow_id}?step=3`)},className:`opacity-0 group-hover/row:opacity-100 transition-all ${a?"text-text-tertiary hover:text-status-success":"text-text-tertiary/30 cursor-not-allowed"}`,title:a?"Compile":"Complete discovery first",disabled:!a,children:e.jsx(g,{className:"w-3.5 h-3.5",strokeWidth:1.5})})]})}}]}function ae(){const s=M(),t=E(s),{filters:o,setFilter:a,pagination:l,sort:d,setSort:r}=q({filters:{search:"",status:"",type:""},pageSize:20}),{data:n,isLoading:m,refetch:b}=D({limit:l.pageSize,offset:l.offset,search:o.search,status:o.status,entity:o.type||void 0});T();const u=(n==null?void 0:n.jobs)??[],x=(n==null?void 0:n.total)??0;return e.jsxs(e.Fragment,{children:[e.jsx(j,{title:"MCP Tool Designer",docsHash:"#docs:dashboard.md:mcp-tool-designer",actions:e.jsxs("button",{onClick:()=>s("/mcp/queries/new"),className:"btn-primary text-xs inline-flex items-center gap-1.5",children:[e.jsx(y,{className:"w-3.5 h-3.5",strokeWidth:1.5}),"Create New MCP Tool"]})}),e.jsxs(v,{actions:e.jsx(N,{onRefresh:()=>b(),apiPath:C("/workflow-states/jobs",{entity:o.type||"mcpQuery,mcpTriage,mcpWorkflowPlanner",limit:l.pageSize,offset:l.offset,sort_by:"created_at",order:"desc",status:o.status||void 0,search:o.search||void 0})}),children:[e.jsx(f,{label:"Type",value:o.type,onChange:i=>a("type",i),options:[{value:"mcpQuery",label:"Discovery"},{value:"mcpWorkflowPlanner",label:"Build"},{value:"mcpTriage",label:"Triage"}]}),e.jsx(f,{label:"Status",value:o.status,onChange:i=>a("status",i),options:[{value:"completed",label:"Completed"},{value:"running",label:"Running"},{value:"failed",label:"Failed"}]})]}),e.jsx(_,{columns:t,data:u,keyFn:i=>i.workflow_id,onRowClick:i=>{if(i.entity==="mcpWorkflowPlanner"){const w=i.set_id?`/mcp/queries/${i.workflow_id}?mode=plan&set_id=${i.set_id}`:`/mcp/queries/${i.workflow_id}?mode=plan`;s(w)}else i.entity==="mcpWorkflowBuilder"?s(`/mcp/queries/${i.workflow_id}?mode=builder`):s(`/mcp/queries/${i.workflow_id}`)},isLoading:m,emptyMessage:"",sort:d,onSort:r}),!m&&u.length===0&&e.jsx("div",{className:"cursor-pointer",onClick:()=>s("/mcp/queries/new"),children:e.jsx(S,{icon:y,title:"No tool designs yet",description:"Click to create your first MCP tool"})}),e.jsx(P,{page:l.page,pageSize:l.pageSize,total:x,totalPages:l.totalPages(x),onPageChange:l.setPage})]})}export{ae as McpQueryPage};
|
|
2
|
+
//# sourceMappingURL=McpQueryPage-C3GDzqZM.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpQueryPage-CKKOxks0.js","sources":["../../src/pages/mcp/McpQueryPage.tsx"],"sourcesContent":["import { useNavigate } from 'react-router-dom';\nimport { MessageSquare, Lightbulb, Layers, Wand2, Settings, GitBranch } from 'lucide-react';\n\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { DataTable, type Column } from '../../components/common/data/DataTable';\nimport { FilterBar, FilterSelect } from '../../components/common/data/FilterBar';\nimport { StickyPagination } from '../../components/common/data/StickyPagination';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\nimport { buildApiPath } from '../../lib/api-path';\nimport { TimestampCell } from '../../components/common/display/TimestampCell';\nimport { ElapsedCell } from '../../components/common/display/ElapsedCell';\nimport { WorkflowPill } from '../../components/common/display/WorkflowPill';\nimport { EmptyState } from '../../components/common/display/EmptyState';\nimport { RowActionGroup } from '../../components/common/layout/RowActions';\nimport { useFilterParams } from '../../hooks/useFilterParams';\nimport { useWorkflowListEvents } from '../../hooks/useEventHooks';\nimport { useMcpQueryJobs } from '../../api/mcp-query';\nimport type { LTJob } from '../../api/types';\n\nconst STATUS_DOT: Record<string, string> = {\n in_progress: 'bg-status-active',\n completed: 'bg-status-success',\n failed: 'bg-status-error',\n};\n\nfunction mapStatus(job: LTJob): string {\n if (job.status === 'completed') return 'completed';\n if (Number(job.status) === 0) return 'completed';\n if (job.is_live) return 'in_progress';\n return 'failed';\n}\n\nfunction buildColumns(navigate: ReturnType<typeof useNavigate>): Column<LTJob>[] {\n return [\n {\n key: 'workflow_id',\n label: 'Workflow ID / Type',\n render: (row) => {\n const s = mapStatus(row);\n const dotClass = STATUS_DOT[s] ?? 'bg-status-pending';\n const pulseClass = s === 'in_progress' ? ' animate-pulse' : '';\n return (\n <div className=\"flex items-start gap-2 min-w-0\">\n <span className={`w-[9px] h-[9px] shrink-0 rounded-full mt-1 ${dotClass}${pulseClass}`} title={s} />\n <div className=\"min-w-0\">\n <span className=\"font-mono text-xs text-text-primary truncate block\">\n {row.workflow_id}\n </span>\n <div className=\"mt-0.5\">\n <WorkflowPill type={row.entity || 'unknown'} />\n </div>\n </div>\n </div>\n );\n },\n },\n {\n key: 'created_at',\n label: 'Created',\n render: (row) => <TimestampCell date={row.created_at} />,\n className: 'w-40',\n sortable: true,\n },\n {\n key: 'updated_at',\n label: 'Updated',\n render: (row) => <TimestampCell date={row.updated_at} />,\n className: 'w-40',\n sortable: true,\n },\n {\n key: 'duration',\n label: 'Duration',\n render: (row) => {\n const s = mapStatus(row);\n return (\n <ElapsedCell\n startDate={row.created_at}\n endDate={s === 'in_progress' ? null : row.updated_at}\n isLive={s === 'in_progress'}\n />\n );\n },\n className: 'w-28',\n },\n {\n key: 'actions',\n label: '',\n className: 'w-28',\n render: (row) => {\n const s = mapStatus(row);\n const isComplete = s === 'completed';\n const isBuilder = row.entity === 'mcpWorkflowBuilder';\n const isPlanner = row.entity === 'mcpWorkflowPlanner';\n\n if (isPlanner) {\n const planUrl = row.set_id\n ? `/mcp/queries/${row.workflow_id}?mode=plan&set_id=${row.set_id}`\n : `/mcp/queries/${row.workflow_id}?mode=plan`;\n return (\n <RowActionGroup>\n <button\n onClick={(e) => { e.stopPropagation(); navigate(`${planUrl}&step=1`); }}\n className=\"opacity-0 group-hover/row:opacity-100 text-text-tertiary hover:text-accent transition-all\"\n title=\"Plan\"\n >\n <GitBranch className=\"w-3.5 h-3.5\" strokeWidth={1.5} />\n </button>\n <button\n onClick={(e) => { e.stopPropagation(); navigate(`${planUrl}&step=2`); }}\n className={`opacity-0 group-hover/row:opacity-100 transition-all ${isComplete ? 'text-text-tertiary hover:text-status-success' : 'text-text-tertiary/30 cursor-not-allowed'}`}\n title={isComplete ? 'Build' : 'Planning...'}\n disabled={!isComplete}\n >\n <Layers className=\"w-3.5 h-3.5\" strokeWidth={1.5} />\n </button>\n </RowActionGroup>\n );\n }\n\n if (isBuilder) {\n return (\n <RowActionGroup>\n <button\n onClick={(e) => { e.stopPropagation(); navigate(`/mcp/queries/${row.workflow_id}?mode=builder&step=1`); }}\n className=\"opacity-0 group-hover/row:opacity-100 text-text-tertiary hover:text-accent transition-all\"\n title=\"Describe\"\n >\n <MessageSquare className=\"w-3.5 h-3.5\" strokeWidth={1.5} />\n </button>\n <button\n onClick={(e) => { e.stopPropagation(); navigate(`/mcp/queries/${row.workflow_id}?mode=builder&step=2`); }}\n className={`opacity-0 group-hover/row:opacity-100 transition-all ${isComplete ? 'text-text-tertiary hover:text-status-success' : 'text-text-tertiary/30 cursor-not-allowed'}`}\n title={isComplete ? 'Profile' : 'Building...'}\n disabled={!isComplete}\n >\n <Settings className=\"w-3.5 h-3.5\" strokeWidth={1.5} />\n </button>\n </RowActionGroup>\n );\n }\n\n return (\n <RowActionGroup>\n <button\n onClick={(e) => { e.stopPropagation(); navigate(`/mcp/queries/${row.workflow_id}?step=1`); }}\n className=\"opacity-0 group-hover/row:opacity-100 text-text-tertiary hover:text-accent transition-all\"\n title=\"Describe\"\n >\n <MessageSquare className=\"w-3.5 h-3.5\" strokeWidth={1.5} />\n </button>\n <button\n onClick={(e) => { e.stopPropagation(); navigate(`/mcp/queries/${row.workflow_id}?step=2`); }}\n className=\"opacity-0 group-hover/row:opacity-100 text-text-tertiary hover:text-status-warning transition-all\"\n title=\"Discover\"\n >\n <Lightbulb className=\"w-3.5 h-3.5\" strokeWidth={1.5} />\n </button>\n <button\n onClick={(e) => { e.stopPropagation(); navigate(`/mcp/queries/${row.workflow_id}?step=3`); }}\n className={`opacity-0 group-hover/row:opacity-100 transition-all ${isComplete ? 'text-text-tertiary hover:text-status-success' : 'text-text-tertiary/30 cursor-not-allowed'}`}\n title={isComplete ? 'Compile' : 'Complete discovery first'}\n disabled={!isComplete}\n >\n <Layers className=\"w-3.5 h-3.5\" strokeWidth={1.5} />\n </button>\n </RowActionGroup>\n );\n },\n },\n ];\n}\n\nexport function McpQueryPage() {\n const navigate = useNavigate();\n const columns = buildColumns(navigate);\n\n const { filters, setFilter, pagination, sort, setSort } = useFilterParams({\n filters: { search: '', status: '', type: '' },\n pageSize: 20,\n });\n\n const { data, isLoading, refetch } = useMcpQueryJobs({\n limit: pagination.pageSize,\n offset: pagination.offset,\n search: filters.search,\n status: filters.status,\n entity: filters.type || undefined,\n });\n\n useWorkflowListEvents();\n\n const jobs = data?.jobs ?? [];\n const total = data?.total ?? 0;\n\n return (\n <>\n <PageHeader\n title=\"MCP Tool Designer\"\n docsHash=\"#docs:dashboard.md:mcp-tool-designer\"\n actions={\n <button\n onClick={() => navigate('/mcp/queries/new')}\n className=\"btn-primary text-xs inline-flex items-center gap-1.5\"\n >\n <Wand2 className=\"w-3.5 h-3.5\" strokeWidth={1.5} />\n Create New MCP Tool\n </button>\n }\n />\n\n <FilterBar actions={\n <ListToolbar\n onRefresh={() => refetch()}\n apiPath={buildApiPath('/workflow-states/jobs', {\n entity: filters.type || 'mcpQuery,mcpTriage,mcpWorkflowPlanner',\n limit: pagination.pageSize,\n offset: pagination.offset,\n sort_by: 'created_at',\n order: 'desc',\n status: filters.status || undefined,\n search: filters.search || undefined,\n })}\n />\n }>\n <FilterSelect\n label=\"Type\"\n value={filters.type}\n onChange={(v) => setFilter('type', v)}\n options={[\n { value: 'mcpQuery', label: 'Discovery' },\n { value: 'mcpWorkflowPlanner', label: 'Build' },\n { value: 'mcpTriage', label: 'Triage' },\n ]}\n />\n <FilterSelect\n label=\"Status\"\n value={filters.status}\n onChange={(v) => setFilter('status', v)}\n options={[\n { value: 'completed', label: 'Completed' },\n { value: 'running', label: 'Running' },\n { value: 'failed', label: 'Failed' },\n ]}\n />\n </FilterBar>\n\n <DataTable\n columns={columns}\n data={jobs}\n keyFn={(row) => row.workflow_id}\n onRowClick={(row) => {\n if (row.entity === 'mcpWorkflowPlanner') {\n const url = row.set_id\n ? `/mcp/queries/${row.workflow_id}?mode=plan&set_id=${row.set_id}`\n : `/mcp/queries/${row.workflow_id}?mode=plan`;\n navigate(url);\n } else if (row.entity === 'mcpWorkflowBuilder') {\n navigate(`/mcp/queries/${row.workflow_id}?mode=builder`);\n } else {\n navigate(`/mcp/queries/${row.workflow_id}`);\n }\n }}\n isLoading={isLoading}\n emptyMessage=\"\"\n sort={sort}\n onSort={setSort}\n />\n\n {!isLoading && jobs.length === 0 && (\n <div className=\"cursor-pointer\" onClick={() => navigate('/mcp/queries/new')}>\n <EmptyState icon={Wand2} title=\"No tool designs yet\" description=\"Click to create your first MCP tool\" />\n </div>\n )}\n\n <StickyPagination\n page={pagination.page}\n pageSize={pagination.pageSize}\n total={total}\n totalPages={pagination.totalPages(total)}\n onPageChange={pagination.setPage}\n />\n </>\n );\n}\n"],"names":["STATUS_DOT","mapStatus","job","buildColumns","navigate","row","s","dotClass","pulseClass","jsxs","jsx","WorkflowPill","TimestampCell","ElapsedCell","isComplete","isBuilder","planUrl","RowActionGroup","e","GitBranch","Layers","MessageSquare","Settings","Lightbulb","McpQueryPage","useNavigate","columns","filters","setFilter","pagination","sort","setSort","useFilterParams","data","isLoading","refetch","useMcpQueryJobs","useWorkflowListEvents","jobs","total","Fragment","PageHeader","Wand2","FilterBar","ListToolbar","buildApiPath","FilterSelect","v","DataTable","url","EmptyState","StickyPagination"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"McpQueryPage-C3GDzqZM.js","sources":["../../src/pages/mcp/McpQueryPage.tsx"],"sourcesContent":["import { useNavigate } from 'react-router-dom';\nimport { MessageSquare, Lightbulb, Layers, Wand2, Settings, GitBranch } from 'lucide-react';\n\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { DataTable, type Column } from '../../components/common/data/DataTable';\nimport { FilterBar, FilterSelect } from '../../components/common/data/FilterBar';\nimport { StickyPagination } from '../../components/common/data/StickyPagination';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\nimport { buildApiPath } from '../../lib/api-path';\nimport { TimestampCell } from '../../components/common/display/TimestampCell';\nimport { ElapsedCell } from '../../components/common/display/ElapsedCell';\nimport { WorkflowPill } from '../../components/common/display/WorkflowPill';\nimport { EmptyState } from '../../components/common/display/EmptyState';\nimport { RowActionGroup } from '../../components/common/layout/RowActions';\nimport { useFilterParams } from '../../hooks/useFilterParams';\nimport { useWorkflowListEvents } from '../../hooks/useEventHooks';\nimport { useMcpQueryJobs } from '../../api/mcp-query';\nimport type { LTJob } from '../../api/types';\n\nconst STATUS_DOT: Record<string, string> = {\n in_progress: 'bg-status-active',\n completed: 'bg-status-success',\n failed: 'bg-status-error',\n};\n\nfunction mapStatus(job: LTJob): string {\n if (job.status === 'completed') return 'completed';\n if (Number(job.status) === 0) return 'completed';\n if (job.is_live) return 'in_progress';\n return 'failed';\n}\n\nfunction buildColumns(navigate: ReturnType<typeof useNavigate>): Column<LTJob>[] {\n return [\n {\n key: 'workflow_id',\n label: 'Workflow ID / Type',\n render: (row) => {\n const s = mapStatus(row);\n const dotClass = STATUS_DOT[s] ?? 'bg-status-pending';\n const pulseClass = s === 'in_progress' ? ' animate-pulse' : '';\n return (\n <div className=\"flex items-start gap-2 min-w-0\">\n <span className={`w-[9px] h-[9px] shrink-0 rounded-full mt-1 ${dotClass}${pulseClass}`} title={s} />\n <div className=\"min-w-0\">\n <span className=\"font-mono text-xs text-text-primary truncate block\">\n {row.workflow_id}\n </span>\n <div className=\"mt-0.5\">\n <WorkflowPill type={row.entity || 'unknown'} />\n </div>\n </div>\n </div>\n );\n },\n },\n {\n key: 'created_at',\n label: 'Created',\n render: (row) => <TimestampCell date={row.created_at} />,\n className: 'w-40',\n sortable: true,\n },\n {\n key: 'updated_at',\n label: 'Updated',\n render: (row) => <TimestampCell date={row.updated_at} />,\n className: 'w-40',\n sortable: true,\n },\n {\n key: 'duration',\n label: 'Duration',\n render: (row) => {\n const s = mapStatus(row);\n return (\n <ElapsedCell\n startDate={row.created_at}\n endDate={s === 'in_progress' ? null : row.updated_at}\n isLive={s === 'in_progress'}\n />\n );\n },\n className: 'w-28',\n },\n {\n key: 'actions',\n label: '',\n className: 'w-28',\n render: (row) => {\n const s = mapStatus(row);\n const isComplete = s === 'completed';\n const isBuilder = row.entity === 'mcpWorkflowBuilder';\n const isPlanner = row.entity === 'mcpWorkflowPlanner';\n\n if (isPlanner) {\n const planUrl = row.set_id\n ? `/mcp/queries/${row.workflow_id}?mode=plan&set_id=${row.set_id}`\n : `/mcp/queries/${row.workflow_id}?mode=plan`;\n return (\n <RowActionGroup>\n <button\n onClick={(e) => { e.stopPropagation(); navigate(`${planUrl}&step=1`); }}\n className=\"opacity-0 group-hover/row:opacity-100 text-text-tertiary hover:text-accent transition-all\"\n title=\"Plan\"\n >\n <GitBranch className=\"w-3.5 h-3.5\" strokeWidth={1.5} />\n </button>\n <button\n onClick={(e) => { e.stopPropagation(); navigate(`${planUrl}&step=2`); }}\n className={`opacity-0 group-hover/row:opacity-100 transition-all ${isComplete ? 'text-text-tertiary hover:text-status-success' : 'text-text-tertiary/30 cursor-not-allowed'}`}\n title={isComplete ? 'Build' : 'Planning...'}\n disabled={!isComplete}\n >\n <Layers className=\"w-3.5 h-3.5\" strokeWidth={1.5} />\n </button>\n </RowActionGroup>\n );\n }\n\n if (isBuilder) {\n return (\n <RowActionGroup>\n <button\n onClick={(e) => { e.stopPropagation(); navigate(`/mcp/queries/${row.workflow_id}?mode=builder&step=1`); }}\n className=\"opacity-0 group-hover/row:opacity-100 text-text-tertiary hover:text-accent transition-all\"\n title=\"Describe\"\n >\n <MessageSquare className=\"w-3.5 h-3.5\" strokeWidth={1.5} />\n </button>\n <button\n onClick={(e) => { e.stopPropagation(); navigate(`/mcp/queries/${row.workflow_id}?mode=builder&step=2`); }}\n className={`opacity-0 group-hover/row:opacity-100 transition-all ${isComplete ? 'text-text-tertiary hover:text-status-success' : 'text-text-tertiary/30 cursor-not-allowed'}`}\n title={isComplete ? 'Profile' : 'Building...'}\n disabled={!isComplete}\n >\n <Settings className=\"w-3.5 h-3.5\" strokeWidth={1.5} />\n </button>\n </RowActionGroup>\n );\n }\n\n return (\n <RowActionGroup>\n <button\n onClick={(e) => { e.stopPropagation(); navigate(`/mcp/queries/${row.workflow_id}?step=1`); }}\n className=\"opacity-0 group-hover/row:opacity-100 text-text-tertiary hover:text-accent transition-all\"\n title=\"Describe\"\n >\n <MessageSquare className=\"w-3.5 h-3.5\" strokeWidth={1.5} />\n </button>\n <button\n onClick={(e) => { e.stopPropagation(); navigate(`/mcp/queries/${row.workflow_id}?step=2`); }}\n className=\"opacity-0 group-hover/row:opacity-100 text-text-tertiary hover:text-status-warning transition-all\"\n title=\"Discover\"\n >\n <Lightbulb className=\"w-3.5 h-3.5\" strokeWidth={1.5} />\n </button>\n <button\n onClick={(e) => { e.stopPropagation(); navigate(`/mcp/queries/${row.workflow_id}?step=3`); }}\n className={`opacity-0 group-hover/row:opacity-100 transition-all ${isComplete ? 'text-text-tertiary hover:text-status-success' : 'text-text-tertiary/30 cursor-not-allowed'}`}\n title={isComplete ? 'Compile' : 'Complete discovery first'}\n disabled={!isComplete}\n >\n <Layers className=\"w-3.5 h-3.5\" strokeWidth={1.5} />\n </button>\n </RowActionGroup>\n );\n },\n },\n ];\n}\n\nexport function McpQueryPage() {\n const navigate = useNavigate();\n const columns = buildColumns(navigate);\n\n const { filters, setFilter, pagination, sort, setSort } = useFilterParams({\n filters: { search: '', status: '', type: '' },\n pageSize: 20,\n });\n\n const { data, isLoading, refetch } = useMcpQueryJobs({\n limit: pagination.pageSize,\n offset: pagination.offset,\n search: filters.search,\n status: filters.status,\n entity: filters.type || undefined,\n });\n\n useWorkflowListEvents();\n\n const jobs = data?.jobs ?? [];\n const total = data?.total ?? 0;\n\n return (\n <>\n <PageHeader\n title=\"MCP Tool Designer\"\n docsHash=\"#docs:dashboard.md:mcp-tool-designer\"\n actions={\n <button\n onClick={() => navigate('/mcp/queries/new')}\n className=\"btn-primary text-xs inline-flex items-center gap-1.5\"\n >\n <Wand2 className=\"w-3.5 h-3.5\" strokeWidth={1.5} />\n Create New MCP Tool\n </button>\n }\n />\n\n <FilterBar actions={\n <ListToolbar\n onRefresh={() => refetch()}\n apiPath={buildApiPath('/workflow-states/jobs', {\n entity: filters.type || 'mcpQuery,mcpTriage,mcpWorkflowPlanner',\n limit: pagination.pageSize,\n offset: pagination.offset,\n sort_by: 'created_at',\n order: 'desc',\n status: filters.status || undefined,\n search: filters.search || undefined,\n })}\n />\n }>\n <FilterSelect\n label=\"Type\"\n value={filters.type}\n onChange={(v) => setFilter('type', v)}\n options={[\n { value: 'mcpQuery', label: 'Discovery' },\n { value: 'mcpWorkflowPlanner', label: 'Build' },\n { value: 'mcpTriage', label: 'Triage' },\n ]}\n />\n <FilterSelect\n label=\"Status\"\n value={filters.status}\n onChange={(v) => setFilter('status', v)}\n options={[\n { value: 'completed', label: 'Completed' },\n { value: 'running', label: 'Running' },\n { value: 'failed', label: 'Failed' },\n ]}\n />\n </FilterBar>\n\n <DataTable\n columns={columns}\n data={jobs}\n keyFn={(row) => row.workflow_id}\n onRowClick={(row) => {\n if (row.entity === 'mcpWorkflowPlanner') {\n const url = row.set_id\n ? `/mcp/queries/${row.workflow_id}?mode=plan&set_id=${row.set_id}`\n : `/mcp/queries/${row.workflow_id}?mode=plan`;\n navigate(url);\n } else if (row.entity === 'mcpWorkflowBuilder') {\n navigate(`/mcp/queries/${row.workflow_id}?mode=builder`);\n } else {\n navigate(`/mcp/queries/${row.workflow_id}`);\n }\n }}\n isLoading={isLoading}\n emptyMessage=\"\"\n sort={sort}\n onSort={setSort}\n />\n\n {!isLoading && jobs.length === 0 && (\n <div className=\"cursor-pointer\" onClick={() => navigate('/mcp/queries/new')}>\n <EmptyState icon={Wand2} title=\"No tool designs yet\" description=\"Click to create your first MCP tool\" />\n </div>\n )}\n\n <StickyPagination\n page={pagination.page}\n pageSize={pagination.pageSize}\n total={total}\n totalPages={pagination.totalPages(total)}\n onPageChange={pagination.setPage}\n />\n </>\n );\n}\n"],"names":["STATUS_DOT","mapStatus","job","buildColumns","navigate","row","s","dotClass","pulseClass","jsxs","jsx","WorkflowPill","TimestampCell","ElapsedCell","isComplete","isBuilder","planUrl","RowActionGroup","e","GitBranch","Layers","MessageSquare","Settings","Lightbulb","McpQueryPage","useNavigate","columns","filters","setFilter","pagination","sort","setSort","useFilterParams","data","isLoading","refetch","useMcpQueryJobs","useWorkflowListEvents","jobs","total","Fragment","PageHeader","Wand2","FilterBar","ListToolbar","buildApiPath","FilterSelect","v","DataTable","url","EmptyState","StickyPagination"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{b as R,a as m,j as e}from"./vendor-query-B2UbickB.js";import{b as D,c as L}from"./pipelines-
|
|
2
|
-
//# sourceMappingURL=McpRunDetailPage-
|
|
1
|
+
import{b as R,a as m,j as e}from"./vendor-query-B2UbickB.js";import{b as D,c as L}from"./pipelines-CNLhgj8b.js";import{u as J,c as K,D as M,b as S,J as _,N as U}from"./index-Dgw1KKpq.js";import{S as $}from"./StatusBadge-D9MeQHrh.js";import{P as E}from"./PageHeader-BhaWTWcM.js";import{C as A}from"./CopyableId-blg-gZvT.js";import{C as b}from"./CollapsibleSection-Cx99mqNN.js";import{u as V}from"./useCollapsedSections-BU5HULGs.js";import{L as q}from"./ListToolbar-FpcvqNkN.js";import{S as B}from"./SwimlaneTimeline-CUEf2R5R.js";import{E as F}from"./EventTable-Bh9FKXLI.js";import{e as H,f as Q}from"./vendor-react-CXumBFUA.js";import"./vendor-icons-CEWCGPeJ.js";import"./StreamMessageDetail-D5v95pmz.js";import"./FilterBar-BQ2JGg8U.js";const z={running:"in_progress",completed:"completed",failed:"failed"};function O({isRunning:a,onTerminate:l}){const[s,n]=m.useState(!1),t=m.useRef(null);return m.useEffect(()=>{if(!s)return;const o=i=>{t.current&&!t.current.contains(i.target)&&n(!1)};return document.addEventListener("mousedown",o),()=>document.removeEventListener("mousedown",o)},[s]),a?e.jsxs("div",{className:"relative",ref:t,children:[e.jsx("button",{onClick:()=>n(!s),className:"btn-primary text-xs",children:"Actions"}),s&&e.jsx("div",{className:"absolute right-0 mt-1 w-44 bg-surface-raised border border-surface-border rounded-md shadow-lg z-10",children:e.jsx("button",{onClick:()=>{l(),n(!1)},className:"block w-full text-left px-4 py-2 text-xs text-status-error hover:bg-surface-hover",children:"Terminate"})})]}):null}function de(){var N,w;const{jobId:a}=H(),[l]=Q(),s=l.get("namespace")||"",n=R(),{data:t,isLoading:o,error:i,refetch:v,isFetching:T}=D(a,s),C=L(),{data:u}=J(),{isCollapsed:p,toggle:f}=V("mcp-run-detail"),g=((N=u==null?void 0:u.telemetry)==null?void 0:N.traceUrl)??null,I=m.useCallback(x=>{!a||x.workflowId!==a||n.invalidateQueries({queryKey:["mcpRunExecution",a]})},[a,n]);if(K(`${U}.system.>`,I),o)return e.jsxs("div",{className:"animate-pulse space-y-4",children:[e.jsx("div",{className:"h-8 bg-surface-sunken rounded w-64"}),e.jsx("div",{className:"h-60 bg-surface-sunken rounded"})]});if(i||!t)return e.jsxs("div",{children:[e.jsx(E,{title:"Pipeline Execution"}),e.jsxs("div",{className:"mt-4 text-center py-8",children:[e.jsx("p",{className:"text-sm text-text-primary mb-1",children:(w=i==null?void 0:i.message)!=null&&w.includes("expired")?"Execution data is no longer available":"Unable to load execution"}),e.jsx("p",{className:"text-xs text-text-tertiary",children:(i==null?void 0:i.message)??"The run could not be resolved."})]})]});const{events:j,summary:r}=t,h=j.find(x=>{var k;return x.category==="activity"&&((k=x.attributes.kind)==null?void 0:k.includes("completed"))}),P=(h==null?void 0:h.attributes.result)??null,d=t.result,y=(d==null?void 0:d.data)??d??null;return e.jsxs("div",{children:[e.jsx(E,{title:"Pipeline Execution",actions:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(q,{onRefresh:()=>v(),isFetching:T,apiPath:`/pipelines/${a}/execution?app_id=${s}`}),e.jsx(O,{isRunning:t.status==="running",onTerminate:()=>{confirm("Interrupt this pipeline execution? This cannot be undone.")&&C.mutate({jobId:t.workflow_id,topic:t.workflow_type,appId:s},{onSuccess:()=>v()})}})]})}),e.jsxs("div",{className:"bg-surface-sunken/50 rounded-md p-5 mb-8",children:[e.jsxs("div",{className:"flex items-center gap-4 mb-4",children:[e.jsx("h2",{className:"text-sm font-mono text-text-primary truncate flex-1",children:t.workflow_id}),e.jsxs("div",{className:"flex items-center gap-4 shrink-0",children:[e.jsx(c,{label:"Tools",value:r.activities.user}),e.jsx(c,{label:"System",value:r.activities.system,muted:!0}),r.child_workflows.total>0&&e.jsx(c,{label:"Children",value:r.child_workflows.total}),r.timers>0&&e.jsx(c,{label:"Timers",value:r.timers}),r.signals>0&&e.jsx(c,{label:"Signals",value:r.signals}),e.jsx($,{status:z[t.status]??t.status})]})]}),e.jsxs("div",{className:"grid grid-cols-6 gap-x-6",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5",children:"Server"}),e.jsx("p",{className:"text-xs font-mono text-text-primary truncate",children:s})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5",children:"Tool"}),e.jsx("p",{className:"text-xs font-mono text-text-primary truncate",children:t.workflow_type||"—"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5",children:"Duration"}),e.jsx(M,{ms:t.duration_ms,className:"font-mono text-text-primary"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5",children:"Started"}),t.start_time?e.jsx(S,{date:t.start_time,format:"datetime",className:"font-mono text-text-primary"}):e.jsx("span",{className:"text-xs text-text-tertiary",children:"--"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5",children:"Completed"}),t.close_time?e.jsx(S,{date:t.close_time,format:"datetime",className:"font-mono text-text-primary"}):e.jsx("span",{className:"text-xs text-text-tertiary",children:"--"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5",children:"Trace"}),t.trace_id?e.jsx(A,{label:"",value:t.trace_id,href:g?g.replace("{traceId}",t.trace_id):void 0,external:!0}):e.jsx("span",{className:"text-xs text-text-tertiary",children:"—"})]})]})]}),e.jsxs("div",{className:"space-y-6",children:[e.jsx(b,{title:"Details",sectionKey:"details",isCollapsed:p("details"),onToggle:f,children:e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4 mb-6",children:[e.jsx("div",{children:e.jsx(_,{data:P??{},label:"Input"})}),y!==null&&e.jsx("div",{children:e.jsx(_,{data:y,label:"Result"})})]})}),e.jsx(b,{title:"Execution Timeline",sectionKey:"timeline",isCollapsed:p("timeline"),onToggle:f,children:e.jsx(B,{events:j,outline:!0,jid:a,appId:s||"durable"})}),e.jsx(b,{title:"Events",sectionKey:"events",isCollapsed:p("events"),onToggle:f,children:e.jsx(F,{events:j,jid:a,appId:s||"durable"})})]})]})}function c({label:a,value:l,muted:s}){return e.jsxs("div",{className:"flex items-center gap-1.5 text-xs",children:[e.jsx("span",{className:"text-text-tertiary",children:a}),e.jsx("span",{className:`font-medium tabular-nums ${s?"text-text-tertiary":"text-text-primary"}`,children:l})]})}export{de as McpRunDetailPage};
|
|
2
|
+
//# sourceMappingURL=McpRunDetailPage-SzOyhDBW.js.map
|
package/dashboard/dist/assets/{McpRunDetailPage-CyTbHs0J.js.map → McpRunDetailPage-SzOyhDBW.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpRunDetailPage-CyTbHs0J.js","sources":["../../src/pages/mcp/McpRunDetailPage.tsx"],"sourcesContent":["import { useState, useRef, useEffect, useCallback } from 'react';\nimport { useParams, useSearchParams } from 'react-router-dom';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useMcpRunExecution, useInterruptJob } from '../../api/pipelines';\nimport { useSettings } from '../../api/settings';\nimport { StatusBadge } from '../../components/common/display/StatusBadge';\nimport { JsonViewer } from '../../components/common/data/JsonViewer';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { CopyableId } from '../../components/common/display/CopyableId';\nimport { CollapsibleSection } from '../../components/common/layout/CollapsibleSection';\nimport { useCollapsedSections } from '../../hooks/useCollapsedSections';\nimport { useEventSubscription } from '../../hooks/useEventContext';\nimport { NATS_SUBJECT_PREFIX } from '../../lib/nats/config';\nimport { DateValue } from '../../components/common/display/DateValue';\nimport { DurationValue } from '../../components/common/display/DurationValue';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\n\nimport { SwimlaneTimeline } from '../workflows/workflow-execution/SwimlaneTimeline';\nimport { EventTable } from '../workflows/workflow-execution/EventTable';\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nconst statusMap: Record<string, string> = {\n running: 'in_progress',\n completed: 'completed',\n failed: 'failed',\n};\n\n// ── Actions dropdown ────────────────────────────────────────────────────────\n\nfunction ActionsDropdown({ isRunning, onTerminate }: {\n isRunning: boolean;\n onTerminate: () => void;\n}) {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, [open]);\n\n if (!isRunning) return null;\n\n return (\n <div className=\"relative\" ref={ref}>\n <button onClick={() => setOpen(!open)} className=\"btn-primary text-xs\">\n Actions\n </button>\n {open && (\n <div className=\"absolute right-0 mt-1 w-44 bg-surface-raised border border-surface-border rounded-md shadow-lg z-10\">\n <button\n onClick={() => { onTerminate(); setOpen(false); }}\n className=\"block w-full text-left px-4 py-2 text-xs text-status-error hover:bg-surface-hover\"\n >\n Terminate\n </button>\n </div>\n )}\n </div>\n );\n}\n\n// ── Main page ────────────────────────────────────────────────────────────────\n\nexport function McpRunDetailPage() {\n const { jobId } = useParams<{ jobId: string }>();\n const [searchParams] = useSearchParams();\n const namespace = searchParams.get('namespace') || '';\n const queryClient = useQueryClient();\n const { data: execution, isLoading, error, refetch, isFetching } = useMcpRunExecution(jobId!, namespace);\n const interruptMutation = useInterruptJob();\n const { data: settings } = useSettings();\n const { isCollapsed, toggle } = useCollapsedSections('mcp-run-detail');\n\n\n const traceUrl = settings?.telemetry?.traceUrl ?? null;\n\n // Subscribe to activity events for this job — refetch execution on each step\n const activityHandler = useCallback((event: any) => {\n if (!jobId || event.workflowId !== jobId) return;\n queryClient.invalidateQueries({ queryKey: ['mcpRunExecution', jobId] });\n }, [jobId, queryClient]);\n useEventSubscription(`${NATS_SUBJECT_PREFIX}.system.>`, activityHandler);\n\n if (isLoading) {\n return (\n <div className=\"animate-pulse space-y-4\">\n <div className=\"h-8 bg-surface-sunken rounded w-64\" />\n <div className=\"h-60 bg-surface-sunken rounded\" />\n </div>\n );\n }\n\n if (error || !execution) {\n return (\n <div>\n <PageHeader title=\"Pipeline Execution\" />\n <div className=\"mt-4 text-center py-8\">\n <p className=\"text-sm text-text-primary mb-1\">\n {(error as Error)?.message?.includes('expired')\n ? 'Execution data is no longer available'\n : 'Unable to load execution'}\n </p>\n <p className=\"text-xs text-text-tertiary\">\n {(error as Error)?.message ?? 'The run could not be resolved.'}\n </p>\n </div>\n </div>\n );\n }\n\n const { events, summary } = execution;\n\n // The trigger activity's result is the effective input to the flow —\n // it accepts outside job input and provides it to descendant activities.\n const triggerCompleted = events.find(\n (e) => e.category === 'activity' && e.attributes.kind?.includes('completed'),\n );\n const triggerInput = triggerCompleted?.attributes.result ?? null;\n\n // Unwrap result — the `data` field is what users care about\n const rawResult = execution.result as Record<string, unknown> | null | undefined;\n const result = rawResult?.data ?? rawResult ?? null;\n\n return (\n <div>\n <PageHeader\n title=\"Pipeline Execution\"\n actions={\n <div className=\"flex items-center gap-2\">\n <ListToolbar\n onRefresh={() => refetch()}\n isFetching={isFetching}\n apiPath={`/pipelines/${jobId}/execution?app_id=${namespace}`}\n />\n <ActionsDropdown\n isRunning={execution.status === 'running'}\n onTerminate={() => {\n if (confirm('Interrupt this pipeline execution? This cannot be undone.')) {\n interruptMutation.mutate(\n { jobId: execution.workflow_id, topic: execution.workflow_type, appId: namespace },\n { onSuccess: () => refetch() },\n );\n }\n }}\n />\n </div>\n }\n />\n\n {/* ── Header card ─────────────────────────────────── */}\n <div className=\"bg-surface-sunken/50 rounded-md p-5 mb-8\">\n {/* Row 1: Job ID + stats + status */}\n <div className=\"flex items-center gap-4 mb-4\">\n <h2 className=\"text-sm font-mono text-text-primary truncate flex-1\">{execution.workflow_id}</h2>\n <div className=\"flex items-center gap-4 shrink-0\">\n <Stat label=\"Tools\" value={summary.activities.user} />\n <Stat label=\"System\" value={summary.activities.system} muted />\n {summary.child_workflows.total > 0 && (\n <Stat label=\"Children\" value={summary.child_workflows.total} />\n )}\n {summary.timers > 0 && <Stat label=\"Timers\" value={summary.timers} />}\n {summary.signals > 0 && <Stat label=\"Signals\" value={summary.signals} />}\n <StatusBadge status={statusMap[execution.status] ?? execution.status} />\n </div>\n </div>\n\n {/* Row 2: Namespace, Topic, Duration, Started, Trace */}\n <div className=\"grid grid-cols-6 gap-x-6\">\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5\">Server</p>\n <p className=\"text-xs font-mono text-text-primary truncate\">{namespace}</p>\n </div>\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5\">Tool</p>\n <p className=\"text-xs font-mono text-text-primary truncate\">{execution.workflow_type || '—'}</p>\n </div>\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5\">Duration</p>\n <DurationValue ms={execution.duration_ms} className=\"font-mono text-text-primary\" />\n </div>\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5\">Started</p>\n {execution.start_time\n ? <DateValue date={execution.start_time} format=\"datetime\" className=\"font-mono text-text-primary\" />\n : <span className=\"text-xs text-text-tertiary\">--</span>}\n </div>\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5\">Completed</p>\n {execution.close_time\n ? <DateValue date={execution.close_time} format=\"datetime\" className=\"font-mono text-text-primary\" />\n : <span className=\"text-xs text-text-tertiary\">--</span>}\n </div>\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5\">Trace</p>\n {execution.trace_id ? (\n <CopyableId\n label=\"\"\n value={execution.trace_id}\n href={traceUrl ? traceUrl.replace('{traceId}', execution.trace_id) : undefined}\n external\n />\n ) : (\n <span className=\"text-xs text-text-tertiary\">—</span>\n )}\n </div>\n </div>\n </div>\n\n {/* ── Sections ────────────────────────────────────── */}\n <div className=\"space-y-6\">\n {/* Details: Input + Result */}\n <CollapsibleSection title=\"Details\" sectionKey=\"details\" isCollapsed={isCollapsed('details')} onToggle={toggle}>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-6\">\n <div>\n <JsonViewer data={triggerInput ?? {}} label=\"Input\" />\n </div>\n {result !== null && (\n <div>\n <JsonViewer data={result} label=\"Result\" />\n </div>\n )}\n </div>\n </CollapsibleSection>\n\n {/* Execution Timeline (swimlane) */}\n <CollapsibleSection title=\"Execution Timeline\" sectionKey=\"timeline\" isCollapsed={isCollapsed('timeline')} onToggle={toggle}>\n <SwimlaneTimeline events={events} outline jid={jobId} appId={namespace || 'durable'} />\n </CollapsibleSection>\n\n {/* Events (table) */}\n <CollapsibleSection title=\"Events\" sectionKey=\"events\" isCollapsed={isCollapsed('events')} onToggle={toggle}>\n <EventTable events={events} jid={jobId} appId={namespace || 'durable'} />\n </CollapsibleSection>\n </div>\n </div>\n );\n}\n\n// ── Stat pill ────────────────────────────────────────────────────────────────\n\nfunction Stat({ label, value, muted }: { label: string; value: number; muted?: boolean }) {\n return (\n <div className=\"flex items-center gap-1.5 text-xs\">\n <span className=\"text-text-tertiary\">{label}</span>\n <span className={`font-medium tabular-nums ${muted ? 'text-text-tertiary' : 'text-text-primary'}`}>{value}</span>\n </div>\n );\n}\n"],"names":["statusMap","ActionsDropdown","isRunning","onTerminate","open","setOpen","useState","ref","useRef","useEffect","handler","e","jsxs","jsx","McpRunDetailPage","jobId","useParams","searchParams","useSearchParams","namespace","queryClient","useQueryClient","execution","isLoading","error","refetch","isFetching","useMcpRunExecution","interruptMutation","useInterruptJob","settings","useSettings","isCollapsed","toggle","useCollapsedSections","traceUrl","_a","activityHandler","useCallback","event","useEventSubscription","NATS_SUBJECT_PREFIX","PageHeader","_b","events","summary","triggerCompleted","triggerInput","rawResult","result","ListToolbar","Stat","StatusBadge","DurationValue","DateValue","CopyableId","CollapsibleSection","JsonViewer","SwimlaneTimeline","EventTable","label","value","muted"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"McpRunDetailPage-SzOyhDBW.js","sources":["../../src/pages/mcp/McpRunDetailPage.tsx"],"sourcesContent":["import { useState, useRef, useEffect, useCallback } from 'react';\nimport { useParams, useSearchParams } from 'react-router-dom';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useMcpRunExecution, useInterruptJob } from '../../api/pipelines';\nimport { useSettings } from '../../api/settings';\nimport { StatusBadge } from '../../components/common/display/StatusBadge';\nimport { JsonViewer } from '../../components/common/data/JsonViewer';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { CopyableId } from '../../components/common/display/CopyableId';\nimport { CollapsibleSection } from '../../components/common/layout/CollapsibleSection';\nimport { useCollapsedSections } from '../../hooks/useCollapsedSections';\nimport { useEventSubscription } from '../../hooks/useEventContext';\nimport { NATS_SUBJECT_PREFIX } from '../../lib/nats/config';\nimport { DateValue } from '../../components/common/display/DateValue';\nimport { DurationValue } from '../../components/common/display/DurationValue';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\n\nimport { SwimlaneTimeline } from '../workflows/workflow-execution/SwimlaneTimeline';\nimport { EventTable } from '../workflows/workflow-execution/EventTable';\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nconst statusMap: Record<string, string> = {\n running: 'in_progress',\n completed: 'completed',\n failed: 'failed',\n};\n\n// ── Actions dropdown ────────────────────────────────────────────────────────\n\nfunction ActionsDropdown({ isRunning, onTerminate }: {\n isRunning: boolean;\n onTerminate: () => void;\n}) {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, [open]);\n\n if (!isRunning) return null;\n\n return (\n <div className=\"relative\" ref={ref}>\n <button onClick={() => setOpen(!open)} className=\"btn-primary text-xs\">\n Actions\n </button>\n {open && (\n <div className=\"absolute right-0 mt-1 w-44 bg-surface-raised border border-surface-border rounded-md shadow-lg z-10\">\n <button\n onClick={() => { onTerminate(); setOpen(false); }}\n className=\"block w-full text-left px-4 py-2 text-xs text-status-error hover:bg-surface-hover\"\n >\n Terminate\n </button>\n </div>\n )}\n </div>\n );\n}\n\n// ── Main page ────────────────────────────────────────────────────────────────\n\nexport function McpRunDetailPage() {\n const { jobId } = useParams<{ jobId: string }>();\n const [searchParams] = useSearchParams();\n const namespace = searchParams.get('namespace') || '';\n const queryClient = useQueryClient();\n const { data: execution, isLoading, error, refetch, isFetching } = useMcpRunExecution(jobId!, namespace);\n const interruptMutation = useInterruptJob();\n const { data: settings } = useSettings();\n const { isCollapsed, toggle } = useCollapsedSections('mcp-run-detail');\n\n\n const traceUrl = settings?.telemetry?.traceUrl ?? null;\n\n // Subscribe to activity events for this job — refetch execution on each step\n const activityHandler = useCallback((event: any) => {\n if (!jobId || event.workflowId !== jobId) return;\n queryClient.invalidateQueries({ queryKey: ['mcpRunExecution', jobId] });\n }, [jobId, queryClient]);\n useEventSubscription(`${NATS_SUBJECT_PREFIX}.system.>`, activityHandler);\n\n if (isLoading) {\n return (\n <div className=\"animate-pulse space-y-4\">\n <div className=\"h-8 bg-surface-sunken rounded w-64\" />\n <div className=\"h-60 bg-surface-sunken rounded\" />\n </div>\n );\n }\n\n if (error || !execution) {\n return (\n <div>\n <PageHeader title=\"Pipeline Execution\" />\n <div className=\"mt-4 text-center py-8\">\n <p className=\"text-sm text-text-primary mb-1\">\n {(error as Error)?.message?.includes('expired')\n ? 'Execution data is no longer available'\n : 'Unable to load execution'}\n </p>\n <p className=\"text-xs text-text-tertiary\">\n {(error as Error)?.message ?? 'The run could not be resolved.'}\n </p>\n </div>\n </div>\n );\n }\n\n const { events, summary } = execution;\n\n // The trigger activity's result is the effective input to the flow —\n // it accepts outside job input and provides it to descendant activities.\n const triggerCompleted = events.find(\n (e) => e.category === 'activity' && e.attributes.kind?.includes('completed'),\n );\n const triggerInput = triggerCompleted?.attributes.result ?? null;\n\n // Unwrap result — the `data` field is what users care about\n const rawResult = execution.result as Record<string, unknown> | null | undefined;\n const result = rawResult?.data ?? rawResult ?? null;\n\n return (\n <div>\n <PageHeader\n title=\"Pipeline Execution\"\n actions={\n <div className=\"flex items-center gap-2\">\n <ListToolbar\n onRefresh={() => refetch()}\n isFetching={isFetching}\n apiPath={`/pipelines/${jobId}/execution?app_id=${namespace}`}\n />\n <ActionsDropdown\n isRunning={execution.status === 'running'}\n onTerminate={() => {\n if (confirm('Interrupt this pipeline execution? This cannot be undone.')) {\n interruptMutation.mutate(\n { jobId: execution.workflow_id, topic: execution.workflow_type, appId: namespace },\n { onSuccess: () => refetch() },\n );\n }\n }}\n />\n </div>\n }\n />\n\n {/* ── Header card ─────────────────────────────────── */}\n <div className=\"bg-surface-sunken/50 rounded-md p-5 mb-8\">\n {/* Row 1: Job ID + stats + status */}\n <div className=\"flex items-center gap-4 mb-4\">\n <h2 className=\"text-sm font-mono text-text-primary truncate flex-1\">{execution.workflow_id}</h2>\n <div className=\"flex items-center gap-4 shrink-0\">\n <Stat label=\"Tools\" value={summary.activities.user} />\n <Stat label=\"System\" value={summary.activities.system} muted />\n {summary.child_workflows.total > 0 && (\n <Stat label=\"Children\" value={summary.child_workflows.total} />\n )}\n {summary.timers > 0 && <Stat label=\"Timers\" value={summary.timers} />}\n {summary.signals > 0 && <Stat label=\"Signals\" value={summary.signals} />}\n <StatusBadge status={statusMap[execution.status] ?? execution.status} />\n </div>\n </div>\n\n {/* Row 2: Namespace, Topic, Duration, Started, Trace */}\n <div className=\"grid grid-cols-6 gap-x-6\">\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5\">Server</p>\n <p className=\"text-xs font-mono text-text-primary truncate\">{namespace}</p>\n </div>\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5\">Tool</p>\n <p className=\"text-xs font-mono text-text-primary truncate\">{execution.workflow_type || '—'}</p>\n </div>\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5\">Duration</p>\n <DurationValue ms={execution.duration_ms} className=\"font-mono text-text-primary\" />\n </div>\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5\">Started</p>\n {execution.start_time\n ? <DateValue date={execution.start_time} format=\"datetime\" className=\"font-mono text-text-primary\" />\n : <span className=\"text-xs text-text-tertiary\">--</span>}\n </div>\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5\">Completed</p>\n {execution.close_time\n ? <DateValue date={execution.close_time} format=\"datetime\" className=\"font-mono text-text-primary\" />\n : <span className=\"text-xs text-text-tertiary\">--</span>}\n </div>\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5\">Trace</p>\n {execution.trace_id ? (\n <CopyableId\n label=\"\"\n value={execution.trace_id}\n href={traceUrl ? traceUrl.replace('{traceId}', execution.trace_id) : undefined}\n external\n />\n ) : (\n <span className=\"text-xs text-text-tertiary\">—</span>\n )}\n </div>\n </div>\n </div>\n\n {/* ── Sections ────────────────────────────────────── */}\n <div className=\"space-y-6\">\n {/* Details: Input + Result */}\n <CollapsibleSection title=\"Details\" sectionKey=\"details\" isCollapsed={isCollapsed('details')} onToggle={toggle}>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-6\">\n <div>\n <JsonViewer data={triggerInput ?? {}} label=\"Input\" />\n </div>\n {result !== null && (\n <div>\n <JsonViewer data={result} label=\"Result\" />\n </div>\n )}\n </div>\n </CollapsibleSection>\n\n {/* Execution Timeline (swimlane) */}\n <CollapsibleSection title=\"Execution Timeline\" sectionKey=\"timeline\" isCollapsed={isCollapsed('timeline')} onToggle={toggle}>\n <SwimlaneTimeline events={events} outline jid={jobId} appId={namespace || 'durable'} />\n </CollapsibleSection>\n\n {/* Events (table) */}\n <CollapsibleSection title=\"Events\" sectionKey=\"events\" isCollapsed={isCollapsed('events')} onToggle={toggle}>\n <EventTable events={events} jid={jobId} appId={namespace || 'durable'} />\n </CollapsibleSection>\n </div>\n </div>\n );\n}\n\n// ── Stat pill ────────────────────────────────────────────────────────────────\n\nfunction Stat({ label, value, muted }: { label: string; value: number; muted?: boolean }) {\n return (\n <div className=\"flex items-center gap-1.5 text-xs\">\n <span className=\"text-text-tertiary\">{label}</span>\n <span className={`font-medium tabular-nums ${muted ? 'text-text-tertiary' : 'text-text-primary'}`}>{value}</span>\n </div>\n );\n}\n"],"names":["statusMap","ActionsDropdown","isRunning","onTerminate","open","setOpen","useState","ref","useRef","useEffect","handler","e","jsxs","jsx","McpRunDetailPage","jobId","useParams","searchParams","useSearchParams","namespace","queryClient","useQueryClient","execution","isLoading","error","refetch","isFetching","useMcpRunExecution","interruptMutation","useInterruptJob","settings","useSettings","isCollapsed","toggle","useCollapsedSections","traceUrl","_a","activityHandler","useCallback","event","useEventSubscription","NATS_SUBJECT_PREFIX","PageHeader","_b","events","summary","triggerCompleted","triggerInput","rawResult","result","ListToolbar","Stat","StatusBadge","DurationValue","DateValue","CopyableId","CollapsibleSection","JsonViewer","SwimlaneTimeline","EventTable","label","value","muted"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as m,j as s}from"./vendor-query-B2UbickB.js";import{a as R,u as T}from"./pipelines-
|
|
2
|
-
//# sourceMappingURL=McpRunsPage-
|
|
1
|
+
import{a as m,j as s}from"./vendor-query-B2UbickB.js";import{a as R,u as T}from"./pipelines-CNLhgj8b.js";import{a as M}from"./yaml-workflows-BjrMQLTK.js";import{u as z}from"./useFilterParams-x-Dg0Vgz.js";import{u as E}from"./useNamespace-C88ZxGoX.js";import{b as $}from"./api-path-u2Jf9QXS.js";import{D as A}from"./DataTable-ZWgVQg7F.js";import{W as L}from"./WorkflowPill-IDjTRfQ8.js";import{E as U}from"./ElapsedCell-BtmDQaym.js";import{b}from"./index-Dgw1KKpq.js";import{P as I}from"./PageHeader-BhaWTWcM.js";import{F as O,b as g}from"./FilterBar-BQ2JGg8U.js";import{S as W}from"./StickyPagination-D8XuMSWD.js";import{L as B}from"./ListToolbar-FpcvqNkN.js";import{R as H,a as q}from"./RowActions-BA9L9djf.js";import{u as G}from"./vendor-icons-CEWCGPeJ.js";import{c as V}from"./vendor-react-CXumBFUA.js";import"./controlplane-B7VJTlZD.js";import"./EmptyState-BcsfPq9T.js";const Y={running:"in_progress",completed:"completed",failed:"failed"},D={in_progress:"bg-status-active",completed:"bg-status-success",failed:"bg-status-error"},J={running:"text-status-active",completed:"text-status-success",failed:"text-status-error"};function K(x,f){return[{key:"workflow_id",label:"Run ID",render:t=>{const a=D[Y[t.status]??t.status]??"bg-status-pending",i=t.status==="running"?" animate-pulse":"";return s.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[s.jsx("span",{className:`w-1.5 h-1.5 shrink-0 rounded-full ${a}${i}`,title:t.status}),s.jsx("span",{className:"font-mono text-xs text-text-primary truncate",children:t.workflow_id})]})}},{key:"entity",label:"Tool",render:t=>t.entity?s.jsx(L,{type:t.entity,variant:"pipeline",size:"xs"}):s.jsx("span",{className:"text-[10px] text-text-tertiary",children:"—"}),className:"w-44 shrink-0"},{key:"created_at",label:"Created",sortable:!0,render:t=>s.jsx(b,{date:t.created_at,format:"relative",className:"text-xs text-text-secondary whitespace-nowrap"}),className:"w-32"},{key:"updated_at",label:"Updated",sortable:!0,render:t=>s.jsx(b,{date:t.updated_at,format:"relative",className:"text-xs text-text-secondary whitespace-nowrap"}),className:"w-32"},{key:"duration",label:"Duration",render:t=>s.jsx(U,{startDate:t.created_at,endDate:t.status==="running"?null:t.updated_at,isLive:t.status==="running"}),className:"w-28"},{key:"actions",label:"",render:t=>s.jsxs(H,{children:[s.jsx(q,{icon:G,title:`Filter by ${t.entity}`,onClick:()=>x(t.entity)}),s.jsx("button",{onClick:a=>{a.stopPropagation(),f(t.status)},className:"opacity-0 group-hover/row:opacity-100 transition-opacity",title:`Filter by ${t.status}`,children:s.jsx("svg",{className:`w-[18px] h-[18px] ${J[t.status]??"text-text-tertiary"} hover:opacity-70`,viewBox:"0 0 24 24",fill:"currentColor",children:s.jsx("circle",{cx:"12",cy:"12",r:"6"})})})]}),className:"w-24 text-right"}]}function ge(){const x=V(),{namespace:f,available:t}=E("namespace"),{filters:a,setFilter:i,setFilters:v,pagination:o,sort:u,setSort:j}=z({filters:{search:"",entity:"",status:"",namespace:""}}),[d,_]=m.useState(a.search);m.useEffect(()=>{if(d===a.search)return;const e=setTimeout(()=>i("search",d),300);return()=>clearTimeout(e)},[d,i,a.search]);const{data:l}=M(),y=m.useMemo(()=>{const e=new Set(t);for(const r of(l==null?void 0:l.app_ids)??[])e.add(r);return[...e].sort()},[t,l==null?void 0:l.app_ids]),n=a.namespace||f,{data:c}=R(n),{data:p,isLoading:S,refetch:N,isFetching:k}=T({app_id:n,limit:o.pageSize,offset:o.offset,entity:a.entity||void 0,search:a.search||void 0,status:a.status||void 0,sort_by:u.sort_by||"created_at",order:u.order||"desc"}),h=(p==null?void 0:p.total)??0,w=(p==null?void 0:p.jobs)??[],C=K(e=>i("entity",e),e=>i("status",e)),P=m.useMemo(()=>{const e=new Set(y);return n&&e.add(n),[...e].sort().map(r=>({value:r,label:r}))},[y,n]),F=m.useMemo(()=>{const e=new Set((c==null?void 0:c.entities)??[]);return a.entity&&!e.has(a.entity)&&e.add(a.entity),[...e].sort().map(r=>({value:r,label:r}))},[c==null?void 0:c.entities,a.entity]);return s.jsxs("div",{children:[s.jsx(I,{title:"Pipeline Executions",docsHash:"#docs:dashboard.md:pipeline-executions"}),s.jsxs(O,{actions:s.jsx(B,{onRefresh:()=>N(),isFetching:k,apiPath:$("/pipelines",{app_id:n,limit:o.pageSize,offset:o.offset,entity:a.entity||void 0,status:a.status||void 0,search:a.search||void 0,sort_by:u.sort_by||"created_at",order:u.order||"desc"})}),children:[s.jsx(g,{label:"Namespace",value:n,onChange:e=>{v({namespace:e,entity:""})},options:P,required:!0}),s.jsx("input",{type:"text",placeholder:"Search run ID...",value:d,onChange:e=>_(e.target.value),className:"input text-[11px] py-1 px-2 w-56"}),s.jsx(g,{label:"Tool",value:a.entity,onChange:e=>i("entity",e),options:F}),s.jsx(g,{label:"Status",value:a.status,onChange:e=>i("status",e),options:[{value:"running",label:"Running"},{value:"completed",label:"Completed"},{value:"failed",label:"Failed"}]})]}),s.jsx(A,{columns:C,data:w,keyFn:e=>e.workflow_id,onRowClick:e=>x(`/mcp/executions/${encodeURIComponent(e.workflow_id)}?namespace=${n}`),isLoading:S,emptyMessage:"No pipeline executions found",sort:u,onSort:j}),s.jsx(W,{page:o.page,totalPages:o.totalPages(h),onPageChange:o.setPage,total:h,pageSize:o.pageSize,onPageSizeChange:o.setPageSize})]})}export{ge as McpRunsPage};
|
|
2
|
+
//# sourceMappingURL=McpRunsPage-BwgB6mRV.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpRunsPage-MIwmK-Ky.js","sources":["../../src/pages/mcp/McpRunsPage.tsx"],"sourcesContent":["import { useState, useEffect, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Filter } from 'lucide-react';\nimport { useMcpRuns, useMcpEntities } from '../../api/pipelines';\nimport { useYamlWorkflowAppIds } from '../../api/yaml-workflows';\nimport { useFilterParams } from '../../hooks/useFilterParams';\nimport { useNamespace } from '../../hooks/useNamespace';\nimport { buildApiPath } from '../../lib/api-path';\nimport { DataTable, type Column } from '../../components/common/data/DataTable';\nimport { WorkflowPill } from '../../components/common/display/WorkflowPill';\nimport { ElapsedCell } from '../../components/common/display/ElapsedCell';\nimport { DateValue } from '../../components/common/display/DateValue';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { FilterBar, FilterSelect } from '../../components/common/data/FilterBar';\nimport { StickyPagination } from '../../components/common/data/StickyPagination';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\nimport { RowAction, RowActionGroup } from '../../components/common/layout/RowActions';\nimport type { LTJob } from '../../api/types';\n\nconst statusMap: Record<string, string> = {\n running: 'in_progress',\n completed: 'completed',\n failed: 'failed',\n};\n\nconst STATUS_DOT: Record<string, string> = {\n in_progress: 'bg-status-active',\n completed: 'bg-status-success',\n failed: 'bg-status-error',\n};\n\nconst STATUS_COLORS: Record<string, string> = {\n running: 'text-status-active',\n completed: 'text-status-success',\n failed: 'text-status-error',\n};\n\nfunction buildColumns(\n onFilterEntity: (entity: string) => void,\n onFilterStatus: (status: string) => void,\n): Column<LTJob>[] {\n return [\n {\n key: 'workflow_id',\n label: 'Run ID',\n render: (row) => {\n const dotClass = STATUS_DOT[statusMap[row.status] ?? row.status] ?? 'bg-status-pending';\n const pulseClass = row.status === 'running' ? ' animate-pulse' : '';\n return (\n <div className=\"flex items-center gap-2 min-w-0\">\n <span className={`w-1.5 h-1.5 shrink-0 rounded-full ${dotClass}${pulseClass}`} title={row.status} />\n <span className=\"font-mono text-xs text-text-primary truncate\">{row.workflow_id}</span>\n </div>\n );\n },\n },\n {\n key: 'entity',\n label: 'Tool',\n render: (row) => row.entity\n ? <WorkflowPill type={row.entity} variant=\"pipeline\" size=\"xs\" />\n : <span className=\"text-[10px] text-text-tertiary\">—</span>,\n className: 'w-44 shrink-0',\n },\n {\n key: 'created_at',\n label: 'Created',\n sortable: true,\n render: (row) => <DateValue date={row.created_at} format=\"relative\" className=\"text-xs text-text-secondary whitespace-nowrap\" />,\n className: 'w-32',\n },\n {\n key: 'updated_at',\n label: 'Updated',\n sortable: true,\n render: (row) => <DateValue date={row.updated_at} format=\"relative\" className=\"text-xs text-text-secondary whitespace-nowrap\" />,\n className: 'w-32',\n },\n {\n key: 'duration',\n label: 'Duration',\n render: (row) => (\n <ElapsedCell\n startDate={row.created_at}\n endDate={row.status === 'running' ? null : row.updated_at}\n isLive={row.status === 'running'}\n />\n ),\n className: 'w-28',\n },\n {\n key: 'actions',\n label: '',\n render: (row) => (\n <RowActionGroup>\n <RowAction\n icon={Filter}\n title={`Filter by ${row.entity}`}\n onClick={() => onFilterEntity(row.entity)}\n />\n <button\n onClick={(e) => { e.stopPropagation(); onFilterStatus(row.status); }}\n className=\"opacity-0 group-hover/row:opacity-100 transition-opacity\"\n title={`Filter by ${row.status}`}\n >\n <svg className={`w-[18px] h-[18px] ${STATUS_COLORS[row.status] ?? 'text-text-tertiary'} hover:opacity-70`} viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <circle cx=\"12\" cy=\"12\" r=\"6\" />\n </svg>\n </button>\n </RowActionGroup>\n ),\n className: 'w-24 text-right',\n },\n ];\n}\n\nexport function McpRunsPage() {\n const navigate = useNavigate();\n const { namespace: hookNamespace, available } = useNamespace('namespace');\n const { filters, setFilter, setFilters, pagination, sort, setSort } = useFilterParams({\n filters: { search: '', entity: '', status: '', namespace: '' },\n });\n\n const [searchInput, setSearchInput] = useState(filters.search);\n\n useEffect(() => {\n if (searchInput === filters.search) return;\n const timer = setTimeout(() => setFilter('search', searchInput), 300);\n return () => clearTimeout(timer);\n }, [searchInput, setFilter, filters.search]);\n\n const { data: appIdData } = useYamlWorkflowAppIds();\n\n // Merge real HotMesh namespaces (from controlplane/apps) with YAML workflow app_ids\n const allNamespaceNames = useMemo(() => {\n const set = new Set(available);\n for (const id of appIdData?.app_ids ?? []) {\n set.add(id);\n }\n return [...set].sort();\n }, [available, appIdData?.app_ids]);\n\n const activeNamespace = filters.namespace || hookNamespace;\n const { data: entitiesData } = useMcpEntities(activeNamespace);\n\n const { data: runsData, isLoading, refetch, isFetching } = useMcpRuns({\n app_id: activeNamespace,\n limit: pagination.pageSize,\n offset: pagination.offset,\n entity: filters.entity || undefined,\n search: filters.search || undefined,\n status: filters.status || undefined,\n sort_by: sort.sort_by || 'created_at',\n order: sort.order || 'desc',\n });\n\n const total = runsData?.total ?? 0;\n const jobs = runsData?.jobs ?? [];\n\n const columns = buildColumns(\n (entity) => setFilter('entity', entity),\n (status) => setFilter('status', status),\n );\n\n const namespaces = useMemo(() => {\n const set = new Set(allNamespaceNames);\n if (activeNamespace) set.add(activeNamespace);\n return [...set].sort().map((id) => ({ value: id, label: id }));\n }, [allNamespaceNames, activeNamespace]);\n\n const entities = useMemo(() => {\n const known = new Set(entitiesData?.entities ?? []);\n if (filters.entity && !known.has(filters.entity)) known.add(filters.entity);\n return [...known].sort().map((e) => ({ value: e, label: e }));\n }, [entitiesData?.entities, filters.entity]);\n\n return (\n <div>\n <PageHeader title=\"Pipeline Executions\" docsHash=\"#docs:dashboard.md:pipeline-executions\" />\n\n <FilterBar actions={\n <ListToolbar\n onRefresh={() => refetch()}\n isFetching={isFetching}\n apiPath={buildApiPath('/pipelines', {\n app_id: activeNamespace,\n limit: pagination.pageSize,\n offset: pagination.offset,\n entity: filters.entity || undefined,\n status: filters.status || undefined,\n search: filters.search || undefined,\n sort_by: sort.sort_by || 'created_at',\n order: sort.order || 'desc',\n })}\n />\n }>\n <FilterSelect\n label=\"Namespace\"\n value={activeNamespace}\n onChange={(v) => {\n setFilters({ namespace: v, entity: '' });\n }}\n options={namespaces}\n required\n />\n <input\n type=\"text\"\n placeholder=\"Search run ID...\"\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n className=\"input text-[11px] py-1 px-2 w-56\"\n />\n <FilterSelect\n label=\"Tool\"\n value={filters.entity}\n onChange={(v) => setFilter('entity', v)}\n options={entities}\n />\n <FilterSelect\n label=\"Status\"\n value={filters.status}\n onChange={(v) => setFilter('status', v)}\n options={[\n { value: 'running', label: 'Running' },\n { value: 'completed', label: 'Completed' },\n { value: 'failed', label: 'Failed' },\n ]}\n />\n </FilterBar>\n\n <DataTable\n columns={columns}\n data={jobs}\n keyFn={(row) => row.workflow_id}\n onRowClick={(row) => navigate(`/mcp/executions/${encodeURIComponent(row.workflow_id)}?namespace=${activeNamespace}`)}\n isLoading={isLoading}\n emptyMessage=\"No pipeline executions found\"\n sort={sort}\n onSort={setSort}\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":["statusMap","STATUS_DOT","STATUS_COLORS","buildColumns","onFilterEntity","onFilterStatus","row","dotClass","pulseClass","jsxs","jsx","WorkflowPill","DateValue","ElapsedCell","RowActionGroup","RowAction","Filter","e","McpRunsPage","navigate","useNavigate","hookNamespace","available","useNamespace","filters","setFilter","setFilters","pagination","sort","setSort","useFilterParams","searchInput","setSearchInput","useState","useEffect","timer","appIdData","useYamlWorkflowAppIds","allNamespaceNames","useMemo","set","id","activeNamespace","entitiesData","useMcpEntities","runsData","isLoading","refetch","isFetching","useMcpRuns","total","jobs","columns","entity","status","namespaces","entities","known","PageHeader","FilterBar","ListToolbar","buildApiPath","FilterSelect","v","DataTable","StickyPagination"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"McpRunsPage-BwgB6mRV.js","sources":["../../src/pages/mcp/McpRunsPage.tsx"],"sourcesContent":["import { useState, useEffect, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Filter } from 'lucide-react';\nimport { useMcpRuns, useMcpEntities } from '../../api/pipelines';\nimport { useYamlWorkflowAppIds } from '../../api/yaml-workflows';\nimport { useFilterParams } from '../../hooks/useFilterParams';\nimport { useNamespace } from '../../hooks/useNamespace';\nimport { buildApiPath } from '../../lib/api-path';\nimport { DataTable, type Column } from '../../components/common/data/DataTable';\nimport { WorkflowPill } from '../../components/common/display/WorkflowPill';\nimport { ElapsedCell } from '../../components/common/display/ElapsedCell';\nimport { DateValue } from '../../components/common/display/DateValue';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { FilterBar, FilterSelect } from '../../components/common/data/FilterBar';\nimport { StickyPagination } from '../../components/common/data/StickyPagination';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\nimport { RowAction, RowActionGroup } from '../../components/common/layout/RowActions';\nimport type { LTJob } from '../../api/types';\n\nconst statusMap: Record<string, string> = {\n running: 'in_progress',\n completed: 'completed',\n failed: 'failed',\n};\n\nconst STATUS_DOT: Record<string, string> = {\n in_progress: 'bg-status-active',\n completed: 'bg-status-success',\n failed: 'bg-status-error',\n};\n\nconst STATUS_COLORS: Record<string, string> = {\n running: 'text-status-active',\n completed: 'text-status-success',\n failed: 'text-status-error',\n};\n\nfunction buildColumns(\n onFilterEntity: (entity: string) => void,\n onFilterStatus: (status: string) => void,\n): Column<LTJob>[] {\n return [\n {\n key: 'workflow_id',\n label: 'Run ID',\n render: (row) => {\n const dotClass = STATUS_DOT[statusMap[row.status] ?? row.status] ?? 'bg-status-pending';\n const pulseClass = row.status === 'running' ? ' animate-pulse' : '';\n return (\n <div className=\"flex items-center gap-2 min-w-0\">\n <span className={`w-1.5 h-1.5 shrink-0 rounded-full ${dotClass}${pulseClass}`} title={row.status} />\n <span className=\"font-mono text-xs text-text-primary truncate\">{row.workflow_id}</span>\n </div>\n );\n },\n },\n {\n key: 'entity',\n label: 'Tool',\n render: (row) => row.entity\n ? <WorkflowPill type={row.entity} variant=\"pipeline\" size=\"xs\" />\n : <span className=\"text-[10px] text-text-tertiary\">—</span>,\n className: 'w-44 shrink-0',\n },\n {\n key: 'created_at',\n label: 'Created',\n sortable: true,\n render: (row) => <DateValue date={row.created_at} format=\"relative\" className=\"text-xs text-text-secondary whitespace-nowrap\" />,\n className: 'w-32',\n },\n {\n key: 'updated_at',\n label: 'Updated',\n sortable: true,\n render: (row) => <DateValue date={row.updated_at} format=\"relative\" className=\"text-xs text-text-secondary whitespace-nowrap\" />,\n className: 'w-32',\n },\n {\n key: 'duration',\n label: 'Duration',\n render: (row) => (\n <ElapsedCell\n startDate={row.created_at}\n endDate={row.status === 'running' ? null : row.updated_at}\n isLive={row.status === 'running'}\n />\n ),\n className: 'w-28',\n },\n {\n key: 'actions',\n label: '',\n render: (row) => (\n <RowActionGroup>\n <RowAction\n icon={Filter}\n title={`Filter by ${row.entity}`}\n onClick={() => onFilterEntity(row.entity)}\n />\n <button\n onClick={(e) => { e.stopPropagation(); onFilterStatus(row.status); }}\n className=\"opacity-0 group-hover/row:opacity-100 transition-opacity\"\n title={`Filter by ${row.status}`}\n >\n <svg className={`w-[18px] h-[18px] ${STATUS_COLORS[row.status] ?? 'text-text-tertiary'} hover:opacity-70`} viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <circle cx=\"12\" cy=\"12\" r=\"6\" />\n </svg>\n </button>\n </RowActionGroup>\n ),\n className: 'w-24 text-right',\n },\n ];\n}\n\nexport function McpRunsPage() {\n const navigate = useNavigate();\n const { namespace: hookNamespace, available } = useNamespace('namespace');\n const { filters, setFilter, setFilters, pagination, sort, setSort } = useFilterParams({\n filters: { search: '', entity: '', status: '', namespace: '' },\n });\n\n const [searchInput, setSearchInput] = useState(filters.search);\n\n useEffect(() => {\n if (searchInput === filters.search) return;\n const timer = setTimeout(() => setFilter('search', searchInput), 300);\n return () => clearTimeout(timer);\n }, [searchInput, setFilter, filters.search]);\n\n const { data: appIdData } = useYamlWorkflowAppIds();\n\n // Merge real HotMesh namespaces (from controlplane/apps) with YAML workflow app_ids\n const allNamespaceNames = useMemo(() => {\n const set = new Set(available);\n for (const id of appIdData?.app_ids ?? []) {\n set.add(id);\n }\n return [...set].sort();\n }, [available, appIdData?.app_ids]);\n\n const activeNamespace = filters.namespace || hookNamespace;\n const { data: entitiesData } = useMcpEntities(activeNamespace);\n\n const { data: runsData, isLoading, refetch, isFetching } = useMcpRuns({\n app_id: activeNamespace,\n limit: pagination.pageSize,\n offset: pagination.offset,\n entity: filters.entity || undefined,\n search: filters.search || undefined,\n status: filters.status || undefined,\n sort_by: sort.sort_by || 'created_at',\n order: sort.order || 'desc',\n });\n\n const total = runsData?.total ?? 0;\n const jobs = runsData?.jobs ?? [];\n\n const columns = buildColumns(\n (entity) => setFilter('entity', entity),\n (status) => setFilter('status', status),\n );\n\n const namespaces = useMemo(() => {\n const set = new Set(allNamespaceNames);\n if (activeNamespace) set.add(activeNamespace);\n return [...set].sort().map((id) => ({ value: id, label: id }));\n }, [allNamespaceNames, activeNamespace]);\n\n const entities = useMemo(() => {\n const known = new Set(entitiesData?.entities ?? []);\n if (filters.entity && !known.has(filters.entity)) known.add(filters.entity);\n return [...known].sort().map((e) => ({ value: e, label: e }));\n }, [entitiesData?.entities, filters.entity]);\n\n return (\n <div>\n <PageHeader title=\"Pipeline Executions\" docsHash=\"#docs:dashboard.md:pipeline-executions\" />\n\n <FilterBar actions={\n <ListToolbar\n onRefresh={() => refetch()}\n isFetching={isFetching}\n apiPath={buildApiPath('/pipelines', {\n app_id: activeNamespace,\n limit: pagination.pageSize,\n offset: pagination.offset,\n entity: filters.entity || undefined,\n status: filters.status || undefined,\n search: filters.search || undefined,\n sort_by: sort.sort_by || 'created_at',\n order: sort.order || 'desc',\n })}\n />\n }>\n <FilterSelect\n label=\"Namespace\"\n value={activeNamespace}\n onChange={(v) => {\n setFilters({ namespace: v, entity: '' });\n }}\n options={namespaces}\n required\n />\n <input\n type=\"text\"\n placeholder=\"Search run ID...\"\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n className=\"input text-[11px] py-1 px-2 w-56\"\n />\n <FilterSelect\n label=\"Tool\"\n value={filters.entity}\n onChange={(v) => setFilter('entity', v)}\n options={entities}\n />\n <FilterSelect\n label=\"Status\"\n value={filters.status}\n onChange={(v) => setFilter('status', v)}\n options={[\n { value: 'running', label: 'Running' },\n { value: 'completed', label: 'Completed' },\n { value: 'failed', label: 'Failed' },\n ]}\n />\n </FilterBar>\n\n <DataTable\n columns={columns}\n data={jobs}\n keyFn={(row) => row.workflow_id}\n onRowClick={(row) => navigate(`/mcp/executions/${encodeURIComponent(row.workflow_id)}?namespace=${activeNamespace}`)}\n isLoading={isLoading}\n emptyMessage=\"No pipeline executions found\"\n sort={sort}\n onSort={setSort}\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":["statusMap","STATUS_DOT","STATUS_COLORS","buildColumns","onFilterEntity","onFilterStatus","row","dotClass","pulseClass","jsxs","jsx","WorkflowPill","DateValue","ElapsedCell","RowActionGroup","RowAction","Filter","e","McpRunsPage","navigate","useNavigate","hookNamespace","available","useNamespace","filters","setFilter","setFilters","pagination","sort","setSort","useFilterParams","searchInput","setSearchInput","useState","useEffect","timer","appIdData","useYamlWorkflowAppIds","allNamespaceNames","useMemo","set","id","activeNamespace","entitiesData","useMcpEntities","runsData","isLoading","refetch","isFetching","useMcpRuns","total","jobs","columns","entity","status","namespaces","entities","known","PageHeader","FilterBar","ListToolbar","buildApiPath","FilterSelect","v","DataTable","StickyPagination"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as k,j as e}from"./vendor-query-B2UbickB.js";import{b as Ne}from"./roles-BdtnzLsL.js";import{K as ue}from"./index-D-7W2AHB.js";import{i as ke}from"./useEventHooks-SfWdyc5L.js";import{P as $e}from"./PageHeader-BhaWTWcM.js";import{X as we,ae,au as Se,as as Me,av as _e}from"./vendor-icons-CEWCGPeJ.js";import{L as T,f as Le}from"./vendor-react-CXumBFUA.js";const he=800,me=270,O=40,Pe=76,re=24,Re=72,se=he-O-Pe,fe=me-re-Re,v=re+fe,de=O+se,b="0.5s cubic-bezier(0.4, 0, 0.2, 1)";function qe(t){return t.length===0?"":t.map((n,o)=>`${o===0?"M":"L"} ${n.x.toFixed(1)} ${n.y.toFixed(1)}`).join(" ")}function U(t){if(t.length===0)return"";if(t.length===1)return`M ${t[0].x} ${t[0].y}`;const n=[];for(let o=0;o<t.length-1;o++){const c=t[Math.max(0,o-1)],d=t[o],p=t[o+1],a=t[Math.min(t.length-1,o+2)],x=(d.x+(p.x-c.x)/6).toFixed(1),u=(d.y+(p.y-c.y)/6).toFixed(1),l=(p.x-(a.x-d.x)/6).toFixed(1),i=(p.y-(a.y-d.y)/6).toFixed(1);o===0&&n.push(`M ${d.x.toFixed(1)} ${d.y.toFixed(1)}`),n.push(`C ${x} ${u}, ${l} ${i}, ${p.x.toFixed(1)} ${p.y.toFixed(1)}`)}return n.join(" ")}function Ae(t,n){if(t.length<2||n.length<2)return"";const o=U(t),c=[...n].reverse(),d=U(c),p=d.slice(d.indexOf("C"));return`${o} L ${c[0].x.toFixed(1)} ${c[0].y.toFixed(1)} ${p} Z`}function Ce(t){return t>=1e4?`${Math.round(t/1e3)}k`:t>=1e3?`${(t/1e3).toFixed(1)}k`:String(t)}function J(t){return t.length>0?t[t.length-1]:void 0}function Fe(t){return t==null?{stroke:"#cbd5e1",fill:"#f8fafc"}:t>=1?{stroke:"#10b981",fill:"#ecfdf5"}:t>=.6?{stroke:"#f59e0b",fill:"#fffbeb"}:{stroke:"#ef4444",fill:"#fef2f2"}}const q="#6366f1",D="#0ea5e9",I="#4e6a5e",Ee=13;function We(t,n){const o=[...t].sort((a,x)=>a.y-x.y);let c=-1/0;const d=o.map(a=>{const x=Math.max(a.y+3,c+Ee);return c=x,{...a,labelY:x}}),p=d.length>0?d[d.length-1].labelY-n:0;if(p>0)for(const a of d)a.labelY-=p;return d}function Oe({stations:t,selectedRole:n,onSelect:o,onUpstreamSelect:c,periodHours:d}){const[p,a]=k.useState(null),x=t.length;if(x===0)return null;const u=s=>x===1?O+se/2:O+s/(x-1)*se,l=new Map(t.map((s,m)=>[s.role,u(m)])),i=t.map((s,m)=>{var W,Y,L,G;const g=s.target_per_hour??null,R=g!=null?g*d:null;return{idx:m,x:u(m),expected:R,actual:((W=s.metric)==null?void 0:W.resolved)??0,active:((Y=s.metric)==null?void 0:Y.claimed)??0,pending:((L=s.metric)==null?void 0:L.pending)??0,inArrears:((G=s.metric)==null?void 0:G.in_arrears)??0}}),$=i.some(s=>s.expected!=null),f=Math.max(1,...i.map(s=>s.expected??0),...i.map(s=>s.actual),...i.map(s=>s.expected!=null?s.pending:0))*1.15,h=s=>re+fe*(1-Math.max(0,Math.min(s,f))/f),N=i.filter(s=>s.expected!=null),w=N.map(s=>({...s,y:h(s.expected)})),_=N.map(s=>({...s,y:h(s.actual)})),j=N.map(s=>({...s,y:h(s.active)})),P=N.map(s=>({...s,y:h(s.pending)})),S=qe(w),A=U(_),z=U(j),Q=U(P),C=J(_),K=J(w),F=J(j),Z=J(P),B=_.length>=2&&C?`${A} L ${C.x.toFixed(1)} ${v} L ${_[0].x.toFixed(1)} ${v} Z`:"",H=N.some(s=>s.pending>0||s.active>0),V=H&&j.length>=2&&F?`${z} L ${F.x.toFixed(1)} ${v} L ${j[0].x.toFixed(1)} ${v} Z`:"",r=H?Ae(P,j):"",y=N.some(s=>s.active>0),E=N.some(s=>s.pending>s.active),ne=We([K?{key:"target",text:"target",color:"#ef4444",y:K.y}:null,C?{key:"actual",text:"actual",color:I,y:C.y}:null,y&&F?{key:"active",text:"active",color:q,y:F.y}:null,E&&Z?{key:"queued",text:"queued",color:D,y:Z.y}:null].filter(Boolean),v+4);return e.jsxs("svg",{viewBox:`0 0 ${he} ${me}`,className:"w-full h-full",preserveAspectRatio:"xMidYMid meet",style:{display:"block"},children:[t.map(s=>{if(!s.parent_role)return null;const m=l.get(s.parent_role);if(m==null)return null;const g=u(t.findIndex(R=>R.role===s.role));return e.jsx("line",{x1:m,y1:v,x2:g,y2:v,stroke:"#e2e8f0",strokeWidth:.75},`dep-${s.role}`)}),B&&e.jsx("path",{d:B,fill:I,opacity:.05,style:{transition:`d ${b}`}}),V&&e.jsx("path",{d:V,fill:q,opacity:.12,style:{transition:`d ${b}`}}),r&&e.jsx("path",{d:r,fill:D,opacity:.12,style:{transition:`d ${b}`}}),S&&e.jsx("path",{d:S,fill:"none",stroke:"#ef4444",strokeWidth:.5,strokeLinejoin:"round",opacity:.9,style:{transition:`d ${b}`}}),w.map(s=>e.jsx("text",{x:s.x,y:s.y-3.5,textAnchor:"middle",fontSize:6.5,fill:"#ef4444",fontFamily:"ui-monospace, monospace",fontWeight:"500",opacity:.7,style:{transition:`y ${b}`},children:Math.round(s.expected)},`tval-${s.idx}`)),H&&Q&&e.jsx("path",{d:Q,fill:"none",stroke:D,strokeWidth:.75,strokeDasharray:"2 3",strokeLinecap:"round",opacity:.55,style:{transition:`d ${b}`}}),z&&e.jsx("path",{d:z,fill:"none",stroke:q,strokeWidth:.75,strokeDasharray:"2 3",strokeLinecap:"round",opacity:.5,style:{transition:`d ${b}`}}),A&&e.jsx("path",{d:A,fill:"none",stroke:I,strokeWidth:1,strokeLinejoin:"round",strokeLinecap:"round",opacity:.75,style:{transition:`d ${b}`}}),j.map((s,m)=>{if(s.pending<=0&&s.active<=0)return null;const g=Math.max(2.5,Math.min(5,2.5+s.active/10)),R=s.pending>s.active,W=Math.min(P[m].y-4,s.y-g-4);return e.jsxs("g",{children:[s.pending>0&&e.jsx("text",{x:s.x,y:W,textAnchor:"middle",fontSize:7.5,fill:R?D:"#64748b",fontFamily:"ui-monospace, monospace",fontWeight:"600",style:{transition:`y ${b}`},children:s.pending}),e.jsxs("g",{transform:`translate(${s.x} ${s.y})`,style:{transition:`transform ${b}`},children:[e.jsx("circle",{r:g,fill:q,opacity:.85}),s.active>0&&e.jsx("text",{y:g+9,textAnchor:"middle",fontSize:7.5,fill:q,fontFamily:"ui-monospace, monospace",fontWeight:"600",children:s.active})]})]},`active-${s.idx}`)}),i.map(s=>{var xe;const m=t[s.idx],g=s.x,R=s.expected!=null?h(s.actual):v,W=s.expected&&s.expected>0?s.actual/s.expected:null,{stroke:Y}=Fe(s.expected!=null?W:null),L=Math.max(3,Math.min(5.5,3+s.actual/120)),G=m.role===n,le=p===s.idx,oe=s.expected==null?"idle · set a target rate to plot pace":`${s.actual} done · target ${Math.round(s.expected)}`+(s.pending>s.active?` · ${s.pending-s.active} waiting`:"")+(s.active>0?` · ${s.active} active`:""),X=oe.length*5.5+20,ie=Math.max(O+X/2+4,Math.min(de-X/2-4,g)),ce=R-L-10;return e.jsxs("g",{onClick:()=>o(m.role),onMouseEnter:()=>a(s.idx),onMouseLeave:()=>a(null),style:{cursor:"pointer"},children:[e.jsxs("g",{transform:`translate(${g} ${R})`,style:{transition:`transform ${b}`},children:[e.jsx("circle",{r:22,fill:"transparent"}),s.inArrears>0&&e.jsx("circle",{r:L+4,fill:"none",stroke:"#ef4444",strokeWidth:1,strokeDasharray:"3 2",opacity:.6}),e.jsx("circle",{r:L,fill:Y,opacity:.9,style:{transition:`r ${b}`}}),s.expected!=null&&e.jsx("text",{y:-L-5,textAnchor:"middle",fontSize:9.5,fill:I,fontFamily:"ui-monospace, monospace",fontWeight:"500",children:Ce(s.actual)}),le&&!G&&e.jsx("circle",{r:L+3,fill:"none",stroke:Y,strokeWidth:1,opacity:.4}),G&&e.jsx("circle",{r:L+4,fill:"none",stroke:"#6366f1",strokeWidth:2})]}),(((xe=m.upstream_roles)==null?void 0:xe.length)??0)>0&&e.jsxs("g",{transform:`translate(${g-20} ${v})`,onClick:ve=>{ve.stopPropagation(),c==null||c(m.upstream_roles[0])},style:{cursor:"pointer"},children:[e.jsx("title",{children:`Fed by ${m.upstream_roles.join(", ")} — click to view that sequence`}),e.jsx("circle",{r:9,cy:-6,fill:"transparent"}),e.jsx("path",{d:"M -7 -14 C -3 -14 -1 -9 0 -2",fill:"none",stroke:"#94a3b8",strokeWidth:1,strokeDasharray:"2 2",strokeLinecap:"round"}),e.jsx("path",{d:"M 0 -2 L 8 -2",stroke:"#94a3b8",strokeWidth:1,strokeLinecap:"round"}),e.jsx("path",{d:"M 8 -2 l -3.5 -2 v 4 z",fill:"#94a3b8"})]}),e.jsx("text",{x:g,y:v+14,textAnchor:"middle",fontSize:9.5,fill:"#475569",fontFamily:"ui-sans-serif, sans-serif",fontWeight:"500",children:m.title??m.role}),e.jsx("text",{x:g,y:v+26,textAnchor:"middle",fontSize:8,fill:"#94a3b8",fontFamily:"ui-monospace, monospace",children:m.role}),le&&e.jsxs("g",{children:[e.jsx("rect",{x:ie-X/2,y:ce-16,width:X,height:19,rx:3,fill:"#0f172a",opacity:.88}),e.jsx("text",{x:ie,y:ce-3,textAnchor:"middle",fontSize:8.5,fill:"white",fontFamily:"ui-monospace, monospace",children:oe})]})]},m.role)}),!$&&e.jsx("text",{x:O+se/2,y:v+48,textAnchor:"middle",fontSize:8.5,fill:"#94a3b8",fontFamily:"ui-sans-serif, sans-serif",children:"Set target_per_hour on each role in Admin → Roles to enable the pace chart"}),ne.map(s=>e.jsx("text",{x:de+6,y:s.labelY,fontSize:8,fill:s.color,fontFamily:"ui-sans-serif, sans-serif",fontWeight:s.key==="actual"?700:500,opacity:s.key==="active"?.85:1,style:{transition:`y ${b}`},children:s.text},s.key))]})}const ye=["15m","1h","24h","7d","30d"],De=t=>ye.includes(t);function ee(t){if(t==null)return"—";if(t<1){const n=Math.round(t*60);return n<=0?"< 1s":`${n}s`}return t<60?`${t.toFixed(0)}m`:`${(t/60).toFixed(1)}h`}function te({label:t,value:n}){return e.jsxs("div",{className:"flex items-center justify-between py-1",children:[e.jsx("span",{className:"text-[10px] text-text-tertiary uppercase tracking-wider",children:t}),e.jsx("span",{className:"text-xs font-mono font-medium text-text-primary tabular-nums",children:n})]})}function Ie({period:t,onChange:n}){return e.jsx("div",{className:"flex items-center gap-1 mb-4",children:ye.map(o=>e.jsx("button",{onClick:()=>n(o),className:`px-2 py-0.5 text-[10px] font-mono rounded transition-colors ${t===o?"bg-accent/10 text-accent font-semibold":"text-text-quaternary hover:text-text-secondary"}`,children:o},o))})}function Te({role:t,globalPeriod:n,onClose:o}){const[c,d]=k.useState(De(n)?n:"24h"),{data:p}=ue(c),a=p==null?void 0:p.stations.find(i=>i.role===t.role),x=t.sla_minutes??void 0,u=t.target_per_hour??void 0,l=t.worker_count??void 0;return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-start justify-between mb-1",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-baseline gap-1.5 flex-wrap",children:[e.jsx("span",{className:"text-sm font-mono font-bold text-text-primary",children:t.role}),t.title&&e.jsx("span",{className:"text-[10px] text-text-secondary",children:t.title})]}),t.description&&e.jsx("p",{className:"text-[10px] text-text-tertiary mt-0.5 line-clamp-2 leading-relaxed",children:t.description})]}),e.jsx("button",{onClick:o,className:"text-text-quaternary hover:text-text-secondary transition-colors mt-0.5 shrink-0 ml-2",children:e.jsx(we,{className:"w-4 h-4"})})]}),e.jsxs(T,{to:`/admin/roles/${encodeURIComponent(t.role)}`,className:"flex items-center gap-1 text-[10px] text-accent hover:underline mb-4",children:[e.jsx(ae,{className:"w-2.5 h-2.5"}),"Edit in Roles"]}),e.jsx(Ie,{period:c,onChange:d}),(u||x||l)&&e.jsxs("div",{className:"flex items-center gap-4 mb-4 text-[10px]",children:[u&&e.jsxs("div",{children:[e.jsxs("div",{className:"font-mono font-semibold text-text-primary",children:[u,"/h"]}),e.jsx("div",{className:"text-text-quaternary uppercase tracking-wider text-[8.5px]",children:"target"})]}),x&&e.jsxs("div",{children:[e.jsxs("div",{className:"font-mono font-semibold text-text-primary",children:[x,"m"]}),e.jsx("div",{className:"text-text-quaternary uppercase tracking-wider text-[8.5px]",children:"SLA"})]}),l&&e.jsxs("div",{children:[e.jsx("div",{className:"font-mono font-semibold text-text-primary",children:l}),e.jsx("div",{className:"text-text-quaternary uppercase tracking-wider text-[8.5px]",children:"workers"})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-x-3",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-[9px] text-text-quaternary uppercase tracking-wider mb-1.5",children:"Wait (queue)"}),e.jsx(te,{label:"P99",value:ee((a==null?void 0:a.wait.p99)??null)}),e.jsx(te,{label:"avg",value:ee((a==null?void 0:a.wait.avg)??null)})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[9px] text-text-quaternary uppercase tracking-wider mb-1.5",children:"Work (proc.)"}),e.jsx(te,{label:"P99",value:ee((a==null?void 0:a.work.p99)??null)}),e.jsx(te,{label:"avg",value:ee((a==null?void 0:a.work.avg)??null)})]})]}),e.jsxs("div",{className:"border-t border-surface-border/40 pt-2 mt-3 space-y-1.5",children:[x&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-[10px] text-text-tertiary",children:"SLA target"}),e.jsxs("span",{className:"text-xs font-mono text-text-secondary",children:[x,"m"]})]}),a&&a.in_arrears>0&&e.jsxs(T,{to:`/escalations/available?role=${encodeURIComponent(a.role)}&sort_by=created_at&order=asc`,className:"flex items-center justify-between group",children:[e.jsxs("span",{className:"text-[10px] text-red-500",children:[a.in_arrears," past SLA"]}),e.jsx(ae,{className:"w-3 h-3 text-red-400 group-hover:text-red-500 transition-colors"})]})]}),e.jsx("div",{className:"mt-4 border-t border-surface-border/40 pt-3",children:e.jsxs(T,{to:`/escalations/available?role=${encodeURIComponent(t.role)}`,className:"flex items-center gap-1.5 text-[10px] text-accent hover:underline",children:["View full queue",e.jsx(ae,{className:"w-2.5 h-2.5"})]})})]})}function ze({allMetrics:t,orderedRoles:n,period:o}){const c=t.reduce((l,i)=>l+i.pending,0),d=t.reduce((l,i)=>l+i.resolved,0),p=t.reduce((l,i)=>l+i.in_arrears,0),a=new Map(t.map(l=>[l.role,l])),x=t.filter(l=>l.in_arrears>0).length,u=t.filter(l=>l.pending>0).length;return e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"text-[9px] text-text-quaternary uppercase tracking-wider mb-3",children:["Pipeline · ",o]}),e.jsx("div",{className:"mb-4",children:x>0?e.jsxs("p",{className:"text-[11px] text-red-400",children:[x," station",x>1?"s":""," past SLA"]}):u>0?e.jsxs("p",{className:"text-[11px] text-amber-400",children:[u," station",u>1?"s":""," with backlog"]}):d>0?e.jsx("p",{className:"text-[11px] text-emerald-500",children:"Flowing — queue clear"}):e.jsx("p",{className:"text-[11px] text-text-quaternary",children:"Quiet — awaiting work"})}),e.jsxs("div",{className:"space-y-1.5 mb-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-[9px] text-text-quaternary uppercase tracking-wider",children:"Pending"}),e.jsx("span",{className:`text-xs font-mono tabular-nums ${c>0?"text-text-primary font-semibold":"text-text-quaternary"}`,children:c})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-[9px] text-text-quaternary uppercase tracking-wider",children:["Resolved · ",o]}),e.jsx("span",{className:"text-xs font-mono tabular-nums text-text-secondary",children:d})]}),p>0&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-[9px] text-text-quaternary uppercase tracking-wider",children:"Past SLA"}),e.jsx("span",{className:"text-xs font-mono tabular-nums text-red-500 font-semibold",children:p})]})]}),e.jsx("div",{className:"border-t border-surface-border/40 pt-2 mb-1",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-[8px] text-text-quaternary uppercase tracking-wider flex-1",children:"Station"}),e.jsx("span",{className:"text-[8px] text-text-quaternary uppercase tracking-wider w-8 text-right shrink-0",children:"pend"}),e.jsx("span",{className:"text-[8px] text-text-quaternary uppercase tracking-wider w-8 text-right shrink-0",children:"actv"}),e.jsx("span",{className:"text-[8px] text-text-quaternary uppercase tracking-wider w-8 text-right shrink-0",children:"res"})]})}),e.jsx("div",{className:"space-y-0.5",children:n.map(l=>{const i=a.get(l.role),$=(i==null?void 0:i.pending)??0,M=(i==null?void 0:i.claimed)??0,f=(i==null?void 0:i.resolved)??0,h=(i==null?void 0:i.in_arrears)??0,N=l.title||l.role,w=h>0,_=$>0;return e.jsxs("div",{className:"flex items-center gap-2 py-0.5",children:[e.jsxs("span",{className:`text-[10px] font-mono flex-1 truncate ${w?"text-red-400":_?"text-text-primary":"text-text-quaternary"}`,children:[N,w&&e.jsx("span",{className:"ml-1 text-[8px] text-red-400 font-semibold",children:"SLA"})]}),e.jsx("span",{className:`text-[10px] font-mono tabular-nums w-8 text-right shrink-0 ${w?"text-red-400":_?"text-text-primary font-semibold":"text-text-quaternary"}`,children:$>0?$:"—"}),e.jsx("span",{className:`text-[10px] font-mono tabular-nums w-8 text-right shrink-0 ${M>0?"text-accent":"text-text-quaternary"}`,children:M>0?M:"—"}),e.jsx("span",{className:`text-[10px] font-mono tabular-nums w-8 text-right shrink-0 ${f>0?"text-text-secondary":"text-text-quaternary"}`,children:f>0?f:"—"})]},l.role)})}),e.jsx("p",{className:"text-[9px] text-text-quaternary mt-5",children:"Select a station for queue detail."})]})}function Be({role:t,allMetrics:n,orderedRoles:o,globalPeriod:c,onClose:d}){return e.jsx("div",{className:"w-[280px] shrink-0 px-6 py-8 flex flex-col overflow-y-auto min-h-0",children:t?e.jsx(Te,{role:t,globalPeriod:c,onClose:d}):e.jsx(ze,{allMetrics:n,orderedRoles:o,period:c})})}const ge=`${D}14`,je=`${q}14`,be=`${I}14`,He=["15m","1h","24h","7d","30d"],Ve={"15m":.25,"1h":1,"24h":24,"7d":168,"30d":720};function Ye(t){const n=t.filter(a=>a.ops_visible),o=new Map(n.map(a=>[a.role,a])),c=new Set,p=n.filter(a=>!a.parent_role||!o.has(a.parent_role)).map(a=>{const x=[],u=[{role:a,depth:0}];for(;u.length>0;){const l=u.shift();c.has(l.role.role)||(c.add(l.role.role),x.push(l),n.filter(i=>i.parent_role===l.role.role&&!c.has(i.role)).forEach(i=>u.push({role:i,depth:l.depth+1})))}return{origin:a,stations:x}});return n.filter(a=>!c.has(a.role)).forEach(a=>p.push({origin:a,stations:[{role:a,depth:0}]})),p.sort((a,x)=>x.stations.length-a.stations.length||a.origin.role.localeCompare(x.origin.role))}function pe(t){if(t==null)return"—";if(t<1){const n=Math.round(t*60);return n<=0?"< 1s":`${n}s`}return t<60?`${t.toFixed(0)}m`:`${(t/60).toFixed(1)}h`}function Ge(t,n,o,c){if(!n)return{pct:null,color:"bg-surface-border",historical:!1};if(t>0){const x=t/n,u=Math.round(x*100),l=x>1?"bg-amber-400":x<.2?"bg-orange-400":"bg-emerald-400";return{pct:u,color:l,historical:!1}}if(c===0||o==null)return{pct:null,color:"bg-surface-border",historical:!0};const d=o/100,p=Math.round(o),a=d>1?"bg-amber-400":"bg-surface-border";return{pct:p,color:a,historical:!0}}function Ue({role:t,metric:n,selected:o,onClick:c}){var f;const d=(n==null?void 0:n.pending)??0,p=(n==null?void 0:n.claimed)??0,a=(n==null?void 0:n.resolved)??0,x=(n==null?void 0:n.in_arrears)??0,u=t.target_per_hour??null,{pct:l,color:i,historical:$}=Ge(d,u,(n==null?void 0:n.throughput_pct)??null,a),M=l!=null?Math.min(100,l):0;return e.jsxs(e.Fragment,{children:[e.jsxs("div",{role:"button",tabIndex:0,onClick:c,onKeyDown:h=>{h.key==="Enter"&&c()},className:`grid items-center gap-4 cursor-pointer transition-colors ${o?"border-l-2 border-accent":"pl-0.5"}`,style:{gridTemplateColumns:"1fr 64px 56px 56px 60px 72px 72px 104px"},children:[e.jsxs("div",{className:"flex items-center gap-1.5 min-w-0 py-3.5",children:[e.jsx("span",{className:"font-mono font-bold text-text-primary truncate text-[11px]",children:t.role}),t.title&&e.jsx("span",{className:"text-[10px] text-text-tertiary truncate",children:t.title}),(((f=t.upstream_roles)==null?void 0:f.length)??0)>0&&e.jsx("span",{title:`Fed by ${t.upstream_roles.join(", ")}`,className:"shrink-0 leading-none",children:e.jsx(Me,{className:"w-3 h-3 text-text-quaternary"})})]}),e.jsx("span",{className:`text-xs font-mono tabular-nums text-right py-3.5 ${u!=null?"text-text-secondary":"text-text-quaternary"}`,children:u??"—"}),e.jsx("div",{className:"self-stretch flex items-center justify-end px-1.5",style:{backgroundColor:ge},children:e.jsx("span",{className:`text-xs font-mono tabular-nums ${d>0?"text-text-primary font-semibold":"text-text-quaternary"}`,children:d})}),e.jsx("div",{className:"self-stretch flex items-center justify-end px-1.5",style:{backgroundColor:je},children:e.jsx("span",{className:`text-xs font-mono tabular-nums ${p>0?"text-accent font-semibold":"text-text-quaternary"}`,children:p})}),e.jsx("div",{className:"self-stretch flex items-center justify-end px-1.5",style:{backgroundColor:be},children:e.jsx("span",{className:"text-xs font-mono tabular-nums text-text-quaternary",children:a})}),e.jsx("span",{className:"text-xs font-mono tabular-nums text-right py-3.5 text-text-secondary",children:pe((n==null?void 0:n.wait.p99)??null)}),e.jsx("span",{className:"text-xs font-mono tabular-nums text-right py-3.5 text-text-secondary",children:pe((n==null?void 0:n.work.p99)??null)}),e.jsxs("div",{className:"flex items-center gap-2 py-3.5",children:[e.jsx("div",{className:"w-12 h-1.5 bg-surface-sunken rounded-full overflow-hidden shrink-0",children:e.jsx("div",{className:`h-full rounded-full ${i}`,style:{width:`${M}%`}})}),e.jsx("span",{className:`text-[10px] font-mono tabular-nums ${l!=null&&l>100?"text-amber-500 font-semibold":"text-text-quaternary"}`,title:$?"Throughput efficiency for the selected period":void 0,children:l!=null?`${l}%${$?"↩":""}`:"—"})]})]}),x>0&&e.jsxs("div",{className:"flex items-center gap-1.5 pb-2 pl-1",children:[e.jsx(_e,{className:"w-3 h-3 text-red-400 shrink-0"}),e.jsxs(T,{to:`/escalations/available?role=${encodeURIComponent(t.role)}&sort_by=created_at&order=asc`,className:"text-[10px] text-red-400 hover:text-red-500 hover:underline",onClick:h=>h.stopPropagation(),children:[x," past SLA — view oldest first →"]})]})]})}function Qe(){const t=[{label:"ROLE"},{label:"TARGET/H"},{label:"PENDING",band:ge,hue:D},{label:"ACTIVE",band:je,hue:q},{label:"RESOLVED",band:be,hue:I},{label:"P99 WAIT"},{label:"P99 WORK"},{label:"TREND"}];return e.jsx("div",{className:"grid items-center gap-4 border-b border-surface-border mb-0.5",style:{gridTemplateColumns:"1fr 64px 56px 56px 60px 72px 72px 104px"},children:t.map((n,o)=>n.band?e.jsx("div",{className:"self-stretch flex items-center justify-end px-1.5",style:{backgroundColor:n.band},children:e.jsx("span",{className:"text-[9px] font-semibold uppercase tracking-wider",style:{color:n.hue},children:n.label})},n.label):e.jsx("span",{className:`text-[9px] font-semibold uppercase tracking-wider text-text-quaternary py-1.5 ${o>0&&o<7?"text-right":""}`,children:n.label},n.label))})}function nt(){var V;const[t,n]=k.useState("24h"),[o,c]=k.useState(null),[d,p]=k.useState(!1);ke();const{data:a,isLoading:x,refetch:u}=Ne(),{data:l,isLoading:i,refetch:$}=ue(t),M=(a==null?void 0:a.roles)??[],f=(l==null?void 0:l.stations)??[],h=k.useMemo(()=>Ye(M),[M]),[N,w]=Le(),_=N.get("fragment"),j=h.find(r=>r.origin.role===_)??h[0]??null,P=k.useCallback(r=>{c(null),w(y=>{const E=new URLSearchParams(y);return E.set("fragment",r),E})},[w]),S=(j==null?void 0:j.stations)??[],A=k.useMemo(()=>new Set(S.map(({role:r})=>r.role)),[S]),z=k.useMemo(()=>f.filter(r=>A.has(r.role)),[f,A]),Q=k.useMemo(()=>S.map(({role:r})=>({role:r.role,title:r.title,parent_role:r.parent_role,target_per_hour:r.target_per_hour??null,upstream_roles:r.upstream_roles??[],metric:f.find(y=>y.role===r.role)})),[S,f]),C=k.useCallback(r=>{const y=h.find(E=>E.stations.some(({role:ne})=>ne.role===r));y&&P(y.origin.role)},[h,P]),K=((V=S.find(({role:r})=>r.role===o))==null?void 0:V.role)??null,F=x||i,Z=async()=>{p(!0),await Promise.all([u(),$()]),p(!1)},B=r=>c(y=>y===r?null:r),H=e.jsx("div",{className:"flex items-center gap-0.5",children:He.map(r=>e.jsx("button",{onClick:()=>n(r),className:`px-2.5 py-1 text-[10px] font-mono rounded transition-colors ${t===r?"bg-accent/10 text-accent font-semibold":"text-text-quaternary hover:text-text-secondary"}`,children:r},r))});return e.jsxs("div",{className:"flex flex-col flex-1 min-h-0",children:[e.jsx($e,{title:"Pace Board",docsHash:"#docs:dashboard.md:operations",center:H,actions:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("button",{onClick:Z,disabled:d,className:"text-text-quaternary hover:text-text-secondary transition-colors disabled:opacity-40",children:e.jsx(Se,{className:`w-3.5 h-3.5 ${d?"animate-spin":""}`})}),e.jsx(T,{to:"/admin/roles",className:"btn-secondary text-xs",children:"Configure"})]})}),F?e.jsxs("div",{className:"animate-pulse space-y-6 mt-4",children:[e.jsx("div",{className:"h-8 bg-surface-sunken rounded w-64"}),e.jsx("div",{className:"h-64 bg-surface-sunken rounded w-full"}),e.jsx("div",{className:"space-y-3",children:[1,2,3].map(r=>e.jsx("div",{className:"h-8 bg-surface-sunken rounded w-full"},r))})]}):h.length===0?e.jsxs("div",{className:"mt-8",children:[e.jsx("p",{className:"text-sm text-text-secondary mb-2",children:"Stations appear here once roles are marked visible in Operations."}),e.jsxs("p",{className:"text-xs text-text-tertiary",children:["Go to"," ",e.jsx(T,{to:"/admin/roles",className:"text-accent hover:underline",children:"Roles"})," ","and enable ",e.jsx("strong",{children:"Visible in Operations"})," on roles that represent pipeline stations."]})]}):e.jsxs("div",{className:"flex flex-col flex-1 min-h-0",children:[h.length>1&&e.jsx("div",{className:"flex items-center gap-0.5 px-4 pt-2",children:h.map(r=>{const y=r.origin.role===(j==null?void 0:j.origin.role);return e.jsxs("button",{onClick:()=>P(r.origin.role),className:`px-2.5 py-1 text-[10px] font-mono rounded transition-colors ${y?"bg-accent/10 text-accent font-semibold":"text-text-quaternary hover:text-text-secondary"}`,children:[r.origin.title??r.origin.role,e.jsx("span",{className:`ml-1.5 tabular-nums ${y?"text-accent/60":"text-text-quaternary/60"}`,children:r.stations.length})]},r.origin.role)})}),e.jsxs("div",{className:"flex-1 min-h-0 flex items-stretch overflow-hidden",children:[e.jsx("div",{className:"flex-1 min-w-0 min-h-0 flex flex-col justify-center overflow-hidden p-4",children:e.jsx(Oe,{stations:Q,selectedRole:o,onSelect:B,onUpstreamSelect:C,periodHours:Ve[t]})}),e.jsx("div",{className:"w-px bg-surface-border shrink-0 self-stretch"}),e.jsx(Be,{role:K,allMetrics:z,orderedRoles:S.map(r=>r.role),globalPeriod:t,onClose:()=>c(null)})]}),e.jsxs("div",{className:"h-[30vh] flex-none flex flex-col border-t border-surface-border overflow-hidden",children:[e.jsx(Qe,{}),e.jsx("div",{className:"flex-1 min-h-0 overflow-y-auto divide-y divide-surface-border/30",children:S.map(({role:r})=>e.jsx(Ue,{role:r,metric:f.find(y=>y.role===r.role),selected:o===r.role,onClick:()=>B(r.role)},r.role))})]})]})]})}export{nt as OperationsPage};
|
|
2
|
-
//# sourceMappingURL=OperationsPage-
|
|
1
|
+
import{a as k,j as e}from"./vendor-query-B2UbickB.js";import{b as Ne}from"./roles-CFD2eYap.js";import{K as ue}from"./index-Dgw1KKpq.js";import{i as ke}from"./useEventHooks-DcIgMDh3.js";import{P as $e}from"./PageHeader-BhaWTWcM.js";import{X as we,ae,au as Se,as as Me,av as _e}from"./vendor-icons-CEWCGPeJ.js";import{L as T,f as Le}from"./vendor-react-CXumBFUA.js";const he=800,me=270,O=40,Pe=76,re=24,Re=72,se=he-O-Pe,fe=me-re-Re,v=re+fe,de=O+se,b="0.5s cubic-bezier(0.4, 0, 0.2, 1)";function qe(t){return t.length===0?"":t.map((n,o)=>`${o===0?"M":"L"} ${n.x.toFixed(1)} ${n.y.toFixed(1)}`).join(" ")}function U(t){if(t.length===0)return"";if(t.length===1)return`M ${t[0].x} ${t[0].y}`;const n=[];for(let o=0;o<t.length-1;o++){const c=t[Math.max(0,o-1)],d=t[o],p=t[o+1],a=t[Math.min(t.length-1,o+2)],x=(d.x+(p.x-c.x)/6).toFixed(1),u=(d.y+(p.y-c.y)/6).toFixed(1),l=(p.x-(a.x-d.x)/6).toFixed(1),i=(p.y-(a.y-d.y)/6).toFixed(1);o===0&&n.push(`M ${d.x.toFixed(1)} ${d.y.toFixed(1)}`),n.push(`C ${x} ${u}, ${l} ${i}, ${p.x.toFixed(1)} ${p.y.toFixed(1)}`)}return n.join(" ")}function Ae(t,n){if(t.length<2||n.length<2)return"";const o=U(t),c=[...n].reverse(),d=U(c),p=d.slice(d.indexOf("C"));return`${o} L ${c[0].x.toFixed(1)} ${c[0].y.toFixed(1)} ${p} Z`}function Ce(t){return t>=1e4?`${Math.round(t/1e3)}k`:t>=1e3?`${(t/1e3).toFixed(1)}k`:String(t)}function J(t){return t.length>0?t[t.length-1]:void 0}function Fe(t){return t==null?{stroke:"#cbd5e1",fill:"#f8fafc"}:t>=1?{stroke:"#10b981",fill:"#ecfdf5"}:t>=.6?{stroke:"#f59e0b",fill:"#fffbeb"}:{stroke:"#ef4444",fill:"#fef2f2"}}const q="#6366f1",D="#0ea5e9",I="#4e6a5e",Ee=13;function We(t,n){const o=[...t].sort((a,x)=>a.y-x.y);let c=-1/0;const d=o.map(a=>{const x=Math.max(a.y+3,c+Ee);return c=x,{...a,labelY:x}}),p=d.length>0?d[d.length-1].labelY-n:0;if(p>0)for(const a of d)a.labelY-=p;return d}function Oe({stations:t,selectedRole:n,onSelect:o,onUpstreamSelect:c,periodHours:d}){const[p,a]=k.useState(null),x=t.length;if(x===0)return null;const u=s=>x===1?O+se/2:O+s/(x-1)*se,l=new Map(t.map((s,m)=>[s.role,u(m)])),i=t.map((s,m)=>{var W,Y,L,G;const g=s.target_per_hour??null,R=g!=null?g*d:null;return{idx:m,x:u(m),expected:R,actual:((W=s.metric)==null?void 0:W.resolved)??0,active:((Y=s.metric)==null?void 0:Y.claimed)??0,pending:((L=s.metric)==null?void 0:L.pending)??0,inArrears:((G=s.metric)==null?void 0:G.in_arrears)??0}}),$=i.some(s=>s.expected!=null),f=Math.max(1,...i.map(s=>s.expected??0),...i.map(s=>s.actual),...i.map(s=>s.expected!=null?s.pending:0))*1.15,h=s=>re+fe*(1-Math.max(0,Math.min(s,f))/f),N=i.filter(s=>s.expected!=null),w=N.map(s=>({...s,y:h(s.expected)})),_=N.map(s=>({...s,y:h(s.actual)})),j=N.map(s=>({...s,y:h(s.active)})),P=N.map(s=>({...s,y:h(s.pending)})),S=qe(w),A=U(_),z=U(j),Q=U(P),C=J(_),K=J(w),F=J(j),Z=J(P),B=_.length>=2&&C?`${A} L ${C.x.toFixed(1)} ${v} L ${_[0].x.toFixed(1)} ${v} Z`:"",H=N.some(s=>s.pending>0||s.active>0),V=H&&j.length>=2&&F?`${z} L ${F.x.toFixed(1)} ${v} L ${j[0].x.toFixed(1)} ${v} Z`:"",r=H?Ae(P,j):"",y=N.some(s=>s.active>0),E=N.some(s=>s.pending>s.active),ne=We([K?{key:"target",text:"target",color:"#ef4444",y:K.y}:null,C?{key:"actual",text:"actual",color:I,y:C.y}:null,y&&F?{key:"active",text:"active",color:q,y:F.y}:null,E&&Z?{key:"queued",text:"queued",color:D,y:Z.y}:null].filter(Boolean),v+4);return e.jsxs("svg",{viewBox:`0 0 ${he} ${me}`,className:"w-full h-full",preserveAspectRatio:"xMidYMid meet",style:{display:"block"},children:[t.map(s=>{if(!s.parent_role)return null;const m=l.get(s.parent_role);if(m==null)return null;const g=u(t.findIndex(R=>R.role===s.role));return e.jsx("line",{x1:m,y1:v,x2:g,y2:v,stroke:"#e2e8f0",strokeWidth:.75},`dep-${s.role}`)}),B&&e.jsx("path",{d:B,fill:I,opacity:.05,style:{transition:`d ${b}`}}),V&&e.jsx("path",{d:V,fill:q,opacity:.12,style:{transition:`d ${b}`}}),r&&e.jsx("path",{d:r,fill:D,opacity:.12,style:{transition:`d ${b}`}}),S&&e.jsx("path",{d:S,fill:"none",stroke:"#ef4444",strokeWidth:.5,strokeLinejoin:"round",opacity:.9,style:{transition:`d ${b}`}}),w.map(s=>e.jsx("text",{x:s.x,y:s.y-3.5,textAnchor:"middle",fontSize:6.5,fill:"#ef4444",fontFamily:"ui-monospace, monospace",fontWeight:"500",opacity:.7,style:{transition:`y ${b}`},children:Math.round(s.expected)},`tval-${s.idx}`)),H&&Q&&e.jsx("path",{d:Q,fill:"none",stroke:D,strokeWidth:.75,strokeDasharray:"2 3",strokeLinecap:"round",opacity:.55,style:{transition:`d ${b}`}}),z&&e.jsx("path",{d:z,fill:"none",stroke:q,strokeWidth:.75,strokeDasharray:"2 3",strokeLinecap:"round",opacity:.5,style:{transition:`d ${b}`}}),A&&e.jsx("path",{d:A,fill:"none",stroke:I,strokeWidth:1,strokeLinejoin:"round",strokeLinecap:"round",opacity:.75,style:{transition:`d ${b}`}}),j.map((s,m)=>{if(s.pending<=0&&s.active<=0)return null;const g=Math.max(2.5,Math.min(5,2.5+s.active/10)),R=s.pending>s.active,W=Math.min(P[m].y-4,s.y-g-4);return e.jsxs("g",{children:[s.pending>0&&e.jsx("text",{x:s.x,y:W,textAnchor:"middle",fontSize:7.5,fill:R?D:"#64748b",fontFamily:"ui-monospace, monospace",fontWeight:"600",style:{transition:`y ${b}`},children:s.pending}),e.jsxs("g",{transform:`translate(${s.x} ${s.y})`,style:{transition:`transform ${b}`},children:[e.jsx("circle",{r:g,fill:q,opacity:.85}),s.active>0&&e.jsx("text",{y:g+9,textAnchor:"middle",fontSize:7.5,fill:q,fontFamily:"ui-monospace, monospace",fontWeight:"600",children:s.active})]})]},`active-${s.idx}`)}),i.map(s=>{var xe;const m=t[s.idx],g=s.x,R=s.expected!=null?h(s.actual):v,W=s.expected&&s.expected>0?s.actual/s.expected:null,{stroke:Y}=Fe(s.expected!=null?W:null),L=Math.max(3,Math.min(5.5,3+s.actual/120)),G=m.role===n,le=p===s.idx,oe=s.expected==null?"idle · set a target rate to plot pace":`${s.actual} done · target ${Math.round(s.expected)}`+(s.pending>s.active?` · ${s.pending-s.active} waiting`:"")+(s.active>0?` · ${s.active} active`:""),X=oe.length*5.5+20,ie=Math.max(O+X/2+4,Math.min(de-X/2-4,g)),ce=R-L-10;return e.jsxs("g",{onClick:()=>o(m.role),onMouseEnter:()=>a(s.idx),onMouseLeave:()=>a(null),style:{cursor:"pointer"},children:[e.jsxs("g",{transform:`translate(${g} ${R})`,style:{transition:`transform ${b}`},children:[e.jsx("circle",{r:22,fill:"transparent"}),s.inArrears>0&&e.jsx("circle",{r:L+4,fill:"none",stroke:"#ef4444",strokeWidth:1,strokeDasharray:"3 2",opacity:.6}),e.jsx("circle",{r:L,fill:Y,opacity:.9,style:{transition:`r ${b}`}}),s.expected!=null&&e.jsx("text",{y:-L-5,textAnchor:"middle",fontSize:9.5,fill:I,fontFamily:"ui-monospace, monospace",fontWeight:"500",children:Ce(s.actual)}),le&&!G&&e.jsx("circle",{r:L+3,fill:"none",stroke:Y,strokeWidth:1,opacity:.4}),G&&e.jsx("circle",{r:L+4,fill:"none",stroke:"#6366f1",strokeWidth:2})]}),(((xe=m.upstream_roles)==null?void 0:xe.length)??0)>0&&e.jsxs("g",{transform:`translate(${g-20} ${v})`,onClick:ve=>{ve.stopPropagation(),c==null||c(m.upstream_roles[0])},style:{cursor:"pointer"},children:[e.jsx("title",{children:`Fed by ${m.upstream_roles.join(", ")} — click to view that sequence`}),e.jsx("circle",{r:9,cy:-6,fill:"transparent"}),e.jsx("path",{d:"M -7 -14 C -3 -14 -1 -9 0 -2",fill:"none",stroke:"#94a3b8",strokeWidth:1,strokeDasharray:"2 2",strokeLinecap:"round"}),e.jsx("path",{d:"M 0 -2 L 8 -2",stroke:"#94a3b8",strokeWidth:1,strokeLinecap:"round"}),e.jsx("path",{d:"M 8 -2 l -3.5 -2 v 4 z",fill:"#94a3b8"})]}),e.jsx("text",{x:g,y:v+14,textAnchor:"middle",fontSize:9.5,fill:"#475569",fontFamily:"ui-sans-serif, sans-serif",fontWeight:"500",children:m.title??m.role}),e.jsx("text",{x:g,y:v+26,textAnchor:"middle",fontSize:8,fill:"#94a3b8",fontFamily:"ui-monospace, monospace",children:m.role}),le&&e.jsxs("g",{children:[e.jsx("rect",{x:ie-X/2,y:ce-16,width:X,height:19,rx:3,fill:"#0f172a",opacity:.88}),e.jsx("text",{x:ie,y:ce-3,textAnchor:"middle",fontSize:8.5,fill:"white",fontFamily:"ui-monospace, monospace",children:oe})]})]},m.role)}),!$&&e.jsx("text",{x:O+se/2,y:v+48,textAnchor:"middle",fontSize:8.5,fill:"#94a3b8",fontFamily:"ui-sans-serif, sans-serif",children:"Set target_per_hour on each role in Admin → Roles to enable the pace chart"}),ne.map(s=>e.jsx("text",{x:de+6,y:s.labelY,fontSize:8,fill:s.color,fontFamily:"ui-sans-serif, sans-serif",fontWeight:s.key==="actual"?700:500,opacity:s.key==="active"?.85:1,style:{transition:`y ${b}`},children:s.text},s.key))]})}const ye=["15m","1h","24h","7d","30d"],De=t=>ye.includes(t);function ee(t){if(t==null)return"—";if(t<1){const n=Math.round(t*60);return n<=0?"< 1s":`${n}s`}return t<60?`${t.toFixed(0)}m`:`${(t/60).toFixed(1)}h`}function te({label:t,value:n}){return e.jsxs("div",{className:"flex items-center justify-between py-1",children:[e.jsx("span",{className:"text-[10px] text-text-tertiary uppercase tracking-wider",children:t}),e.jsx("span",{className:"text-xs font-mono font-medium text-text-primary tabular-nums",children:n})]})}function Ie({period:t,onChange:n}){return e.jsx("div",{className:"flex items-center gap-1 mb-4",children:ye.map(o=>e.jsx("button",{onClick:()=>n(o),className:`px-2 py-0.5 text-[10px] font-mono rounded transition-colors ${t===o?"bg-accent/10 text-accent font-semibold":"text-text-quaternary hover:text-text-secondary"}`,children:o},o))})}function Te({role:t,globalPeriod:n,onClose:o}){const[c,d]=k.useState(De(n)?n:"24h"),{data:p}=ue(c),a=p==null?void 0:p.stations.find(i=>i.role===t.role),x=t.sla_minutes??void 0,u=t.target_per_hour??void 0,l=t.worker_count??void 0;return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-start justify-between mb-1",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-baseline gap-1.5 flex-wrap",children:[e.jsx("span",{className:"text-sm font-mono font-bold text-text-primary",children:t.role}),t.title&&e.jsx("span",{className:"text-[10px] text-text-secondary",children:t.title})]}),t.description&&e.jsx("p",{className:"text-[10px] text-text-tertiary mt-0.5 line-clamp-2 leading-relaxed",children:t.description})]}),e.jsx("button",{onClick:o,className:"text-text-quaternary hover:text-text-secondary transition-colors mt-0.5 shrink-0 ml-2",children:e.jsx(we,{className:"w-4 h-4"})})]}),e.jsxs(T,{to:`/admin/roles/${encodeURIComponent(t.role)}`,className:"flex items-center gap-1 text-[10px] text-accent hover:underline mb-4",children:[e.jsx(ae,{className:"w-2.5 h-2.5"}),"Edit in Roles"]}),e.jsx(Ie,{period:c,onChange:d}),(u||x||l)&&e.jsxs("div",{className:"flex items-center gap-4 mb-4 text-[10px]",children:[u&&e.jsxs("div",{children:[e.jsxs("div",{className:"font-mono font-semibold text-text-primary",children:[u,"/h"]}),e.jsx("div",{className:"text-text-quaternary uppercase tracking-wider text-[8.5px]",children:"target"})]}),x&&e.jsxs("div",{children:[e.jsxs("div",{className:"font-mono font-semibold text-text-primary",children:[x,"m"]}),e.jsx("div",{className:"text-text-quaternary uppercase tracking-wider text-[8.5px]",children:"SLA"})]}),l&&e.jsxs("div",{children:[e.jsx("div",{className:"font-mono font-semibold text-text-primary",children:l}),e.jsx("div",{className:"text-text-quaternary uppercase tracking-wider text-[8.5px]",children:"workers"})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-x-3",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-[9px] text-text-quaternary uppercase tracking-wider mb-1.5",children:"Wait (queue)"}),e.jsx(te,{label:"P99",value:ee((a==null?void 0:a.wait.p99)??null)}),e.jsx(te,{label:"avg",value:ee((a==null?void 0:a.wait.avg)??null)})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[9px] text-text-quaternary uppercase tracking-wider mb-1.5",children:"Work (proc.)"}),e.jsx(te,{label:"P99",value:ee((a==null?void 0:a.work.p99)??null)}),e.jsx(te,{label:"avg",value:ee((a==null?void 0:a.work.avg)??null)})]})]}),e.jsxs("div",{className:"border-t border-surface-border/40 pt-2 mt-3 space-y-1.5",children:[x&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-[10px] text-text-tertiary",children:"SLA target"}),e.jsxs("span",{className:"text-xs font-mono text-text-secondary",children:[x,"m"]})]}),a&&a.in_arrears>0&&e.jsxs(T,{to:`/escalations/available?role=${encodeURIComponent(a.role)}&sort_by=created_at&order=asc`,className:"flex items-center justify-between group",children:[e.jsxs("span",{className:"text-[10px] text-red-500",children:[a.in_arrears," past SLA"]}),e.jsx(ae,{className:"w-3 h-3 text-red-400 group-hover:text-red-500 transition-colors"})]})]}),e.jsx("div",{className:"mt-4 border-t border-surface-border/40 pt-3",children:e.jsxs(T,{to:`/escalations/available?role=${encodeURIComponent(t.role)}`,className:"flex items-center gap-1.5 text-[10px] text-accent hover:underline",children:["View full queue",e.jsx(ae,{className:"w-2.5 h-2.5"})]})})]})}function ze({allMetrics:t,orderedRoles:n,period:o}){const c=t.reduce((l,i)=>l+i.pending,0),d=t.reduce((l,i)=>l+i.resolved,0),p=t.reduce((l,i)=>l+i.in_arrears,0),a=new Map(t.map(l=>[l.role,l])),x=t.filter(l=>l.in_arrears>0).length,u=t.filter(l=>l.pending>0).length;return e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"text-[9px] text-text-quaternary uppercase tracking-wider mb-3",children:["Pipeline · ",o]}),e.jsx("div",{className:"mb-4",children:x>0?e.jsxs("p",{className:"text-[11px] text-red-400",children:[x," station",x>1?"s":""," past SLA"]}):u>0?e.jsxs("p",{className:"text-[11px] text-amber-400",children:[u," station",u>1?"s":""," with backlog"]}):d>0?e.jsx("p",{className:"text-[11px] text-emerald-500",children:"Flowing — queue clear"}):e.jsx("p",{className:"text-[11px] text-text-quaternary",children:"Quiet — awaiting work"})}),e.jsxs("div",{className:"space-y-1.5 mb-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-[9px] text-text-quaternary uppercase tracking-wider",children:"Pending"}),e.jsx("span",{className:`text-xs font-mono tabular-nums ${c>0?"text-text-primary font-semibold":"text-text-quaternary"}`,children:c})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-[9px] text-text-quaternary uppercase tracking-wider",children:["Resolved · ",o]}),e.jsx("span",{className:"text-xs font-mono tabular-nums text-text-secondary",children:d})]}),p>0&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-[9px] text-text-quaternary uppercase tracking-wider",children:"Past SLA"}),e.jsx("span",{className:"text-xs font-mono tabular-nums text-red-500 font-semibold",children:p})]})]}),e.jsx("div",{className:"border-t border-surface-border/40 pt-2 mb-1",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-[8px] text-text-quaternary uppercase tracking-wider flex-1",children:"Station"}),e.jsx("span",{className:"text-[8px] text-text-quaternary uppercase tracking-wider w-8 text-right shrink-0",children:"pend"}),e.jsx("span",{className:"text-[8px] text-text-quaternary uppercase tracking-wider w-8 text-right shrink-0",children:"actv"}),e.jsx("span",{className:"text-[8px] text-text-quaternary uppercase tracking-wider w-8 text-right shrink-0",children:"res"})]})}),e.jsx("div",{className:"space-y-0.5",children:n.map(l=>{const i=a.get(l.role),$=(i==null?void 0:i.pending)??0,M=(i==null?void 0:i.claimed)??0,f=(i==null?void 0:i.resolved)??0,h=(i==null?void 0:i.in_arrears)??0,N=l.title||l.role,w=h>0,_=$>0;return e.jsxs("div",{className:"flex items-center gap-2 py-0.5",children:[e.jsxs("span",{className:`text-[10px] font-mono flex-1 truncate ${w?"text-red-400":_?"text-text-primary":"text-text-quaternary"}`,children:[N,w&&e.jsx("span",{className:"ml-1 text-[8px] text-red-400 font-semibold",children:"SLA"})]}),e.jsx("span",{className:`text-[10px] font-mono tabular-nums w-8 text-right shrink-0 ${w?"text-red-400":_?"text-text-primary font-semibold":"text-text-quaternary"}`,children:$>0?$:"—"}),e.jsx("span",{className:`text-[10px] font-mono tabular-nums w-8 text-right shrink-0 ${M>0?"text-accent":"text-text-quaternary"}`,children:M>0?M:"—"}),e.jsx("span",{className:`text-[10px] font-mono tabular-nums w-8 text-right shrink-0 ${f>0?"text-text-secondary":"text-text-quaternary"}`,children:f>0?f:"—"})]},l.role)})}),e.jsx("p",{className:"text-[9px] text-text-quaternary mt-5",children:"Select a station for queue detail."})]})}function Be({role:t,allMetrics:n,orderedRoles:o,globalPeriod:c,onClose:d}){return e.jsx("div",{className:"w-[280px] shrink-0 px-6 py-8 flex flex-col overflow-y-auto min-h-0",children:t?e.jsx(Te,{role:t,globalPeriod:c,onClose:d}):e.jsx(ze,{allMetrics:n,orderedRoles:o,period:c})})}const ge=`${D}14`,je=`${q}14`,be=`${I}14`,He=["15m","1h","24h","7d","30d"],Ve={"15m":.25,"1h":1,"24h":24,"7d":168,"30d":720};function Ye(t){const n=t.filter(a=>a.ops_visible),o=new Map(n.map(a=>[a.role,a])),c=new Set,p=n.filter(a=>!a.parent_role||!o.has(a.parent_role)).map(a=>{const x=[],u=[{role:a,depth:0}];for(;u.length>0;){const l=u.shift();c.has(l.role.role)||(c.add(l.role.role),x.push(l),n.filter(i=>i.parent_role===l.role.role&&!c.has(i.role)).forEach(i=>u.push({role:i,depth:l.depth+1})))}return{origin:a,stations:x}});return n.filter(a=>!c.has(a.role)).forEach(a=>p.push({origin:a,stations:[{role:a,depth:0}]})),p.sort((a,x)=>x.stations.length-a.stations.length||a.origin.role.localeCompare(x.origin.role))}function pe(t){if(t==null)return"—";if(t<1){const n=Math.round(t*60);return n<=0?"< 1s":`${n}s`}return t<60?`${t.toFixed(0)}m`:`${(t/60).toFixed(1)}h`}function Ge(t,n,o,c){if(!n)return{pct:null,color:"bg-surface-border",historical:!1};if(t>0){const x=t/n,u=Math.round(x*100),l=x>1?"bg-amber-400":x<.2?"bg-orange-400":"bg-emerald-400";return{pct:u,color:l,historical:!1}}if(c===0||o==null)return{pct:null,color:"bg-surface-border",historical:!0};const d=o/100,p=Math.round(o),a=d>1?"bg-amber-400":"bg-surface-border";return{pct:p,color:a,historical:!0}}function Ue({role:t,metric:n,selected:o,onClick:c}){var f;const d=(n==null?void 0:n.pending)??0,p=(n==null?void 0:n.claimed)??0,a=(n==null?void 0:n.resolved)??0,x=(n==null?void 0:n.in_arrears)??0,u=t.target_per_hour??null,{pct:l,color:i,historical:$}=Ge(d,u,(n==null?void 0:n.throughput_pct)??null,a),M=l!=null?Math.min(100,l):0;return e.jsxs(e.Fragment,{children:[e.jsxs("div",{role:"button",tabIndex:0,onClick:c,onKeyDown:h=>{h.key==="Enter"&&c()},className:`grid items-center gap-4 cursor-pointer transition-colors ${o?"border-l-2 border-accent":"pl-0.5"}`,style:{gridTemplateColumns:"1fr 64px 56px 56px 60px 72px 72px 104px"},children:[e.jsxs("div",{className:"flex items-center gap-1.5 min-w-0 py-3.5",children:[e.jsx("span",{className:"font-mono font-bold text-text-primary truncate text-[11px]",children:t.role}),t.title&&e.jsx("span",{className:"text-[10px] text-text-tertiary truncate",children:t.title}),(((f=t.upstream_roles)==null?void 0:f.length)??0)>0&&e.jsx("span",{title:`Fed by ${t.upstream_roles.join(", ")}`,className:"shrink-0 leading-none",children:e.jsx(Me,{className:"w-3 h-3 text-text-quaternary"})})]}),e.jsx("span",{className:`text-xs font-mono tabular-nums text-right py-3.5 ${u!=null?"text-text-secondary":"text-text-quaternary"}`,children:u??"—"}),e.jsx("div",{className:"self-stretch flex items-center justify-end px-1.5",style:{backgroundColor:ge},children:e.jsx("span",{className:`text-xs font-mono tabular-nums ${d>0?"text-text-primary font-semibold":"text-text-quaternary"}`,children:d})}),e.jsx("div",{className:"self-stretch flex items-center justify-end px-1.5",style:{backgroundColor:je},children:e.jsx("span",{className:`text-xs font-mono tabular-nums ${p>0?"text-accent font-semibold":"text-text-quaternary"}`,children:p})}),e.jsx("div",{className:"self-stretch flex items-center justify-end px-1.5",style:{backgroundColor:be},children:e.jsx("span",{className:"text-xs font-mono tabular-nums text-text-quaternary",children:a})}),e.jsx("span",{className:"text-xs font-mono tabular-nums text-right py-3.5 text-text-secondary",children:pe((n==null?void 0:n.wait.p99)??null)}),e.jsx("span",{className:"text-xs font-mono tabular-nums text-right py-3.5 text-text-secondary",children:pe((n==null?void 0:n.work.p99)??null)}),e.jsxs("div",{className:"flex items-center gap-2 py-3.5",children:[e.jsx("div",{className:"w-12 h-1.5 bg-surface-sunken rounded-full overflow-hidden shrink-0",children:e.jsx("div",{className:`h-full rounded-full ${i}`,style:{width:`${M}%`}})}),e.jsx("span",{className:`text-[10px] font-mono tabular-nums ${l!=null&&l>100?"text-amber-500 font-semibold":"text-text-quaternary"}`,title:$?"Throughput efficiency for the selected period":void 0,children:l!=null?`${l}%${$?"↩":""}`:"—"})]})]}),x>0&&e.jsxs("div",{className:"flex items-center gap-1.5 pb-2 pl-1",children:[e.jsx(_e,{className:"w-3 h-3 text-red-400 shrink-0"}),e.jsxs(T,{to:`/escalations/available?role=${encodeURIComponent(t.role)}&sort_by=created_at&order=asc`,className:"text-[10px] text-red-400 hover:text-red-500 hover:underline",onClick:h=>h.stopPropagation(),children:[x," past SLA — view oldest first →"]})]})]})}function Qe(){const t=[{label:"ROLE"},{label:"TARGET/H"},{label:"PENDING",band:ge,hue:D},{label:"ACTIVE",band:je,hue:q},{label:"RESOLVED",band:be,hue:I},{label:"P99 WAIT"},{label:"P99 WORK"},{label:"TREND"}];return e.jsx("div",{className:"grid items-center gap-4 border-b border-surface-border mb-0.5",style:{gridTemplateColumns:"1fr 64px 56px 56px 60px 72px 72px 104px"},children:t.map((n,o)=>n.band?e.jsx("div",{className:"self-stretch flex items-center justify-end px-1.5",style:{backgroundColor:n.band},children:e.jsx("span",{className:"text-[9px] font-semibold uppercase tracking-wider",style:{color:n.hue},children:n.label})},n.label):e.jsx("span",{className:`text-[9px] font-semibold uppercase tracking-wider text-text-quaternary py-1.5 ${o>0&&o<7?"text-right":""}`,children:n.label},n.label))})}function nt(){var V;const[t,n]=k.useState("24h"),[o,c]=k.useState(null),[d,p]=k.useState(!1);ke();const{data:a,isLoading:x,refetch:u}=Ne(),{data:l,isLoading:i,refetch:$}=ue(t),M=(a==null?void 0:a.roles)??[],f=(l==null?void 0:l.stations)??[],h=k.useMemo(()=>Ye(M),[M]),[N,w]=Le(),_=N.get("fragment"),j=h.find(r=>r.origin.role===_)??h[0]??null,P=k.useCallback(r=>{c(null),w(y=>{const E=new URLSearchParams(y);return E.set("fragment",r),E})},[w]),S=(j==null?void 0:j.stations)??[],A=k.useMemo(()=>new Set(S.map(({role:r})=>r.role)),[S]),z=k.useMemo(()=>f.filter(r=>A.has(r.role)),[f,A]),Q=k.useMemo(()=>S.map(({role:r})=>({role:r.role,title:r.title,parent_role:r.parent_role,target_per_hour:r.target_per_hour??null,upstream_roles:r.upstream_roles??[],metric:f.find(y=>y.role===r.role)})),[S,f]),C=k.useCallback(r=>{const y=h.find(E=>E.stations.some(({role:ne})=>ne.role===r));y&&P(y.origin.role)},[h,P]),K=((V=S.find(({role:r})=>r.role===o))==null?void 0:V.role)??null,F=x||i,Z=async()=>{p(!0),await Promise.all([u(),$()]),p(!1)},B=r=>c(y=>y===r?null:r),H=e.jsx("div",{className:"flex items-center gap-0.5",children:He.map(r=>e.jsx("button",{onClick:()=>n(r),className:`px-2.5 py-1 text-[10px] font-mono rounded transition-colors ${t===r?"bg-accent/10 text-accent font-semibold":"text-text-quaternary hover:text-text-secondary"}`,children:r},r))});return e.jsxs("div",{className:"flex flex-col flex-1 min-h-0",children:[e.jsx($e,{title:"Pace Board",docsHash:"#docs:dashboard.md:pace-board",center:H,actions:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("button",{onClick:Z,disabled:d,className:"text-text-quaternary hover:text-text-secondary transition-colors disabled:opacity-40",children:e.jsx(Se,{className:`w-3.5 h-3.5 ${d?"animate-spin":""}`})}),e.jsx(T,{to:"/admin/roles",className:"btn-secondary text-xs",children:"Configure"})]})}),F?e.jsxs("div",{className:"animate-pulse space-y-6 mt-4",children:[e.jsx("div",{className:"h-8 bg-surface-sunken rounded w-64"}),e.jsx("div",{className:"h-64 bg-surface-sunken rounded w-full"}),e.jsx("div",{className:"space-y-3",children:[1,2,3].map(r=>e.jsx("div",{className:"h-8 bg-surface-sunken rounded w-full"},r))})]}):h.length===0?e.jsxs("div",{className:"mt-8",children:[e.jsx("p",{className:"text-sm text-text-secondary mb-2",children:"Stations appear here once roles are marked visible in Operations."}),e.jsxs("p",{className:"text-xs text-text-tertiary",children:["Go to"," ",e.jsx(T,{to:"/admin/roles",className:"text-accent hover:underline",children:"Roles"})," ","and enable ",e.jsx("strong",{children:"Visible in Operations"})," on roles that represent pipeline stations."]})]}):e.jsxs("div",{className:"flex flex-col flex-1 min-h-0",children:[h.length>1&&e.jsx("div",{className:"flex items-center gap-0.5 px-4 pt-2",children:h.map(r=>{const y=r.origin.role===(j==null?void 0:j.origin.role);return e.jsxs("button",{onClick:()=>P(r.origin.role),className:`px-2.5 py-1 text-[10px] font-mono rounded transition-colors ${y?"bg-accent/10 text-accent font-semibold":"text-text-quaternary hover:text-text-secondary"}`,children:[r.origin.title??r.origin.role,e.jsx("span",{className:`ml-1.5 tabular-nums ${y?"text-accent/60":"text-text-quaternary/60"}`,children:r.stations.length})]},r.origin.role)})}),e.jsxs("div",{className:"flex-1 min-h-0 flex items-stretch overflow-hidden",children:[e.jsx("div",{className:"flex-1 min-w-0 min-h-0 flex flex-col justify-center overflow-hidden p-4",children:e.jsx(Oe,{stations:Q,selectedRole:o,onSelect:B,onUpstreamSelect:C,periodHours:Ve[t]})}),e.jsx("div",{className:"w-px bg-surface-border shrink-0 self-stretch"}),e.jsx(Be,{role:K,allMetrics:z,orderedRoles:S.map(r=>r.role),globalPeriod:t,onClose:()=>c(null)})]}),e.jsxs("div",{className:"h-[30vh] flex-none flex flex-col border-t border-surface-border overflow-hidden",children:[e.jsx(Qe,{}),e.jsx("div",{className:"flex-1 min-h-0 overflow-y-auto divide-y divide-surface-border/30",children:S.map(({role:r})=>e.jsx(Ue,{role:r,metric:f.find(y=>y.role===r.role),selected:o===r.role,onClick:()=>B(r.role)},r.role))})]})]})]})}export{nt as OperationsPage};
|
|
2
|
+
//# sourceMappingURL=OperationsPage-BCr21p8I.js.map
|