@hotmeshio/long-tail 0.18.1 → 0.19.1
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/escalations/index.d.ts +1 -1
- package/build/api/escalations/index.js +2 -1
- package/build/api/escalations/list.d.ts +11 -0
- package/build/api/escalations/list.js +31 -2
- package/build/api/users.d.ts +11 -0
- package/build/api/users.js +19 -0
- package/build/api/workflows/config.d.ts +5 -1
- package/build/api/workflows/config.js +9 -1
- package/build/api/workflows/index.d.ts +3 -0
- package/build/api/workflows/index.js +7 -1
- package/build/api/workflows/input-validation.d.ts +13 -0
- package/build/api/workflows/input-validation.js +38 -0
- package/build/api/workflows/invocable.d.ts +19 -0
- package/build/api/workflows/invocable.js +106 -0
- package/build/api/workflows/invocation.js +6 -0
- package/build/lib/db/schemas/034_workflow_input_schema.sql +13 -0
- package/build/lib/uuid.d.ts +11 -0
- package/build/lib/uuid.js +20 -0
- package/build/routes/escalations/list.js +10 -1
- package/build/routes/users.js +9 -0
- package/build/routes/workflows/config.js +2 -0
- package/build/routes/workflows/discovery.js +14 -0
- package/build/scripts/ortho-populate.d.ts +3 -1
- package/build/scripts/ortho-populate.js +15 -5
- package/build/sdk/index.d.ts +1 -0
- package/build/services/config/cache.js +2 -0
- package/build/services/config/read.js +4 -0
- package/build/services/config/sql.d.ts +2 -2
- package/build/services/config/sql.js +7 -5
- package/build/services/config/write.js +11 -1
- package/build/services/escalation/batch.js +3 -0
- package/build/services/escalation/bulk.js +8 -0
- package/build/services/escalation/crud.js +26 -0
- package/build/services/escalation/queries.d.ts +14 -1
- package/build/services/escalation/queries.js +49 -7
- package/build/services/escalation/sql.d.ts +4 -2
- package/build/services/escalation/sql.js +4 -0
- package/build/services/interceptor/index.js +7 -0
- package/build/services/invocation-access.d.ts +18 -0
- package/build/services/invocation-access.js +32 -0
- package/build/services/role/types.d.ts +1 -1
- package/build/services/role/types.js +1 -1
- package/build/services/user/auth.js +2 -2
- package/build/services/user/crud.d.ts +13 -0
- package/build/services/user/crud.js +26 -3
- package/build/services/user/index.d.ts +1 -1
- package/build/services/user/index.js +2 -1
- package/build/services/user/sql.d.ts +11 -5
- package/build/services/user/sql.js +18 -6
- package/build/services/workflow-invocation.js +4 -9
- package/build/shared/form-validation/index.d.ts +1 -0
- package/build/shared/form-validation/index.js +1 -0
- package/build/shared/form-validation/invoke-context.d.ts +7 -0
- package/build/shared/form-validation/invoke-context.js +11 -0
- package/build/shared/form-validation/validate-resolver-payload.d.ts +1 -1
- package/build/shared/form-validation/validate-resolver-payload.js +1 -0
- package/build/shared/form-validation/x-lt-help.d.ts +2 -2
- package/build/shared/form-validation/x-lt-help.js +2 -2
- package/build/shared/form-validation/x-lt-show-if.d.ts +1 -0
- package/build/shared/form-validation/x-lt-show-if.js +3 -0
- package/build/start/workers.js +2 -0
- package/build/system/mcp-servers/admin/workflows.js +15 -2
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/config.d.ts +6 -0
- package/build/types/index.d.ts +2 -0
- package/build/types/index.js +4 -1
- package/build/types/startup.d.ts +10 -0
- package/build/types/validation.d.ts +4 -2
- package/build/types/workflow-icons.d.ts +86 -0
- package/build/types/workflow-icons.js +92 -0
- package/dashboard/dist/assets/{AdminDashboard-DDY8bceq.js → AdminDashboard-Drs-9TRM.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-DDY8bceq.js.map → AdminDashboard-Drs-9TRM.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-D47sHnup.js → AgentConfigPage-BDPDZ7-v.js} +3 -3
- package/dashboard/dist/assets/{AgentConfigPage-D47sHnup.js.map → AgentConfigPage-BDPDZ7-v.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-DwrfByA2.js → AgentDetailPage-CGBulM4_.js} +3 -3
- package/dashboard/dist/assets/{AgentDetailPage-DwrfByA2.js.map → AgentDetailPage-CGBulM4_.js.map} +1 -1
- package/dashboard/dist/assets/AgentsPage-D77JeViQ.js +2 -0
- package/dashboard/dist/assets/{AgentsPage-CLSjlyXy.js.map → AgentsPage-D77JeViQ.js.map} +1 -1
- package/dashboard/dist/assets/{AutoGrowTextarea-DgEQeRQw.js → AutoGrowTextarea-7X3T9La8.js} +2 -2
- package/dashboard/dist/assets/{AutoGrowTextarea-DgEQeRQw.js.map → AutoGrowTextarea-7X3T9La8.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-CqM_MOMy.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-CqM_MOMy.js.map +1 -0
- package/dashboard/dist/assets/{BotPicker-CbL7gQFq.js → BotPicker-CC5vI_Sv.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-CbL7gQFq.js.map → BotPicker-CC5vI_Sv.js.map} +1 -1
- package/dashboard/dist/assets/BulkAssignModal-BXiJnlqt.js +2 -0
- package/dashboard/dist/assets/BulkAssignModal-BXiJnlqt.js.map +1 -0
- package/dashboard/dist/assets/{CapabilitiesPage-Q9Pe0y_p.js → CapabilitiesPage-D9TC2iKy.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-Q9Pe0y_p.js.map → CapabilitiesPage-D9TC2iKy.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-BZOtaWPR.js → CollapsibleSection-D10lGw_u.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-BZOtaWPR.js.map → CollapsibleSection-D10lGw_u.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-6CidwpPx.js → ConfirmDeleteModal-BJdLN6No.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-6CidwpPx.js.map → ConfirmDeleteModal-BJdLN6No.js.map} +1 -1
- package/dashboard/dist/assets/{CopyableId-4Lqlc5cU.js → CopyableId-Bn02zYxt.js} +2 -2
- package/dashboard/dist/assets/{CopyableId-4Lqlc5cU.js.map → CopyableId-Bn02zYxt.js.map} +1 -1
- package/dashboard/dist/assets/CountdownTimer-D9B-BjQ7.js +2 -0
- package/dashboard/dist/assets/CountdownTimer-D9B-BjQ7.js.map +1 -0
- package/dashboard/dist/assets/{CredentialsPage-dxjrUEyO.js → CredentialsPage-hniUAFBK.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-dxjrUEyO.js.map → CredentialsPage-hniUAFBK.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-D8oo8eaA.js → CronLabel-v9DCD2FX.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-D8oo8eaA.js.map → CronLabel-v9DCD2FX.js.map} +1 -1
- package/dashboard/dist/assets/{DataTable-DFPMeqyQ.js → DataTable-7C7riavf.js} +2 -2
- package/dashboard/dist/assets/{DataTable-DFPMeqyQ.js.map → DataTable-7C7riavf.js.map} +1 -1
- package/dashboard/dist/assets/{DropZone-CWCh5ItZ.js → DropZone-XlcY8hEH.js} +2 -2
- package/dashboard/dist/assets/{DropZone-CWCh5ItZ.js.map → DropZone-XlcY8hEH.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-FHHQ69G3.js → ElapsedCell-_xvVTK8N.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-FHHQ69G3.js.map → ElapsedCell-_xvVTK8N.js.map} +1 -1
- package/dashboard/dist/assets/{EmptyState-lpUFYfun.js → EmptyState-DgC_6njU.js} +2 -2
- package/dashboard/dist/assets/{EmptyState-lpUFYfun.js.map → EmptyState-DgC_6njU.js.map} +1 -1
- package/dashboard/dist/assets/EntityTimelinePanel-1lT3jkCM.js +2 -0
- package/dashboard/dist/assets/EntityTimelinePanel-1lT3jkCM.js.map +1 -0
- package/dashboard/dist/assets/{EscalationListSchemaPage-D5L5lDNb.js → EscalationListSchemaPage-BeQUTUEO.js} +3 -3
- package/dashboard/dist/assets/{EscalationListSchemaPage-D5L5lDNb.js.map → EscalationListSchemaPage-BeQUTUEO.js.map} +1 -1
- package/dashboard/dist/assets/EscalationListView-uuZRMSLB.js +2 -0
- package/dashboard/dist/assets/EscalationListView-uuZRMSLB.js.map +1 -0
- package/dashboard/dist/assets/{EscalationSchemaPage-bYbfEpSB.js → EscalationSchemaPage-D4VlEwyS.js} +3 -3
- package/dashboard/dist/assets/{EscalationSchemaPage-bYbfEpSB.js.map → EscalationSchemaPage-D4VlEwyS.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-DjtIjL1b.js → EscalationsOverview-Bx6Zrzm-.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-DjtIjL1b.js.map → EscalationsOverview-Bx6Zrzm-.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-CihVTREC.js → EventTable-KEC3YWBf.js} +2 -2
- package/dashboard/dist/assets/{EventTable-CihVTREC.js.map → EventTable-KEC3YWBf.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-Fin1IqHc.js → FilterBar-xwN_b5fj.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-Fin1IqHc.js.map → FilterBar-xwN_b5fj.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-D77ILPd3.js → GraphInvokePage-DV7Y0fe2.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-D77ILPd3.js.map → GraphInvokePage-DV7Y0fe2.js.map} +1 -1
- package/dashboard/dist/assets/HomePage-G785SWcW.js +2 -0
- package/dashboard/dist/assets/HomePage-G785SWcW.js.map +1 -0
- package/dashboard/dist/assets/ListToolbar-zPVYPg3W.js +2 -0
- package/dashboard/dist/assets/{ListToolbar-DyHaJBTk.js.map → ListToolbar-zPVYPg3W.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-qz7Ivf0G.js → McpOverview-CMGUq8hx.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-qz7Ivf0G.js.map → McpOverview-CMGUq8hx.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-D6MB4CZM.js → McpQueryDetailPage-CdhLhaKn.js} +3 -3
- package/dashboard/dist/assets/{McpQueryDetailPage-D6MB4CZM.js.map → McpQueryDetailPage-CdhLhaKn.js.map} +1 -1
- package/dashboard/dist/assets/McpQueryPage-CNSNMagY.js +2 -0
- package/dashboard/dist/assets/{McpQueryPage-BqqRF5cQ.js.map → McpQueryPage-CNSNMagY.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-DxLEhzhn.js → McpRunDetailPage-DBm8hUaW.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-DxLEhzhn.js.map → McpRunDetailPage-DBm8hUaW.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-BOsS4Hdf.js → McpRunsPage-B6rb5QBf.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-BOsS4Hdf.js.map → McpRunsPage-B6rb5QBf.js.map} +1 -1
- package/dashboard/dist/assets/NamespacePill-Bb3revqD.js +2 -0
- package/dashboard/dist/assets/{NamespacePill-CJikgGzE.js.map → NamespacePill-Bb3revqD.js.map} +1 -1
- package/dashboard/dist/assets/OperationsPage-Dxk1fAMg.js +3 -0
- package/dashboard/dist/assets/OperationsPage-Dxk1fAMg.js.map +1 -0
- package/dashboard/dist/assets/OperatorDashboard-DBOscDnf.js +2 -0
- package/dashboard/dist/assets/{OperatorDashboard-C5rlijvh.js.map → OperatorDashboard-DBOscDnf.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-DZmymFBS.js → PageHeader-Di5Sz3an.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-DZmymFBS.js.map → PageHeader-Di5Sz3an.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-DuAm6YK2.js → PageHeaderWithStats-DutKJ-h2.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-DuAm6YK2.js.map → PageHeaderWithStats-DutKJ-h2.js.map} +1 -1
- package/dashboard/dist/assets/{PersonaDetailPage-JBdVvT5g.js → PersonaDetailPage-BGRdGpeR.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage-JBdVvT5g.js.map → PersonaDetailPage-BGRdGpeR.js.map} +1 -1
- package/dashboard/dist/assets/PersonasPage-DRzOZcVa.js +2 -0
- package/dashboard/dist/assets/PersonasPage-DRzOZcVa.js.map +1 -0
- package/dashboard/dist/assets/{PriorityBadge-BETdj4M-.js → PriorityBadge-r33mpDju.js} +2 -2
- package/dashboard/dist/assets/{PriorityBadge-BETdj4M-.js.map → PriorityBadge-r33mpDju.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-CHnzOzQn.js → ProcessDetailPage-BLGjZXpM.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-CHnzOzQn.js.map → ProcessDetailPage-BLGjZXpM.js.map} +1 -1
- package/dashboard/dist/assets/ProcessesListPage-5NnysKFC.js +2 -0
- package/dashboard/dist/assets/{ProcessesListPage-DuXTS5-v.js.map → ProcessesListPage-5NnysKFC.js.map} +1 -1
- package/dashboard/dist/assets/ResolverForm-Dy0yirtP.js +2 -0
- package/dashboard/dist/assets/ResolverForm-Dy0yirtP.js.map +1 -0
- package/dashboard/dist/assets/RoleDetailPage-C_LIoe1j.js +8 -0
- package/dashboard/dist/assets/RoleDetailPage-C_LIoe1j.js.map +1 -0
- package/dashboard/dist/assets/{RolePill-C9LSs1aK.js → RolePill-DhnVPK4q.js} +2 -2
- package/dashboard/dist/assets/{RolePill-C9LSs1aK.js.map → RolePill-DhnVPK4q.js.map} +1 -1
- package/dashboard/dist/assets/RolesPage-BmW1LzkU.js +2 -0
- package/dashboard/dist/assets/{RolesPage-h77-JOLd.js.map → RolesPage-BmW1LzkU.js.map} +1 -1
- package/dashboard/dist/assets/{RowActions-eYrzgQSj.js → RowActions-Bdd7z4eB.js} +2 -2
- package/dashboard/dist/assets/{RowActions-eYrzgQSj.js.map → RowActions-Bdd7z4eB.js.map} +1 -1
- package/dashboard/dist/assets/RunAsSelector-BwZTJ4Yj.js +2 -0
- package/dashboard/dist/assets/{RunAsSelector-DoLFJ0mZ.js.map → RunAsSelector-BwZTJ4Yj.js.map} +1 -1
- package/dashboard/dist/assets/ScanCodesPage-FiYIYB-m.js +2 -0
- package/dashboard/dist/assets/{ScanCodesPage-b5NZM_-f.js.map → ScanCodesPage-FiYIYB-m.js.map} +1 -1
- package/dashboard/dist/assets/{ScanSchemeDetailPage-t7X6ekaW.js → ScanSchemeDetailPage-BiAqtD-a.js} +2 -2
- package/dashboard/dist/assets/{ScanSchemeDetailPage-t7X6ekaW.js.map → ScanSchemeDetailPage-BiAqtD-a.js.map} +1 -1
- package/dashboard/dist/assets/ScanStationPage-8CdOtbCD.js +2 -0
- package/dashboard/dist/assets/{ScanStationPage-r02hkTAG.js.map → ScanStationPage-8CdOtbCD.js.map} +1 -1
- package/dashboard/dist/assets/{ScopeBadge-CjyC7iyO.js → ScopeBadge-CXUg0FHo.js} +2 -2
- package/dashboard/dist/assets/{ScopeBadge-CjyC7iyO.js.map → ScopeBadge-CXUg0FHo.js.map} +1 -1
- package/dashboard/dist/assets/{SegmentedTabs-DXNzY05q.js → SegmentedTabs-BpJh4Hwn.js} +2 -2
- package/dashboard/dist/assets/{SegmentedTabs-DXNzY05q.js.map → SegmentedTabs-BpJh4Hwn.js.map} +1 -1
- package/dashboard/dist/assets/{StatCard-BXQ8dD9Y.js → StatCard-nWY4sndl.js} +2 -2
- package/dashboard/dist/assets/{StatCard-BXQ8dD9Y.js.map → StatCard-nWY4sndl.js.map} +1 -1
- package/dashboard/dist/assets/{StatusBadge-BDeUwPtb.js → StatusBadge-DHVwxre2.js} +2 -2
- package/dashboard/dist/assets/{StatusBadge-BDeUwPtb.js.map → StatusBadge-DHVwxre2.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-BGHQbp0_.js → StickyPagination-DRuqKhZt.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-BGHQbp0_.js.map → StickyPagination-DRuqKhZt.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-C-wfdbLJ.js → StreamMessageDetail-JwlbRiMn.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-C-wfdbLJ.js.map → StreamMessageDetail-JwlbRiMn.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-Dnoz-me3.js → SwimlaneTimeline-hu3c4bCJ.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-Dnoz-me3.js.map → SwimlaneTimeline-hu3c4bCJ.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-D-vLSMQC.js → TagInput-BZ8vb2oW.js} +2 -2
- package/dashboard/dist/assets/{TagInput-D-vLSMQC.js.map → TagInput-BZ8vb2oW.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-c9IiAhVJ.js → TaskDetailPage-NqVZF3jW.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-c9IiAhVJ.js.map → TaskDetailPage-NqVZF3jW.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-sFRMrQ5D.js → TaskQueuePill-Bxir8WRl.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-sFRMrQ5D.js.map → TaskQueuePill-Bxir8WRl.js.map} +1 -1
- package/dashboard/dist/assets/TasksListPage-BQNaSzCn.js +2 -0
- package/dashboard/dist/assets/{TasksListPage-Dor8LSc5.js.map → TasksListPage-BQNaSzCn.js.map} +1 -1
- package/dashboard/dist/assets/TimeAgo-Cv35DOiI.js +2 -0
- package/dashboard/dist/assets/{TimeAgo-Dd8vmRnM.js.map → TimeAgo-Cv35DOiI.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-qJfC6-iT.js → TimestampCell-DHUXey9s.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-qJfC6-iT.js.map → TimestampCell-DHUXey9s.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-OQ3mC11d.js → ToolPill-FkgTXIhq.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-OQ3mC11d.js.map → ToolPill-FkgTXIhq.js.map} +1 -1
- package/dashboard/dist/assets/ToolTestPanel-DvuLFWqQ.js +2 -0
- package/dashboard/dist/assets/{ToolTestPanel-CEGY5jss.js.map → ToolTestPanel-DvuLFWqQ.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-SI80ZTVv.js → TopicDetailPage-TXX3QNSo.js} +3 -3
- package/dashboard/dist/assets/{TopicDetailPage-SI80ZTVv.js.map → TopicDetailPage-TXX3QNSo.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-DiVB8tNr.js → TopicsPage-h-oyTeEJ.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-DiVB8tNr.js.map → TopicsPage-h-oyTeEJ.js.map} +1 -1
- package/dashboard/dist/assets/UserName-BceRCeDF.js +2 -0
- package/dashboard/dist/assets/UserName-BceRCeDF.js.map +1 -0
- package/dashboard/dist/assets/WorkflowExecutionPage-CmHGcaN9.js +2 -0
- package/dashboard/dist/assets/{WorkflowExecutionPage-e-Q57yiJ.js.map → WorkflowExecutionPage-CmHGcaN9.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowPill-Dh3hIW1l.js → WorkflowPill--AYMW7u_.js} +2 -2
- package/dashboard/dist/assets/WorkflowPill--AYMW7u_.js.map +1 -0
- package/dashboard/dist/assets/WorkflowsDashboard-B0r2lQXk.js +2 -0
- package/dashboard/dist/assets/{WorkflowsDashboard-DLKzN80h.js.map → WorkflowsDashboard-B0r2lQXk.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowsOverview-BTMc2PJ_.js +2 -0
- package/dashboard/dist/assets/{WorkflowsOverview-J-ITQiO5.js.map → WorkflowsOverview-BTMc2PJ_.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-B_-ahhf1.js → YamlWorkflowDetailPage-DUiCVnZp.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-B_-ahhf1.js.map → YamlWorkflowDetailPage-DUiCVnZp.js.map} +1 -1
- package/dashboard/dist/assets/YamlWorkflowsPage-BAuXfwi0.js +2 -0
- package/dashboard/dist/assets/{YamlWorkflowsPage-DQNeERXU.js.map → YamlWorkflowsPage-BAuXfwi0.js.map} +1 -1
- package/dashboard/dist/assets/{agents-BsJ-MizQ.js → agents-BvmLCk4h.js} +2 -2
- package/dashboard/dist/assets/{agents-BsJ-MizQ.js.map → agents-BvmLCk4h.js.map} +1 -1
- package/dashboard/dist/assets/{bots-q1UYqaIh.js → bots-f_tyhl4I.js} +2 -2
- package/dashboard/dist/assets/{bots-q1UYqaIh.js.map → bots-f_tyhl4I.js.map} +1 -1
- package/dashboard/dist/assets/capabilities-DNo5bqLx.js +2 -0
- package/dashboard/dist/assets/{capabilities-BvjPXUcJ.js.map → capabilities-DNo5bqLx.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-BwlNpoJ_.js → controlplane-Dyyj2Irb.js} +2 -2
- package/dashboard/dist/assets/{controlplane-BwlNpoJ_.js.map → controlplane-Dyyj2Irb.js.map} +1 -1
- package/dashboard/dist/assets/escalation-columns-DIigeTOK.js +2 -0
- package/dashboard/dist/assets/escalation-columns-DIigeTOK.js.map +1 -0
- package/dashboard/dist/assets/index-BMlQYOE1.js +67 -0
- package/dashboard/dist/assets/index-BMlQYOE1.js.map +1 -0
- package/dashboard/dist/assets/index-BNZknxFY.js +2 -0
- package/dashboard/dist/assets/{index-cvmt1plS.js.map → index-BNZknxFY.js.map} +1 -1
- package/dashboard/dist/assets/index-Bpvfr4OW.css +1 -0
- package/dashboard/dist/assets/{index-CldVY0UQ.js → index-C-Xr2V3F.js} +2 -2
- package/dashboard/dist/assets/{index-CldVY0UQ.js.map → index-C-Xr2V3F.js.map} +1 -1
- package/dashboard/dist/assets/index-CegPUKpc.js +3 -0
- package/dashboard/dist/assets/index-CegPUKpc.js.map +1 -0
- package/dashboard/dist/assets/{index-O9uuK2yO.js → index-CsKiRyhy.js} +2 -2
- package/dashboard/dist/assets/{index-O9uuK2yO.js.map → index-CsKiRyhy.js.map} +1 -1
- package/dashboard/dist/assets/index-D7ESqn22.js +2 -0
- package/dashboard/dist/assets/{index-BhzsR_gZ.js.map → index-D7ESqn22.js.map} +1 -1
- package/dashboard/dist/assets/{index-Hbbox1A4.js → index-DL83W7Gu.js} +2 -2
- package/dashboard/dist/assets/{index-Hbbox1A4.js.map → index-DL83W7Gu.js.map} +1 -1
- package/dashboard/dist/assets/index-DPLssnMW.js +6 -0
- package/dashboard/dist/assets/index-DPLssnMW.js.map +1 -0
- package/dashboard/dist/assets/{index-DsKqDMs4.js → index-DWse7ERF.js} +2 -2
- package/dashboard/dist/assets/{index-DsKqDMs4.js.map → index-DWse7ERF.js.map} +1 -1
- package/dashboard/dist/assets/index-DoETPlJP.js +11 -0
- package/dashboard/dist/assets/index-DoETPlJP.js.map +1 -0
- package/dashboard/dist/assets/{index-8Gmtvd8e.js → index-DvxxrFBo.js} +2 -2
- package/dashboard/dist/assets/{index-8Gmtvd8e.js.map → index-DvxxrFBo.js.map} +1 -1
- package/dashboard/dist/assets/{index-DDHoDZRg.js → index-PcyGjmBm.js} +2 -2
- package/dashboard/dist/assets/{index-DDHoDZRg.js.map → index-PcyGjmBm.js.map} +1 -1
- package/dashboard/dist/assets/{index-BvGIyZUt.js → index-e2X-s0EQ.js} +2 -2
- package/dashboard/dist/assets/{index-BvGIyZUt.js.map → index-e2X-s0EQ.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-DM0tNphj.js → knowledge-Coo6CKzo.js} +2 -2
- package/dashboard/dist/assets/{knowledge-DM0tNphj.js.map → knowledge-Coo6CKzo.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-CQ_TD2P9.js → mcp-Cz5eFnP_.js} +2 -2
- package/dashboard/dist/assets/{mcp-CQ_TD2P9.js.map → mcp-Cz5eFnP_.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-BP7KSGhc.js → mcp-query-BtnuO4LF.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-BP7KSGhc.js.map → mcp-query-BtnuO4LF.js.map} +1 -1
- package/dashboard/dist/assets/{personas-DclHdHKK.js → personas-C2-LgpHQ.js} +2 -2
- package/dashboard/dist/assets/{personas-DclHdHKK.js.map → personas-C2-LgpHQ.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-LwuKJfj-.js → pipelines-TuXQvUA-.js} +2 -2
- package/dashboard/dist/assets/{pipelines-LwuKJfj-.js.map → pipelines-TuXQvUA-.js.map} +1 -1
- package/dashboard/dist/assets/resolver-payload-C1dXB3n6.js +2 -0
- package/dashboard/dist/assets/resolver-payload-C1dXB3n6.js.map +1 -0
- package/dashboard/dist/assets/seed-form-json-DvPsISxD.js +2 -0
- package/dashboard/dist/assets/seed-form-json-DvPsISxD.js.map +1 -0
- package/dashboard/dist/assets/{tasks-CDs-Li2v.js → tasks-OUzpu__z.js} +2 -2
- package/dashboard/dist/assets/{tasks-CDs-Li2v.js.map → tasks-OUzpu__z.js.map} +1 -1
- package/dashboard/dist/assets/{topics-BeOSelBX.js → topics-B8bdrBaW.js} +2 -2
- package/dashboard/dist/assets/{topics-BeOSelBX.js.map → topics-B8bdrBaW.js.map} +1 -1
- package/dashboard/dist/assets/useDebouncedValue-Cp5ZOtVE.js +2 -0
- package/dashboard/dist/assets/{useDebouncedValue-DhhAKjDC.js.map → useDebouncedValue-Cp5ZOtVE.js.map} +1 -1
- package/dashboard/dist/assets/{useFilterParams-crmlBw_l.js → useFilterParams-DBRw1Hcv.js} +2 -2
- package/dashboard/dist/assets/{useFilterParams-crmlBw_l.js.map → useFilterParams-DBRw1Hcv.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-C-E2gNEK.js → useNamespace-DtQe3wZ5.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-C-E2gNEK.js.map → useNamespace-DtQe3wZ5.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-CmLzX3YU.js → useYamlActivityEvents-CS22c15X.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-CmLzX3YU.js.map → useYamlActivityEvents-CS22c15X.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-R9b9gQ04.js → vendor-icons-DeBdvyKJ.js} +368 -143
- package/dashboard/dist/assets/vendor-icons-DeBdvyKJ.js.map +1 -0
- package/dashboard/dist/assets/vendor-query-DvWWuNIB.js +18 -0
- package/dashboard/dist/assets/vendor-query-DvWWuNIB.js.map +1 -0
- package/dashboard/dist/assets/{vendor-react-CdqEC2zv.js → vendor-react-_9U4mKFr.js} +2 -2
- package/dashboard/dist/assets/{vendor-react-CdqEC2zv.js.map → vendor-react-_9U4mKFr.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-BgAsc6-I.js → yaml-workflows-HQIki3hI.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-BgAsc6-I.js.map → yaml-workflows-HQIki3hI.js.map} +1 -1
- package/dashboard/dist/index.html +5 -5
- package/docs/api/http/workflows.md +25 -1
- package/docs/code-owned-configuration.md +1 -1
- package/docs/dashboard.md +179 -80
- package/docs/events.md +3 -1
- package/docs/faceted-routing.md +5 -1
- package/docs/hitl/iframe.md +35 -6
- package/docs/hitl/invoke-form.md +98 -0
- package/docs/hitl/x-lt-list-schema.md +3 -0
- package/docs/hitl/x-lt-show-if.md +11 -0
- package/docs/hitl-guide.md +4 -2
- package/docs/iam.md +1 -1
- package/docs/operations.md +61 -60
- package/docs/scan-codes.md +30 -3
- package/docs/workflows.md +1 -1
- package/package.json +1 -1
- package/dashboard/dist/assets/AgentsPage-CLSjlyXy.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-D2ukvuQh.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-D2ukvuQh.js.map +0 -1
- package/dashboard/dist/assets/BulkAssignModal-CMSgvHIs.js +0 -2
- package/dashboard/dist/assets/BulkAssignModal-CMSgvHIs.js.map +0 -1
- package/dashboard/dist/assets/CountdownTimer-B5lM7PfE.js +0 -2
- package/dashboard/dist/assets/CountdownTimer-B5lM7PfE.js.map +0 -1
- package/dashboard/dist/assets/EntityTimelinePanel-B5NuHnPF.js +0 -2
- package/dashboard/dist/assets/EntityTimelinePanel-B5NuHnPF.js.map +0 -1
- package/dashboard/dist/assets/HomePage-8XsQFqKL.js +0 -2
- package/dashboard/dist/assets/HomePage-8XsQFqKL.js.map +0 -1
- package/dashboard/dist/assets/ListToolbar-DyHaJBTk.js +0 -2
- package/dashboard/dist/assets/McpQueryPage-BqqRF5cQ.js +0 -2
- package/dashboard/dist/assets/NamespacePill-CJikgGzE.js +0 -2
- package/dashboard/dist/assets/OperationsPage-Cj1mJLMC.js +0 -3
- package/dashboard/dist/assets/OperationsPage-Cj1mJLMC.js.map +0 -1
- package/dashboard/dist/assets/OperatorDashboard-C5rlijvh.js +0 -2
- package/dashboard/dist/assets/PersonasPage-Xp_Gt6El.js +0 -2
- package/dashboard/dist/assets/PersonasPage-Xp_Gt6El.js.map +0 -1
- package/dashboard/dist/assets/ProcessesListPage-DuXTS5-v.js +0 -2
- package/dashboard/dist/assets/RoleDetailPage-C9GGHNf4.js +0 -8
- package/dashboard/dist/assets/RoleDetailPage-C9GGHNf4.js.map +0 -1
- package/dashboard/dist/assets/RolesPage-h77-JOLd.js +0 -2
- package/dashboard/dist/assets/RunAsSelector-DoLFJ0mZ.js +0 -2
- package/dashboard/dist/assets/ScanCodesPage-b5NZM_-f.js +0 -2
- package/dashboard/dist/assets/ScanStationPage-r02hkTAG.js +0 -2
- package/dashboard/dist/assets/TasksListPage-Dor8LSc5.js +0 -2
- package/dashboard/dist/assets/TimeAgo-Dd8vmRnM.js +0 -2
- package/dashboard/dist/assets/ToolTestPanel-CEGY5jss.js +0 -2
- package/dashboard/dist/assets/UserName-Dmm456xT.js +0 -2
- package/dashboard/dist/assets/UserName-Dmm456xT.js.map +0 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-e-Q57yiJ.js +0 -2
- package/dashboard/dist/assets/WorkflowPill-Dh3hIW1l.js.map +0 -1
- package/dashboard/dist/assets/WorkflowsDashboard-DLKzN80h.js +0 -2
- package/dashboard/dist/assets/WorkflowsOverview-J-ITQiO5.js +0 -2
- package/dashboard/dist/assets/YamlWorkflowsPage-DQNeERXU.js +0 -2
- package/dashboard/dist/assets/capabilities-BvjPXUcJ.js +0 -2
- package/dashboard/dist/assets/escalation-columns-Bo3PfIZj.js +0 -2
- package/dashboard/dist/assets/escalation-columns-Bo3PfIZj.js.map +0 -1
- package/dashboard/dist/assets/index-B8JfGtQB.js +0 -3
- package/dashboard/dist/assets/index-B8JfGtQB.js.map +0 -1
- package/dashboard/dist/assets/index-Bb9ZZUyB.js +0 -5
- package/dashboard/dist/assets/index-Bb9ZZUyB.js.map +0 -1
- package/dashboard/dist/assets/index-BhzsR_gZ.js +0 -2
- package/dashboard/dist/assets/index-D88VWEVp.js +0 -67
- package/dashboard/dist/assets/index-D88VWEVp.js.map +0 -1
- package/dashboard/dist/assets/index-DBvkaa-B.js +0 -6
- package/dashboard/dist/assets/index-DBvkaa-B.js.map +0 -1
- package/dashboard/dist/assets/index-cvmt1plS.js +0 -2
- package/dashboard/dist/assets/index-qU_dXqP4.css +0 -1
- package/dashboard/dist/assets/useDebouncedValue-DhhAKjDC.js +0 -2
- package/dashboard/dist/assets/vendor-icons-R9b9gQ04.js.map +0 -1
- package/dashboard/dist/assets/vendor-query-RUZdMvN6.js +0 -18
- package/dashboard/dist/assets/vendor-query-RUZdMvN6.js.map +0 -1
- package/dashboard/dist/assets/workflows-CYv1CTU0.js +0 -2
- package/dashboard/dist/assets/workflows-CYv1CTU0.js.map +0 -1
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Invoke Forms
|
|
2
|
+
|
|
3
|
+
A workflow's invoke form can be the same rich, versioned form the escalation surfaces use. Declare `inputSchema` on the worker config and the Invoke Tool page renders it with the full [x-lt-* vocabulary](../hitl-guide.md#full-vocabulary-quick-reference): two-column layout, sections, column groups, conditional display, instruction blocks, dynamic options, and a help panel. The submitted `data` is the x-lt-bind mapped payload, and the invoke API validates it against the same schema with the same shared pass, so a payload the form accepts is accepted by the API, and a rejection lists the exact violations the form shows.
|
|
4
|
+
|
|
5
|
+
Without `inputSchema`, the page renders the envelope template form from `envelopeSchema` exactly as before. Nothing changes for existing deployments until a workflow opts in.
|
|
6
|
+
|
|
7
|
+
## Declaring the form
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
const fleetToolsConfig: LTWorkerConfig = {
|
|
11
|
+
description: '**Fleet tools** — one form, four tools for one machine.',
|
|
12
|
+
invocable: true,
|
|
13
|
+
invocationRoles: ['printer-fleet', 'print-servicer'],
|
|
14
|
+
envelopeSchema: { data: {}, metadata: { source: 'dashboard' } },
|
|
15
|
+
inputSchema: FLEET_TOOLS_INPUT_SCHEMA,
|
|
16
|
+
icon: WORKFLOW_ICONS.WRENCH,
|
|
17
|
+
};
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Workflow names read as titles on the page: `fleetTools` shows as **Fleet Tools**, and queue names the same way, with the identifiers kept as metadata beside them.
|
|
21
|
+
|
|
22
|
+
| Field | Role in the invoke |
|
|
23
|
+
|---|---|
|
|
24
|
+
| `inputSchema` | The form. JSON Schema `properties` plus x-lt-* tokens. Rendered by the Invoke Tool page; enforced by the invoke API. |
|
|
25
|
+
| `envelopeSchema.metadata` | The `metadata` stamped on every run from this form. `envelopeSchema.data` is ignored when `inputSchema` is present. |
|
|
26
|
+
| `invocationRoles` | Who sees the workflow on the Invoke Tool page and who may start it. Empty means every authenticated user. |
|
|
27
|
+
| `description` | One line at the top of the form column, markdown allowed. Keep the reference material in `x-lt-help`, which appears in the side panel on demand. |
|
|
28
|
+
| `icon` | A curated icon from `WORKFLOW_ICONS` (`icon: WORKFLOW_ICONS.WRENCH`). Leads the workflow's row and heading in place of the tier glyph so operators tell tools apart at a glance. The registry offers the same set as a picker. |
|
|
29
|
+
|
|
30
|
+
The registry detail page edits the same schema under **Input Form** in its Invocation column, beside a live preview of the form, and the registration wizard offers the field for new entries. The reference is [`examples/workflows/fleet-tools/forms.ts`](../../examples/workflows/fleet-tools/forms.ts): a `serialNumber` and an `action` decision, then one section per action that appears only when that action is chosen, each carrying its own knobs and its own instruction block.
|
|
31
|
+
|
|
32
|
+
## Form values, payload, and domains
|
|
33
|
+
|
|
34
|
+
The form edits flat values keyed by property name. On submit, `x-lt-bind` maps them into the nested `data` the workflow receives:
|
|
35
|
+
|
|
36
|
+
```jsonc
|
|
37
|
+
// properties
|
|
38
|
+
"serialNumber": { "x-lt-bind": "printer.serialNumber" },
|
|
39
|
+
"action": { "x-lt-bind": "tool.action" },
|
|
40
|
+
"copies": { "x-lt-bind": "tool.details.copies", "x-lt-showIf": "input.action=reprint-label" }
|
|
41
|
+
|
|
42
|
+
// POST /api/workflows/fleetTools/invoke
|
|
43
|
+
{ "data": { "printer": { "serialNumber": "printer-07" }, "tool": { "action": "reprint-label", "details": { "copies": 2 } } },
|
|
44
|
+
"metadata": { "source": "dashboard" } }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Conditions and help tokens read the live form under the `input` domain: `x-lt-showIf: "input.action=retire"`, `{{input.serialNumber}}`. `resolver` names the same values, so a schema written for an escalation form works unchanged. The only other domain an invoke form can read is `metadata`, the envelope metadata declared above.
|
|
48
|
+
|
|
49
|
+
Hidden conditional fields still submit their defaults, as on every x-lt-* form. Treat empty as absent in the workflow.
|
|
50
|
+
|
|
51
|
+
## Conditional instructions
|
|
52
|
+
|
|
53
|
+
An instruction is a read-only markdown field. Give it the same `x-lt-showIf` as the knobs it explains and it arrives with them:
|
|
54
|
+
|
|
55
|
+
```jsonc
|
|
56
|
+
"powerCycleFirst": {
|
|
57
|
+
"type": "string",
|
|
58
|
+
"x-lt-widget": "markdown",
|
|
59
|
+
"readOnly": true,
|
|
60
|
+
"default": "**Power cycle first.** Most stalls clear on a restart.",
|
|
61
|
+
"x-lt-section": "Report the machine offline",
|
|
62
|
+
"x-lt-showIf": ["input.action=report-offline", "!input.powerCycled"]
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
An array of conditions requires every one, so the prompt belongs to its tool and still reacts to the checkbox.
|
|
67
|
+
|
|
68
|
+
`x-lt-help` on the schema root is the longer reference for the side panel: markdown, tables, and `{{input.*}}` tokens that re-interpolate as the operator types.
|
|
69
|
+
|
|
70
|
+
## The Invoke Tool page
|
|
71
|
+
|
|
72
|
+
The page is open to anyone the server lists an invokable workflow for. Builders reach **Invoke Tool** under Orchestrate; every other persona gets a **Tools** section in the nav that appears only when there is something to invoke. Each invokable workflow is a tool; the list sits on the left, grouped by task queue, with the first workflow preselected; the form takes the rest of the row. Below 1280px the list folds into a select and the form takes the full width.
|
|
73
|
+
|
|
74
|
+
The form's side panel carries two views: **Instructions**, the interpolated `x-lt-help`, and **Issues**, the current violations, each click focusing its field. A server rejection lands in the same Issues view.
|
|
75
|
+
|
|
76
|
+
Once a run starts, the page subscribes to `system.workflow.{workflowId}.completed` and `.failed` for that id. The outcome and the workflow's returned `data` render beside Submit, so a tool's answer comes back to the person who asked for it. Submit disarms after one click until the person chooses to submit again, and a warning offers to reconnect live events when they are off.
|
|
77
|
+
|
|
78
|
+
## The server contract
|
|
79
|
+
|
|
80
|
+
`POST /api/workflows/:type/invoke` validates `data` against `input_schema` after the role check and before anything starts. A rejection is the canonical 422 body used by every schema gate:
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"error": "data failed input schema validation (2 violations)",
|
|
85
|
+
"code": "schema_validation",
|
|
86
|
+
"violations": [
|
|
87
|
+
{ "field": "serialNumber", "message": "Required" },
|
|
88
|
+
{ "field": "action", "message": "Required" }
|
|
89
|
+
],
|
|
90
|
+
"role": null,
|
|
91
|
+
"schemaVersion": null,
|
|
92
|
+
"workflowType": "fleetTools"
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The MCP tools `invoke_workflow` and `invoke_workflow_read_safe` run the same gate and return the body as an error result. The gate reads bound paths from the nested `data`, skips fields a `x-lt-showIf` hides, and applies every validation keyword the form applies.
|
|
97
|
+
|
|
98
|
+
`GET /api/workflows/invocable` returns the caller's invokable workflows with their tier. The list and the gate share one predicate, so the page never offers a workflow the API would refuse.
|
|
@@ -23,6 +23,8 @@ Every string is a markdown/text template run through the same `{{domain.path}}`
|
|
|
23
23
|
|
|
24
24
|
`format: "age"` on a `facet-table` column or `facet-board` field renders a timestamp as a compact age (`12m`, `3h`, `2d`) with the absolute time as its tooltip, repainted each minute — aging interim states are scannable at a glance.
|
|
25
25
|
|
|
26
|
+
`format: "user"` resolves a user-id token — `{{escalation.assigned_to}}` — to that person's display name. Resolution is batched: every id on a page is coalesced into one `POST /api/users/names` request returning display fields only (no secrets, scopes, or metadata), cached by id for the session and not refetched on window focus; a user edit invalidates the cache. It truncates with an ellipsis and carries the full name on hover; an unassigned row shows a quiet em dash. `assigned_to` is the claimant while the item is worked and stays as the resolver once it is resolved, so one column reads correctly across the row's whole life. The built-in table and timeline views carry this user column by default; authored templates opt in per column.
|
|
27
|
+
|
|
26
28
|
The **active** item is the first non-terminal escalation. The **history** column is lazy-loaded — a "Load full history" link fetches resolved items on demand (`status` defaults to `"resolved"`, `limit` to 25). Unknown or absent `x-lt-layout` is a safe no-op that falls back to the table.
|
|
27
29
|
|
|
28
30
|
### Row action (`x-lt-row-action`)
|
|
@@ -94,6 +96,7 @@ Use when the queue contains many concurrent rows and the role's context is best
|
|
|
94
96
|
{ "label": "Heel cup", "value": "{{metadata.heelCup}}" },
|
|
95
97
|
{ "label": "PDAC", "value": "{{metadata.pdac}}" },
|
|
96
98
|
{ "label": "Station", "value": "{{metadata.station}}" },
|
|
99
|
+
{ "label": "Assignee", "value": "{{escalation.assigned_to}}", "format": "user" },
|
|
97
100
|
{ "label": "Priority", "value": "{{escalation.priority}}" },
|
|
98
101
|
{ "label": "Created", "value": "{{escalation.created_at}}" }
|
|
99
102
|
]
|
|
@@ -21,6 +21,16 @@ Compare the resolved value's string form against a literal:
|
|
|
21
21
|
|
|
22
22
|
The expected value is the raw remainder after the operator (trimmed; no quoting). Numbers and booleans compare via their string form (`metadata.count=3`, `metadata.live=true`). An absent value compares as the empty string — so `=X` is false and `!=X` is true when the path is missing. `resolver.` conditions react live as the user edits, exactly like the truthy form — this is what drives per-designation sub-surfaces on verdict forms (different fields for send-to-design vs send-to-printing).
|
|
23
23
|
|
|
24
|
+
### Several conditions
|
|
25
|
+
|
|
26
|
+
Pass an array to require every condition. The field shows only when all hold:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
"x-lt-showIf": ["input.action=report-offline", "!input.powerCycled"]
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Each entry uses the same grammar as a single condition. A hidden field is skipped by validation exactly as with one condition.
|
|
33
|
+
|
|
24
34
|
### Domains
|
|
25
35
|
|
|
26
36
|
| Domain | Resolves against |
|
|
@@ -30,6 +40,7 @@ The expected value is the raw remainder after the operator (trimmed; no quoting)
|
|
|
30
40
|
| `envelope` | The workflow-sent input envelope |
|
|
31
41
|
| `escalation` | Top-level escalation row fields (`role`, `status`, `priority`, …) |
|
|
32
42
|
| `resolver` | The submitted resolver payload — **live**: reacts in real time as the user edits the form |
|
|
43
|
+
| `input` | The same live form values under the invoke form's name (see [invoke-form.md](invoke-form.md)) |
|
|
33
44
|
|
|
34
45
|
Conditions based on `metadata`, `payload`, `envelope`, and `escalation` are static (read from the stored row). Conditions based on `resolver` are dynamic — the field appears or disappears immediately as the user edits a sibling field, without a page reload.
|
|
35
46
|
|
package/docs/hitl-guide.md
CHANGED
|
@@ -24,6 +24,7 @@ This works because the form is data: a JSON Schema stored on the role, versioned
|
|
|
24
24
|
| Rename the resolve footer, or claim-and-submit in one gesture | Footer tokens | [x-lt-footer.md](hitl/x-lt-footer.md) |
|
|
25
25
|
| Block the resolve until embedded work drains, then auto-close when it does | `x-lt-submit-guard` | [x-lt-embed.md](hitl/x-lt-embed.md) |
|
|
26
26
|
| A fully custom UI nothing above can express | Iframe viewport | [iframe.md](hitl/iframe.md) |
|
|
27
|
+
| The same rich form for starting a workflow from the Invoke Tool page | `inputSchema` on the worker config | [invoke-form.md](hitl/invoke-form.md) |
|
|
27
28
|
|
|
28
29
|
---
|
|
29
30
|
|
|
@@ -103,6 +104,7 @@ Ordered as a learning path — each file adds one capability to the same form:
|
|
|
103
104
|
|
|
104
105
|
| Keyword | Level | Purpose |
|
|
105
106
|
|---------|-------|---------|
|
|
107
|
+
| `input.*` | domain | The live form values on the Invoke surface (alias of `resolver.*`) for `x-lt-showIf`, `x-lt-help`, and `x-lt-options` |
|
|
106
108
|
| `x-lt-widget` | field | Rich control: `file-upload`, `code-editor`, `signature`, `rich-text`, `markdown`, `checklist`, `attachment` (alias `image`) |
|
|
107
109
|
| `x-lt-source` | field | Data path for context-driven widgets: `"domain.path"` or an ordered array of paths (first to resolve wins); may embed `{{domain.path}}` interpolation segments |
|
|
108
110
|
| `x-lt-require-all` | field | Checklist completion guard — every item must be checked, except items declared `required: false` |
|
|
@@ -113,7 +115,7 @@ Ordered as a learning path — each file adds one capability to the same form:
|
|
|
113
115
|
| `accept` | field | File-type filter for `file-upload` (e.g. `".pdf,.png"`) |
|
|
114
116
|
| `x-lt-bind` | field | Path in the resolver payload (e.g. `"customer.email"`) |
|
|
115
117
|
| `x-lt-span` | field | Column span in a `two-column` layout (`2` = full width) |
|
|
116
|
-
| `x-lt-showIf` | field | Show field when a value is truthy at `domain.path`; prefix `!` to invert; `=VALUE` / `!=VALUE` compare the string form |
|
|
118
|
+
| `x-lt-showIf` | field | Show field when a value is truthy at `domain.path`; prefix `!` to invert; `=VALUE` / `!=VALUE` compare the string form; an array requires every condition |
|
|
117
119
|
| `x-lt-hide-if-empty` | field | `true` — suppress the field when its value is null, `""`, `false`, or `0` |
|
|
118
120
|
| `x-lt-section` | field | Section group label |
|
|
119
121
|
| `x-lt-options` | field | Dynamic select options — resolves a `"domain.path"` (or an ordered array of paths, first to resolve wins) to the field's option list (scalars or `{ value, label }`); static `enum` wins; `{{domain.path}}` segments make cascading selects |
|
|
@@ -128,7 +130,7 @@ Ordered as a learning path — each file adds one capability to the same form:
|
|
|
128
130
|
| `x-lt-card` | schema (list) | `facet-board`: per-entity card — `{ title, state?, fields? }`; fields accept `format: "age"` |
|
|
129
131
|
| `x-lt-help` | schema | Markdown guidance for the side panel's Help view |
|
|
130
132
|
| `x-lt-context` | schema | Plain-text fallback for the Help view when `x-lt-help` is absent |
|
|
131
|
-
| `x-lt-viewport` | schema | Replace the generated form with a custom iframe UI |
|
|
133
|
+
| `x-lt-viewport` | schema | Replace the generated form with a custom iframe UI; `src` is the editor, `onPending` / `onResolved` show the embed at the other stages |
|
|
132
134
|
| `x-lt-submit-guard` | schema | Block the resolve while an embedded escalation query returns rows; `autoResolveWhenEmpty` auto-closes the claimed parent once it drains. Enforced isomorphically for `enforce_schema` roles |
|
|
133
135
|
| `x-lt-submit-on-claim` | schema | Claiming also resolves the form's seeded defaults in one gesture |
|
|
134
136
|
| `x-lt-labels` | schema | Per-target labels for the footer controls (`claim`, `cancel`, `submit`, `release`) |
|
package/docs/iam.md
CHANGED
|
@@ -259,7 +259,7 @@ The dashboard surfaces IAM across four pages:
|
|
|
259
259
|
|
|
260
260
|
**Accounts** (`/admin/users`) — unified management for User Accounts and Service Accounts via tab toggle. Create service accounts, assign roles, generate API keys. The key generation flow displays the raw key once; it cannot be retrieved after dismissal.
|
|
261
261
|
|
|
262
|
-
**Invoke
|
|
262
|
+
**Invoke Tool** (`/workflows/start`) — all invocable workflows in a single list with visual tier distinction. Certified workflows show the green shield; durable workflows show the standard icon. Both support Start Now and Schedule (cron).
|
|
263
263
|
|
|
264
264
|
**Connections** (`/credentials`) — each user manages their OAuth provider connections. Status, credential type, and expiry are visible. Users connect or revoke providers here.
|
|
265
265
|
|
package/docs/operations.md
CHANGED
|
@@ -1,109 +1,104 @@
|
|
|
1
1
|
# Operations
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Operations gives anyone managing a process pipeline a live picture of how work is flowing across a segment of roles. It answers the question the COO actually asks: *are we keeping up, and where are things backing up?* It surfaces as two boards that share one selector:
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- **Pace Board** (`/pace`) — actual-vs-target throughput across a segment of roles.
|
|
6
|
+
- **Trend Board** (`/trends`) — the entity lens: where an entity's time goes across the roles that handle it.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
`/operations` redirects to `/pace`.
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
## What Operations means
|
|
11
|
+
|
|
12
|
+
A process is a directed sequence of **roles** — each a queue where work lands, is claimed, and gets resolved before moving downstream. The ortho manufacturing pipeline is one example: `design → review → print → grind → glue → finish → qa → ship`. Any set of roles with `parent_role` set forms a process graph.
|
|
13
|
+
|
|
14
|
+
A role opts onto the boards by setting `ops_visible = true` (Role Detail → Pace Board → **Show this role on the Pace Board**). Roles without that flag appear in the Roles admin page but not on the boards.
|
|
10
15
|
|
|
11
16
|
## Capacity settings
|
|
12
17
|
|
|
13
|
-
Each
|
|
18
|
+
Each role has three settings that define what "healthy" looks like — knowing any two derives the third (`target_per_hour = worker_count / (sla_minutes / 60)`):
|
|
14
19
|
|
|
15
20
|
| Field | Description |
|
|
16
21
|
|-------|-------------|
|
|
17
22
|
| `sla_minutes` | Target resolution time in minutes. The default age threshold for the priority count. |
|
|
18
|
-
| `target_per_hour` | Intended throughput — how many items should resolve per hour. Used to compute `throughput_pct` and the
|
|
19
|
-
| `worker_count` | Capacity at this
|
|
23
|
+
| `target_per_hour` | Intended throughput — how many items should resolve per hour. Used to compute `throughput_pct` and the role's expected count on the pace chart. |
|
|
24
|
+
| `worker_count` | Capacity at this role — number of staff or machines expected to be active. |
|
|
20
25
|
|
|
21
26
|
These are set via `PATCH /api/roles/:role` or the Roles admin page.
|
|
22
27
|
|
|
23
|
-
##
|
|
28
|
+
## Jeopardy count
|
|
24
29
|
|
|
25
|
-
Every
|
|
30
|
+
Every role carries one age signal: `priority_count`, the number of **pending, unclaimed** items older than the role's threshold — its jeopardy. It is deliberately a count, not a re-sorted queue — the floor rebalances coarsely, pulling the counted items to the front of the rack, rather than continuously re-ordering everything.
|
|
26
31
|
|
|
27
32
|
Two per-role dials shape it, each with a fallback so the count works from `sla_minutes` alone:
|
|
28
33
|
|
|
29
34
|
| Dial | Description |
|
|
30
35
|
|------|-------------|
|
|
31
36
|
| `priority_facet` | `lt_escalations.metadata` key holding each item's age origin as an ISO 8601 UTC timestamp (e.g. `authorized_at`, the date the order was authorized). Blank = age from `created_at`. When set, items missing the key or holding an unparseable value are not counted. |
|
|
32
|
-
| `priority_threshold_minutes` | Max age before an item counts as
|
|
37
|
+
| `priority_threshold_minutes` | Max age before an item counts as jeopardy. Blank = the role's `sla_minutes`. |
|
|
33
38
|
|
|
34
|
-
Claimed items are excluded — they are already in someone's hands; the count is what still needs pulling forward. On the
|
|
39
|
+
Claimed items are excluded — they are already in someone's hands; the count is what still needs pulling forward. On the board the count renders as a jeopardy action on the role (a warning triangle); clicking it opens the role's queue filtered to `jeopardy=1`, ordered oldest-first by the same facet, so the counted items sit at the top.
|
|
35
40
|
|
|
36
41
|
## Pace chart
|
|
37
42
|
|
|
38
|
-
The chart is the centrepiece. It plots **absolute counts for the selected window** across the
|
|
39
|
-
|
|
40
|
-
Two lines cross the stations:
|
|
41
|
-
|
|
42
|
-
- **Target** — a straight red polyline at each station's expected count for the window (`target_per_hour × window hours`; e.g. 22/h over 15m ≈ 5).
|
|
43
|
-
- **Actual** — a smooth curve through each station's resolved count for the window, with a light area fill beneath it. Reading actual against target shows at a glance which stations are keeping pace.
|
|
44
|
-
|
|
45
|
-
Each station appears as a circle on the actual curve, colored by its pace ratio (`actual / target`):
|
|
46
|
-
|
|
47
|
-
- **Green** — met or beat the target (ratio ≥ 1.0).
|
|
48
|
-
- **Amber** — behind (ratio ≥ 0.6).
|
|
49
|
-
- **Red** — well behind (ratio < 0.6).
|
|
50
|
-
- **Grey** — target unset for this station.
|
|
43
|
+
The chart is the centrepiece. It plots **absolute counts for the selected window** across the segment — every role in dependency order (parent before children) on the X axis.
|
|
51
44
|
|
|
52
|
-
|
|
45
|
+
Two lines cross the roles:
|
|
53
46
|
|
|
54
|
-
|
|
47
|
+
- **Target** — a muted-gray dashed polyline at each role's expected count for the window (`target_per_hour × window hours`; e.g. 22/h over 15m ≈ 5).
|
|
48
|
+
- **Actual** — a smooth green curve through each role's resolved count for the window, with a light area fill beneath it. Reading actual against target shows at a glance which roles are keeping pace.
|
|
55
49
|
|
|
56
|
-
|
|
57
|
-
5↑ · 2● · 12✓
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
- `↑` pending (amber when > 0)
|
|
61
|
-
- `●` active / claimed (indigo when > 0)
|
|
62
|
-
- `✓` resolved in period (green, bold — the "did we hit target" signal)
|
|
50
|
+
Each role appears as a circle on the actual curve, its radius growing modestly with resolved volume; the selected role gets a ring. Beneath the curve, the live queue shows as two faint stacked bands — **claimed/worked** (orange) and **waiting/unclaimed** (sky). A `lin | log` toggle switches the Y axis (log by default, so small and large queues stay legible together).
|
|
63
51
|
|
|
64
|
-
|
|
52
|
+
Roles without a `target_per_hour` still appear on the X axis — the target line has a gap there, and the tooltip prompts you to set a target rate to plot pace.
|
|
65
53
|
|
|
66
|
-
##
|
|
54
|
+
## Role table
|
|
67
55
|
|
|
68
|
-
Below the chart, a flat table lists every
|
|
56
|
+
Below the chart, a flat table lists every role with its live numbers. Columns in order:
|
|
69
57
|
|
|
70
58
|
| Column | Description |
|
|
71
59
|
|--------|-------------|
|
|
72
|
-
|
|
|
73
|
-
|
|
|
74
|
-
|
|
|
75
|
-
|
|
|
76
|
-
|
|
|
77
|
-
|
|
|
60
|
+
| NAME | The role's display title. |
|
|
61
|
+
| ROLE | The role id (wide viewports). |
|
|
62
|
+
| TARGET/H | Intended throughput — edit inline. |
|
|
63
|
+
| SLA/M | SLA in minutes — edit inline. |
|
|
64
|
+
| WORKERS | Derived capacity — `target ÷ (60 ÷ sla)`. |
|
|
65
|
+
| PENDING | Items queued right now — links to the available queue. |
|
|
66
|
+
| CLAIMED | Items currently claimed — links to the claimed queue. |
|
|
67
|
+
| RESOLVED | Items resolved in the selected period — links to the resolved queue. |
|
|
68
|
+
| P99 WAIT | 99th-percentile queue time (created → claimed) in minutes (wide viewports). |
|
|
69
|
+
| P99 WORK | 99th-percentile processing time (claimed → resolved) in minutes (wide viewports). |
|
|
70
|
+
| MIX | A time-in-state bar for the role's current items. |
|
|
71
|
+
| TREND | Mini fill bar + percentage — the pending-to-target ratio (amber above 1.0, gray below 0.2, green between). |
|
|
72
|
+
| ACTIONS | View queue, configure, and a jeopardy count when the role has aging unclaimed work. |
|
|
78
73
|
|
|
79
|
-
|
|
74
|
+
The three status columns carry the chart's hues as faint tints. The jeopardy action links to the escalation queue filtered to that role, `jeopardy=1`, ordered oldest-first by the role's priority facet (`created_at` when none is configured), so the counted items sit at the top.
|
|
80
75
|
|
|
81
|
-
Clicking any row opens the
|
|
76
|
+
Clicking any row opens the role detail panel.
|
|
82
77
|
|
|
83
|
-
##
|
|
78
|
+
## Role detail panel
|
|
84
79
|
|
|
85
|
-
A
|
|
80
|
+
A right rail that slides open when a row or chart circle is clicked. It carries:
|
|
86
81
|
|
|
87
82
|
1. **Identity** — role key, title, description, link to edit in Roles.
|
|
88
|
-
2. **Period selector** — `15m | 1h | 24h | 7d | 30d` toggle for this
|
|
89
|
-
3. **Metrics** — pending / resolved /
|
|
83
|
+
2. **Period selector** — a `15m | 1h | 24h | 7d | 30d` toggle for this role only. It opens on the board's selected window, then adjusts independently.
|
|
84
|
+
3. **Metrics** — pending / resolved / claimed counts; wait and work percentiles (P99, P50, avg); SLA target; worker count; the time-in-state mix and per-entity timelines inline; links to the queue.
|
|
90
85
|
|
|
91
86
|
Close the panel with × or by clicking another row.
|
|
92
87
|
|
|
93
|
-
##
|
|
88
|
+
## Trend Board (the entity lens)
|
|
94
89
|
|
|
95
|
-
The board
|
|
90
|
+
The [combined board selector](dashboard.md#pace-board) offers, alongside the Pace Board segments, one **lens** per entity facet the visible roles declare, labeled `by <key>` (e.g. `by serialNumber`). Choosing a lens navigates to the Trend Board (`/trends`), the active lens deep-linked as `?lens=<key>`. The Trend Board is entity-first: roles sharing the facet form the entity's **system**, and each role contributes states per its `entity_state_source`. Three tiers, aggregate → individual:
|
|
96
91
|
|
|
97
|
-
- **
|
|
98
|
-
- **Slice by** — the same
|
|
99
|
-
- **The entity table** — one row per entity, ranked by tracked time: the entity value, its current state, its own dwell band, its total tracked time, and a timeline action
|
|
92
|
+
- **Where the time went** — how the system's time splits across states over the selected period: a ranked-bar legend by total dwell beside an insight (the leader's share as a headline percentage, `<state> is the biggest time sink`, and `across N stages · M <entity> in queue now`).
|
|
93
|
+
- **Slice by** — the same split per value of any metadata key (`?slice=<key>`, e.g. `model` → `p1s` vs `h2s`), as small-multiple columns ranked by dwell; `?sliceValue=<value>` focuses one value with a paginated entity list.
|
|
94
|
+
- **The entity table** — one row per entity, ranked by tracked time: the entity value, its current state, its own dwell band, its total tracked time, and a timeline action. `?entity=<value>` opens that entity's cross-queue interval timeline in the right panel; `?find=<prefix>` prefix-filters the list.
|
|
100
95
|
|
|
101
96
|
The lens is driven by two dials on the role's Pace Board section ([Role Detail](dashboard.md#role-detail)):
|
|
102
97
|
|
|
103
98
|
| Dial | Description |
|
|
104
99
|
|------|-------------|
|
|
105
100
|
| `entity_facet` | The `lt_escalations.metadata` key naming the entity that moves through the role (e.g. `serialNumber`, `orderId`). Roles sharing a key form that entity's system. Blank = the role has no entity notion. |
|
|
106
|
-
| `entity_state_source` | How the role names the entity's state: **
|
|
101
|
+
| `entity_state_source` | How the role names the entity's state: **Role** (`'role'` — being in this role is one state, e.g. a servicing queue) or **Subtypes** (`'subtype'` — the one role holds several states named by each escalation's subtype, e.g. a fleet role parking `idle` / `printing`). Default `'role'`. |
|
|
107
102
|
|
|
108
103
|
The band tiers are counts-only aggregates, readable by any login while the public board flag stands; the slice and per-entity tiers group by facet values and require full (`read_all`) access to the system's queues. Data comes from `POST /api/escalations/aggregate-by-facets` and `POST /api/escalations/timeline-by-facet` — see [escalation-analytics.md](escalation-analytics.md) for the query contract.
|
|
109
104
|
|
|
@@ -115,16 +110,22 @@ All station metrics come from `GET /api/escalations/station-metrics?period=<peri
|
|
|
115
110
|
|
|
116
111
|
## Period selector
|
|
117
112
|
|
|
118
|
-
The
|
|
113
|
+
The period toggle in the page header controls the chart and table together. It is deep-linked as `?period=` (the `1h` default stays out of the URL for clean links) and carries across a Pace↔Trend switch. The role detail panel has its own independent period toggle so you can zoom into a single role without losing the overview.
|
|
119
114
|
|
|
120
115
|
Period options: `15m`, `1h`, `24h`, `7d`, `30d`.
|
|
121
116
|
|
|
122
|
-
##
|
|
117
|
+
## Scoping the board
|
|
118
|
+
|
|
119
|
+
When your roles declare [link variables](faceted-routing.md#link-variables), a scope pill sits in the board header. Its value is your **device binding** — the same one that scopes your role pins — so binding `facility = north` once (avatar menu → Link variables, or the pill itself) narrows the whole board to that facet: the role counts, the "where the time went" mix, and every entity timeline all reflect only matching rows. The pill shows the active scope (`facility = north`) or `All` when nothing is bound; clearing the binding restores the full board.
|
|
120
|
+
|
|
121
|
+
The scope is a metadata `@>` filter (`GET /api/escalations/station-metrics?...&facets={"facility":"north"}`), applied on top of role scope — it narrows within what you may already see, never widens it. The value picker's choices come from `GET /api/escalations/facet-values?key=<facet>` (the distinct values present in your visible rows).
|
|
122
|
+
|
|
123
|
+
## Configuring a role onto the board
|
|
123
124
|
|
|
124
125
|
1. Go to `/admin/roles` and click the role.
|
|
125
|
-
2.
|
|
126
|
-
3. Set `parent_role` to the upstream role this
|
|
127
|
-
4. The role appears on `/
|
|
126
|
+
2. In the Pace Board section, turn on **Show this role on the Pace Board** and set `sla_minutes`, `target_per_hour`, and `worker_count`.
|
|
127
|
+
3. Set **Prior Step** (`parent_role`) to the upstream role this role receives work from. Leave blank for a segment root.
|
|
128
|
+
4. The role appears on `/pace` on the next refresh — settings take effect live.
|
|
128
129
|
|
|
129
130
|
## The ortho pipeline
|
|
130
131
|
|
|
@@ -140,4 +141,4 @@ See [MCP Admin Tools — Ortho Pipeline](api/mcp/admin.md#ortho-pipeline) for th
|
|
|
140
141
|
|
|
141
142
|
## Navigation
|
|
142
143
|
|
|
143
|
-
|
|
144
|
+
**Pace Board** and **Trend Board** are both globally surfaced in the choreography sidebar (the Monitor section of the left rail), separate from the Admin sidebar. Both routes admit every authenticated user — the boards are aggregate counts and trends, readonly by nature. Metrics span all roles for any login while the `features.publicPaceBoard` flag (default on) stands; a deployment that sets it false (e.g. one provisioning external one-time accounts) narrows metrics back to role membership and the boards back to admin-type users and superadmins.
|
package/docs/scan-codes.md
CHANGED
|
@@ -240,6 +240,28 @@ Pair kiosk with `x-lt-transition-done` on the role's form schema
|
|
|
240
240
|
resolve lands back on the list rather than walking browser history — see
|
|
241
241
|
[x-lt-transition](./hitl/x-lt-transition.md).
|
|
242
242
|
|
|
243
|
+
### The work surface — edit freely, badge at submit
|
|
244
|
+
|
|
245
|
+
On the work form, the badge belongs to the submission, not the editing. Once
|
|
246
|
+
an item is claimed, anyone at the bench edits the form freely: a grant is not
|
|
247
|
+
required to type. This is the read-only station login's surface: plain member
|
|
248
|
+
grants, none able to write. A login that holds its own write authority, an
|
|
249
|
+
operator with write scope on the queue or an admin or superadmin, is a person
|
|
250
|
+
and keeps the standard surface: another person's claim shows as claimed by
|
|
251
|
+
them, with the management verbs its RBAC allows, and no badge is asked of it. The submit is the state-changing act, so that is where the
|
|
252
|
+
badge is asked for. The form warns up front who the submit will act as — "When
|
|
253
|
+
you submit, you'll scan your badge to confirm you're <claimant>" — and the
|
|
254
|
+
submit opens a badge prompt naming that claimant. The resolve fires the moment
|
|
255
|
+
a matching badge primes; a badge that is not the claimant's is named and the
|
|
256
|
+
submit is held.
|
|
257
|
+
|
|
258
|
+
The gate is on **use**, not on grant lifetime. Acting grants are single-use:
|
|
259
|
+
the claim already spent the grant it was minted with, so the submit owes a
|
|
260
|
+
fresh tap — every write consumes its own grant. A held token proves nothing
|
|
261
|
+
about whether a submit can succeed, so the surface never lets one skip the
|
|
262
|
+
badge. Editing persists nothing locally, so the identity gate sits at the one
|
|
263
|
+
place a record actually changes, once per change.
|
|
264
|
+
|
|
243
265
|
Mutations attribute to the badged person (`assigned_to`, `resolved_by`)
|
|
244
266
|
with the device recorded beside them (`scanStation` in the scan
|
|
245
267
|
provenance) — every action individually owned and geographically placed.
|
|
@@ -323,9 +345,14 @@ Capture sources are pluggable (`dashboard/src/lib/scan-sources/`): the
|
|
|
323
345
|
keyboard wedge is one provider behind a `ScanSource` contract; an RFID or
|
|
324
346
|
camera provider plugs into the same dispatch pipeline.
|
|
325
347
|
|
|
326
|
-
The **
|
|
327
|
-
|
|
328
|
-
|
|
348
|
+
The **header bar** runs rules without hardware: its type chip lists every
|
|
349
|
+
enabled rule as a Run mode, the bar shows the rule's code head (`10:1:`) ahead
|
|
350
|
+
of the input, and Enter composes and executes `10:1:<target>` through the same
|
|
351
|
+
pipeline a scanner uses. See [Search and run](dashboard.md#search-and-run).
|
|
352
|
+
|
|
353
|
+
The **scan panel** (the bar's menu footer, or the user menu) carries a manual
|
|
354
|
+
entry field — type or paste a whole code to execute it — the last scan's
|
|
355
|
+
outcome, the live barcode preview, and the capture settings.
|
|
329
356
|
|
|
330
357
|
## Scanner setup
|
|
331
358
|
|
package/docs/workflows.md
CHANGED
|
@@ -26,7 +26,7 @@ A certified workflow is durable plus the full Long Tail control plane. It has an
|
|
|
26
26
|
- **Invocation controls** — `invocable: true` exposes the workflow for external invocation via the API and dashboard.
|
|
27
27
|
- **Execution identity** — roles, default assignees, and `execute_as` overrides are defined in the config.
|
|
28
28
|
|
|
29
|
-
In the dashboard, certified workflows display a ShieldCheck icon with a "Certified" label in accent blue. Durable workflows display a muted "Durable" badge. Both are invocable from the same **Invoke
|
|
29
|
+
In the dashboard, certified workflows display a ShieldCheck icon with a "Certified" label in accent blue. Durable workflows display a muted "Durable" badge. Both are invocable from the same **Invoke Tool** page; the distinction is how much operational infrastructure backs them.
|
|
30
30
|
|
|
31
31
|
To certify a workflow, create a config entry with the `certified` flag:
|
|
32
32
|
|
package/package.json
CHANGED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{j as t}from"./vendor-query-RUZdMvN6.js";import{u as f}from"./agents-BsJ-MizQ.js";import{b,w as v,b4 as j,e as N}from"./index-D88VWEVp.js";import{u as y}from"./useFilterParams-crmlBw_l.js";import{b as w}from"./api-path-u2Jf9QXS.js";import{D as P}from"./DataTable-DFPMeqyQ.js";import{S}from"./StickyPagination-BGHQbp0_.js";import{F as k,b as A}from"./FilterBar-Fin1IqHc.js";import{P as _}from"./PageHeader-DZmymFBS.js";import{L as C}from"./ListToolbar-DyHaJBTk.js";import{f as F}from"./vendor-icons-R9b9gQ04.js";import{u as z}from"./vendor-react-CdqEC2zv.js";import"./EmptyState-lpUFYfun.js";const L=[{value:"active",label:"Active"},{value:"inactive",label:"Inactive"},{value:"paused",label:"Paused"},{value:"error",label:"Error"}],T=[{key:"name",label:"Agent",render:e=>t.jsxs("div",{className:"flex items-center gap-2.5 min-w-0",children:[t.jsx("span",{className:`w-2.5 h-2.5 rounded-full dot-ring shrink-0 ${e.status==="active"?"bg-status-success":e.status==="paused"?"bg-status-warning":e.status==="error"?"bg-status-error":"bg-surface-border"}`}),t.jsx("span",{className:"text-xs font-medium text-text-primary whitespace-nowrap",children:e.id}),e.description&&t.jsx("p",{className:"flex-1 min-w-0 truncate text-2xs text-text-tertiary",children:e.description})]})},{key:"knowledge_domain",label:"Knowledge",render:e=>e.knowledge_domain?t.jsx("span",{className:"text-2xs font-mono text-text-secondary whitespace-nowrap",children:e.knowledge_domain}):t.jsx("span",{className:"text-text-quaternary",children:"—"}),className:"w-28"},{key:"schedules",label:"Schedules",render:e=>{var r,i;const s=(r=e.behaviors)==null?void 0:r.schedules,a=s!=null&&s.length?s.map(c=>c.cron):(i=e.behaviors)!=null&&i.cron?[e.behaviors.cron]:[];return a.length?t.jsxs("span",{className:"text-2xs font-mono text-text-secondary whitespace-nowrap",children:[a[0],a.length>1?` +${a.length-1}`:""]}):t.jsx("span",{className:"text-text-quaternary",children:"—"})},className:"w-28"},{key:"subscriptions",label:"Subscriptions",render:e=>{var i;const s=e.subscription_count??0,a=e.sub_topics??[];if(!s)return t.jsx("span",{className:"text-text-quaternary",children:"—"});const r=((i=a[0])==null?void 0:i.replace(/^lt\.events\./,""))??"";return t.jsxs("span",{className:"text-2xs font-mono text-text-secondary whitespace-nowrap",children:[r,s>1?` +${s-1}`:""]})},className:"w-36"},{key:"last_run_at",label:"Last Run",render:e=>e.last_run_at?t.jsx("span",{className:"whitespace-nowrap",children:t.jsx(N,{date:e.last_run_at})}):t.jsx("span",{className:"text-text-quaternary",children:"—"}),className:"w-32"}];function G(){var p;const e=z(),{data:s}=b(),a=v(),r=a!==null?a:!!((p=s==null?void 0:s.ai)!=null&&p.enabled),i=r?"Agent":"Automation",c=r?"Agents":"Automations";j();const{filters:u,setFilter:d,pagination:n}=y({filters:{status:""}}),{data:o,isLoading:x,refetch:g,isFetching:h}=f({status:u.status||void 0,limit:n.pageSize,offset:n.offset}),m=(o==null?void 0:o.total)??0;return t.jsxs("div",{children:[t.jsx(_,{title:c,docsHash:"#docs:agents.md",actions:t.jsxs("button",{onClick:()=>e("/agents/new"),className:"flex items-center gap-2 px-4 py-2 text-sm rounded-md bg-accent text-text-inverse hover:bg-accent-hover transition-colors",children:[t.jsx(F,{className:"w-4 h-4"})," Create ",i]})}),t.jsx(k,{actions:t.jsx(C,{onRefresh:()=>g(),isFetching:h,apiPath:w("/agents",{limit:n.pageSize,offset:n.offset,status:u.status||void 0})}),children:t.jsx(A,{label:"Status",value:u.status,onChange:l=>d("status",l),options:L})}),t.jsx(P,{columns:T,data:(o==null?void 0:o.agents)??[],keyFn:l=>l.id,onRowClick:l=>e(`/agents/${l.id}`),isLoading:x,emptyMessage:`No ${c.toLowerCase()} found`}),t.jsx(S,{page:n.page,totalPages:n.totalPages(m),onPageChange:n.setPage,total:m,pageSize:n.pageSize,onPageSizeChange:n.setPageSize})]})}export{G as AgentsPage};
|
|
2
|
-
//# sourceMappingURL=AgentsPage-CLSjlyXy.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as b,j as e}from"./vendor-query-RUZdMvN6.js";import{t as Rt,v as Lt,b as _t,w as Bt,M as Ke,x as _e,y as zt,z as Ut,A as qt,B as Dt,E as Vt,G as It,H as Gt,I as Ht,K as Qt,L as Kt,O as Wt,p as Xt,Q as Yt,R as Zt,T as Jt,U as es,V as ts,W as ss,X as as,Y as ns,Z as rs,_ as is,$ as ls,a0 as os,a1 as cs,a2 as ds,a3 as us,a4 as xs}from"./index-D88VWEVp.js";import{a as We,u as Xe,L as Be,f as ms}from"./vendor-react-CdqEC2zv.js";import{i as hs}from"./task-queues-7-sHKPsN.js";import{X as se,ah as ps,ai as fs,C as gs,d as bs,aj as ys,b as vs,t as js,s as Ns,ak as Cs,x as ks,al as ws,am as Ss,V as Ps,h as Ms,an as Ts,P as As,ao as Es}from"./vendor-icons-R9b9gQ04.js";import{u as Ye,C as Os,r as $s,B as Fs,a as Rs}from"./BulkAssignModal-CMSgvHIs.js";import{m as Ls,E as _s,a as Bs}from"./escalation-columns-Bo3PfIZj.js";import{i as Ze,s as zs,E as Us}from"./CountdownTimer-B5lM7PfE.js";import{u as qs}from"./useFilterParams-crmlBw_l.js";import{u as Ds}from"./useDebouncedValue-DhhAKjDC.js";import{D as Vs}from"./DataTable-DFPMeqyQ.js";import{S as Is}from"./StickyPagination-BGHQbp0_.js";import{P as Gs}from"./constants-BHkpVaqx.js";import{R as Hs,a as Qs}from"./RowActions-eYrzgQSj.js";import"./EntityTimelinePanel-B5NuHnPF.js";import"./FilterBar-Fin1IqHc.js";import"./PriorityBadge-BETdj4M-.js";import"./RolePill-C9LSs1aK.js";import"./WorkflowPill-Dh3hIW1l.js";import"./StatusBadge-BDeUwPtb.js";import"./EmptyState-lpUFYfun.js";function Ks(){const{pathname:t,search:s}=We(),i=Xe(),{resolveUrl:n}=Rt();b.useEffect(()=>{const m=t+s;if(Lt(m).length===0)return;const x=n(m);x!==m&&i(x,{replace:!0})},[t,s,n,i])}const Ws=["<","<=",">",">=","="],Xs=["priority","created_at","updated_at","status","role"],B="input text-xs py-1",ze="select text-xs py-1",J="text-text-tertiary hover:text-text-primary transition-colors";function Ue(t){return t==="true"?!0:t==="false"?!1:t.trim()!==""&&!Number.isNaN(Number(t))?Number(t):t}const Ys=t=>Object.entries(t??{}).map(([s,i])=>({key:s,value:String(i)})),Zs=t=>(t??[]).map(s=>{const[i,n]=Object.entries(s)[0]??["",""];return{key:i,value:String(n)}});function L({title:t,hint:s,children:i}){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-2xs font-medium uppercase tracking-wide text-text-tertiary",children:t}),s&&e.jsx("span",{className:"text-2xs font-mono text-text-tertiary/70",children:s})]}),i]})}function ee({value:t,onChange:s,placeholder:i}){return e.jsx("input",{list:"lt-facet-keys",className:`${B} w-40`,placeholder:i,value:t,onChange:n=>s(n.target.value)})}function Js({value:t,onChange:s,facetKeys:i=[],search:n="",onSearchChange:m}){const x=Ys(t.facets),h=Zs(t.block),f=t.range??[],o=t.exists??[],y=t.orderBy??[],N=r=>{const u={};for(const d of r)d.key&&(u[d.key]=Ue(d.value));s({...t,facets:Object.keys(u).length?u:void 0})},S=r=>{const u=r.filter(d=>d.key).map(d=>({[d.key]:Ue(d.value)}));s({...t,block:u.length?u:void 0})},M=r=>s({...t,range:r.length?r:void 0}),j=r=>s({...t,exists:r.length?r:void 0}),P=r=>s({...t,orderBy:r.length?r:void 0});return e.jsxs("div",{className:"text-xs",children:[e.jsx("datalist",{id:"lt-facet-keys",children:i.map(r=>e.jsx("option",{value:r},r))}),e.jsxs("datalist",{id:"lt-sort-fields",children:[Xs.map(r=>e.jsx("option",{value:r},r)),i.map(r=>e.jsx("option",{value:`metadata.${r}`},r))]}),m&&e.jsx(L,{title:"Match id",hint:"id · workflow · origin",children:e.jsx("input",{className:`${B} w-full`,placeholder:"Exact escalation, workflow, or origin id…",value:n,onChange:r=>m(r.target.value)})}),e.jsx(L,{title:"Has facet",hint:"metadata @>",children:[...x,{key:"",value:""}].map((r,u)=>e.jsxs("div",{className:"mb-1 flex items-center gap-1",children:[e.jsx(ee,{value:r.key,placeholder:"key",onChange:d=>{const l=[...x];l[u]={...r,key:d},N(l)}}),e.jsx("span",{className:"text-text-tertiary",children:"="}),e.jsx("input",{className:`${B} w-40`,placeholder:"value",value:r.value,onChange:d=>{const l=[...x];l[u]={...r,value:d.target.value},N(l)}}),u<x.length&&e.jsx("button",{className:J,onClick:()=>N(x.filter((d,l)=>l!==u)),children:"×"})]},u))}),e.jsx(L,{title:"Range",hint:"numeric",children:[...f,{facet:"",op:"<=",value:0}].map((r,u)=>e.jsxs("div",{className:"mb-1 flex items-center gap-1",children:[e.jsx(ee,{value:r.facet,placeholder:"numeric facet",onChange:d=>{const l=[...f];l[u]={...r,facet:d},M(l.filter(c=>c.facet))}}),e.jsx("select",{className:ze,value:r.op,onChange:d=>{const l=[...f];l[u]={...r,op:d.target.value},M(l.filter(c=>c.facet))},children:Ws.map(d=>e.jsx("option",{value:d,children:d},d))}),e.jsx("input",{type:"number",className:`${B} w-24`,value:r.value,onChange:d=>{const l=[...f];l[u]={...r,value:Number(d.target.value)},M(l.filter(c=>c.facet))}}),u<f.length&&e.jsx("button",{className:J,onClick:()=>M(f.filter((d,l)=>l!==u)),children:"×"})]},u))}),e.jsx(L,{title:"Has key",hint:"metadata ? key",children:e.jsxs("div",{className:"flex flex-wrap items-center gap-1",children:[o.map(r=>e.jsxs("span",{className:"flex items-center gap-1 rounded bg-accent/15 px-1.5 py-0.5 text-accent",children:[r,e.jsx("button",{className:"text-accent/70 hover:text-accent",onClick:()=>j(o.filter(u=>u!==r)),children:"×"})]},r)),e.jsx(ee,{value:"",placeholder:"+ key",onChange:r=>{r&&!o.includes(r)&&j([...o,r])}})]})}),e.jsx(L,{title:"Exclude",hint:"NOT @>",children:[...h,{key:"",value:""}].map((r,u)=>e.jsxs("div",{className:"mb-1 flex items-center gap-1",children:[e.jsx(ee,{value:r.key,placeholder:"key",onChange:d=>{const l=[...h];l[u]={...r,key:d},S(l)}}),e.jsx("span",{className:"text-text-tertiary",children:"="}),e.jsx("input",{className:`${B} w-40`,placeholder:"value",value:r.value,onChange:d=>{const l=[...h];l[u]={...r,value:d.target.value},S(l)}}),u<h.length&&e.jsx("button",{className:J,onClick:()=>S(h.filter((d,l)=>l!==u)),children:"×"})]},u))}),e.jsx(L,{title:"Sort by",children:[...y,{field:"",direction:"asc"}].map((r,u)=>e.jsxs("div",{className:"mb-1 flex items-center gap-1",children:[e.jsx("input",{list:"lt-sort-fields",className:`${B} w-44`,placeholder:"column or metadata.key",value:r.field,onChange:d=>{const l=[...y];l[u]={...r,field:d.target.value},P(l.filter(c=>c.field))}}),e.jsxs("select",{className:ze,value:r.direction??"asc",onChange:d=>{const l=[...y];l[u]={...r,direction:d.target.value},P(l.filter(c=>c.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:!!r.numeric,onChange:d=>{const l=[...y];l[u]={...r,numeric:d.target.checked},P(l.filter(c=>c.field))}}),"num"]}),u<y.length&&e.jsx("button",{className:J,onClick:()=>P(y.filter((d,l)=>l!==u)),children:"×"})]},u))})]})}function ea({value:t,onChange:s,facetKeys:i,search:n,onSearchChange:m,activeFacetCount:x,onClear:h,onClose:f}){return e.jsxs("div",{className:"h-full overflow-y-auto",children:[e.jsxs("div",{className:"sticky top-0 z-10 flex items-center justify-between px-4 py-3 bg-surface-raised border-b border-surface-border/50",children:[e.jsx("span",{className:"text-xs font-semibold text-text-primary",children:"Faceted query"}),e.jsxs("div",{className:"flex items-center gap-2",children:[x>0&&e.jsx("button",{onClick:h,className:"text-2xs text-text-tertiary hover:text-text-primary transition-colors",children:"Clear"}),e.jsx("button",{onClick:f,className:"p-1 rounded hover:bg-surface-hover text-text-tertiary hover:text-text-primary transition-colors",title:"Close",children:e.jsx(se,{className:"w-4 h-4"})})]})]}),e.jsxs("div",{className:"px-4 py-2",children:[e.jsxs("p",{className:"mb-2 text-2xs 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(Js,{value:t,onChange:s,facetKeys:i,search:n,onSearchChange:m})]})]})}const qe="created_at";function he(t){return t.replace(/^metadata\./,"")}function ta({orderBy:t,onChange:s}){const i=t==null?void 0:t[0],n=(i==null?void 0:i.field)??qe,m=(i==null?void 0:i.direction)??"desc",x=n===qe,h=f=>s([{...i??{},field:n,direction:f}]);return e.jsxs("div",{className:"flex items-center gap-1.5",children:[!x&&e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full border border-accent/25 bg-accent/8 px-2 py-0.5 text-2xs font-medium text-accent/90",children:[e.jsx("span",{className:"text-text-quaternary",children:"sort"}),e.jsx("span",{className:"font-mono max-w-[120px] truncate",title:n,children:he(n)}),e.jsx("button",{onClick:()=>s(void 0),className:"ml-0.5 -mr-0.5 flex items-center text-text-quaternary hover:text-status-error transition-colors","aria-label":"Reset sort to created date",children:e.jsx(se,{className:"w-2.5 h-2.5"})})]}),e.jsxs("div",{className:"flex items-center rounded overflow-hidden border border-surface-border",role:"radiogroup","aria-label":"Sort direction",children:[e.jsx("button",{type:"button",role:"radio","aria-checked":m==="desc",onClick:()=>h("desc"),className:`px-1.5 py-1 transition-colors ${m==="desc"?"bg-accent text-text-inverse":"icon-link hover:bg-surface-hover"}`,title:x?"Newest first":`${he(n)} descending`,children:e.jsx(ps,{className:"w-3.5 h-3.5"})}),e.jsx("button",{type:"button",role:"radio","aria-checked":m==="asc",onClick:()=>h("asc"),className:`px-1.5 py-1 border-l border-surface-border transition-colors ${m==="asc"?"bg-accent text-text-inverse":"icon-link hover:bg-surface-hover"}`,title:x?"Oldest first":`${he(n)} ascending`,children:e.jsx(fs,{className:"w-3.5 h-3.5"})})]})]})}const sa=t=>t.isPriorityPending||t.isClaimPending||t.isAssignPending||t.isUnassignPending||t.isTriagePending||t.isCancelPending,te="inline-flex items-center h-7 px-2.5 text-2xs 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",De=`${te} appearance-none cursor-pointer`,aa="inline-flex items-center h-7 px-2.5 text-2xs 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 na(t){var f;const s=sa(t),i=Ye(),{data:n}=_t(),m=Bt(),x=m!==null?m:((f=n==null?void 0:n.ai)==null?void 0:f.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-2xs 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:o=>{o.target.value&&(t.onSetPriority(parseInt(o.target.value)),o.target.value="")},disabled:s,className:De,defaultValue:"",children:[e.jsx("option",{value:"",disabled:!0,children:"Priority…"}),Gs.map(o=>e.jsx("option",{value:o.value,children:o.label},o.value))]}),e.jsxs("select",{onChange:o=>{o.target.value&&(t.onClaim(parseInt(o.target.value)),o.target.value="")},disabled:s,className:De,defaultValue:"",children:[e.jsx("option",{value:"",disabled:!0,children:"Claim for…"}),i.map(o=>e.jsx("option",{value:o.value,children:o.label},o.value))]}),e.jsx("button",{onClick:t.onAssign,disabled:s,className:te,children:t.isAssignPending?"Assigning…":"Assign to…"}),e.jsx("button",{onClick:t.onUnassign,disabled:s,className:te,children:t.isUnassignPending?"Unassigning…":"Unassign"}),x&&e.jsx("button",{onClick:t.onTriage,disabled:s,className:te,children:t.isTriagePending?"Triaging…":"Triage"}),t.cancelLabel!==!1&&e.jsx("button",{onClick:t.onCancel,disabled:s,className:aa,children:t.isCancelPending?t.cancelLabel?`${t.cancelLabel}…`:"Cancelling…":t.cancelLabel||"Cancel"}),e.jsx("div",{className:"flex-1"}),s&&e.jsx("span",{className:"text-2xs text-text-tertiary animate-pulse",children:"Processing…"}),e.jsx("button",{onClick:t.onClearSelection,className:"px-1 text-2xs font-medium text-text-tertiary hover:text-text-primary transition-colors",children:"Clear"})]})})})}function ra({open:t,onClose:s,selectedCount:i,onSubmit:n,isPending:m}){const[x,h]=b.useState(""),f=()=>{n(x||void 0)};return e.jsx(Ke,{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:i})," 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:x,onChange:o=>h(o.target.value),placeholder:"e.g., image_orientation",className:"input text-xs font-mono w-full"}),e.jsx("p",{className:"text-2xs 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:f,disabled:m,className:"btn-primary text-xs",children:m?"Submitting...":"Submit for Triage"})]})]})})}function _(t,s,i){return n=>{t.mutate(n,{onSuccess:()=>{s(),i==null||i()}})}}function ia(t){const s=()=>[...t.selectedIds];return{handleSetPriority:o=>{_(t.setPriority,t.clearSelection)({ids:s(),priority:o})},handleBulkClaim:o=>{_(t.bulkClaim,t.clearSelection)({ids:s(),durationMinutes:o})},handleBulkTriage:o=>{_(t.bulkTriage,t.clearSelection,t.closeTriageModal)({ids:s(),hint:o})},handleBulkAssign:(o,y,N)=>{_(t.bulkAssign,t.clearSelection,t.closeAssignModal)({ids:s(),targetUserId:o,durationMinutes:y,reassign:N})},handleBulkUnassign:()=>{_(t.bulkUnassign,t.clearSelection)({ids:s()})},handleBulkCancel:()=>{_(t.bulkCancel,t.clearSelection,t.closeCancelModal)({ids:s()})}}}function la({claimTarget:t,onClose:s,claimDuration:i,onDurationChange:n,claimDurations:m,onCustomClaimChange:x,onClaim:h,isPending:f}){return e.jsx(Ke,{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:i,onChange:o=>{n(o.target.value)},className:"select w-full text-sm",children:[m.map(o=>e.jsx("option",{value:o.value,children:o.label},o.value)),e.jsx("option",{value:"custom",children:"Other..."})]}),i==="custom"&&e.jsx(Os,{onChange:x,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:h,className:"btn-primary text-xs",disabled:f,children:f?"Claiming...":"Claim"})]})]})})}const Je={pending:"--lt-status-queued-graphic",claimed:"--lt-status-claimed-graphic",resolved:"--lt-status-success-graphic",cancelled:"--lt-text-quaternary",expired:"--lt-text-tertiary"},et="--lt-text-quaternary";function oa(t){return Je[t]??et}const I=Object.fromEntries(Object.entries(Je).map(([t,s])=>[t,`rgb(var(${s}))`])),Ve=40,ca=64,da=24,Ie=3;function tt(t){return t<6e4?`${Math.round(t/1e3)}s`:t<36e5?`${Math.round(t/6e4)}m`:t<864e5?`${(t/36e5).toFixed(1)}h`:`${(t/864e5).toFixed(1)}d`}function Ge(t){const s=Date.now()-t;return s<6e4?"just now":s<36e5?`${Math.round(s/6e4)}m ago`:s<864e5?`${Math.round(s/36e5)}h ago`:`${Math.round(s/864e5)}d ago`}function He(t){return t.replace(/-/g," ").replace(/\b\w/g,s=>s.toUpperCase())}function ua(t,s){return t?[...s.filter(n=>n in t),...Object.keys(t).filter(n=>!s.includes(n))].map(n=>[n,t[n]]):[]}function xa({e:t}){const s=t.endMs-t.startMs;if(s<=0)return null;const i=I.pending,n=I.claimed,m=t.status==="cancelled"||t.status==="expired"?I.cancelled:I.resolved;let x=100,h=0,f=0;return t.claimedMs!==null?(x=Math.max(0,Math.min(100,(t.claimedMs-t.startMs)/s*100)),t.isOpen?h=100-x:(h=Math.max(0,Math.min(100-x,(t.endMs-t.claimedMs)/s*100)),f=Math.max(0,100-x-h))):t.isOpen||(f=100,x=0),e.jsxs("div",{className:"mt-2 h-0.5 rounded-full overflow-hidden flex bg-surface-sunken",children:[x>0&&e.jsx("div",{style:{width:`${x}%`,backgroundColor:i,opacity:.6}}),h>0&&e.jsx("div",{style:{width:`${h}%`,backgroundColor:n,opacity:.6}}),f>0&&e.jsx("div",{style:{width:`${f}%`,backgroundColor:m,opacity:.6}})]})}function ma({gapMs:t,heightPx:s}){return e.jsx("div",{className:"relative flex items-center justify-center",style:{height:s},children:t>=6e4&&e.jsx("span",{className:"text-2xs text-text-quaternary font-mono bg-surface px-2 relative z-10",children:tt(t)})})}function Qe({e:t,highlightKeys:s,onRowClick:i}){const[n,m]=b.useState(!1),x=I[t.displayStatus]??`rgb(var(${et}))`,h=ua(t.metadata,s),f=n?h:h.slice(0,Ie),o=h.length-Ie;return e.jsxs("div",{className:"cursor-pointer max-w-[460px] min-w-[260px] w-full bg-surface-raised rounded-lg shadow-sm border border-surface-border/60 px-3.5 pt-2.5 pb-2 hover:shadow-md hover:border-surface-border transition-all duration-150",style:{borderTopWidth:"3px",borderTopColor:x},onClick:()=>i==null?void 0:i(t),children:[e.jsxs("div",{className:"flex items-baseline gap-2 mb-1.5",children:[e.jsx("span",{className:"text-2xs font-bold uppercase tracking-widest text-text-quaternary shrink-0",children:He(t.role)}),e.jsxs("span",{className:"text-xs font-semibold text-text-primary truncate",title:t.type,children:[t.type,t.subtype&&t.subtype!==t.type&&t.subtype!==""&&e.jsxs("span",{className:"font-normal text-text-tertiary",children:[" · ",t.subtype]})]})]}),f.length>0&&e.jsxs("div",{className:"border-t border-surface-border/40 pt-1 space-y-px",children:[f.map(([y,N])=>{const S=String(N),M=s.includes(y);return e.jsxs("div",{className:"group/row flex items-center gap-1.5 -mx-1 px-1 py-[2px] rounded",children:[e.jsx("span",{className:`shrink-0 w-[60px] text-2xs font-mono uppercase tracking-wide truncate ${M?"text-accent":"text-text-quaternary"}`,title:y,children:y}),e.jsx("span",{className:`flex-1 min-w-0 text-2xs font-medium truncate ${M?"text-text-primary":"text-text-tertiary"}`,title:S,children:S}),e.jsxs("span",{className:"flex items-center gap-px shrink-0 opacity-0 group-hover/row:opacity-100 transition-opacity",children:[e.jsx(Be,{to:_e(y,N,t.role),className:"p-0.5 rounded text-text-quaternary hover:text-accent transition-colors",title:`Filter ${He(t.role)}: ${y} = ${S}`,onClick:j=>j.stopPropagation(),children:e.jsx(ys,{className:"w-2.5 h-2.5"})}),e.jsx(Be,{to:_e(y,N),className:"p-0.5 rounded text-text-quaternary hover:text-accent transition-colors",title:`Search all: ${y} = ${S}`,onClick:j=>j.stopPropagation(),children:e.jsx(vs,{className:"w-2.5 h-2.5"})})]})]},y)}),o>0&&e.jsx("button",{className:"flex items-center gap-0.5 text-2xs text-text-quaternary hover:text-accent transition-colors mt-0.5 -mx-1 px-1 py-px",onClick:y=>{y.stopPropagation(),m(N=>!N)},children:n?e.jsxs(e.Fragment,{children:[e.jsx(js,{className:"w-2.5 h-2.5"})," less"]}):e.jsxs(e.Fragment,{children:[e.jsx(Ns,{className:"w-2.5 h-2.5"})," ",o," more"]})})]}),e.jsx(xa,{e:t})]})}function ha({escalations:t,highlightKeys:s=[],onRowClick:i,total:n,page:m,totalPages:x,onPageChange:h}){var d,l;const f=Date.now(),y=t.map(c=>{const k=new Date(c.created_at).getTime(),w=c.resolved_at?new Date(c.resolved_at).getTime():null,g=c.claimed_at?new Date(c.claimed_at).getTime():null,C=!w&&c.status!=="cancelled"&&c.status!=="expired",$=w??(C?f:k+3e4),E=c.status==="pending"&&Ze(c)?"claimed":c.status;return{...c,startMs:k,claimedMs:g,endMs:$,isOpen:C,displayStatus:E}});if(y.length===0)return e.jsx("p",{className:"mt-12 text-center text-sm text-text-tertiary",children:"No escalations matched."});const N=y.length,M=Math.max(Math.abs((((d=y[N-1])==null?void 0:d.startMs)??0)-(((l=y[0])==null?void 0:l.startMs)??0)),1)/Math.max(N-1,1),j=ca/Math.max(M,1),r=new Set(y.map(c=>new Date(c.startMs).toDateString())).size>1;function u(c){const k=new Date(c),w=k.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});return r?k.toLocaleDateString([],{month:"short",day:"numeric"})+" "+w:w}return e.jsxs("div",{className:"mt-4 pb-24",children:[e.jsxs("div",{className:"relative",children:[e.jsx("div",{className:"absolute left-1/2 -translate-x-px inset-y-0 w-px bg-surface-border/80"}),y.map((c,k)=>{const w=y[k-1],g=w?Math.abs(c.startMs-w.startMs):null,C=g!==null?Math.max(da,Math.round(g*j)):0,$=k%2===0,E=oa(c.displayStatus),z=`rgb(var(${E}))`,G=c.endMs-c.startMs,U=c.isOpen?Ge(c.startMs):`${Ge(c.startMs)} · ${tt(G)}`;return e.jsxs("div",{children:[k>0&&e.jsx(ma,{gapMs:g,heightPx:C}),e.jsxs("div",{className:"flex items-center",children:[e.jsx("div",{className:"flex-1 flex justify-end items-center",children:$?e.jsxs("div",{className:"flex items-center",children:[e.jsx(Qe,{e:c,highlightKeys:s,onRowClick:i}),e.jsx("div",{className:"flex-shrink-0 h-px bg-surface-border/70",style:{width:Ve}})]}):e.jsx("span",{className:"text-2xs text-text-quaternary font-mono tabular-nums pr-3",children:U})}),e.jsx("div",{className:"relative z-10 flex-shrink-0 w-3.5 h-3.5 rounded-full border-2 border-surface cursor-pointer transition-all duration-150 hover:scale-[1.5]",style:{backgroundColor:z,boxShadow:`0 0 0 3px rgb(var(${E}) / 0.16), 0 1px 3px rgb(var(${E}) / 0.19)`},onClick:()=>i==null?void 0:i(c)}),e.jsx("div",{className:"flex-1 flex justify-start items-center",children:$?e.jsx("span",{className:"text-2xs text-text-quaternary font-mono tabular-nums pl-3",children:U}):e.jsxs("div",{className:"flex items-center",children:[e.jsx("div",{className:"flex-shrink-0 h-px bg-surface-border/70",style:{width:Ve}}),e.jsx(Qe,{e:c,highlightKeys:s,onRowClick:i})]})})]}),e.jsx("div",{className:"flex justify-center relative z-10 mt-0.5",children:e.jsx("span",{className:"text-2xs text-text-quaternary font-mono tabular-nums bg-surface px-1.5",children:u(c.startMs)})})]},c.id)})]}),x>1&&e.jsxs("div",{className:"sticky bottom-0 z-20 bg-surface/95 backdrop-blur-sm border-t border-surface-border -mx-page-x px-page-x pt-2 pb-4 flex items-center justify-between mt-10",children:[e.jsxs("span",{className:"text-2xs text-text-tertiary",children:["Page ",e.jsx("span",{className:"font-medium text-text-secondary",children:m})," ","of ",e.jsx("span",{className:"font-medium text-text-secondary",children:x})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{onClick:()=>h(m-1),disabled:m<=1,className:"p-1.5 rounded hover:bg-surface-hover disabled:opacity-30 text-text-tertiary hover:text-text-primary transition-colors disabled:cursor-not-allowed",children:e.jsx(gs,{className:"w-4 h-4"})}),e.jsx("button",{onClick:()=>h(m+1),disabled:m>=x,className:"p-1.5 rounded hover:bg-surface-hover disabled:opacity-30 text-text-tertiary hover:text-text-primary transition-colors disabled:cursor-not-allowed",children:e.jsx(bs,{className:"w-4 h-4"})})]})]})]})}function La(){var Fe,Re,Le;Ks();const t=Xe(),{filters:s,setFilter:i,pagination:n}=qs({filters:{role:"",type:"",priority:"",status:"available",search:""}});zt({role:s.role||null,verbs:["created","claimed"]});const m=Ds(s.search),x=Ye(),[h,f]=b.useState(null),[o,y]=b.useState("30"),[N,S]=b.useState(0),M=b.useCallback(a=>S(a),[]),[j,P]=b.useState(new Set),r=b.useRef(null),u=b.useRef(null),d=b.useCallback(a=>{var v;if((v=u.current)==null||v.disconnect(),u.current=null,!a||typeof ResizeObserver>"u")return;const p=new ResizeObserver(()=>{var Z;(Z=r.current)==null||Z.style.setProperty("--lt-sticky-top",`${a.offsetHeight-1}px`)});p.observe(a),u.current=p},[]),[l,c]=b.useState(!1),[k,w]=ms(),g=b.useMemo(()=>Ut(k),[k]),C=b.useCallback(a=>{w(p=>{const v=new URLSearchParams(p);return qt(v,a),v.delete("page"),v})},[w]),{data:$}=Dt(l),E=Vt(g)+(s.search?1:0),z="facet-query",{setPanel:G,closePanel:U,open:st,ownerKey:at}=It();b.useEffect(()=>{if(!l){U(z);return}G(e.jsx(ea,{value:g,onChange:C,facetKeys:($==null?void 0:$.keys)??[],search:s.search??"",onSearchChange:a=>i("search",a),activeFacetCount:E,onClear:()=>{C({}),i("search","")},onClose:()=>c(!1)}),{width:420,key:z})},[l,g,C,$,s.search,i,E,G,U]);const pe=st&&at===z,ae=b.useRef(!1);b.useEffect(()=>{if(pe){ae.current=!0;return}ae.current&&(ae.current=!1,c(!1))},[pe]);const[nt,ne]=b.useState(!1),[rt,re]=b.useState(!1),[it,ie]=b.useState(!1),lt=b.useCallback(a=>C({...g,orderBy:a}),[g,C]),H=We(),{data:Q}=Gt(),fe=Ht(),ot=b.useCallback(()=>{var v;const a=window.prompt("Pin label:");if(!(a!=null&&a.trim()))return;const p=((v=Q==null?void 0:Q.preferences)==null?void 0:v.pinnedViews)??[];fe.mutate({pinnedViews:[...p,{id:Qt(),label:a.trim(),url:H.pathname+H.search,badge:!0}]})},[H.pathname,H.search,Q,fe]),{canBulk:ct}=Kt(),{kiosk:le}=Wt(),ge=g.facets?Object.keys(g.facets):[],oe=k.get("view"),dt=b.useCallback(a=>{w(p=>{const v=new URLSearchParams(p);return a?v.set("view",a):v.delete("view"),v},{replace:!0})},[w]),q=oe==="timeline",ut=b.useCallback(a=>{const{[a]:p,...v}=g.facets??{};C({...g,facets:Object.keys(v).length>0?v:void 0})},[g,C]),be=Xt(),ye=Yt(),ve=Zt(),ce=Jt(),je=es(),de=ts(),K=ss(),{data:ue}=as(),{data:F}=ns(),{data:xe}=rs(),{user:W,isSuperAdmin:xt,hasRoleType:mt}=is(),Ne=xt||mt("admin"),Ce=b.useMemo(()=>new Set(((W==null?void 0:W.roles)??[]).map(a=>a.role)),[W]),ht=b.useMemo(()=>{const a=(F==null?void 0:F.roles)??[];return(Ne?a:a.filter(v=>Ce.has(v.role)&&!hs(v.role))).map(v=>({value:v.role,label:ls(v)})).sort((v,Z)=>v.label.localeCompare(Z.label))},[F,Ne,Ce]);b.useEffect(()=>{P(new Set)},[s.role,s.type,s.priority,s.status,m,n.page,n.pageSize]);const D=s.status||"",X=D==="available",ke=D==="claimed",pt=ke?"pending":D==="resolved"?"resolved":D==="cancelled"?"cancelled":D==="expired"?"expired":void 0,T=s.role||(((Fe=g.roles)==null?void 0:Fe.length)===1?g.roles[0]:null),we=os(T??"",void 0,!!T),ft=cs(T??"",void 0,!!T),me=T?$s((Re=ft.data)==null?void 0:Re.form_schema).cancel:void 0,V=((Le=we.data)==null?void 0:Le.list_schema)??null,Se=!T||we.isFetched,Pe=100,Me={role:s.role||void 0,type:s.type||void 0,priority:s.priority?parseInt(s.priority):void 0,limit:q?Pe:n.pageSize,offset:n.offset,sort_by:"created_at",order:"desc",search:m||void 0,...g,include:zs(V)?"envelope":void 0},gt=ds({...Me,enabled:X&&Se}),bt=us({status:pt,claimed:ke||void 0,...Me,enabled:!X&&Se}),yt=X?gt:bt,{data:R,isLoading:vt,error:Y,refetch:jt,isFetching:Te}=yt,A=(R==null?void 0:R.escalations)??[],O=(R==null?void 0:R.total)??0,Ae=!!T&&!!V&&!!V["x-lt-layout"]&&V["x-lt-layout"]!=="table",Ee=Ae&&!q&&(oe?oe==="rich":!0),Oe=q?"timeline":Ee?"rich":"table",$e=b.useMemo(()=>{if(!g.jeopardy||!T)return null;const a=((F==null?void 0:F.roles)??[]).find(v=>v.role===T),p=(a==null?void 0:a.priority_threshold_minutes)??(a==null?void 0:a.sla_minutes)??null;return p!=null?xs(p*6e4):null},[g.jeopardy,T,F]),Nt=b.useMemo(()=>{const a=new Set;for(const p of A)j.has(p.id)&&a.add(p.role);return[...a]},[A,j]),Ct=b.useMemo(()=>A.filter(a=>j.has(a.id)&&Ze(a)).length,[A,j]),kt=b.useCallback(()=>P(new Set),[]),wt=()=>{if(!h)return;const a=o==="custom"?N:parseInt(o);!a||a<=0||be.mutate({id:h.id,durationMinutes:a},{onSuccess:()=>{f(null),t(`/escalations/detail/${h.id}`)}})},{handleSetPriority:St,handleBulkClaim:Pt,handleBulkTriage:Mt,handleBulkAssign:Tt,handleBulkUnassign:At,handleBulkCancel:Et}=ia({selectedIds:j,clearSelection:kt,setPriority:ye,bulkClaim:ve,bulkTriage:de,bulkAssign:ce,bulkUnassign:je,bulkCancel:K,closeTriageModal:()=>ne(!1),closeAssignModal:()=>re(!1),closeCancelModal:()=>ie(!1)}),Ot=a=>{const p=new Set(j);p.has(a)?p.delete(a):p.add(a),P(p)},$t=()=>{j.size===A.length?P(new Set):P(new Set(A.map(a=>a.id)))},Ft=[ct?{key:"select",label:e.jsx("input",{type:"checkbox",checked:A.length>0&&j.size===A.length,onChange:$t,className:"rounded"}),render:a=>e.jsx("input",{type:"checkbox",checked:j.has(a.id),onChange:p=>{p.stopPropagation(),Ot(a.id)},onClick:p=>p.stopPropagation(),className:"rounded"}),className:"w-10",priority:1}:{key:"spacer",label:"",render:()=>null,className:"w-10",priority:3},...Ls({highlightKeys:ge}),{key:"actions",label:"",render:a=>e.jsx(Hs,{children:e.jsx(Qs,{icon:Cs,title:"Claim escalation",onClick:()=>f(a),alwaysVisible:!0,colorClass:"text-accent/40 hover:text-accent",size:"sm"})}),className:"w-10 text-right"}];return e.jsxs("div",{ref:r,children:[e.jsxs("div",{className:"flex items-center gap-2 mb-10 min-w-0",children:[e.jsx(_s,{role:s.role,options:ht,onChange:a=>i("role",a),locked:le}),!le&&e.jsx("button",{onClick:()=>{window.location.hash="#docs:dashboard.md:all-escalations"},className:"text-text-quaternary hover:text-accent transition-colors mt-1 shrink-0",title:"Open docs for this page",children:e.jsx(ks,{className:"w-4 h-4",strokeWidth:1.5})})]}),e.jsxs("div",{ref:d,className:"sticky top-0 z-20 bg-surface",children:[e.jsx(Bs,{filters:s,setFilter:i,roles:(ue==null?void 0:ue.roles)??[],types:(xe==null?void 0:xe.types)??[],showStatus:!0,showSearch:!1,showRole:!le,actions:e.jsxs(e.Fragment,{children:[q&&e.jsxs("span",{className:"text-2xs text-text-tertiary whitespace-nowrap",children:[O>100&&e.jsxs(e.Fragment,{children:[e.jsxs("span",{className:"font-medium text-text-secondary",children:[(n.page-1)*100+1,"–",Math.min(n.page*100,O)]})," of "]}),e.jsx("span",{className:"font-medium text-text-secondary",children:O})," ",O===1?"escalation":"escalations"]}),e.jsx(ta,{orderBy:g.orderBy,onChange:lt}),e.jsx("div",{role:"radiogroup","aria-label":"List view",className:"flex items-center rounded overflow-hidden border border-surface-border",children:[{key:"table",title:"Table view",Icon:ws},{key:"rich",title:"Rich view",Icon:Ss},{key:"timeline",title:"Timeline view",Icon:Ps}].filter(a=>a.key!=="rich"||Ae).map(({key:a,title:p,Icon:v})=>e.jsx("button",{role:"radio","aria-checked":Oe===a,onClick:()=>dt(a),className:`px-1.5 py-1 transition-colors ${Oe===a?"bg-accent text-text-inverse":"icon-link hover:bg-surface-hover"}`,title:p,children:e.jsx(v,{className:"w-3.5 h-3.5"})},a))}),e.jsxs("button",{onClick:()=>c(a=>!a),"aria-pressed":l,className:`relative rounded border border-surface-border px-1.5 py-1 transition-colors ${l?"bg-accent text-text-inverse":"icon-link hover:bg-surface-hover"}`,title:"Faceted query",children:[e.jsx(Ms,{className:"w-3.5 h-3.5"}),E>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-2xs font-medium text-text-inverse",children:E})]}),e.jsxs("div",{className:"flex items-center gap-0.5",children:[e.jsx("button",{onClick:()=>jt(),disabled:Te,className:"inline-flex h-7 w-7 items-center justify-center rounded icon-link hover:bg-surface-hover disabled:opacity-50",title:"Refresh",children:e.jsx(Ts,{className:`w-4 h-4 ${Te?"animate-spin":""}`})}),e.jsx("button",{onClick:ot,className:"inline-flex h-7 w-7 items-center justify-center rounded icon-link hover:bg-surface-hover",title:"Pin this view — save the current filters to your Pinned section","data-testid":"pin-current-view",children:e.jsx(As,{className:"w-4 h-4"})})]})]})}),e.jsx(na,{selectedCount:j.size,onClearSelection:()=>P(new Set),onSetPriority:St,onClaim:Pt,onAssign:()=>re(!0),onUnassign:At,onTriage:()=>ne(!0),onCancel:()=>ie(!0),isPriorityPending:ye.isPending,isClaimPending:ve.isPending,isAssignPending:ce.isPending,isUnassignPending:je.isPending,isTriagePending:de.isPending,isCancelPending:K.isPending,cancelLabel:me}),(g.facets&&Object.keys(g.facets).length>0||g.jeopardy)&&e.jsxs("div",{className:"bg-surface/98 backdrop-blur-sm border-b border-surface-border/30 -mx-page-x px-page-x py-2 flex items-center gap-1.5 flex-wrap",children:[g.jeopardy&&e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full bg-status-error px-2.5 py-0.5 text-2xs font-semibold text-text-inverse",children:[e.jsx(Es,{className:"w-2.5 h-2.5",strokeWidth:2.5}),"in jeopardy",$e&&e.jsxs("span",{className:"font-mono font-normal opacity-90",children:["> ",$e]}),e.jsx("button",{onClick:()=>C({...g,jeopardy:void 0}),className:"ml-0.5 -mr-0.5 flex items-center text-text-inverse/70 hover:text-text-inverse transition-colors","aria-label":"Clear jeopardy filter",children:e.jsx(se,{className:"w-2.5 h-2.5"})})]}),Object.entries(g.facets??{}).map(([a,p])=>e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full border border-accent/25 bg-accent/8 px-2.5 py-0.5 text-2xs font-medium text-accent/90",children:[e.jsx("span",{className:"font-mono text-text-tertiary",children:a}),e.jsx("span",{className:"text-text-quaternary",children:"="}),e.jsx("span",{className:"font-mono max-w-[160px] truncate",title:String(p),children:String(p)}),e.jsx("button",{onClick:()=>ut(a),className:"ml-0.5 -mr-0.5 flex items-center text-text-quaternary hover:text-status-error transition-colors","aria-label":`Remove ${a} filter`,children:e.jsx(se,{className:"w-2.5 h-2.5"})})]},a)),Object.keys(g.facets??{}).length>1&&e.jsx("button",{onClick:()=>C({...g,facets:void 0}),className:"text-2xs text-text-quaternary hover:text-text-secondary transition-colors px-1",children:"clear all"})]})]}),Y&&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:Y.message==="Session expired"?"Your session has expired. Please log in again.":`Failed to load escalations: ${Y.message}`}),q?e.jsx(ha,{escalations:A,highlightKeys:ge,onRowClick:a=>t(`/escalations/detail/${a.id}`,{state:{from:"/escalations/available"}}),total:O,page:n.page,totalPages:Math.ceil(O/Pe),onPageChange:n.setPage}):Ee?e.jsx(Us,{role:T,listSchema:V,activeEscalations:A,onRowClick:a=>t(`/escalations/detail/${a.id}`,{state:{from:"/escalations/available"}}),onOpenGroup:a=>t(a),onAddFacet:(a,p)=>C({...g,facets:{...g.facets??{},[a]:typeof p=="object"&&p!==null?JSON.stringify(p):p}}),total:O,page:n.page,totalPages:n.totalPages(O),pageSize:n.pageSize,onPageChange:n.setPage,onPageSizeChange:n.setPageSize}):e.jsxs(e.Fragment,{children:[e.jsx(Vs,{columns:Ft,data:A,layout:"fixed",keyFn:a=>a.id,onRowClick:a=>t(`/escalations/detail/${a.id}`,{state:{from:"/escalations/available"}}),isLoading:vt,emptyMessage:Y?"Unable to load data":"No escalations"}),e.jsx(Is,{page:n.page,totalPages:n.totalPages(O),onPageChange:n.setPage,total:O,pageSize:n.pageSize,onPageSizeChange:n.setPageSize})]}),e.jsx(la,{claimTarget:h,onClose:()=>f(null),claimDuration:o,onDurationChange:a=>{y(a),S(0)},claimDurations:x,customClaimMinutes:N,onCustomClaimChange:M,onClaim:wt,isPending:be.isPending}),e.jsx(ra,{open:nt,onClose:()=>ne(!1),selectedCount:j.size,onSubmit:Mt,isPending:de.isPending}),e.jsx(Fs,{open:rt,onClose:()=>re(!1),selectedCount:j.size,selectedRoles:Nt,claimedCount:Ct,onSubmit:Tt,isPending:ce.isPending}),e.jsx(Rs,{open:it,onClose:()=>ie(!1),onConfirm:Et,selectedCount:j.size,isPending:K.isPending,error:K.error,actionLabel:typeof me=="string"?me:void 0})]})}export{La as AvailableEscalationsPage};
|
|
2
|
-
//# sourceMappingURL=AvailableEscalationsPage-D2ukvuQh.js.map
|