@hotmeshio/long-tail 0.9.0 → 0.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/api/settings.js +2 -0
- package/build/index.js +1 -0
- package/build/modules/branding.d.ts +13 -0
- package/build/modules/branding.js +19 -0
- package/build/start/adapters.js +2 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/startup.d.ts +8 -0
- package/dashboard/dist/assets/{AdminDashboard-5bWcBxyS.js → AdminDashboard-BONGlQva.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-5bWcBxyS.js.map → AdminDashboard-BONGlQva.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-CVg_tFbf.js → AgentConfigPage-C_NJ4-pr.js} +4 -4
- package/dashboard/dist/assets/{AgentConfigPage-CVg_tFbf.js.map → AgentConfigPage-C_NJ4-pr.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-CLlkIoRQ.js → AgentDetailPage-MSCS6bFD.js} +4 -4
- package/dashboard/dist/assets/{AgentDetailPage-CLlkIoRQ.js.map → AgentDetailPage-MSCS6bFD.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-CjruF_ek.js → AgentsPage-PfSvedS-.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-CjruF_ek.js.map → AgentsPage-PfSvedS-.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-DBeBLNWW.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-DBeBLNWW.js.map +1 -0
- package/dashboard/dist/assets/{BotPicker-CGEFHHDE.js → BotPicker-DmCdoim8.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-CGEFHHDE.js.map → BotPicker-DmCdoim8.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-BI1tNYun.js → CapabilitiesPage-DVf4zIMZ.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-BI1tNYun.js.map → CapabilitiesPage-DVf4zIMZ.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-B9f52Z2K.js → CollapsibleSection-7ACdYUZy.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-B9f52Z2K.js.map → CollapsibleSection-7ACdYUZy.js.map} +1 -1
- package/dashboard/dist/assets/{CountdownTimer-C71erQ67.js → CountdownTimer-Gbp6RHav.js} +2 -2
- package/dashboard/dist/assets/{CountdownTimer-C71erQ67.js.map → CountdownTimer-Gbp6RHav.js.map} +1 -1
- package/dashboard/dist/assets/CredentialsPage-JWCUgQMi.js +2 -0
- package/dashboard/dist/assets/{CredentialsPage-smk5H_mP.js.map → CredentialsPage-JWCUgQMi.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-CCJLmkIq.js → CronLabel-9GtrGEDe.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-CCJLmkIq.js.map → CronLabel-9GtrGEDe.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-DQ28g5GB.js → CustomDurationPicker-xNJMIvjL.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-DQ28g5GB.js.map → CustomDurationPicker-xNJMIvjL.js.map} +1 -1
- package/dashboard/dist/assets/{DropZone-C_Mc4UrO.js → DropZone-wJqP4zA4.js} +2 -2
- package/dashboard/dist/assets/{DropZone-C_Mc4UrO.js.map → DropZone-wJqP4zA4.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-Cw1uvJKx.js → ElapsedCell-rRiChKDm.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-Cw1uvJKx.js.map → ElapsedCell-rRiChKDm.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-3v2tiCnq.js → EscalationListSchemaPage-B7PHz5CB.js} +2 -2
- package/dashboard/dist/assets/{EscalationListSchemaPage-3v2tiCnq.js.map → EscalationListSchemaPage-B7PHz5CB.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-DIq2pMED.js → EscalationSchemaPage-_CbayTDk.js} +3 -3
- package/dashboard/dist/assets/{EscalationSchemaPage-DIq2pMED.js.map → EscalationSchemaPage-_CbayTDk.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-BqOZ1v8w.js → EscalationsOverview-C5bVdGf2.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-BqOZ1v8w.js.map → EscalationsOverview-C5bVdGf2.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-CyfHfOWj.js → EventTable-DGaRYVnB.js} +2 -2
- package/dashboard/dist/assets/{EventTable-CyfHfOWj.js.map → EventTable-DGaRYVnB.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-DbNUaWhH.js → GraphInvokePage-R6_p2Sy7.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-DbNUaWhH.js.map → GraphInvokePage-R6_p2Sy7.js.map} +1 -1
- package/dashboard/dist/assets/HomePage-DHxtqRkD.js +2 -0
- package/dashboard/dist/assets/{HomePage-Cj9sLt4Z.js.map → HomePage-DHxtqRkD.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-D7PoQOZC.js → ListToolbar-BhXp7clK.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-D7PoQOZC.js.map → ListToolbar-BhXp7clK.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-D9g1iJyn.js → McpOverview-COgIIWkK.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-D9g1iJyn.js.map → McpOverview-COgIIWkK.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-DwS1pXdT.js → McpQueryDetailPage-4LEqQZax.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-DwS1pXdT.js.map → McpQueryDetailPage-4LEqQZax.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-DZQ1z6-H.js → McpQueryPage-DWAcSqF-.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-DZQ1z6-H.js.map → McpQueryPage-DWAcSqF-.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-Bx6w39lr.js → McpRunDetailPage-BNjhOPLp.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-Bx6w39lr.js.map → McpRunDetailPage-BNjhOPLp.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-C-oS_tTh.js → McpRunsPage-DAjYKqqt.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-C-oS_tTh.js.map → McpRunsPage-DAjYKqqt.js.map} +1 -1
- package/dashboard/dist/assets/{NamespacePill-DhgC3EUO.js → NamespacePill-BlhSWa5S.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-DhgC3EUO.js.map → NamespacePill-BlhSWa5S.js.map} +1 -1
- package/dashboard/dist/assets/OperationsPage-5RkfIbtT.js +2 -0
- package/dashboard/dist/assets/OperationsPage-5RkfIbtT.js.map +1 -0
- package/dashboard/dist/assets/{OperatorDashboard-Cqf87ojd.js → OperatorDashboard-B-2dIbj4.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-Cqf87ojd.js.map → OperatorDashboard-B-2dIbj4.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-sGNTmSXX.js → PageHeader-Ji1AtA4f.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-sGNTmSXX.js.map → PageHeader-Ji1AtA4f.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-87STTAJX.js → PageHeaderWithStats-B2qrFAaG.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-87STTAJX.js.map → PageHeaderWithStats-B2qrFAaG.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-CplnDXkz.js → ProcessDetailPage-Bx7sF-vV.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-CplnDXkz.js.map → ProcessDetailPage-Bx7sF-vV.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-DFOJC27f.js → ProcessesListPage-Dsfc-DX_.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-DFOJC27f.js.map → ProcessesListPage-Dsfc-DX_.js.map} +1 -1
- package/dashboard/dist/assets/{RoleDetailPage-VrWOaPlg.js → RoleDetailPage-DF-ov9E9.js} +3 -3
- package/dashboard/dist/assets/{RoleDetailPage-VrWOaPlg.js.map → RoleDetailPage-DF-ov9E9.js.map} +1 -1
- package/dashboard/dist/assets/{RolePill-C91qbDOW.js → RolePill-ColM_ynA.js} +2 -2
- package/dashboard/dist/assets/{RolePill-C91qbDOW.js.map → RolePill-ColM_ynA.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-DdI1rVAP.js → RolesPage-DIlde9bw.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-DdI1rVAP.js.map → RolesPage-DIlde9bw.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-C6EozzKV.js → RunAsSelector-DOYUYXcD.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-C6EozzKV.js.map → RunAsSelector-DOYUYXcD.js.map} +1 -1
- package/dashboard/dist/assets/{SlidePanel-BpWveV1T.js → SlidePanel-BzeKveus.js} +2 -2
- package/dashboard/dist/assets/{SlidePanel-BpWveV1T.js.map → SlidePanel-BzeKveus.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-BEgkYJ0-.js → StickyPagination-BwXLmDc-.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-BEgkYJ0-.js.map → StickyPagination-BwXLmDc-.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-DWVPtzj7.js → StreamMessageDetail-CCez20kE.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-DWVPtzj7.js.map → StreamMessageDetail-CCez20kE.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-4NrDJNYc.js → SwimlaneTimeline-hcWBunXb.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-4NrDJNYc.js.map → SwimlaneTimeline-hcWBunXb.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-Csm36_pS.js → TagInput-By0E_Jym.js} +2 -2
- package/dashboard/dist/assets/{TagInput-Csm36_pS.js.map → TagInput-By0E_Jym.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-BvdaAUtF.js → TaskDetailPage-CIarmoAk.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-BvdaAUtF.js.map → TaskDetailPage-CIarmoAk.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-5XdNaqwM.js → TaskQueuePill-CY1ZSwWu.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-5XdNaqwM.js.map → TaskQueuePill-CY1ZSwWu.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-BxA161LH.js → TasksListPage-CFqMwhLE.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-BxA161LH.js.map → TasksListPage-CFqMwhLE.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-ChwJ4fjZ.js → TimeAgo-CuI-66Kw.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-ChwJ4fjZ.js.map → TimeAgo-CuI-66Kw.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-C7KzmvyC.js → TimestampCell-BI3Uptj8.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-C7KzmvyC.js.map → TimestampCell-BI3Uptj8.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-CAwj7EPw.js → ToolPill-D0IzqLEe.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-CAwj7EPw.js.map → ToolPill-D0IzqLEe.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-ISkuXtkT.js → ToolTestPanel-QwGyWRfG.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-ISkuXtkT.js.map → ToolTestPanel-QwGyWRfG.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-D8uZ8Wbs.js → TopicDetailPage-CGCiqQGf.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-D8uZ8Wbs.js.map → TopicDetailPage-CGCiqQGf.js.map} +1 -1
- package/dashboard/dist/assets/TopicsPage-Bk8-inSO.js +2 -0
- package/dashboard/dist/assets/{TopicsPage-rj88vA_1.js.map → TopicsPage-Bk8-inSO.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-D03Lh6Aj.js → UserName-BOaihCFP.js} +2 -2
- package/dashboard/dist/assets/{UserName-D03Lh6Aj.js.map → UserName-BOaihCFP.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-LD9WzPee.js → WorkflowExecutionPage-CE0QzhIt.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-LD9WzPee.js.map → WorkflowExecutionPage-CE0QzhIt.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowPill-fodIWnT3.js → WorkflowPill-BXmmLR0t.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill-fodIWnT3.js.map → WorkflowPill-BXmmLR0t.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-DH0jitAb.js → WorkflowsDashboard-wgWRZOnB.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-DH0jitAb.js.map → WorkflowsDashboard-wgWRZOnB.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-D6BVaH9e.js → WorkflowsOverview-CLyitES7.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-D6BVaH9e.js.map → WorkflowsOverview-CLyitES7.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-D_CfNEqW.js → YamlWorkflowDetailPage-pP2i1ptj.js} +25 -25
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-D_CfNEqW.js.map → YamlWorkflowDetailPage-pP2i1ptj.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-BMJgtcAq.js → YamlWorkflowsPage-BwQSMfYw.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-BMJgtcAq.js.map → YamlWorkflowsPage-BwQSMfYw.js.map} +1 -1
- package/dashboard/dist/assets/{agents-Ci0tZDO3.js → agents-CRtBacrZ.js} +2 -2
- package/dashboard/dist/assets/{agents-Ci0tZDO3.js.map → agents-CRtBacrZ.js.map} +1 -1
- package/dashboard/dist/assets/{bots-DZyt1oO4.js → bots-FjzeqLzA.js} +2 -2
- package/dashboard/dist/assets/{bots-DZyt1oO4.js.map → bots-FjzeqLzA.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-DzVKeWyC.js → capabilities-CB0y1ZCx.js} +2 -2
- package/dashboard/dist/assets/{capabilities-DzVKeWyC.js.map → capabilities-CB0y1ZCx.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-CQzrn-rD.js → controlplane-ZJtfQopv.js} +2 -2
- package/dashboard/dist/assets/{controlplane-CQzrn-rD.js.map → controlplane-ZJtfQopv.js.map} +1 -1
- package/dashboard/dist/assets/escalation-columns-735GLlEN.js +2 -0
- package/dashboard/dist/assets/escalation-columns-735GLlEN.js.map +1 -0
- package/dashboard/dist/assets/{index-DOHGHMP7.js → index-AUrwksY_.js} +2 -2
- package/dashboard/dist/assets/{index-DOHGHMP7.js.map → index-AUrwksY_.js.map} +1 -1
- package/dashboard/dist/assets/{index-CcKXMU-s.js → index-BH0BQHF-.js} +2 -2
- package/dashboard/dist/assets/{index-CcKXMU-s.js.map → index-BH0BQHF-.js.map} +1 -1
- package/dashboard/dist/assets/index-BTrN5iqE.js +5 -0
- package/dashboard/dist/assets/index-BTrN5iqE.js.map +1 -0
- package/dashboard/dist/assets/{index-Dv8mzG9B.js → index-B_pZXTTp.js} +2 -2
- package/dashboard/dist/assets/{index-Dv8mzG9B.js.map → index-B_pZXTTp.js.map} +1 -1
- package/dashboard/dist/assets/{index-B2dB90aC.js → index-Bho1kYrO.js} +3 -3
- package/dashboard/dist/assets/{index-B2dB90aC.js.map → index-Bho1kYrO.js.map} +1 -1
- package/dashboard/dist/assets/index-CsMAT5cs.css +1 -0
- package/dashboard/dist/assets/{index-sdc9ecdW.js → index-CzYOxahh.js} +2 -2
- package/dashboard/dist/assets/{index-sdc9ecdW.js.map → index-CzYOxahh.js.map} +1 -1
- package/dashboard/dist/assets/{index-BWy4UvaT.js → index-D4z4fzW5.js} +2 -2
- package/dashboard/dist/assets/{index-BWy4UvaT.js.map → index-D4z4fzW5.js.map} +1 -1
- package/dashboard/dist/assets/{index-BqKxJ2fB.js → index-DiCp9bmR.js} +2 -2
- package/dashboard/dist/assets/{index-BqKxJ2fB.js.map → index-DiCp9bmR.js.map} +1 -1
- package/dashboard/dist/assets/{index-DTn4XzYN.js → index-DlrsXckY.js} +2 -2
- package/dashboard/dist/assets/{index-DTn4XzYN.js.map → index-DlrsXckY.js.map} +1 -1
- package/dashboard/dist/assets/index-DpGeD89g.js +63 -0
- package/dashboard/dist/assets/{index-C9moIiIq.js.map → index-DpGeD89g.js.map} +1 -1
- package/dashboard/dist/assets/{index-LwodswlU.js → index-DzIB5CaR.js} +3 -3
- package/dashboard/dist/assets/{index-LwodswlU.js.map → index-DzIB5CaR.js.map} +1 -1
- package/dashboard/dist/assets/{index-3SrgIA7w.js → index-GRckVBX1.js} +2 -2
- package/dashboard/dist/assets/{index-3SrgIA7w.js.map → index-GRckVBX1.js.map} +1 -1
- package/dashboard/dist/assets/{index-kPipMHZx.js → index-iEn58vjL.js} +2 -2
- package/dashboard/dist/assets/{index-kPipMHZx.js.map → index-iEn58vjL.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-fi5z5YLq.js → knowledge-Bw51BCX9.js} +2 -2
- package/dashboard/dist/assets/{knowledge-fi5z5YLq.js.map → knowledge-Bw51BCX9.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-CH8Tj9Pw.js → mcp-D4KRVy2a.js} +2 -2
- package/dashboard/dist/assets/{mcp-CH8Tj9Pw.js.map → mcp-D4KRVy2a.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-6alwNh7K.js → mcp-query-0Zo3GwTv.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-6alwNh7K.js.map → mcp-query-0Zo3GwTv.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-Dqh9PLUw.js → pipelines-B8sOpeCD.js} +2 -2
- package/dashboard/dist/assets/{pipelines-Dqh9PLUw.js.map → pipelines-B8sOpeCD.js.map} +1 -1
- package/dashboard/dist/assets/roles-Bs6hUrQJ.js +2 -0
- package/dashboard/dist/assets/{roles-dJKBZUBh.js.map → roles-Bs6hUrQJ.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-BYz490un.js → tasks-KDV3bflF.js} +2 -2
- package/dashboard/dist/assets/{tasks-BYz490un.js.map → tasks-KDV3bflF.js.map} +1 -1
- package/dashboard/dist/assets/{topics-Dt975EWi.js → topics-BS_n738l.js} +2 -2
- package/dashboard/dist/assets/{topics-Dt975EWi.js.map → topics-BS_n738l.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-ZT6RV2Gj.js → useEventHooks-RbAigCWV.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-ZT6RV2Gj.js.map → useEventHooks-RbAigCWV.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-B_G1iE9i.js → useNamespace-ChDZWKAd.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-B_G1iE9i.js.map → useNamespace-ChDZWKAd.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-DGkvIadL.js → useYamlActivityEvents-6xNaRNAc.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-DGkvIadL.js.map → useYamlActivityEvents-6xNaRNAc.js.map} +1 -1
- package/dashboard/dist/assets/{users-C2jopvM1.js → users-BPt2YERY.js} +2 -2
- package/dashboard/dist/assets/{users-C2jopvM1.js.map → users-BPt2YERY.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-BXhWQC7l.js → vendor-icons-BX2Vih4L.js} +138 -123
- package/dashboard/dist/assets/vendor-icons-BX2Vih4L.js.map +1 -0
- package/dashboard/dist/assets/{workflows-By8Wgvig.js → workflows-BaSjfNsd.js} +2 -2
- package/dashboard/dist/assets/{workflows-By8Wgvig.js.map → workflows-BaSjfNsd.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-Cq_vp41d.js → yaml-workflows-Be3rM5i2.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-Cq_vp41d.js.map → yaml-workflows-Be3rM5i2.js.map} +1 -1
- package/dashboard/dist/index.html +3 -3
- package/docs/api/http/settings.md +4 -0
- package/docs/api/sdk/settings.md +2 -1
- package/package.json +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-h6awiuVk.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-h6awiuVk.js.map +0 -1
- package/dashboard/dist/assets/CredentialsPage-smk5H_mP.js +0 -2
- package/dashboard/dist/assets/HomePage-Cj9sLt4Z.js +0 -2
- package/dashboard/dist/assets/OperationsPage-CQzX6jM1.js +0 -2
- package/dashboard/dist/assets/OperationsPage-CQzX6jM1.js.map +0 -1
- package/dashboard/dist/assets/TopicsPage-rj88vA_1.js +0 -2
- package/dashboard/dist/assets/escalation-columns-s29Q4mrF.js +0 -2
- package/dashboard/dist/assets/escalation-columns-s29Q4mrF.js.map +0 -1
- package/dashboard/dist/assets/index-BSOcWfeR.js +0 -5
- package/dashboard/dist/assets/index-BSOcWfeR.js.map +0 -1
- package/dashboard/dist/assets/index-C9moIiIq.js +0 -63
- package/dashboard/dist/assets/index-DIPe82gq.css +0 -1
- package/dashboard/dist/assets/roles-dJKBZUBh.js +0 -2
- package/dashboard/dist/assets/vendor-icons-BXhWQC7l.js.map +0 -1
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{j as e,a as f}from"./vendor-query-B2UbickB.js";import{c as et,f as tt,a as st}from"./vendor-react-CXumBFUA.js";import{M as ne,j as Pe,b as Ae,u as at,k as nt,l as lt,g as it,m as rt,n as ot,o as ct,p as dt,q as ut,r as xt,s as mt,t as ht,v as gt}from"./index-C9moIiIq.js";import{f as pt}from"./useEventHooks-ZT6RV2Gj.js";import{i as A,u as ie,C as Ee,a as ft}from"./CustomDurationPicker-DQ28g5GB.js";import{u as bt,a as yt}from"./roles-dJKBZUBh.js";import{a as vt}from"./StatusBadge-CEQMRmSQ.js";import{i as jt}from"./CountdownTimer-C71erQ67.js";import{a4 as Nt,a5 as Ct,a6 as kt,a7 as St,S as wt,X as Pt}from"./vendor-icons-BXhWQC7l.js";import{u as At}from"./useFilterParams-x-Dg0Vgz.js";import{u as Be}from"./useDebouncedValue-BA5S7V54.js";import{b as Et}from"./api-path-u2Jf9QXS.js";import{D as Bt}from"./DataTable-Byn3oyT9.js";import{S as Tt}from"./StickyPagination-BEgkYJ0-.js";import{P as Ot}from"./PageHeader-sGNTmSXX.js";import{P as Mt}from"./constants-BHkpVaqx.js";import{M as re}from"./Modal-CSrxpXeM.js";import{u as Ft}from"./users-C2jopvM1.js";import{E as _t,a as Lt}from"./escalation-columns-s29Q4mrF.js";import{R as Rt,a as zt}from"./RowActions-BA9L9djf.js";import{L as It}from"./ListToolbar-D7PoQOZC.js";import"./EmptyState-BcsfPq9T.js";import"./FilterBar-DDIn8TOs.js";import"./PriorityBadge-B4ykBH7f.js";import"./RolePill-C91qbDOW.js";import"./WorkflowPill-fodIWnT3.js";const F=t=>{if(t)try{return JSON.parse(t)}catch{return}},E=t=>t==null||Array.isArray(t)&&t.length===0||typeof t=="object"&&!Array.isArray(t)&&Object.keys(t).length===0;function $t(t){const s={},l=F(t.get("facets"));E(l)||(s.facets=l);const n=F(t.get("block"));E(n)||(s.block=n);const m=F(t.get("range"));E(m)||(s.range=m);const h=F(t.get("exists"));E(h)||(s.exists=h);const u=F(t.get("roles"));E(u)||(s.roles=u);const i=F(t.get("orderBy"));return E(i)||(s.orderBy=i),t.get("available")!=null&&(s.available=t.get("available")==="true"),s}function Dt(t,s){const l=(n,m)=>E(m)?t.delete(n):t.set(n,JSON.stringify(m));l("facets",s.facets),l("block",s.block),l("range",s.range),l("exists",s.exists),l("roles",s.roles),l("orderBy",s.orderBy),s.available==null?t.delete("available"):t.set("available",String(s.available))}function Ht(t){var s,l,n,m;return Object.keys(t.facets??{}).length+(((s=t.block)==null?void 0:s.length)??0)+(((l=t.range)==null?void 0:l.length)??0)+(((n=t.exists)==null?void 0:n.length)??0)+(((m=t.orderBy)==null?void 0:m.length)??0)+(t.available!=null?1:0)}const Ut=["<","<=",">",">=","="],qt=["priority","created_at","updated_at","status","role"],P="h-7 rounded border border-surface-border bg-surface px-2 text-xs text-text-primary focus:border-accent focus:outline-none",V="text-text-tertiary hover:text-text-primary transition-colors";function ke(t){return t==="true"?!0:t==="false"?!1:t.trim()!==""&&!Number.isNaN(Number(t))?Number(t):t}const Jt=t=>Object.entries(t??{}).map(([s,l])=>({key:s,value:String(l)})),Vt=t=>(t??[]).map(s=>{const[l,n]=Object.entries(s)[0]??["",""];return{key:l,value:String(n)}});function _({title:t,hint:s,children:l}){return e.jsxs("div",{className:"border-t border-surface-border/50 py-3 first:border-t-0 first:pt-1",children:[e.jsxs("div",{className:"mb-1.5 flex items-baseline justify-between",children:[e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-text-tertiary",children:t}),s&&e.jsx("span",{className:"text-[10px] font-mono text-text-tertiary/70",children:s})]}),l]})}function Q({value:t,onChange:s,placeholder:l}){return e.jsx("input",{list:"lt-facet-keys",className:`${P} w-40`,placeholder:l,value:t,onChange:n=>s(n.target.value)})}function Qt({value:t,onChange:s,facetKeys:l=[],search:n="",onSearchChange:m}){const h=Jt(t.facets),u=Vt(t.block),i=t.range??[],d=t.exists??[],b=t.orderBy??[],v=a=>{const o={};for(const r of a)r.key&&(o[r.key]=ke(r.value));s({...t,facets:Object.keys(o).length?o:void 0})},y=a=>{const o=a.filter(r=>r.key).map(r=>({[r.key]:ke(r.value)}));s({...t,block:o.length?o:void 0})},N=a=>s({...t,range:a.length?a:void 0}),S=a=>s({...t,exists:a.length?a:void 0}),k=a=>s({...t,orderBy:a.length?a:void 0});return e.jsxs("div",{className:"text-xs",children:[e.jsx("datalist",{id:"lt-facet-keys",children:l.map(a=>e.jsx("option",{value:a},a))}),e.jsxs("datalist",{id:"lt-sort-fields",children:[qt.map(a=>e.jsx("option",{value:a},a)),l.map(a=>e.jsx("option",{value:`metadata.${a}`},a))]}),m&&e.jsx(_,{title:"Match id",hint:"id · workflow · origin",children:e.jsx("input",{className:`${P} w-full`,placeholder:"Exact escalation, workflow, or origin id…",value:n,onChange:a=>m(a.target.value)})}),e.jsx(_,{title:"Has facet",hint:"metadata @>",children:[...h,{key:"",value:""}].map((a,o)=>e.jsxs("div",{className:"mb-1 flex items-center gap-1",children:[e.jsx(Q,{value:a.key,placeholder:"key",onChange:r=>{const c=[...h];c[o]={...a,key:r},v(c)}}),e.jsx("span",{className:"text-text-tertiary",children:"="}),e.jsx("input",{className:`${P} w-40`,placeholder:"value",value:a.value,onChange:r=>{const c=[...h];c[o]={...a,value:r.target.value},v(c)}}),o<h.length&&e.jsx("button",{className:V,onClick:()=>v(h.filter((r,c)=>c!==o)),children:"×"})]},o))}),e.jsx(_,{title:"Range",hint:"numeric",children:[...i,{facet:"",op:"<=",value:0}].map((a,o)=>e.jsxs("div",{className:"mb-1 flex items-center gap-1",children:[e.jsx(Q,{value:a.facet,placeholder:"numeric facet",onChange:r=>{const c=[...i];c[o]={...a,facet:r},N(c.filter(j=>j.facet))}}),e.jsx("select",{className:P,value:a.op,onChange:r=>{const c=[...i];c[o]={...a,op:r.target.value},N(c.filter(j=>j.facet))},children:Ut.map(r=>e.jsx("option",{value:r,children:r},r))}),e.jsx("input",{type:"number",className:`${P} w-24`,value:a.value,onChange:r=>{const c=[...i];c[o]={...a,value:Number(r.target.value)},N(c.filter(j=>j.facet))}}),o<i.length&&e.jsx("button",{className:V,onClick:()=>N(i.filter((r,c)=>c!==o)),children:"×"})]},o))}),e.jsx(_,{title:"Has key",hint:"metadata ? key",children:e.jsxs("div",{className:"flex flex-wrap items-center gap-1",children:[d.map(a=>e.jsxs("span",{className:"flex items-center gap-1 rounded bg-accent/15 px-1.5 py-0.5 text-accent",children:[a,e.jsx("button",{className:"text-accent/70 hover:text-accent",onClick:()=>S(d.filter(o=>o!==a)),children:"×"})]},a)),e.jsx(Q,{value:"",placeholder:"+ key",onChange:a=>{a&&!d.includes(a)&&S([...d,a])}})]})}),e.jsx(_,{title:"Exclude",hint:"NOT @>",children:[...u,{key:"",value:""}].map((a,o)=>e.jsxs("div",{className:"mb-1 flex items-center gap-1",children:[e.jsx(Q,{value:a.key,placeholder:"key",onChange:r=>{const c=[...u];c[o]={...a,key:r},y(c)}}),e.jsx("span",{className:"text-text-tertiary",children:"="}),e.jsx("input",{className:`${P} w-40`,placeholder:"value",value:a.value,onChange:r=>{const c=[...u];c[o]={...a,value:r.target.value},y(c)}}),o<u.length&&e.jsx("button",{className:V,onClick:()=>y(u.filter((r,c)=>c!==o)),children:"×"})]},o))}),e.jsx(_,{title:"Sort by",children:[...b,{field:"",direction:"asc"}].map((a,o)=>e.jsxs("div",{className:"mb-1 flex items-center gap-1",children:[e.jsx("input",{list:"lt-sort-fields",className:`${P} w-44`,placeholder:"column or metadata.key",value:a.field,onChange:r=>{const c=[...b];c[o]={...a,field:r.target.value},k(c.filter(j=>j.field))}}),e.jsxs("select",{className:P,value:a.direction??"asc",onChange:r=>{const c=[...b];c[o]={...a,direction:r.target.value},k(c.filter(j=>j.field))},children:[e.jsx("option",{value:"asc",children:"asc"}),e.jsx("option",{value:"desc",children:"desc"})]}),e.jsxs("label",{className:"flex items-center gap-1 text-text-tertiary",children:[e.jsx("input",{type:"checkbox",checked:!!a.numeric,onChange:r=>{const c=[...b];c[o]={...a,numeric:r.target.checked},k(c.filter(j=>j.field))}}),"num"]}),o<b.length&&e.jsx("button",{className:V,onClick:()=>k(b.filter((r,c)=>c!==o)),children:"×"})]},o))})]})}function oe(t){const s=l=>{if(!l)return null;try{const n=JSON.parse(l);return n&&typeof n=="object"?n:null}catch{return null}};return{escalation:t,metadata:t.metadata??null,envelope:s(t.envelope),payload:s(t.escalation_payload),resolver:s(t.resolver_payload)}}const Gt=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/,Se="—";function Yt({raw:t}){return!t||t===Se?e.jsx("span",{className:"text-text-quaternary",children:Se}):Gt.test(t)?e.jsx(Ae,{date:t,format:"datetime",className:"text-text-primary"}):e.jsx(e.Fragment,{children:t})}function Kt({esc:t,card:s,onOpen:l}){const n=oe(t),m=s.title?A(s.title,n):t.type,h=t.status==="pending"&&!jt(t);return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-start justify-between gap-6",children:[e.jsxs("button",{onClick:l,className:"text-left group min-w-0",children:[e.jsx("h3",{className:"text-2xl font-light text-text-primary group-hover:text-accent transition-colors leading-tight",children:m}),s.subtitle&&e.jsx("p",{className:"text-xs text-text-tertiary mt-1.5",children:A(s.subtitle,n)})]}),h&&e.jsxs("button",{onClick:l,className:"inline-flex items-center gap-1.5 px-4 py-2 rounded-md bg-accent text-text-inverse text-xs font-medium hover:bg-accent-hover transition-colors shrink-0",children:["Claim",e.jsx(Nt,{className:"w-3.5 h-3.5"})]})]}),s.fields&&s.fields.length>0&&e.jsx("dl",{className:"flex flex-wrap gap-x-10 gap-y-4 mt-6",children:s.fields.map((u,i)=>e.jsxs("div",{children:[e.jsx("dt",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:u.label}),e.jsx("dd",{className:"text-xs text-text-primary mt-1",children:e.jsx(Yt,{raw:A(u.value,n)})})]},i))}),s.body&&e.jsx("div",{className:"mt-7 pt-6 border-t border-surface-border/50",children:e.jsx(ne,{content:A(s.body,n)})})]})}function Xt({role:t,def:s,onRowClick:l}){var b,v;const[n,m]=f.useState(!1),h=Pe({role:t,status:s.status??"resolved",sort_by:"resolved_at",order:"desc",limit:s.limit??25,enabled:n}),u=((b=h.data)==null?void 0:b.escalations)??[],i=((v=h.data)==null?void 0:v.total)??0,d=s.row??{};return n?h.isLoading?e.jsx("p",{className:"text-xs text-text-tertiary italic",children:"Loading history…"}):u.length===0?e.jsx("p",{className:"text-xs text-text-tertiary italic",children:"No past revisions."}):e.jsxs("div",{children:[e.jsx("div",{className:"divide-y divide-surface-border/40",children:u.map(y=>{const N=oe(y);return e.jsxs("button",{onClick:()=>l==null?void 0:l(y),className:"w-full text-left py-2.5 group flex items-center gap-3",children:[e.jsx("span",{className:`w-1.5 h-1.5 shrink-0 rounded-full dot-ring ${vt[y.status]??"bg-status-pending"}`,title:y.status}),e.jsxs("span",{className:"min-w-0 flex-1",children:[e.jsx("span",{className:"block text-xs text-text-primary group-hover:text-accent transition-colors truncate",children:d.title?A(d.title,N):y.type}),d.subtitle&&e.jsx("span",{className:"block text-[10px] text-text-tertiary truncate",children:A(d.subtitle,N)})]}),d.meta?e.jsx("span",{className:"text-[10px] text-text-tertiary shrink-0",children:A(d.meta,N)}):y.resolved_at&&e.jsx(Ae,{date:y.resolved_at,format:"relative",className:"text-[10px] text-text-tertiary shrink-0 whitespace-nowrap"})]},y.id)})}),i>u.length&&e.jsxs("p",{className:"text-[10px] text-text-quaternary mt-3",children:["Showing ",u.length," of ",i,"."]})]}):e.jsx("button",{onClick:()=>m(!0),className:"text-xs text-accent hover:underline","data-testid":"load-history",children:"Load full history →"})}function we({children:t}){return e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-3",children:t})}function Wt({role:t,listSchema:s,activeEscalations:l,onRowClick:n}){const m=s["x-lt-layout"],h=s["x-lt-active"]??{},u=l[0],i=s["x-lt-help"],d=u?e.jsx(Kt,{esc:u,card:h,onOpen:()=>n==null?void 0:n(u)}):e.jsx("p",{className:"text-xs text-text-tertiary italic",children:"No active item right now."}),b=i&&u?e.jsx("div",{className:"mb-8",children:e.jsx(ne,{content:A(i,oe(u))})}):i?e.jsx("div",{className:"mb-8",children:e.jsx(ne,{content:i})}):null;return m==="active-history"?e.jsxs("div",{children:[b,e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-[1.6fr_1fr] gap-12 items-start",children:[e.jsxs("div",{children:[e.jsx(we,{children:"Active"}),d]}),e.jsxs("div",{children:[e.jsx(we,{children:"History"}),e.jsx(Xt,{role:t,def:s["x-lt-history"]??{},onRowClick:n})]})]})]}):e.jsxs("div",{children:[b,d]})}const Zt=t=>t.isPriorityPending||t.isClaimPending||t.isAssignPending||t.isEscalatePending||t.isTriagePending||t.isCancelPending,le="inline-flex items-center h-7 px-2.5 text-[11px] font-medium text-text-secondary bg-surface border border-surface-border rounded-[4px] hover:border-accent/50 hover:text-text-primary transition-colors disabled:opacity-50 disabled:hover:border-surface-border",ae=`${le} appearance-none cursor-pointer`,es="inline-flex items-center h-7 px-2.5 text-[11px] font-medium text-status-error bg-surface border border-status-error/30 rounded-[4px] hover:border-status-error hover:bg-status-error/5 transition-colors disabled:opacity-50";function ts(t){var u;const s=Zt(t),l=ie(),{data:n}=at(),m=((u=n==null?void 0:n.ai)==null?void 0:u.enabled)===!0,h=t.selectedCount>0;return e.jsx("div",{className:`grid transition-all duration-200 ease-in-out ${h?"grid-rows-[1fr] opacity-100":"grid-rows-[0fr] opacity-0 pointer-events-none"}`,children:e.jsx("div",{className:"overflow-hidden",children:e.jsxs("div",{className:"flex flex-wrap items-center gap-2 py-2.5 pl-3 pr-2 mt-4 mb-3 bg-surface-sunken/60 border-l-2 border-l-accent",children:[e.jsxs("span",{className:"text-[11px] font-semibold uppercase tracking-wider text-accent tabular-nums",children:[t.selectedCount," selected"]}),e.jsx("div",{className:"mx-1 h-4 w-px bg-surface-border"}),e.jsxs("select",{onChange:i=>{i.target.value&&(t.onSetPriority(parseInt(i.target.value)),i.target.value="")},disabled:s,className:ae,defaultValue:"",children:[e.jsx("option",{value:"",disabled:!0,children:"Priority…"}),Mt.map(i=>e.jsx("option",{value:i.value,children:i.label},i.value))]}),e.jsxs("select",{onChange:i=>{i.target.value&&(t.onClaim(parseInt(i.target.value)),i.target.value="")},disabled:s,className:ae,defaultValue:"",children:[e.jsx("option",{value:"",disabled:!0,children:"Claim for…"}),l.map(i=>e.jsx("option",{value:i.value,children:i.label},i.value))]}),e.jsx("button",{onClick:t.onAssign,disabled:s,className:le,children:t.isAssignPending?"Assigning…":"Assign to…"}),t.availableRoles.length>0&&e.jsxs("select",{onChange:i=>{i.target.value&&(t.onEscalate(i.target.value),i.target.value="")},disabled:s,className:ae,defaultValue:"",children:[e.jsx("option",{value:"",disabled:!0,children:"Escalate to…"}),t.availableRoles.map(i=>e.jsx("option",{value:i,children:i},i))]}),m&&e.jsx("button",{onClick:t.onTriage,disabled:s,className:le,children:t.isTriagePending?"Triaging…":"Triage"}),e.jsx("button",{onClick:t.onCancel,disabled:s,className:es,children:t.isCancelPending?"Cancelling…":"Cancel"}),e.jsx("div",{className:"flex-1"}),s&&e.jsx("span",{className:"text-[11px] text-text-tertiary animate-pulse",children:"Processing…"}),e.jsx("button",{onClick:t.onClearSelection,className:"px-1 text-[11px] font-medium text-text-tertiary hover:text-text-primary transition-colors",children:"Clear"})]})})})}function ss({open:t,onClose:s,selectedCount:l,selectedRoles:n,onSubmit:m,isPending:h}){const{isSuperAdmin:u}=nt(),i=ie(),[d,b]=f.useState("user"),[v,y]=f.useState(null),[N,S]=f.useState(""),[k,a]=f.useState("30"),[o,r]=f.useState(0),c=f.useCallback(g=>r(g),[]),j=!u&&n.length===1?n[0]:void 0,D=Be(N,250),{data:p,isLoading:R}=Ft({role:j,status:"active",search:D.trim()||void 0,limit:200}),B=(p==null?void 0:p.users)??[],T=()=>{b("user"),y(null),S(""),a("30"),r(0),s()},G=g=>{y(g),b("duration")},z=()=>{b("user")},Y=()=>{if(!v)return;const g=k==="custom"?o:parseInt(k);!g||g<=0||m(v.id,g)};return e.jsx(re,{open:t,onClose:T,title:"Assign Escalations",children:e.jsxs("div",{className:"space-y-4",children:[d==="user"&&e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"text-sm text-text-secondary",children:["Select a user to assign"," ",e.jsx("span",{className:"font-medium text-text-primary",children:l})," ","escalation(s) to:"]}),e.jsx("input",{type:"text",value:N,onChange:g=>S(g.target.value),placeholder:"Search by name or email...",className:"input text-xs w-full",autoFocus:!0}),e.jsxs("div",{className:"max-h-60 overflow-y-auto border border-surface-border rounded-lg divide-y divide-surface-border",children:[R&&e.jsx("p",{className:"text-xs text-text-tertiary p-3",children:"Loading users..."}),!R&&B.length===0&&e.jsx("p",{className:"text-xs text-text-tertiary p-3",children:"No users found"}),B.map(g=>e.jsxs("button",{onClick:()=>G(g),className:"w-full text-left px-3 py-2 hover:bg-surface-hover transition-colors",children:[e.jsx("p",{className:"text-xs font-medium text-text-primary",children:g.display_name||g.external_id}),g.email&&e.jsx("p",{className:"text-[10px] text-text-tertiary",children:g.email})]},g.id))]}),e.jsx("div",{className:"flex justify-end pt-2",children:e.jsx("button",{onClick:T,className:"btn-secondary text-xs",children:"Cancel"})})]}),d==="duration"&&v&&e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"text-sm text-text-secondary",children:["Assign to"," ",e.jsx("span",{className:"font-medium text-text-primary",children:v.display_name||v.external_id})," ","for:"]}),e.jsxs("select",{value:k,onChange:g=>{a(g.target.value),r(0)},className:"select w-full text-sm",children:[i.map(g=>e.jsx("option",{value:g.value,children:g.label},g.value)),e.jsx("option",{value:"custom",children:"Other..."})]}),k==="custom"&&e.jsx(Ee,{onChange:c,autoFocus:!0}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{onClick:z,className:"btn-secondary text-xs",children:"Back"}),e.jsx("button",{onClick:Y,disabled:h,className:"btn-primary text-xs",children:h?"Assigning...":"Assign"})]})]})]})})}function as({open:t,onClose:s,selectedCount:l,onSubmit:n,isPending:m}){const[h,u]=f.useState(""),i=()=>{n(h||void 0)};return e.jsx(re,{open:t,onClose:s,title:"Submit for AI Triage",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("p",{className:"text-sm text-text-secondary",children:["Submit ",e.jsx("span",{className:"font-medium text-text-primary",children:l})," escalation(s) for AI triage? The triage orchestrator will take over resolution."]}),e.jsxs("div",{children:[e.jsxs("label",{className:"text-xs font-medium text-text-secondary block mb-1",children:["Triage hint ",e.jsx("span",{className:"text-text-tertiary",children:"(optional)"})]}),e.jsx("input",{type:"text",value:h,onChange:d=>u(d.target.value),placeholder:"e.g., image_orientation",className:"input text-xs font-mono w-full"}),e.jsx("p",{className:"text-[10px] text-text-tertiary mt-1",children:"Guides the triage workflow on what remediation to apply"})]}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{onClick:s,className:"btn-secondary text-xs",children:"Cancel"}),e.jsx("button",{onClick:i,disabled:m,className:"btn-primary text-xs",children:m?"Submitting...":"Submit for Triage"})]})]})})}function L(t,s,l){return n=>{t.mutate(n,{onSuccess:()=>{s(),l==null||l()}})}}function ns(t){const s=()=>[...t.selectedIds];return{handleSetPriority:d=>{L(t.setPriority,t.clearSelection)({ids:s(),priority:d})},handleBulkClaim:d=>{L(t.bulkClaim,t.clearSelection)({ids:s(),durationMinutes:d})},handleBulkEscalate:d=>{L(t.bulkEscalate,t.clearSelection)({ids:s(),targetRole:d})},handleBulkTriage:d=>{L(t.bulkTriage,t.clearSelection,t.closeTriageModal)({ids:s(),hint:d})},handleBulkAssign:(d,b)=>{L(t.bulkAssign,t.clearSelection,t.closeAssignModal)({ids:s(),targetUserId:d,durationMinutes:b})},handleBulkCancel:()=>{L(t.bulkCancel,t.clearSelection,t.closeCancelModal)({ids:s()})}}}function ls({claimTarget:t,onClose:s,claimDuration:l,onDurationChange:n,claimDurations:m,onCustomClaimChange:h,onClaim:u,isPending:i}){return e.jsx(re,{open:!!t,onClose:s,title:"Claim Escalation",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("p",{className:"text-sm text-text-secondary",children:["Claim ",e.jsx("span",{className:"font-medium text-text-primary",children:t==null?void 0:t.type})," for:"]}),e.jsxs("select",{value:l,onChange:d=>{n(d.target.value)},className:"select w-full text-sm",children:[m.map(d=>e.jsx("option",{value:d.value,children:d.label},d.value)),e.jsx("option",{value:"custom",children:"Other..."})]}),l==="custom"&&e.jsx(Ee,{onChange:h,autoFocus:!0}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{onClick:s,className:"btn-secondary text-xs",children:"Cancel"}),e.jsx("button",{onClick:u,className:"btn-primary text-xs",disabled:i,children:i?"Claiming...":"Claim"})]})]})})}function Ms(){var fe,be,ye,ve,je,Ne,Ce;pt();const t=et(),{filters:s,setFilter:l,pagination:n,sort:m,setSort:h}=At({filters:{role:"",type:"",priority:"",status:"available",search:""}}),u=Be(s.search,300),i=ie(),[d,b]=f.useState(null),[v,y]=f.useState("30"),[N,S]=f.useState(0),k=f.useCallback(x=>S(x),[]),[a,o]=f.useState(new Set),[r,c]=f.useState(!1),[j,D]=tt(),p=f.useMemo(()=>$t(j),[j]),R=f.useCallback(x=>{D(C=>{const se=new URLSearchParams(C);return Dt(se,x),se.delete("page"),se},{replace:!0})},[D]),{data:B}=lt(r),T=Ht(p)+(s.search?1:0),[G,z]=f.useState(!1),[Y,g]=f.useState(!1),[Te,K]=f.useState(!1),ce=it(),de=rt(),ue=ot(),X=ct(),xe=dt(),W=ut(),H=xt(),{data:O}=bt(),{data:Z}=mt();f.useEffect(()=>{o(new Set)},[s.role,s.type,s.priority,s.status,u,n.page,n.pageSize]);const I=s.status||"",$=I==="available",ee=I==="claimed",me=ee?"pending":I==="resolved"?"resolved":I==="cancelled"?"cancelled":I==="expired"?"expired":void 0,he={role:s.role||void 0,type:s.type||void 0,priority:s.priority?parseInt(s.priority):void 0,limit:n.pageSize,offset:n.offset,sort_by:m.sort_by||"created_at",order:m.order||"desc",search:u||void 0,...p},Oe=ht({...he,enabled:$}),Me=Pe({status:me,claimed:ee||void 0,...he,enabled:!$}),Fe=$?Oe:Me,{data:M,isLoading:_e,error:U,refetch:Le,isFetching:Re}=Fe,ze=Et(`/escalations${$?"/available":""}`,{status:me,claimed:ee||void 0,role:s.role||void 0,type:s.type||void 0,priority:s.priority||void 0,search:u||void 0,sort_by:m.sort_by||"created_at",order:m.order||"desc",limit:n.pageSize,offset:n.offset,facets:p.facets&&Object.keys(p.facets).length?JSON.stringify(p.facets):void 0,block:(fe=p.block)!=null&&fe.length?JSON.stringify(p.block):void 0,range:(be=p.range)!=null&&be.length?JSON.stringify(p.range):void 0,exists:(ye=p.exists)!=null&&ye.length?JSON.stringify(p.exists):void 0,roles:(ve=p.roles)!=null&&ve.length?JSON.stringify(p.roles):void 0,orderBy:(je=p.orderBy)!=null&&je.length?JSON.stringify(p.orderBy):void 0,available:p.available!=null?String(p.available):void 0}),w=(M==null?void 0:M.escalations)??[],ge=(M==null?void 0:M.total)??0,{canBulk:Ie}=gt(),q=s.role||(((Ne=p.roles)==null?void 0:Ne.length)===1?p.roles[0]:null),[te,$e]=f.useState(!1),J=((Ce=yt(q??"",void 0,!!q).data)==null?void 0:Ce.list_schema)??null,pe=!!q&&!!J&&!!J["x-lt-layout"]&&J["x-lt-layout"]!=="table",De=pe&&!te,He=f.useMemo(()=>{const x=new Set;for(const C of w)a.has(C.id)&&x.add(C.role);return[...x]},[w,a]),Ue=f.useCallback(()=>o(new Set),[]),qe=()=>{if(!d)return;const x=v==="custom"?N:parseInt(v);!x||x<=0||ce.mutate({id:d.id,durationMinutes:x},{onSuccess:()=>{b(null),t(`/escalations/detail/${d.id}`)}})},{handleSetPriority:Je,handleBulkClaim:Ve,handleBulkEscalate:Qe,handleBulkTriage:Ge,handleBulkAssign:Ye,handleBulkCancel:Ke}=ns({selectedIds:a,clearSelection:Ue,setPriority:de,bulkClaim:ue,bulkEscalate:xe,bulkTriage:W,bulkAssign:X,bulkCancel:H,closeTriageModal:()=>z(!1),closeAssignModal:()=>g(!1),closeCancelModal:()=>K(!1)}),Xe=x=>{const C=new Set(a);C.has(x)?C.delete(x):C.add(x),o(C)},We=()=>{a.size===w.length?o(new Set):o(new Set(w.map(x=>x.id)))},Ze=[Ie?{key:"select",label:e.jsx("input",{type:"checkbox",checked:w.length>0&&a.size===w.length,onChange:We,className:"rounded"}),render:x=>e.jsx("input",{type:"checkbox",checked:a.has(x.id),onChange:C=>{C.stopPropagation(),Xe(x.id)},onClick:C=>C.stopPropagation(),className:"rounded"}),className:"w-10"}:{key:"spacer",label:"",render:()=>null,className:"w-10"},..._t,{key:"actions",label:"",render:x=>e.jsx(Rt,{children:e.jsx(zt,{icon:Ct,title:"Claim escalation",onClick:()=>b(x),colorClass:"text-accent/75 hover:text-accent",size:"sm"})}),className:"w-10 text-right"}];return e.jsxs("div",{children:[e.jsx(Ot,{title:"All Escalations",docsHash:"#docs:dashboard.md:all-escalations"}),e.jsx(Lt,{filters:s,setFilter:l,roles:(O==null?void 0:O.roles)??[],types:(Z==null?void 0:Z.types)??[],showStatus:!0,showSearch:!1,actions:e.jsxs(e.Fragment,{children:[e.jsx(It,{onRefresh:()=>Le(),isFetching:Re,apiPath:ze}),pe&&e.jsx("button",{onClick:()=>$e(x=>!x),className:"ml-2 inline-flex h-7 w-7 items-center justify-center rounded text-text-tertiary hover:bg-surface-hover hover:text-text-primary transition-colors",title:te?"Rich view":"Table view",children:te?e.jsx(kt,{className:"w-4 h-4"}):e.jsx(St,{className:"w-4 h-4"})}),e.jsxs("button",{onClick:()=>c(x=>!x),className:"relative ml-2 inline-flex h-7 w-7 items-center justify-center rounded text-text-tertiary hover:bg-surface-hover hover:text-text-primary transition-colors",title:"Faceted query",children:[e.jsx(wt,{className:"w-4 h-4"}),T>0&&e.jsx("span",{className:"absolute -right-1 -top-1 flex h-3.5 min-w-[14px] items-center justify-center rounded-full bg-accent px-0.5 text-[9px] font-medium text-white",children:T})]})]})}),st.createPortal(e.jsxs("div",{className:`fixed right-0 bottom-0 w-[420px] z-40 border-l border-surface-border bg-surface overflow-y-auto shadow-lg transition-transform duration-200 ease-out ${r?"translate-x-0":"pointer-events-none translate-x-full"}`,style:{top:"3.5rem"},"aria-hidden":!r,children:[e.jsxs("div",{className:"sticky top-0 z-10 flex items-center justify-between px-4 py-3 bg-surface border-b border-surface-border/50",children:[e.jsx("span",{className:"text-xs font-medium text-text-primary",children:"Faceted query"}),e.jsxs("div",{className:"flex items-center gap-2",children:[T>0&&e.jsx("button",{onClick:()=>{R({}),l("search","")},className:"text-[11px] text-text-tertiary hover:text-text-primary transition-colors",children:"Clear"}),e.jsx("button",{onClick:()=>c(!1),className:"p-1 rounded hover:bg-surface-hover text-text-tertiary hover:text-text-primary transition-colors",title:"Close",children:e.jsx(Pt,{className:"w-4 h-4"})})]})]}),e.jsxs("div",{className:"px-4 py-2",children:[e.jsxs("p",{className:"mb-2 text-[11px] leading-snug text-text-tertiary",children:["Precise metadata facets plus exact correlation-id lookup — they compose in one SQL query. Facet keys are the ones that actually exist in your visible escalations. Set status to ",e.jsx("span",{className:"font-medium",children:"All"})," to find an order across every status; the whole query is shareable via the URL."]}),e.jsx(Qt,{value:p,onChange:R,facetKeys:(B==null?void 0:B.keys)??[],search:s.search??"",onSearchChange:x=>l("search",x)})]})]}),document.body),e.jsx(ts,{selectedCount:a.size,onClearSelection:()=>o(new Set),onSetPriority:Je,onClaim:Ve,onAssign:()=>g(!0),onEscalate:Qe,onTriage:()=>z(!0),onCancel:()=>K(!0),isPriorityPending:de.isPending,isClaimPending:ue.isPending,isAssignPending:X.isPending,isEscalatePending:xe.isPending,isTriagePending:W.isPending,isCancelPending:H.isPending,availableRoles:(O==null?void 0:O.roles)??[]}),U&&e.jsx("div",{className:"mb-4 px-4 py-3 rounded-md bg-status-error/10 border border-status-error/20 text-xs text-status-error",children:U.message==="Session expired"?"Your session has expired. Please log in again.":`Failed to load escalations: ${U.message}`}),De?e.jsx(Wt,{role:q,listSchema:J,activeEscalations:w,onRowClick:x=>t(`/escalations/detail/${x.id}`,{state:{from:"/escalations/available"}})}):e.jsxs(e.Fragment,{children:[e.jsx(Bt,{columns:Ze,data:w,keyFn:x=>x.id,onRowClick:x=>t(`/escalations/detail/${x.id}`,{state:{from:"/escalations/available"}}),isLoading:_e,emptyMessage:U?"Unable to load data":"No escalations",sort:m,onSort:h}),e.jsx(Tt,{page:n.page,totalPages:n.totalPages(ge),onPageChange:n.setPage,total:ge,pageSize:n.pageSize,onPageSizeChange:n.setPageSize})]}),e.jsx(ls,{claimTarget:d,onClose:()=>b(null),claimDuration:v,onDurationChange:x=>{y(x),S(0)},claimDurations:i,customClaimMinutes:N,onCustomClaimChange:k,onClaim:qe,isPending:ce.isPending}),e.jsx(as,{open:G,onClose:()=>z(!1),selectedCount:a.size,onSubmit:Ge,isPending:W.isPending}),e.jsx(ss,{open:Y,onClose:()=>g(!1),selectedCount:a.size,selectedRoles:He,onSubmit:Ye,isPending:X.isPending}),e.jsx(ft,{open:Te,onClose:()=>K(!1),onConfirm:Ke,selectedCount:a.size,isPending:H.isPending,error:H.error})]})}export{Ms as AvailableEscalationsPage};
|
|
2
|
-
//# sourceMappingURL=AvailableEscalationsPage-h6awiuVk.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AvailableEscalationsPage-h6awiuVk.js","sources":["../../src/lib/facet-url.ts","../../src/pages/operator/FacetedFilterPanel.tsx","../../src/components/escalation/EscalationListView.tsx","../../src/components/common/modal/BulkActionBar.tsx","../../src/components/common/modal/BulkAssignModal.tsx","../../src/components/common/modal/BulkTriageModal.tsx","../../src/pages/operator/helpers.ts","../../src/pages/operator/ClaimModal.tsx","../../src/pages/operator/AvailableEscalationsPage.tsx"],"sourcesContent":["import type { FacetFilters } from '../api/escalations';\n\n// The faceted query is DEEP-LINKED: every element lives in the URL as a JSON-encoded\n// search param (the same names the API/route use), so a shared link reproduces the\n// exact query and back/forward navigation restores it.\n\nconst parse = (v: string | null): any => {\n if (!v) return undefined;\n try { return JSON.parse(v); } catch { return undefined; }\n};\n\nconst isEmpty = (v: unknown): boolean =>\n v == null ||\n (Array.isArray(v) && v.length === 0) ||\n (typeof v === 'object' && !Array.isArray(v) && Object.keys(v as object).length === 0);\n\n/** Read the faceted query from URL search params. */\nexport function parseFacetParams(sp: URLSearchParams): FacetFilters {\n const f: FacetFilters = {};\n const facets = parse(sp.get('facets')); if (!isEmpty(facets)) f.facets = facets;\n const block = parse(sp.get('block')); if (!isEmpty(block)) f.block = block;\n const range = parse(sp.get('range')); if (!isEmpty(range)) f.range = range;\n const exists = parse(sp.get('exists')); if (!isEmpty(exists)) f.exists = exists;\n const roles = parse(sp.get('roles')); if (!isEmpty(roles)) f.roles = roles;\n const orderBy = parse(sp.get('orderBy')); if (!isEmpty(orderBy)) f.orderBy = orderBy;\n if (sp.get('available') != null) f.available = sp.get('available') === 'true';\n return f;\n}\n\n/** Write the faceted query onto URL search params (deleting empty elements). */\nexport function writeFacetParams(p: URLSearchParams, f: FacetFilters): void {\n const set = (k: string, v: unknown) => (isEmpty(v) ? p.delete(k) : p.set(k, JSON.stringify(v)));\n set('facets', f.facets);\n set('block', f.block);\n set('range', f.range);\n set('exists', f.exists);\n set('roles', f.roles);\n set('orderBy', f.orderBy);\n if (f.available == null) p.delete('available'); else p.set('available', String(f.available));\n}\n\n/** Count of active facet conditions (for the trigger badge). */\nexport function facetCount(f: FacetFilters): number {\n return (\n Object.keys(f.facets ?? {}).length +\n (f.block?.length ?? 0) +\n (f.range?.length ?? 0) +\n (f.exists?.length ?? 0) +\n (f.orderBy?.length ?? 0) +\n (f.available != null ? 1 : 0)\n );\n}\n","import type { FacetFilters, FacetRange, FacetOrder } from '../../api/escalations';\n\nconst RANGE_OPS: FacetRange['op'][] = ['<', '<=', '>', '>=', '='];\nconst SORT_COLUMNS = ['priority', 'created_at', 'updated_at', 'status', 'role'];\n\nconst inputCls =\n 'h-7 rounded border border-surface-border bg-surface px-2 text-xs text-text-primary focus:border-accent focus:outline-none';\nconst xBtn = 'text-text-tertiary hover:text-text-primary transition-colors';\n\n/** A facet value is JSONB-containment-sensitive: 0.65 (number) ≠ \"0.65\" (string). */\nfunction coerce(v: string): unknown {\n if (v === 'true') return true;\n if (v === 'false') return false;\n if (v.trim() !== '' && !Number.isNaN(Number(v))) return Number(v);\n return v;\n}\n\ntype KV = { key: string; value: string };\nconst recordRows = (rec?: Record<string, unknown>): KV[] =>\n Object.entries(rec ?? {}).map(([key, value]) => ({ key, value: String(value) }));\nconst blockRows = (arr?: Record<string, unknown>[]): KV[] =>\n (arr ?? []).map((o) => {\n const [key, value] = Object.entries(o)[0] ?? ['', ''];\n return { key, value: String(value) };\n });\n\nfunction Section({ title, hint, children }: { title: string; hint?: string; children: React.ReactNode }) {\n return (\n <div className=\"border-t border-surface-border/50 py-3 first:border-t-0 first:pt-1\">\n <div className=\"mb-1.5 flex items-baseline justify-between\">\n <span className=\"text-[11px] font-medium uppercase tracking-wide text-text-tertiary\">{title}</span>\n {hint && <span className=\"text-[10px] font-mono text-text-tertiary/70\">{hint}</span>}\n </div>\n {children}\n </div>\n );\n}\n\nfunction KeyInput({ value, onChange, placeholder }: {\n value: string; onChange: (v: string) => void; placeholder: string;\n}) {\n return (\n <input\n list=\"lt-facet-keys\" className={`${inputCls} w-40`} placeholder={placeholder}\n value={value} onChange={(e) => onChange(e.target.value)}\n />\n );\n}\n\n/**\n * Faceted query editor — the advanced operations surface (rendered inside the\n * slide-out drawer). Controlled: edits a FacetFilters value. `facetKeys` are the\n * metadata keys that actually exist in the caller's rows (from listFacetKeys), so\n * the UI never offers a non-existent facet.\n */\nexport function FacetedFilterPanel({ value, onChange, facetKeys = [], search = '', onSearchChange }: {\n value: FacetFilters;\n onChange: (next: FacetFilters) => void;\n facetKeys?: string[];\n /** Correlation-id term — exact match on escalation id / workflow id / origin id, composed\n * with the facets in the same SQL query. Not a substring search; for values inside metadata\n * use a facet. */\n search?: string;\n onSearchChange?: (next: string) => void;\n}) {\n const facets = recordRows(value.facets);\n const exclude = blockRows(value.block);\n const ranges = value.range ?? [];\n const exists = value.exists ?? [];\n const sorts = value.orderBy ?? [];\n\n const setFacets = (rows: KV[]) => {\n const rec: Record<string, unknown> = {};\n for (const r of rows) if (r.key) rec[r.key] = coerce(r.value);\n onChange({ ...value, facets: Object.keys(rec).length ? rec : undefined });\n };\n const setBlock = (rows: KV[]) => {\n const arr = rows.filter((r) => r.key).map((r) => ({ [r.key]: coerce(r.value) }));\n onChange({ ...value, block: arr.length ? arr : undefined });\n };\n const setRange = (r: FacetRange[]) => onChange({ ...value, range: r.length ? r : undefined });\n const setExists = (e: string[]) => onChange({ ...value, exists: e.length ? e : undefined });\n const setSorts = (o: FacetOrder[]) => onChange({ ...value, orderBy: o.length ? o : undefined });\n\n return (\n <div className=\"text-xs\">\n {/* Autocomplete sources rendered once (shared by all rows). */}\n <datalist id=\"lt-facet-keys\">\n {facetKeys.map((k) => <option key={k} value={k} />)}\n </datalist>\n <datalist id=\"lt-sort-fields\">\n {SORT_COLUMNS.map((c) => <option key={c} value={c} />)}\n {facetKeys.map((k) => <option key={k} value={`metadata.${k}`} />)}\n </datalist>\n\n {onSearchChange && (\n <Section title=\"Match id\" hint=\"id · workflow · origin\">\n <input\n className={`${inputCls} w-full`}\n placeholder=\"Exact escalation, workflow, or origin id…\"\n value={search}\n onChange={(e) => onSearchChange(e.target.value)}\n />\n </Section>\n )}\n\n <Section title=\"Has facet\" hint=\"metadata @>\">\n {[...facets, { key: '', value: '' }].map((row, i) => (\n <div key={i} className=\"mb-1 flex items-center gap-1\">\n <KeyInput value={row.key} placeholder=\"key\"\n onChange={(k) => { const next = [...facets]; next[i] = { ...row, key: k }; setFacets(next); }} />\n <span className=\"text-text-tertiary\">=</span>\n <input className={`${inputCls} w-40`} placeholder=\"value\" value={row.value}\n onChange={(e) => { const next = [...facets]; next[i] = { ...row, value: e.target.value }; setFacets(next); }} />\n {i < facets.length && (\n <button className={xBtn} onClick={() => setFacets(facets.filter((_, j) => j !== i))}>×</button>\n )}\n </div>\n ))}\n </Section>\n\n <Section title=\"Range\" hint=\"numeric\">\n {[...ranges, { facet: '', op: '<=' as const, value: 0 }].map((r, i) => (\n <div key={i} className=\"mb-1 flex items-center gap-1\">\n <KeyInput value={r.facet} placeholder=\"numeric facet\"\n onChange={(f) => { const next = [...ranges]; next[i] = { ...r, facet: f }; setRange(next.filter((x) => x.facet)); }} />\n <select className={inputCls} value={r.op}\n onChange={(e) => { const next = [...ranges]; next[i] = { ...r, op: e.target.value as FacetRange['op'] }; setRange(next.filter((x) => x.facet)); }}>\n {RANGE_OPS.map((o) => <option key={o} value={o}>{o}</option>)}\n </select>\n <input type=\"number\" className={`${inputCls} w-24`} value={r.value}\n onChange={(e) => { const next = [...ranges]; next[i] = { ...r, value: Number(e.target.value) }; setRange(next.filter((x) => x.facet)); }} />\n {i < ranges.length && (\n <button className={xBtn} onClick={() => setRange(ranges.filter((_, j) => j !== i))}>×</button>\n )}\n </div>\n ))}\n </Section>\n\n <Section title=\"Has key\" hint=\"metadata ? key\">\n <div className=\"flex flex-wrap items-center gap-1\">\n {exists.map((k) => (\n <span key={k} className=\"flex items-center gap-1 rounded bg-accent/15 px-1.5 py-0.5 text-accent\">\n {k}<button className=\"text-accent/70 hover:text-accent\" onClick={() => setExists(exists.filter((x) => x !== k))}>×</button>\n </span>\n ))}\n <KeyInput value=\"\" placeholder=\"+ key\"\n onChange={(k) => { if (k && !exists.includes(k)) setExists([...exists, k]); }} />\n </div>\n </Section>\n\n <Section title=\"Exclude\" hint=\"NOT @>\">\n {[...exclude, { key: '', value: '' }].map((row, i) => (\n <div key={i} className=\"mb-1 flex items-center gap-1\">\n <KeyInput value={row.key} placeholder=\"key\"\n onChange={(k) => { const next = [...exclude]; next[i] = { ...row, key: k }; setBlock(next); }} />\n <span className=\"text-text-tertiary\">=</span>\n <input className={`${inputCls} w-40`} placeholder=\"value\" value={row.value}\n onChange={(e) => { const next = [...exclude]; next[i] = { ...row, value: e.target.value }; setBlock(next); }} />\n {i < exclude.length && (\n <button className={xBtn} onClick={() => setBlock(exclude.filter((_, j) => j !== i))}>×</button>\n )}\n </div>\n ))}\n </Section>\n\n <Section title=\"Sort by\">\n {[...sorts, { field: '', direction: 'asc' as const }].map((s, i) => (\n <div key={i} className=\"mb-1 flex items-center gap-1\">\n <input list=\"lt-sort-fields\" className={`${inputCls} w-44`} placeholder=\"column or metadata.key\"\n value={s.field}\n onChange={(e) => { const next = [...sorts]; next[i] = { ...s, field: e.target.value }; setSorts(next.filter((x) => x.field)); }} />\n <select className={inputCls} value={s.direction ?? 'asc'}\n onChange={(e) => { const next = [...sorts]; next[i] = { ...s, direction: e.target.value as 'asc' | 'desc' }; setSorts(next.filter((x) => x.field)); }}>\n <option value=\"asc\">asc</option><option value=\"desc\">desc</option>\n </select>\n <label className=\"flex items-center gap-1 text-text-tertiary\">\n <input type=\"checkbox\" checked={!!s.numeric}\n onChange={(e) => { const next = [...sorts]; next[i] = { ...s, numeric: e.target.checked }; setSorts(next.filter((x) => x.field)); }} />\n num\n </label>\n {i < sorts.length && (\n <button className={xBtn} onClick={() => setSorts(sorts.filter((_, j) => j !== i))}>×</button>\n )}\n </div>\n ))}\n </Section>\n </div>\n );\n}\n","import { useState } from 'react';\nimport { interpolateHelp, type HelpTokenContext } from '../../lib/x-lt-help';\nimport { ArrowRight } from 'lucide-react';\nimport { MarkdownRenderer } from '../common/display/MarkdownRenderer';\nimport { STATUS_DOT_STYLES } from '../common/display/StatusBadge';\nimport { DateValue } from '../common/display/DateValue';\nimport { useEscalations } from '../../api/escalations';\nimport { isEffectivelyClaimed } from '../../lib/escalation';\nimport type { LTEscalationRecord } from '../../api/types';\n\n/**\n * EscalationListView — the role-authored rich view of an escalation list, driven\n * by a versioned `list_schema` (x-lt-* markup). The list-page analog of the\n * resolve form: the same `{{domain.path}}` token binding (via interpolateHelp)\n * against each row's context, and MarkdownRenderer for rich bodies.\n *\n * Flagship layout `active-history`: the single live (non-terminal) escalation\n * rendered as a card on the left, and a history column on the right that is NOT\n * auto-loaded — a \"Load full history\" link fetches resolved items on demand.\n */\n\ninterface CardDef {\n title?: string;\n subtitle?: string;\n body?: string;\n fields?: { label: string; value: string }[];\n}\n\ninterface HistoryDef {\n row?: { title?: string; subtitle?: string; meta?: string };\n limit?: number;\n status?: string;\n}\n\ninterface ListSchema {\n 'x-lt-layout'?: string;\n 'x-lt-help'?: string;\n 'x-lt-active'?: CardDef;\n 'x-lt-history'?: HistoryDef;\n}\n\n/** Build the token context for one escalation row (payloads are JSON strings). */\nexport function rowContext(e: LTEscalationRecord): HelpTokenContext {\n const parse = (s: string | null | undefined): Record<string, unknown> | null => {\n if (!s) return null;\n try {\n const v = JSON.parse(s);\n return v && typeof v === 'object' ? v : null;\n } catch {\n return null;\n }\n };\n return {\n escalation: e as unknown as Record<string, unknown>,\n metadata: e.metadata ?? null,\n envelope: parse(e.envelope),\n payload: parse(e.escalation_payload),\n resolver: parse(e.resolver_payload),\n };\n}\n\nconst ISO_DATETIME = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}/;\nconst EM_DASH = '—';\n\n/**\n * Render an interpolated field value with a little care: a full ISO datetime\n * becomes a friendly, hoverable date; an empty value a quiet em dash; anything\n * else plain text. Authors bind tokens; we make the common shapes look right.\n */\nfunction FieldValue({ raw }: { raw: string }) {\n if (!raw || raw === EM_DASH) return <span className=\"text-text-quaternary\">{EM_DASH}</span>;\n if (ISO_DATETIME.test(raw)) return <DateValue date={raw} format=\"datetime\" className=\"text-text-primary\" />;\n return <>{raw}</>;\n}\n\nfunction ActiveCard({ esc, card, onOpen }: {\n esc: LTEscalationRecord;\n card: CardDef;\n onOpen?: () => void;\n}) {\n const ctx = rowContext(esc);\n const title = card.title ? interpolateHelp(card.title, ctx) : esc.type;\n const claimable = esc.status === 'pending' && !isEffectivelyClaimed(esc);\n return (\n <div>\n <div className=\"flex items-start justify-between gap-6\">\n <button onClick={onOpen} className=\"text-left group min-w-0\">\n <h3 className=\"text-2xl font-light text-text-primary group-hover:text-accent transition-colors leading-tight\">\n {title}\n </h3>\n {card.subtitle && (\n <p className=\"text-xs text-text-tertiary mt-1.5\">{interpolateHelp(card.subtitle, ctx)}</p>\n )}\n </button>\n\n {/* Explicit way through to the detail page to claim the open item. */}\n {claimable && (\n <button\n onClick={onOpen}\n className=\"inline-flex items-center gap-1.5 px-4 py-2 rounded-md bg-accent text-text-inverse text-xs font-medium hover:bg-accent-hover transition-colors shrink-0\"\n >\n Claim\n <ArrowRight className=\"w-3.5 h-3.5\" />\n </button>\n )}\n </div>\n\n {card.fields && card.fields.length > 0 && (\n <dl className=\"flex flex-wrap gap-x-10 gap-y-4 mt-6\">\n {card.fields.map((f, i) => (\n <div key={i}>\n <dt className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary\">{f.label}</dt>\n <dd className=\"text-xs text-text-primary mt-1\"><FieldValue raw={interpolateHelp(f.value, ctx)} /></dd>\n </div>\n ))}\n </dl>\n )}\n\n {card.body && (\n <div className=\"mt-7 pt-6 border-t border-surface-border/50\">\n <MarkdownRenderer content={interpolateHelp(card.body, ctx)} />\n </div>\n )}\n </div>\n );\n}\n\nfunction HistoryColumn({ role, def, onRowClick }: {\n role: string;\n def: HistoryDef;\n onRowClick?: (row: LTEscalationRecord) => void;\n}) {\n const [show, setShow] = useState(false);\n const query = useEscalations({\n role,\n status: def.status ?? 'resolved',\n sort_by: 'resolved_at',\n order: 'desc',\n limit: def.limit ?? 25,\n enabled: show,\n });\n const rows = query.data?.escalations ?? [];\n const total = query.data?.total ?? 0;\n const rowDef = def.row ?? {};\n\n if (!show) {\n return (\n <button\n onClick={() => setShow(true)}\n className=\"text-xs text-accent hover:underline\"\n data-testid=\"load-history\"\n >\n Load full history →\n </button>\n );\n }\n\n if (query.isLoading) {\n return <p className=\"text-xs text-text-tertiary italic\">Loading history…</p>;\n }\n\n if (rows.length === 0) {\n return <p className=\"text-xs text-text-tertiary italic\">No past revisions.</p>;\n }\n\n return (\n <div>\n <div className=\"divide-y divide-surface-border/40\">\n {rows.map((e) => {\n const ctx = rowContext(e);\n return (\n <button\n key={e.id}\n onClick={() => onRowClick?.(e)}\n className=\"w-full text-left py-2.5 group flex items-center gap-3\"\n >\n {/* Status as a bare outlined dot — colour carries the meaning. */}\n <span\n className={`w-1.5 h-1.5 shrink-0 rounded-full dot-ring ${STATUS_DOT_STYLES[e.status] ?? 'bg-status-pending'}`}\n title={e.status}\n />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block text-xs text-text-primary group-hover:text-accent transition-colors truncate\">\n {rowDef.title ? interpolateHelp(rowDef.title, ctx) : e.type}\n </span>\n {rowDef.subtitle && (\n <span className=\"block text-[10px] text-text-tertiary truncate\">\n {interpolateHelp(rowDef.subtitle, ctx)}\n </span>\n )}\n </span>\n {rowDef.meta\n ? <span className=\"text-[10px] text-text-tertiary shrink-0\">{interpolateHelp(rowDef.meta, ctx)}</span>\n : e.resolved_at && <DateValue date={e.resolved_at} format=\"relative\" className=\"text-[10px] text-text-tertiary shrink-0 whitespace-nowrap\" />}\n </button>\n );\n })}\n </div>\n {total > rows.length && (\n <p className=\"text-[10px] text-text-quaternary mt-3\">Showing {rows.length} of {total}.</p>\n )}\n </div>\n );\n}\n\nfunction SectionLabel({ children }: { children: React.ReactNode }) {\n return (\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-3\">{children}</p>\n );\n}\n\nexport function EscalationListView({ role, listSchema, activeEscalations, onRowClick }: {\n role: string;\n listSchema: ListSchema;\n activeEscalations: LTEscalationRecord[];\n onRowClick?: (row: LTEscalationRecord) => void;\n}) {\n const layout = listSchema['x-lt-layout'];\n const card = listSchema['x-lt-active'] ?? {};\n const active = activeEscalations[0];\n const help = listSchema['x-lt-help'];\n\n const activeBlock = active ? (\n <ActiveCard esc={active} card={card} onOpen={() => onRowClick?.(active)} />\n ) : (\n <p className=\"text-xs text-text-tertiary italic\">No active item right now.</p>\n );\n\n const header = help && active ? (\n <div className=\"mb-8\"><MarkdownRenderer content={interpolateHelp(help, rowContext(active))} /></div>\n ) : help ? (\n <div className=\"mb-8\"><MarkdownRenderer content={help} /></div>\n ) : null;\n\n if (layout === 'active-history') {\n return (\n <div>\n {header}\n <div className=\"grid grid-cols-1 lg:grid-cols-[1.6fr_1fr] gap-12 items-start\">\n <div>\n <SectionLabel>Active</SectionLabel>\n {activeBlock}\n </div>\n <div>\n <SectionLabel>History</SectionLabel>\n <HistoryColumn role={role} def={listSchema['x-lt-history'] ?? {}} onRowClick={onRowClick} />\n </div>\n </div>\n </div>\n );\n }\n\n // \"active\" (or any non-table layout): just the active card.\n return (\n <div>\n {header}\n {activeBlock}\n </div>\n );\n}\n","import { PRIORITY_OPTIONS } from '../../../lib/constants';\nimport { useClaimDurations } from '../../../hooks/useClaimDurations';\nimport { useSettings } from '../../../api/settings';\n\ninterface BulkActionBarProps {\n selectedCount: number;\n onClearSelection: () => void;\n onSetPriority: (priority: 1 | 2 | 3 | 4) => void;\n onClaim: (durationMinutes: number) => void;\n onAssign: () => void;\n onEscalate: (targetRole: string) => void;\n onTriage: () => void;\n onCancel: () => void;\n isPriorityPending: boolean;\n isClaimPending: boolean;\n isAssignPending: boolean;\n isEscalatePending: boolean;\n isTriagePending: boolean;\n isCancelPending: boolean;\n availableRoles: string[];\n}\n\nconst anyPending = (props: BulkActionBarProps) =>\n props.isPriorityPending || props.isClaimPending || props.isAssignPending || props.isEscalatePending || props.isTriagePending || props.isCancelPending;\n\n// One control chrome for the whole bar — white pill-free buttons on the band,\n// hairline border, a barely-there 3px radius (square reads timeless, not dated),\n// definition on hover. Selects share it so the toolbar is one cohesive set.\nconst CTRL =\n 'inline-flex items-center h-7 px-2.5 text-[11px] font-medium text-text-secondary bg-surface border border-surface-border rounded-[4px] hover:border-accent/50 hover:text-text-primary transition-colors disabled:opacity-50 disabled:hover:border-surface-border';\nconst SELECT = `${CTRL} appearance-none cursor-pointer`;\nconst DANGER =\n 'inline-flex items-center h-7 px-2.5 text-[11px] font-medium text-status-error bg-surface border border-status-error/30 rounded-[4px] hover:border-status-error hover:bg-status-error/5 transition-colors disabled:opacity-50';\n\nexport function BulkActionBar(props: BulkActionBarProps) {\n const disabled = anyPending(props);\n const claimDurations = useClaimDurations();\n // Triage is an LLM action. `useSettings().ai.enabled` is the single source of\n // truth — it merges the server /settings flag with the persisted localStorage\n // override (lt_ai_override). Hide the button entirely when AI is off.\n const { data: settings } = useSettings();\n const aiEnabled = settings?.ai?.enabled === true;\n const open = props.selectedCount > 0;\n\n return (\n // Animated reveal — grows and opacity-fades in/out with ease-in-out as the\n // selection changes. Always mounted so it can animate on exit, not just enter.\n <div\n className={`grid transition-all duration-200 ease-in-out ${\n open ? 'grid-rows-[1fr] opacity-100' : 'grid-rows-[0fr] opacity-0 pointer-events-none'\n }`}\n >\n <div className=\"overflow-hidden\">\n {/* Contextual band: neutral fill + a 2px accent left rule anchors it as a\n distinct \"selection mode\" surface without a rounded card. */}\n <div className=\"flex flex-wrap items-center gap-2 py-2.5 pl-3 pr-2 mt-4 mb-3 bg-surface-sunken/60 border-l-2 border-l-accent\">\n <span className=\"text-[11px] font-semibold uppercase tracking-wider text-accent tabular-nums\">\n {props.selectedCount} selected\n </span>\n\n <div className=\"mx-1 h-4 w-px bg-surface-border\" />\n\n {/* Priority */}\n <select\n onChange={(e) => {\n if (!e.target.value) return;\n props.onSetPriority(parseInt(e.target.value) as 1 | 2 | 3 | 4);\n e.target.value = '';\n }}\n disabled={disabled}\n className={SELECT}\n defaultValue=\"\"\n >\n <option value=\"\" disabled>Priority…</option>\n {PRIORITY_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>{opt.label}</option>\n ))}\n </select>\n\n {/* Claim */}\n <select\n onChange={(e) => {\n if (!e.target.value) return;\n props.onClaim(parseInt(e.target.value));\n e.target.value = '';\n }}\n disabled={disabled}\n className={SELECT}\n defaultValue=\"\"\n >\n <option value=\"\" disabled>Claim for…</option>\n {claimDurations.map((opt) => (\n <option key={opt.value} value={opt.value}>{opt.label}</option>\n ))}\n </select>\n\n {/* Assign */}\n <button onClick={props.onAssign} disabled={disabled} className={CTRL}>\n {props.isAssignPending ? 'Assigning…' : 'Assign to…'}\n </button>\n\n {/* Escalate */}\n {props.availableRoles.length > 0 && (\n <select\n onChange={(e) => {\n if (!e.target.value) return;\n props.onEscalate(e.target.value);\n e.target.value = '';\n }}\n disabled={disabled}\n className={SELECT}\n defaultValue=\"\"\n >\n <option value=\"\" disabled>Escalate to…</option>\n {props.availableRoles.map((role) => (\n <option key={role} value={role}>{role}</option>\n ))}\n </select>\n )}\n\n {/* Triage — LLM-powered, shown only when AI is enabled */}\n {aiEnabled && (\n <button onClick={props.onTriage} disabled={disabled} className={CTRL}>\n {props.isTriagePending ? 'Triaging…' : 'Triage'}\n </button>\n )}\n\n {/* Cancel */}\n <button onClick={props.onCancel} disabled={disabled} className={DANGER}>\n {props.isCancelPending ? 'Cancelling…' : 'Cancel'}\n </button>\n\n <div className=\"flex-1\" />\n\n {disabled && (\n <span className=\"text-[11px] text-text-tertiary animate-pulse\">Processing…</span>\n )}\n\n {/* Clear */}\n <button\n onClick={props.onClearSelection}\n className=\"px-1 text-[11px] font-medium text-text-tertiary hover:text-text-primary transition-colors\"\n >\n Clear\n </button>\n </div>\n </div>\n </div>\n );\n}\n","import { useState, useCallback } from 'react';\nimport { Modal } from './Modal';\nimport { CustomDurationPicker } from '../form/CustomDurationPicker';\nimport { useUsers } from '../../../api/users';\nimport { useAuth } from '../../../hooks/useAuth';\nimport { useClaimDurations } from '../../../hooks/useClaimDurations';\nimport { useDebouncedValue } from '../../../hooks/useDebouncedValue';\nimport type { LTUserRecord } from '../../../api/types';\n\ninterface BulkAssignModalProps {\n open: boolean;\n onClose: () => void;\n selectedCount: number;\n /** Distinct roles of the selected escalations; scopes user list for admins */\n selectedRoles: string[];\n onSubmit: (targetUserId: string, durationMinutes: number) => void;\n isPending: boolean;\n}\n\nexport function BulkAssignModal({\n open,\n onClose,\n selectedCount,\n selectedRoles,\n onSubmit,\n isPending,\n}: BulkAssignModalProps) {\n const { isSuperAdmin } = useAuth();\n const claimDurations = useClaimDurations();\n const [step, setStep] = useState<'user' | 'duration'>('user');\n const [selectedUser, setSelectedUser] = useState<LTUserRecord | null>(null);\n const [search, setSearch] = useState('');\n const [duration, setDuration] = useState('30');\n const [customMinutes, setCustomMinutes] = useState(0);\n const onCustomChange = useCallback((m: number) => setCustomMinutes(m), []);\n\n // Admins with a single role: scope to that role. Otherwise show all active users.\n const roleFilter =\n !isSuperAdmin && selectedRoles.length === 1 ? selectedRoles[0] : undefined;\n\n // Search is resolved server-side (ILIKE on name/email/external_id) so it matches\n // every user, not just a fetched slice — no client-side filtering over a cap.\n const debouncedSearch = useDebouncedValue(search, 250);\n const { data: usersData, isLoading: usersLoading } = useUsers({\n role: roleFilter,\n status: 'active',\n search: debouncedSearch.trim() || undefined,\n limit: 200,\n });\n\n const users = usersData?.users ?? [];\n\n const handleClose = () => {\n setStep('user');\n setSelectedUser(null);\n setSearch('');\n setDuration('30');\n setCustomMinutes(0);\n onClose();\n };\n\n const handleSelectUser = (user: LTUserRecord) => {\n setSelectedUser(user);\n setStep('duration');\n };\n\n const handleBack = () => {\n setStep('user');\n };\n\n const handleSubmit = () => {\n if (!selectedUser) return;\n const minutes = duration === 'custom' ? customMinutes : parseInt(duration);\n if (!minutes || minutes <= 0) return;\n onSubmit(selectedUser.id, minutes);\n };\n\n return (\n <Modal open={open} onClose={handleClose} title=\"Assign Escalations\">\n <div className=\"space-y-4\">\n {step === 'user' && (\n <>\n <p className=\"text-sm text-text-secondary\">\n Select a user to assign{' '}\n <span className=\"font-medium text-text-primary\">\n {selectedCount}\n </span>{' '}\n escalation(s) to:\n </p>\n\n <input\n type=\"text\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"Search by name or email...\"\n className=\"input text-xs w-full\"\n autoFocus\n />\n\n <div className=\"max-h-60 overflow-y-auto border border-surface-border rounded-lg divide-y divide-surface-border\">\n {usersLoading && (\n <p className=\"text-xs text-text-tertiary p-3\">\n Loading users...\n </p>\n )}\n {!usersLoading && users.length === 0 && (\n <p className=\"text-xs text-text-tertiary p-3\">\n No users found\n </p>\n )}\n {users.map((user) => (\n <button\n key={user.id}\n onClick={() => handleSelectUser(user)}\n className=\"w-full text-left px-3 py-2 hover:bg-surface-hover transition-colors\"\n >\n <p className=\"text-xs font-medium text-text-primary\">\n {user.display_name || user.external_id}\n </p>\n {user.email && (\n <p className=\"text-[10px] text-text-tertiary\">\n {user.email}\n </p>\n )}\n </button>\n ))}\n </div>\n\n <div className=\"flex justify-end pt-2\">\n <button onClick={handleClose} className=\"btn-secondary text-xs\">\n Cancel\n </button>\n </div>\n </>\n )}\n\n {step === 'duration' && selectedUser && (\n <>\n <p className=\"text-sm text-text-secondary\">\n Assign to{' '}\n <span className=\"font-medium text-text-primary\">\n {selectedUser.display_name || selectedUser.external_id}\n </span>{' '}\n for:\n </p>\n\n <select\n value={duration}\n onChange={(e) => { setDuration(e.target.value); setCustomMinutes(0); }}\n className=\"select w-full text-sm\"\n >\n {claimDurations.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n <option value=\"custom\">Other...</option>\n </select>\n {duration === 'custom' && (\n <CustomDurationPicker onChange={onCustomChange} autoFocus />\n )}\n\n <div className=\"flex justify-end gap-3 pt-2\">\n <button onClick={handleBack} className=\"btn-secondary text-xs\">\n Back\n </button>\n <button\n onClick={handleSubmit}\n disabled={isPending}\n className=\"btn-primary text-xs\"\n >\n {isPending ? 'Assigning...' : 'Assign'}\n </button>\n </div>\n </>\n )}\n </div>\n </Modal>\n );\n}\n","import { useState } from 'react';\nimport { Modal } from './Modal';\n\ninterface BulkTriageModalProps {\n open: boolean;\n onClose: () => void;\n selectedCount: number;\n onSubmit: (hint?: string) => void;\n isPending: boolean;\n}\n\nexport function BulkTriageModal({\n open,\n onClose,\n selectedCount,\n onSubmit,\n isPending,\n}: BulkTriageModalProps) {\n const [hint, setHint] = useState('');\n\n const handleSubmit = () => {\n onSubmit(hint || undefined);\n };\n\n return (\n <Modal open={open} onClose={onClose} title=\"Submit for AI Triage\">\n <div className=\"space-y-4\">\n <p className=\"text-sm text-text-secondary\">\n Submit <span className=\"font-medium text-text-primary\">{selectedCount}</span> escalation(s)\n for AI triage? The triage orchestrator will take over resolution.\n </p>\n\n <div>\n <label className=\"text-xs font-medium text-text-secondary block mb-1\">\n Triage hint <span className=\"text-text-tertiary\">(optional)</span>\n </label>\n <input\n type=\"text\"\n value={hint}\n onChange={(e) => setHint(e.target.value)}\n placeholder=\"e.g., image_orientation\"\n className=\"input text-xs font-mono w-full\"\n />\n <p className=\"text-[10px] text-text-tertiary mt-1\">\n Guides the triage workflow on what remediation to apply\n </p>\n </div>\n\n <div className=\"flex justify-end gap-3 pt-2\">\n <button onClick={onClose} className=\"btn-secondary text-xs\">\n Cancel\n </button>\n <button\n onClick={handleSubmit}\n disabled={isPending}\n className=\"btn-primary text-xs\"\n >\n {isPending ? 'Submitting...' : 'Submit for Triage'}\n </button>\n </div>\n </div>\n </Modal>\n );\n}\n","import type { UseMutationResult } from '@tanstack/react-query';\n\n/**\n * Create a bulk-action handler that calls a mutation and clears selection on success.\n */\nfunction bulkHandler<TData, TVariables>(\n mutation: UseMutationResult<TData, Error, TVariables>,\n clearSelection: () => void,\n afterSuccess?: () => void,\n) {\n return (variables: TVariables) => {\n mutation.mutate(variables, {\n onSuccess: () => {\n clearSelection();\n afterSuccess?.();\n },\n });\n };\n}\n\nexport function createBulkHandlers(deps: {\n selectedIds: Set<string>;\n clearSelection: () => void;\n setPriority: UseMutationResult<{ updated: number }, Error, { ids: string[]; priority: 1 | 2 | 3 | 4 }>;\n bulkClaim: UseMutationResult<{ claimed: number; skipped: number }, Error, { ids: string[]; durationMinutes: number }>;\n bulkEscalate: UseMutationResult<{ updated: number }, Error, { ids: string[]; targetRole: string }>;\n bulkTriage: UseMutationResult<{ triaged: number }, Error, { ids: string[]; hint?: string }>;\n bulkAssign: UseMutationResult<{ assigned: number; skipped: number }, Error, { ids: string[]; targetUserId: string; durationMinutes: number }>;\n bulkCancel: UseMutationResult<{ cancelled: number; skipped: number }, Error, { ids: string[] }>;\n closeTriageModal: () => void;\n closeAssignModal: () => void;\n closeCancelModal: () => void;\n}) {\n const ids = () => [...deps.selectedIds];\n\n const handleSetPriority = (priority: 1 | 2 | 3 | 4) => {\n bulkHandler(\n deps.setPriority,\n deps.clearSelection,\n )({ ids: ids(), priority });\n };\n\n const handleBulkClaim = (durationMinutes: number) => {\n bulkHandler(\n deps.bulkClaim,\n deps.clearSelection,\n )({ ids: ids(), durationMinutes });\n };\n\n const handleBulkEscalate = (targetRole: string) => {\n bulkHandler(\n deps.bulkEscalate,\n deps.clearSelection,\n )({ ids: ids(), targetRole });\n };\n\n const handleBulkTriage = (hint?: string) => {\n bulkHandler(\n deps.bulkTriage,\n deps.clearSelection,\n deps.closeTriageModal,\n )({ ids: ids(), hint });\n };\n\n const handleBulkAssign = (targetUserId: string, durationMinutes: number) => {\n bulkHandler(\n deps.bulkAssign,\n deps.clearSelection,\n deps.closeAssignModal,\n )({ ids: ids(), targetUserId, durationMinutes });\n };\n\n const handleBulkCancel = () => {\n bulkHandler(\n deps.bulkCancel,\n deps.clearSelection,\n deps.closeCancelModal,\n )({ ids: ids() });\n };\n\n return { handleSetPriority, handleBulkClaim, handleBulkEscalate, handleBulkTriage, handleBulkAssign, handleBulkCancel };\n}\n","import { Modal } from '../../components/common/modal/Modal';\nimport { CustomDurationPicker } from '../../components/common/form/CustomDurationPicker';\nimport type { LTEscalationRecord } from '../../api/types';\n\ninterface ClaimModalProps {\n claimTarget: LTEscalationRecord | null;\n onClose: () => void;\n claimDuration: string;\n onDurationChange: (value: string) => void;\n claimDurations: Array<{ value: string; label: string }>;\n customClaimMinutes: number;\n onCustomClaimChange: (minutes: number) => void;\n onClaim: () => void;\n isPending: boolean;\n}\n\nexport function ClaimModal({\n claimTarget,\n onClose,\n claimDuration,\n onDurationChange,\n claimDurations,\n onCustomClaimChange,\n onClaim,\n isPending,\n}: ClaimModalProps) {\n return (\n <Modal\n open={!!claimTarget}\n onClose={onClose}\n title=\"Claim Escalation\"\n >\n <div className=\"space-y-4\">\n <p className=\"text-sm text-text-secondary\">\n Claim <span className=\"font-medium text-text-primary\">{claimTarget?.type}</span> for:\n </p>\n <select\n value={claimDuration}\n onChange={(e) => { onDurationChange(e.target.value); }}\n className=\"select w-full text-sm\"\n >\n {claimDurations.map((opt) => (\n <option key={opt.value} value={opt.value}>{opt.label}</option>\n ))}\n <option value=\"custom\">Other...</option>\n </select>\n {claimDuration === 'custom' && (\n <CustomDurationPicker onChange={onCustomClaimChange} autoFocus />\n )}\n <div className=\"flex justify-end gap-3 pt-2\">\n <button onClick={onClose} className=\"btn-secondary text-xs\">\n Cancel\n </button>\n <button\n onClick={onClaim}\n className=\"btn-primary text-xs\"\n disabled={isPending}\n >\n {isPending ? 'Claiming...' : 'Claim'}\n </button>\n </div>\n </div>\n </Modal>\n );\n}\n","import { useState, useEffect, useMemo, useCallback } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useNavigate, useSearchParams } from 'react-router-dom';\nimport { parseFacetParams, writeFacetParams, facetCount } from '../../lib/facet-url';\nimport { useAccess } from '../../hooks/useAccess';\nimport { useEscalationListEvents } from '../../hooks/useEventHooks';\nimport {\n useEscalations,\n useAvailableEscalations,\n useEscalationTypes,\n useFacetKeys,\n useClaimEscalation,\n useSetEscalationPriority,\n useBulkClaimEscalations,\n useBulkAssignEscalations,\n useBulkEscalateToRole,\n useBulkTriageEscalations,\n useBulkCancelEscalations,\n type FacetFilters,\n} from '../../api/escalations';\nimport { FacetedFilterPanel } from './FacetedFilterPanel';\nimport { ConfirmCancelModal } from '../../components/common/modal/ConfirmCancelModal';\nimport { useRoles, useRoleListSchema } from '../../api/roles';\nimport { EscalationListView } from '../../components/escalation/EscalationListView';\nimport { useFilterParams } from '../../hooks/useFilterParams';\nimport { useDebouncedValue } from '../../hooks/useDebouncedValue';\nimport { buildApiPath } from '../../lib/api-path';\nimport { DataTable, type Column } from '../../components/common/data/DataTable';\nimport { StickyPagination } from '../../components/common/data/StickyPagination';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { BulkActionBar } from '../../components/common/modal/BulkActionBar';\nimport { BulkAssignModal } from '../../components/common/modal/BulkAssignModal';\nimport { BulkTriageModal } from '../../components/common/modal/BulkTriageModal';\nimport { useClaimDurations } from '../../hooks/useClaimDurations';\nimport { Lock, SlidersHorizontal, X, LayoutList, Table } from 'lucide-react';\nimport { ESCALATION_COLUMNS, EscalationFilterBar } from './escalation-columns';\nimport { RowAction, RowActionGroup } from '../../components/common/layout/RowActions';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\nimport { createBulkHandlers } from './helpers';\nimport { ClaimModal } from './ClaimModal';\nimport type { LTEscalationRecord } from '../../api/types';\n\nexport function AvailableEscalationsPage() {\n useEscalationListEvents();\n const navigate = useNavigate();\n const { filters, setFilter, pagination, sort, setSort } = useFilterParams({\n filters: { role: '', type: '', priority: '', status: 'available', search: '' },\n });\n // Debounce so server-side search fires once the user pauses, not per keystroke.\n const debouncedSearch = useDebouncedValue(filters.search, 300);\n const claimDurations = useClaimDurations();\n const [claimTarget, setClaimTarget] = useState<LTEscalationRecord | null>(null);\n const [claimDuration, setClaimDuration] = useState('30');\n const [customClaimMinutes, setCustomClaimMinutes] = useState(0);\n const onCustomClaimChange = useCallback((m: number) => setCustomClaimMinutes(m), []);\n const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());\n // Faceted query — DEEP-LINKED in the URL (a shared link reproduces the exact query).\n // The drawer is the editor surface; fetched keys feed the autocomplete.\n const [facetDrawerOpen, setFacetDrawerOpen] = useState(false);\n const [searchParams, setSearchParams] = useSearchParams();\n const facetFilters = useMemo<FacetFilters>(() => parseFacetParams(searchParams), [searchParams]);\n const setFacetFilters = useCallback((next: FacetFilters) => {\n setSearchParams((prev) => {\n const p = new URLSearchParams(prev);\n writeFacetParams(p, next);\n p.delete('page');\n return p;\n }, { replace: true });\n }, [setSearchParams]);\n const { data: facetKeysData } = useFacetKeys(facetDrawerOpen);\n // The free-text term now lives in the drawer alongside the facets, so it counts\n // toward the active-query badge and is cleared by the drawer's Clear.\n const activeFacetCount = facetCount(facetFilters) + (filters.search ? 1 : 0);\n const [triageModalOpen, setTriageModalOpen] = useState(false);\n const [assignModalOpen, setAssignModalOpen] = useState(false);\n const [cancelModalOpen, setCancelModalOpen] = useState(false);\n\n const claim = useClaimEscalation();\n const setPriority = useSetEscalationPriority();\n const bulkClaim = useBulkClaimEscalations();\n const bulkAssign = useBulkAssignEscalations();\n const bulkEscalate = useBulkEscalateToRole();\n const bulkTriage = useBulkTriageEscalations();\n const bulkCancel = useBulkCancelEscalations();\n const { data: rolesData } = useRoles();\n const { data: typesData } = useEscalationTypes();\n\n // Clear selections on filter/page changes\n useEffect(() => {\n setSelectedIds(new Set());\n }, [filters.role, filters.type, filters.priority, filters.status, debouncedSearch, pagination.page, pagination.pageSize]);\n\n const statusFilter = filters.status || '';\n const isAvailable = statusFilter === 'available';\n const isClaimed = statusFilter === 'claimed';\n // `all` and `available` both send no status filter. `available` additionally routes\n // through the available-only query (pending + unclaimed); `all` spans every status so\n // a metadata facet search returns an order's escalations regardless of where they are.\n const apiStatus = isClaimed ? 'pending'\n : statusFilter === 'resolved' ? 'resolved'\n : statusFilter === 'cancelled' ? 'cancelled'\n : statusFilter === 'expired' ? 'expired'\n : isAvailable ? undefined\n : undefined;\n\n const sharedFilters = {\n role: filters.role || undefined,\n type: filters.type || undefined,\n priority: filters.priority ? parseInt(filters.priority) : undefined,\n limit: pagination.pageSize,\n offset: pagination.offset,\n sort_by: sort.sort_by || 'created_at',\n order: sort.order || 'desc',\n search: debouncedSearch || undefined,\n // Faceted metadata query (composes with role-scope + the basic filters in SQL).\n ...facetFilters,\n };\n\n const availableQuery = useAvailableEscalations({\n ...sharedFilters,\n enabled: isAvailable,\n });\n\n const escalationsQuery = useEscalations({\n status: apiStatus,\n claimed: isClaimed || undefined,\n ...sharedFilters,\n enabled: !isAvailable,\n });\n\n const activeQuery = isAvailable ? availableQuery : escalationsQuery;\n const { data, isLoading, error: queryError, refetch, isFetching } = activeQuery;\n\n // Copy-URL/curl path built from the SAME params the active query sends, so the\n // generated command always reproduces the real request (filters + search + sort).\n const apiPath = buildApiPath(`/escalations${isAvailable ? '/available' : ''}`, {\n status: apiStatus,\n claimed: isClaimed || undefined,\n role: filters.role || undefined,\n type: filters.type || undefined,\n priority: filters.priority || undefined,\n search: debouncedSearch || undefined,\n sort_by: sort.sort_by || 'created_at',\n order: sort.order || 'desc',\n limit: pagination.pageSize,\n offset: pagination.offset,\n // Faceted query — JSON-encoded so the copy-URL/curl reproduces the exact query.\n facets: facetFilters.facets && Object.keys(facetFilters.facets).length ? JSON.stringify(facetFilters.facets) : undefined,\n block: facetFilters.block?.length ? JSON.stringify(facetFilters.block) : undefined,\n range: facetFilters.range?.length ? JSON.stringify(facetFilters.range) : undefined,\n exists: facetFilters.exists?.length ? JSON.stringify(facetFilters.exists) : undefined,\n roles: facetFilters.roles?.length ? JSON.stringify(facetFilters.roles) : undefined,\n orderBy: facetFilters.orderBy?.length ? JSON.stringify(facetFilters.orderBy) : undefined,\n available: facetFilters.available != null ? String(facetFilters.available) : undefined,\n });\n\n // Search is server-side (full result set), so results and total come straight\n // from the query — no client-side filtering of the current page.\n const escalations = data?.escalations ?? [];\n const total = data?.total ?? 0;\n const { canBulk: canBulkManage } = useAccess();\n\n // Role-owned rich view: only when the list targets exactly ONE role (the basic\n // filter, or a single faceted role) and that role owns a list_schema. Absent\n // or multi-role → the engineer table, unchanged. `forceTable` lets the user\n // flip back to the columns.\n const singleRole = filters.role\n || (facetFilters.roles?.length === 1 ? facetFilters.roles[0] : null);\n const [forceTable, setForceTable] = useState(false);\n const listSchemaQuery = useRoleListSchema(singleRole ?? '', undefined, !!singleRole);\n const listSchema = (listSchemaQuery.data?.list_schema ?? null) as Record<string, any> | null;\n // A rich view is available for this list; the toggle flips to the table.\n const hasRichView = !!singleRole && !!listSchema\n && !!listSchema['x-lt-layout'] && listSchema['x-lt-layout'] !== 'table';\n const useRichView = hasRichView && !forceTable;\n\n const selectedRoles = useMemo(() => {\n const roles = new Set<string>();\n for (const esc of escalations) {\n if (selectedIds.has(esc.id)) roles.add(esc.role);\n }\n return [...roles];\n }, [escalations, selectedIds]);\n\n const clearSelection = useCallback(() => setSelectedIds(new Set()), []);\n\n const handleClaim = () => {\n if (!claimTarget) return;\n const minutes = claimDuration === 'custom' ? customClaimMinutes : parseInt(claimDuration);\n if (!minutes || minutes <= 0) return;\n claim.mutate(\n { id: claimTarget.id, durationMinutes: minutes },\n {\n onSuccess: () => {\n setClaimTarget(null);\n navigate(`/escalations/detail/${claimTarget.id}`);\n },\n },\n );\n };\n\n const {\n handleSetPriority,\n handleBulkClaim,\n handleBulkEscalate,\n handleBulkTriage,\n handleBulkAssign,\n handleBulkCancel,\n } = createBulkHandlers({\n selectedIds,\n clearSelection,\n setPriority,\n bulkClaim,\n bulkEscalate,\n bulkTriage,\n bulkAssign,\n bulkCancel,\n closeTriageModal: () => setTriageModalOpen(false),\n closeAssignModal: () => setAssignModalOpen(false),\n closeCancelModal: () => setCancelModalOpen(false),\n });\n\n const toggleSelect = (id: string) => {\n const next = new Set(selectedIds);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n setSelectedIds(next);\n };\n\n const toggleAll = () => {\n if (selectedIds.size === escalations.length) {\n setSelectedIds(new Set());\n } else {\n setSelectedIds(new Set(escalations.map((e) => e.id)));\n }\n };\n\n const columns: Column<LTEscalationRecord>[] = [\n canBulkManage ? {\n key: 'select',\n label: (\n <input\n type=\"checkbox\"\n checked={escalations.length > 0 && selectedIds.size === escalations.length}\n onChange={toggleAll}\n className=\"rounded\"\n />\n ) as any,\n render: (row: LTEscalationRecord) => (\n <input\n type=\"checkbox\"\n checked={selectedIds.has(row.id)}\n onChange={(e) => {\n e.stopPropagation();\n toggleSelect(row.id);\n }}\n onClick={(e) => e.stopPropagation()}\n className=\"rounded\"\n />\n ),\n className: 'w-10',\n } : {\n key: 'spacer',\n label: '',\n render: () => null,\n className: 'w-10',\n },\n ...ESCALATION_COLUMNS,\n {\n key: 'actions',\n label: '',\n render: (row) => (\n <RowActionGroup>\n <RowAction\n icon={Lock}\n title=\"Claim escalation\"\n onClick={() => setClaimTarget(row)}\n colorClass=\"text-accent/75 hover:text-accent\"\n size=\"sm\"\n />\n </RowActionGroup>\n ),\n className: 'w-10 text-right',\n },\n ];\n\n return (\n <div>\n <PageHeader title=\"All Escalations\" docsHash=\"#docs:dashboard.md:all-escalations\" />\n\n <EscalationFilterBar\n filters={filters}\n setFilter={setFilter}\n roles={rolesData?.roles ?? []}\n types={typesData?.types ?? []}\n showStatus\n showSearch={false}\n actions={\n <>\n <ListToolbar\n onRefresh={() => refetch()}\n isFetching={isFetching}\n apiPath={apiPath}\n />\n {hasRichView && (\n <button\n onClick={() => setForceTable((v) => !v)}\n className=\"ml-2 inline-flex h-7 w-7 items-center justify-center rounded text-text-tertiary hover:bg-surface-hover hover:text-text-primary transition-colors\"\n title={forceTable ? 'Rich view' : 'Table view'}\n >\n {forceTable\n ? <LayoutList className=\"w-4 h-4\" />\n : <Table className=\"w-4 h-4\" />}\n </button>\n )}\n <button\n onClick={() => setFacetDrawerOpen((v) => !v)}\n className=\"relative ml-2 inline-flex h-7 w-7 items-center justify-center rounded text-text-tertiary hover:bg-surface-hover hover:text-text-primary transition-colors\"\n title=\"Faceted query\"\n >\n <SlidersHorizontal className=\"w-4 h-4\" />\n {activeFacetCount > 0 && (\n <span className=\"absolute -right-1 -top-1 flex h-3.5 min-w-[14px] items-center justify-center rounded-full bg-accent px-0.5 text-[9px] font-medium text-white\">\n {activeFacetCount}\n </span>\n )}\n </button>\n </>\n }\n />\n\n {/* Faceted query — slide-out drawer (deep-linked state), portaled so fixed positioning\n works. Always mounted so it slides open/closed with a subtle transition. */}\n {createPortal(\n <div\n className={`fixed right-0 bottom-0 w-[420px] z-40 border-l border-surface-border bg-surface overflow-y-auto shadow-lg transition-transform duration-200 ease-out ${facetDrawerOpen ? 'translate-x-0' : 'pointer-events-none translate-x-full'}`}\n style={{ top: '3.5rem' }}\n aria-hidden={!facetDrawerOpen}\n >\n <div className=\"sticky top-0 z-10 flex items-center justify-between px-4 py-3 bg-surface border-b border-surface-border/50\">\n <span className=\"text-xs font-medium text-text-primary\">Faceted query</span>\n <div className=\"flex items-center gap-2\">\n {activeFacetCount > 0 && (\n <button\n onClick={() => { setFacetFilters({}); setFilter('search', ''); }}\n className=\"text-[11px] text-text-tertiary hover:text-text-primary transition-colors\"\n >\n Clear\n </button>\n )}\n <button\n onClick={() => setFacetDrawerOpen(false)}\n className=\"p-1 rounded hover:bg-surface-hover text-text-tertiary hover:text-text-primary transition-colors\"\n title=\"Close\"\n >\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n <div className=\"px-4 py-2\">\n <p className=\"mb-2 text-[11px] leading-snug text-text-tertiary\">\n Precise metadata facets plus exact correlation-id lookup — they compose in one\n SQL query. Facet keys are the ones that actually exist in your visible escalations.\n Set status to <span className=\"font-medium\">All</span> to find an order across every\n status; the whole query is shareable via the URL.\n </p>\n <FacetedFilterPanel\n value={facetFilters}\n onChange={setFacetFilters}\n facetKeys={facetKeysData?.keys ?? []}\n search={filters.search ?? ''}\n onSearchChange={(v) => setFilter('search', v)}\n />\n </div>\n </div>,\n document.body,\n )}\n\n {/* Always mounted so the bar can animate in AND out as the selection changes. */}\n <BulkActionBar\n selectedCount={selectedIds.size}\n onClearSelection={() => setSelectedIds(new Set())}\n onSetPriority={handleSetPriority}\n onClaim={handleBulkClaim}\n onAssign={() => setAssignModalOpen(true)}\n onEscalate={handleBulkEscalate}\n onTriage={() => setTriageModalOpen(true)}\n onCancel={() => setCancelModalOpen(true)}\n isPriorityPending={setPriority.isPending}\n isClaimPending={bulkClaim.isPending}\n isAssignPending={bulkAssign.isPending}\n isEscalatePending={bulkEscalate.isPending}\n isTriagePending={bulkTriage.isPending}\n isCancelPending={bulkCancel.isPending}\n availableRoles={rolesData?.roles ?? []}\n />\n\n {queryError && (\n <div className=\"mb-4 px-4 py-3 rounded-md bg-status-error/10 border border-status-error/20 text-xs text-status-error\">\n {(queryError as Error).message === 'Session expired'\n ? 'Your session has expired. Please log in again.'\n : `Failed to load escalations: ${(queryError as Error).message}`}\n </div>\n )}\n\n {useRichView ? (\n <EscalationListView\n role={singleRole!}\n listSchema={listSchema!}\n activeEscalations={escalations}\n onRowClick={(row) => navigate(`/escalations/detail/${row.id}`, { state: { from: '/escalations/available' } })}\n />\n ) : (\n <>\n <DataTable\n columns={columns}\n data={escalations}\n keyFn={(row) => row.id}\n onRowClick={(row) => navigate(`/escalations/detail/${row.id}`, { state: { from: '/escalations/available' } })}\n isLoading={isLoading}\n emptyMessage={queryError ? 'Unable to load data' : 'No escalations'}\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 </>\n )}\n\n <ClaimModal\n claimTarget={claimTarget}\n onClose={() => setClaimTarget(null)}\n claimDuration={claimDuration}\n onDurationChange={(v) => { setClaimDuration(v); setCustomClaimMinutes(0); }}\n claimDurations={claimDurations}\n customClaimMinutes={customClaimMinutes}\n onCustomClaimChange={onCustomClaimChange}\n onClaim={handleClaim}\n isPending={claim.isPending}\n />\n\n <BulkTriageModal\n open={triageModalOpen}\n onClose={() => setTriageModalOpen(false)}\n selectedCount={selectedIds.size}\n onSubmit={handleBulkTriage}\n isPending={bulkTriage.isPending}\n />\n\n <BulkAssignModal\n open={assignModalOpen}\n onClose={() => setAssignModalOpen(false)}\n selectedCount={selectedIds.size}\n selectedRoles={selectedRoles}\n onSubmit={handleBulkAssign}\n isPending={bulkAssign.isPending}\n />\n\n <ConfirmCancelModal\n open={cancelModalOpen}\n onClose={() => setCancelModalOpen(false)}\n onConfirm={handleBulkCancel}\n selectedCount={selectedIds.size}\n isPending={bulkCancel.isPending}\n error={bulkCancel.error as Error | null}\n />\n </div>\n );\n}\n"],"names":["parse","v","isEmpty","parseFacetParams","sp","f","facets","block","range","exists","roles","orderBy","writeFacetParams","p","set","k","facetCount","_a","_b","_c","_d","RANGE_OPS","SORT_COLUMNS","inputCls","xBtn","coerce","recordRows","rec","key","value","blockRows","arr","o","Section","title","hint","children","jsxs","jsx","KeyInput","onChange","placeholder","e","FacetedFilterPanel","facetKeys","search","onSearchChange","exclude","ranges","sorts","setFacets","rows","setBlock","setRange","r","setExists","setSorts","c","row","i","next","_","j","x","s","rowContext","ISO_DATETIME","EM_DASH","FieldValue","raw","DateValue","ActiveCard","esc","card","onOpen","ctx","interpolateHelp","claimable","isEffectivelyClaimed","ArrowRight","MarkdownRenderer","HistoryColumn","role","def","onRowClick","show","setShow","useState","query","useEscalations","total","rowDef","STATUS_DOT_STYLES","SectionLabel","EscalationListView","listSchema","activeEscalations","layout","active","help","activeBlock","header","anyPending","props","CTRL","SELECT","DANGER","BulkActionBar","disabled","claimDurations","useClaimDurations","settings","useSettings","aiEnabled","open","PRIORITY_OPTIONS","opt","BulkAssignModal","onClose","selectedCount","selectedRoles","onSubmit","isPending","isSuperAdmin","useAuth","step","setStep","selectedUser","setSelectedUser","setSearch","duration","setDuration","customMinutes","setCustomMinutes","onCustomChange","useCallback","m","roleFilter","debouncedSearch","useDebouncedValue","usersData","usersLoading","useUsers","users","handleClose","handleSelectUser","user","handleBack","handleSubmit","minutes","Modal","Fragment","CustomDurationPicker","BulkTriageModal","setHint","bulkHandler","mutation","clearSelection","afterSuccess","variables","createBulkHandlers","deps","ids","priority","durationMinutes","targetRole","targetUserId","ClaimModal","claimTarget","claimDuration","onDurationChange","onCustomClaimChange","onClaim","AvailableEscalationsPage","useEscalationListEvents","navigate","useNavigate","filters","setFilter","pagination","sort","setSort","useFilterParams","setClaimTarget","setClaimDuration","customClaimMinutes","setCustomClaimMinutes","selectedIds","setSelectedIds","facetDrawerOpen","setFacetDrawerOpen","searchParams","setSearchParams","useSearchParams","facetFilters","useMemo","setFacetFilters","prev","facetKeysData","useFacetKeys","activeFacetCount","triageModalOpen","setTriageModalOpen","assignModalOpen","setAssignModalOpen","cancelModalOpen","setCancelModalOpen","claim","useClaimEscalation","setPriority","useSetEscalationPriority","bulkClaim","useBulkClaimEscalations","bulkAssign","useBulkAssignEscalations","bulkEscalate","useBulkEscalateToRole","bulkTriage","useBulkTriageEscalations","bulkCancel","useBulkCancelEscalations","rolesData","useRoles","typesData","useEscalationTypes","useEffect","statusFilter","isAvailable","isClaimed","apiStatus","sharedFilters","availableQuery","useAvailableEscalations","escalationsQuery","activeQuery","data","isLoading","queryError","refetch","isFetching","apiPath","buildApiPath","_e","escalations","canBulkManage","useAccess","singleRole","_f","forceTable","setForceTable","_g","useRoleListSchema","hasRichView","useRichView","handleClaim","handleSetPriority","handleBulkClaim","handleBulkEscalate","handleBulkTriage","handleBulkAssign","handleBulkCancel","toggleSelect","id","toggleAll","columns","ESCALATION_COLUMNS","RowActionGroup","RowAction","Lock","PageHeader","EscalationFilterBar","ListToolbar","LayoutList","Table","SlidersHorizontal","createPortal","X","DataTable","StickyPagination","ConfirmCancelModal"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as l,j as e}from"./vendor-query-B2UbickB.js";import{Q as g,R as N,T as p,L as f,O as C}from"./index-C9moIiIq.js";import{P as k}from"./PageHeader-sGNTmSXX.js";import{T as A}from"./TimeAgo-ChwJ4fjZ.js";import{C as w}from"./ConfirmDeleteModal-D9_1b4MW.js";import{l as P,i as T,au as O,p as S}from"./vendor-icons-BXhWQC7l.js";import"./vendor-react-CXumBFUA.js";import"./Modal-CSrxpXeM.js";const o={anthropic:{name:"Anthropic",helpText:'Run "claude setup-token" for an OAuth token, or use an API key from console.anthropic.com.',placeholder:"sk-ant-oat01-... or sk-ant-api03-..."},openai:{name:"OpenAI",helpText:"Create an API key at platform.openai.com/api-keys.",placeholder:"sk-..."},google:{name:"Google",helpText:"Connect your Google account for Gmail, Calendar, and Drive access.",placeholder:"",oauth:!0}};function U(){var d,x;const{data:r,isLoading:m}=g(),n=N(),[a,i]=l.useState(null),[h,u]=l.useState(!1),[s,j]=l.useState("anthropic"),c=(r==null?void 0:r.connections)??[],v=()=>{a&&n.mutate({provider:a.provider,label:a.label},{onSuccess:()=>i(null)})},b=t=>`${f}/api/auth/oauth/connect/${t}?token=${encodeURIComponent(C()||"")}&returnTo=/credentials`;return e.jsxs("div",{children:[e.jsx(k,{title:"Credentials",docsHash:"#docs:dashboard.md:credentials",actions:e.jsxs("button",{onClick:()=>u(t=>!t),className:"btn-primary text-xs inline-flex items-center gap-1.5",children:[e.jsx(P,{className:"w-3.5 h-3.5"}),"Add Credential"]})}),e.jsx("p",{className:"text-sm text-text-secondary mb-6",children:"Manage credentials used by tools when invoked on your behalf. Each credential is encrypted at rest and resolved automatically during tool execution."}),h&&e.jsxs("div",{className:"mb-6 pb-5 border-b border-surface-border/60 space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("label",{className:"text-xs text-text-secondary font-medium",children:"Provider"}),e.jsxs("div",{className:"relative",children:[e.jsx("select",{value:s,onChange:t=>j(t.target.value),className:"input text-xs pr-7 appearance-none",children:Object.entries(o).map(([t,y])=>e.jsx("option",{value:t,children:y.name},t))}),e.jsx(T,{className:"absolute right-2 top-1/2 -translate-y-1/2 w-3 h-3 text-text-tertiary pointer-events-none"})]})]}),e.jsx("p",{className:"text-xs text-text-tertiary",children:(d=o[s])==null?void 0:d.helpText}),e.jsxs("a",{href:b(s),className:"btn-primary text-xs inline-flex items-center gap-1.5",children:[e.jsx(p,{provider:s,className:"w-3.5 h-3.5"}),"Connect ",(x=o[s])==null?void 0:x.name]})]}),m?e.jsx("div",{className:"animate-pulse space-y-3",children:[1,2].map(t=>e.jsx("div",{className:"h-16 bg-surface-sunken rounded"},t))}):c.length===0?e.jsxs("div",{className:"text-center py-16 text-text-tertiary",children:[e.jsx(O,{className:"w-10 h-10 mx-auto mb-3 opacity-40"}),e.jsx("p",{className:"text-sm",children:"No credentials registered."}),e.jsx("p",{className:"text-xs mt-1",children:"Add a credential to enable tool authentication."})]}):e.jsx("div",{className:"divide-y divide-surface-border/30",children:c.map(t=>e.jsxs("div",{className:"group/row flex items-center gap-4 px-3 py-2.5 -mx-3",children:[e.jsx(p,{provider:t.provider,className:"w-6 h-6 shrink-0"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-text-primary font-medium capitalize",children:t.provider}),t.label!=="default"&&e.jsx("span",{className:"text-[10px] px-1.5 py-0.5 bg-surface-sunken rounded text-text-tertiary",children:t.label}),t.credential_type&&e.jsx("span",{className:"text-[10px] px-1.5 py-0.5 bg-accent-faint rounded text-accent",children:t.credential_type})]}),e.jsxs("div",{className:"flex items-center gap-3 mt-0.5",children:[t.email&&e.jsx("span",{className:"text-xs text-text-tertiary",children:t.email}),t.expires_at&&e.jsxs("span",{className:"text-xs text-text-tertiary",children:["Expires ",e.jsx(A,{date:t.expires_at})]})]})]}),e.jsx("button",{onClick:()=>i({provider:t.provider,label:t.label}),className:"opacity-0 group-hover/row:opacity-100 transition-opacity text-text-tertiary hover:text-status-error",title:"Revoke credential",children:e.jsx(S,{className:"w-4 h-4"})})]},`${t.provider}-${t.label}`))}),e.jsx(w,{open:!!a,onClose:()=>i(null),onConfirm:v,title:"Revoke Credential",description:e.jsxs(e.Fragment,{children:["Revoke the"," ",e.jsx("span",{className:"font-medium text-text-primary capitalize",children:a==null?void 0:a.provider}),(a==null?void 0:a.label)!=="default"&&e.jsxs(e.Fragment,{children:[" (",a==null?void 0:a.label,")"]})," ","credential? Tools will no longer be able to use this credential."]}),isPending:n.isPending,error:n.error})]})}export{U as CredentialsPage};
|
|
2
|
-
//# sourceMappingURL=CredentialsPage-smk5H_mP.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as d,j as e}from"./vendor-query-B2UbickB.js";import{k as xe,v as pe,P as me,t as ue,j as he,b as S,U as fe}from"./index-C9moIiIq.js";import{d as je}from"./roles-dJKBZUBh.js";import{b as ge}from"./workflows-By8Wgvig.js";import{u as be}from"./pipelines-Dqh9PLUw.js";import{u as ve}from"./controlplane-CQzrn-rD.js";import{e as ye,b as Ne,i as we}from"./useEventHooks-ZT6RV2Gj.js";import{R as V}from"./RolePill-C91qbDOW.js";import{W as k}from"./WorkflowPill-fodIWnT3.js";import{L as _}from"./ListToolbar-D7PoQOZC.js";import{b as ke,P as _e,p as Ee}from"./OperationsPage-CQzX6jM1.js";import{I as E,an as f,a as X,C as K,W as Y,B as Pe}from"./vendor-icons-BXhWQC7l.js";import{c as se,f as Ce}from"./vendor-react-CXumBFUA.js";import"./PageHeader-sGNTmSXX.js";const Re={completed:"bg-status-success",active:"bg-status-active",running:"bg-status-active",pending:"bg-status-pending",error:"bg-status-error",failed:"bg-status-error"};function Z(s){return Re[s]??"bg-text-tertiary"}function j({icon:s,color:a,docsHash:n,count:o,children:i,actions:l}){return e.jsxs("div",{className:"flex items-center justify-between mb-4 pb-2 border-b border-surface-border",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(s,{className:`w-4.5 h-4.5 ${a||"text-accent/60"}`,strokeWidth:1.5}),e.jsx("h2",{className:"section-h2",children:i}),o!==void 0&&o>0&&e.jsx("span",{className:"px-1.5 py-0.5 rounded-full bg-accent/10 text-accent text-[10px] font-semibold tabular-nums",children:fe(o)})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[n&&e.jsx("button",{onClick:()=>{window.location.hash=n},className:"text-text-quaternary hover:text-accent transition-colors",title:"Docs",children:e.jsx(Pe,{className:"w-2.5 h-2.5",strokeWidth:1.5})}),l]})]})}function g({icon:s,text:a}){return e.jsxs("div",{className:"flex flex-col items-center justify-center py-10 text-center",children:[e.jsx(s,{className:"w-6 h-6 text-text-quaternary/50 mb-2",strokeWidth:1}),e.jsx("p",{className:"text-xs text-text-quaternary",children:a})]})}function Se(s,a=37){if(!s||s.length<=a)return s;const n=Math.floor((a-3)/2);return`${s.slice(0,n)}...${s.slice(-n)}`}function ee({dot:s,pill:a,id:n,date:o,onClick:i}){return e.jsxs("button",{onClick:i,className:"w-full text-left hover:bg-surface-hover/50 rounded-md px-1 py-1.5 transition-colors",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-0.5",children:[e.jsx("span",{className:`w-1.5 h-1.5 rounded-full dot-ring shrink-0 ${s}`}),e.jsx("span",{className:"text-[12px] text-text-primary font-mono truncate max-w-[60%]",children:Se(n)}),e.jsx("span",{className:"text-[10px] text-text-quaternary shrink-0 ml-auto whitespace-nowrap",children:e.jsx(S,{date:o})})]}),e.jsx("div",{className:"pl-3.5 flex items-center gap-1 overflow-hidden",children:a})]})}function b({to:s,icon:a,title:n}){const o=se();return e.jsx("button",{onClick:()=>o(s),className:"text-text-quaternary hover:text-accent transition-colors",title:n,children:e.jsx(a,{className:"w-2.5 h-2.5",strokeWidth:1.5})})}function te({appIds:s,selected:a,onSelect:n}){const[o,i]=d.useState(!1),l=d.useRef(null);return d.useEffect(()=>{if(!o)return;const r=p=>{l.current&&!l.current.contains(p.target)&&i(!1)};return document.addEventListener("mousedown",r),()=>document.removeEventListener("mousedown",r)},[o]),s.length<=1?null:e.jsxs("div",{className:"relative mb-3 -mt-2",ref:l,children:[e.jsxs("button",{onClick:()=>i(r=>!r),className:"flex items-center gap-1 px-2 py-0.5 text-[10px] rounded bg-accent/10 text-accent hover:bg-accent/20 transition-colors",children:[a,e.jsx("svg",{className:`w-2.5 h-2.5 transition-transform ${o?"rotate-180":""}`,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2.5,children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"})})]}),o&&e.jsx("div",{className:"absolute top-full left-0 mt-1 bg-surface-raised border border-surface-border rounded-md shadow-lg z-30 py-1 min-w-[120px]",children:s.map(r=>e.jsx("button",{onClick:()=>{n(r),i(!1)},className:`w-full text-left px-3 py-1.5 text-[11px] transition-colors ${a===r?"text-accent bg-accent/5":"text-text-secondary hover:bg-surface-hover"}`,children:r},r))})]})}function De(){var F,B,H,Q,O,z,D,U;const s=se(),{user:a}=xe(),{isBuilder:n,isOps:o}=pe(),[i,l]=Ce(),{data:r}=ve({enabled:n}),p=d.useMemo(()=>((r==null?void 0:r.apps)??[]).map(t=>t.appId).sort(),[r]),$=p[0]??"",v=i.get("pipelinenamespace")||$,P=i.get("durablenamespace")||$,A=d.useCallback((t,c)=>{l(R=>{const h=new URLSearchParams(R);return h.set(t,c),h},{replace:!1})},[l]);ye(),Ne(),we();const C=n||o,y=je({enabled:C}),q=me("1h",{enabled:C}),N=ge({limit:5,sort_by:"updated_at",order:"desc",namespace:P},{enabled:n}),ae=p,ne=p,w=be({limit:5,app_id:v,sort_by:"updated_at",order:"desc"},{enabled:n}),m=ue({limit:5,sort_by:"created_at",order:"desc"}),u=he({assigned_to:a==null?void 0:a.userId,status:"pending",limit:5,sort_by:"created_at",order:"desc"});d.useEffect(()=>{const t=setTimeout(()=>{u.refetch(),m.refetch()},2e3);return()=>clearTimeout(t)},[]);const I=d.useMemo(()=>{var h,G,J;const c=((G=ke(((h=y.data)==null?void 0:h.roles)??[])[0])==null?void 0:G.stations)??[],R=((J=q.data)==null?void 0:J.stations)??[];return c.map(({role:x})=>({role:x.role,title:x.title,parent_role:x.parent_role,target_per_hour:x.target_per_hour??null,upstream_roles:x.upstream_roles??[],metric:R.find(de=>de.role===x.role)}))},[y.data,q.data]),oe=d.useMemo(()=>{var t;return new Map((((t=y.data)==null?void 0:t.roles)??[]).map(c=>[c.role,c]))},[y.data]),M=((F=N.data)==null?void 0:F.jobs)??[],re=(B=N.data)==null?void 0:B.total,L=((H=w.data)==null?void 0:H.jobs)??[],ie=(Q=w.data)==null?void 0:Q.total,T=((O=m.data)==null?void 0:O.escalations)??[],ce=(z=m.data)==null?void 0:z.total,W=((D=u.data)==null?void 0:D.escalations)??[],le=(U=u.data)==null?void 0:U.total;return e.jsxs("div",{children:[e.jsx("h1",{className:"text-3xl font-light text-text-primary mb-10",children:"Recent Activity"}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-x-14 min-h-[35vh]",children:[e.jsxs("div",{children:[e.jsx(j,{icon:E,color:"text-accent",count:ce,docsHash:"#docs:dashboard.md:all-escalations",actions:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(_,{onRefresh:()=>m.refetch(),isFetching:m.isFetching,apiPath:"/escalations?status=pending&limit=5&sort_by=created_at&order=desc"}),e.jsx(b,{to:"/escalations/available",icon:f,title:"All escalations"})]}),children:"All Escalations"}),T.length===0?e.jsx(g,{icon:E,text:"No pending escalations"}):e.jsx("div",{className:"space-y-1",children:T.map(t=>e.jsxs("button",{onClick:()=>s(`/escalations/detail/${t.id}`),className:"w-full text-left hover:bg-surface-hover/50 rounded-md px-1 py-1.5 transition-colors",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-0.5",children:[e.jsxs("span",{className:"text-[9px] text-text-quaternary font-medium shrink-0",children:["P",t.priority??2]}),e.jsx("span",{className:"text-[12px] text-text-primary truncate flex-1 max-w-[65%]",children:t.description||t.subtype||t.type}),e.jsx("span",{className:"text-[10px] text-text-quaternary shrink-0 ml-auto",children:e.jsx(S,{date:t.updated_at??t.created_at})})]}),e.jsxs("div",{className:"flex items-center gap-2 pl-5",children:[e.jsx(k,{type:t.type||"unknown",size:"xs"}),e.jsx("span",{className:"flex-1"}),e.jsx(V,{role:t.role})]})]},t.id))})]}),e.jsxs("div",{children:[e.jsx(j,{icon:E,color:"text-accent",count:le,docsHash:"#docs:dashboard.md:escalations-overview",actions:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(_,{onRefresh:()=>u.refetch(),isFetching:u.isFetching,apiPath:`/escalations?assigned_to=${(a==null?void 0:a.userId)??""}&status=pending&limit=5&sort_by=created_at&order=desc`}),e.jsx(b,{to:"/escalations/queue",icon:f,title:"My escalation queue"})]}),children:"My Escalations"}),W.length===0?e.jsx(g,{icon:E,text:"No assigned escalations"}):e.jsx("div",{className:"space-y-1",children:W.map(t=>e.jsxs("button",{onClick:()=>s(`/escalations/detail/${t.id}`),className:"w-full text-left hover:bg-surface-hover/50 rounded-md px-1 py-1.5 transition-colors",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-0.5",children:[e.jsxs("span",{className:"text-[9px] text-text-quaternary font-medium shrink-0",children:["P",t.priority??2]}),e.jsx("span",{className:"text-[12px] text-text-primary truncate flex-1 max-w-[65%]",children:t.description||t.subtype||t.type}),e.jsx("span",{className:"text-[10px] text-text-quaternary shrink-0 ml-auto",children:e.jsx(S,{date:t.updated_at??t.created_at})})]}),e.jsxs("div",{className:"flex items-center gap-2 pl-5",children:[e.jsx(k,{type:t.type||"unknown",size:"xs"}),e.jsx("span",{className:"flex-1"}),e.jsx(V,{role:t.role})]})]},t.id))})]})]}),C&&e.jsxs("div",{className:`grid grid-cols-1 ${n?"lg:grid-cols-3":""} gap-x-14 mt-14`,children:[e.jsxs("div",{children:[e.jsx(j,{icon:X,color:"text-accent",docsHash:"#docs:dashboard.md:pace-board",actions:e.jsx(b,{to:"/operations",icon:f,title:"Open the Pace Board"}),children:"Pace Board"}),I.length===0?e.jsx(g,{icon:X,text:"No stations yet — mark roles visible in Operations"}):e.jsx("div",{className:`${n?"h-64":"h-80"} cursor-pointer`,onClick:()=>s("/operations"),children:e.jsx(_e,{stations:I,selectedRole:null,onSelect:()=>s("/operations"),onUpstreamSelect:()=>s("/operations"),onPrioritySelect:t=>{const c=oe.get(t);c&&s(Ee(c))},periodHours:1})})]}),n&&e.jsxs("div",{children:[e.jsx(j,{icon:K,color:"text-accent",count:re,docsHash:"#docs:dashboard.md:procedural-executions",actions:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(_,{onRefresh:()=>N.refetch(),isFetching:N.isFetching,apiPath:`/workflow-states/jobs?namespace=${P}&limit=5`}),e.jsx(b,{to:"/workflows/executions",icon:f,title:"All procedural executions"})]}),children:"Procedural"}),e.jsx(te,{appIds:ae,selected:P,onSelect:t=>A("durablenamespace",t)}),M.length===0?e.jsx(g,{icon:K,text:"No recent procedural runs"}):e.jsx("div",{className:"space-y-1",children:M.map(t=>e.jsx(ee,{dot:Z(t.status),pill:e.jsx(k,{type:t.entity||t.type||"workflow",size:"xs"}),id:t.workflow_id,date:t.updated_at??t.created_at,onClick:()=>s(`/workflows/executions/${t.workflow_id}`)},t.workflow_id))})]}),n&&e.jsxs("div",{children:[e.jsx(j,{icon:Y,color:"text-accent",count:ie,docsHash:"#docs:dashboard.md:graph-executions",actions:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(_,{onRefresh:()=>w.refetch(),isFetching:w.isFetching,apiPath:`/pipelines?app_id=${v}&limit=5`}),e.jsx(b,{to:"/mcp/executions",icon:f,title:"All graph executions"})]}),children:"Graph"}),e.jsx(te,{appIds:ne,selected:v,onSelect:t=>A("pipelinenamespace",t)}),L.length===0?e.jsx(g,{icon:Y,text:"No recent graph runs"}):e.jsx("div",{className:"space-y-1",children:L.map(t=>e.jsx(ee,{dot:Z(t.status),pill:e.jsx(k,{type:t.entity||t.workflow_name||"pipeline",variant:"pipeline",size:"xs"}),id:t.workflow_id,date:t.updated_at??t.created_at,onClick:()=>s(`/mcp/executions/${t.workflow_id}?namespace=${v}`)},t.workflow_id))})]})]})]})}export{De as HomePage};
|
|
2
|
-
//# sourceMappingURL=HomePage-Cj9sLt4Z.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as $,j as e}from"./vendor-query-B2UbickB.js";import{d as Se}from"./roles-dJKBZUBh.js";import{P as ye}from"./index-C9moIiIq.js";import{i as Me}from"./useEventHooks-ZT6RV2Gj.js";import{P as Le}from"./PageHeader-sGNTmSXX.js";import{X as qe,y as Ae,aE as ge,an as Oe,aD as Fe,az as Ee}from"./vendor-icons-BXhWQC7l.js";import{L as M,f as Ie,c as Te}from"./vendor-react-CXumBFUA.js";function We(t){return t.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1 $2").split(/[-_\s]+/).filter(Boolean).map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join(" ")}function le(t){var n;return((n=t.title)==null?void 0:n.trim())||We(t.role)}const je=800,be=270,W=40,De=76,ce=24,ze=72,oe=je-W-De,ve=be-ce-ze,C=ce+ve,me=W+oe,j="0.5s cubic-bezier(0.4, 0, 0.2, 1)",he=9;function Be(t){return`M ${(t.x-he).toFixed(1)} ${t.y.toFixed(1)} L ${(t.x+he).toFixed(1)} ${t.y.toFixed(1)}`}function D(t){if(t.length===0)return"";if(t.length===1)return Be(t[0]);const n=[];for(let l=0;l<t.length-1;l++){const i=t[Math.max(0,l-1)],c=t[l],p=t[l+1],a=t[Math.min(t.length-1,l+2)],d=(c.x+(p.x-i.x)/6).toFixed(1),u=(c.y+(p.y-i.y)/6).toFixed(1),o=(p.x-(a.x-c.x)/6).toFixed(1),x=(p.y-(a.y-c.y)/6).toFixed(1);l===0&&n.push(`M ${c.x.toFixed(1)} ${c.y.toFixed(1)}`),n.push(`C ${d} ${u}, ${o} ${x}, ${p.x.toFixed(1)} ${p.y.toFixed(1)}`)}return n.join(" ")}function He(t,n){if(t.length<2||n.length<2)return"";const l=D(t),i=[...n].reverse(),c=D(i),p=c.slice(c.indexOf("C"));return`${l} L ${i[0].x.toFixed(1)} ${i[0].y.toFixed(1)} ${p} Z`}function Ue(t){return t>=1e4?`${Math.round(t/1e3)}k`:t>=1e3?`${(t/1e3).toFixed(1)}k`:String(t)}function ne(t){return t.length>0?t[t.length-1]:void 0}const F="#6366f1",z="#0ea5e9",A="#1E3A8A",B="#059669",Ne="#b0e0e6",E="#5b93ad",Ve=13;function Ye(t,n){const l=[...t].sort((a,d)=>a.y-d.y);let i=-1/0;const c=l.map(a=>{const d=Math.max(a.y+3,i+Ve);return i=d,{...a,labelY:d}}),p=c.length>0?c[c.length-1].labelY-n:0;if(p>0)for(const a of c)a.labelY-=p;return c}function Ge({stations:t,selectedRole:n,onSelect:l,onUpstreamSelect:i,onPrioritySelect:c,periodHours:p}){const[a,d]=$.useState(null),u=t.length;if(u===0)return null;const o=s=>u===1?W+oe/2:W+s/(u-1)*oe,x=new Map(t.map((s,f)=>[s.role,o(f)])),y=t.map((s,f)=>{var _,G,Z,Q;const g=s.target_per_hour??null,S=g!=null?g*p:null;return{idx:f,x:o(f),expected:S,actual:((_=s.metric)==null?void 0:_.resolved)??0,active:((G=s.metric)==null?void 0:G.claimed)??0,pending:((Z=s.metric)==null?void 0:Z.pending)??0,priorityCount:((Q=s.metric)==null?void 0:Q.priority_count)??0}}),b=y.some(s=>s.expected!=null),v=Math.max(1,...y.map(s=>s.expected??0),...y.map(s=>s.actual),...y.map(s=>s.expected!=null?s.pending:0))*1.15,P=s=>ce+ve*(1-Math.max(0,Math.min(s,v))/v),N=y.filter(s=>s.expected!=null),L=N.map(s=>({...s,y:P(s.expected)})),w=N.map(s=>({...s,y:P(s.actual)})),R=N.map(s=>({...s,y:P(s.active)})),k=N.map(s=>({...s,y:P(s.pending)})),H=D(L),U=D(w),V=D(R),X=D(k),O=ne(w),K=ne(L),I=ne(R),J=ne(k),ee=w.length>=2&&O?`${U} L ${O.x.toFixed(1)} ${C} L ${w[0].x.toFixed(1)} ${C} Z`:"",T=N.some(s=>s.pending>0||s.active>0),te=T&&R.length>=2&&I?`${V} L ${I.x.toFixed(1)} ${C} L ${R[0].x.toFixed(1)} ${C} Z`:"",Y=T?He(k,R):"",r=N.some(s=>s.active>0),h=N.some(s=>s.pending>s.active),q=Ye([K?{key:"target",text:"Target",color:B,y:K.y}:null,O?{key:"actual",text:"Resolved",color:A,y:O.y}:null,r&&I?{key:"active",text:"Claimed",color:F,y:I.y}:null,h&&J?{key:"queued",text:"Pending",color:z,y:J.y}:null].filter(Boolean),C+4);return e.jsxs("svg",{viewBox:`0 0 ${je} ${be}`,className:"w-full h-full",preserveAspectRatio:"xMidYMid meet",style:{display:"block"},children:[t.map(s=>{if(!s.parent_role)return null;const f=x.get(s.parent_role);if(f==null)return null;const g=o(t.findIndex(S=>S.role===s.role));return e.jsx("line",{x1:f,y1:C,x2:g,y2:C,stroke:"#e2e8f0",strokeWidth:.75},`dep-${s.role}`)}),ee&&e.jsx("path",{d:ee,fill:A,opacity:.05,style:{transition:`d ${j}`}}),te&&e.jsx("path",{d:te,fill:F,opacity:.12,style:{transition:`d ${j}`}}),Y&&e.jsx("path",{d:Y,fill:z,opacity:.12,style:{transition:`d ${j}`}}),H&&e.jsx("path",{d:H,fill:"none",stroke:B,strokeWidth:.5,strokeLinejoin:"round",opacity:.9,style:{transition:`d ${j}`}}),L.map(s=>e.jsxs("g",{transform:`translate(${s.x} ${s.y})`,style:{transition:`transform ${j}`},children:[e.jsx("circle",{r:2,fill:B,opacity:.8}),e.jsx("text",{y:-5,textAnchor:"middle",fontSize:6.5,fill:B,fontFamily:"ui-monospace, monospace",fontWeight:"500",opacity:.7,children:Math.round(s.expected)})]},`tval-${s.idx}`)),T&&X&&e.jsx("path",{d:X,fill:"none",stroke:z,strokeWidth:.75,strokeDasharray:"2 3",strokeLinecap:"round",opacity:.55,style:{transition:`d ${j}`}}),V&&e.jsx("path",{d:V,fill:"none",stroke:F,strokeWidth:.75,strokeDasharray:"2 3",strokeLinecap:"round",opacity:.5,style:{transition:`d ${j}`}}),U&&e.jsx("path",{d:U,fill:"none",stroke:A,strokeWidth:.6,strokeLinejoin:"round",strokeLinecap:"round",opacity:.65,style:{transition:`d ${j}`}}),R.map((s,f)=>{if(s.pending<=0&&s.active<=0)return null;const g=Math.max(2.5,Math.min(5,2.5+s.active/10)),S=s.pending>s.active,_=Math.min(k[f].y-4,s.y-g-4);return e.jsxs("g",{children:[s.pending>0&&e.jsx("text",{x:s.x,y:_,textAnchor:"middle",fontSize:7.5,fill:S?z:"#64748b",fontFamily:"ui-monospace, monospace",fontWeight:"600",style:{transition:`y ${j}`},children:s.pending}),e.jsxs("g",{transform:`translate(${s.x} ${s.y})`,style:{transition:`transform ${j}`},children:[e.jsx("circle",{r:g,fill:F,opacity:.85}),s.active>0&&e.jsx("text",{y:g+9,textAnchor:"middle",fontSize:7.5,fill:F,fontFamily:"ui-monospace, monospace",fontWeight:"600",children:s.active})]})]},`active-${s.idx}`)}),y.map(s=>{var ue;const f=t[s.idx],g=s.x,S=s.expected!=null?P(s.actual):C,_=Math.max(2.25,Math.min(4,2.25+s.actual/160)),G=f.role===n,Z=a===s.idx,Q=s.expected==null?"idle · set a target rate to plot pace":`${s.actual} resolved · target ${Math.round(s.expected)}`+(s.pending>s.active?` · ${s.pending-s.active} pending`:"")+(s.active>0?` · ${s.active} claimed`:"")+(s.priorityCount>0?` · ${s.priorityCount} priority`:""),se=Q.length*5.5+20,de=Math.max(W+se/2+4,Math.min(me-se/2-4,g)),pe=S-_-10;return e.jsxs("g",{onClick:()=>l(f.role),onMouseEnter:()=>d(s.idx),onMouseLeave:()=>d(null),style:{cursor:"pointer"},children:[e.jsxs("g",{transform:`translate(${g} ${S})`,style:{transition:`transform ${j}`},children:[e.jsx("circle",{r:22,fill:"transparent"}),e.jsx("circle",{r:_,fill:A,opacity:.9,style:{transition:`r ${j}`}}),s.expected!=null&&e.jsx("text",{y:-_-5,textAnchor:"middle",fontSize:9.5,fill:A,fontFamily:"ui-monospace, monospace",fontWeight:"500",children:Ue(s.actual)}),Z&&!G&&e.jsx("circle",{r:_+3,fill:"none",stroke:A,strokeWidth:1,opacity:.4}),G&&e.jsx("circle",{r:_+4,fill:"none",stroke:"#6366f1",strokeWidth:2})]}),s.priorityCount>0&&e.jsxs("g",{transform:`translate(${g+15} ${Math.max(S-15,12)})`,onClick:ie=>{ie.stopPropagation(),c==null||c(f.role)},style:{cursor:"pointer",transition:`transform ${j}`},children:[e.jsx("title",{children:`${s.priorityCount} past the priority threshold — click to pull oldest first`}),e.jsx("circle",{r:6.5+(String(s.priorityCount).length-1)*2,fill:Ne,opacity:.9}),e.jsx("text",{y:2.5,textAnchor:"middle",fontSize:7,fill:E,fontFamily:"ui-monospace, monospace",fontWeight:"700",children:s.priorityCount})]}),(((ue=f.upstream_roles)==null?void 0:ue.length)??0)>0&&e.jsxs("g",{transform:`translate(${g-20} ${C})`,onClick:ie=>{ie.stopPropagation(),i==null||i(f.upstream_roles[0])},style:{cursor:"pointer"},children:[e.jsx("title",{children:`Fed by ${f.upstream_roles.join(", ")} — click to view that sequence`}),e.jsx("circle",{r:9,cy:-6,fill:"transparent"}),e.jsx("path",{d:"M -7 -14 C -3 -14 -1 -9 0 -2",fill:"none",stroke:"#94a3b8",strokeWidth:1,strokeDasharray:"2 2",strokeLinecap:"round"}),e.jsx("path",{d:"M 0 -2 L 8 -2",stroke:"#94a3b8",strokeWidth:1,strokeLinecap:"round"}),e.jsx("path",{d:"M 8 -2 l -3.5 -2 v 4 z",fill:"#94a3b8"})]}),e.jsx("text",{x:g,y:C+(s.idx%2===0?14:27),textAnchor:"middle",fontSize:9.5,fill:"#475569",fontFamily:"ui-sans-serif, sans-serif",fontWeight:"500",children:le(f)}),Z&&e.jsxs("g",{children:[e.jsx("rect",{x:de-se/2,y:pe-16,width:se,height:19,rx:3,fill:"#0f172a",opacity:.88}),e.jsx("text",{x:de,y:pe-3,textAnchor:"middle",fontSize:8.5,fill:"white",fontFamily:"ui-monospace, monospace",children:Q})]})]},f.role)}),!b&&e.jsx("text",{x:W+oe/2,y:C+48,textAnchor:"middle",fontSize:8.5,fill:"#94a3b8",fontFamily:"ui-sans-serif, sans-serif",children:"Set target_per_hour on each role in Admin → Roles to enable the pace chart"}),q.map(s=>e.jsx("text",{x:me+6,y:s.labelY,fontSize:8,fill:s.color,fontFamily:"ui-sans-serif, sans-serif",fontWeight:s.key==="actual"?700:500,opacity:s.key==="active"?.85:1,style:{transition:`y ${j}`},children:s.text},s.key))]})}function xe(t){const n=`/escalations/available?role=${encodeURIComponent(t.role)}`;if(t.priority_facet){const l=JSON.stringify([{field:`metadata.${t.priority_facet}`,direction:"asc"}]);return`${n}&orderBy=${encodeURIComponent(l)}`}return`${n}&sort_by=created_at&order=asc`}const ke=["15m","1h","24h","7d","30d"],Ze=t=>ke.includes(t);function ae(t){if(t==null)return"—";if(t<1){const n=Math.round(t*60);return n<=0?"< 1s":`${n}s`}return t<60?`${t.toFixed(0)}m`:`${(t/60).toFixed(1)}h`}function re({label:t,value:n}){return e.jsxs("div",{className:"flex items-center justify-between py-1",children:[e.jsx("span",{className:"text-[10px] text-text-tertiary uppercase tracking-wider",children:t}),e.jsx("span",{className:"text-xs font-mono font-medium text-text-primary tabular-nums",children:n})]})}function Qe({period:t,onChange:n}){return e.jsx("div",{className:"flex items-center gap-1 mb-4",children:ke.map(l=>e.jsx("button",{onClick:()=>n(l),className:`px-2 py-0.5 text-[10px] font-mono rounded transition-colors ${t===l?"bg-accent/10 text-accent font-semibold":"text-text-quaternary hover:text-text-secondary"}`,children:l},l))})}function Xe({role:t,globalPeriod:n,onClose:l}){const[i,c]=$.useState(Ze(n)?n:"24h"),{data:p}=ye(i),a=p==null?void 0:p.stations.find(x=>x.role===t.role),d=t.sla_minutes??void 0,u=t.target_per_hour??void 0,o=t.worker_count??void 0;return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-start justify-between mb-1",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-baseline gap-1.5 flex-wrap",children:[e.jsx("span",{className:"text-sm font-bold text-text-primary",children:le(t)}),e.jsx("span",{className:"text-[10px] font-mono text-text-secondary",children:t.role})]}),t.description&&e.jsx("p",{className:"text-[10px] text-text-tertiary mt-0.5 line-clamp-2 leading-relaxed",children:t.description})]}),e.jsx("button",{onClick:l,className:"text-text-quaternary hover:text-text-secondary transition-colors mt-0.5 shrink-0 ml-2",children:e.jsx(qe,{className:"w-4 h-4"})})]}),e.jsxs("div",{className:"flex items-center gap-3 mb-4",children:[e.jsxs(M,{to:`/admin/roles/${encodeURIComponent(t.role)}`,className:"flex items-center gap-1 text-[10px] text-accent hover:underline",children:[e.jsx(Ae,{className:"w-2.5 h-2.5"}),"Edit in Roles"]}),e.jsxs(M,{to:`/escalations/available?role=${encodeURIComponent(t.role)}`,className:"flex items-center gap-1 text-[10px] text-accent hover:underline",children:[e.jsx(ge,{className:"w-2.5 h-2.5"}),"View full queue"]})]}),e.jsx(Qe,{period:i,onChange:c}),(u||d||o)&&e.jsxs("div",{className:"flex items-center gap-4 mb-4 text-[10px]",children:[u&&e.jsxs("div",{children:[e.jsxs("div",{className:"font-mono font-semibold text-text-primary",children:[u,"/h"]}),e.jsx("div",{className:"text-text-quaternary uppercase tracking-wider text-[8.5px]",children:"target"})]}),d&&e.jsxs("div",{children:[e.jsxs("div",{className:"font-mono font-semibold text-text-primary",children:[d,"m"]}),e.jsx("div",{className:"text-text-quaternary uppercase tracking-wider text-[8.5px]",children:"SLA"})]}),o&&e.jsxs("div",{children:[e.jsx("div",{className:"font-mono font-semibold text-text-primary",children:o}),e.jsx("div",{className:"text-text-quaternary uppercase tracking-wider text-[8.5px]",children:"workers"})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-x-3",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-[9px] text-text-quaternary uppercase tracking-wider mb-1.5",children:"Wait (queue)"}),e.jsx(re,{label:"P99",value:ae((a==null?void 0:a.wait.p99)??null)}),e.jsx(re,{label:"avg",value:ae((a==null?void 0:a.wait.avg)??null)})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[9px] text-text-quaternary uppercase tracking-wider mb-1.5",children:"Work (proc.)"}),e.jsx(re,{label:"P99",value:ae((a==null?void 0:a.work.p99)??null)}),e.jsx(re,{label:"avg",value:ae((a==null?void 0:a.work.avg)??null)})]})]}),e.jsxs("div",{className:"border-t border-surface-border/40 pt-2 mt-3 space-y-1.5",children:[d&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-[10px] text-text-tertiary",children:"SLA target"}),e.jsxs("span",{className:"text-xs font-mono text-text-secondary",children:[d,"m"]})]}),a&&a.priority_count>0&&e.jsxs(M,{to:xe(t),className:"flex items-center justify-between group",children:[e.jsxs("span",{className:"text-[10px]",style:{color:E},children:[a.priority_count," priority — pull oldest first"]}),e.jsx(Oe,{className:"w-3 h-3 transition-colors",style:{color:E}})]})]})]})}function Ke({allMetrics:t,orderedRoles:n,period:l}){const i=t.reduce((o,x)=>o+x.pending,0),c=t.reduce((o,x)=>o+x.resolved,0),p=t.reduce((o,x)=>o+x.priority_count,0),a=new Map(t.map(o=>[o.role,o])),d=t.filter(o=>o.priority_count>0).length,u=t.filter(o=>o.pending>0).length;return e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"text-[9px] text-text-quaternary uppercase tracking-wider mb-3",children:["Pipeline · ",l]}),e.jsx("div",{className:"mb-4",children:d>0?e.jsxs("p",{className:"text-[11px]",style:{color:E},children:[d," station",d>1?"s":""," with priority items"]}):u>0?e.jsxs("p",{className:"text-[11px] text-status-warning",children:[u," station",u>1?"s":""," with backlog"]}):c>0?e.jsx("p",{className:"text-[11px] text-status-success",children:"Flowing — queue clear"}):e.jsx("p",{className:"text-[11px] text-text-quaternary",children:"Quiet — awaiting work"})}),e.jsxs("div",{className:"space-y-1.5 mb-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-[9px] text-text-quaternary uppercase tracking-wider",children:"Pending"}),e.jsx("span",{className:`text-xs font-mono tabular-nums ${i>0?"text-text-primary font-semibold":"text-text-quaternary"}`,children:i})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-[9px] text-text-quaternary uppercase tracking-wider",children:["Resolved · ",l]}),e.jsx("span",{className:"text-xs font-mono tabular-nums text-text-secondary",children:c})]}),p>0&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-[9px] text-text-quaternary uppercase tracking-wider",children:"Priority"}),e.jsx("span",{className:"text-xs font-mono tabular-nums font-semibold",style:{color:E},children:p})]})]}),e.jsx("div",{className:"border-t border-surface-border/40 pt-2 mb-1",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-[8px] text-text-quaternary uppercase tracking-wider flex-1",children:"Station"}),e.jsx("span",{className:"text-[8px] text-text-quaternary uppercase tracking-wider w-8 text-right shrink-0",children:"pend"}),e.jsx("span",{className:"text-[8px] text-text-quaternary uppercase tracking-wider w-8 text-right shrink-0",children:"clmd"}),e.jsx("span",{className:"text-[8px] text-text-quaternary uppercase tracking-wider w-8 text-right shrink-0",children:"res"})]})}),e.jsx("div",{className:"space-y-0.5",children:n.map(o=>{const x=a.get(o.role),y=(x==null?void 0:x.pending)??0,b=(x==null?void 0:x.claimed)??0,m=(x==null?void 0:x.resolved)??0,v=(x==null?void 0:x.priority_count)??0,P=o.title||o.role,N=v>0,L=y>0;return e.jsxs("div",{className:"flex items-center gap-2 py-0.5",children:[e.jsxs("span",{className:`text-[10px] font-mono flex-1 truncate ${L?"text-text-primary":"text-text-quaternary"}`,children:[P,N&&e.jsxs("span",{className:"ml-1 text-[8px] font-semibold",style:{color:E},children:[v," PRIORITY"]})]}),e.jsx("span",{className:`text-[10px] font-mono tabular-nums w-8 text-right shrink-0 ${L?"text-text-primary font-semibold":"text-text-quaternary"}`,children:y>0?y:"—"}),e.jsx("span",{className:`text-[10px] font-mono tabular-nums w-8 text-right shrink-0 ${b>0?"text-accent":"text-text-quaternary"}`,children:b>0?b:"—"}),e.jsx("span",{className:`text-[10px] font-mono tabular-nums w-8 text-right shrink-0 ${m>0?"text-text-secondary":"text-text-quaternary"}`,children:m>0?m:"—"})]},o.role)})}),e.jsx("p",{className:"text-[9px] text-text-quaternary mt-5",children:"Select a station for queue detail."})]})}function Je({role:t,allMetrics:n,orderedRoles:l,globalPeriod:i,onClose:c}){return e.jsx("div",{className:"w-[280px] shrink-0 px-6 py-8 flex flex-col overflow-y-auto min-h-0",children:t?e.jsx(Xe,{role:t,globalPeriod:i,onClose:c}):e.jsx(Ke,{allMetrics:n,orderedRoles:l,period:i})})}const $e=`${B}14`,we=`${z}14`,Ce=`${F}14`,Re=`${A}14`,_e="minmax(120px, 1.1fr) minmax(100px, 0.9fr) 64px 56px 56px 60px 72px 72px 104px 36px",et=["15m","1h","24h","7d","30d"],tt={"15m":.25,"1h":1,"24h":24,"7d":168,"30d":720};function Pe(t){const n=t.filter(a=>a.ops_visible),l=new Map(n.map(a=>[a.role,a])),i=new Set,p=n.filter(a=>!a.parent_role||!l.has(a.parent_role)).map(a=>{const d=[],u=[{role:a,depth:0}];for(;u.length>0;){const o=u.shift();i.has(o.role.role)||(i.add(o.role.role),d.push(o),n.filter(x=>x.parent_role===o.role.role&&!i.has(x.role)).forEach(x=>u.push({role:x,depth:o.depth+1})))}return{origin:a,stations:d}});return n.filter(a=>!i.has(a.role)).forEach(a=>p.push({origin:a,stations:[{role:a,depth:0}]})),p.sort((a,d)=>d.stations.length-a.stations.length||a.origin.role.localeCompare(d.origin.role))}function fe(t){if(t==null)return"—";if(t<1){const n=Math.round(t*60);return n<=0?"< 1s":`${n}s`}return t<60?`${t.toFixed(0)}m`:`${(t/60).toFixed(1)}h`}function st(t,n){if(!n||t===0)return{pct:null,color:"bg-surface-border"};const l=t/n,i=Math.round(l*100),c=l>1?"bg-status-warning":l<.2?"bg-status-draft":"bg-status-success";return{pct:i,color:c}}function nt({role:t,metric:n,selected:l,onClick:i}){var b;const c=(n==null?void 0:n.pending)??0,p=(n==null?void 0:n.claimed)??0,a=(n==null?void 0:n.resolved)??0,d=(n==null?void 0:n.priority_count)??0,u=t.target_per_hour??null,{pct:o,color:x}=st(c,u),y=o!=null?Math.min(100,o):0;return e.jsxs(e.Fragment,{children:[e.jsxs("div",{role:"button",tabIndex:0,onClick:i,onKeyDown:m=>{m.key==="Enter"&&i()},className:`grid items-center gap-4 pr-3 cursor-pointer transition-colors ${l?"border-l-2 !border-l-accent pl-2.5":"pl-3"}`,style:{gridTemplateColumns:_e},children:[e.jsxs("div",{className:"flex items-center gap-1.5 min-w-0 py-1.5",children:[e.jsx("span",{className:"font-bold text-text-primary truncate text-xs",children:le(t)}),(((b=t.upstream_roles)==null?void 0:b.length)??0)>0&&e.jsx("span",{title:`Fed by ${t.upstream_roles.join(", ")}`,className:"shrink-0 leading-none",children:e.jsx(Ee,{className:"w-3 h-3 text-text-quaternary"})})]}),e.jsx("span",{className:"font-mono text-[11px] text-text-tertiary truncate py-1.5",children:t.role}),e.jsx("div",{className:"self-stretch flex items-center justify-end px-1.5",style:{backgroundColor:$e},children:e.jsx("span",{className:`text-xs font-mono tabular-nums ${u!=null?"text-text-secondary":"text-text-quaternary"}`,children:u??"—"})}),e.jsx("div",{className:"self-stretch flex items-center justify-end px-1.5",style:{backgroundColor:we},children:e.jsx(M,{to:`/escalations/available?role=${encodeURIComponent(t.role)}&status=available`,className:`text-xs font-mono tabular-nums hover:underline ${c>0?"text-text-primary font-semibold":"text-text-quaternary"}`,onClick:m=>m.stopPropagation(),children:c})}),e.jsx("div",{className:"self-stretch flex items-center justify-end px-1.5",style:{backgroundColor:Ce},children:e.jsx(M,{to:`/escalations/available?role=${encodeURIComponent(t.role)}&status=claimed`,className:`text-xs font-mono tabular-nums hover:underline ${p>0?"text-accent font-semibold":"text-text-quaternary"}`,onClick:m=>m.stopPropagation(),children:p})}),e.jsx("div",{className:"self-stretch flex items-center justify-end px-1.5",style:{backgroundColor:Re},children:e.jsx(M,{to:`/escalations/available?role=${encodeURIComponent(t.role)}&status=resolved`,className:"text-xs font-mono tabular-nums hover:underline text-text-quaternary",onClick:m=>m.stopPropagation(),children:a})}),e.jsx("span",{className:"text-xs font-mono tabular-nums text-right py-1.5 text-text-secondary",children:fe((n==null?void 0:n.wait.p99)??null)}),e.jsx("span",{className:"text-xs font-mono tabular-nums text-right py-1.5 text-text-secondary",children:fe((n==null?void 0:n.work.p99)??null)}),e.jsxs("div",{className:"flex items-center gap-2 py-1.5",children:[e.jsx("div",{className:"w-12 h-1.5 bg-surface-sunken rounded-full overflow-hidden shrink-0",children:e.jsx("div",{className:`h-full rounded-full ${x}`,style:{width:`${y}%`}})}),e.jsx("span",{className:`text-[10px] font-mono tabular-nums ${o!=null&&o>100?"text-status-warning font-semibold":"text-text-quaternary"}`,children:o!=null?`${o}%`:"—"})]}),e.jsx("div",{className:"flex items-center justify-center py-1.5",children:e.jsx(M,{to:`/escalations/available?role=${encodeURIComponent(t.role)}`,className:"text-text-quaternary hover:text-accent transition-colors",title:"View full queue",onClick:m=>m.stopPropagation(),children:e.jsx(ge,{className:"w-3.5 h-3.5"})})})]}),d>0&&e.jsxs("div",{className:"flex items-center gap-1.5 pb-2 pl-3.5",children:[e.jsx("span",{className:"w-2.5 h-2.5 rounded-full dot-ring shrink-0",style:{backgroundColor:Ne}}),e.jsxs(M,{to:xe(t),className:"text-[10px] hover:underline",style:{color:E},onClick:m=>m.stopPropagation(),children:[d," priority — pull oldest first →"]})]})]})}function at(){const t=[{label:"NAME"},{label:"ROLE"},{label:"TARGET/H",band:$e,hue:B},{label:"PENDING",band:we,hue:z},{label:"CLAIMED",band:Ce,hue:F},{label:"RESOLVED",band:Re,hue:A},{label:"P99 WAIT"},{label:"P99 WORK"},{label:"TREND"},{label:"ACTIONS"}];return e.jsx("div",{className:"grid items-center gap-4 px-3 border-b border-surface-border mb-0.5",style:{gridTemplateColumns:_e},children:t.map((n,l)=>n.band?e.jsx("div",{className:"self-stretch flex items-center justify-end px-1.5",style:{backgroundColor:n.band},children:e.jsx("span",{className:"text-[9px] font-semibold uppercase tracking-wider",style:{color:n.hue},children:n.label})},n.label):e.jsx("span",{className:`text-[9px] font-semibold uppercase tracking-wider text-text-quaternary py-1.5 ${l>1&&l<8?"text-right":l===9?"text-center":""}`,children:n.label},n.label))})}function rt(){var Y;const[t,n]=$.useState("1h"),[l,i]=$.useState(null),[c,p]=$.useState(!1);Me();const{data:a,isLoading:d,refetch:u}=Se(),{data:o,isLoading:x,refetch:y}=ye(t),b=(a==null?void 0:a.roles)??[],m=(o==null?void 0:o.stations)??[],v=$.useMemo(()=>Pe(b),[b]),[P,N]=Ie(),L=P.get("fragment"),w=v.find(r=>r.origin.role===L)??v[0]??null,R=$.useCallback(r=>{i(null),N(h=>{const q=new URLSearchParams(h);return q.set("fragment",r),q})},[N]),k=(w==null?void 0:w.stations)??[],H=$.useMemo(()=>new Set(k.map(({role:r})=>r.role)),[k]),U=$.useMemo(()=>m.filter(r=>H.has(r.role)),[m,H]),V=$.useMemo(()=>k.map(({role:r})=>({role:r.role,title:r.title,parent_role:r.parent_role,target_per_hour:r.target_per_hour??null,upstream_roles:r.upstream_roles??[],metric:m.find(h=>h.role===r.role)})),[k,m]),X=$.useCallback(r=>{const h=v.find(q=>q.stations.some(({role:s})=>s.role===r));h&&R(h.origin.role)},[v,R]),O=Te(),K=$.useCallback(r=>{const h=b.find(q=>q.role===r);h&&O(xe(h))},[b,O]),I=((Y=k.find(({role:r})=>r.role===l))==null?void 0:Y.role)??null,J=d||x,ee=async()=>{p(!0),await Promise.all([u(),y()]),p(!1)},T=r=>i(h=>h===r?null:r),te=e.jsx("div",{className:"flex items-center gap-0.5",children:et.map(r=>e.jsx("button",{onClick:()=>n(r),className:`px-2.5 py-1 text-[10px] font-mono rounded transition-colors ${t===r?"bg-accent/10 text-accent font-semibold":"text-text-quaternary hover:text-text-secondary"}`,children:r},r))});return e.jsxs("div",{className:"flex flex-col flex-1 min-h-0",children:[e.jsx(Le,{title:"Pace Board",docsHash:"#docs:dashboard.md:pace-board",center:te,actions:e.jsx("button",{onClick:ee,disabled:c,className:"text-text-quaternary hover:text-text-secondary transition-colors disabled:opacity-40",children:e.jsx(Fe,{className:`w-3.5 h-3.5 ${c?"animate-spin":""}`})})}),J?e.jsxs("div",{className:"animate-pulse space-y-6 mt-4",children:[e.jsx("div",{className:"h-8 bg-surface-sunken rounded w-64"}),e.jsx("div",{className:"h-64 bg-surface-sunken rounded w-full"}),e.jsx("div",{className:"space-y-3",children:[1,2,3].map(r=>e.jsx("div",{className:"h-8 bg-surface-sunken rounded w-full"},r))})]}):v.length===0?e.jsxs("div",{className:"mt-8",children:[e.jsx("p",{className:"text-sm text-text-secondary mb-2",children:"Stations appear here once roles are marked visible in Operations."}),e.jsxs("p",{className:"text-xs text-text-tertiary",children:["Go to"," ",e.jsx(M,{to:"/admin/roles",className:"text-accent hover:underline",children:"Roles"})," ","and enable ",e.jsx("strong",{children:"Visible in Operations"})," on roles that represent pipeline stations."]})]}):e.jsxs("div",{className:"flex flex-col flex-1 min-h-0",children:[v.length>1&&e.jsx("div",{className:"flex items-center gap-0.5 px-4 pt-2",children:v.map(r=>{const h=r.origin.role===(w==null?void 0:w.origin.role);return e.jsxs("button",{onClick:()=>R(r.origin.role),className:`px-2.5 py-1 text-[10px] font-mono rounded transition-colors ${h?"bg-accent/10 text-accent font-semibold":"text-text-quaternary hover:text-text-secondary"}`,children:[le(r.origin),e.jsx("span",{className:`ml-1.5 tabular-nums ${h?"text-accent/60":"text-text-quaternary/60"}`,children:r.stations.length})]},r.origin.role)})}),e.jsxs("div",{className:"flex-1 min-h-[40vh] flex items-stretch overflow-hidden",children:[e.jsx("div",{className:"flex-1 min-w-0 min-h-0 flex flex-col justify-center overflow-hidden p-4",children:e.jsx(Ge,{stations:V,selectedRole:l,onSelect:T,onUpstreamSelect:X,onPrioritySelect:K,periodHours:tt[t]})}),e.jsx("div",{className:"w-px bg-surface-border shrink-0 self-stretch"}),e.jsx(Je,{role:I,allMetrics:U,orderedRoles:k.map(r=>r.role),globalPeriod:t,onClose:()=>i(null)})]}),e.jsxs("div",{className:"max-h-[30vh] flex-none flex flex-col border-t border-surface-border overflow-hidden",children:[e.jsx(at,{}),e.jsx("div",{className:"flex-1 min-h-0 overflow-y-auto divide-y divide-surface-border/30",children:k.map(({role:r})=>e.jsx(nt,{role:r,metric:m.find(h=>h.role===r.role),selected:l===r.role,onClick:()=>T(r.role)},r.role))})]})]})]})}const ut=Object.freeze(Object.defineProperty({__proto__:null,OperationsPage:rt,buildFragments:Pe},Symbol.toStringTag,{value:"Module"}));export{ut as O,Ge as P,Pe as b,xe as p};
|
|
2
|
-
//# sourceMappingURL=OperationsPage-CQzX6jM1.js.map
|