@hotmeshio/long-tail 0.10.2 → 0.10.3
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/README.md +1 -0
- package/build/api/bot-accounts.d.ts +4 -0
- package/build/api/bot-accounts.js +3 -1
- package/build/api/escalations/metadata.js +21 -1
- package/build/api/escalations/resolve.d.ts +8 -0
- package/build/api/escalations/resolve.js +82 -3
- package/build/api/roles.d.ts +2 -0
- package/build/api/roles.js +4 -0
- package/build/bin/ltc.js +10 -1
- package/build/lib/cli/client.d.ts +4 -1
- package/build/lib/cli/client.js +4 -2
- package/build/lib/db/schemas/023_role_enforce_schema.sql +18 -0
- package/build/lib/typed-resolution.d.ts +35 -0
- package/build/lib/typed-resolution.js +37 -0
- package/build/modules/config.d.ts +1 -0
- package/build/modules/config.js +5 -0
- package/build/routes/bot-accounts.js +3 -1
- package/build/sdk/index.d.ts +4 -0
- package/build/sdk/index.js +14 -0
- package/build/services/escalation/crud.d.ts +18 -6
- package/build/services/escalation/crud.js +18 -2
- package/build/services/escalation/index.d.ts +1 -0
- package/build/services/escalation/index.js +1 -0
- package/build/services/escalation/resolver-validation.d.ts +28 -0
- package/build/services/escalation/resolver-validation.js +95 -0
- package/build/services/escalation/sql.d.ts +12 -2
- package/build/services/escalation/sql.js +22 -2
- package/build/services/iam/bots.d.ts +4 -1
- package/build/services/iam/bots.js +5 -3
- package/build/services/iam/sql.d.ts +2 -2
- package/build/services/iam/sql.js +15 -1
- package/build/services/role/enforcement-cache.d.ts +21 -0
- package/build/services/role/enforcement-cache.js +0 -0
- package/build/services/role/index.js +5 -0
- package/build/services/role/sql.d.ts +12 -2
- package/build/services/role/sql.js +15 -2
- package/build/services/role/types.d.ts +9 -0
- package/build/shared/form-validation/field-validator.d.ts +45 -0
- package/build/shared/form-validation/field-validator.js +214 -0
- package/build/shared/form-validation/index.d.ts +11 -0
- package/build/shared/form-validation/index.js +27 -0
- package/build/shared/form-validation/validate-resolver-payload.d.ts +41 -0
- package/build/shared/form-validation/validate-resolver-payload.js +62 -0
- package/build/shared/form-validation/x-lt-bind.d.ts +41 -0
- package/build/shared/form-validation/x-lt-bind.js +110 -0
- package/build/shared/form-validation/x-lt-help.d.ts +21 -0
- package/build/shared/form-validation/x-lt-help.js +91 -0
- package/build/shared/form-validation/x-lt-show-if.d.ts +7 -0
- package/build/shared/form-validation/x-lt-show-if.js +84 -0
- package/build/system/mcp-servers/admin/schemas.d.ts +3 -0
- package/build/system/mcp-servers/admin/schemas.js +1 -0
- package/build/system/mcp-servers/admin/users.js +3 -1
- package/build/system/mcp-servers/human-queue-schemas.d.ts +4 -4
- package/build/system/mcp-servers/human-queue-schemas.js +4 -1
- package/build/system/mcp-servers/human-queue.js +41 -2
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/sdk.d.ts +6 -1
- package/build/types/validation.d.ts +43 -0
- package/build/types/validation.js +28 -0
- package/dashboard/dist/assets/{AdminDashboard-Dy031e9g.js → AdminDashboard-DQLGybZ9.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-Dy031e9g.js.map → AdminDashboard-DQLGybZ9.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-CqmtYBbC.js → AgentConfigPage-4JgMpuYJ.js} +3 -3
- package/dashboard/dist/assets/AgentConfigPage-4JgMpuYJ.js.map +1 -0
- package/dashboard/dist/assets/{AgentDetailPage-oYLBrN74.js → AgentDetailPage-DCgKokgX.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-oYLBrN74.js.map → AgentDetailPage-DCgKokgX.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-CHczRx5N.js → AgentsPage-BK_8VKZO.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-CHczRx5N.js.map → AgentsPage-BK_8VKZO.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-Dp1rsIHC.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-Dp1rsIHC.js.map +1 -0
- package/dashboard/dist/assets/BotPicker-DvUnYEJk.js +2 -0
- package/dashboard/dist/assets/BotPicker-DvUnYEJk.js.map +1 -0
- package/dashboard/dist/assets/{CapabilitiesPage-lQJGZ_-t.js → CapabilitiesPage-CJ5ldY8w.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-lQJGZ_-t.js.map → CapabilitiesPage-CJ5ldY8w.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-CHWP0WI6.js → CollapsibleSection-BXOpfs3z.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-CHWP0WI6.js.map → CollapsibleSection-BXOpfs3z.js.map} +1 -1
- package/dashboard/dist/assets/{CountdownTimer-TXsRlTU4.js → CountdownTimer-D20FNwS-.js} +2 -2
- package/dashboard/dist/assets/{CountdownTimer-TXsRlTU4.js.map → CountdownTimer-D20FNwS-.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-BKxS-1sA.js → CredentialsPage-vZ2psNnd.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-BKxS-1sA.js.map → CredentialsPage-vZ2psNnd.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-Bd2G0Rap.js → CronLabel-KRkqNSYs.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-Bd2G0Rap.js.map → CronLabel-KRkqNSYs.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-j4bBrDJ6.js → CustomDurationPicker-C-vGsrFl.js} +2 -2
- package/dashboard/dist/assets/CustomDurationPicker-C-vGsrFl.js.map +1 -0
- package/dashboard/dist/assets/{DropZone-DNDEgMpJ.js → DropZone-C3NdMtwK.js} +2 -2
- package/dashboard/dist/assets/{DropZone-DNDEgMpJ.js.map → DropZone-C3NdMtwK.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-g7GO7f8L.js → ElapsedCell-DNH-XHOS.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-g7GO7f8L.js.map → ElapsedCell-DNH-XHOS.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-CIJ-OgVC.js → EscalationListSchemaPage-BIW1qxjC.js} +3 -3
- package/dashboard/dist/assets/{EscalationListSchemaPage-CIJ-OgVC.js.map → EscalationListSchemaPage-BIW1qxjC.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-C7dHgG8e.js → EscalationSchemaPage-Fj2IwQXQ.js} +3 -3
- package/dashboard/dist/assets/{EscalationSchemaPage-C7dHgG8e.js.map → EscalationSchemaPage-Fj2IwQXQ.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-D8NrATg2.js → EscalationsOverview-BVUx0vZH.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-D8NrATg2.js.map → EscalationsOverview-BVUx0vZH.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-DBV1P2ME.js → EventTable-Dm4zZaRl.js} +2 -2
- package/dashboard/dist/assets/{EventTable-DBV1P2ME.js.map → EventTable-Dm4zZaRl.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-DbHvggQ_.js → GraphInvokePage-D4f074qh.js} +2 -2
- package/dashboard/dist/assets/GraphInvokePage-D4f074qh.js.map +1 -0
- package/dashboard/dist/assets/HomePage-DQ0bb_M_.js +2 -0
- package/dashboard/dist/assets/HomePage-DQ0bb_M_.js.map +1 -0
- package/dashboard/dist/assets/{ListToolbar-KC6LGtKP.js → ListToolbar-CItVkLQ-.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-KC6LGtKP.js.map → ListToolbar-CItVkLQ-.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-BDZC9Hvl.js → McpOverview-ByYVDldF.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-BDZC9Hvl.js.map → McpOverview-ByYVDldF.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-CXhgX1pS.js → McpQueryDetailPage-DYuIdJiH.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-CXhgX1pS.js.map → McpQueryDetailPage-DYuIdJiH.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-CsKNXUhb.js → McpQueryPage-C9C4mPC0.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-CsKNXUhb.js.map → McpQueryPage-C9C4mPC0.js.map} +1 -1
- package/dashboard/dist/assets/McpRunDetailPage-CWHKhx8n.js +2 -0
- package/dashboard/dist/assets/McpRunDetailPage-CWHKhx8n.js.map +1 -0
- package/dashboard/dist/assets/{McpRunsPage-f5hDbpLo.js → McpRunsPage-DMamEjjr.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-f5hDbpLo.js.map → McpRunsPage-DMamEjjr.js.map} +1 -1
- package/dashboard/dist/assets/{NamespacePill-C4u6Go1W.js → NamespacePill-B3YOa1xo.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-C4u6Go1W.js.map → NamespacePill-B3YOa1xo.js.map} +1 -1
- package/dashboard/dist/assets/{OperationsPage-D37cZ8Qh.js → OperationsPage-CVPDugQz.js} +2 -2
- package/dashboard/dist/assets/OperationsPage-CVPDugQz.js.map +1 -0
- package/dashboard/dist/assets/OperatorDashboard-CK-4GREp.js +2 -0
- package/dashboard/dist/assets/{OperatorDashboard-_axS17fp.js.map → OperatorDashboard-CK-4GREp.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-Bxa1XFz0.js → PageHeader-poyTWcUA.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-Bxa1XFz0.js.map → PageHeader-poyTWcUA.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-D_sO0MqJ.js → PageHeaderWithStats-CAmspbl9.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-D_sO0MqJ.js.map → PageHeaderWithStats-CAmspbl9.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-D8pAWUXx.js → ProcessDetailPage-BBCwv1bQ.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-D8pAWUXx.js.map → ProcessDetailPage-BBCwv1bQ.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-CoQEi_Su.js → ProcessesListPage-m70xmTZx.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-CoQEi_Su.js.map → ProcessesListPage-m70xmTZx.js.map} +1 -1
- package/dashboard/dist/assets/RoleDetailPage-l865Cx3n.js +8 -0
- package/dashboard/dist/assets/RoleDetailPage-l865Cx3n.js.map +1 -0
- package/dashboard/dist/assets/RolePill-C0SWz9X7.js +2 -0
- package/dashboard/dist/assets/RolePill-C0SWz9X7.js.map +1 -0
- package/dashboard/dist/assets/RolesPage-Wzfjz7Wc.js +2 -0
- package/dashboard/dist/assets/RolesPage-Wzfjz7Wc.js.map +1 -0
- package/dashboard/dist/assets/{RunAsSelector-BebF8Lib.js → RunAsSelector-DlnIolTf.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-BebF8Lib.js.map → RunAsSelector-DlnIolTf.js.map} +1 -1
- package/dashboard/dist/assets/{SlidePanel-BDVDuwIf.js → SlidePanel-Bm9B6zIA.js} +2 -2
- package/dashboard/dist/assets/{SlidePanel-BDVDuwIf.js.map → SlidePanel-Bm9B6zIA.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-Cd83AHd_.js → StickyPagination-BHF5fTt5.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-Cd83AHd_.js.map → StickyPagination-BHF5fTt5.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-BIXbrZM0.js → StreamMessageDetail-Dgp1lzay.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-BIXbrZM0.js.map → StreamMessageDetail-Dgp1lzay.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-CC5qZjYo.js → SwimlaneTimeline-BlptZ8lr.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-CC5qZjYo.js.map → SwimlaneTimeline-BlptZ8lr.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-C2gi47M8.js → TagInput-CM3AV5Ky.js} +2 -2
- package/dashboard/dist/assets/{TagInput-C2gi47M8.js.map → TagInput-CM3AV5Ky.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-DnjhW7qv.js → TaskDetailPage-f5K9dVPG.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-DnjhW7qv.js.map → TaskDetailPage-f5K9dVPG.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-BPP0Almh.js → TaskQueuePill-BZYmqdcv.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-BPP0Almh.js.map → TaskQueuePill-BZYmqdcv.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-DySfZFgs.js → TasksListPage-BPyPG6UY.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-DySfZFgs.js.map → TasksListPage-BPyPG6UY.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-BKOl-7Tt.js → TimeAgo-CBaGbueK.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-BKOl-7Tt.js.map → TimeAgo-CBaGbueK.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-DGOsba-A.js → TimestampCell-Z5kDrR9U.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-DGOsba-A.js.map → TimestampCell-Z5kDrR9U.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-D74TkYB-.js → ToolPill-D_-m3lUO.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-D74TkYB-.js.map → ToolPill-D_-m3lUO.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-Bez6OyRL.js → ToolTestPanel-DFrP_aMx.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-Bez6OyRL.js.map → ToolTestPanel-DFrP_aMx.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-BHccgkU_.js → TopicDetailPage-Cj9qXnTW.js} +3 -3
- package/dashboard/dist/assets/TopicDetailPage-Cj9qXnTW.js.map +1 -0
- package/dashboard/dist/assets/{TopicsPage-5yW63ELl.js → TopicsPage-Dyq6niOv.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-5yW63ELl.js.map → TopicsPage-Dyq6niOv.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-DcXhOSVm.js → UserName-DOX2P-8M.js} +2 -2
- package/dashboard/dist/assets/{UserName-DcXhOSVm.js.map → UserName-DOX2P-8M.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-Cb_dSIoq.js +2 -0
- package/dashboard/dist/assets/WorkflowExecutionPage-Cb_dSIoq.js.map +1 -0
- package/dashboard/dist/assets/{WorkflowPill-Fjc2q9U9.js → WorkflowPill-CyYYPB7b.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill-Fjc2q9U9.js.map → WorkflowPill-CyYYPB7b.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-C0Bbrd5M.js → WorkflowsDashboard-DJpMO5IY.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-C0Bbrd5M.js.map → WorkflowsDashboard-DJpMO5IY.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-D8MkSMex.js → WorkflowsOverview-CCC_KaXz.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-D8MkSMex.js.map → WorkflowsOverview-CCC_KaXz.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-BcbrYhDI.js → YamlWorkflowDetailPage-C3ntUyoZ.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-BcbrYhDI.js.map → YamlWorkflowDetailPage-C3ntUyoZ.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-9Ki54d-9.js → YamlWorkflowsPage-ju-9JDXg.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-9Ki54d-9.js.map → YamlWorkflowsPage-ju-9JDXg.js.map} +1 -1
- package/dashboard/dist/assets/{agents-CopQ3t5o.js → agents-gs9fea8r.js} +2 -2
- package/dashboard/dist/assets/{agents-CopQ3t5o.js.map → agents-gs9fea8r.js.map} +1 -1
- package/dashboard/dist/assets/bots-DYxAHrob.js +2 -0
- package/dashboard/dist/assets/bots-DYxAHrob.js.map +1 -0
- package/dashboard/dist/assets/{capabilities-5JRieYUy.js → capabilities-BJoxz6DJ.js} +2 -2
- package/dashboard/dist/assets/{capabilities-5JRieYUy.js.map → capabilities-BJoxz6DJ.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-B4rT6tIw.js → controlplane-BeDZgDDf.js} +2 -2
- package/dashboard/dist/assets/{controlplane-B4rT6tIw.js.map → controlplane-BeDZgDDf.js.map} +1 -1
- package/dashboard/dist/assets/escalation-columns-CZ4fl0IE.js +2 -0
- package/dashboard/dist/assets/escalation-columns-CZ4fl0IE.js.map +1 -0
- package/dashboard/dist/assets/{index-CUZJHXew.js → index-BMM3Xug7.js} +2 -2
- package/dashboard/dist/assets/index-BMM3Xug7.js.map +1 -0
- package/dashboard/dist/assets/index-BMXkxgnK.js +2 -0
- package/dashboard/dist/assets/{index-BOJMUk4F.js.map → index-BMXkxgnK.js.map} +1 -1
- package/dashboard/dist/assets/{index-mcAkQblr.js → index-Bj1Mjjiv.js} +2 -2
- package/dashboard/dist/assets/{index-mcAkQblr.js.map → index-Bj1Mjjiv.js.map} +1 -1
- package/dashboard/dist/assets/{index-iOb3sGsC.js → index-BqVb13tE.js} +2 -2
- package/dashboard/dist/assets/index-BqVb13tE.js.map +1 -0
- package/dashboard/dist/assets/{index-CDHDoHYz.js → index-CGrtjUdj.js} +2 -2
- package/dashboard/dist/assets/{index-CDHDoHYz.js.map → index-CGrtjUdj.js.map} +1 -1
- package/dashboard/dist/assets/{index-BAi89Xpm.js → index-CQ8cd4JZ.js} +2 -2
- package/dashboard/dist/assets/{index-BAi89Xpm.js.map → index-CQ8cd4JZ.js.map} +1 -1
- package/dashboard/dist/assets/{index-B68A3v-S.js → index-CruL35yU.js} +2 -2
- package/dashboard/dist/assets/{index-B68A3v-S.js.map → index-CruL35yU.js.map} +1 -1
- package/dashboard/dist/assets/index-DAM1Dm1F.js +2 -0
- package/dashboard/dist/assets/index-DAM1Dm1F.js.map +1 -0
- package/dashboard/dist/assets/{index-Dd1RxGNw.js → index-DZ7PWRg1.js} +2 -2
- package/dashboard/dist/assets/{index-Dd1RxGNw.js.map → index-DZ7PWRg1.js.map} +1 -1
- package/dashboard/dist/assets/{index-BxgtIqvl.js → index-DfbrPOP3.js} +2 -2
- package/dashboard/dist/assets/{index-BxgtIqvl.js.map → index-DfbrPOP3.js.map} +1 -1
- package/dashboard/dist/assets/index-DwuM7Fka.js +5 -0
- package/dashboard/dist/assets/index-DwuM7Fka.js.map +1 -0
- package/dashboard/dist/assets/index-DycfrrTK.js +63 -0
- package/dashboard/dist/assets/index-DycfrrTK.js.map +1 -0
- package/dashboard/dist/assets/{index-BrgYykPV.js → index-tbvwCdvQ.js} +2 -2
- package/dashboard/dist/assets/{index-BrgYykPV.js.map → index-tbvwCdvQ.js.map} +1 -1
- package/dashboard/dist/assets/index-zP2ncT4m.css +1 -0
- package/dashboard/dist/assets/{knowledge-B9bmoXOe.js → knowledge-DZnI1Fdk.js} +2 -2
- package/dashboard/dist/assets/{knowledge-B9bmoXOe.js.map → knowledge-DZnI1Fdk.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-DYMFBOFz.js → mcp-BB_m6UyI.js} +2 -2
- package/dashboard/dist/assets/{mcp-DYMFBOFz.js.map → mcp-BB_m6UyI.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-wloSpyPM.js → mcp-query-BTSWn0de.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-wloSpyPM.js.map → mcp-query-BTSWn0de.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-DBXX6TEi.js → pipelines-CvGQLyUz.js} +2 -2
- package/dashboard/dist/assets/{pipelines-DBXX6TEi.js.map → pipelines-CvGQLyUz.js.map} +1 -1
- package/dashboard/dist/assets/task-queues-7-sHKPsN.js +2 -0
- package/dashboard/dist/assets/task-queues-7-sHKPsN.js.map +1 -0
- package/dashboard/dist/assets/{tasks-CD3-C7tP.js → tasks-BbgOhCVm.js} +2 -2
- package/dashboard/dist/assets/{tasks-CD3-C7tP.js.map → tasks-BbgOhCVm.js.map} +1 -1
- package/dashboard/dist/assets/{topics-D8pKi6zA.js → topics-D9usuYHv.js} +2 -2
- package/dashboard/dist/assets/{topics-D8pKi6zA.js.map → topics-D9usuYHv.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-DV9pLDOW.js → useEventHooks-DxnqYVPg.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-DV9pLDOW.js.map → useEventHooks-DxnqYVPg.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-DykYhZY9.js → useNamespace-CBAn0o5z.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-DykYhZY9.js.map → useNamespace-CBAn0o5z.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-By044UAv.js → useYamlActivityEvents-blOlKGDO.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-By044UAv.js.map → useYamlActivityEvents-blOlKGDO.js.map} +1 -1
- package/dashboard/dist/assets/{users-mI9goDjj.js → users-CYVJHgNM.js} +2 -2
- package/dashboard/dist/assets/{users-mI9goDjj.js.map → users-CYVJHgNM.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-ihWGa7_d.js → vendor-icons-B98-XxNc.js} +2 -2
- package/dashboard/dist/assets/{vendor-icons-ihWGa7_d.js.map → vendor-icons-B98-XxNc.js.map} +1 -1
- package/dashboard/dist/assets/{workflows-DCUilz68.js → workflows-csQAJF0G.js} +2 -2
- package/dashboard/dist/assets/{workflows-DCUilz68.js.map → workflows-csQAJF0G.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-DWNMP1PT.js → yaml-workflows-CctsTDby.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-DWNMP1PT.js.map → yaml-workflows-CctsTDby.js.map} +1 -1
- package/dashboard/dist/index.html +3 -3
- package/docs/api/http/escalations.md +15 -1
- package/docs/api/http/roles.md +2 -0
- package/docs/hitl/x-lt-list-schema.md +8 -1
- package/docs/hitl-guide.md +3 -2
- package/docs/schema-enforcement.md +149 -0
- package/package.json +1 -1
- package/dashboard/dist/assets/AgentConfigPage-CqmtYBbC.js.map +0 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-DDVuivEE.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-DDVuivEE.js.map +0 -1
- package/dashboard/dist/assets/BotPicker-2QEIpc-K.js +0 -2
- package/dashboard/dist/assets/BotPicker-2QEIpc-K.js.map +0 -1
- package/dashboard/dist/assets/CustomDurationPicker-j4bBrDJ6.js.map +0 -1
- package/dashboard/dist/assets/GraphInvokePage-DbHvggQ_.js.map +0 -1
- package/dashboard/dist/assets/HomePage-BpexnDO_.js +0 -2
- package/dashboard/dist/assets/HomePage-BpexnDO_.js.map +0 -1
- package/dashboard/dist/assets/McpRunDetailPage-BM3mUSlH.js +0 -2
- package/dashboard/dist/assets/McpRunDetailPage-BM3mUSlH.js.map +0 -1
- package/dashboard/dist/assets/OperationsPage-D37cZ8Qh.js.map +0 -1
- package/dashboard/dist/assets/OperatorDashboard-_axS17fp.js +0 -2
- package/dashboard/dist/assets/RoleDetailPage-ufbypNNR.js +0 -8
- package/dashboard/dist/assets/RoleDetailPage-ufbypNNR.js.map +0 -1
- package/dashboard/dist/assets/RolePill-DLwmVMam.js +0 -2
- package/dashboard/dist/assets/RolePill-DLwmVMam.js.map +0 -1
- package/dashboard/dist/assets/RolesPage-CxpXm4Sw.js +0 -2
- package/dashboard/dist/assets/RolesPage-CxpXm4Sw.js.map +0 -1
- package/dashboard/dist/assets/TopicDetailPage-BHccgkU_.js.map +0 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-CDDLled5.js +0 -2
- package/dashboard/dist/assets/WorkflowExecutionPage-CDDLled5.js.map +0 -1
- package/dashboard/dist/assets/bots-CAYJYL9E.js +0 -2
- package/dashboard/dist/assets/bots-CAYJYL9E.js.map +0 -1
- package/dashboard/dist/assets/escalation-columns-BbS5X61l.js +0 -2
- package/dashboard/dist/assets/escalation-columns-BbS5X61l.js.map +0 -1
- package/dashboard/dist/assets/index-BJ0jjFsI.js +0 -5
- package/dashboard/dist/assets/index-BJ0jjFsI.js.map +0 -1
- package/dashboard/dist/assets/index-BOJMUk4F.js +0 -2
- package/dashboard/dist/assets/index-C0cHXaX-.css +0 -1
- package/dashboard/dist/assets/index-CUZJHXew.js.map +0 -1
- package/dashboard/dist/assets/index-D5n_e59T.js +0 -2
- package/dashboard/dist/assets/index-D5n_e59T.js.map +0 -1
- package/dashboard/dist/assets/index-DIgiIoou.js +0 -63
- package/dashboard/dist/assets/index-DIgiIoou.js.map +0 -1
- package/dashboard/dist/assets/index-iOb3sGsC.js.map +0 -1
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{b as be,j as e,a as p}from"./vendor-query-B2UbickB.js";import{o as ce,k as le,c as ye,N as ve,am as Ne,ac as de,I as xe,x as we,an as ke,P as _e,b as B,ae as Ce,ao as Se}from"./index-DIgiIoou.js";import{b as Pe}from"./workflows-DCUilz68.js";import{u as Ee}from"./pipelines-DBXX6TEi.js";import{u as Re}from"./controlplane-B4rT6tIw.js";import{e as qe,b as We,i as $e}from"./useEventHooks-DV9pLDOW.js";import{R as ee}from"./RolePill-DLwmVMam.js";import{W as q}from"./WorkflowPill-Fjc2q9U9.js";import{L as W}from"./ListToolbar-KC6LGtKP.js";import{j as Te,b as Ie}from"./OperationsPage-D37cZ8Qh.js";import{b0 as Ae,ar as j,ai as Qe,H as Be,C as te,W as se,I as $,L as ae,B as Me}from"./vendor-icons-ihWGa7_d.js";import{c as T,f as Fe}from"./vendor-react-CXumBFUA.js";import"./PageHeader-Bxa1XFz0.js";function Le(){const{user:s}=ce(),o=s==null?void 0:s.userId,a=be(),{data:n}=le({assigned_to:o,status:"pending",limit:1});return ye(`${ve}.system.escalation.>`,()=>{o&&a.invalidateQueries({queryKey:["escalations"]})}),(n==null?void 0:n.total)??0}function Q({n:s,label:o,tone:a}){return e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:`text-2xl font-light tabular-nums leading-none ${a==="muted"?"text-text-tertiary":"text-text-primary"}`,children:s}),e.jsx("div",{className:"text-[9px] uppercase tracking-wider text-text-quaternary mt-1 truncate",children:o})]})}function De({role:s,title:o,metric:a,priorityFacet:n,periodLabel:c}){const l=T(),i=(a==null?void 0:a.pending)??0,x=(a==null?void 0:a.claimed)??0,f=(a==null?void 0:a.resolved)??0,u=(a==null?void 0:a.priority_count)??0;return e.jsxs("div",{role:"button",tabIndex:0,onClick:()=>l(`/escalations/available?role=${encodeURIComponent(s)}`),onKeyDown:m=>{(m.key==="Enter"||m.key===" ")&&(m.preventDefault(),l(`/escalations/available?role=${encodeURIComponent(s)}`))},className:"group h-full border-l-2 border-accent/30 bg-surface-sunken/40 rounded-[0.125em] px-4 py-3.5 cursor-pointer transition-colors hover:bg-surface-sunken/70 focus:outline-none focus-visible:ring-1 focus-visible:ring-accent/40",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2 mb-3",children:[e.jsx("span",{className:"text-[11px] font-semibold uppercase tracking-wider text-text-secondary truncate",children:o||s}),e.jsx(j,{className:"w-3 h-3 shrink-0 text-text-quaternary opacity-0 group-hover:opacity-100 transition-opacity",strokeWidth:1.5})]}),e.jsxs("div",{className:"flex items-baseline gap-5",children:[e.jsx(Q,{n:i,label:"pending"}),e.jsx(Q,{n:x,label:"claimed"}),e.jsx(Q,{n:f,label:`resolved · ${c}`,tone:"muted"})]}),e.jsx("div",{className:"mt-3 h-6 flex items-center",children:u>0?e.jsxs("button",{type:"button",onClick:m=>{m.stopPropagation(),l(Te({role:s,priority_facet:n}))},className:"inline-flex items-center gap-1.5 pl-1.5 pr-2.5 py-1 rounded-full text-[11px] font-semibold tabular-nums bg-status-error text-white transition-transform hover:scale-[1.05]",title:"Past the priority threshold — a hard limit; open oldest first",children:[e.jsx(Qe,{className:"w-3 h-3",strokeWidth:2.5}),u," in jeopardy"]}):e.jsx("span",{className:"text-[10px] text-text-quaternary",children:"on pace"})})]})}function ne({count:s}){const o=T();return e.jsxs("div",{role:"button",tabIndex:0,onClick:()=>o("/escalations/queue"),onKeyDown:a=>{(a.key==="Enter"||a.key===" ")&&(a.preventDefault(),o("/escalations/queue"))},className:"group h-full border-l-2 border-status-warning/70 bg-status-warning/[0.06] rounded-[0.125em] px-4 py-3.5 cursor-pointer transition-colors hover:bg-status-warning/[0.1] focus:outline-none focus-visible:ring-1 focus-visible:ring-status-warning/40",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2 mb-3",children:[e.jsxs("span",{className:"flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wider text-status-warning",children:[e.jsx(Ae,{className:"w-3 h-3",strokeWidth:2}),"Claimed"]}),e.jsx(j,{className:"w-3 h-3 shrink-0 text-text-quaternary opacity-0 group-hover:opacity-100 transition-opacity",strokeWidth:1.5})]}),e.jsx("div",{className:"text-2xl font-light tabular-nums leading-none text-text-primary",children:s}),e.jsx("div",{className:"text-[9px] uppercase tracking-wider text-text-quaternary mt-1",children:"assigned to you"}),e.jsx("div",{className:"mt-3 h-6 flex items-center",children:e.jsx("span",{className:"text-[11px] font-medium text-status-warning",children:s>0?"Finish these first →":"Nothing claimed"})})]})}const He=["15m","1h","24h","7d"];function Oe({maxRows:s}){const[o,a]=p.useState("24h"),n=Ne(),c=Le(),l=de(o),i=xe(),x=p.useMemo(()=>{var r;return new Map((((r=l.data)==null?void 0:r.stations)??[]).map(d=>[d.role,d]))},[l.data]),f=p.useMemo(()=>{var r;return new Map((((r=i.data)==null?void 0:r.roles)??[]).map(d=>[d.role,d]))},[i.data]),u=p.useMemo(()=>[...n].sort((r,d)=>{var R,g;const h=((R=x.get(r))==null?void 0:R.priority_count)??0,E=((g=x.get(d))==null?void 0:g.priority_count)??0;return E!==h?E-h:r.localeCompare(d)}),[n,x]),P=s*4-1,y=u.slice(0,P),v=u.length-y.length;return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-4 pb-2 border-b border-surface-border",children:[e.jsxs("h2",{className:"flex items-center gap-2 text-sm font-medium text-text-primary",children:[e.jsx(Be,{className:"w-4 h-4 text-accent",strokeWidth:1.5}),"Task Queues"]}),e.jsx("div",{className:"flex items-center gap-0.5",children:He.map(r=>e.jsx("button",{onClick:()=>a(r),className:`px-2.5 py-1 text-[10px] font-mono rounded transition-colors ${o===r?"bg-accent/10 text-accent font-semibold":"text-text-quaternary hover:text-text-secondary"}`,children:r},r))})]}),n.length===0?e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4",children:[e.jsx(ne,{count:c}),e.jsx("div",{className:"lg:col-span-3 flex items-center px-4 py-3.5 text-sm text-text-tertiary",children:"You are not a member of a role. Task queues appear here once you join one."})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 auto-rows-fr",children:[e.jsx(ne,{count:c}),y.map(r=>{var d,h;return e.jsx(De,{role:r,title:((d=f.get(r))==null?void 0:d.title)??null,metric:x.get(r),priorityFacet:((h=f.get(r))==null?void 0:h.priority_facet)??null,periodLabel:o},r)})]}),v>0&&e.jsxs("p",{className:"mt-3 text-[11px] text-text-quaternary",children:["+",v," more ",v===1?"lane":"lanes"," in the Task Queues sidebar."]})]})]})}const Ue={completed:"bg-status-success",active:"bg-status-active",running:"bg-status-active",pending:"bg-status-pending",error:"bg-status-error",failed:"bg-status-error"};function oe(s){return Ue[s]??"bg-text-tertiary"}function _({icon:s,color:o,docsHash:a,count:n,children:c,actions:l}){return e.jsxs("div",{className:"flex items-center justify-between mb-4 pb-2 border-b border-surface-border",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(s,{className:`w-4.5 h-4.5 ${o||"text-accent/60"}`,strokeWidth:1.5}),e.jsx("h2",{className:"section-h2",children:c}),n!==void 0&&n>0&&e.jsx("span",{className:"px-1.5 py-0.5 rounded-full bg-accent/10 text-accent text-[10px] font-semibold tabular-nums",children:Se(n)})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[a&&e.jsx("button",{onClick:()=>{window.location.hash=a},className:"text-text-quaternary hover:text-accent transition-colors",title:"Docs",children:e.jsx(Me,{className:"w-2.5 h-2.5",strokeWidth:1.5})}),l]})]})}function C({icon:s,text:o}){return e.jsxs("div",{className:"flex flex-col items-center justify-center py-10 text-center",children:[e.jsx(s,{className:"w-6 h-6 text-text-quaternary/50 mb-2",strokeWidth:1}),e.jsx("p",{className:"text-xs text-text-quaternary",children:o})]})}function ze(s,o=37){if(!s||s.length<=o)return s;const a=Math.floor((o-3)/2);return`${s.slice(0,a)}...${s.slice(-a)}`}function re({dot:s,pill:o,id:a,date:n,onClick:c}){return e.jsxs("button",{onClick:c,className:"w-full text-left hover:bg-surface-hover/50 rounded-md px-1 py-1.5 transition-colors",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-0.5",children:[e.jsx("span",{className:`w-1.5 h-1.5 rounded-full dot-ring shrink-0 ${s}`}),e.jsx("span",{className:"text-[12px] text-text-primary font-mono truncate max-w-[60%]",children:ze(a)}),e.jsx("span",{className:"text-[10px] text-text-quaternary shrink-0 ml-auto whitespace-nowrap",children:e.jsx(B,{date:n})})]}),e.jsx("div",{className:"pl-3.5 flex items-center gap-1 overflow-hidden",children:o})]})}function S({to:s,icon:o,title:a}){const n=T();return e.jsx("button",{onClick:()=>n(s),className:"text-text-quaternary hover:text-accent transition-colors",title:a,children:e.jsx(o,{className:"w-2.5 h-2.5",strokeWidth:1.5})})}function ie({appIds:s,selected:o,onSelect:a}){const[n,c]=p.useState(!1),l=p.useRef(null);return p.useEffect(()=>{if(!n)return;const i=x=>{l.current&&!l.current.contains(x.target)&&c(!1)};return document.addEventListener("mousedown",i),()=>document.removeEventListener("mousedown",i)},[n]),s.length<=1?null:e.jsxs("div",{className:"relative mb-3 -mt-2",ref:l,children:[e.jsxs("button",{onClick:()=>c(i=>!i),className:"flex items-center gap-1 px-2 py-0.5 text-[10px] rounded bg-accent/10 text-accent hover:bg-accent/20 transition-colors",children:[o,e.jsx("svg",{className:`w-2.5 h-2.5 transition-transform ${n?"rotate-180":""}`,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2.5,children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"})})]}),n&&e.jsx("div",{className:"absolute top-full left-0 mt-1 bg-surface-raised border border-surface-border rounded-md shadow-lg z-30 py-1 min-w-[120px]",children:s.map(i=>e.jsx("button",{onClick:()=>{a(i),c(!1)},className:`w-full text-left px-3 py-1.5 text-[11px] transition-colors ${o===i?"text-accent bg-accent/5":"text-text-secondary hover:bg-surface-hover"}`,children:i},i))})]})}function rt(){var O,U,z,K,G,J,X,V;const s=T(),{user:o}=ce(),{isBuilder:a}=we(),n=ke(),[c,l]=Fe(),{data:i}=Re({enabled:a}),x=p.useMemo(()=>((i==null?void 0:i.apps)??[]).map(t=>t.appId).sort(),[i]),f=x[0]??"",u=c.get("pipelinenamespace")||f,m=c.get("durablenamespace")||f,P=p.useCallback((t,I)=>{l(A=>{const k=new URLSearchParams(A);return k.set(t,I),k},{replace:!1})},[l]);qe(),We(),$e();const y=!n.showTaskQueueCards,v=n.canSeePaceBoard&&n.canSeeWorkflows?"lg:grid-cols-3":n.canSeeWorkflows?"lg:grid-cols-2":"",r=xe({enabled:n.canSeePaceBoard}),d=de("1h",{enabled:n.canSeePaceBoard}),h=Pe({limit:5,sort_by:"updated_at",order:"desc",namespace:m},{enabled:n.canSeeWorkflows}),E=x,R=x,g=Ee({limit:5,app_id:u,sort_by:"updated_at",order:"desc"},{enabled:n.canSeeWorkflows}),N=_e({limit:5,sort_by:"created_at",order:"desc",enabled:y}),w=le({assigned_to:o==null?void 0:o.userId,status:"pending",limit:5,sort_by:"created_at",order:"desc",enabled:y});p.useEffect(()=>{const t=setTimeout(()=>{w.refetch(),N.refetch()},2e3);return()=>clearTimeout(t)},[]);const M=p.useMemo(()=>{var k,Y,Z;const I=((Y=Ie(((k=r.data)==null?void 0:k.roles)??[])[0])==null?void 0:Y.stations)??[],A=((Z=d.data)==null?void 0:Z.stations)??[];return I.map(({role:b})=>({role:b.role,title:b.title,parent_role:b.parent_role,target_per_hour:b.target_per_hour??null,upstream_roles:b.upstream_roles??[],metric:A.find(je=>je.role===b.role)}))},[r.data,d.data]),F=((O=h.data)==null?void 0:O.jobs)??[],pe=(U=h.data)==null?void 0:U.total,L=((z=g.data)==null?void 0:z.jobs)??[],ue=(K=g.data)==null?void 0:K.total,D=((G=N.data)==null?void 0:G.escalations)??[],me=(J=N.data)==null?void 0:J.total,H=((X=w.data)==null?void 0:X.escalations)??[],he=(V=w.data)==null?void 0:V.total,fe=e.jsxs("div",{children:[e.jsx(_,{icon:te,color:"text-accent",count:pe,docsHash:"#docs:dashboard.md:procedural-executions",actions:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(W,{onRefresh:()=>h.refetch(),isFetching:h.isFetching,apiPath:`/workflow-states/jobs?namespace=${m}&limit=5`}),e.jsx(S,{to:"/workflows/executions",icon:j,title:"All procedural executions"})]}),children:"Procedural"}),e.jsx(ie,{appIds:E,selected:m,onSelect:t=>P("durablenamespace",t)}),F.length===0?e.jsx(C,{icon:te,text:"No recent procedural runs"}):e.jsx("div",{className:"space-y-1",children:F.map(t=>e.jsx(re,{dot:oe(t.status),pill:e.jsx(q,{type:t.entity||t.type||"workflow",size:"xs"}),id:t.workflow_id,date:t.updated_at??t.created_at,onClick:()=>s(`/workflows/executions/${t.workflow_id}`)},t.workflow_id))})]}),ge=e.jsxs("div",{children:[e.jsx(_,{icon:se,color:"text-accent",count:ue,docsHash:"#docs:dashboard.md:graph-executions",actions:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(W,{onRefresh:()=>g.refetch(),isFetching:g.isFetching,apiPath:`/pipelines?app_id=${u}&limit=5`}),e.jsx(S,{to:"/mcp/executions",icon:j,title:"All graph executions"})]}),children:"Graph"}),e.jsx(ie,{appIds:R,selected:u,onSelect:t=>P("pipelinenamespace",t)}),L.length===0?e.jsx(C,{icon:se,text:"No recent graph runs"}):e.jsx("div",{className:"space-y-1",children:L.map(t=>e.jsx(re,{dot:oe(t.status),pill:e.jsx(q,{type:t.entity||t.workflow_name||"pipeline",variant:"pipeline",size:"xs"}),id:t.workflow_id,date:t.updated_at??t.created_at,onClick:()=>s(`/mcp/executions/${t.workflow_id}?namespace=${u}`)},t.workflow_id))})]});return n.showTaskQueueCards?e.jsxs("div",{children:[e.jsx("h1",{className:"text-3xl font-light text-text-primary mb-10",children:"Recent Activity"}),e.jsx(Oe,{maxRows:2})]}):e.jsxs("div",{children:[e.jsx("h1",{className:"text-3xl font-light text-text-primary mb-10",children:"Recent Activity"}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-x-14 min-h-[35vh]",children:[e.jsxs("div",{children:[e.jsx(_,{icon:$,color:"text-accent",count:me,docsHash:"#docs:dashboard.md:all-escalations",actions:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(W,{onRefresh:()=>N.refetch(),isFetching:N.isFetching,apiPath:"/escalations?status=pending&limit=5&sort_by=created_at&order=desc"}),e.jsx(S,{to:"/escalations/available",icon:j,title:"All escalations"})]}),children:"All Escalations"}),D.length===0?e.jsx(C,{icon:$,text:"No pending escalations"}):e.jsx("div",{className:"space-y-1",children:D.map(t=>e.jsxs("button",{onClick:()=>s(`/escalations/detail/${t.id}`),className:"w-full text-left hover:bg-surface-hover/50 rounded-md px-1 py-1.5 transition-colors",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-0.5",children:[e.jsxs("span",{className:"text-[9px] text-text-quaternary font-medium shrink-0",children:["P",t.priority??2]}),e.jsx("span",{className:"text-[12px] text-text-primary truncate flex-1 max-w-[65%]",children:t.description||t.subtype||t.type}),e.jsx("span",{className:"text-[10px] text-text-quaternary shrink-0 ml-auto",children:e.jsx(B,{date:t.updated_at??t.created_at})})]}),e.jsxs("div",{className:"flex items-center gap-2 pl-5",children:[e.jsx(q,{type:t.type||"unknown",size:"xs"}),e.jsx("span",{className:"flex-1"}),e.jsx(ee,{role:t.role})]})]},t.id))})]}),e.jsxs("div",{children:[e.jsx(_,{icon:$,color:"text-accent",count:he,docsHash:"#docs:dashboard.md:escalations-overview",actions:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(W,{onRefresh:()=>w.refetch(),isFetching:w.isFetching,apiPath:`/escalations?assigned_to=${(o==null?void 0:o.userId)??""}&status=pending&limit=5&sort_by=created_at&order=desc`}),e.jsx(S,{to:"/escalations/queue",icon:j,title:"My escalation queue"})]}),children:"My Escalations"}),H.length===0?e.jsx(C,{icon:$,text:"No assigned escalations"}):e.jsx("div",{className:"space-y-1",children:H.map(t=>e.jsxs("button",{onClick:()=>s(`/escalations/detail/${t.id}`),className:"w-full text-left hover:bg-surface-hover/50 rounded-md px-1 py-1.5 transition-colors",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-0.5",children:[e.jsxs("span",{className:"text-[9px] text-text-quaternary font-medium shrink-0",children:["P",t.priority??2]}),e.jsx("span",{className:"text-[12px] text-text-primary truncate flex-1 max-w-[65%]",children:t.description||t.subtype||t.type}),e.jsx("span",{className:"text-[10px] text-text-quaternary shrink-0 ml-auto",children:e.jsx(B,{date:t.updated_at??t.created_at})})]}),e.jsxs("div",{className:"flex items-center gap-2 pl-5",children:[e.jsx(q,{type:t.type||"unknown",size:"xs"}),e.jsx("span",{className:"flex-1"}),e.jsx(ee,{role:t.role})]})]},t.id))})]})]}),(n.canSeePaceBoard||n.canSeeWorkflows)&&e.jsxs("div",{className:`grid grid-cols-1 ${v} gap-x-14 mt-14`,children:[n.canSeePaceBoard&&e.jsxs("div",{children:[e.jsx(_,{icon:ae,color:"text-accent",docsHash:"#docs:dashboard.md:pace-board",actions:e.jsx(S,{to:"/operations",icon:j,title:"Open the Pace Board"}),children:"Pace Board"}),M.length===0?e.jsx(C,{icon:ae,text:"No stations yet — mark roles visible in Operations"}):e.jsx("div",{className:`${a?"h-64":"h-80"} cursor-pointer`,onClick:()=>s("/operations"),children:e.jsx(Ce,{stations:M,selectedRole:null,onSelect:()=>s("/operations"),onUpstreamSelect:()=>s("/operations"),periodHours:1})})]}),n.canSeeWorkflows&&fe,n.canSeeWorkflows&&ge]})]})}export{rt as HomePage};
|
|
2
|
-
//# sourceMappingURL=HomePage-BpexnDO_.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"HomePage-BpexnDO_.js","sources":["../../src/hooks/useMyEscalationCount.ts","../../src/pages/home/TaskQueueCard.tsx","../../src/pages/home/TaskQueueCards.tsx","../../src/pages/home/HomePage.tsx"],"sourcesContent":["import { useQueryClient } from '@tanstack/react-query';\nimport { useAuth } from './useAuth';\nimport { useEscalations } from '../api/escalations';\nimport { useEventSubscription } from './useEventContext';\nimport { NATS_SUBJECT_PREFIX } from '../lib/nats/config';\n\n/**\n * Returns the number of active (non-expired) escalations assigned to the current user.\n * The API filters expired claims server-side (assigned_until > NOW()) when\n * assigned_to is provided, so the total from the query is accurate.\n */\nexport function useMyEscalationCount(): number {\n const { user } = useAuth();\n const userId = user?.userId;\n const qc = useQueryClient();\n\n const { data } = useEscalations({\n assigned_to: userId,\n status: 'pending',\n limit: 1,\n });\n\n useEventSubscription(`${NATS_SUBJECT_PREFIX}.system.escalation.>`, () => {\n if (userId) {\n qc.invalidateQueries({ queryKey: ['escalations'] });\n }\n });\n\n return data?.total ?? 0;\n}\n","import { useNavigate } from 'react-router-dom';\nimport { ExternalLink, TriangleAlert, Hand } from 'lucide-react';\nimport type { StationMetric } from '../../api/escalations';\nimport { jeopardyQueueLink } from '../operations/priority-link';\n\nfunction Stat({ n, label, tone }: { n: number; label: string; tone?: 'muted' }) {\n return (\n <div className=\"min-w-0\">\n <div className={`text-2xl font-light tabular-nums leading-none ${tone === 'muted' ? 'text-text-tertiary' : 'text-text-primary'}`}>\n {n}\n </div>\n <div className=\"text-[9px] uppercase tracking-wider text-text-quaternary mt-1 truncate\">{label}</div>\n </div>\n );\n}\n\n/**\n * One lane's shape at a glance: pending / claimed / resolved over the selected\n * window, plus the jeopardy signal when items sit past the role's priority\n * threshold. The card opens the role's queue; the jeopardy pill opens it\n * sorted oldest-first so the at-risk items sit on top.\n */\nexport function TaskQueueCard({\n role,\n title,\n metric,\n priorityFacet,\n periodLabel,\n}: {\n role: string;\n title: string | null;\n metric: StationMetric | undefined;\n priorityFacet: string | null;\n periodLabel: string;\n}) {\n const navigate = useNavigate();\n const pending = metric?.pending ?? 0;\n const claimed = metric?.claimed ?? 0;\n const resolved = metric?.resolved ?? 0;\n const jeopardy = metric?.priority_count ?? 0;\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => navigate(`/escalations/available?role=${encodeURIComponent(role)}`)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n navigate(`/escalations/available?role=${encodeURIComponent(role)}`);\n }\n }}\n className=\"group h-full border-l-2 border-accent/30 bg-surface-sunken/40 rounded-[0.125em] px-4 py-3.5 cursor-pointer transition-colors hover:bg-surface-sunken/70 focus:outline-none focus-visible:ring-1 focus-visible:ring-accent/40\"\n >\n <div className=\"flex items-center justify-between gap-2 mb-3\">\n <span className=\"text-[11px] font-semibold uppercase tracking-wider text-text-secondary truncate\">\n {title || role}\n </span>\n <ExternalLink className=\"w-3 h-3 shrink-0 text-text-quaternary opacity-0 group-hover:opacity-100 transition-opacity\" strokeWidth={1.5} />\n </div>\n\n <div className=\"flex items-baseline gap-5\">\n <Stat n={pending} label=\"pending\" />\n <Stat n={claimed} label=\"claimed\" />\n <Stat n={resolved} label={`resolved · ${periodLabel}`} tone=\"muted\" />\n </div>\n\n <div className=\"mt-3 h-6 flex items-center\">\n {jeopardy > 0 ? (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n navigate(jeopardyQueueLink({ role, priority_facet: priorityFacet }));\n }}\n className=\"inline-flex items-center gap-1.5 pl-1.5 pr-2.5 py-1 rounded-full text-[11px] font-semibold tabular-nums bg-status-error text-white transition-transform hover:scale-[1.05]\"\n title=\"Past the priority threshold — a hard limit; open oldest first\"\n >\n <TriangleAlert className=\"w-3 h-3\" strokeWidth={2.5} />\n {jeopardy} in jeopardy\n </button>\n ) : (\n <span className=\"text-[10px] text-text-quaternary\">on pace</span>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * The runner's own work, across every lane. First and highlighted — what to\n * finish before pulling anything new. Opens their personal queue.\n */\nexport function ClaimedCard({ count }: { count: number }) {\n const navigate = useNavigate();\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => navigate('/escalations/queue')}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n navigate('/escalations/queue');\n }\n }}\n className=\"group h-full border-l-2 border-status-warning/70 bg-status-warning/[0.06] rounded-[0.125em] px-4 py-3.5 cursor-pointer transition-colors hover:bg-status-warning/[0.1] focus:outline-none focus-visible:ring-1 focus-visible:ring-status-warning/40\"\n >\n <div className=\"flex items-center justify-between gap-2 mb-3\">\n <span className=\"flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wider text-status-warning\">\n <Hand className=\"w-3 h-3\" strokeWidth={2} />\n Claimed\n </span>\n <ExternalLink className=\"w-3 h-3 shrink-0 text-text-quaternary opacity-0 group-hover:opacity-100 transition-opacity\" strokeWidth={1.5} />\n </div>\n\n <div className=\"text-2xl font-light tabular-nums leading-none text-text-primary\">{count}</div>\n <div className=\"text-[9px] uppercase tracking-wider text-text-quaternary mt-1\">assigned to you</div>\n\n <div className=\"mt-3 h-6 flex items-center\">\n <span className=\"text-[11px] font-medium text-status-warning\">\n {count > 0 ? 'Finish these first →' : 'Nothing claimed'}\n </span>\n </div>\n </div>\n );\n}\n","import { useState, useMemo } from 'react';\nimport { Layers } from 'lucide-react';\nimport { useStationMetrics } from '../../api/escalations';\nimport { useRoleDetails } from '../../api/roles';\nimport { useTaskQueueRoles } from '../../hooks/useTaskQueueRoles';\nimport { useMyEscalationCount } from '../../hooks/useMyEscalationCount';\nimport { TaskQueueCard, ClaimedCard } from './TaskQueueCard';\n\nconst PERIODS = ['15m', '1h', '24h', '7d'] as const;\ntype Period = (typeof PERIODS)[number];\n\n/**\n * The scoped runner's home: their own claimed work first, then one card per\n * lane they belong to — pending / claimed / resolved and a jeopardy signal over\n * a chosen window. A poor-man's Pace Board: no cross-role trend, just \"what is\n * in my lanes and what needs attention.\" Engineers get a single compact row\n * (workflows sit below); operators get the fuller two-row surface.\n */\nexport function TaskQueueCards({ maxRows }: { maxRows: 1 | 2 }) {\n const [period, setPeriod] = useState<Period>('24h');\n const roles = useTaskQueueRoles();\n const claimedCount = useMyEscalationCount();\n const metricsQ = useStationMetrics(period);\n const rolesQ = useRoleDetails();\n\n const metricByRole = useMemo(\n () => new Map((metricsQ.data?.stations ?? []).map((m) => [m.role, m])),\n [metricsQ.data],\n );\n const detailByRole = useMemo(\n () => new Map((rolesQ.data?.roles ?? []).map((r) => [r.role, r])),\n [rolesQ.data],\n );\n\n // Lanes lead with the most at-risk: sort by jeopardy count (a hard limit the\n // plant manager pulls to the front of the line), then alphabetically for a\n // stable order among ties. Card #1 is always Claimed, ahead of these.\n const sortedRoles = useMemo(() => {\n return [...roles].sort((a, b) => {\n const ja = metricByRole.get(a)?.priority_count ?? 0;\n const jb = metricByRole.get(b)?.priority_count ?? 0;\n if (jb !== ja) return jb - ja;\n return a.localeCompare(b);\n });\n }, [roles, metricByRole]);\n\n // The rest of the grid is lanes. Cap to the persona's row budget and surface\n // any overflow rather than hiding it.\n const slots = maxRows * 4;\n const laneBudget = slots - 1;\n const shownRoles = sortedRoles.slice(0, laneBudget);\n const overflow = sortedRoles.length - shownRoles.length;\n\n return (\n <div>\n <div className=\"flex items-center justify-between mb-4 pb-2 border-b border-surface-border\">\n <h2 className=\"flex items-center gap-2 text-sm font-medium text-text-primary\">\n <Layers className=\"w-4 h-4 text-accent\" strokeWidth={1.5} />\n Task Queues\n </h2>\n <div className=\"flex items-center gap-0.5\">\n {PERIODS.map((p) => (\n <button\n key={p}\n onClick={() => setPeriod(p)}\n className={`px-2.5 py-1 text-[10px] font-mono rounded transition-colors ${\n period === p\n ? 'bg-accent/10 text-accent font-semibold'\n : 'text-text-quaternary hover:text-text-secondary'\n }`}\n >\n {p}\n </button>\n ))}\n </div>\n </div>\n\n {roles.length === 0 ? (\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4\">\n <ClaimedCard count={claimedCount} />\n <div className=\"lg:col-span-3 flex items-center px-4 py-3.5 text-sm text-text-tertiary\">\n You are not a member of a role. Task queues appear here once you join one.\n </div>\n </div>\n ) : (\n <>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 auto-rows-fr\">\n <ClaimedCard count={claimedCount} />\n {shownRoles.map((role) => (\n <TaskQueueCard\n key={role}\n role={role}\n title={detailByRole.get(role)?.title ?? null}\n metric={metricByRole.get(role)}\n priorityFacet={detailByRole.get(role)?.priority_facet ?? null}\n periodLabel={period}\n />\n ))}\n </div>\n {overflow > 0 && (\n <p className=\"mt-3 text-[11px] text-text-quaternary\">\n +{overflow} more {overflow === 1 ? 'lane' : 'lanes'} in the Task Queues sidebar.\n </p>\n )}\n </>\n )}\n </div>\n );\n}\n","import { useState, useRef, useCallback, useEffect, useMemo } from 'react';\nimport { useNavigate, useSearchParams } from 'react-router-dom';\nimport {\n Inbox, Code2, Workflow, LayoutDashboard, ExternalLink, BookOpen,\n} from 'lucide-react';\nimport { formatCountCompact } from '../../lib/format';\nimport { useAvailableEscalations, useEscalations, useStationMetrics } from '../../api/escalations';\nimport { useRoleDetails } from '../../api/roles';\nimport { useJobs } from '../../api/workflows';\nimport { useMcpRuns } from '../../api/pipelines';\nimport { useControlPlaneApps } from '../../api/controlplane';\nimport { useAuth } from '../../hooks/useAuth';\nimport { useAccess } from '../../hooks/useAccess';\nimport { usePersona } from '../../hooks/usePersona';\nimport { useEscalationStatsEvents, useWorkflowListEvents, useStationMetricsEvents } from '../../hooks/useEventHooks';\nimport { DateValue } from '../../components/common/display/DateValue';\nimport { RolePill } from '../../components/common/display/RolePill';\nimport { WorkflowPill } from '../../components/common/display/WorkflowPill';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\nimport { PaceChart, type ChartStation } from '../operations/PaceChart';\nimport { buildFragments } from '../operations/OperationsPage';\nimport { TaskQueueCards } from './TaskQueueCards';\n\nconst STATUS_DOT: Record<string, string> = {\n completed: 'bg-status-success',\n active: 'bg-status-active',\n running: 'bg-status-active',\n pending: 'bg-status-pending',\n error: 'bg-status-error',\n failed: 'bg-status-error',\n};\nfunction statusDotClass(status: string): string {\n return STATUS_DOT[status] ?? 'bg-text-tertiary';\n}\n\n// ── Section header ──────────────────────────────────────────────────────────\n\nfunction SectionHeader({ icon: Icon, color, docsHash, count, children, actions }: { icon: React.ElementType; color?: string; docsHash?: string; count?: number; children: React.ReactNode; actions?: React.ReactNode }) {\n return (\n <div className=\"flex items-center justify-between mb-4 pb-2 border-b border-surface-border\">\n <div className=\"flex items-center gap-2\">\n <Icon className={`w-4.5 h-4.5 ${color || 'text-accent/60'}`} strokeWidth={1.5} />\n <h2 className=\"section-h2\">{children}</h2>\n {count !== undefined && count > 0 && (\n <span className=\"px-1.5 py-0.5 rounded-full bg-accent/10 text-accent text-[10px] font-semibold tabular-nums\">\n {formatCountCompact(count)}\n </span>\n )}\n </div>\n <div className=\"flex items-center gap-2\">\n {docsHash && (\n <button onClick={() => { window.location.hash = docsHash; }} className=\"text-text-quaternary hover:text-accent transition-colors\" title=\"Docs\">\n <BookOpen className=\"w-2.5 h-2.5\" strokeWidth={1.5} />\n </button>\n )}\n {actions}\n </div>\n </div>\n );\n}\n\nfunction EmptyPanel({ icon: Icon, text }: { icon: React.ElementType; text: string }) {\n return (\n <div className=\"flex flex-col items-center justify-center py-10 text-center\">\n <Icon className=\"w-6 h-6 text-text-quaternary/50 mb-2\" strokeWidth={1} />\n <p className=\"text-xs text-text-quaternary\">{text}</p>\n </div>\n );\n}\n\n/** Middle-ellipsis: keep first N and last N chars with ... in between */\nfunction midEllipsis(s: string, maxLen = 37): string {\n if (!s || s.length <= maxLen) return s;\n const keep = Math.floor((maxLen - 3) / 2);\n return `${s.slice(0, keep)}...${s.slice(-keep)}`;\n}\n\n/** Consistent row for all execution lists in row 1 */\nfunction ExecutionRow({ dot, pill, id, date, onClick }: {\n dot: string;\n pill: React.ReactNode;\n id: string;\n date: string;\n onClick: () => void;\n}) {\n return (\n <button onClick={onClick} className=\"w-full text-left hover:bg-surface-hover/50 rounded-md px-1 py-1.5 transition-colors\">\n <div className=\"flex items-center gap-2 mb-0.5\">\n <span className={`w-1.5 h-1.5 rounded-full dot-ring shrink-0 ${dot}`} />\n <span className=\"text-[12px] text-text-primary font-mono truncate max-w-[60%]\">{midEllipsis(id)}</span>\n <span className=\"text-[10px] text-text-quaternary shrink-0 ml-auto whitespace-nowrap\"><DateValue date={date} /></span>\n </div>\n <div className=\"pl-3.5 flex items-center gap-1 overflow-hidden\">{pill}</div>\n </button>\n );\n}\n\nfunction NavIcon({ to, icon: Icon, title }: { to: string; icon: React.ElementType; title: string }) {\n const navigate = useNavigate();\n return (\n <button\n onClick={() => navigate(to)}\n className=\"text-text-quaternary hover:text-accent transition-colors\"\n title={title}\n >\n <Icon className=\"w-2.5 h-2.5\" strokeWidth={1.5} />\n </button>\n );\n}\n\n// ── Namespace Picker ────────────────────────────────────────────────────────\n\nfunction AppPicker({ appIds, selected, onSelect }: {\n appIds: string[];\n selected: string;\n onSelect: (id: string) => 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 (appIds.length <= 1) return null;\n\n return (\n <div className=\"relative mb-3 -mt-2\" ref={ref}>\n <button\n onClick={() => setOpen((v) => !v)}\n className=\"flex items-center gap-1 px-2 py-0.5 text-[10px] rounded bg-accent/10 text-accent hover:bg-accent/20 transition-colors\"\n >\n {selected}\n <svg className={`w-2.5 h-2.5 transition-transform ${open ? 'rotate-180' : ''}`} fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19 9l-7 7-7-7\" />\n </svg>\n </button>\n {open && (\n <div className=\"absolute top-full left-0 mt-1 bg-surface-raised border border-surface-border rounded-md shadow-lg z-30 py-1 min-w-[120px]\">\n {appIds.map((id) => (\n <button\n key={id}\n onClick={() => { onSelect(id); setOpen(false); }}\n className={`w-full text-left px-3 py-1.5 text-[11px] transition-colors ${\n selected === id ? 'text-accent bg-accent/5' : 'text-text-secondary hover:bg-surface-hover'\n }`}\n >\n {id}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n// ── Page ─────────────────────────────────────────────────────────────────────\n\nexport function HomePage() {\n const navigate = useNavigate();\n const { user } = useAuth();\n const { isBuilder } = useAccess();\n const persona = usePersona();\n const [searchParams, setSearchParams] = useSearchParams();\n const { data: cpData } = useControlPlaneApps({ enabled: isBuilder });\n const allAppIds = useMemo(() => (cpData?.apps ?? []).map((a: any) => a.appId).sort(), [cpData]);\n const firstAppId = allAppIds[0] ?? '';\n const pipelineNs = searchParams.get('pipelinenamespace') || firstAppId;\n const durableNs = searchParams.get('durablenamespace') || firstAppId;\n const setNs = useCallback((key: string, ns: string) => {\n setSearchParams((prev) => {\n const next = new URLSearchParams(prev);\n next.set(key, ns);\n return next;\n }, { replace: false });\n }, [setSearchParams]);\n useEscalationStatsEvents();\n useWorkflowListEvents();\n useStationMetricsEvents();\n\n // The home page renders one of two layouts (see the return below): the\n // operator's task-queue cards, or the builder home shared by admin, engineer,\n // and superadmin. Gate each data source to the tiers that render it, so no one\n // fires a request they can't access (403 on control-plane apps → empty\n // namespace → 400 on jobs):\n // - All/My escalation firehose → the builder home (everyone except operator)\n // - Pace Board → admin, superadmin only\n // - Procedural/Graph workflows → builders (engineer, superadmin)\n // - Task-queue cards fetch their own scoped metrics inside TaskQueueCards.\n const builderHome = !persona.showTaskQueueCards;\n // Row 2 width adapts to what the tier can see: pace + both workflow columns\n // (superadmin), workflows only (engineer), or pace only, full-width (admin).\n const row2GridClass = persona.canSeePaceBoard && persona.canSeeWorkflows ? 'lg:grid-cols-3'\n : persona.canSeeWorkflows ? 'lg:grid-cols-2' : '';\n const rolesQ = useRoleDetails({ enabled: persona.canSeePaceBoard });\n const stationQ = useStationMetrics('1h', { enabled: persona.canSeePaceBoard });\n const jobsQ = useJobs({ limit: 5, sort_by: 'updated_at', order: 'desc', namespace: durableNs }, { enabled: persona.canSeeWorkflows });\n const durableAppIds = allAppIds;\n const pipelineAppIds = allAppIds;\n const mcpQ = useMcpRuns({ limit: 5, app_id: pipelineNs, sort_by: 'updated_at', order: 'desc' }, { enabled: persona.canSeeWorkflows });\n const allEscQ = useAvailableEscalations({ limit: 5, sort_by: 'created_at', order: 'desc', enabled: builderHome });\n const myEscQ = useEscalations({ assigned_to: user?.userId, status: 'pending', limit: 5, sort_by: 'created_at', order: 'desc', enabled: builderHome });\n\n // Delayed refetch — allows signal-routed escalation resolutions\n // (durable activity) time to commit before refreshing the list\n useEffect(() => {\n const timer = setTimeout(() => {\n myEscQ.refetch();\n allEscQ.refetch();\n }, 2000);\n return () => clearTimeout(timer);\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Pace Board mini — the primary sequence (longest line) at the 1h window.\n const paceStations = useMemo((): ChartStation[] => {\n const fragments = buildFragments(rolesQ.data?.roles ?? []);\n const primary = fragments[0]?.stations ?? [];\n const metrics = stationQ.data?.stations ?? [];\n return primary.map(({ role: r }) => ({\n role: r.role,\n title: r.title,\n parent_role: r.parent_role,\n target_per_hour: r.target_per_hour ?? null,\n upstream_roles: r.upstream_roles ?? [],\n metric: metrics.find((m) => m.role === r.role),\n }));\n }, [rolesQ.data, stationQ.data]);\n\n const jobs = jobsQ.data?.jobs ?? [];\n const jobsTotal = jobsQ.data?.total;\n const mcpRuns = (mcpQ.data as any)?.jobs ?? [];\n const mcpTotal = (mcpQ.data as any)?.total as number | undefined;\n const allEscalations = allEscQ.data?.escalations ?? [];\n const allEscTotal = allEscQ.data?.total;\n const myEscalations = myEscQ.data?.escalations ?? [];\n const myEscTotal = myEscQ.data?.total;\n\n // The two workflow execution columns, shared by the builder branches (the\n // engineer layout below and the superadmin Row 2). Defined once so the JSX\n // has a single source of truth.\n const proceduralColumn = (\n <div>\n <SectionHeader icon={Code2} color=\"text-accent\" count={jobsTotal} docsHash=\"#docs:dashboard.md:procedural-executions\" actions={\n <div className=\"flex items-center gap-2\">\n <ListToolbar onRefresh={() => jobsQ.refetch()} isFetching={jobsQ.isFetching} apiPath={`/workflow-states/jobs?namespace=${durableNs}&limit=5`} />\n <NavIcon to=\"/workflows/executions\" icon={ExternalLink} title=\"All procedural executions\" />\n </div>\n }>\n Procedural\n </SectionHeader>\n <AppPicker appIds={durableAppIds} selected={durableNs} onSelect={(ns) => setNs('durablenamespace', ns)} />\n {jobs.length === 0 ? (\n <EmptyPanel icon={Code2} text=\"No recent procedural runs\" />\n ) : (\n <div className=\"space-y-1\">\n {jobs.map((job: any) => (\n <ExecutionRow\n key={job.workflow_id}\n dot={statusDotClass(job.status)}\n pill={<WorkflowPill type={job.entity || job.type || 'workflow'} size=\"xs\" />}\n id={job.workflow_id}\n date={job.updated_at ?? job.created_at}\n onClick={() => navigate(`/workflows/executions/${job.workflow_id}`)}\n />\n ))}\n </div>\n )}\n </div>\n );\n\n const graphColumn = (\n <div>\n <SectionHeader icon={Workflow} color=\"text-accent\" count={mcpTotal} docsHash=\"#docs:dashboard.md:graph-executions\" actions={\n <div className=\"flex items-center gap-2\">\n <ListToolbar onRefresh={() => mcpQ.refetch()} isFetching={mcpQ.isFetching} apiPath={`/pipelines?app_id=${pipelineNs}&limit=5`} />\n <NavIcon to=\"/mcp/executions\" icon={ExternalLink} title=\"All graph executions\" />\n </div>\n }>\n Graph\n </SectionHeader>\n <AppPicker appIds={pipelineAppIds} selected={pipelineNs} onSelect={(ns) => setNs('pipelinenamespace', ns)} />\n {mcpRuns.length === 0 ? (\n <EmptyPanel icon={Workflow} text=\"No recent graph runs\" />\n ) : (\n <div className=\"space-y-1\">\n {mcpRuns.map((run: any) => (\n <ExecutionRow\n key={run.workflow_id}\n dot={statusDotClass(run.status)}\n pill={<WorkflowPill type={run.entity || run.workflow_name || 'pipeline'} variant=\"pipeline\" size=\"xs\" />}\n id={run.workflow_id}\n date={run.updated_at ?? run.created_at}\n onClick={() => navigate(`/mcp/executions/${run.workflow_id}?namespace=${pipelineNs}`)}\n />\n ))}\n </div>\n )}\n </div>\n );\n\n // ── Operator: their own lanes as Task Queue cards, nothing else. Scoped to\n // the roles they belong to; no firehose, no Pace Board, no workflows.\n if (persona.showTaskQueueCards) {\n return (\n <div>\n <h1 className=\"text-3xl font-light text-text-primary mb-10\">Recent Activity</h1>\n <TaskQueueCards maxRows={2} />\n </div>\n );\n }\n\n // ── Builder home (admin, engineer, superadmin): the All/My firehose, plus the\n // Pace Board (admin/superadmin) and the workflow columns (engineer/\n // superadmin). Engineers see everything here except the Pace Board.\n return (\n <div>\n <h1 className=\"text-3xl font-light text-text-primary mb-10\">Recent Activity</h1>\n\n {/* ── Row 1: All Escalations | My Escalations ──────────────────────── */}\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-x-14 min-h-[35vh]\">\n\n {/* Col 1: All Escalations */}\n <div>\n <SectionHeader icon={Inbox} color=\"text-accent\" count={allEscTotal} docsHash=\"#docs:dashboard.md:all-escalations\" actions={\n <div className=\"flex items-center gap-2\">\n <ListToolbar onRefresh={() => allEscQ.refetch()} isFetching={allEscQ.isFetching} apiPath=\"/escalations?status=pending&limit=5&sort_by=created_at&order=desc\" />\n <NavIcon to=\"/escalations/available\" icon={ExternalLink} title=\"All escalations\" />\n </div>\n }>\n All Escalations\n </SectionHeader>\n {allEscalations.length === 0 ? (\n <EmptyPanel icon={Inbox} text=\"No pending escalations\" />\n ) : (\n <div className=\"space-y-1\">\n {allEscalations.map((esc: any) => (\n <button\n key={esc.id}\n onClick={() => navigate(`/escalations/detail/${esc.id}`)}\n className=\"w-full text-left hover:bg-surface-hover/50 rounded-md px-1 py-1.5 transition-colors\"\n >\n <div className=\"flex items-center gap-2 mb-0.5\">\n <span className=\"text-[9px] text-text-quaternary font-medium shrink-0\">P{esc.priority ?? 2}</span>\n <span className=\"text-[12px] text-text-primary truncate flex-1 max-w-[65%]\">{esc.description || esc.subtype || esc.type}</span>\n <span className=\"text-[10px] text-text-quaternary shrink-0 ml-auto\"><DateValue date={esc.updated_at ?? esc.created_at} /></span>\n </div>\n <div className=\"flex items-center gap-2 pl-5\">\n <WorkflowPill type={esc.type || 'unknown'} size=\"xs\" />\n <span className=\"flex-1\" />\n <RolePill role={esc.role} />\n </div>\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Col 2: My Escalations */}\n <div>\n <SectionHeader icon={Inbox} color=\"text-accent\" count={myEscTotal} docsHash=\"#docs:dashboard.md:escalations-overview\" actions={\n <div className=\"flex items-center gap-2\">\n <ListToolbar onRefresh={() => myEscQ.refetch()} isFetching={myEscQ.isFetching} apiPath={`/escalations?assigned_to=${user?.userId ?? ''}&status=pending&limit=5&sort_by=created_at&order=desc`} />\n <NavIcon to=\"/escalations/queue\" icon={ExternalLink} title=\"My escalation queue\" />\n </div>\n }>\n My Escalations\n </SectionHeader>\n {myEscalations.length === 0 ? (\n <EmptyPanel icon={Inbox} text=\"No assigned escalations\" />\n ) : (\n <div className=\"space-y-1\">\n {myEscalations.map((esc: any) => (\n <button\n key={esc.id}\n onClick={() => navigate(`/escalations/detail/${esc.id}`)}\n className=\"w-full text-left hover:bg-surface-hover/50 rounded-md px-1 py-1.5 transition-colors\"\n >\n <div className=\"flex items-center gap-2 mb-0.5\">\n <span className=\"text-[9px] text-text-quaternary font-medium shrink-0\">P{esc.priority ?? 2}</span>\n <span className=\"text-[12px] text-text-primary truncate flex-1 max-w-[65%]\">{esc.description || esc.subtype || esc.type}</span>\n <span className=\"text-[10px] text-text-quaternary shrink-0 ml-auto\"><DateValue date={esc.updated_at ?? esc.created_at} /></span>\n </div>\n <div className=\"flex items-center gap-2 pl-5\">\n <WorkflowPill type={esc.type || 'unknown'} size=\"xs\" />\n <span className=\"flex-1\" />\n <RolePill role={esc.role} />\n </div>\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n\n {/* ── Row 2: Pace Board (admin/superadmin) | Procedural | Graph (builders).\n Engineers get the workflow columns but no Pace Board; admins get the\n Pace Board full-width. */}\n {(persona.canSeePaceBoard || persona.canSeeWorkflows) && (\n <div className={`grid grid-cols-1 ${row2GridClass} gap-x-14 mt-14`}>\n\n {/* Pace Board — the story being told, at a glance */}\n {persona.canSeePaceBoard && (\n <div>\n <SectionHeader icon={LayoutDashboard} color=\"text-accent\" docsHash=\"#docs:dashboard.md:pace-board\" actions={\n <NavIcon to=\"/operations\" icon={ExternalLink} title=\"Open the Pace Board\" />\n }>\n Pace Board\n </SectionHeader>\n {paceStations.length === 0 ? (\n <EmptyPanel icon={LayoutDashboard} text=\"No stations yet — mark roles visible in Operations\" />\n ) : (\n <div className={`${isBuilder ? 'h-64' : 'h-80'} cursor-pointer`} onClick={() => navigate('/operations')}>\n <PaceChart\n stations={paceStations}\n selectedRole={null}\n onSelect={() => navigate('/operations')}\n onUpstreamSelect={() => navigate('/operations')}\n periodHours={1}\n />\n </div>\n )}\n </div>\n )}\n\n {/* Workflow executions — builders (engineer, superadmin) */}\n {persona.canSeeWorkflows && proceduralColumn}\n {persona.canSeeWorkflows && graphColumn}\n </div>\n )}\n </div>\n );\n}\n"],"names":["useMyEscalationCount","user","useAuth","userId","qc","useQueryClient","data","useEscalations","useEventSubscription","NATS_SUBJECT_PREFIX","Stat","n","label","tone","jsxs","jsx","TaskQueueCard","role","title","metric","priorityFacet","periodLabel","navigate","useNavigate","pending","claimed","resolved","jeopardy","e","ExternalLink","jeopardyQueueLink","TriangleAlert","ClaimedCard","count","Hand","PERIODS","TaskQueueCards","maxRows","period","setPeriod","useState","roles","useTaskQueueRoles","claimedCount","metricsQ","useStationMetrics","rolesQ","useRoleDetails","metricByRole","useMemo","_a","m","detailByRole","r","sortedRoles","a","b","ja","jb","_b","laneBudget","shownRoles","overflow","Layers","p","Fragment","STATUS_DOT","statusDotClass","status","SectionHeader","Icon","color","docsHash","children","actions","formatCountCompact","BookOpen","EmptyPanel","text","midEllipsis","maxLen","keep","ExecutionRow","dot","pill","id","date","onClick","DateValue","NavIcon","to","AppPicker","appIds","selected","onSelect","open","setOpen","ref","useRef","useEffect","handler","v","HomePage","isBuilder","useAccess","persona","usePersona","searchParams","setSearchParams","useSearchParams","cpData","useControlPlaneApps","allAppIds","firstAppId","pipelineNs","durableNs","setNs","useCallback","key","ns","prev","next","useEscalationStatsEvents","useWorkflowListEvents","useStationMetricsEvents","builderHome","row2GridClass","stationQ","jobsQ","useJobs","durableAppIds","pipelineAppIds","mcpQ","useMcpRuns","allEscQ","useAvailableEscalations","myEscQ","timer","paceStations","primary","buildFragments","metrics","_c","jobs","jobsTotal","mcpRuns","mcpTotal","_d","allEscalations","_e","allEscTotal","_f","myEscalations","_g","myEscTotal","_h","proceduralColumn","Code2","ListToolbar","job","WorkflowPill","graphColumn","Workflow","run","Inbox","esc","RolePill","LayoutDashboard","PaceChart"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
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-DBXX6TEi.js";import{u as J,c as K,D as M,b as S,J as _,N as U}from"./index-DIgiIoou.js";import{S as $}from"./StatusBadge-CEQMRmSQ.js";import{P as E}from"./PageHeader-Bxa1XFz0.js";import{C as A}from"./CopyableId-uot2mE_g.js";import{C as b}from"./CollapsibleSection-CHWP0WI6.js";import{u as V,E as q}from"./EventTable-DBV1P2ME.js";import{L as B}from"./ListToolbar-KC6LGtKP.js";import{S as F}from"./SwimlaneTimeline-CC5qZjYo.js";import{e as H,f as Q}from"./vendor-react-CXumBFUA.js";import"./vendor-icons-ihWGa7_d.js";import"./FilterBar-B5Vk5tBF.js";import"./StreamMessageDetail-BIXbrZM0.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 oe(){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(B,{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(F,{events:j,outline:!0,jid:a,appId:s||"durable"})}),e.jsx(b,{title:"Events",sectionKey:"events",isCollapsed:p("events"),onToggle:f,children:e.jsx(q,{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{oe as McpRunDetailPage};
|
|
2
|
-
//# sourceMappingURL=McpRunDetailPage-BM3mUSlH.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"McpRunDetailPage-BM3mUSlH.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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"OperationsPage-D37cZ8Qh.js","sources":["../../src/pages/operations/priority-link.ts","../../src/pages/operations/StationDetailPanel.tsx","../../src/pages/operations/OperationsPage.tsx"],"sourcesContent":["import type { RoleDetail } from '../../api/roles';\n\n/**\n * The jeopardy deep link — the plant manager's \"focus on exactly these n items\".\n * One builder for every jeopardy pill (Pace Board chart, Home mini board, the\n * operator's Task Queue cards), producing a URL that reproduces the pill's set\n * precisely:\n *\n * - `jeopardy=1` — the server-side threshold predicate (the SAME expression\n * that produced the pill's count), so the list total equals the pill.\n * - `orderBy` on the role's age origin, ascending — oldest first. The metadata\n * facet when configured, else created_at; the sort control labels the field.\n * - `view=table` — a discrete, countable list, never the timeline.\n */\nexport function jeopardyQueueLink(role: Pick<RoleDetail, 'role' | 'priority_facet'>): string {\n const field = role.priority_facet ? `metadata.${role.priority_facet}` : 'created_at';\n const orderBy = JSON.stringify([{ field, direction: 'asc' }]);\n return `/escalations/available?role=${encodeURIComponent(role.role)}&jeopardy=1&view=table&orderBy=${encodeURIComponent(orderBy)}`;\n}\n","import { useState } from 'react';\nimport { Link } from 'react-router-dom';\nimport { X, ExternalLink, Settings, List } from 'lucide-react';\nimport { useStationMetrics } from '../../api/escalations';\nimport type { StationMetric } from '../../api/escalations';\nimport type { RoleDetail } from '../../api/roles';\nimport { PRIORITY_TEXT_COLOR } from './PaceChart';\nimport { jeopardyQueueLink } from './priority-link';\nimport { displayRoleTitle } from '../../lib/role-display';\n\ninterface StationDetailPanelProps {\n role: RoleDetail | null;\n allMetrics: StationMetric[];\n orderedRoles: RoleDetail[];\n globalPeriod: string;\n onClose: () => void;\n}\n\n// Mirrors OperationsPage's selector — the panel reports the same windows the\n// chart can show, and opens on whichever one the chart has selected.\nconst PERIODS = ['15m', '1h', '24h', '7d', '30d'] as const;\ntype Period = (typeof PERIODS)[number];\n\nconst isPeriod = (p: string): p is Period => (PERIODS as readonly string[]).includes(p);\n\nfunction fmt(min: number | null): string {\n if (min == null) return '—';\n if (min < 1) {\n const s = Math.round(min * 60);\n return s <= 0 ? '< 1s' : `${s}s`;\n }\n if (min < 60) return `${min.toFixed(0)}m`;\n return `${(min / 60).toFixed(1)}h`;\n}\n\nfunction MetricRow({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"flex items-center justify-between py-1.5\">\n <span className=\"text-[10px] text-text-tertiary uppercase tracking-wider\">{label}</span>\n <span className=\"text-xs font-mono font-medium text-text-primary tabular-nums\">{value}</span>\n </div>\n );\n}\n\nfunction PeriodSelector({ period, onChange }: { period: Period; onChange: (p: Period) => void }) {\n return (\n <div className=\"flex items-center gap-1 mb-4\">\n {PERIODS.map((p) => (\n <button\n key={p}\n onClick={() => onChange(p)}\n className={`px-2 py-0.5 text-[10px] font-mono rounded transition-colors ${\n period === p\n ? 'bg-accent/10 text-accent font-semibold'\n : 'text-text-quaternary hover:text-text-secondary'\n }`}\n >\n {p}\n </button>\n ))}\n </div>\n );\n}\n\nfunction RoleView({ role, globalPeriod, onClose }: { role: RoleDetail; globalPeriod: string; onClose: () => void }) {\n // Open on the chart's selected window so the panel's numbers agree with the\n // chart beside it; the local selector still lets the viewer drill around.\n const [period, setPeriod] = useState<Period>(isPeriod(globalPeriod) ? globalPeriod : '24h');\n const { data } = useStationMetrics(period);\n const metric = data?.stations.find((s) => s.role === role.role);\n const slaMinutes = role.sla_minutes ?? undefined;\n const targetPerHour = role.target_per_hour ?? undefined;\n const workerCount = role.worker_count ?? undefined;\n\n return (\n <>\n {/* Header */}\n <div className=\"flex items-start justify-between mb-4\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-baseline gap-1.5 flex-wrap\">\n <span className=\"text-sm font-bold text-text-primary\">{displayRoleTitle(role)}</span>\n <span className=\"text-[10px] font-mono text-text-secondary\">{role.role}</span>\n </div>\n {role.description && (\n <p className=\"text-[10px] text-text-tertiary mt-1 line-clamp-2 leading-relaxed\">\n {role.description}\n </p>\n )}\n </div>\n <button\n onClick={onClose}\n className=\"text-text-quaternary hover:text-text-secondary transition-colors mt-0.5 shrink-0 ml-2\"\n >\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n\n <div className=\"flex items-center gap-3 mb-6\">\n <Link\n to={`/admin/roles/${encodeURIComponent(role.role)}`}\n className=\"flex items-center gap-1 text-[10px] text-accent hover:underline\"\n >\n <Settings className=\"w-2.5 h-2.5\" />\n Edit in Roles\n </Link>\n <Link\n to={`/escalations/available?role=${encodeURIComponent(role.role)}`}\n className=\"flex items-center gap-1 text-[10px] text-accent hover:underline\"\n >\n <List className=\"w-2.5 h-2.5\" />\n View full queue\n </Link>\n </div>\n\n <PeriodSelector period={period} onChange={setPeriod} />\n\n {/* Capacity settings */}\n {(targetPerHour || slaMinutes || workerCount) && (\n <div className=\"flex items-center gap-6 mb-6 text-[10px] border-b border-surface-border/30 pb-5\">\n {targetPerHour && (\n <div>\n <div className=\"font-mono font-semibold text-text-primary text-sm\">{targetPerHour}/h</div>\n <div className=\"text-text-quaternary uppercase tracking-wider text-[8.5px] mt-0.5\">target</div>\n </div>\n )}\n {slaMinutes && (\n <div>\n <div className=\"font-mono font-semibold text-text-primary text-sm\">{slaMinutes}m</div>\n <div className=\"text-text-quaternary uppercase tracking-wider text-[8.5px] mt-0.5\">SLA</div>\n </div>\n )}\n {workerCount && (\n <div>\n <div className=\"font-mono font-semibold text-text-primary text-sm\">{workerCount}</div>\n <div className=\"text-text-quaternary uppercase tracking-wider text-[8.5px] mt-0.5\">workers</div>\n </div>\n )}\n </div>\n )}\n\n {/* Two-column wait / work grid */}\n <div className=\"grid grid-cols-2 gap-x-4 mb-2\">\n <div>\n <p className=\"text-[9px] text-text-quaternary uppercase tracking-wider mb-2\">Wait (queue)</p>\n <MetricRow label=\"P99\" value={fmt(metric?.wait.p99 ?? null)} />\n <MetricRow label=\"avg\" value={fmt(metric?.wait.avg ?? null)} />\n </div>\n <div>\n <p className=\"text-[9px] text-text-quaternary uppercase tracking-wider mb-2\">Work (proc.)</p>\n <MetricRow label=\"P99\" value={fmt(metric?.work.p99 ?? null)} />\n <MetricRow label=\"avg\" value={fmt(metric?.work.avg ?? null)} />\n </div>\n </div>\n\n {/* SLA + priority */}\n <div className=\"border-t border-surface-border/40 pt-4 mt-5 space-y-2.5\">\n {slaMinutes && (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-[10px] text-text-tertiary\">SLA target</span>\n <span className=\"text-xs font-mono text-text-secondary\">{slaMinutes}m</span>\n </div>\n )}\n {metric && metric.priority_count > 0 && (\n <Link\n to={jeopardyQueueLink(role)}\n className=\"flex items-center justify-between group\"\n >\n <span className=\"text-[10px]\" style={{ color: PRIORITY_TEXT_COLOR }}>\n {metric.priority_count} in jeopardy — pull oldest first\n </span>\n <ExternalLink className=\"w-3 h-3 transition-colors\" style={{ color: PRIORITY_TEXT_COLOR }} />\n </Link>\n )}\n </div>\n\n </>\n );\n}\n\nfunction OverviewPanel({\n allMetrics,\n orderedRoles,\n period,\n}: {\n allMetrics: StationMetric[];\n orderedRoles: RoleDetail[];\n period: string;\n}) {\n const totalPending = allMetrics.reduce((s, m) => s + m.pending, 0);\n const totalResolved = allMetrics.reduce((s, m) => s + m.resolved, 0);\n const totalPriority = allMetrics.reduce((s, m) => s + m.priority_count, 0);\n\n const metricByRole = new Map(allMetrics.map((m) => [m.role, m]));\n const stationsAtRisk = allMetrics.filter((m) => m.priority_count > 0).length;\n const stationsWithLoad = allMetrics.filter((m) => m.pending > 0).length;\n\n return (\n <>\n <p className=\"text-[9px] text-text-quaternary uppercase tracking-wider mb-3\">\n Pipeline · {period}\n </p>\n\n {/* Health headline */}\n <div className=\"mb-4\">\n {stationsAtRisk > 0 ? (\n <p className=\"text-[11px]\" style={{ color: PRIORITY_TEXT_COLOR }}>\n {stationsAtRisk} station{stationsAtRisk > 1 ? 's' : ''} with items in jeopardy\n </p>\n ) : stationsWithLoad > 0 ? (\n <p className=\"text-[11px] text-status-warning\">\n {stationsWithLoad} station{stationsWithLoad > 1 ? 's' : ''} with backlog\n </p>\n ) : totalResolved > 0 ? (\n <p className=\"text-[11px] text-status-success\">Flowing — queue clear</p>\n ) : (\n <p className=\"text-[11px] text-text-quaternary\">Quiet — awaiting work</p>\n )}\n </div>\n\n {/* Key counters */}\n <div className=\"space-y-1.5 mb-4\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-[9px] text-text-quaternary uppercase tracking-wider\">Pending</span>\n <span className={`text-xs font-mono tabular-nums ${totalPending > 0 ? 'text-text-primary font-semibold' : 'text-text-quaternary'}`}>\n {totalPending}\n </span>\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-[9px] text-text-quaternary uppercase tracking-wider\">Resolved · {period}</span>\n <span className=\"text-xs font-mono tabular-nums text-text-secondary\">{totalResolved}</span>\n </div>\n {totalPriority > 0 && (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-[9px] text-text-quaternary uppercase tracking-wider\">Priority</span>\n <span className=\"text-xs font-mono tabular-nums font-semibold\" style={{ color: PRIORITY_TEXT_COLOR }}>\n {totalPriority}\n </span>\n </div>\n )}\n </div>\n\n {/* Divider + column headers */}\n <div className=\"border-t border-surface-border/40 pt-2 mb-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-[8px] text-text-quaternary uppercase tracking-wider flex-1\">Station</span>\n <span className=\"text-[8px] text-text-quaternary uppercase tracking-wider w-8 text-right shrink-0\">pend</span>\n <span className=\"text-[8px] text-text-quaternary uppercase tracking-wider w-8 text-right shrink-0\">clmd</span>\n <span className=\"text-[8px] text-text-quaternary uppercase tracking-wider w-8 text-right shrink-0\">res</span>\n </div>\n </div>\n\n {/* Station list in pipeline order */}\n <div className=\"space-y-0.5\">\n {orderedRoles.map((r) => {\n const m = metricByRole.get(r.role);\n const pending = m?.pending ?? 0;\n const claimed = m?.claimed ?? 0;\n const resolved = m?.resolved ?? 0;\n const priorityCount = m?.priority_count ?? 0;\n const label = r.title || r.role;\n const hasAlert = priorityCount > 0;\n const hasLoad = pending > 0;\n\n return (\n <div key={r.role} className=\"flex items-center gap-2 py-0.5\">\n <span\n className={`text-[10px] font-mono flex-1 truncate ${\n hasLoad ? 'text-text-primary' : 'text-text-quaternary'\n }`}\n >\n {label}\n {hasAlert && (\n <span className=\"ml-1 text-[8px] font-semibold\" style={{ color: PRIORITY_TEXT_COLOR }}>\n {priorityCount} PRIORITY\n </span>\n )}\n </span>\n <span\n className={`text-[10px] font-mono tabular-nums w-8 text-right shrink-0 ${\n hasLoad ? 'text-text-primary font-semibold' : 'text-text-quaternary'\n }`}\n >\n {pending > 0 ? pending : '—'}\n </span>\n <span className={`text-[10px] font-mono tabular-nums w-8 text-right shrink-0 ${claimed > 0 ? 'text-accent font-semibold' : 'text-text-quaternary'}`}>\n {claimed > 0 ? claimed : '—'}\n </span>\n <span className={`text-[10px] font-mono tabular-nums w-8 text-right shrink-0 ${resolved > 0 ? 'text-text-secondary' : 'text-text-quaternary'}`}>\n {resolved > 0 ? resolved : '—'}\n </span>\n </div>\n );\n })}\n </div>\n\n <p className=\"text-[9px] text-text-quaternary mt-5\">\n Select a station for queue detail.\n </p>\n </>\n );\n}\n\nexport function StationDetailPanel({\n role,\n allMetrics,\n orderedRoles,\n globalPeriod,\n onClose,\n}: StationDetailPanelProps) {\n return (\n <div className=\"w-[280px] shrink-0 px-7 py-10 flex flex-col overflow-y-auto min-h-0\">\n {role ? (\n <RoleView role={role} globalPeriod={globalPeriod} onClose={onClose} />\n ) : (\n <OverviewPanel allMetrics={allMetrics} orderedRoles={orderedRoles} period={globalPeriod} />\n )}\n </div>\n );\n}\n","import { useState, useEffect, useMemo, useCallback, useRef } from 'react';\nimport { Link, useNavigate, useSearchParams } from 'react-router-dom';\nimport { GitMerge, RefreshCw, Eye, TriangleAlert, ChevronDown } from 'lucide-react';\nimport { useRoleDetails, useUpdateRole, type RoleDetail } from '../../api/roles';\nimport { useStationMetrics } from '../../api/escalations';\nimport type { StationMetric } from '../../api/escalations';\nimport { useStationMetricsEvents } from '../../hooks/useEventHooks';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport {\n PaceChart,\n ACTIVE_COLOR,\n QUEUED_COLOR,\n RESOLVED_COLOR,\n TARGET_COLOR,\n PRIORITY_TEXT_COLOR,\n type ChartStation,\n} from './PaceChart';\nimport { StationDetailPanel } from './StationDetailPanel';\nimport { jeopardyQueueLink } from './priority-link';\nimport { displayRoleTitle } from '../../lib/role-display';\n\n// Column band tints — same hues as the chart bands (~8% alpha).\n// Semantic palette: pending=sky, claimed=orange, resolved=green, target=slate, sla=amber.\nconst SLA_COLOR = TARGET_COLOR;\nconst TARGET_BAND = `${TARGET_COLOR}18`;\nconst SLA_BAND = `${TARGET_COLOR}18`;\nconst PENDING_BAND = `${QUEUED_COLOR}14`;\nconst ACTIVE_BAND = `${ACTIVE_COLOR}14`;\nconst RESOLVED_BAND = `${RESOLVED_COLOR}14`;\n\n// Station table grid. The 5 colored columns are grouped into a single auto\n// cell rendered as a flex row with no internal gap so they touch each other.\nconst STATION_GRID_COLS = 'minmax(120px, 1.1fr) minmax(100px, 0.9fr) auto 72px 72px 104px 36px';\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nconst PERIODS = ['15m', '1h', '24h', '7d', '30d'] as const;\ntype Period = (typeof PERIODS)[number];\n\n// Window length in hours — used to express the target as a count for the\n// selected window (target_per_hour × hours), e.g. 22/h over 15m ≈ 5 expected.\nconst PERIOD_HOURS: Record<Period, number> = {\n '15m': 0.25,\n '1h': 1,\n '24h': 24,\n '7d': 168,\n '30d': 720,\n};\n\ninterface OrderedStation {\n role: RoleDetail;\n depth: number;\n}\n\n/**\n * One sequence of stations, named by its origin role. Execution is a graph;\n * each fragment is the human-readable line the user composed via parent_role.\n * Cross-fragment edges live in upstream_roles and render as a merge affordance\n * on the chart, never as a bend in the line.\n */\ninterface SequenceFragment {\n origin: RoleDetail;\n stations: OrderedStation[];\n}\n\n// ── Fragment builder — BFS per parent_role root, tracking actual depth ────────\n\nexport function buildFragments(roles: RoleDetail[]): SequenceFragment[] {\n const opsRoles = roles.filter((r) => r.ops_visible);\n const roleMap = new Map(opsRoles.map((r) => [r.role, r]));\n const visited = new Set<string>();\n\n // Roots: no parent, or parent not in ops set — each roots its own fragment.\n const roots = opsRoles.filter((r) => !r.parent_role || !roleMap.has(r.parent_role));\n\n const fragments: SequenceFragment[] = roots.map((root) => {\n const stations: OrderedStation[] = [];\n const queue: OrderedStation[] = [{ role: root, depth: 0 }];\n while (queue.length > 0) {\n const item = queue.shift()!;\n if (visited.has(item.role.role)) continue;\n visited.add(item.role.role);\n stations.push(item);\n opsRoles\n .filter((c) => c.parent_role === item.role.role && !visited.has(c.role))\n .forEach((c) => queue.push({ role: c, depth: item.depth + 1 }));\n }\n return { origin: root, stations };\n });\n\n // Unreachable (cycles / dangling) — each stands alone rather than vanishing.\n opsRoles\n .filter((r) => !visited.has(r.role))\n .forEach((r) => fragments.push({ origin: r, stations: [{ role: r, depth: 0 }] }));\n\n // Longest line first — the primary sequence leads; side-quests follow.\n return fragments.sort(\n (a, b) => b.stations.length - a.stations.length || a.origin.role.localeCompare(b.origin.role),\n );\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction fmtMin(v: number | null): string {\n if (v == null) return '—';\n if (v < 1) {\n const s = Math.round(v * 60);\n return s <= 0 ? '< 1s' : `${s}s`;\n }\n if (v < 60) return `${v.toFixed(0)}m`;\n return `${(v / 60).toFixed(1)}h`;\n}\n\nfunction loadBar(pending: number, target: number | null) {\n // No target, or nothing pending — there is no live load to trend. Show the\n // empty state rather than inventing a rate from historical throughput.\n if (!target || pending === 0) return { pct: null, color: 'bg-surface-border' };\n\n const ratio = pending / target;\n const pct = Math.round(ratio * 100);\n // Amber: backlog. Orange: some work but well under pace. Green: healthy.\n const color = ratio > 1.0 ? 'bg-status-warning' : ratio < 0.2 ? 'bg-status-draft' : 'bg-status-success';\n return { pct, color };\n}\n\n// ── Editable numeric cell ─────────────────────────────────────────────────────\n\nfunction EditableNumber({ value, onSave }: { value: number | null; onSave: (n: number | null) => void }) {\n const [local, setLocal] = useState(value != null ? String(value) : '');\n const timer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n const commit = (val: string) => {\n const n = parseInt(val, 10);\n onSave(!val.trim() || isNaN(n) || n < 0 ? null : n);\n };\n\n return (\n <input\n type=\"number\"\n min={0}\n step={1}\n value={local}\n onChange={(e) => {\n const val = e.target.value;\n setLocal(val);\n clearTimeout(timer.current);\n timer.current = setTimeout(() => commit(val), 400);\n }}\n onBlur={(e) => { clearTimeout(timer.current); commit(e.target.value); }}\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n className=\"w-full bg-transparent text-xs font-mono tabular-nums text-right focus:outline-none\"\n />\n );\n}\n\n// ── Station table row ─────────────────────────────────────────────────────────\n\nfunction StationRow({\n role,\n metric,\n selected,\n onClick,\n}: {\n role: RoleDetail;\n metric: StationMetric | undefined;\n selected: boolean;\n onClick: () => void;\n}) {\n const updateRole = useUpdateRole();\n const pending = metric?.pending ?? 0;\n const claimed = metric?.claimed ?? 0;\n const resolved = metric?.resolved ?? 0;\n const priorityCount = metric?.priority_count ?? 0;\n const target = role.target_per_hour ?? null;\n const { pct, color } = loadBar(pending, target);\n const barWidth = pct != null ? Math.min(100, pct) : 0;\n\n const saveTarget = (n: number | null) => updateRole.mutate({ role: role.role, target_per_hour: n });\n const saveSla = (n: number | null) => updateRole.mutate({ role: role.role, sla_minutes: n });\n\n return (\n <>\n <div\n role=\"button\"\n tabIndex={0}\n onClick={onClick}\n onKeyDown={(e) => { if (e.key === 'Enter') onClick(); }}\n className={`grid items-center gap-4 pr-3 cursor-pointer transition-colors ${\n selected ? 'border-l-2 !border-l-accent pl-2.5' : 'pl-3'\n }`}\n style={{ gridTemplateColumns: STATION_GRID_COLS }}\n >\n {/* Name — user-set title, or derived from the role id */}\n <div className=\"flex items-center gap-1.5 min-w-0 py-1.5\">\n <span className=\"font-bold text-text-primary truncate text-xs\">\n {displayRoleTitle(role)}\n </span>\n {(role.upstream_roles?.length ?? 0) > 0 && (\n <span title={`Fed by ${role.upstream_roles.join(', ')}`} className=\"shrink-0 leading-none\">\n <GitMerge className=\"w-3 h-3 text-text-quaternary\" />\n </span>\n )}\n </div>\n\n {/* Role id */}\n <span className=\"font-mono text-[11px] text-text-tertiary truncate py-1.5\">\n {role.role}\n </span>\n\n {/* ── 5 colored columns in one touching flex group ── */}\n <div className=\"self-stretch flex items-stretch\">\n {/* Target/h — editable, slate band */}\n <div className=\"w-16 shrink-0 flex items-center justify-end px-1.5\" style={{ backgroundColor: TARGET_BAND }}>\n <EditableNumber value={role.target_per_hour ?? null} onSave={saveTarget} />\n </div>\n {/* SLA/m — editable, amber band */}\n <div className=\"w-16 shrink-0 flex items-center justify-end px-1.5\" style={{ backgroundColor: SLA_BAND }}>\n <EditableNumber value={role.sla_minutes ?? null} onSave={saveSla} />\n </div>\n {/* Pending — sky band */}\n <div className=\"w-16 shrink-0 flex items-center justify-end px-3\" style={{ backgroundColor: PENDING_BAND }}>\n <Link\n to={`/escalations/available?role=${encodeURIComponent(role.role)}&status=available`}\n className={`text-xs font-mono tabular-nums hover:underline ${\n pending > 0 ? 'text-text-primary font-semibold' : 'text-text-quaternary'\n }`}\n onClick={(e) => e.stopPropagation()}\n >\n {pending}\n </Link>\n </div>\n {/* Claimed — orange band */}\n <div className=\"w-16 shrink-0 flex items-center justify-end px-3\" style={{ backgroundColor: ACTIVE_BAND }}>\n <Link\n to={`/escalations/available?role=${encodeURIComponent(role.role)}&status=claimed`}\n className={`text-xs font-mono tabular-nums hover:underline ${\n claimed > 0 ? 'font-semibold' : 'text-text-quaternary'\n }`}\n style={claimed > 0 ? { color: ACTIVE_COLOR } : undefined}\n onClick={(e) => e.stopPropagation()}\n >\n {claimed}\n </Link>\n </div>\n {/* Resolved — green band */}\n <div className=\"w-16 shrink-0 flex items-center justify-end px-3\" style={{ backgroundColor: RESOLVED_BAND }}>\n <Link\n to={`/escalations/available?role=${encodeURIComponent(role.role)}&status=resolved`}\n className={`text-xs font-mono tabular-nums hover:underline ${\n resolved > 0 ? 'text-text-secondary' : 'text-text-quaternary'\n }`}\n style={resolved > 0 ? { color: RESOLVED_COLOR } : undefined}\n onClick={(e) => e.stopPropagation()}\n >\n {resolved}\n </Link>\n </div>\n </div>\n\n {/* P99 wait */}\n <span className=\"text-xs font-mono tabular-nums text-right py-1.5 text-text-secondary\">\n {fmtMin(metric?.wait.p99 ?? null)}\n </span>\n\n {/* P99 work */}\n <span className=\"text-xs font-mono tabular-nums text-right py-1.5 text-text-secondary\">\n {fmtMin(metric?.work.p99 ?? null)}\n </span>\n\n {/* Load mini-bar */}\n <div className=\"flex items-center gap-2 py-1.5\">\n <div className=\"w-12 h-1.5 bg-surface-sunken rounded-full overflow-hidden shrink-0\">\n <div className={`h-full rounded-full ${color}`} style={{ width: `${barWidth}%` }} />\n </div>\n <span\n className={`text-[10px] font-mono tabular-nums ${\n pct != null && pct > 100\n ? 'text-status-warning font-semibold'\n : 'text-text-quaternary'\n }`}\n >\n {pct != null ? `${pct}%` : '—'}\n </span>\n </div>\n\n {/* Actions — jeopardy first (the hard-limit alarm, hover names the\n count, click opens the exact counted set oldest-first), then the\n full-queue view. */}\n <div className=\"flex items-center justify-center gap-2 py-1.5\">\n {priorityCount > 0 && (\n <Link\n to={jeopardyQueueLink(role)}\n className=\"text-status-error hover:opacity-70 transition-opacity\"\n title={`${priorityCount} item${priorityCount === 1 ? '' : 's'} in jeopardy — pull oldest first`}\n onClick={(e) => e.stopPropagation()}\n >\n <TriangleAlert className=\"w-3.5 h-3.5\" strokeWidth={2} />\n </Link>\n )}\n <Link\n to={`/escalations/available?role=${encodeURIComponent(role.role)}&status=all`}\n className=\"text-text-quaternary hover:text-accent transition-colors\"\n title=\"View all items in queue\"\n onClick={(e) => e.stopPropagation()}\n >\n <Eye className=\"w-3.5 h-3.5\" />\n </Link>\n </div>\n </div>\n </>\n );\n}\n\n// ── Sequence menu ─────────────────────────────────────────────────────────────\n\ninterface SequenceAggregate {\n stations: number;\n pending: number;\n jeopardy: number;\n}\n\n/** Red jeopardy count, capped at 9+ — the same shorthand as the queue pills. */\nfunction JeopardyCount({ n }: { n: number }) {\n if (n <= 0) return null;\n return (\n <span\n className=\"inline-flex items-center gap-0.5 font-semibold tabular-nums\"\n style={{ color: PRIORITY_TEXT_COLOR }}\n title={`${n} in jeopardy`}\n >\n <TriangleAlert className=\"w-3 h-3\" strokeWidth={2.25} />\n {n > 9 ? '9+' : n}\n </span>\n );\n}\n\n/**\n * The segment selector for the 30k-foot view — compact at any segment count.\n * Collapsed, it names the ACTIVE sequence large with its aggregate story\n * (stations · pending · jeopardy) and a caret; expanded, it lists every\n * sequence with the same breakdown so trouble in an unselected segment is\n * visible from here and one click away. Metrics span every visible role, so\n * the numbers are live for all segments, not just the chosen one.\n */\nfunction SequenceMenu({ fragments, aggregates, activeOrigin, onSelect }: {\n fragments: SequenceFragment[];\n aggregates: Map<string, SequenceAggregate>;\n activeOrigin: string | null;\n onSelect: (origin: string) => void;\n}) {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n const onClick = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') setOpen(false); };\n document.addEventListener('mousedown', onClick);\n document.addEventListener('keydown', onKey);\n return () => {\n document.removeEventListener('mousedown', onClick);\n document.removeEventListener('keydown', onKey);\n };\n }, [open]);\n\n const active = fragments.find((f) => f.origin.role === activeOrigin) ?? fragments[0];\n if (!active) return null;\n const agg = aggregates.get(active.origin.role);\n\n return (\n <div ref={ref} className=\"relative px-4 pt-2\">\n <button\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n className=\"group flex items-baseline gap-2.5\"\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n >\n <span className=\"text-sm font-medium text-text-primary group-hover:text-accent transition-colors\">\n {displayRoleTitle(active.origin)}\n </span>\n <span className=\"text-[10px] font-mono text-text-quaternary tabular-nums\">\n {agg?.stations ?? active.stations.length} station{(agg?.stations ?? active.stations.length) === 1 ? '' : 's'} · {agg?.pending ?? 0} pending\n </span>\n <JeopardyCount n={agg?.jeopardy ?? 0} />\n <ChevronDown\n className={`w-3.5 h-3.5 self-center shrink-0 text-text-tertiary group-hover:text-accent transition-transform ${open ? 'rotate-180' : ''}`}\n strokeWidth={1.5}\n />\n </button>\n\n {open && (\n <div\n role=\"listbox\"\n className=\"absolute z-40 top-full left-4 mt-1.5 min-w-[20rem] max-h-80 overflow-y-auto bg-surface-raised border border-surface-border rounded-md shadow-lg py-1\"\n >\n {fragments.map((f) => {\n const a = aggregates.get(f.origin.role);\n const isActive = f.origin.role === active.origin.role;\n return (\n <button\n key={f.origin.role}\n type=\"button\"\n role=\"option\"\n aria-selected={isActive}\n onClick={() => { onSelect(f.origin.role); setOpen(false); }}\n className={`w-full text-left px-3 py-1.5 flex items-baseline gap-2.5 transition-colors ${\n isActive ? 'text-accent bg-accent/5' : 'text-text-primary hover:bg-surface-hover'\n }`}\n >\n <span className=\"text-xs font-medium truncate\">{displayRoleTitle(f.origin)}</span>\n <span className=\"ml-auto text-[10px] font-mono text-text-quaternary tabular-nums shrink-0\">\n {a?.stations ?? f.stations.length} st · {a?.pending ?? 0} pending\n </span>\n {/* Fixed-width, left-aligned jeopardy column: every ⚠ starts at\n the same x, so the icons stack vertically whether the count\n is 1 or 9+. */}\n <span className=\"w-12 shrink-0 text-left text-[10px]\">\n <JeopardyCount n={a?.jeopardy ?? 0} />\n </span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n\n// ── Table header ──────────────────────────────────────────────────────────────\n\nfunction TableHead() {\n const coloredCols = [\n { label: 'TARGET/H', band: TARGET_BAND, hue: TARGET_COLOR, w: 'w-16' },\n { label: 'SLA/M', band: SLA_BAND, hue: SLA_COLOR, w: 'w-16' },\n { label: 'PENDING', band: PENDING_BAND, hue: QUEUED_COLOR, w: 'w-16', px: 'px-3' },\n { label: 'CLAIMED', band: ACTIVE_BAND, hue: ACTIVE_COLOR, w: 'w-16', px: 'px-3' },\n { label: 'RESOLVED', band: RESOLVED_BAND, hue: RESOLVED_COLOR, w: 'w-16', px: 'px-3' },\n ];\n return (\n <div\n className=\"grid items-center gap-4 px-3 border-b border-surface-border mb-0.5\"\n style={{ gridTemplateColumns: STATION_GRID_COLS }}\n >\n <span className=\"text-[9px] font-semibold uppercase tracking-wider text-text-quaternary py-1.5\">NAME</span>\n <span className=\"text-[9px] font-semibold uppercase tracking-wider text-text-quaternary py-1.5\">ROLE</span>\n\n {/* Touching colored column group */}\n <div className=\"self-stretch flex items-stretch\">\n {coloredCols.map((col) => (\n <div\n key={col.label}\n className={`${col.w} shrink-0 flex items-center justify-end ${'px' in col ? col.px : 'px-1.5'}`}\n style={{ backgroundColor: col.band }}\n >\n <span className=\"text-[9px] font-semibold uppercase tracking-wider\" style={{ color: col.hue }}>\n {col.label}\n </span>\n </div>\n ))}\n </div>\n\n <span className=\"text-[9px] font-semibold uppercase tracking-wider text-text-quaternary py-1.5 text-right\">P99 WAIT</span>\n <span className=\"text-[9px] font-semibold uppercase tracking-wider text-text-quaternary py-1.5 text-right\">P99 WORK</span>\n <span className=\"text-[9px] font-semibold uppercase tracking-wider text-text-quaternary py-1.5\">TREND</span>\n <span className=\"text-[9px] font-semibold uppercase tracking-wider text-text-quaternary py-1.5 text-center\">ACTIONS</span>\n </div>\n );\n}\n\n\n// ── Page ──────────────────────────────────────────────────────────────────────\n\nexport function OperationsPage() {\n // 1h default: long enough to show a whole simulation shift's shape,\n // short enough that stale history doesn't drown the current run.\n const [period, setPeriod] = useState<Period>('1h');\n const [selectedRole, setSelectedRole] = useState<string | null>(null);\n const [refreshing, setRefreshing] = useState(false);\n\n // Push-driven refresh: every escalation event invalidates ['stationMetrics']\n // through the central event system (debounced, transport-agnostic). The\n // header's refresh button covers user-initiated reloads.\n useStationMetricsEvents();\n\n const { data: roleData, isLoading: rolesLoading, refetch: refetchRoles } = useRoleDetails();\n const {\n data: metricsData,\n isLoading: metricsLoading,\n refetch: refetchMetrics,\n } = useStationMetrics(period);\n\n const roles = roleData?.roles ?? [];\n const metrics = metricsData?.stations ?? [];\n\n // Per-sequence aggregates for the segment menu — computed over ALL visible\n // roles, so unselected segments report their live pending/jeopardy too.\n const fragmentAggregates = useMemo(() => {\n const metricByRole = new Map(metrics.map((m) => [m.role, m]));\n const out = new Map<string, SequenceAggregate>();\n for (const f of buildFragments(roleData?.roles ?? [])) {\n let pending = 0, jeopardy = 0;\n for (const s of f.stations) {\n const m = metricByRole.get(s.role.role);\n pending += m?.pending ?? 0;\n jeopardy += m?.priority_count ?? 0;\n }\n out.set(f.origin.role, { stations: f.stations.length, pending, jeopardy });\n }\n return out;\n }, [metrics, roleData]);\n\n // Sequence fragments, one per parent_role root. The active one is\n // DEEP-LINKED (?fragment=<origin role>) and each switch is a history entry,\n // so a shared link opens the same sequence and back/forward walks them.\n const fragments = useMemo((): SequenceFragment[] => buildFragments(roles), [roles]);\n const [searchParams, setSearchParams] = useSearchParams();\n const fragmentParam = searchParams.get('fragment');\n const activeFragment =\n fragments.find((f) => f.origin.role === fragmentParam) ?? fragments[0] ?? null;\n const selectFragment = useCallback(\n (origin: string) => {\n setSelectedRole(null);\n setSearchParams((prev) => {\n const p = new URLSearchParams(prev);\n p.set('fragment', origin);\n return p;\n });\n },\n [setSearchParams],\n );\n\n const ordered = activeFragment?.stations ?? [];\n const fragmentRoleSet = useMemo(\n () => new Set(ordered.map(({ role }) => role.role)),\n [ordered],\n );\n const fragmentMetrics = useMemo(\n () => metrics.filter((m) => fragmentRoleSet.has(m.role)),\n [metrics, fragmentRoleSet],\n );\n\n const chartStations = useMemo(\n (): ChartStation[] =>\n ordered.map(({ role: r }) => ({\n role: r.role,\n title: r.title,\n parent_role: r.parent_role,\n target_per_hour: r.target_per_hour ?? null,\n upstream_roles: r.upstream_roles ?? [],\n metric: metrics.find((m) => m.role === r.role),\n })),\n [ordered, metrics],\n );\n\n // Jump to the sequence that feeds this station — the merge glyph's click.\n const handleUpstreamSelect = useCallback(\n (upstreamRole: string) => {\n const target = fragments.find((f) =>\n f.stations.some(({ role }) => role.role === upstreamRole),\n );\n if (target) selectFragment(target.origin.role);\n },\n [fragments, selectFragment],\n );\n\n const navigate = useNavigate();\n\n const selectedRoleDetail =\n ordered.find(({ role }) => role.role === selectedRole)?.role ?? null;\n\n const isLoading = rolesLoading || metricsLoading;\n\n const handleRefresh = async () => {\n setRefreshing(true);\n await Promise.all([refetchRoles(), refetchMetrics()]);\n setRefreshing(false);\n };\n\n const handleSelect = (role: string) =>\n setSelectedRole((prev) => (prev === role ? null : role));\n\n const periodSelector = (\n <div className=\"flex items-center gap-0.5\">\n {PERIODS.map((p) => (\n <button\n key={p}\n onClick={() => setPeriod(p)}\n className={`px-2.5 py-1 text-[10px] font-mono rounded transition-colors ${\n period === p\n ? 'bg-accent/10 text-accent font-semibold'\n : 'text-text-quaternary hover:text-text-secondary'\n }`}\n >\n {p}\n </button>\n ))}\n </div>\n );\n\n return (\n <div className=\"flex flex-col flex-1 min-h-0\">\n <PageHeader\n title=\"Pace Board\"\n docsHash=\"#docs:dashboard.md:pace-board\"\n center={periodSelector}\n actions={\n <button\n onClick={handleRefresh}\n disabled={refreshing}\n className=\"text-text-quaternary hover:text-text-secondary transition-colors disabled:opacity-40\"\n >\n <RefreshCw className={`w-3.5 h-3.5 ${refreshing ? 'animate-spin' : ''}`} />\n </button>\n }\n />\n\n {isLoading ? (\n <div className=\"animate-pulse space-y-6 mt-4\">\n <div className=\"h-8 bg-surface-sunken rounded w-64\" />\n <div className=\"h-64 bg-surface-sunken rounded w-full\" />\n <div className=\"space-y-3\">\n {[1, 2, 3].map((i) => (\n <div key={i} className=\"h-8 bg-surface-sunken rounded w-full\" />\n ))}\n </div>\n </div>\n ) : fragments.length === 0 ? (\n <div className=\"mt-8\">\n <p className=\"text-sm text-text-secondary mb-2\">Stations appear here once roles are marked visible in Operations.</p>\n <p className=\"text-xs text-text-tertiary\">\n Go to{' '}\n <Link to=\"/admin/roles\" className=\"text-accent hover:underline\">\n Roles\n </Link>{' '}\n and enable <strong>Visible in Operations</strong> on roles that represent pipeline\n stations.\n </p>\n </div>\n ) : (\n /* Console layout: fixed header (above) → chart row (min 40vh) → table row (max 30vh) */\n <div className=\"flex flex-col flex-1 min-h-0\">\n\n {/* Sequence menu — the active segment named large with its aggregate\n story; the caret opens the full segment list. Compact at any\n segment count. Only rendered when there is more than one story\n to tell. */}\n {fragments.length > 1 && (\n <SequenceMenu\n fragments={fragments}\n aggregates={fragmentAggregates}\n activeOrigin={activeFragment?.origin.role ?? null}\n onSelect={selectFragment}\n />\n )}\n\n {/* Middle row: flexible, never below 40vh — SVG fills left, sidebar fixed-width right */}\n <div className=\"flex-1 min-h-[40vh] flex items-stretch overflow-hidden\">\n {/* SVG chart — scales to fill available space */}\n <div className=\"flex-1 min-w-0 min-h-0 flex flex-col justify-center overflow-hidden p-4\">\n <PaceChart\n stations={chartStations}\n selectedRole={selectedRole}\n onSelect={handleSelect}\n onUpstreamSelect={handleUpstreamSelect}\n onCmdClick={(role) => navigate(`/escalations/available?role=${encodeURIComponent(role)}`)}\n periodHours={PERIOD_HOURS[period]}\n />\n </div>\n {/* Vertical divider */}\n <div className=\"w-px bg-surface-border shrink-0 self-stretch\" />\n {/* Right sidebar — fixed width, scrolls its own content */}\n <StationDetailPanel\n role={selectedRoleDetail}\n allMetrics={fragmentMetrics}\n orderedRoles={ordered.map((o) => o.role)}\n globalPeriod={period}\n onClose={() => setSelectedRole(null)}\n />\n </div>\n\n {/* Bottom row: sized to its rows up to 30vh — header sticky, rows scroll */}\n <div className=\"max-h-[30vh] flex-none flex flex-col border-t border-surface-border overflow-hidden\">\n <TableHead />\n <div className=\"flex-1 min-h-0 overflow-y-auto divide-y divide-surface-border/30\">\n {ordered.map(({ role }) => (\n <StationRow\n key={role.role}\n role={role}\n metric={metrics.find((m) => m.role === role.role)}\n selected={selectedRole === role.role}\n onClick={() => handleSelect(role.role)}\n />\n ))}\n </div>\n </div>\n\n </div>\n )}\n </div>\n );\n}\n"],"names":["jeopardyQueueLink","role","field","orderBy","PERIODS","isPeriod","p","fmt","min","s","MetricRow","label","value","jsxs","jsx","PeriodSelector","period","onChange","RoleView","globalPeriod","onClose","setPeriod","useState","data","useStationMetrics","metric","slaMinutes","targetPerHour","workerCount","Fragment","displayRoleTitle","X","Link","Settings","List","PRIORITY_TEXT_COLOR","ExternalLink","OverviewPanel","allMetrics","orderedRoles","totalPending","m","totalResolved","totalPriority","metricByRole","stationsAtRisk","stationsWithLoad","r","pending","claimed","resolved","priorityCount","hasAlert","hasLoad","StationDetailPanel","SLA_COLOR","TARGET_COLOR","TARGET_BAND","SLA_BAND","PENDING_BAND","QUEUED_COLOR","ACTIVE_BAND","ACTIVE_COLOR","RESOLVED_BAND","RESOLVED_COLOR","STATION_GRID_COLS","PERIOD_HOURS","buildFragments","roles","opsRoles","roleMap","visited","fragments","root","stations","queue","item","c","a","b","fmtMin","v","loadBar","target","ratio","pct","color","EditableNumber","onSave","local","setLocal","timer","useRef","commit","val","n","e","StationRow","selected","onClick","updateRole","useUpdateRole","barWidth","saveTarget","saveSla","_a","GitMerge","TriangleAlert","Eye","JeopardyCount","SequenceMenu","aggregates","activeOrigin","onSelect","open","setOpen","ref","useEffect","onKey","active","f","agg","ChevronDown","isActive","TableHead","coloredCols","col","OperationsPage","selectedRole","setSelectedRole","refreshing","setRefreshing","useStationMetricsEvents","roleData","rolesLoading","refetchRoles","useRoleDetails","metricsData","metricsLoading","refetchMetrics","metrics","fragmentAggregates","useMemo","out","jeopardy","searchParams","setSearchParams","useSearchParams","fragmentParam","activeFragment","selectFragment","useCallback","origin","prev","ordered","fragmentRoleSet","fragmentMetrics","chartStations","handleUpstreamSelect","upstreamRole","navigate","useNavigate","selectedRoleDetail","isLoading","handleRefresh","handleSelect","periodSelector","PageHeader","RefreshCw","i","PaceChart"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{j as s}from"./vendor-query-B2UbickB.js";import{o as v,T as C,H as L,K as R,k as T}from"./index-DIgiIoou.js";import{f as k}from"./useEventHooks-DV9pLDOW.js";import{u as F}from"./useFilterParams-x-Dg0Vgz.js";import{u as N}from"./useDebouncedValue-BA5S7V54.js";import{b as _}from"./api-path-u2Jf9QXS.js";import{D as z}from"./DataTable-Byn3oyT9.js";import{P as A}from"./PageHeader-Bxa1XFz0.js";import{S as w}from"./StickyPagination-Cd83AHd_.js";import{R as M,a as O}from"./RowActions-BA9L9djf.js";import{E as I,T as U,a as q}from"./escalation-columns-BbS5X61l.js";import{L as D}from"./ListToolbar-KC6LGtKP.js";import{aj as H}from"./vendor-icons-ihWGa7_d.js";import{c as $}from"./vendor-react-CXumBFUA.js";import"./EmptyState-BcsfPq9T.js";import"./FilterBar-B5Vk5tBF.js";import"./PriorityBadge-B4ykBH7f.js";import"./RolePill-DLwmVMam.js";import"./WorkflowPill-Fjc2q9U9.js";import"./CountdownTimer-TXsRlTU4.js";function me(){k();const d=$(),{user:i}=v(),{filters:t,setFilter:u,pagination:e,sort:n,setSort:g}=F({filters:{role:"",type:"",priority:"",search:""}}),f=N(t.search,300),x=C(),{data:l}=L(),{data:c}=R(),m={assigned_to:i==null?void 0:i.userId,status:"pending",role:t.role||void 0,type:t.type||void 0,priority:t.priority?parseInt(t.priority):void 0,search:f||void 0,sort_by:n.sort_by||"created_at",order:n.order||"desc"},{data:o,isLoading:y,error:r,refetch:h,isFetching:b}=T({...m,limit:e.pageSize,offset:e.offset}),S=(o==null?void 0:o.escalations)??[],p=(o==null?void 0:o.total)??0,E=_("/escalations",{...m,limit:e.pageSize,offset:e.offset}),P={key:"actions",label:"",render:a=>s.jsx(M,{children:s.jsx(O,{icon:H,title:"Release escalation",onClick:()=>x.mutate(a.id),colorClass:"text-text-tertiary hover:text-status-warning"})}),className:"w-16 text-right"},j=[U,...q,P];return s.jsxs("div",{children:[s.jsx(A,{title:"My Escalations"}),s.jsx(I,{filters:t,setFilter:u,roles:(l==null?void 0:l.roles)??[],types:(c==null?void 0:c.types)??[],actions:s.jsx(D,{onRefresh:()=>h(),isFetching:b,apiPath:E})}),r&&s.jsx("div",{className:"mb-4 px-4 py-3 rounded-md bg-status-error/10 border border-status-error/20 text-xs text-status-error",children:r.message==="Session expired"?"Your session has expired. Please log in again.":`Failed to load escalations: ${r.message}`}),s.jsx(z,{columns:j,data:S,keyFn:a=>a.id,onRowClick:a=>d(`/escalations/detail/${a.id}`,{state:{from:"/escalations/queue"}}),isLoading:y,emptyMessage:r?"Unable to load data":"No assigned escalations",sort:n,onSort:g}),s.jsx(w,{page:e.page,totalPages:e.totalPages(p),onPageChange:e.setPage,total:p,pageSize:e.pageSize,onPageSizeChange:e.setPageSize})]})}export{me as OperatorDashboard};
|
|
2
|
-
//# sourceMappingURL=OperatorDashboard-_axS17fp.js.map
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import{a as p,j as e}from"./vendor-query-B2UbickB.js";import{I as X,a2 as T,a3 as ee,J as te,a1 as se,a4 as ae,a5 as ne}from"./index-DIgiIoou.js";import{C as re}from"./ConfirmDeleteModal-C0x0HcHX.js";import{u as ie}from"./users-mI9goDjj.js";import{T as E,B as le,A as oe,a1 as ce,u as de,L as xe,N as me,k as ue,P as pe,l as J,ag as he}from"./vendor-icons-ihWGa7_d.js";import{e as fe,c as ve,L as M}from"./vendor-react-CXumBFUA.js";import"./Modal-D4afnAjc.js";function ge({value:t,onChange:i,rows:r=2,className:l="",...d}){const c=p.useRef(null);return p.useLayoutEffect(()=>{const o=c.current;o&&(o.style.height="auto",o.style.height=`${o.scrollHeight}px`)},[t]),e.jsx("textarea",{ref:c,value:t,onChange:o=>i(o.target.value),rows:r,className:`textarea-quiet ${l}`,...d})}function je({role:t}){const{data:i}=ie({role:t,limit:100}),r=(i==null?void 0:i.users)??[];return r.length===0?e.jsx("p",{className:"text-[11px] text-text-tertiary",children:"Assign users to this role to staff its queue. Members see and resolve escalations here according to their read/write scope; admins manage the role itself."}):e.jsx("div",{className:"divide-y divide-surface-border/40",children:r.map(l=>{const d=l.roles.find(c=>c.role===t);return d?e.jsxs("div",{className:"flex items-center justify-between py-1.5 gap-2",children:[e.jsx("span",{className:"text-xs text-text-secondary truncate",children:l.display_name||l.external_id}),e.jsx("span",{className:"text-[10px] text-text-quaternary font-mono shrink-0",children:be(d)})]},l.id):null})})}function be(t){return t.type==="superadmin"||t.type==="admin"?t.type:`member · read ${t.read_scope} · write ${t.write_scope}`}function I(t){return t==null?"":JSON.stringify(t,null,2)}function L(t){const i=t.trim();if(!i)return{ok:!0,value:void 0};try{const r=JSON.parse(i);return typeof r!="object"||Array.isArray(r)||r===null?{ok:!1}:{ok:!0,value:r}}catch{return{ok:!1}}}function j({icon:t,label:i,annotation:r,aside:l,accent:d=!1,children:c}){const o=d?"text-accent":"text-text-tertiary";return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-5",children:[e.jsxs("div",{className:"flex items-center gap-1.5 min-w-0",children:[e.jsx(t,{className:`w-3 h-3 ${o} shrink-0`,strokeWidth:1.5}),e.jsx("span",{className:`text-[9px] font-semibold uppercase tracking-widest ${o}`,children:i}),r&&e.jsxs("span",{className:"text-[9px] text-text-quaternary truncate",children:["— ",r]})]}),l]}),e.jsx("div",{className:`border-l-2 pl-5 ${d?"border-accent/15":"border-surface-border/60"}`,children:c})]})}function O(){return e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"w-1.5 h-1.5 rounded-full dot-ring bg-status-success"}),e.jsx("span",{className:"text-[9px] font-semibold uppercase tracking-widest text-status-success",children:"Live"})]})}function _e({role:t,allRoles:i}){const{data:r}=se(),l=ae(),d=ne(),[c,o]=p.useState(""),a=(r==null?void 0:r.chains)??[],s=p.useMemo(()=>a.filter(x=>x.source_role===t.role).map(x=>x.target_role),[a,t.role]),f=p.useMemo(()=>i.map(x=>x.role).filter(x=>x!==t.role&&x!=="superadmin"&&!s.includes(x)),[i,t.role,s]);return t.role==="superadmin"?e.jsx("p",{className:"text-[11px] text-text-tertiary",children:"Superadmins can escalate to any role implicitly."}):e.jsxs("div",{className:"space-y-2",children:[f.length>0&&e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("select",{value:c,onChange:x=>o(x.target.value),className:"select text-xs font-mono flex-1",children:[e.jsx("option",{value:"",children:"Add target…"}),f.map(x=>e.jsx("option",{value:x,children:x},x))]}),e.jsx("button",{onClick:()=>{c&&l.mutate({source_role:t.role,target_role:c},{onSuccess:()=>o("")})},disabled:!c||l.isPending,className:"px-2.5 py-1 text-xs rounded bg-accent text-text-inverse hover:bg-accent-hover transition-colors disabled:opacity-40 disabled:cursor-not-allowed shrink-0",children:l.isPending?"…":"Add"})]}),e.jsx(W,{items:s,empty:"Roles this one can escalate to. Add a target above and it lands here.",onRemove:x=>d.mutate({source_role:t.role,target_role:x})})]})}function W({items:t,empty:i,onRemove:r}){return t.length===0?e.jsx("p",{className:"text-[10px] text-text-tertiary leading-relaxed",children:i}):e.jsx("div",{className:"flex flex-wrap gap-1.5",children:t.map(l=>e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 text-[10px] bg-accent/10 rounded-sm font-mono text-accent",children:[l,e.jsx("button",{onClick:()=>r(l),className:"text-accent/50 hover:text-status-error transition-colors leading-none ml-0.5",children:"×"})]},l))})}function Ne({role:t,allRoles:i}){const r=T(),[l,d]=p.useState(""),c=t.upstream_roles??[],o=p.useMemo(()=>i.map(s=>s.role).filter(s=>s!==t.role&&s!=="superadmin"&&!c.includes(s)),[i,t.role,c]),a=s=>r.mutate({role:t.role,upstream_roles:s},{onSuccess:()=>d("")});return e.jsxs("div",{className:"space-y-2",children:[o.length>0&&e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("select",{value:l,onChange:s=>d(s.target.value),className:"select text-xs font-mono flex-1",children:[e.jsx("option",{value:"",children:"Add upstream input…"}),o.map(s=>e.jsx("option",{value:s,children:s},s))]}),e.jsx("button",{onClick:()=>{l&&a([...c,l])},disabled:!l||r.isPending,className:"px-2.5 py-1 text-xs rounded bg-accent text-text-inverse hover:bg-accent-hover transition-colors disabled:opacity-40 disabled:cursor-not-allowed shrink-0",children:r.isPending?"…":"Add"})]}),e.jsx(W,{items:c,empty:"Roles from other sequences this station draws input from. Add one above and it lands here.",onRemove:s=>a(c.filter(f=>f!==s))}),r.error&&e.jsx("p",{className:"text-[10px] text-status-error",children:r.error.message})]})}function ye({role:t}){const i=T(),[r,l]=p.useState(""),[d,c]=p.useState(""),[o,a]=p.useState(!0),s=t.default_pins??[],f=m=>i.mutate({role:t.role,default_pins:m.length?m:null},{onSuccess:()=>{l(""),c(""),a(!0)}}),x=r.trim()!==""&&d.trim().startsWith("/");return e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"text",value:r,onChange:m=>l(m.target.value),placeholder:"Label — e.g. Needs harvesting",className:"input text-xs w-40 shrink-0"}),e.jsx("input",{type:"text",value:d,onChange:m=>c(m.target.value),placeholder:"/escalations/available?role=…",className:"input text-xs font-mono flex-1"}),e.jsxs("label",{className:"flex items-center gap-1 text-[10px] text-text-tertiary shrink-0",title:"Show a live count beside the label",children:[e.jsx("input",{type:"checkbox",checked:o,onChange:m=>a(m.target.checked),className:"w-3 h-3 accent-accent"}),"count"]}),e.jsx("button",{onClick:()=>{x&&f([...s,{label:r.trim(),url:d.trim(),badge:o}])},disabled:!x||i.isPending,className:"px-2.5 py-1 text-xs rounded bg-accent text-text-inverse hover:bg-accent-hover transition-colors disabled:opacity-40 disabled:cursor-not-allowed shrink-0",children:i.isPending?"…":"Add"})]}),s.length===0?e.jsx("p",{className:"text-[10px] text-text-tertiary leading-relaxed",children:"Pinned views every member starts with — the persona's exact queries. Add one above and it lands here."}):e.jsx("div",{className:"space-y-1",children:s.map(m=>e.jsxs("div",{className:"flex items-baseline gap-2 text-[11px]",children:[e.jsx("span",{className:"font-medium text-text-secondary shrink-0",children:m.label}),m.badge&&e.jsx("span",{className:"text-[9px] text-accent shrink-0",title:"Shows a live count",children:"count"}),e.jsx("span",{className:"font-mono text-text-quaternary truncate flex-1",title:m.url,children:m.url}),e.jsx("button",{onClick:()=>f(s.filter(C=>C.label!==m.label)),className:"text-text-quaternary hover:text-status-error transition-colors leading-none shrink-0","aria-label":`Remove pin ${m.label}`,children:"×"})]},m.label))}),i.error&&e.jsx("p",{className:"text-[10px] text-status-error",children:i.error.message})]})}function we(t){return{title:t.title??"",description:t.description??"",ops_visible:t.ops_visible,parent_role:t.parent_role??"",metadata_schema:I(t.metadata_schema),properties:I(t.properties)||"{}",sla_minutes:t.sla_minutes!=null?String(t.sla_minutes):"",target_per_hour:t.target_per_hour!=null?String(t.target_per_hour):"",worker_count:t.worker_count!=null?String(t.worker_count):"",priority_threshold_minutes:t.priority_threshold_minutes!=null?String(t.priority_threshold_minutes):"",priority_facet:t.priority_facet??""}}const ke=/^[a-zA-Z0-9_]+$/;function De(){const{role:t}=fe(),i=ve(),{data:r,isLoading:l}=X(),d=T(),c=ee(),o=(r==null?void 0:r.roles)??[],a=o.find(n=>n.role===t),[s,f]=p.useState({title:"",description:"",ops_visible:!1,parent_role:"",metadata_schema:"",properties:"{}",sla_minutes:"",target_per_hour:"",worker_count:"",priority_threshold_minutes:"",priority_facet:""}),[x,m]=p.useState(!1),[C,y]=p.useState(!1),[_,P]=p.useState({}),[V,U]=p.useState(!1),[B,A]=p.useState(new Set),z=n=>A(u=>new Set([...u,n]));p.useEffect(()=>{a&&(f(we(a)),m(!1),y(!1),P({}),A(new Set))},[t,a==null?void 0:a.role]);const g=n=>{f(u=>({...u,...n})),m(!0),y(!1)},G=p.useMemo(()=>o.filter(n=>{if(!a||n.role===a.role)return!1;let u=n;const h=new Set;for(;u!=null&&u.parent_role;){if(u.parent_role===a.role)return!1;if(h.has(u.parent_role))break;h.add(u.parent_role),u=o.find(v=>v.role===u.parent_role)}return!0}),[o,a]),K=()=>{const n=L(s.metadata_schema),u=L(s.properties),h=s.priority_facet.trim(),v={};if(n.ok||(v.metadata_schema="Invalid JSON"),u.ok||(v.properties="Invalid JSON"),h&&!ke.test(h)&&(v.priority_facet="Letters, numbers, underscores only"),P(v),Object.keys(v).length||!a)return;const b=D=>{const N=parseFloat(D);return isNaN(N)?null:N},Q=D=>{const N=b(D);return N==null?null:Math.round(N)};d.mutate({role:a.role,title:s.title.trim()||null,description:s.description.trim()||null,ops_visible:s.ops_visible,parent_role:s.parent_role||null,metadata_schema:n.value??null,properties:u.value??{},sla_minutes:b(s.sla_minutes),target_per_hour:b(s.target_per_hour),worker_count:Q(s.worker_count),priority_threshold_minutes:b(s.priority_threshold_minutes),priority_facet:h||null},{onSuccess:()=>{m(!1),y(!0),A(new Set),window.setTimeout(()=>y(!1),2500)}})},H=()=>{a&&c.mutate(a.role,{onSuccess:()=>i("/admin/roles")})};if(l)return e.jsxs("div",{className:"animate-pulse space-y-4",children:[e.jsx("div",{className:"h-8 bg-surface-sunken rounded w-48"}),e.jsx("div",{className:"h-4 bg-surface-sunken rounded w-64"}),e.jsx("div",{className:"h-64 bg-surface-sunken rounded"})]});if(!a)return e.jsxs("div",{className:"flex flex-col items-center justify-center py-20 text-center",children:[e.jsx(E,{className:"w-12 h-12 text-text-quaternary mb-4",strokeWidth:1}),e.jsx("h2",{className:"text-lg font-medium text-text-primary mb-2",children:"Role not found"})]});const Y=a.user_count>0||a.chain_count>0||a.workflow_count>0,Z=x&&!Object.values(_).some(Boolean),w=parseFloat(s.sla_minutes),k=parseFloat(s.target_per_hour),S=parseFloat(s.worker_count),R=!isNaN(w)&&w>0,$=!isNaN(k)&&k>0,q=!isNaN(S)&&S>0,F=R&&q&&!$?`→ target ≈ ${(S/(w/60)).toFixed(1)}/h`:R&&$&&!q?`→ workers ≈ ${(k*(w/60)).toFixed(1)}`:$&&q&&!R?`→ SLA ≈ ${(S/k*60).toFixed(0)}m`:null;return e.jsxs("div",{children:[e.jsxs("div",{className:"grid grid-cols-3 gap-16 items-center mb-12",children:[e.jsxs("div",{className:"flex items-center justify-between gap-4 min-w-0",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-1",children:[e.jsx(E,{className:"w-5 h-5 text-accent",strokeWidth:1.5}),e.jsx("h1",{className:"text-lg font-mono font-medium text-text-primary",children:a.role}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:dashboard.md:role-detail"},className:"text-text-quaternary hover:text-accent transition-colors",title:"Open docs for this page",children:e.jsx(le,{className:"w-4 h-4",strokeWidth:1.5})}),a.parent_role&&e.jsxs("span",{className:"flex items-center gap-1 text-[10px] text-text-quaternary font-mono",children:[e.jsx(oe,{className:"w-3 h-3"})," ",a.parent_role]})]}),a.title&&e.jsx("p",{className:"text-sm text-text-secondary pl-8",children:a.title})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",title:"Show as a station on the Pace Board",children:[e.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:"Pace Board"}),e.jsx("button",{onClick:()=>g({ops_visible:!s.ops_visible}),className:`w-9 h-5 rounded-full transition-colors relative shrink-0 ${s.ops_visible?"bg-accent":"bg-surface-border"}`,children:e.jsx("span",{className:`absolute top-[3px] left-0 w-3.5 h-3.5 rounded-full bg-white transition-transform shadow ${s.ops_visible?"translate-x-[18px]":"translate-x-[3px]"}`})})]})]}),e.jsxs("div",{className:"flex items-end justify-center gap-4 bg-surface-sunken rounded-lg px-4 py-2.5 w-full",title:"throughput = workers / (sla / 60)",children:[[{key:"sla_minutes",label:"SLA",unit:"min",placeholder:"30"},{key:"target_per_hour",label:"Target",unit:"/h",placeholder:"20"},{key:"worker_count",label:"Workers",unit:"",placeholder:"4"}].map(({key:n,label:u,unit:h,placeholder:v})=>e.jsxs("div",{children:[e.jsxs("label",{className:"block text-[9px] font-semibold uppercase tracking-widest text-text-quaternary mb-1",children:[u,h&&e.jsx("span",{className:"normal-case font-normal ml-1",children:h})]}),e.jsx("input",{type:"number",min:"0",step:"any",value:s[n],onChange:b=>g({[n]:b.target.value}),placeholder:v,className:"input text-xs w-16 font-mono"})]},n)),F&&e.jsx("span",{className:"text-[10px] text-accent font-mono whitespace-nowrap pb-2",children:F})]}),e.jsxs("div",{className:"flex items-center justify-between gap-4 min-w-0",children:[e.jsxs("div",{className:"flex items-end gap-4 bg-surface-sunken rounded-lg px-4 py-2.5 shrink-0",title:"Pending unclaimed items older than the threshold count as priority on the Pace Board. Age is measured from the metadata facet (an ISO 8601 UTC timestamp, e.g. authorized_at) or from created_at when the facet is blank; the threshold falls back to SLA when blank.",children:[e.jsxs("div",{children:[e.jsxs("label",{className:"block text-[9px] font-semibold uppercase tracking-widest text-text-quaternary mb-1",children:["Priority",e.jsx("span",{className:"normal-case font-normal ml-1",children:"min"})]}),e.jsx("input",{type:"number",min:"0",step:"any",value:s.priority_threshold_minutes,onChange:n=>g({priority_threshold_minutes:n.target.value}),placeholder:s.sla_minutes||"60",className:"input text-xs w-16 font-mono"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[9px] font-semibold uppercase tracking-widest text-text-quaternary mb-1",children:"Facet"}),e.jsx("input",{type:"text",value:s.priority_facet,onChange:n=>g({priority_facet:n.target.value}),placeholder:"created_at",className:"input text-xs w-28 font-mono"}),_.priority_facet&&e.jsx("p",{className:"text-[9px] text-status-error mt-0.5",children:_.priority_facet})]})]}),e.jsxs("div",{className:"flex items-center gap-3 shrink-0",children:[C&&e.jsxs("span",{className:"flex items-center gap-1 text-xs text-status-success animate-page-enter",children:[e.jsx(ce,{className:"w-3 h-3"})," Saved"]}),d.error&&e.jsx("span",{className:"text-xs text-status-error max-w-[180px] truncate",children:d.error.message}),e.jsx("button",{onClick:K,disabled:!Z||d.isPending,className:"px-3 py-1.5 text-xs rounded-md bg-accent text-text-inverse hover:bg-accent-hover transition-colors disabled:opacity-40 disabled:cursor-not-allowed",children:d.isPending?"Saving…":"Save"}),!Y&&e.jsxs("button",{onClick:()=>U(!0),className:"px-3 py-1.5 text-xs rounded-md text-status-error/60 hover:text-status-error hover:bg-status-error/10 transition-colors flex items-center gap-1",children:[e.jsx(de,{className:"w-3 h-3"})," Delete"]})]})]})]}),e.jsxs("div",{className:"grid grid-cols-3 gap-16 items-start",children:[e.jsxs("div",{className:"space-y-14",children:[e.jsx(j,{icon:E,label:"Identity",annotation:"name and description",accent:!0,children:e.jsxs("div",{className:"space-y-8",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-1.5",children:"Display Name"}),e.jsx("input",{type:"text",value:s.title,onChange:n=>g({title:n.target.value}),placeholder:`e.g., ${a.role.charAt(0).toUpperCase()+a.role.slice(1)}`,className:"input text-sm w-full"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-1.5",children:"Description"}),e.jsx(ge,{value:s.description,onChange:n=>g({description:n}),placeholder:"A short description shown on role cards and in the operations view.",rows:2})]})]})}),e.jsx("div",{className:`overflow-hidden transition-all duration-300 ease-out ${s.ops_visible?"opacity-100 max-h-[900px]":"opacity-0 max-h-0 pointer-events-none"}`,"aria-hidden":!s.ops_visible,children:e.jsx(j,{icon:xe,label:"Pace Board",annotation:"where this station sits on the floor",accent:!0,children:e.jsxs("div",{className:"space-y-8",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-1.5",children:"Prior Step"}),e.jsxs("select",{value:s.parent_role,onChange:n=>g({parent_role:n.target.value}),className:"select text-sm w-full font-mono",children:[e.jsx("option",{value:"",children:"None — root process"}),G.map(n=>e.jsx("option",{value:n.role,children:n.title?`${n.role} — ${n.title}`:n.role},n.role))]}),e.jsx("p",{className:"text-[10px] text-text-tertiary leading-relaxed mt-1.5",children:"Places this role in one Pace Board sequence. A role with no prior step starts its own sequence."})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-1.5",children:[e.jsx("label",{className:"block text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:"Upstream Inputs"}),e.jsx(O,{})]}),e.jsx(Ne,{role:a,allRoles:o})]})]})})})]}),e.jsxs("div",{className:"space-y-14",children:[e.jsx(j,{icon:me,label:"Escalation Targets",annotation:"hand-off routing",aside:e.jsx(O,{}),children:e.jsx(_e,{role:a,allRoles:o})}),e.jsx(j,{icon:ue,label:"Members",annotation:"read = what appears · write = what they can act on",children:e.jsx(je,{role:a.role})}),e.jsx(j,{icon:pe,label:"Default Pins",annotation:"pinned views every member starts with",aside:e.jsx(O,{}),children:e.jsx(ye,{role:a})})]}),e.jsxs("div",{className:"space-y-14",children:[e.jsxs(j,{icon:J,label:"Escalation Schema",annotation:"the resolve form",accent:!0,aside:a.current_schema_version!=null?e.jsxs("span",{className:"text-[9px] font-mono text-text-quaternary",children:["v",a.current_schema_version," in use"]}):void 0,children:[e.jsxs("p",{className:"text-[10px] text-text-tertiary mb-3 leading-relaxed",children:["The form a person completes to resolve this role's escalations. Versioned — each save adds one; workflows pin any version via"," ",e.jsx("code",{className:"font-mono",children:"schemaVersion"}),"."]}),e.jsx(M,{to:`/admin/roles/${encodeURIComponent(a.role)}/schema`,className:"text-xs text-accent hover:underline",children:a.form_schema?`Open schema editor — v${a.current_schema_version??1} in use →`:"Define the escalation form →"})]}),e.jsxs(j,{icon:he,label:"Escalations List Schema",annotation:"rich list view",aside:a.current_list_schema_version!=null?e.jsxs("span",{className:"text-[9px] font-mono text-text-quaternary",children:["v",a.current_list_schema_version," in use"]}):void 0,children:[e.jsx("p",{className:"text-[10px] text-text-tertiary mb-3 leading-relaxed",children:"Richly formats the escalation list when it's scoped to just this role. Versioned on its own timeline — separate from the resolve form."}),e.jsx(M,{to:`/admin/roles/${encodeURIComponent(a.role)}/list-schema`,className:"text-xs text-accent hover:underline",children:a.list_schema?`Open list schema editor — v${a.current_list_schema_version??1} in use →`:"Define the list view →"})]}),e.jsxs(j,{icon:J,label:"Metadata Schema",annotation:"validates metadata at creation",aside:!B.has("metadata_schema")&&a.metadata_schema?e.jsx("button",{onClick:()=>z("metadata_schema"),className:"text-[9px] text-accent hover:underline",children:"Edit"}):void 0,children:[e.jsxs("p",{className:"text-[10px] text-text-tertiary mb-3 leading-relaxed",children:["Validates ",e.jsx("code",{className:"font-mono",children:"metadata"})," at creation time. Keys appear in faceted search autocomplete."]}),!B.has("metadata_schema")&&a.metadata_schema?e.jsx(te,{data:a.metadata_schema}):e.jsxs(e.Fragment,{children:[e.jsx("textarea",{value:s.metadata_schema,onChange:n=>{const u=n.target.value;g({metadata_schema:u}),P(h=>({...h,metadata_schema:L(u).ok?void 0:"Invalid JSON"}))},rows:10,spellCheck:!1,className:"input text-xs font-mono w-full resize-y",placeholder:`{
|
|
2
|
-
"type": "object",
|
|
3
|
-
"properties": {
|
|
4
|
-
"order_id": { "type": "string" }
|
|
5
|
-
},
|
|
6
|
-
"required": ["order_id"]
|
|
7
|
-
}`}),_.metadata_schema&&e.jsx("p",{className:"text-[10px] text-status-error mt-1",children:_.metadata_schema})]})]})]})]}),e.jsx(re,{open:V,onClose:()=>U(!1),onConfirm:H,title:"Delete Role",description:e.jsxs(e.Fragment,{children:["Delete role ",e.jsx("span",{className:"font-medium font-mono text-text-primary",children:a.role}),"? This cannot be undone."]}),isPending:c.isPending,error:c.error})]})}export{De as RoleDetailPage};
|
|
8
|
-
//# sourceMappingURL=RoleDetailPage-ufbypNNR.js.map
|