@hotmeshio/long-tail 0.10.11 → 0.10.14
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 +2 -4
- package/build/api/escalations/list.d.ts +1 -0
- package/build/api/escalations/list.js +1 -0
- package/build/api/escalations/metadata.d.ts +11 -0
- package/build/api/escalations/metadata.js +28 -8
- package/build/api/escalations/resolve.js +4 -4
- package/build/api/scan-codes/config.d.ts +22 -0
- package/build/api/scan-codes/config.js +136 -0
- package/build/api/scan-codes/execute.d.ts +9 -0
- package/build/api/scan-codes/execute.js +372 -0
- package/build/api/scan-codes/index.d.ts +2 -0
- package/build/api/scan-codes/index.js +14 -0
- package/build/lib/db/schemas/026_scan_codes.sql +51 -0
- package/build/lib/db/schemas/027_scan_codes_reindex.sql +23 -0
- package/build/lib/events/system-events.js +4 -0
- package/build/modules/features.d.ts +8 -0
- package/build/modules/features.js +1 -0
- package/build/routes/escalations/list.js +1 -0
- package/build/routes/index.js +2 -0
- package/build/routes/scan-codes.d.ts +2 -0
- package/build/routes/scan-codes.js +138 -0
- package/build/sdk/index.d.ts +4 -0
- package/build/services/escalation/crud.d.ts +1 -1
- package/build/services/escalation/crud.js +4 -2
- package/build/services/escalation/queries.d.ts +1 -0
- package/build/services/escalation/queries.js +2 -0
- package/build/services/escalation/resolver-validation.d.ts +1 -1
- package/build/services/escalation/resolver-validation.js +12 -5
- package/build/services/escalation/sql.d.ts +11 -6
- package/build/services/escalation/sql.js +20 -20
- package/build/services/escalation/submit-guard.d.ts +29 -0
- package/build/services/escalation/submit-guard.js +57 -0
- package/build/services/scan-code/index.d.ts +4 -0
- package/build/services/scan-code/index.js +21 -0
- package/build/services/scan-code/parse.d.ts +35 -0
- package/build/services/scan-code/parse.js +108 -0
- package/build/services/scan-code/read.d.ts +5 -0
- package/build/services/scan-code/read.js +50 -0
- package/build/services/scan-code/sql.d.ts +10 -0
- package/build/services/scan-code/sql.js +57 -0
- package/build/services/scan-code/validate.d.ts +12 -0
- package/build/services/scan-code/validate.js +78 -0
- package/build/services/scan-code/write.d.ts +26 -0
- package/build/services/scan-code/write.js +71 -0
- package/build/shared/form-validation/index.d.ts +5 -0
- package/build/shared/form-validation/index.js +5 -0
- package/build/shared/form-validation/x-lt-labels.d.ts +28 -0
- package/build/shared/form-validation/x-lt-labels.js +42 -0
- package/build/shared/form-validation/x-lt-query.d.ts +56 -0
- package/build/shared/form-validation/x-lt-query.js +49 -0
- package/build/shared/form-validation/x-lt-submit-guard.d.ts +46 -0
- package/build/shared/form-validation/x-lt-submit-guard.js +25 -0
- package/build/shared/form-validation/x-lt-submit-on-claim.d.ts +22 -0
- package/build/shared/form-validation/x-lt-submit-on-claim.js +28 -0
- package/build/shared/form-validation/x-lt-transition.d.ts +47 -0
- package/build/shared/form-validation/x-lt-transition.js +65 -0
- package/build/system/mcp-servers/admin/index.d.ts +1 -0
- package/build/system/mcp-servers/admin/index.js +5 -2
- package/build/system/mcp-servers/admin/scan-codes.d.ts +10 -0
- package/build/system/mcp-servers/admin/scan-codes.js +111 -0
- package/build/system/mcp-servers/admin/schemas.d.ts +232 -14
- package/build/system/mcp-servers/admin/schemas.js +50 -0
- package/build/system/seed/tool-manifests-admin.d.ts +1380 -0
- package/build/system/seed/tool-manifests-admin.js +6 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/events.d.ts +9 -0
- package/build/types/index.d.ts +2 -0
- package/build/types/index.js +10 -1
- package/build/types/scan-code.d.ts +183 -0
- package/build/types/scan-code.js +80 -0
- package/build/types/startup.d.ts +6 -0
- package/dashboard/dist/assets/{AdminDashboard-CkTbRfY9.js → AdminDashboard-Chg69wlx.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-CkTbRfY9.js.map → AdminDashboard-Chg69wlx.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-Cm8FRpXi.js → AgentConfigPage-DRTFwbfC.js} +6 -6
- package/dashboard/dist/assets/{AgentConfigPage-Cm8FRpXi.js.map → AgentConfigPage-DRTFwbfC.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-sQ1-UT46.js → AgentDetailPage-JKByfFIi.js} +3 -3
- package/dashboard/dist/assets/{AgentDetailPage-sQ1-UT46.js.map → AgentDetailPage-JKByfFIi.js.map} +1 -1
- package/dashboard/dist/assets/AgentsPage-BlgEmKhA.js +2 -0
- package/dashboard/dist/assets/{AgentsPage-bSx_mdae.js.map → AgentsPage-BlgEmKhA.js.map} +1 -1
- package/dashboard/dist/assets/{AutoGrowTextarea-y-oNY51_.js → AutoGrowTextarea-DgEQeRQw.js} +2 -2
- package/dashboard/dist/assets/{AutoGrowTextarea-y-oNY51_.js.map → AutoGrowTextarea-DgEQeRQw.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-C_7y692Q.js +2 -0
- package/dashboard/dist/assets/{AvailableEscalationsPage-8pMC7Xv6.js.map → AvailableEscalationsPage-C_7y692Q.js.map} +1 -1
- package/dashboard/dist/assets/BotPicker-CCVcz4Cq.js +2 -0
- package/dashboard/dist/assets/{BotPicker-C4uGH2x9.js.map → BotPicker-CCVcz4Cq.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-BRoOeKcc.js → CapabilitiesPage-Czi9jUwD.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-BRoOeKcc.js.map → CapabilitiesPage-Czi9jUwD.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-CIj8Adc9.js → CollapsibleSection-8YE965QX.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-CIj8Adc9.js.map → CollapsibleSection-8YE965QX.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-Ugi_9Ukq.js → ConfirmDeleteModal-CQsJUzEa.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-Ugi_9Ukq.js.map → ConfirmDeleteModal-CQsJUzEa.js.map} +1 -1
- package/dashboard/dist/assets/{CopyableId-GUEdiiL5.js → CopyableId-4Lqlc5cU.js} +2 -2
- package/dashboard/dist/assets/{CopyableId-GUEdiiL5.js.map → CopyableId-4Lqlc5cU.js.map} +1 -1
- package/dashboard/dist/assets/CountdownTimer-Bxvq3D7j.js +2 -0
- package/dashboard/dist/assets/CountdownTimer-Bxvq3D7j.js.map +1 -0
- package/dashboard/dist/assets/{CredentialsPage-B73Si6K1.js → CredentialsPage-Bn7_SX6-.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-B73Si6K1.js.map → CredentialsPage-Bn7_SX6-.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-Ca1aHolt.js → CronLabel-Bn4mX_Yn.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-Ca1aHolt.js.map → CronLabel-Bn4mX_Yn.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-_9E9x1YN.js → CustomDurationPicker-pMcrFyW6.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-_9E9x1YN.js.map → CustomDurationPicker-pMcrFyW6.js.map} +1 -1
- package/dashboard/dist/assets/{DataTable-BTu2AaEl.js → DataTable-Bir0Xs1p.js} +2 -2
- package/dashboard/dist/assets/{DataTable-BTu2AaEl.js.map → DataTable-Bir0Xs1p.js.map} +1 -1
- package/dashboard/dist/assets/{DropZone-NYn6TWHz.js → DropZone-zCEGjjk-.js} +2 -2
- package/dashboard/dist/assets/{DropZone-NYn6TWHz.js.map → DropZone-zCEGjjk-.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-karxia93.js → ElapsedCell-BGO7IXEg.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-karxia93.js.map → ElapsedCell-BGO7IXEg.js.map} +1 -1
- package/dashboard/dist/assets/{EmptyState-BcsfPq9T.js → EmptyState-lpUFYfun.js} +2 -2
- package/dashboard/dist/assets/{EmptyState-BcsfPq9T.js.map → EmptyState-lpUFYfun.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-CDaNmbUA.js → EscalationListSchemaPage-CFDxbd50.js} +3 -3
- package/dashboard/dist/assets/{EscalationListSchemaPage-CDaNmbUA.js.map → EscalationListSchemaPage-CFDxbd50.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-k-2hFT2t.js → EscalationSchemaPage-DnXPnDkz.js} +3 -3
- package/dashboard/dist/assets/{EscalationSchemaPage-k-2hFT2t.js.map → EscalationSchemaPage-DnXPnDkz.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-C1e7IPn_.js → EscalationsOverview-BZMVXrkK.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-C1e7IPn_.js.map → EscalationsOverview-BZMVXrkK.js.map} +1 -1
- package/dashboard/dist/assets/EventTable-Bfi-f8as.js +2 -0
- package/dashboard/dist/assets/EventTable-Bfi-f8as.js.map +1 -0
- package/dashboard/dist/assets/FilterBar-Do7yR4xM.js +2 -0
- package/dashboard/dist/assets/FilterBar-Do7yR4xM.js.map +1 -0
- package/dashboard/dist/assets/{GraphInvokePage-LMpWw8z1.js → GraphInvokePage-d1ie4T7f.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-LMpWw8z1.js.map → GraphInvokePage-d1ie4T7f.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-Kl2DBG6l.js → HomePage-BEeodImU.js} +2 -2
- package/dashboard/dist/assets/{HomePage-Kl2DBG6l.js.map → HomePage-BEeodImU.js.map} +1 -1
- package/dashboard/dist/assets/ListToolbar-CLtw-1QN.js +2 -0
- package/dashboard/dist/assets/{ListToolbar-B2fub0DY.js.map → ListToolbar-CLtw-1QN.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-odYnCZCC.js → McpOverview-DIsy9TB3.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-odYnCZCC.js.map → McpOverview-DIsy9TB3.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-BtqwHUAg.js → McpQueryDetailPage-6PomdsyD.js} +3 -3
- package/dashboard/dist/assets/{McpQueryDetailPage-BtqwHUAg.js.map → McpQueryDetailPage-6PomdsyD.js.map} +1 -1
- package/dashboard/dist/assets/McpQueryPage-YMdQCXm9.js +2 -0
- package/dashboard/dist/assets/{McpQueryPage-CPkVwNIK.js.map → McpQueryPage-YMdQCXm9.js.map} +1 -1
- package/dashboard/dist/assets/McpRunDetailPage-DsD1Gm2o.js +2 -0
- package/dashboard/dist/assets/McpRunDetailPage-DsD1Gm2o.js.map +1 -0
- package/dashboard/dist/assets/{McpRunsPage-rdpZ2yMh.js → McpRunsPage--a5Jgb33.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-rdpZ2yMh.js.map → McpRunsPage--a5Jgb33.js.map} +1 -1
- package/dashboard/dist/assets/{Modal-Dr1Xy0j0.js → Modal-BU7No9NH.js} +2 -2
- package/dashboard/dist/assets/{Modal-Dr1Xy0j0.js.map → Modal-BU7No9NH.js.map} +1 -1
- package/dashboard/dist/assets/{NamespacePill-GwO-WfhX.js → NamespacePill-wV6L4VW1.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-GwO-WfhX.js.map → NamespacePill-wV6L4VW1.js.map} +1 -1
- package/dashboard/dist/assets/OperationsPage-B2v9k3DT.js +2 -0
- package/dashboard/dist/assets/{OperationsPage-DlyGLPAs.js.map → OperationsPage-B2v9k3DT.js.map} +1 -1
- package/dashboard/dist/assets/{OperatorDashboard-Csei5vj-.js → OperatorDashboard-CkLfbxEh.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-Csei5vj-.js.map → OperatorDashboard-CkLfbxEh.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-Bo9BU9pK.js → PageHeader-BtIr6r-8.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-Bo9BU9pK.js.map → PageHeader-BtIr6r-8.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-8_5cOSKL.js → PageHeaderWithStats-C2sGqFQG.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-8_5cOSKL.js.map → PageHeaderWithStats-C2sGqFQG.js.map} +1 -1
- package/dashboard/dist/assets/{PersonaDetailPage--ZL6Or6v.js → PersonaDetailPage-CCmOgKQb.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage--ZL6Or6v.js.map → PersonaDetailPage-CCmOgKQb.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-Bdcoay3P.js → PersonasPage-BJkSuDTN.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-Bdcoay3P.js.map → PersonasPage-BJkSuDTN.js.map} +1 -1
- package/dashboard/dist/assets/{PriorityBadge-CCERr9vQ.js → PriorityBadge-BETdj4M-.js} +2 -2
- package/dashboard/dist/assets/{PriorityBadge-CCERr9vQ.js.map → PriorityBadge-BETdj4M-.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-HrmVQq7S.js → ProcessDetailPage-DT9BlJXK.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-HrmVQq7S.js.map → ProcessDetailPage-DT9BlJXK.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-_xmj6Bo-.js → ProcessesListPage-DgSGzTDT.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-_xmj6Bo-.js.map → ProcessesListPage-DgSGzTDT.js.map} +1 -1
- package/dashboard/dist/assets/{RoleDetailPage-C0ju2-4K.js → RoleDetailPage-DMphTvro.js} +3 -3
- package/dashboard/dist/assets/{RoleDetailPage-C0ju2-4K.js.map → RoleDetailPage-DMphTvro.js.map} +1 -1
- package/dashboard/dist/assets/{RolePill-CQlnEWkK.js → RolePill-BBYjhAPj.js} +2 -2
- package/dashboard/dist/assets/{RolePill-CQlnEWkK.js.map → RolePill-BBYjhAPj.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-CKluVSpB.js → RolesPage-gi_kaot1.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-CKluVSpB.js.map → RolesPage-gi_kaot1.js.map} +1 -1
- package/dashboard/dist/assets/{RowActions-BA9L9djf.js → RowActions-eYrzgQSj.js} +2 -2
- package/dashboard/dist/assets/{RowActions-BA9L9djf.js.map → RowActions-eYrzgQSj.js.map} +1 -1
- package/dashboard/dist/assets/RunAsSelector-CateuvcC.js +2 -0
- package/dashboard/dist/assets/{RunAsSelector-DdfecQ1U.js.map → RunAsSelector-CateuvcC.js.map} +1 -1
- package/dashboard/dist/assets/ScanCodesPage-CQ8RxMug.js +2 -0
- package/dashboard/dist/assets/ScanCodesPage-CQ8RxMug.js.map +1 -0
- package/dashboard/dist/assets/ScanSchemeDetailPage-puSbuxcV.js +2 -0
- package/dashboard/dist/assets/ScanSchemeDetailPage-puSbuxcV.js.map +1 -0
- package/dashboard/dist/assets/{ScopeBadge-BBYkevuR.js → ScopeBadge-xs2Nhjy4.js} +2 -2
- package/dashboard/dist/assets/{ScopeBadge-BBYkevuR.js.map → ScopeBadge-xs2Nhjy4.js.map} +1 -1
- package/dashboard/dist/assets/SegmentedTabs-DXNzY05q.js +2 -0
- package/dashboard/dist/assets/SegmentedTabs-DXNzY05q.js.map +1 -0
- package/dashboard/dist/assets/{StatCard-Ca-ngCaD.js → StatCard-BXQ8dD9Y.js} +2 -2
- package/dashboard/dist/assets/{StatCard-Ca-ngCaD.js.map → StatCard-BXQ8dD9Y.js.map} +1 -1
- package/dashboard/dist/assets/{StatusBadge-BwUvykDo.js → StatusBadge-DkgllZHv.js} +2 -2
- package/dashboard/dist/assets/{StatusBadge-BwUvykDo.js.map → StatusBadge-DkgllZHv.js.map} +1 -1
- package/dashboard/dist/assets/StickyPagination-Cg-QdYWL.js +2 -0
- package/dashboard/dist/assets/StickyPagination-Cg-QdYWL.js.map +1 -0
- package/dashboard/dist/assets/{StreamMessageDetail-CZXWDawC.js → StreamMessageDetail-DEeuh4_-.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-CZXWDawC.js.map → StreamMessageDetail-DEeuh4_-.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-fWY0gaf3.js → SwimlaneTimeline-DMY0jL2F.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-fWY0gaf3.js.map → SwimlaneTimeline-DMY0jL2F.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-CDKbslLx.js → TagInput-BMmiV-MD.js} +2 -2
- package/dashboard/dist/assets/{TagInput-CDKbslLx.js.map → TagInput-BMmiV-MD.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-BjE4G2yn.js → TaskDetailPage-CPbkIvfF.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-BjE4G2yn.js.map → TaskDetailPage-CPbkIvfF.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-G3RuYRNZ.js → TaskQueuePill-DLgYaw1x.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-G3RuYRNZ.js.map → TaskQueuePill-DLgYaw1x.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-KAhmCWB2.js → TasksListPage-CtHudKhQ.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-KAhmCWB2.js.map → TasksListPage-CtHudKhQ.js.map} +1 -1
- package/dashboard/dist/assets/TimeAgo-BdHOizWg.js +2 -0
- package/dashboard/dist/assets/{TimeAgo-C_H2TyZw.js.map → TimeAgo-BdHOizWg.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-COG_4Flg.js → TimestampCell-FVukzKRe.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-COG_4Flg.js.map → TimestampCell-FVukzKRe.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-ChSyRJZC.js → ToolPill-BvS53hxP.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-ChSyRJZC.js.map → ToolPill-BvS53hxP.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-BPdJECW0.js → ToolTestPanel-HN0OCYTL.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-BPdJECW0.js.map → ToolTestPanel-HN0OCYTL.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-DAqx5JqA.js → TopicDetailPage-DHdSpN61.js} +4 -4
- package/dashboard/dist/assets/{TopicDetailPage-DAqx5JqA.js.map → TopicDetailPage-DHdSpN61.js.map} +1 -1
- package/dashboard/dist/assets/TopicsPage-Clr6Tl5P.js +2 -0
- package/dashboard/dist/assets/{TopicsPage-DoGqAdPm.js.map → TopicsPage-Clr6Tl5P.js.map} +1 -1
- package/dashboard/dist/assets/UserName-BUVYyIAS.js +2 -0
- package/dashboard/dist/assets/{UserName-CKO_rk1R.js.map → UserName-BUVYyIAS.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-kncWFfe5.js +2 -0
- package/dashboard/dist/assets/WorkflowExecutionPage-kncWFfe5.js.map +1 -0
- package/dashboard/dist/assets/{WorkflowPill-CNbwug5p.js → WorkflowPill-BPC_Dc_I.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill-CNbwug5p.js.map → WorkflowPill-BPC_Dc_I.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowsDashboard-4ypPDGKx.js +2 -0
- package/dashboard/dist/assets/{WorkflowsDashboard-DdJ86We6.js.map → WorkflowsDashboard-4ypPDGKx.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-ZfFBzePp.js → WorkflowsOverview-CeQlZkkd.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-ZfFBzePp.js.map → WorkflowsOverview-CeQlZkkd.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-4bd5yXdA.js → YamlWorkflowDetailPage-DLAlEzwT.js} +13 -13
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-4bd5yXdA.js.map → YamlWorkflowDetailPage-DLAlEzwT.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-iHPNXjQj.js → YamlWorkflowsPage-DQhenKFT.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-iHPNXjQj.js.map → YamlWorkflowsPage-DQhenKFT.js.map} +1 -1
- package/dashboard/dist/assets/{agents-DjD5U3Wb.js → agents-s3feet3W.js} +2 -2
- package/dashboard/dist/assets/{agents-DjD5U3Wb.js.map → agents-s3feet3W.js.map} +1 -1
- package/dashboard/dist/assets/{bots-DiljVapH.js → bots-CkSd2rn9.js} +2 -2
- package/dashboard/dist/assets/{bots-DiljVapH.js.map → bots-CkSd2rn9.js.map} +1 -1
- package/dashboard/dist/assets/capabilities-DA_r09tM.js +2 -0
- package/dashboard/dist/assets/{capabilities-DV_5ghHT.js.map → capabilities-DA_r09tM.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-BKMvfWCB.js → controlplane-C9c25q21.js} +2 -2
- package/dashboard/dist/assets/{controlplane-BKMvfWCB.js.map → controlplane-C9c25q21.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-BQpCaJId.js → escalation-columns-Cp3UrT48.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-BQpCaJId.js.map → escalation-columns-Cp3UrT48.js.map} +1 -1
- package/dashboard/dist/assets/{index-BO-7S9Xw.js → index--7Vdkzwd.js} +2 -2
- package/dashboard/dist/assets/{index-BO-7S9Xw.js.map → index--7Vdkzwd.js.map} +1 -1
- package/dashboard/dist/assets/index--DG-qQBT.js +65 -0
- package/dashboard/dist/assets/index--DG-qQBT.js.map +1 -0
- package/dashboard/dist/assets/{index-BaV3l0UE.js → index-BIcYbDVf.js} +2 -2
- package/dashboard/dist/assets/{index-BaV3l0UE.js.map → index-BIcYbDVf.js.map} +1 -1
- package/dashboard/dist/assets/index-BU5FFAJo.js +2 -0
- package/dashboard/dist/assets/{index-CItsikDw.js.map → index-BU5FFAJo.js.map} +1 -1
- package/dashboard/dist/assets/{index-BsOxMMmb.js → index-Bo5TtX9l.js} +2 -2
- package/dashboard/dist/assets/{index-BsOxMMmb.js.map → index-Bo5TtX9l.js.map} +1 -1
- package/dashboard/dist/assets/{index-Tx_ETzcH.js → index-C-MmR-jf.js} +2 -2
- package/dashboard/dist/assets/{index-Tx_ETzcH.js.map → index-C-MmR-jf.js.map} +1 -1
- package/dashboard/dist/assets/index-C7ABSOU2.js +6 -0
- package/dashboard/dist/assets/index-C7ABSOU2.js.map +1 -0
- package/dashboard/dist/assets/index-Cmxzk4ay.js +5 -0
- package/dashboard/dist/assets/{index-nIrYejxe.js.map → index-Cmxzk4ay.js.map} +1 -1
- package/dashboard/dist/assets/{index-CI8rrKjx.js → index-Cw9poaez.js} +2 -2
- package/dashboard/dist/assets/{index-CI8rrKjx.js.map → index-Cw9poaez.js.map} +1 -1
- package/dashboard/dist/assets/index-DEbY57_c.js +3 -0
- package/dashboard/dist/assets/index-DEbY57_c.js.map +1 -0
- package/dashboard/dist/assets/index-DnV6LSeY.css +1 -0
- package/dashboard/dist/assets/{index-xZqQxqu2.js → index-DvoMXQqO.js} +2 -2
- package/dashboard/dist/assets/{index-xZqQxqu2.js.map → index-DvoMXQqO.js.map} +1 -1
- package/dashboard/dist/assets/{index-DhATO1cS.js → index-S13oPvuS.js} +2 -2
- package/dashboard/dist/assets/{index-DhATO1cS.js.map → index-S13oPvuS.js.map} +1 -1
- package/dashboard/dist/assets/index-WxE3ONia.js +2 -0
- package/dashboard/dist/assets/{index-CStR4uIU.js.map → index-WxE3ONia.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-BocTnSiA.js → knowledge-Bpln0zy_.js} +2 -2
- package/dashboard/dist/assets/{knowledge-BocTnSiA.js.map → knowledge-Bpln0zy_.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-C1KBjKQ_.js → mcp-BqDq3RZH.js} +2 -2
- package/dashboard/dist/assets/{mcp-C1KBjKQ_.js.map → mcp-BqDq3RZH.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-B3cjukkA.js → mcp-query-DGue75R6.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-B3cjukkA.js.map → mcp-query-DGue75R6.js.map} +1 -1
- package/dashboard/dist/assets/{personas-DiA2bJaX.js → personas-B8z_sTiJ.js} +2 -2
- package/dashboard/dist/assets/{personas-DiA2bJaX.js.map → personas-B8z_sTiJ.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-Dt2d2EFR.js → pipelines-DYgNd9nB.js} +2 -2
- package/dashboard/dist/assets/{pipelines-Dt2d2EFR.js.map → pipelines-DYgNd9nB.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-cDh2hNml.js → tasks-CJdjjhgO.js} +2 -2
- package/dashboard/dist/assets/{tasks-cDh2hNml.js.map → tasks-CJdjjhgO.js.map} +1 -1
- package/dashboard/dist/assets/{topics-yFlGF-u1.js → topics-DPrL8Dtq.js} +2 -2
- package/dashboard/dist/assets/{topics-yFlGF-u1.js.map → topics-DPrL8Dtq.js.map} +1 -1
- package/dashboard/dist/assets/{useDebouncedValue-BA5S7V54.js → useDebouncedValue-C4P2jQuh.js} +2 -2
- package/dashboard/dist/assets/{useDebouncedValue-BA5S7V54.js.map → useDebouncedValue-C4P2jQuh.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-D2R_ckS8.js → useEventHooks-DXCgDgiu.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-D2R_ckS8.js.map → useEventHooks-DXCgDgiu.js.map} +1 -1
- package/dashboard/dist/assets/{useFilterParams-B7suPsIK.js → useFilterParams-crmlBw_l.js} +2 -2
- package/dashboard/dist/assets/{useFilterParams-B7suPsIK.js.map → useFilterParams-crmlBw_l.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-u-V1GVUD.js → useNamespace-DnFZfy7N.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-u-V1GVUD.js.map → useNamespace-DnFZfy7N.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-BhOZeqgE.js → useYamlActivityEvents-kx5CLENv.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-BhOZeqgE.js.map → useYamlActivityEvents-kx5CLENv.js.map} +1 -1
- package/dashboard/dist/assets/{users-BoXPwdee.js → users-DKng7vAG.js} +2 -2
- package/dashboard/dist/assets/{users-BoXPwdee.js.map → users-DKng7vAG.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-D71XjkNy.js → vendor-icons-CN-bAo9U.js} +144 -134
- package/dashboard/dist/assets/vendor-icons-CN-bAo9U.js.map +1 -0
- package/dashboard/dist/assets/{vendor-query-B2UbickB.js → vendor-query-RUZdMvN6.js} +2 -2
- package/dashboard/dist/assets/{vendor-query-B2UbickB.js.map → vendor-query-RUZdMvN6.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-react-C1YOyCSV.js → vendor-react-CdqEC2zv.js} +2 -2
- package/dashboard/dist/assets/{vendor-react-C1YOyCSV.js.map → vendor-react-CdqEC2zv.js.map} +1 -1
- package/dashboard/dist/assets/{workflows-mCoyKuLZ.js → workflows-C4V0rMkM.js} +2 -2
- package/dashboard/dist/assets/{workflows-mCoyKuLZ.js.map → workflows-C4V0rMkM.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-CWxXGDpn.js → yaml-workflows-D3PAiJ9d.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-CWxXGDpn.js.map → yaml-workflows-D3PAiJ9d.js.map} +1 -1
- package/dashboard/dist/index.html +5 -5
- package/docs/design-principles.md +9 -7
- package/docs/hitl/x-lt-embed.md +8 -4
- package/docs/hitl/x-lt-footer.md +68 -0
- package/docs/hitl/x-lt-list-schema.md +10 -3
- package/docs/hitl/x-lt-transition.md +105 -0
- package/docs/hitl-guide.md +9 -0
- package/docs/scan-codes.md +243 -0
- package/package.json +2 -2
- package/dashboard/dist/assets/AgentsPage-bSx_mdae.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-8pMC7Xv6.js +0 -2
- package/dashboard/dist/assets/BotPicker-C4uGH2x9.js +0 -2
- package/dashboard/dist/assets/CountdownTimer-D3t0XMhE.js +0 -2
- package/dashboard/dist/assets/CountdownTimer-D3t0XMhE.js.map +0 -1
- package/dashboard/dist/assets/EventTable-CIrrtL7_.js +0 -2
- package/dashboard/dist/assets/EventTable-CIrrtL7_.js.map +0 -1
- package/dashboard/dist/assets/FilterBar-CzjtH74v.js +0 -2
- package/dashboard/dist/assets/FilterBar-CzjtH74v.js.map +0 -1
- package/dashboard/dist/assets/ListToolbar-B2fub0DY.js +0 -2
- package/dashboard/dist/assets/McpQueryPage-CPkVwNIK.js +0 -2
- package/dashboard/dist/assets/McpRunDetailPage-D-Rz9MRw.js +0 -2
- package/dashboard/dist/assets/McpRunDetailPage-D-Rz9MRw.js.map +0 -1
- package/dashboard/dist/assets/OperationsPage-DlyGLPAs.js +0 -2
- package/dashboard/dist/assets/RunAsSelector-DdfecQ1U.js +0 -2
- package/dashboard/dist/assets/StickyPagination-cLddIdtT.js +0 -2
- package/dashboard/dist/assets/StickyPagination-cLddIdtT.js.map +0 -1
- package/dashboard/dist/assets/TimeAgo-C_H2TyZw.js +0 -2
- package/dashboard/dist/assets/TopicsPage-DoGqAdPm.js +0 -2
- package/dashboard/dist/assets/UserName-CKO_rk1R.js +0 -2
- package/dashboard/dist/assets/WorkflowExecutionPage-D3VQ9iQV.js +0 -2
- package/dashboard/dist/assets/WorkflowExecutionPage-D3VQ9iQV.js.map +0 -1
- package/dashboard/dist/assets/WorkflowsDashboard-DdJ86We6.js +0 -2
- package/dashboard/dist/assets/capabilities-DV_5ghHT.js +0 -2
- package/dashboard/dist/assets/index-B-WkiNRN.js +0 -6
- package/dashboard/dist/assets/index-B-WkiNRN.js.map +0 -1
- package/dashboard/dist/assets/index-CItsikDw.js +0 -2
- package/dashboard/dist/assets/index-CStR4uIU.js +0 -2
- package/dashboard/dist/assets/index-DbTD-dio.js +0 -63
- package/dashboard/dist/assets/index-DbTD-dio.js.map +0 -1
- package/dashboard/dist/assets/index-DnlsDaAw.css +0 -1
- package/dashboard/dist/assets/index-kzIIeVbx.js +0 -5
- package/dashboard/dist/assets/index-kzIIeVbx.js.map +0 -1
- package/dashboard/dist/assets/index-nIrYejxe.js +0 -5
- package/dashboard/dist/assets/vendor-icons-D71XjkNy.js.map +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as x,j as e}from"./vendor-query-RUZdMvN6.js";import{u as j}from"./topics-DPrL8Dtq.js";import{P as y}from"./PageHeader-BtIr6r-8.js";import{F as b,b as v,a as N}from"./FilterBar-Do7yR4xM.js";import{ba as k,bb as w,d as C,B as S,Z as T,an as B,Y as R,bc as q,R as g}from"./vendor-icons-CN-bAo9U.js";import{u as A}from"./vendor-react-CdqEC2zv.js";import"./index--DG-qQBT.js";const E={task:q,workflow:R,escalation:B,activity:T,knowledge:S,agent:C,app:w,milestone:k};function G(){const t=A(),[a,l]=x.useState(""),[c,f]=x.useState(null),{data:m,isLoading:p}=j({limit:500}),i=(m==null?void 0:m.topics)??[],d=x.useMemo(()=>{const s=new Set;for(const r of i)s.add(r.category);return Array.from(s).sort()},[i]),u=x.useMemo(()=>{const s=a.toLowerCase().trim();return(c?[c]:d).map(o=>({name:o,topics:i.filter(n=>{var h;return n.category===o&&(!s||n.topic.toLowerCase().includes(s)||((h=n.description)==null?void 0:h.toLowerCase().includes(s)))})})).filter(o=>o.topics.length>0)},[i,d,a,c]);return e.jsxs("div",{children:[e.jsx(y,{title:"Event Topics",docsHash:"#docs:topics.md"}),!p&&d.length>0&&e.jsxs(b,{children:[e.jsx(v,{label:"Category",value:c??"",onChange:s=>f(s||null),options:d.map(s=>({value:s,label:s}))}),e.jsx(N,{label:"Search",value:a,onChange:l,placeholder:`${i.length} topics…`})]}),p?e.jsx("div",{className:"animate-pulse space-y-8 mt-4",children:[1,2,3].map(s=>e.jsxs("div",{children:[e.jsx("div",{className:"h-4 bg-surface-sunken rounded w-28 mb-4"}),e.jsx("div",{className:"space-y-3",children:[1,2,3,4].map(r=>e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("div",{className:"h-3 bg-surface-sunken rounded w-64"}),e.jsx("div",{className:"h-3 bg-surface-sunken rounded w-full"})]},r))})]},s))}):u.length===0?e.jsx("p",{className:"text-sm text-text-tertiary mt-8",children:a||c?"No topics match your filter.":"No topics registered yet."}):e.jsx("div",{className:"space-y-10",children:u.map(({name:s,topics:r})=>{const o=E[s]??g;return e.jsxs("div",{children:[e.jsxs("div",{className:"sticky top-[60px] z-10 bg-surface flex items-center gap-2 py-2 mb-2 border-b border-surface-border",children:[e.jsx(o,{className:"w-3 h-3 text-accent",strokeWidth:1.5}),e.jsx("h2",{className:"section-h2 capitalize",children:s}),e.jsx("span",{className:"text-xs text-text-quaternary",children:r.length})]}),e.jsx("div",{className:"divide-y divide-surface-border/30",children:r.map(n=>e.jsx(F,{topic:n,onClick:()=>t(`/topics/${encodeURIComponent(n.topic)}`)},n.topic))})]},s)})})]})}function F({topic:t,onClick:a}){return e.jsx("div",{role:"button",tabIndex:0,onClick:a,onKeyDown:l=>{(l.key==="Enter"||l.key===" ")&&a()},className:"group py-2 px-3 -mx-3 rounded-md cursor-pointer transition-colors text-left",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(g,{className:"w-3 h-3 shrink-0 text-text-quaternary group-hover:text-text-tertiary transition-colors",strokeWidth:1.5}),e.jsx("span",{className:"text-xs font-mono text-text-primary truncate shrink-0 max-w-[24rem]",children:t.topic}),e.jsx("span",{className:"inline-flex items-center px-1.5 py-0.5 rounded text-2xs font-medium shrink-0 bg-accent/10 text-accent",children:t.category}),(t.subscriber_count??0)>0&&e.jsx("span",{className:"inline-flex items-center justify-center min-w-[18px] px-1 py-0.5 rounded-full text-2xs font-medium bg-accent/15 text-accent shrink-0",children:t.subscriber_count}),t.description&&e.jsx("p",{className:"flex-1 min-w-0 truncate text-2xs text-text-tertiary group-hover:text-text-secondary transition-colors",children:t.description}),e.jsx("span",{className:"ml-auto text-2xs font-mono text-text-quaternary shrink-0",children:t.source})]})})}export{G as TopicsPage};
|
|
2
|
+
//# sourceMappingURL=TopicsPage-Clr6Tl5P.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TopicsPage-
|
|
1
|
+
{"version":3,"file":"TopicsPage-Clr6Tl5P.js","sources":["../../src/pages/topics/TopicsPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n Radio,\n CheckSquare, GitBranch, AlertTriangle, Zap,\n BookOpen, Bot, AppWindow, Flag,\n} from 'lucide-react';\nimport { useTopics, type TopicCatalogEntry } from '../../api/topics';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { FilterBar, FilterSelect, FilterInput } from '../../components/common/data/FilterBar';\nimport type { LucideIcon } from 'lucide-react';\n\n// ── Category meta ──────────────────────────────────────────────────────────────\n\nconst CATEGORY_ICONS: Record<string, LucideIcon> = {\n task: CheckSquare,\n workflow: GitBranch,\n escalation: AlertTriangle,\n activity: Zap,\n knowledge: BookOpen,\n agent: Bot,\n app: AppWindow,\n milestone: Flag,\n};\n\n// ── Page ──────────────────────────────────────────────────────────────────────\n\nexport function TopicsPage() {\n const navigate = useNavigate();\n const [search, setSearch] = useState('');\n const [activeCategory, setActiveCategory] = useState<string | null>(null);\n\n const { data, isLoading } = useTopics({ limit: 500 });\n const allTopics: TopicCatalogEntry[] = data?.topics ?? [];\n\n const categories = useMemo(() => {\n const seen = new Set<string>();\n for (const t of allTopics) seen.add(t.category);\n return Array.from(seen).sort();\n }, [allTopics]);\n\n const grouped = useMemo(() => {\n const q = search.toLowerCase().trim();\n const cats = activeCategory ? [activeCategory] : categories;\n return cats\n .map((cat) => ({\n name: cat,\n topics: allTopics.filter(\n (t) =>\n t.category === cat &&\n (!q || t.topic.toLowerCase().includes(q) || t.description?.toLowerCase().includes(q)),\n ),\n }))\n .filter((g) => g.topics.length > 0);\n }, [allTopics, categories, search, activeCategory]);\n\n return (\n <div>\n <PageHeader title=\"Event Topics\" docsHash=\"#docs:topics.md\" />\n\n {/* Sticky filter bar: category select + search */}\n {!isLoading && categories.length > 0 && (\n <FilterBar>\n <FilterSelect\n label=\"Category\"\n value={activeCategory ?? ''}\n onChange={(v) => setActiveCategory(v || null)}\n options={categories.map((c) => ({ value: c, label: c }))}\n />\n <FilterInput\n label=\"Search\"\n value={search}\n onChange={setSearch}\n placeholder={`${allTopics.length} topics…`}\n />\n </FilterBar>\n )}\n\n {/* Topic list */}\n {isLoading ? (\n <div className=\"animate-pulse space-y-8 mt-4\">\n {[1, 2, 3].map((i) => (\n <div key={i}>\n <div className=\"h-4 bg-surface-sunken rounded w-28 mb-4\" />\n <div className=\"space-y-3\">\n {[1, 2, 3, 4].map((j) => (\n <div key={j} className=\"space-y-1.5\">\n <div className=\"h-3 bg-surface-sunken rounded w-64\" />\n <div className=\"h-3 bg-surface-sunken rounded w-full\" />\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n ) : grouped.length === 0 ? (\n <p className=\"text-sm text-text-tertiary mt-8\">\n {search || activeCategory ? 'No topics match your filter.' : 'No topics registered yet.'}\n </p>\n ) : (\n <div className=\"space-y-10\">\n {grouped.map(({ name, topics }) => {\n const Icon = CATEGORY_ICONS[name] ?? Radio;\n return (\n <div key={name}>\n <div className=\"sticky top-[60px] z-10 bg-surface flex items-center gap-2 py-2 mb-2 border-b border-surface-border\">\n <Icon className=\"w-3 h-3 text-accent\" strokeWidth={1.5} />\n <h2 className=\"section-h2 capitalize\">{name}</h2>\n <span className=\"text-xs text-text-quaternary\">{topics.length}</span>\n </div>\n <div className=\"divide-y divide-surface-border/30\">\n {topics.map((topic) => (\n <TopicRow\n key={topic.topic}\n topic={topic}\n onClick={() => navigate(`/topics/${encodeURIComponent(topic.topic)}`)}\n />\n ))}\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n\n// ── Topic row ──────────────────────────────────────────────────────────────────\n\nfunction TopicRow({ topic, onClick }: { topic: TopicCatalogEntry; onClick: () => void }) {\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={onClick}\n onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') onClick(); }}\n className=\"group py-2 px-3 -mx-3 rounded-md cursor-pointer transition-colors text-left\"\n >\n <div className=\"flex items-center gap-3\">\n <Radio className=\"w-3 h-3 shrink-0 text-text-quaternary group-hover:text-text-tertiary transition-colors\" strokeWidth={1.5} />\n <span className=\"text-xs font-mono text-text-primary truncate shrink-0 max-w-[24rem]\">{topic.topic}</span>\n <span className=\"inline-flex items-center px-1.5 py-0.5 rounded text-2xs font-medium shrink-0 bg-accent/10 text-accent\">\n {topic.category}\n </span>\n {(topic.subscriber_count ?? 0) > 0 && (\n <span className=\"inline-flex items-center justify-center min-w-[18px] px-1 py-0.5 rounded-full text-2xs font-medium bg-accent/15 text-accent shrink-0\">\n {topic.subscriber_count}\n </span>\n )}\n {topic.description && (\n <p className=\"flex-1 min-w-0 truncate text-2xs text-text-tertiary group-hover:text-text-secondary transition-colors\">\n {topic.description}\n </p>\n )}\n <span className=\"ml-auto text-2xs font-mono text-text-quaternary shrink-0\">{topic.source}</span>\n </div>\n </div>\n );\n}\n"],"names":["CATEGORY_ICONS","CheckSquare","GitBranch","AlertTriangle","Zap","BookOpen","Bot","AppWindow","Flag","TopicsPage","navigate","useNavigate","search","setSearch","useState","activeCategory","setActiveCategory","data","isLoading","useTopics","allTopics","categories","useMemo","seen","t","grouped","q","cat","_a","g","jsx","PageHeader","FilterBar","FilterSelect","v","c","FilterInput","i","j","jsxs","name","topics","Icon","Radio","topic","TopicRow","onClick","e"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{j as r}from"./vendor-query-RUZdMvN6.js";import{a as t}from"./users-DKng7vAG.js";function m({userId:a,fallback:s}){const{data:e}=t(a);return e?r.jsx(r.Fragment,{children:e.display_name||e.email||e.external_id}):r.jsx(r.Fragment,{children:s??`${a.slice(0,8)}…`})}export{m as U};
|
|
2
|
+
//# sourceMappingURL=UserName-BUVYyIAS.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserName-
|
|
1
|
+
{"version":3,"file":"UserName-BUVYyIAS.js","sources":["../../src/components/common/display/UserName.tsx"],"sourcesContent":["import { useUser } from '../../../api/users';\n\n/**\n * Resolves a user ID to their display name (or email, or truncated ID as fallback).\n * Renders inline — suitable for use inside <span>, <p>, etc.\n */\nexport function UserName({ userId, fallback }: { userId: string; fallback?: string }) {\n const { data: resolved } = useUser(userId);\n\n if (resolved) {\n return <>{resolved.display_name || resolved.email || resolved.external_id}</>;\n }\n\n // Still loading or no record — show fallback or truncated ID\n return <>{fallback ?? `${userId.slice(0, 8)}…`}</>;\n}\n"],"names":["UserName","userId","fallback","resolved","useUser","jsx","Fragment"],"mappings":"uFAMO,SAASA,EAAS,CAAE,OAAAC,EAAQ,SAAAC,GAAmD,CACpF,KAAM,CAAE,KAAMC,GAAaC,EAAQH,CAAM,EAEzC,OAAIE,oBACQ,SAAAA,EAAS,cAAgBA,EAAS,OAASA,EAAS,YAAY,EAIrEE,EAAAA,IAAAC,EAAAA,SAAA,CAAG,YAAY,GAAGL,EAAO,MAAM,EAAG,CAAC,CAAC,GAAA,CAAI,CACjD"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as w,j as e}from"./vendor-query-RUZdMvN6.js";import{a as U,f as F}from"./workflows-C4V0rMkM.js";import{h as Q}from"./useEventHooks-DXCgDgiu.js";import{u as J,E as M}from"./EventTable-Bfi-f8as.js";import{b as z,e as H}from"./tasks-CJdjjhgO.js";import{P as d,b,D as K,c as q,d as Y,J as T,h as Z}from"./index--DG-qQBT.js";import{P as G}from"./PageHeader-BtIr6r-8.js";import{S as X}from"./SegmentedTabs-DXNzY05q.js";import{L as ee}from"./ListToolbar-CLtw-1QN.js";import{S as N}from"./StatusBadge-DkgllZHv.js";import{C as g}from"./CopyableId-4Lqlc5cU.js";import{J as C,aq as te,K as se,O as ae,Q as re,V as ne,s as le}from"./vendor-icons-CN-bAo9U.js";import{L as m,e as oe,u as ie}from"./vendor-react-CdqEC2zv.js";import{S as ce}from"./SwimlaneTimeline-DMY0jL2F.js";import"./FilterBar-Do7yR4xM.js";import"./StreamMessageDetail-DEeuh4_-.js";function de(t){const s=t.lastIndexOf("-");return s<=0?{taskQueue:t,workflowType:t}:{taskQueue:t.substring(0,s),workflowType:t.substring(s+1)}}function xe({children:t}){return e.jsx("p",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-2",children:t})}function ue({escalations:t}){return e.jsx("div",{children:t.map(s=>e.jsxs(m,{to:`/escalations/detail/${s.id}`,className:"grid grid-cols-[1fr_auto_auto] items-center gap-x-3 py-2 border-b border-surface-border/40 last:border-b-0 group",children:[e.jsxs("span",{className:"min-w-0",children:[e.jsx("span",{className:"block text-xs font-mono text-text-primary group-hover:text-accent transition-colors truncate",title:s.type,children:s.type}),e.jsx("span",{className:"block text-2xs text-text-tertiary truncate",children:s.role})]}),e.jsx(b,{date:s.created_at,format:"relative",className:"text-2xs text-text-tertiary whitespace-nowrap"}),e.jsx("span",{className:"w-20 flex justify-end",children:e.jsx(N,{status:s.status})})]},s.id))})}function me({tasks:t}){return e.jsx("div",{children:t.map(s=>e.jsxs(m,{to:`/workflows/tasks/detail/${s.id}`,className:"grid grid-cols-[1fr_auto_auto] items-center gap-x-3 py-2 border-b border-surface-border/40 last:border-b-0 group",children:[e.jsxs("span",{className:"min-w-0",children:[e.jsx("span",{className:"block text-xs font-mono text-text-primary group-hover:text-accent transition-colors truncate",title:s.workflow_type,children:s.workflow_type}),e.jsx("span",{className:"block text-2xs text-text-tertiary truncate",children:s.lt_type})]}),e.jsx(b,{date:s.created_at,format:"relative",className:"text-2xs text-text-tertiary whitespace-nowrap"}),e.jsx("span",{className:"w-20 flex justify-end",children:e.jsx(N,{status:s.status})})]},s.id))})}function fe({execution:t,parentWorkflowId:s,childTasks:a,escalations:n,headerActions:l,open:i}){const u=n.length>0||a.length>0,[x,o]=w.useState(u?"escalations":"details"),{taskQueue:f,workflowType:j}=de(t.workflow_type),p=[{id:"details",icon:C,label:"Details",content:e.jsxs("dl",{className:"space-y-3.5",children:[e.jsx(d,{label:"Status",children:e.jsx(N,{status:t.status})}),e.jsx(d,{label:"Workflow Type",children:e.jsx(g,{bare:!0,value:j,href:`/workflows/executions?entity=${encodeURIComponent(j)}`})}),e.jsx(d,{label:"Workflow ID",children:e.jsx(g,{bare:!0,value:t.workflow_id})}),s&&e.jsx(d,{label:"Parent",children:e.jsx(g,{bare:!0,value:s,href:`/workflows/executions/${s}`})}),e.jsx(d,{label:"Task Queue",children:e.jsx("span",{className:"font-mono",children:f})}),e.jsx(d,{label:"Start Time",children:t.start_time?e.jsx(b,{date:t.start_time,format:"datetime"}):e.jsx("span",{className:"text-text-tertiary",children:"--"})}),e.jsx(d,{label:"End Time",children:t.close_time?e.jsx(b,{date:t.close_time,format:"datetime"}):e.jsx("span",{className:"text-text-tertiary",children:"--"})}),e.jsx(d,{label:"Duration",children:e.jsx(K,{ms:t.duration_ms,className:"font-mono"})}),e.jsxs(d,{label:"History Size",children:[t.summary.total_events," events"]}),e.jsxs(d,{label:"Activities",children:[t.summary.activities.completed," / ",t.summary.activities.total]})]})},{id:"escalations",icon:te,label:"Escalations",content:e.jsxs("div",{className:"space-y-6",children:[e.jsx("div",{children:n.length>0?e.jsx(ue,{escalations:n}):e.jsx("p",{className:"text-xs text-text-tertiary italic",children:"This workflow has not escalated."})}),a.length>0&&e.jsxs("div",{children:[e.jsx(xe,{children:"Related Tasks"}),e.jsx(me,{tasks:a})]})]})}];return e.jsx(q,{open:i,width:384,className:"h-full",children:e.jsx("div",{className:"h-full pl-6",children:e.jsx(Y,{views:p,activeId:x,onViewChange:o,headerActions:l,stickyClassName:"h-full min-h-0",labelInline:!0})})})}function pe(t){var n;const s=t.events.find(l=>l.event_type==="workflow_execution_started"),a=(n=s==null?void 0:s.attributes)==null?void 0:n.input;return a&&typeof a=="object"?a:null}function he({execution:t}){const s=pe(t),a=t.result,n=(a==null?void 0:a.data)??a??null;return!s&&!n?null:e.jsxs("div",{className:"grid grid-cols-1 @form-cols:grid-cols-2 gap-4 mb-6",children:[s!==null&&e.jsx("div",{children:e.jsx(T,{data:s,label:"Input Envelope"})}),n!==null&&e.jsx("div",{children:e.jsx(T,{data:n,label:"Result"})})]})}const we=["details","timeline","events"],E="lt:workflow-execution:tab";function je({isRunning:t,hasToolCalls:s,workflowId:a,onAction:n}){const[l,i]=w.useState(!1),u=w.useRef(null);return w.useEffect(()=>{if(!l)return;const x=o=>{u.current&&!u.current.contains(o.target)&&i(!1)};return document.addEventListener("mousedown",x),()=>document.removeEventListener("mousedown",x)},[l]),e.jsxs("div",{className:"relative",ref:u,children:[e.jsxs("button",{onClick:()=>i(!l),className:"flex items-center gap-0.5 pl-2 pr-1 py-1 rounded-md text-2xs font-medium text-accent hover:text-accent-hover hover:bg-surface-hover transition-colors",title:"Actions",children:["Actions",e.jsx(le,{className:`w-3 h-3 transition-transform ${l?"rotate-180":""}`})]}),l&&e.jsxs("div",{className:"absolute right-0 mt-1 w-44 bg-surface-raised border border-surface-border rounded-md shadow-lg z-[100]",children:[e.jsx("button",{onClick:()=>{n("restart"),i(!1)},className:"block w-full text-left px-4 py-2 text-xs text-text-secondary hover:bg-surface-hover",children:"Restart Workflow"}),t&&e.jsx("button",{onClick:()=>{n("terminate"),i(!1)},className:"block w-full text-left px-4 py-2 text-xs text-status-error hover:bg-surface-hover",children:"Terminate"}),s&&e.jsx(m,{to:`/mcp/queries/${a}?step=3`,className:"block w-full text-left px-4 py-2 text-xs text-accent hover:bg-surface-hover",onClick:()=>i(!1),children:"Compile into Pipeline"}),e.jsx(m,{to:`/mcp/executions/${encodeURIComponent(a)}?namespace=durable`,className:"block w-full text-left px-4 py-2 text-xs text-text-secondary hover:bg-surface-hover",onClick:()=>i(!1),children:"View Pipeline Execution"}),e.jsx(m,{to:`/admin/streams?source=worker&jid=${encodeURIComponent(a)}`,className:"block w-full text-left px-4 py-2 text-xs text-text-secondary hover:bg-surface-hover",onClick:()=>i(!1),children:"Worker Messages"}),e.jsx(m,{to:`/admin/streams?source=engine&jid=${encodeURIComponent(a)}`,className:"block w-full text-left px-4 py-2 text-xs text-text-secondary hover:bg-surface-hover",onClick:()=>i(!1),children:"Engine Messages"})]})]})}function $e(){const{workflowId:t}=oe();Q(t);const s="Workflow Execution",{data:a,isLoading:n,error:l,refetch:i,isFetching:u}=U(t),{data:x}=z(t),{data:o}=H(t),{data:f}=Z(t),j=ie(),p=F(),{isCollapsed:S,toggle:I}=J("workflow-execution"),[h,P]=w.useState(()=>{try{const r=localStorage.getItem(E);return r&&we.includes(r)?r:"details"}catch{return"details"}}),R=r=>{P(r);try{localStorage.setItem(E,r)}catch{}},W=r=>{var c;if(r==="terminate")confirm("Are you sure you want to terminate this workflow?")&&p.mutate(t);else if(r==="restart"&&a){const D=a.workflow_id.replace(/-[A-Za-z0-9_-]{20,}$/,""),y=a.events.find(O=>O.event_type==="workflow_execution_started"),_=(c=y==null?void 0:y.attributes)==null?void 0:c.input;_&&sessionStorage.setItem("lt:invoke:prefill",JSON.stringify(_)),j(`/workflows/start?type=${encodeURIComponent(D)}&mode=now`)}};if(n)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(l||!a){const r=(l==null?void 0:l.message)??"",c=r.includes("expired")||r.includes("no longer available");return e.jsxs("div",{children:[e.jsx(m,{to:"/workflows/executions",className:"text-xs text-text-tertiary hover:text-text-primary",children:"← Workflows"}),e.jsxs("div",{className:"mt-4 text-center py-8",children:[e.jsx("p",{className:"text-sm text-text-primary mb-1",children:c?"Execution data is no longer available":l?"Unable to load execution":"Execution not found"}),e.jsx("p",{className:"text-xs text-text-tertiary",children:c?"This workflow's underlying job has expired. The task record is preserved, but the execution timeline has been cleaned up.":r||"The workflow could not be resolved."})]})]})}const A=a.status!=="completed"&&a.status!=="failed",v=!S("side-panel"),$=a.parent_workflow_id,L=x&&x.workflow_id===a.workflow_id,k=$||(L?x.parent_workflow_id:null)||null,V=k&&k!==a.workflow_id?k:null,B=a.status==="completed"&&a.events.some(r=>{if(r.event_type!=="activity_task_completed")return!1;const c=r.attributes.activity_type;return c==="callDbTool"||c==="callVisionTool"||c==="callMcpTool"||(c==null?void 0:c.startsWith("mcp_"))});return e.jsxs("div",{className:"flex-1 min-h-0 min-w-0 flex items-stretch -mt-8 -mr-page-x -mb-16",children:[e.jsxs("div",{className:"flex-1 min-w-0 flex flex-col min-h-0",children:[e.jsxs("div",{className:"shrink-0 pt-8 pr-page-x",children:[e.jsx(G,{title:s,actions:e.jsx("button",{onClick:()=>I("side-panel"),className:"text-accent/60 hover:text-accent transition-colors",title:v?"Hide side panel":"Show side panel",children:v?e.jsx(se,{className:"w-5 h-5",strokeWidth:1.5}):e.jsx(ae,{className:"w-5 h-5",strokeWidth:1.5})})}),p.error&&e.jsxs("p",{className:"text-xs text-status-error py-2",children:["Terminate failed: ",p.error.message]}),e.jsx("div",{className:"mt-2",children:e.jsx(X,{"aria-label":"Execution section",active:h,onChange:R,tabs:[{key:"details",label:"Details",icon:e.jsx(C,{className:"w-3.5 h-3.5"})},{key:"timeline",label:"Execution Timeline",icon:e.jsx(re,{className:"w-3.5 h-3.5"})},{key:"events",label:"Events",icon:e.jsx(ne,{className:"w-3.5 h-3.5"})}]})})]}),e.jsxs("div",{className:"flex-1 min-h-0 overflow-y-auto pr-page-x pt-6 pb-16 animate-page-in",children:[h==="details"&&e.jsx(he,{execution:a}),h==="timeline"&&e.jsx(ce,{events:a.events,childTasks:o==null?void 0:o.tasks,jid:t,appId:"durable"}),h==="events"&&e.jsx(M,{events:a.events,childTasks:o==null?void 0:o.tasks,jid:t,appId:"durable"})]},h)]}),e.jsx(fe,{execution:a,parentWorkflowId:V,childTasks:(o==null?void 0:o.tasks)??[],escalations:(f==null?void 0:f.escalations)??[],headerActions:e.jsxs(e.Fragment,{children:[e.jsx(ee,{onRefresh:()=>i(),isFetching:u,apiPath:`/workflow-states/${t}/execution`}),e.jsx(je,{isRunning:A,hasToolCalls:B,workflowId:t,onAction:W})]}),open:v})]})}export{$e as WorkflowExecutionPage};
|
|
2
|
+
//# sourceMappingURL=WorkflowExecutionPage-kncWFfe5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkflowExecutionPage-kncWFfe5.js","sources":["../../src/pages/workflows/workflow-execution/ExecutionSidePanel.tsx","../../src/pages/workflows/workflow-execution/ExecutionInputResult.tsx","../../src/pages/workflows/WorkflowExecutionPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { Link } from 'react-router-dom';\nimport { Info, Bell } from 'lucide-react';\nimport { SlidePanel, SlidePanelViews, PanelField, type SlidePanelView } from '../../../components/common/layout/SlidePanel';\nimport { StatusBadge } from '../../../components/common/display/StatusBadge';\nimport { CopyableId } from '../../../components/common/display/CopyableId';\nimport { DateValue } from '../../../components/common/display/DateValue';\nimport { DurationValue } from '../../../components/common/display/DurationValue';\nimport type { WorkflowExecution, LTTaskRecord, LTEscalationRecord } from '../../../api/types';\n\n/**\n * Split a HotMesh compound entity key (taskQueue-workflowName) on the last '-'.\n * Workflow names are camelCase, so the last segment is always the workflow type.\n */\nfunction splitEntityKey(compound: string): { taskQueue: string; workflowType: string } {\n const lastDash = compound.lastIndexOf('-');\n if (lastDash <= 0) return { taskQueue: compound, workflowType: compound };\n return {\n taskQueue: compound.substring(0, lastDash),\n workflowType: compound.substring(lastDash + 1),\n };\n}\n\nfunction SectionLabel({ children }: { children: React.ReactNode }) {\n return (\n <p className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-2\">\n {children}\n </p>\n );\n}\n\n/**\n * A workflow can escalate to multiple targets, and multiple times across its\n * lifecycle — each escalation is its own row: role and type on the left, the\n * status badge in a right-aligned column, so a long history reads as a table\n * instead of running on.\n */\nfunction EscalationRows({ escalations }: { escalations: LTEscalationRecord[] }) {\n return (\n <div>\n {escalations.map((esc) => (\n <Link\n key={esc.id}\n to={`/escalations/detail/${esc.id}`}\n className=\"grid grid-cols-[1fr_auto_auto] items-center gap-x-3 py-2 border-b border-surface-border/40 last:border-b-0 group\"\n >\n <span className=\"min-w-0\">\n <span className=\"block text-xs font-mono text-text-primary group-hover:text-accent transition-colors truncate\" title={esc.type}>\n {esc.type}\n </span>\n <span className=\"block text-2xs text-text-tertiary truncate\">{esc.role}</span>\n </span>\n <DateValue date={esc.created_at} format=\"relative\" className=\"text-2xs text-text-tertiary whitespace-nowrap\" />\n <span className=\"w-20 flex justify-end\"><StatusBadge status={esc.status} /></span>\n </Link>\n ))}\n </div>\n );\n}\n\nfunction TaskRows({ tasks }: { tasks: LTTaskRecord[] }) {\n return (\n <div>\n {tasks.map((t) => (\n <Link\n key={t.id}\n to={`/workflows/tasks/detail/${t.id}`}\n className=\"grid grid-cols-[1fr_auto_auto] items-center gap-x-3 py-2 border-b border-surface-border/40 last:border-b-0 group\"\n >\n <span className=\"min-w-0\">\n <span className=\"block text-xs font-mono text-text-primary group-hover:text-accent transition-colors truncate\" title={t.workflow_type}>\n {t.workflow_type}\n </span>\n <span className=\"block text-2xs text-text-tertiary truncate\">{t.lt_type}</span>\n </span>\n <DateValue date={t.created_at} format=\"relative\" className=\"text-2xs text-text-tertiary whitespace-nowrap\" />\n <span className=\"w-20 flex justify-end\"><StatusBadge status={t.status} /></span>\n </Link>\n ))}\n </div>\n );\n}\n\n/**\n * The execution detail side panel — the record's facts beside the timeline:\n *\n * Details — workflow identity, timing, and history metadata\n * Escalations — every escalation the workflow raised, plus related tasks\n */\nexport function ExecutionSidePanel({\n execution,\n parentWorkflowId,\n childTasks,\n escalations,\n headerActions,\n open,\n}: {\n execution: WorkflowExecution;\n parentWorkflowId: string | null;\n childTasks: LTTaskRecord[];\n escalations: LTEscalationRecord[];\n /** Page controls (toolbar, Actions menu) shown at the right of the icon row. */\n headerActions?: React.ReactNode;\n open: boolean;\n}) {\n const hasRelated = escalations.length > 0 || childTasks.length > 0;\n const [activeView, setActiveView] = useState(hasRelated ? 'escalations' : 'details');\n\n const { taskQueue, workflowType } = splitEntityKey(execution.workflow_type);\n\n const views: SlidePanelView[] = [\n {\n id: 'details',\n icon: Info,\n label: 'Details',\n content: (\n <dl className=\"space-y-3.5\">\n <PanelField label=\"Status\"><StatusBadge status={execution.status} /></PanelField>\n <PanelField label=\"Workflow Type\">\n <CopyableId bare value={workflowType} href={`/workflows/executions?entity=${encodeURIComponent(workflowType)}`} />\n </PanelField>\n <PanelField label=\"Workflow ID\">\n <CopyableId bare value={execution.workflow_id} />\n </PanelField>\n {parentWorkflowId && (\n <PanelField label=\"Parent\">\n <CopyableId bare value={parentWorkflowId} href={`/workflows/executions/${parentWorkflowId}`} />\n </PanelField>\n )}\n <PanelField label=\"Task Queue\"><span className=\"font-mono\">{taskQueue}</span></PanelField>\n <PanelField label=\"Start Time\">\n {execution.start_time\n ? <DateValue date={execution.start_time} format=\"datetime\" />\n : <span className=\"text-text-tertiary\">--</span>}\n </PanelField>\n <PanelField label=\"End Time\">\n {execution.close_time\n ? <DateValue date={execution.close_time} format=\"datetime\" />\n : <span className=\"text-text-tertiary\">--</span>}\n </PanelField>\n <PanelField label=\"Duration\">\n <DurationValue ms={execution.duration_ms} className=\"font-mono\" />\n </PanelField>\n <PanelField label=\"History Size\">{execution.summary.total_events} events</PanelField>\n <PanelField label=\"Activities\">\n {execution.summary.activities.completed} / {execution.summary.activities.total}\n </PanelField>\n </dl>\n ),\n },\n {\n id: 'escalations',\n icon: Bell,\n label: 'Escalations',\n content: (\n <div className=\"space-y-6\">\n <div>\n {escalations.length > 0\n ? <EscalationRows escalations={escalations} />\n : <p className=\"text-xs text-text-tertiary italic\">This workflow has not escalated.</p>}\n </div>\n {childTasks.length > 0 && (\n <div>\n <SectionLabel>Related Tasks</SectionLabel>\n <TaskRows tasks={childTasks} />\n </div>\n )}\n </div>\n ),\n },\n ];\n\n return (\n <SlidePanel open={open} width={384} className=\"h-full\">\n <div className=\"h-full pl-6\">\n <SlidePanelViews\n views={views}\n activeId={activeView}\n onViewChange={setActiveView}\n headerActions={headerActions}\n stickyClassName=\"h-full min-h-0\"\n labelInline\n />\n </div>\n </SlidePanel>\n );\n}\n","import { JsonViewer } from '../../../components/common/data/JsonViewer';\nimport type { WorkflowExecution } from '../../../api/types';\n\ninterface ExecutionInputResultProps {\n execution: WorkflowExecution;\n}\n\n/**\n * Extract the workflow input envelope from the workflow_execution_started event.\n * HotMesh 0.13.0+ includes the actual trigger arguments (the envelope passed\n * to startWorkflow) in the start event's `input` attribute.\n */\nfunction extractInput(execution: WorkflowExecution): Record<string, unknown> | null {\n const startEvent = execution.events.find(\n (e) => e.event_type === 'workflow_execution_started',\n );\n const input = (startEvent?.attributes as any)?.input;\n return input && typeof input === 'object' ? input : null;\n}\n\nexport function ExecutionInputResult({ execution }: ExecutionInputResultProps) {\n const input = extractInput(execution);\n\n // Result: unwrap the workflow return — the `data` field is what LT users care about\n const rawResult = execution.result as Record<string, unknown> | null | undefined;\n const result = rawResult?.data ?? rawResult ?? null;\n\n if (!input && !result) return null;\n\n return (\n <div className=\"grid grid-cols-1 @form-cols:grid-cols-2 gap-4 mb-6\">\n {input !== null && (\n <div>\n <JsonViewer data={input} label=\"Input Envelope\" />\n </div>\n )}\n {result !== null && (\n <div>\n <JsonViewer data={result} label=\"Result\" />\n </div>\n )}\n </div>\n );\n}\n","import { useState, useRef, useEffect } from 'react';\nimport { useParams, useNavigate, Link } from 'react-router-dom';\nimport { useWorkflowExecution, useTerminateWorkflow } from '../../api/workflows';\nimport { useWorkflowDetailEvents } from '../../hooks/useEventHooks';\nimport { useCollapsedSections } from '../../hooks/useCollapsedSections';\nimport { useTaskByWorkflowId, useChildTasks } from '../../api/tasks';\nimport { useEscalationsByWorkflowId } from '../../api/escalations';\n\nimport { PanelRightClose, PanelRightOpen, ChevronDown, Info, Activity, List } from 'lucide-react';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { SegmentedTabs } from '../../components/common/layout/SegmentedTabs';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\n\nimport { ExecutionSidePanel } from './workflow-execution/ExecutionSidePanel';\nimport { ExecutionInputResult } from './workflow-execution/ExecutionInputResult';\nimport { SwimlaneTimeline } from './workflow-execution/SwimlaneTimeline';\nimport { EventTable } from './workflow-execution/EventTable';\n\ntype WfTab = 'details' | 'timeline' | 'events';\nconst WF_TABS = ['details', 'timeline', 'events'] as const;\nconst WF_TAB_KEY = 'lt:workflow-execution:tab';\n\nfunction ActionsDropdown({ isRunning, hasToolCalls, workflowId, onAction }: {\n isRunning: boolean;\n hasToolCalls: boolean;\n workflowId: string;\n onAction: (action: 'restart' | 'terminate') => 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 return (\n <div className=\"relative\" ref={ref}>\n <button\n onClick={() => setOpen(!open)}\n className=\"flex items-center gap-0.5 pl-2 pr-1 py-1 rounded-md text-2xs font-medium text-accent hover:text-accent-hover hover:bg-surface-hover transition-colors\"\n title=\"Actions\"\n >\n Actions\n <ChevronDown className={`w-3 h-3 transition-transform ${open ? 'rotate-180' : ''}`} />\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-[100]\">\n <button\n onClick={() => { onAction('restart'); setOpen(false); }}\n className=\"block w-full text-left px-4 py-2 text-xs text-text-secondary hover:bg-surface-hover\"\n >\n Restart Workflow\n </button>\n {isRunning && (\n <button\n onClick={() => { onAction('terminate'); 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 )}\n {hasToolCalls && (\n <Link\n to={`/mcp/queries/${workflowId}?step=3`}\n className=\"block w-full text-left px-4 py-2 text-xs text-accent hover:bg-surface-hover\"\n onClick={() => setOpen(false)}\n >\n Compile into Pipeline\n </Link>\n )}\n <Link\n to={`/mcp/executions/${encodeURIComponent(workflowId)}?namespace=durable`}\n className=\"block w-full text-left px-4 py-2 text-xs text-text-secondary hover:bg-surface-hover\"\n onClick={() => setOpen(false)}\n >\n View Pipeline Execution\n </Link>\n <Link\n to={`/admin/streams?source=worker&jid=${encodeURIComponent(workflowId)}`}\n className=\"block w-full text-left px-4 py-2 text-xs text-text-secondary hover:bg-surface-hover\"\n onClick={() => setOpen(false)}\n >\n Worker Messages\n </Link>\n <Link\n to={`/admin/streams?source=engine&jid=${encodeURIComponent(workflowId)}`}\n className=\"block w-full text-left px-4 py-2 text-xs text-text-secondary hover:bg-surface-hover\"\n onClick={() => setOpen(false)}\n >\n Engine Messages\n </Link>\n </div>\n )}\n </div>\n );\n}\n\nexport function WorkflowExecutionPage() {\n const { workflowId } = useParams<{ workflowId: string }>();\n useWorkflowDetailEvents(workflowId);\n\n const executionTitle = 'Workflow Execution';\n const { data: execution, isLoading, error, refetch, isFetching } = useWorkflowExecution(workflowId!);\n const { data: task } = useTaskByWorkflowId(workflowId!);\n const { data: childTasksData } = useChildTasks(workflowId!);\n const { data: escalationsData } = useEscalationsByWorkflowId(workflowId);\n const navigate = useNavigate();\n const terminateMutation = useTerminateWorkflow();\n const { isCollapsed, toggle } = useCollapsedSections('workflow-execution');\n\n // The main content is a segmented switch, not an accordion: one section shows\n // at a time and the tabs sit at the top. The choice persists across visits.\n const [tab, setTab] = useState<WfTab>(() => {\n try {\n const saved = localStorage.getItem(WF_TAB_KEY) as WfTab | null;\n return saved && WF_TABS.includes(saved) ? saved : 'details';\n } catch {\n return 'details';\n }\n });\n const selectTab = (next: WfTab) => {\n setTab(next);\n try { localStorage.setItem(WF_TAB_KEY, next); } catch { /* private mode */ }\n };\n\n const handleAction = (action: 'restart' | 'terminate') => {\n if (action === 'terminate') {\n if (confirm('Are you sure you want to terminate this workflow?')) {\n terminateMutation.mutate(workflowId!);\n }\n } else if (action === 'restart' && execution) {\n // Extract entity from workflow_id (format: {entity}-{guid})\n const entity = execution.workflow_id.replace(/-[A-Za-z0-9_-]{20,}$/, '');\n // Extract original input from the started event\n const startEvent = execution.events.find((e) => e.event_type === 'workflow_execution_started');\n const input = (startEvent?.attributes as any)?.input;\n if (input) {\n sessionStorage.setItem('lt:invoke:prefill', JSON.stringify(input));\n }\n navigate(`/workflows/start?type=${encodeURIComponent(entity)}&mode=now`);\n }\n };\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 const msg = (error as Error)?.message ?? '';\n const isExpired = msg.includes('expired') || msg.includes('no longer available');\n\n return (\n <div>\n <Link to=\"/workflows/executions\" className=\"text-xs text-text-tertiary hover:text-text-primary\">\n ← Workflows\n </Link>\n <div className=\"mt-4 text-center py-8\">\n <p className=\"text-sm text-text-primary mb-1\">\n {isExpired\n ? 'Execution data is no longer available'\n : error\n ? 'Unable to load execution'\n : 'Execution not found'}\n </p>\n <p className=\"text-xs text-text-tertiary\">\n {isExpired\n ? \"This workflow's underlying job has expired. The task record is preserved, but the execution timeline has been cleaned up.\"\n : msg || 'The workflow could not be resolved.'}\n </p>\n </div>\n </div>\n );\n }\n\n const isRunning = execution.status !== 'completed' && execution.status !== 'failed';\n const sidePanelOpen = !isCollapsed('side-panel');\n\n // Parent relationship — prefer execution-level pj (from HotMesh raw state),\n // fall back to lt_tasks record. Self-references filtered (cron-invoked\n // workflows store themselves as parent).\n const executionParent = (execution as any).parent_workflow_id as string | undefined;\n const isLeaf = task && task.workflow_id === execution.workflow_id;\n const rawParent = executionParent || (isLeaf ? task.parent_workflow_id : null) || null;\n const parentWorkflowId = rawParent && rawParent !== execution.workflow_id ? rawParent : null;\n const hasToolCalls = execution.status === 'completed' && execution.events.some(\n (e) => {\n if (e.event_type !== 'activity_task_completed') return false;\n const actType = (e.attributes as any).activity_type;\n return actType === 'callDbTool' || actType === 'callVisionTool' || actType === 'callMcpTool' || actType?.startsWith('mcp_');\n },\n );\n\n return (\n // Two fixed-height columns, like the escalation detail page: the header and\n // tab strip stay put while only the active section scrolls, and the side\n // panel is affixed with its own internal scroll. Negative margins let the\n // panel bleed to the page edge; the left column re-adds the gutters.\n <div className=\"flex-1 min-h-0 min-w-0 flex items-stretch -mt-8 -mr-page-x -mb-16\">\n <div className=\"flex-1 min-w-0 flex flex-col min-h-0\">\n {/* Fixed header: title + the panel toggle, then the tab strip. The\n toolbar, status, and Actions menu all live in the panel. */}\n <div className=\"shrink-0 pt-8 pr-page-x\">\n <PageHeader\n title={executionTitle}\n actions={\n <button\n onClick={() => toggle('side-panel')}\n className=\"text-accent/60 hover:text-accent transition-colors\"\n title={sidePanelOpen ? 'Hide side panel' : 'Show side panel'}\n >\n {sidePanelOpen\n ? <PanelRightClose className=\"w-5 h-5\" strokeWidth={1.5} />\n : <PanelRightOpen className=\"w-5 h-5\" strokeWidth={1.5} />}\n </button>\n }\n />\n\n {terminateMutation.error && (\n <p className=\"text-xs text-status-error py-2\">\n Terminate failed: {terminateMutation.error.message}\n </p>\n )}\n\n <div className=\"mt-2\">\n <SegmentedTabs<WfTab>\n aria-label=\"Execution section\"\n active={tab}\n onChange={selectTab}\n tabs={[\n { key: 'details', label: 'Details', icon: <Info className=\"w-3.5 h-3.5\" /> },\n { key: 'timeline', label: 'Execution Timeline', icon: <Activity className=\"w-3.5 h-3.5\" /> },\n { key: 'events', label: 'Events', icon: <List className=\"w-3.5 h-3.5\" /> },\n ]}\n />\n </div>\n </div>\n\n {/* Only the active section scrolls; the key restarts the reveal and\n resets the scroll position on each switch. */}\n <div key={tab} className=\"flex-1 min-h-0 overflow-y-auto pr-page-x pt-6 pb-16 animate-page-in\">\n {tab === 'details' && <ExecutionInputResult execution={execution} />}\n {tab === 'timeline' && (\n <SwimlaneTimeline\n events={execution.events}\n childTasks={childTasksData?.tasks}\n jid={workflowId}\n appId=\"durable\"\n />\n )}\n {tab === 'events' && (\n <EventTable\n events={execution.events}\n childTasks={childTasksData?.tasks}\n jid={workflowId}\n appId=\"durable\"\n />\n )}\n </div>\n </div>\n\n <ExecutionSidePanel\n execution={execution}\n parentWorkflowId={parentWorkflowId}\n childTasks={childTasksData?.tasks ?? []}\n escalations={escalationsData?.escalations ?? []}\n headerActions={\n <>\n <ListToolbar\n onRefresh={() => refetch()}\n isFetching={isFetching}\n apiPath={`/workflow-states/${workflowId}/execution`}\n />\n <ActionsDropdown\n isRunning={isRunning}\n hasToolCalls={hasToolCalls}\n workflowId={workflowId!}\n onAction={handleAction}\n />\n </>\n }\n open={sidePanelOpen}\n />\n </div>\n );\n}\n"],"names":["splitEntityKey","compound","lastDash","SectionLabel","children","jsx","EscalationRows","escalations","esc","jsxs","Link","DateValue","StatusBadge","TaskRows","tasks","t","ExecutionSidePanel","execution","parentWorkflowId","childTasks","headerActions","open","hasRelated","activeView","setActiveView","useState","taskQueue","workflowType","views","Info","PanelField","CopyableId","DurationValue","Bell","SlidePanel","SlidePanelViews","extractInput","startEvent","e","input","_a","ExecutionInputResult","rawResult","result","JsonViewer","WF_TABS","WF_TAB_KEY","ActionsDropdown","isRunning","hasToolCalls","workflowId","onAction","setOpen","ref","useRef","useEffect","handler","ChevronDown","WorkflowExecutionPage","useParams","useWorkflowDetailEvents","executionTitle","isLoading","error","refetch","isFetching","useWorkflowExecution","task","useTaskByWorkflowId","childTasksData","useChildTasks","escalationsData","useEscalationsByWorkflowId","navigate","useNavigate","terminateMutation","useTerminateWorkflow","isCollapsed","toggle","useCollapsedSections","tab","setTab","saved","selectTab","next","handleAction","action","entity","msg","isExpired","sidePanelOpen","executionParent","isLeaf","rawParent","actType","PageHeader","PanelRightClose","PanelRightOpen","SegmentedTabs","Activity","List","SwimlaneTimeline","EventTable","Fragment","ListToolbar"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as e}from"./vendor-query-
|
|
2
|
-
//# sourceMappingURL=WorkflowPill-
|
|
1
|
+
import{j as e}from"./vendor-query-RUZdMvN6.js";import{W as i,Z as o,k as p,g as c,aC as x}from"./vendor-icons-CN-bAo9U.js";const d={certified:x,registered:c,pipeline:p,capability:o,durable:i},m={xs:{pill:"px-1 py-px text-2xs gap-1",icon:"w-2 h-2"},sm:{pill:"px-1.5 py-px text-2xs gap-1",icon:"w-2 h-2"},md:{pill:"px-2 py-0.5 text-xs gap-1.5",icon:"w-2.5 h-2.5"}};function k({type:s,size:n="sm",certified:a,variant:l}){const r=d[l??(a?"certified":"durable")]??i,t=m[n];return e.jsxs("span",{className:`inline-flex items-center max-w-full min-w-0 ${t.pill} font-mono text-text-secondary bg-surface-sunken/50 rounded-md`,title:s,children:[e.jsx(r,{className:`${t.icon} shrink-0 text-text-quaternary`,strokeWidth:1.5}),e.jsx("span",{className:"truncate",children:s})]})}export{k as W};
|
|
2
|
+
//# sourceMappingURL=WorkflowPill-BPC_Dc_I.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkflowPill-
|
|
1
|
+
{"version":3,"file":"WorkflowPill-BPC_Dc_I.js","sources":["../../src/components/common/display/WorkflowPill.tsx"],"sourcesContent":["import { Workflow, ShieldCheck, SlidersHorizontal, Wand2, Zap } from 'lucide-react';\n\ntype WorkflowVariant = 'durable' | 'registered' | 'certified' | 'pipeline' | 'capability';\n\ninterface WorkflowPillProps {\n type: string;\n size?: 'xs' | 'sm' | 'md';\n /** @deprecated Use `variant` instead */\n certified?: boolean;\n variant?: WorkflowVariant;\n}\n\nconst VARIANT_ICON: Record<WorkflowVariant, typeof Workflow> = {\n certified: ShieldCheck,\n registered: SlidersHorizontal,\n pipeline: Wand2,\n capability: Zap,\n durable: Workflow,\n};\n\nconst SIZE_CONFIG = {\n xs: { pill: 'px-1 py-px text-2xs gap-1', icon: 'w-2 h-2' },\n sm: { pill: 'px-1.5 py-px text-2xs gap-1', icon: 'w-2 h-2' },\n md: { pill: 'px-2 py-0.5 text-xs gap-1.5', icon: 'w-2.5 h-2.5' },\n} as const;\n\n/**\n * Universal workflow name chip — mono label with a small tier icon\n * (shield = certified, sliders = registered, wand = pipeline, bolt =\n * capability, workflow = durable). Neutral by design; the icon carries\n * the tier, not color. Matches ToolPill styling.\n */\nexport function WorkflowPill({ type, size = 'sm', certified, variant }: WorkflowPillProps) {\n const resolved = variant ?? (certified ? 'certified' : 'durable');\n // Callers pass server-provided tier strings here — fall back to the durable\n // icon on an unrecognized value so version skew degrades instead of crashing.\n const Icon = VARIANT_ICON[resolved] ?? Workflow;\n const s = SIZE_CONFIG[size];\n\n return (\n <span className={`inline-flex items-center max-w-full min-w-0 ${s.pill} font-mono text-text-secondary bg-surface-sunken/50 rounded-md`} title={type}>\n <Icon className={`${s.icon} shrink-0 text-text-quaternary`} strokeWidth={1.5} />\n <span className=\"truncate\">{type}</span>\n </span>\n );\n}\n"],"names":["VARIANT_ICON","ShieldCheck","SlidersHorizontal","Wand2","Zap","Workflow","SIZE_CONFIG","WorkflowPill","type","size","certified","variant","Icon","s","jsxs","jsx"],"mappings":"2HAYA,MAAMA,EAAyD,CAC7D,UAAYC,EACZ,WAAYC,EACZ,SAAYC,EACZ,WAAYC,EACZ,QAAYC,CACd,EAEMC,EAAc,CAClB,GAAI,CAAE,KAAM,4BAA6B,KAAM,SAAA,EAC/C,GAAI,CAAE,KAAM,8BAA+B,KAAM,SAAA,EACjD,GAAI,CAAE,KAAM,8BAA+B,KAAM,aAAA,CACnD,EAQO,SAASC,EAAa,CAAE,KAAAC,EAAM,KAAAC,EAAO,KAAM,UAAAC,EAAW,QAAAC,GAA8B,CAIzF,MAAMC,EAAOZ,EAHIW,IAAYD,EAAY,YAAc,UAGrB,GAAKL,EACjCQ,EAAIP,EAAYG,CAAI,EAE1B,OACEK,OAAC,QAAK,UAAW,+CAA+CD,EAAE,IAAI,iEAAkE,MAAOL,EAC7I,SAAA,CAAAO,EAAAA,IAACH,GAAK,UAAW,GAAGC,EAAE,IAAI,iCAAkC,YAAa,IAAK,EAC9EE,EAAAA,IAAC,OAAA,CAAK,UAAU,WAAY,SAAAP,CAAA,CAAK,CAAA,EACnC,CAEJ"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as d,j as t}from"./vendor-query-RUZdMvN6.js";import{E as z}from"./ElapsedCell-BGO7IXEg.js";import{m as A,b as v}from"./index--DG-qQBT.js";import{u as E,d as $,b as L}from"./workflows-C4V0rMkM.js";import{u as M}from"./useNamespace-DnFZfy7N.js";import{b as I}from"./useEventHooks-DXCgDgiu.js";import{u as U}from"./useFilterParams-crmlBw_l.js";import{b as H}from"./api-path-u2Jf9QXS.js";import{D as O}from"./DataTable-Bir0Xs1p.js";import{W as B}from"./WorkflowPill-BPC_Dc_I.js";import{P as V}from"./PageHeader-BtIr6r-8.js";import{F as G,c as f,b as x}from"./FilterBar-Do7yR4xM.js";import{S as J}from"./StickyPagination-Cg-QdYWL.js";import{L as q}from"./ListToolbar-CLtw-1QN.js";import{R as K,a as k}from"./RowActions-eYrzgQSj.js";import{H as Q,a0 as X}from"./vendor-icons-CN-bAo9U.js";import{u as Y}from"./vendor-react-CdqEC2zv.js";import"./controlplane-C9c25q21.js";import"./EmptyState-lpUFYfun.js";const Z={running:"in_progress",completed:"completed",failed:"failed"},ee={in_progress:"bg-status-active",completed:"bg-status-success",failed:"bg-status-error"},te={running:"text-status-active",completed:"text-status-success",failed:"text-status-error"};function se(p,n,m,l,a){return[{key:"workflow_id",label:"Workflow ID",render:e=>{const o=ee[Z[e.status]??e.status]??"bg-status-pending",r=e.status==="running"?" animate-pulse":"";return t.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[t.jsx("span",{className:`w-2.5 h-2.5 shrink-0 rounded-full dot-ring ${o}${r}`,title:e.status}),t.jsx("span",{className:"font-mono text-xs text-text-primary truncate",children:e.workflow_id})]})}},{key:"entity",label:"Type",render:e=>t.jsx(B,{type:e.entity,variant:a.get(e.entity)??"durable",size:"xs"}),className:"w-44 shrink-0"},{key:"created_at",label:"Created",render:e=>t.jsx(v,{date:e.created_at,format:"relative",className:"text-xs text-text-secondary whitespace-nowrap"}),className:"w-32",sortable:!0},{key:"updated_at",label:"Updated",render:e=>t.jsx(v,{date:e.updated_at,format:"relative",className:"text-xs text-text-secondary whitespace-nowrap"}),className:"w-32",sortable:!0},{key:"duration",label:"Duration",render:e=>t.jsx(z,{startDate:e.created_at,endDate:e.status==="running"?null:e.updated_at,isLive:e.status==="running"}),className:"w-28"},{key:"actions",label:"",render:e=>t.jsxs(K,{children:[t.jsx(k,{icon:Q,title:`Filter by ${e.entity}`,onClick:()=>p(e.entity)}),t.jsx("button",{onClick:o=>{o.stopPropagation(),n(e.status)},className:"opacity-0 group-hover/row:opacity-100 transition-opacity",title:`Filter by ${e.status}`,children:t.jsx("svg",{className:`w-[18px] h-[18px] ${te[e.status]??"text-text-tertiary"} hover:opacity-70`,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:1.5,children:t.jsx("circle",{cx:"12",cy:"12",r:"6"})})}),m&&t.jsx(k,{icon:X,title:"View config",onClick:()=>l(`/workflows/registry/${encodeURIComponent(e.entity)}`)})]}),className:"w-24 text-right"}]}function ke({tier:p="all"}){I();const n=Y(),{isSuperAdmin:m}=A(),{namespace:l}=M(),{filters:a,setFilter:e,pagination:o,sort:r,setSort:j}=U({filters:{search:"",entity:"",status:"",tier:p}}),c=a.tier||"all",g=c==="certified"?"true":c==="durable"?"false":void 0,{data:b}=E(),{data:y}=$(),S=d.useMemo(()=>{const s=new Map;for(const w of y??[])s.set(w.workflow_type,w.tier??"durable");return s},[y]),_=se(s=>e("entity",s),s=>e("status",s),m,n,S),[u,C]=d.useState(a.search);d.useEffect(()=>{if(u===a.search)return;const s=setTimeout(()=>e("search",u),300);return()=>clearTimeout(s)},[u,e,a.search]);const{data:i,isLoading:N,refetch:P,isFetching:T}=L({limit:o.pageSize,offset:o.offset,entity:a.entity||void 0,search:a.search||void 0,status:a.status||void 0,sort_by:r.sort_by||"created_at",order:r.order||"desc",registered:g,namespace:l||void 0}),h=(i==null?void 0:i.total)??0,F=(i==null?void 0:i.jobs)??[],D=d.useMemo(()=>[...new Set((b??[]).map(s=>s.workflow_type))].sort(),[b]),R="Workflow Executions",W=c==="certified"?"No certified workflow executions found":c==="durable"?"No durable workflow executions found":"No workflow executions found";return t.jsxs("div",{children:[t.jsx(V,{title:R,docsHash:"#docs:dashboard.md:procedural-executions"}),t.jsxs(G,{actions:t.jsx(q,{onRefresh:()=>P(),isFetching:T,apiPath:H("/workflow-states/jobs",{limit:o.pageSize,offset:o.offset,entity:a.entity||void 0,search:a.search||void 0,status:a.status||void 0,sort_by:r.sort_by||"created_at",order:r.order||"desc",registered:g,namespace:l||void 0})}),children:[t.jsx("input",{type:"text",placeholder:"Search workflow ID...",value:u,onChange:s=>C(s.target.value),className:"input text-2xs py-1 px-2 w-56"}),t.jsx(f,{}),t.jsx(x,{label:"Type",value:a.entity,onChange:s=>e("entity",s),options:D.map(s=>({value:s,label:s}))}),t.jsx(f,{}),t.jsx(x,{label:"Status",value:a.status,onChange:s=>e("status",s),options:[{value:"running",label:"Running"},{value:"completed",label:"Completed"},{value:"failed",label:"Failed"}]}),t.jsx(f,{}),t.jsx(x,{label:"Tier",value:a.tier==="all"?"":a.tier,onChange:s=>e("tier",s||"all"),options:[{value:"certified",label:"Certified"},{value:"durable",label:"Durable"}]})]}),t.jsx(O,{columns:_,data:F,keyFn:s=>s.workflow_id,onRowClick:s=>n(`/workflows/executions/${s.workflow_id}`),isLoading:N,emptyMessage:W,sort:r,onSort:j}),t.jsx(J,{page:o.page,totalPages:o.totalPages(h),onPageChange:o.setPage,total:h,pageSize:o.pageSize,onPageSizeChange:o.setPageSize})]})}export{ke as WorkflowsDashboard};
|
|
2
|
+
//# sourceMappingURL=WorkflowsDashboard-4ypPDGKx.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkflowsDashboard-DdJ86We6.js","sources":["../../src/pages/workflows/WorkflowsDashboard.tsx"],"sourcesContent":["import { useState, useEffect, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Filter, Settings } from 'lucide-react';\nimport { ElapsedCell } from '../../components/common/display/ElapsedCell';\nimport { DateValue } from '../../components/common/display/DateValue';\nimport { useJobs, useWorkflowConfigs, useDiscoveredWorkflows } from '../../api/workflows';\nimport { useAuth } from '../../hooks/useAuth';\nimport { useNamespace } from '../../hooks/useNamespace';\nimport { useWorkflowListEvents } from '../../hooks/useEventHooks';\nimport { useFilterParams } from '../../hooks/useFilterParams';\nimport { buildApiPath } from '../../lib/api-path';\nimport { DataTable, type Column } from '../../components/common/data/DataTable';\nimport { WorkflowPill } from '../../components/common/display/WorkflowPill';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { FilterBar, FilterSelect, FilterDivider } from '../../components/common/data/FilterBar';\nimport { StickyPagination } from '../../components/common/data/StickyPagination';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\nimport { RowAction, RowActionGroup } from '../../components/common/layout/RowActions';\nimport type { LTJob, WorkflowTier } from '../../api/types';\n\nexport type ExecutionsTier = 'all' | 'certified' | 'durable';\n\nconst jobStatusMap: Record<string, string> = {\n running: 'in_progress',\n completed: 'completed',\n failed: 'failed',\n};\n\nconst STATUS_DOT: Record<string, string> = {\n in_progress: 'bg-status-active',\n completed: 'bg-status-success',\n failed: 'bg-status-error',\n};\n\nconst STATUS_COLORS: Record<string, string> = {\n running: 'text-status-active',\n completed: 'text-status-success',\n failed: 'text-status-error',\n};\n\nfunction buildColumns(\n onFilterEntity: (entity: string) => void,\n onFilterStatus: (status: string) => void,\n isSuperAdmin: boolean,\n navigate: (path: string) => void,\n tierMap: Map<string, WorkflowTier>,\n): Column<LTJob>[] {\n return [\n {\n key: 'workflow_id',\n label: 'Workflow ID',\n render: (row) => {\n const dotClass = STATUS_DOT[jobStatusMap[row.status] ?? row.status] ?? 'bg-status-pending';\n const pulseClass = row.status === 'running' ? ' animate-pulse' : '';\n return (\n <div className=\"flex items-center gap-2 min-w-0\">\n <span className={`w-2.5 h-2.5 shrink-0 rounded-full dot-ring ${dotClass}${pulseClass}`} title={row.status} />\n <span className=\"font-mono text-xs text-text-primary truncate\">{row.workflow_id}</span>\n </div>\n );\n },\n },\n {\n key: 'entity',\n label: 'Type',\n render: (row) => <WorkflowPill type={row.entity} variant={tierMap.get(row.entity) ?? 'durable'} size=\"xs\" />,\n className: 'w-44 shrink-0',\n },\n {\n key: 'created_at',\n label: 'Created',\n render: (row) => <DateValue date={row.created_at} format=\"relative\" className=\"text-xs text-text-secondary whitespace-nowrap\" />,\n className: 'w-32',\n sortable: true,\n },\n {\n key: 'updated_at',\n label: 'Updated',\n render: (row) => <DateValue date={row.updated_at} format=\"relative\" className=\"text-xs text-text-secondary whitespace-nowrap\" />,\n className: 'w-32',\n sortable: true,\n },\n {\n key: 'duration',\n label: 'Duration',\n render: (row) => (\n <ElapsedCell\n startDate={row.created_at}\n endDate={row.status === 'running' ? null : row.updated_at}\n isLive={row.status === 'running'}\n />\n ),\n className: 'w-28',\n },\n {\n key: 'actions',\n label: '',\n render: (row) => (\n <RowActionGroup>\n <RowAction\n icon={Filter}\n title={`Filter by ${row.entity}`}\n onClick={() => onFilterEntity(row.entity)}\n />\n <button\n onClick={(e) => { e.stopPropagation(); onFilterStatus(row.status); }}\n className=\"opacity-0 group-hover/row:opacity-100 transition-opacity\"\n title={`Filter by ${row.status}`}\n >\n <svg className={`w-[18px] h-[18px] ${STATUS_COLORS[row.status] ?? 'text-text-tertiary'} hover:opacity-70`} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1.5}>\n <circle cx=\"12\" cy=\"12\" r=\"6\" />\n </svg>\n </button>\n {isSuperAdmin && (\n <RowAction\n icon={Settings}\n title=\"View config\"\n onClick={() => navigate(`/workflows/registry/${encodeURIComponent(row.entity)}`)}\n />\n )}\n </RowActionGroup>\n ),\n className: 'w-24 text-right',\n },\n ];\n}\n\nexport function WorkflowsDashboard({ tier: initialTier = 'all' }: { tier?: ExecutionsTier }) {\n useWorkflowListEvents();\n const navigate = useNavigate();\n const { isSuperAdmin } = useAuth();\n const { namespace } = useNamespace();\n\n const { filters, setFilter, pagination, sort, setSort } = useFilterParams({\n filters: { search: '', entity: '', status: '', tier: initialTier },\n });\n\n const activeTier = (filters.tier || 'all') as ExecutionsTier;\n\n // Map tier to server-side registered filter\n const registeredFilter = activeTier === 'certified' ? 'true'\n : activeTier === 'durable' ? 'false'\n : undefined;\n\n const { data: configs } = useWorkflowConfigs();\n const { data: discoveredData } = useDiscoveredWorkflows();\n\n const tierMap = useMemo(() => {\n const map = new Map<string, WorkflowTier>();\n for (const dw of discoveredData ?? []) {\n map.set(dw.workflow_type, dw.tier ?? 'durable');\n }\n return map;\n }, [discoveredData]);\n\n const columns = buildColumns(\n (entity) => setFilter('entity', entity),\n (status) => setFilter('status', status),\n isSuperAdmin,\n navigate,\n tierMap,\n );\n const [searchInput, setSearchInput] = useState(filters.search);\n\n useEffect(() => {\n if (searchInput === filters.search) return;\n const timer = setTimeout(() => setFilter('search', searchInput), 300);\n return () => clearTimeout(timer);\n }, [searchInput, setFilter, filters.search]);\n\n const { data: jobsData, isLoading, refetch, isFetching } = useJobs({\n limit: pagination.pageSize,\n offset: pagination.offset,\n entity: filters.entity || undefined,\n search: filters.search || undefined,\n status: filters.status || undefined,\n sort_by: sort.sort_by || 'created_at',\n order: sort.order || 'desc',\n registered: registeredFilter,\n namespace: namespace || undefined,\n });\n\n const total = jobsData?.total ?? 0;\n const jobs = jobsData?.jobs ?? [];\n\n const entities = useMemo(() => {\n return [...new Set((configs ?? []).map((c) => c.workflow_type))].sort();\n }, [configs]);\n\n const pageTitle = 'Workflow Executions';\n\n const emptyMessage = activeTier === 'certified'\n ? 'No certified workflow executions found'\n : activeTier === 'durable'\n ? 'No durable workflow executions found'\n : 'No workflow executions found';\n\n return (\n <div>\n <PageHeader title={pageTitle} docsHash=\"#docs:dashboard.md:procedural-executions\" />\n\n <FilterBar actions={\n <ListToolbar\n onRefresh={() => refetch()}\n isFetching={isFetching}\n apiPath={buildApiPath('/workflow-states/jobs', {\n limit: pagination.pageSize,\n offset: pagination.offset,\n entity: filters.entity || undefined,\n search: filters.search || undefined,\n status: filters.status || undefined,\n sort_by: sort.sort_by || 'created_at',\n order: sort.order || 'desc',\n registered: registeredFilter,\n namespace: namespace || undefined,\n })}\n />\n }>\n <input\n type=\"text\"\n placeholder=\"Search workflow ID...\"\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n className=\"input text-2xs py-1 px-2 w-56\"\n />\n <FilterDivider />\n <FilterSelect\n label=\"Type\"\n value={filters.entity}\n onChange={(v) => setFilter('entity', v)}\n options={entities.map((e) => ({ value: e, label: e }))}\n />\n <FilterDivider />\n <FilterSelect\n label=\"Status\"\n value={filters.status}\n onChange={(v) => setFilter('status', v)}\n options={[\n { value: 'running', label: 'Running' },\n { value: 'completed', label: 'Completed' },\n { value: 'failed', label: 'Failed' },\n ]}\n />\n <FilterDivider />\n <FilterSelect\n label=\"Tier\"\n value={filters.tier === 'all' ? '' : filters.tier}\n onChange={(v) => setFilter('tier', v || 'all')}\n options={[\n { value: 'certified', label: 'Certified' },\n { value: 'durable', label: 'Durable' },\n ]}\n />\n </FilterBar>\n\n <DataTable\n columns={columns}\n data={jobs}\n keyFn={(row) => row.workflow_id}\n onRowClick={(row) => navigate(`/workflows/executions/${row.workflow_id}`)}\n isLoading={isLoading}\n emptyMessage={emptyMessage}\n sort={sort}\n onSort={setSort}\n />\n\n <StickyPagination\n page={pagination.page}\n totalPages={pagination.totalPages(total)}\n onPageChange={pagination.setPage}\n total={total}\n pageSize={pagination.pageSize}\n onPageSizeChange={pagination.setPageSize}\n />\n </div>\n );\n}\n"],"names":["jobStatusMap","STATUS_DOT","STATUS_COLORS","buildColumns","onFilterEntity","onFilterStatus","isSuperAdmin","navigate","tierMap","row","dotClass","pulseClass","jsxs","jsx","WorkflowPill","DateValue","ElapsedCell","RowActionGroup","RowAction","Filter","e","Settings","WorkflowsDashboard","initialTier","useWorkflowListEvents","useNavigate","useAuth","namespace","useNamespace","filters","setFilter","pagination","sort","setSort","useFilterParams","activeTier","registeredFilter","configs","useWorkflowConfigs","discoveredData","useDiscoveredWorkflows","useMemo","map","dw","columns","entity","status","searchInput","setSearchInput","useState","useEffect","timer","jobsData","isLoading","refetch","isFetching","useJobs","total","jobs","entities","c","pageTitle","emptyMessage","PageHeader","FilterBar","ListToolbar","buildApiPath","FilterDivider","FilterSelect","v","DataTable","StickyPagination"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WorkflowsDashboard-4ypPDGKx.js","sources":["../../src/pages/workflows/WorkflowsDashboard.tsx"],"sourcesContent":["import { useState, useEffect, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Filter, Settings } from 'lucide-react';\nimport { ElapsedCell } from '../../components/common/display/ElapsedCell';\nimport { DateValue } from '../../components/common/display/DateValue';\nimport { useJobs, useWorkflowConfigs, useDiscoveredWorkflows } from '../../api/workflows';\nimport { useAuth } from '../../hooks/useAuth';\nimport { useNamespace } from '../../hooks/useNamespace';\nimport { useWorkflowListEvents } from '../../hooks/useEventHooks';\nimport { useFilterParams } from '../../hooks/useFilterParams';\nimport { buildApiPath } from '../../lib/api-path';\nimport { DataTable, type Column } from '../../components/common/data/DataTable';\nimport { WorkflowPill } from '../../components/common/display/WorkflowPill';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { FilterBar, FilterSelect, FilterDivider } from '../../components/common/data/FilterBar';\nimport { StickyPagination } from '../../components/common/data/StickyPagination';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\nimport { RowAction, RowActionGroup } from '../../components/common/layout/RowActions';\nimport type { LTJob, WorkflowTier } from '../../api/types';\n\nexport type ExecutionsTier = 'all' | 'certified' | 'durable';\n\nconst jobStatusMap: Record<string, string> = {\n running: 'in_progress',\n completed: 'completed',\n failed: 'failed',\n};\n\nconst STATUS_DOT: Record<string, string> = {\n in_progress: 'bg-status-active',\n completed: 'bg-status-success',\n failed: 'bg-status-error',\n};\n\nconst STATUS_COLORS: Record<string, string> = {\n running: 'text-status-active',\n completed: 'text-status-success',\n failed: 'text-status-error',\n};\n\nfunction buildColumns(\n onFilterEntity: (entity: string) => void,\n onFilterStatus: (status: string) => void,\n isSuperAdmin: boolean,\n navigate: (path: string) => void,\n tierMap: Map<string, WorkflowTier>,\n): Column<LTJob>[] {\n return [\n {\n key: 'workflow_id',\n label: 'Workflow ID',\n render: (row) => {\n const dotClass = STATUS_DOT[jobStatusMap[row.status] ?? row.status] ?? 'bg-status-pending';\n const pulseClass = row.status === 'running' ? ' animate-pulse' : '';\n return (\n <div className=\"flex items-center gap-2 min-w-0\">\n <span className={`w-2.5 h-2.5 shrink-0 rounded-full dot-ring ${dotClass}${pulseClass}`} title={row.status} />\n <span className=\"font-mono text-xs text-text-primary truncate\">{row.workflow_id}</span>\n </div>\n );\n },\n },\n {\n key: 'entity',\n label: 'Type',\n render: (row) => <WorkflowPill type={row.entity} variant={tierMap.get(row.entity) ?? 'durable'} size=\"xs\" />,\n className: 'w-44 shrink-0',\n },\n {\n key: 'created_at',\n label: 'Created',\n render: (row) => <DateValue date={row.created_at} format=\"relative\" className=\"text-xs text-text-secondary whitespace-nowrap\" />,\n className: 'w-32',\n sortable: true,\n },\n {\n key: 'updated_at',\n label: 'Updated',\n render: (row) => <DateValue date={row.updated_at} format=\"relative\" className=\"text-xs text-text-secondary whitespace-nowrap\" />,\n className: 'w-32',\n sortable: true,\n },\n {\n key: 'duration',\n label: 'Duration',\n render: (row) => (\n <ElapsedCell\n startDate={row.created_at}\n endDate={row.status === 'running' ? null : row.updated_at}\n isLive={row.status === 'running'}\n />\n ),\n className: 'w-28',\n },\n {\n key: 'actions',\n label: '',\n render: (row) => (\n <RowActionGroup>\n <RowAction\n icon={Filter}\n title={`Filter by ${row.entity}`}\n onClick={() => onFilterEntity(row.entity)}\n />\n <button\n onClick={(e) => { e.stopPropagation(); onFilterStatus(row.status); }}\n className=\"opacity-0 group-hover/row:opacity-100 transition-opacity\"\n title={`Filter by ${row.status}`}\n >\n <svg className={`w-[18px] h-[18px] ${STATUS_COLORS[row.status] ?? 'text-text-tertiary'} hover:opacity-70`} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1.5}>\n <circle cx=\"12\" cy=\"12\" r=\"6\" />\n </svg>\n </button>\n {isSuperAdmin && (\n <RowAction\n icon={Settings}\n title=\"View config\"\n onClick={() => navigate(`/workflows/registry/${encodeURIComponent(row.entity)}`)}\n />\n )}\n </RowActionGroup>\n ),\n className: 'w-24 text-right',\n },\n ];\n}\n\nexport function WorkflowsDashboard({ tier: initialTier = 'all' }: { tier?: ExecutionsTier }) {\n useWorkflowListEvents();\n const navigate = useNavigate();\n const { isSuperAdmin } = useAuth();\n const { namespace } = useNamespace();\n\n const { filters, setFilter, pagination, sort, setSort } = useFilterParams({\n filters: { search: '', entity: '', status: '', tier: initialTier },\n });\n\n const activeTier = (filters.tier || 'all') as ExecutionsTier;\n\n // Map tier to server-side registered filter\n const registeredFilter = activeTier === 'certified' ? 'true'\n : activeTier === 'durable' ? 'false'\n : undefined;\n\n const { data: configs } = useWorkflowConfigs();\n const { data: discoveredData } = useDiscoveredWorkflows();\n\n const tierMap = useMemo(() => {\n const map = new Map<string, WorkflowTier>();\n for (const dw of discoveredData ?? []) {\n map.set(dw.workflow_type, dw.tier ?? 'durable');\n }\n return map;\n }, [discoveredData]);\n\n const columns = buildColumns(\n (entity) => setFilter('entity', entity),\n (status) => setFilter('status', status),\n isSuperAdmin,\n navigate,\n tierMap,\n );\n const [searchInput, setSearchInput] = useState(filters.search);\n\n useEffect(() => {\n if (searchInput === filters.search) return;\n const timer = setTimeout(() => setFilter('search', searchInput), 300);\n return () => clearTimeout(timer);\n }, [searchInput, setFilter, filters.search]);\n\n const { data: jobsData, isLoading, refetch, isFetching } = useJobs({\n limit: pagination.pageSize,\n offset: pagination.offset,\n entity: filters.entity || undefined,\n search: filters.search || undefined,\n status: filters.status || undefined,\n sort_by: sort.sort_by || 'created_at',\n order: sort.order || 'desc',\n registered: registeredFilter,\n namespace: namespace || undefined,\n });\n\n const total = jobsData?.total ?? 0;\n const jobs = jobsData?.jobs ?? [];\n\n const entities = useMemo(() => {\n return [...new Set((configs ?? []).map((c) => c.workflow_type))].sort();\n }, [configs]);\n\n const pageTitle = 'Workflow Executions';\n\n const emptyMessage = activeTier === 'certified'\n ? 'No certified workflow executions found'\n : activeTier === 'durable'\n ? 'No durable workflow executions found'\n : 'No workflow executions found';\n\n return (\n <div>\n <PageHeader title={pageTitle} docsHash=\"#docs:dashboard.md:procedural-executions\" />\n\n <FilterBar actions={\n <ListToolbar\n onRefresh={() => refetch()}\n isFetching={isFetching}\n apiPath={buildApiPath('/workflow-states/jobs', {\n limit: pagination.pageSize,\n offset: pagination.offset,\n entity: filters.entity || undefined,\n search: filters.search || undefined,\n status: filters.status || undefined,\n sort_by: sort.sort_by || 'created_at',\n order: sort.order || 'desc',\n registered: registeredFilter,\n namespace: namespace || undefined,\n })}\n />\n }>\n <input\n type=\"text\"\n placeholder=\"Search workflow ID...\"\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n className=\"input text-2xs py-1 px-2 w-56\"\n />\n <FilterDivider />\n <FilterSelect\n label=\"Type\"\n value={filters.entity}\n onChange={(v) => setFilter('entity', v)}\n options={entities.map((e) => ({ value: e, label: e }))}\n />\n <FilterDivider />\n <FilterSelect\n label=\"Status\"\n value={filters.status}\n onChange={(v) => setFilter('status', v)}\n options={[\n { value: 'running', label: 'Running' },\n { value: 'completed', label: 'Completed' },\n { value: 'failed', label: 'Failed' },\n ]}\n />\n <FilterDivider />\n <FilterSelect\n label=\"Tier\"\n value={filters.tier === 'all' ? '' : filters.tier}\n onChange={(v) => setFilter('tier', v || 'all')}\n options={[\n { value: 'certified', label: 'Certified' },\n { value: 'durable', label: 'Durable' },\n ]}\n />\n </FilterBar>\n\n <DataTable\n columns={columns}\n data={jobs}\n keyFn={(row) => row.workflow_id}\n onRowClick={(row) => navigate(`/workflows/executions/${row.workflow_id}`)}\n isLoading={isLoading}\n emptyMessage={emptyMessage}\n sort={sort}\n onSort={setSort}\n />\n\n <StickyPagination\n page={pagination.page}\n totalPages={pagination.totalPages(total)}\n onPageChange={pagination.setPage}\n total={total}\n pageSize={pagination.pageSize}\n onPageSizeChange={pagination.setPageSize}\n />\n </div>\n );\n}\n"],"names":["jobStatusMap","STATUS_DOT","STATUS_COLORS","buildColumns","onFilterEntity","onFilterStatus","isSuperAdmin","navigate","tierMap","row","dotClass","pulseClass","jsxs","jsx","WorkflowPill","DateValue","ElapsedCell","RowActionGroup","RowAction","Filter","e","Settings","WorkflowsDashboard","initialTier","useWorkflowListEvents","useNavigate","useAuth","namespace","useNamespace","filters","setFilter","pagination","sort","setSort","useFilterParams","activeTier","registeredFilter","configs","useWorkflowConfigs","discoveredData","useDiscoveredWorkflows","useMemo","map","dw","columns","entity","status","searchInput","setSearchInput","useState","useEffect","timer","jobsData","isLoading","refetch","isFetching","useJobs","total","jobs","entities","c","pageTitle","emptyMessage","PageHeader","FilterBar","ListToolbar","buildApiPath","FilterDivider","FilterSelect","v","DataTable","StickyPagination"],"mappings":"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"}
|
package/dashboard/dist/assets/{WorkflowsOverview-ZfFBzePp.js → WorkflowsOverview-CeQlZkkd.js}
RENAMED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as x,j as t}from"./vendor-query-
|
|
2
|
-
//# sourceMappingURL=WorkflowsOverview-
|
|
1
|
+
import{a as x,j as t}from"./vendor-query-RUZdMvN6.js";import{b as C,u as k}from"./workflows-C4V0rMkM.js";import{b as $}from"./useEventHooks-DXCgDgiu.js";import{P as D}from"./PageHeader-BtIr6r-8.js";import{S as h}from"./StatCard-BXQ8dD9Y.js";import{u as w}from"./vendor-react-CdqEC2zv.js";import"./index--DG-qQBT.js";import"./vendor-icons-CN-bAo9U.js";const v=[{label:"1h",ms:36e5},{label:"24h",ms:864e5},{label:"7d",ms:6048e5},{label:"30d",ms:2592e6}];function T(r){return r<1e3?`${Math.round(r)}ms`:r<6e4?`${(r/1e3).toFixed(1)}s`:r<36e5?`${(r/6e4).toFixed(1)}m`:`${(r/36e5).toFixed(1)}h`}function p({value:r,colorClass:o,onClick:f}){return r===0?t.jsx("span",{className:"text-text-tertiary",children:"0"}):t.jsx("button",{onClick:f,className:`${o} hover:underline tabular-nums font-medium`,children:r})}function _(){$();const r=w(),[o,f]=x.useState("24h"),{data:c}=C({limit:500}),{data:g}=k(),b=x.useMemo(()=>{const e=v.find(i=>i.label===o);return Date.now()-e.ms},[o]),n=x.useMemo(()=>((c==null?void 0:c.jobs)??[]).filter(e=>new Date(e.created_at).getTime()>=b),[c==null?void 0:c.jobs,b]),j=x.useMemo(()=>{const e=new Map;for(const a of n){const s=e.get(a.entity)??{total:0,running:0,completed:0,failed:0,durations:[]};if(s.total++,a.status==="running"&&s.running++,a.status==="completed"){s.completed++;const m=new Date(a.updated_at).getTime()-new Date(a.created_at).getTime();m>0&&s.durations.push(m)}a.status==="failed"&&s.failed++,e.set(a.entity,s)}const i=[];for(const[a,s]of e)i.push({type:a,...s,avgDuration:s.durations.length>0?s.durations.reduce((m,N)=>m+N,0)/s.durations.length:null});return i.sort((a,s)=>s.total-a.total)},[n]),u=x.useMemo(()=>({total:n.length,running:n.filter(e=>e.status==="running").length,completed:n.filter(e=>e.status==="completed").length,failed:n.filter(e=>e.status==="failed").length}),[n]),y=(g==null?void 0:g.length)??0,l=(e,i)=>{const a=new URLSearchParams;e&&a.set("entity",e),i&&a.set("status",i);const s=a.toString();r(`/workflows/executions${s?`?${s}`:""}`)},d="pb-2 text-2xs font-semibold uppercase tracking-widest text-text-tertiary";return t.jsxs("div",{children:[t.jsx(D,{title:"Workflows",actions:t.jsxs("span",{className:"text-xs text-text-tertiary",children:[y," certified type",y!==1?"s":""]})}),t.jsx("div",{className:"flex items-center gap-1 mb-6",children:v.map(e=>t.jsx("button",{onClick:()=>f(e.label),className:`px-3 py-1 text-xs rounded-full transition-colors ${o===e.label?"bg-accent text-text-inverse":"text-text-tertiary hover:text-text-primary hover:bg-surface-hover"}`,children:e.label},e.label))}),t.jsxs("div",{className:"grid grid-cols-4 gap-4 mb-8",children:[t.jsx(h,{label:"Total",value:u.total,onClick:()=>l()}),t.jsx(h,{label:"Running",value:u.running,colorClass:"text-status-active",onClick:()=>l(void 0,"running")}),t.jsx(h,{label:"Completed",value:u.completed,colorClass:"text-status-success",onClick:()=>l(void 0,"completed")}),t.jsx(h,{label:"Failed",value:u.failed,colorClass:"text-status-error",onClick:()=>l(void 0,"failed")})]}),j.length>0&&t.jsxs("table",{className:"w-full text-left",children:[t.jsx("thead",{children:t.jsxs("tr",{className:"border-b border-surface-border",children:[t.jsx("th",{className:d,children:"Type"}),t.jsx("th",{className:`${d} text-right w-20`,children:"Total"}),t.jsx("th",{className:`${d} text-right w-20`,children:"Running"}),t.jsx("th",{className:`${d} text-right w-24`,children:"Completed"}),t.jsx("th",{className:`${d} text-right w-20`,children:"Failed"}),t.jsx("th",{className:`${d} text-right w-28`,children:"Avg Duration"})]})}),t.jsx("tbody",{children:j.map(e=>t.jsxs("tr",{className:"border-b border-surface-border last:border-b-0",children:[t.jsx("td",{className:"py-3 text-sm font-mono text-text-primary",children:t.jsx("button",{onClick:()=>l(e.type),className:"hover:text-accent hover:underline",children:e.type})}),t.jsx("td",{className:"py-3 text-sm text-right",children:t.jsx(p,{value:e.total,colorClass:"text-text-secondary",onClick:()=>l(e.type)})}),t.jsx("td",{className:"py-3 text-sm text-right",children:t.jsx(p,{value:e.running,colorClass:"text-status-active",onClick:()=>l(e.type,"running")})}),t.jsx("td",{className:"py-3 text-sm text-right",children:t.jsx(p,{value:e.completed,colorClass:"text-status-success",onClick:()=>l(e.type,"completed")})}),t.jsx("td",{className:"py-3 text-sm text-right",children:t.jsx(p,{value:e.failed,colorClass:"text-status-error",onClick:()=>l(e.type,"failed")})}),t.jsx("td",{className:"py-3 text-sm font-mono text-text-secondary text-right",children:e.avgDuration!==null?T(e.avgDuration):"—"})]},e.type))})]}),j.length===0&&t.jsx("div",{className:"py-16 text-center",children:t.jsxs("p",{className:"text-sm text-text-tertiary",children:["No workflow activity in the last ",o]})})]})}export{_ as WorkflowsOverview};
|
|
2
|
+
//# sourceMappingURL=WorkflowsOverview-CeQlZkkd.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkflowsOverview-ZfFBzePp.js","sources":["../../src/pages/workflows/WorkflowsOverview.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useJobs, useWorkflowConfigs } from '../../api/workflows';\nimport { useWorkflowListEvents } from '../../hooks/useEventHooks';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { StatCard } from '../../components/common/data/StatCard';\n\n// ── Duration filter ──────────────────────────────────────────────────────────\n\nconst DURATIONS = [\n { label: '1h', ms: 3_600_000 },\n { label: '24h', ms: 86_400_000 },\n { label: '7d', ms: 604_800_000 },\n { label: '30d', ms: 2_592_000_000 },\n] as const;\n\ntype DurationLabel = (typeof DURATIONS)[number]['label'];\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${Math.round(ms)}ms`;\n if (ms < 60_000) return `${(ms / 1000).toFixed(1)}s`;\n if (ms < 3_600_000) return `${(ms / 60_000).toFixed(1)}m`;\n return `${(ms / 3_600_000).toFixed(1)}h`;\n}\n\ninterface TypeStats {\n type: string;\n total: number;\n running: number;\n completed: number;\n failed: number;\n avgDuration: number | null;\n}\n\n// ── Clickable stat cell ──────────────────────────────────────────────────────\n\nfunction StatCell({\n value,\n colorClass,\n onClick,\n}: {\n value: number;\n colorClass: string;\n onClick: () => void;\n}) {\n if (value === 0) {\n return <span className=\"text-text-tertiary\">0</span>;\n }\n return (\n <button\n onClick={onClick}\n className={`${colorClass} hover:underline tabular-nums font-medium`}\n >\n {value}\n </button>\n );\n}\n\n// ── Page ─────────────────────────────────────────────────────────────────────\n\nexport function WorkflowsOverview() {\n useWorkflowListEvents();\n const navigate = useNavigate();\n const [duration, setDuration] = useState<DurationLabel>('24h');\n\n const { data: allJobs } = useJobs({ limit: 500 });\n const { data: configs } = useWorkflowConfigs();\n\n const cutoff = useMemo(() => {\n const d = DURATIONS.find((d) => d.label === duration)!;\n return Date.now() - d.ms;\n }, [duration]);\n\n const jobs = useMemo(\n () => (allJobs?.jobs ?? []).filter((j) => new Date(j.created_at).getTime() >= cutoff),\n [allJobs?.jobs, cutoff],\n );\n\n const byType = useMemo(() => {\n const map = new Map<string, { total: number; running: number; completed: number; failed: number; durations: number[] }>();\n for (const j of jobs) {\n const entry = map.get(j.entity) ?? { total: 0, running: 0, completed: 0, failed: 0, durations: [] };\n entry.total++;\n if (j.status === 'running') entry.running++;\n if (j.status === 'completed') {\n entry.completed++;\n const dur = new Date(j.updated_at).getTime() - new Date(j.created_at).getTime();\n if (dur > 0) entry.durations.push(dur);\n }\n if (j.status === 'failed') entry.failed++;\n map.set(j.entity, entry);\n }\n\n const result: TypeStats[] = [];\n for (const [type, stats] of map) {\n result.push({\n type,\n ...stats,\n avgDuration: stats.durations.length > 0\n ? stats.durations.reduce((a, b) => a + b, 0) / stats.durations.length\n : null,\n });\n }\n return result.sort((a, b) => b.total - a.total);\n }, [jobs]);\n\n // Totals\n const totals = useMemo(() => ({\n total: jobs.length,\n running: jobs.filter((j) => j.status === 'running').length,\n completed: jobs.filter((j) => j.status === 'completed').length,\n failed: jobs.filter((j) => j.status === 'failed').length,\n }), [jobs]);\n\n const registered = configs?.length ?? 0;\n\n const goToList = (entity?: string, status?: string) => {\n const params = new URLSearchParams();\n if (entity) params.set('entity', entity);\n if (status) params.set('status', status);\n const qs = params.toString();\n navigate(`/workflows/executions${qs ? `?${qs}` : ''}`);\n };\n\n const thCls = 'pb-2 text-2xs font-semibold uppercase tracking-widest text-text-tertiary';\n\n return (\n <div>\n <PageHeader\n title=\"Workflows\"\n actions={\n <span className=\"text-xs text-text-tertiary\">\n {registered} certified type{registered !== 1 ? 's' : ''}\n </span>\n }\n />\n\n {/* Duration tabs */}\n <div className=\"flex items-center gap-1 mb-6\">\n {DURATIONS.map((d) => (\n <button\n key={d.label}\n onClick={() => setDuration(d.label)}\n className={`px-3 py-1 text-xs rounded-full transition-colors ${\n duration === d.label\n ? 'bg-accent text-text-inverse'\n : 'text-text-tertiary hover:text-text-primary hover:bg-surface-hover'\n }`}\n >\n {d.label}\n </button>\n ))}\n </div>\n\n {/* Summary cards */}\n <div className=\"grid grid-cols-4 gap-4 mb-8\">\n <StatCard label=\"Total\" value={totals.total} onClick={() => goToList()} />\n <StatCard label=\"Running\" value={totals.running} colorClass=\"text-status-active\" onClick={() => goToList(undefined, 'running')} />\n <StatCard label=\"Completed\" value={totals.completed} colorClass=\"text-status-success\" onClick={() => goToList(undefined, 'completed')} />\n <StatCard label=\"Failed\" value={totals.failed} colorClass=\"text-status-error\" onClick={() => goToList(undefined, 'failed')} />\n </div>\n\n {/* By-type table */}\n {byType.length > 0 && (\n <table className=\"w-full text-left\">\n <thead>\n <tr className=\"border-b border-surface-border\">\n <th className={thCls}>Type</th>\n <th className={`${thCls} text-right w-20`}>Total</th>\n <th className={`${thCls} text-right w-20`}>Running</th>\n <th className={`${thCls} text-right w-24`}>Completed</th>\n <th className={`${thCls} text-right w-20`}>Failed</th>\n <th className={`${thCls} text-right w-28`}>Avg Duration</th>\n </tr>\n </thead>\n <tbody>\n {byType.map((row) => (\n <tr key={row.type} className=\"border-b border-surface-border last:border-b-0\">\n <td className=\"py-3 text-sm font-mono text-text-primary\">\n <button\n onClick={() => goToList(row.type)}\n className=\"hover:text-accent hover:underline\"\n >\n {row.type}\n </button>\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.total} colorClass=\"text-text-secondary\" onClick={() => goToList(row.type)} />\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.running} colorClass=\"text-status-active\" onClick={() => goToList(row.type, 'running')} />\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.completed} colorClass=\"text-status-success\" onClick={() => goToList(row.type, 'completed')} />\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.failed} colorClass=\"text-status-error\" onClick={() => goToList(row.type, 'failed')} />\n </td>\n <td className=\"py-3 text-sm font-mono text-text-secondary text-right\">\n {row.avgDuration !== null ? formatDuration(row.avgDuration) : '—'}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n )}\n\n {byType.length === 0 && (\n <div className=\"py-16 text-center\">\n <p className=\"text-sm text-text-tertiary\">\n No workflow activity in the last {duration}\n </p>\n </div>\n )}\n </div>\n );\n}"],"names":["DURATIONS","formatDuration","ms","StatCell","value","colorClass","onClick","jsx","WorkflowsOverview","useWorkflowListEvents","navigate","useNavigate","duration","setDuration","useState","allJobs","useJobs","configs","useWorkflowConfigs","cutoff","useMemo","d","jobs","j","byType","map","entry","dur","result","type","stats","a","b","totals","registered","goToList","entity","status","params","qs","thCls","PageHeader","jsxs","StatCard","row"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WorkflowsOverview-CeQlZkkd.js","sources":["../../src/pages/workflows/WorkflowsOverview.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useJobs, useWorkflowConfigs } from '../../api/workflows';\nimport { useWorkflowListEvents } from '../../hooks/useEventHooks';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { StatCard } from '../../components/common/data/StatCard';\n\n// ── Duration filter ──────────────────────────────────────────────────────────\n\nconst DURATIONS = [\n { label: '1h', ms: 3_600_000 },\n { label: '24h', ms: 86_400_000 },\n { label: '7d', ms: 604_800_000 },\n { label: '30d', ms: 2_592_000_000 },\n] as const;\n\ntype DurationLabel = (typeof DURATIONS)[number]['label'];\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${Math.round(ms)}ms`;\n if (ms < 60_000) return `${(ms / 1000).toFixed(1)}s`;\n if (ms < 3_600_000) return `${(ms / 60_000).toFixed(1)}m`;\n return `${(ms / 3_600_000).toFixed(1)}h`;\n}\n\ninterface TypeStats {\n type: string;\n total: number;\n running: number;\n completed: number;\n failed: number;\n avgDuration: number | null;\n}\n\n// ── Clickable stat cell ──────────────────────────────────────────────────────\n\nfunction StatCell({\n value,\n colorClass,\n onClick,\n}: {\n value: number;\n colorClass: string;\n onClick: () => void;\n}) {\n if (value === 0) {\n return <span className=\"text-text-tertiary\">0</span>;\n }\n return (\n <button\n onClick={onClick}\n className={`${colorClass} hover:underline tabular-nums font-medium`}\n >\n {value}\n </button>\n );\n}\n\n// ── Page ─────────────────────────────────────────────────────────────────────\n\nexport function WorkflowsOverview() {\n useWorkflowListEvents();\n const navigate = useNavigate();\n const [duration, setDuration] = useState<DurationLabel>('24h');\n\n const { data: allJobs } = useJobs({ limit: 500 });\n const { data: configs } = useWorkflowConfigs();\n\n const cutoff = useMemo(() => {\n const d = DURATIONS.find((d) => d.label === duration)!;\n return Date.now() - d.ms;\n }, [duration]);\n\n const jobs = useMemo(\n () => (allJobs?.jobs ?? []).filter((j) => new Date(j.created_at).getTime() >= cutoff),\n [allJobs?.jobs, cutoff],\n );\n\n const byType = useMemo(() => {\n const map = new Map<string, { total: number; running: number; completed: number; failed: number; durations: number[] }>();\n for (const j of jobs) {\n const entry = map.get(j.entity) ?? { total: 0, running: 0, completed: 0, failed: 0, durations: [] };\n entry.total++;\n if (j.status === 'running') entry.running++;\n if (j.status === 'completed') {\n entry.completed++;\n const dur = new Date(j.updated_at).getTime() - new Date(j.created_at).getTime();\n if (dur > 0) entry.durations.push(dur);\n }\n if (j.status === 'failed') entry.failed++;\n map.set(j.entity, entry);\n }\n\n const result: TypeStats[] = [];\n for (const [type, stats] of map) {\n result.push({\n type,\n ...stats,\n avgDuration: stats.durations.length > 0\n ? stats.durations.reduce((a, b) => a + b, 0) / stats.durations.length\n : null,\n });\n }\n return result.sort((a, b) => b.total - a.total);\n }, [jobs]);\n\n // Totals\n const totals = useMemo(() => ({\n total: jobs.length,\n running: jobs.filter((j) => j.status === 'running').length,\n completed: jobs.filter((j) => j.status === 'completed').length,\n failed: jobs.filter((j) => j.status === 'failed').length,\n }), [jobs]);\n\n const registered = configs?.length ?? 0;\n\n const goToList = (entity?: string, status?: string) => {\n const params = new URLSearchParams();\n if (entity) params.set('entity', entity);\n if (status) params.set('status', status);\n const qs = params.toString();\n navigate(`/workflows/executions${qs ? `?${qs}` : ''}`);\n };\n\n const thCls = 'pb-2 text-2xs font-semibold uppercase tracking-widest text-text-tertiary';\n\n return (\n <div>\n <PageHeader\n title=\"Workflows\"\n actions={\n <span className=\"text-xs text-text-tertiary\">\n {registered} certified type{registered !== 1 ? 's' : ''}\n </span>\n }\n />\n\n {/* Duration tabs */}\n <div className=\"flex items-center gap-1 mb-6\">\n {DURATIONS.map((d) => (\n <button\n key={d.label}\n onClick={() => setDuration(d.label)}\n className={`px-3 py-1 text-xs rounded-full transition-colors ${\n duration === d.label\n ? 'bg-accent text-text-inverse'\n : 'text-text-tertiary hover:text-text-primary hover:bg-surface-hover'\n }`}\n >\n {d.label}\n </button>\n ))}\n </div>\n\n {/* Summary cards */}\n <div className=\"grid grid-cols-4 gap-4 mb-8\">\n <StatCard label=\"Total\" value={totals.total} onClick={() => goToList()} />\n <StatCard label=\"Running\" value={totals.running} colorClass=\"text-status-active\" onClick={() => goToList(undefined, 'running')} />\n <StatCard label=\"Completed\" value={totals.completed} colorClass=\"text-status-success\" onClick={() => goToList(undefined, 'completed')} />\n <StatCard label=\"Failed\" value={totals.failed} colorClass=\"text-status-error\" onClick={() => goToList(undefined, 'failed')} />\n </div>\n\n {/* By-type table */}\n {byType.length > 0 && (\n <table className=\"w-full text-left\">\n <thead>\n <tr className=\"border-b border-surface-border\">\n <th className={thCls}>Type</th>\n <th className={`${thCls} text-right w-20`}>Total</th>\n <th className={`${thCls} text-right w-20`}>Running</th>\n <th className={`${thCls} text-right w-24`}>Completed</th>\n <th className={`${thCls} text-right w-20`}>Failed</th>\n <th className={`${thCls} text-right w-28`}>Avg Duration</th>\n </tr>\n </thead>\n <tbody>\n {byType.map((row) => (\n <tr key={row.type} className=\"border-b border-surface-border last:border-b-0\">\n <td className=\"py-3 text-sm font-mono text-text-primary\">\n <button\n onClick={() => goToList(row.type)}\n className=\"hover:text-accent hover:underline\"\n >\n {row.type}\n </button>\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.total} colorClass=\"text-text-secondary\" onClick={() => goToList(row.type)} />\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.running} colorClass=\"text-status-active\" onClick={() => goToList(row.type, 'running')} />\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.completed} colorClass=\"text-status-success\" onClick={() => goToList(row.type, 'completed')} />\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.failed} colorClass=\"text-status-error\" onClick={() => goToList(row.type, 'failed')} />\n </td>\n <td className=\"py-3 text-sm font-mono text-text-secondary text-right\">\n {row.avgDuration !== null ? formatDuration(row.avgDuration) : '—'}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n )}\n\n {byType.length === 0 && (\n <div className=\"py-16 text-center\">\n <p className=\"text-sm text-text-tertiary\">\n No workflow activity in the last {duration}\n </p>\n </div>\n )}\n </div>\n );\n}"],"names":["DURATIONS","formatDuration","ms","StatCell","value","colorClass","onClick","jsx","WorkflowsOverview","useWorkflowListEvents","navigate","useNavigate","duration","setDuration","useState","allJobs","useJobs","configs","useWorkflowConfigs","cutoff","useMemo","d","jobs","j","byType","map","entry","dur","result","type","stats","a","b","totals","registered","goToList","entity","status","params","qs","thCls","PageHeader","jsxs","StatCard","row"],"mappings":"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"}
|