@hotmeshio/long-tail 0.30.4 → 0.31.0
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 -0
- package/build/api/escalations/index.js +5 -2
- package/build/api/escalations/roster-action.d.ts +11 -0
- package/build/api/escalations/roster-action.js +47 -30
- package/build/api/escalations/roster-scan.d.ts +26 -0
- package/build/api/escalations/roster-scan.js +114 -0
- package/build/api/labels/errors.d.ts +3 -0
- package/build/api/labels/errors.js +15 -0
- package/build/api/labels/index.d.ts +2 -0
- package/build/api/labels/index.js +17 -0
- package/build/api/labels/issue.d.ts +54 -0
- package/build/api/labels/issue.js +144 -0
- package/build/api/labels/templates.d.ts +29 -0
- package/build/api/labels/templates.js +98 -0
- package/build/api/scan-codes/context.d.ts +9 -1
- package/build/api/scan-codes/context.js +16 -1
- package/build/api/scan-codes/execute.js +6 -1
- package/build/api/scan-codes/fill-labels.d.ts +8 -0
- package/build/api/scan-codes/fill-labels.js +23 -2
- package/build/api/scan-codes/hold.js +2 -0
- package/build/api/scan-codes/located.d.ts +10 -0
- package/build/api/scan-codes/located.js +74 -0
- package/build/api/scan-codes/open.d.ts +9 -0
- package/build/api/scan-codes/open.js +99 -0
- package/build/api/scan-codes/present.js +1 -0
- package/build/api/scan-codes/verb-fill.js +1 -1
- package/build/api/users.d.ts +8 -4
- package/build/api/users.js +51 -13
- package/build/index.d.ts +1 -0
- package/build/index.js +4 -2
- package/build/lib/db/schemas/044_label_sheets.sql +65 -0
- package/build/lib/db/schemas/045_label_job_delivery.sql +14 -0
- package/build/lib/labels/transports.d.ts +23 -0
- package/build/lib/labels/transports.js +39 -0
- package/build/modules/auth.d.ts +2 -0
- package/build/modules/auth.js +3 -1
- package/build/modules/capabilities.d.ts +5 -1
- package/build/modules/capabilities.js +38 -8
- package/build/modules/config.d.ts +10 -0
- package/build/modules/config.js +10 -0
- package/build/routes/escalations/resolve.js +18 -0
- package/build/routes/index.js +2 -0
- package/build/routes/labels.d.ts +2 -0
- package/build/routes/labels.js +135 -0
- package/build/routes/users.js +1 -1
- package/build/services/labels/content.d.ts +13 -0
- package/build/services/labels/content.js +81 -0
- package/build/services/labels/errors.d.ts +5 -0
- package/build/services/labels/errors.js +12 -0
- package/build/services/labels/index.d.ts +11 -0
- package/build/services/labels/index.js +52 -0
- package/build/services/labels/issue.d.ts +38 -0
- package/build/services/labels/issue.js +181 -0
- package/build/services/labels/jobs.d.ts +37 -0
- package/build/services/labels/jobs.js +75 -0
- package/build/services/labels/media.d.ts +11 -0
- package/build/services/labels/media.js +44 -0
- package/build/services/labels/reissue.d.ts +13 -0
- package/build/services/labels/reissue.js +65 -0
- package/build/services/labels/render-pdf.d.ts +11 -0
- package/build/services/labels/render-pdf.js +138 -0
- package/build/services/labels/targets.d.ts +18 -0
- package/build/services/labels/targets.js +216 -0
- package/build/services/labels/templates/index.d.ts +3 -0
- package/build/services/labels/templates/index.js +18 -0
- package/build/services/labels/templates/read.d.ts +4 -0
- package/build/services/labels/templates/read.js +36 -0
- package/build/services/labels/templates/sql.d.ts +8 -0
- package/build/services/labels/templates/sql.js +50 -0
- package/build/services/labels/templates/validate.d.ts +19 -0
- package/build/services/labels/templates/validate.js +93 -0
- package/build/services/labels/templates/write.d.ts +16 -0
- package/build/services/labels/templates/write.js +75 -0
- package/build/services/labels/token.d.ts +9 -0
- package/build/services/labels/token.js +28 -0
- package/build/services/labels/verify.d.ts +4 -0
- package/build/services/labels/verify.js +38 -0
- package/build/services/role/index.d.ts +2 -0
- package/build/services/role/index.js +7 -0
- package/build/services/role/scan-done.js +4 -1
- package/build/services/role/sql.d.ts +1 -0
- package/build/services/role/sql.js +3 -1
- package/build/services/role/types.d.ts +2 -0
- package/build/services/scan-code/index.d.ts +1 -1
- package/build/services/scan-code/index.js +2 -1
- package/build/services/scan-code/parse.d.ts +5 -1
- package/build/services/scan-code/parse.js +8 -2
- package/build/services/scan-code/validate-station.d.ts +13 -0
- package/build/services/scan-code/validate-station.js +81 -0
- package/build/services/scan-code/validate-subject.js +33 -6
- package/build/services/scan-code/validate.d.ts +3 -0
- package/build/services/scan-code/validate.js +22 -18
- package/build/services/user/crud.d.ts +13 -1
- package/build/services/user/crud.js +42 -11
- package/build/services/user/index.d.ts +3 -2
- package/build/services/user/index.js +7 -1
- package/build/services/user/redact.d.ts +17 -0
- package/build/services/user/redact.js +32 -0
- package/build/services/user/sql.d.ts +8 -15
- package/build/services/user/sql.js +27 -3
- package/build/services/user/types.d.ts +21 -1
- package/build/shared/labels/compose.d.ts +12 -0
- package/build/shared/labels/compose.js +43 -0
- package/build/shared/labels/index.d.ts +9 -0
- package/build/shared/labels/index.js +54 -0
- package/build/shared/labels/label-content.d.ts +17 -0
- package/build/shared/labels/label-content.js +137 -0
- package/build/shared/labels/layout.d.ts +23 -0
- package/build/shared/labels/layout.js +81 -0
- package/build/shared/labels/media.d.ts +22 -0
- package/build/shared/labels/media.js +116 -0
- package/build/shared/labels/render-svg.d.ts +10 -0
- package/build/shared/labels/render-svg.js +58 -0
- package/build/shared/labels/render-zpl.d.ts +9 -0
- package/build/shared/labels/render-zpl.js +63 -0
- package/build/shared/labels/symbol.d.ts +18 -0
- package/build/shared/labels/symbol.js +74 -0
- package/build/shared/labels/tokens.d.ts +18 -0
- package/build/shared/labels/tokens.js +43 -0
- package/build/shared/labels/types.d.ts +105 -0
- package/build/shared/labels/types.js +11 -0
- package/build/start/adapters.js +16 -0
- package/build/start/workers.js +18 -2
- package/build/system/mcp-servers/admin/index.js +2 -0
- package/build/system/mcp-servers/admin/labels-schemas.d.ts +192 -0
- package/build/system/mcp-servers/admin/labels-schemas.js +46 -0
- package/build/system/mcp-servers/admin/labels.d.ts +9 -0
- package/build/system/mcp-servers/admin/labels.js +101 -0
- package/build/system/mcp-servers/admin/schemas.d.ts +491 -24
- package/build/system/mcp-servers/admin/schemas.js +32 -4
- package/build/system/mcp-servers/admin/users.js +1 -1
- package/build/system/seed/tool-manifests-admin.js +5 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/capability.d.ts +2 -1
- package/build/types/index.d.ts +3 -2
- package/build/types/labels/index.d.ts +4 -0
- package/build/types/labels/index.js +2 -0
- package/build/types/labels/job.d.ts +51 -0
- package/build/types/labels/job.js +2 -0
- package/build/types/labels/source.d.ts +44 -0
- package/build/types/labels/source.js +2 -0
- package/build/types/labels/template.d.ts +46 -0
- package/build/types/labels/template.js +2 -0
- package/build/types/labels/transport.d.ts +24 -0
- package/build/types/labels/transport.js +2 -0
- package/build/types/scan-choice.d.ts +2 -4
- package/build/types/scan-code/constants.d.ts +1 -0
- package/build/types/scan-code/constants.js +1 -0
- package/build/types/scan-code/response.d.ts +22 -4
- package/build/types/scan-code/rule.d.ts +66 -3
- package/build/types/startup.d.ts +37 -0
- package/build/types/user.d.ts +2 -0
- package/dashboard/dist/assets/{AdminDashboard-VQ1fhhJP.js → AdminDashboard-BafKaq50.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-VQ1fhhJP.js.map → AdminDashboard-BafKaq50.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-BOe_W2Ij.js → AgentConfigPage-CFHf31DT.js} +6 -6
- package/dashboard/dist/assets/{AgentConfigPage-BOe_W2Ij.js.map → AgentConfigPage-CFHf31DT.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-5ov5D9V2.js → AgentDetailPage-CEvz5rJr.js} +3 -3
- package/dashboard/dist/assets/{AgentDetailPage-5ov5D9V2.js.map → AgentDetailPage-CEvz5rJr.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-DDFMKHhI.js → AgentsPage-DjQaio0O.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-DDFMKHhI.js.map → AgentsPage-DjQaio0O.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-UB03VTJx.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-UB03VTJx.js.map +1 -0
- package/dashboard/dist/assets/{BotPicker-Dqpo36dM.js → BotPicker-C7MNWOF7.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-Dqpo36dM.js.map → BotPicker-C7MNWOF7.js.map} +1 -1
- package/dashboard/dist/assets/BulkAssignModal-h5fX-_cV.js +2 -0
- package/dashboard/dist/assets/{BulkAssignModal-CmLVxkz-.js.map → BulkAssignModal-h5fX-_cV.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-Dfkip6_b.js → CapabilitiesPage-BIzDl-ZT.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-Dfkip6_b.js.map → CapabilitiesPage-BIzDl-ZT.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-CYNYMYSa.js → CollapsibleSection-B5TivtEg.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-CYNYMYSa.js.map → CollapsibleSection-B5TivtEg.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-CpJNP-8w.js → ConfirmDeleteModal-CB4nKePb.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-CpJNP-8w.js.map → ConfirmDeleteModal-CB4nKePb.js.map} +1 -1
- package/dashboard/dist/assets/{ConnectedAppsPage-DXIp2Dpl.js → ConnectedAppsPage-B3S5gVWw.js} +2 -2
- package/dashboard/dist/assets/{ConnectedAppsPage-DXIp2Dpl.js.map → ConnectedAppsPage-B3S5gVWw.js.map} +1 -1
- package/dashboard/dist/assets/{CountdownTimer-CuPY7zkb.js → CountdownTimer-BHVIq3kA.js} +2 -2
- package/dashboard/dist/assets/{CountdownTimer-CuPY7zkb.js.map → CountdownTimer-BHVIq3kA.js.map} +1 -1
- package/dashboard/dist/assets/CredentialConfirmModal-w0AGmCIe.js +2 -0
- package/dashboard/dist/assets/CredentialConfirmModal-w0AGmCIe.js.map +1 -0
- package/dashboard/dist/assets/{CredentialsPage-CtrnkHcj.js → CredentialsPage-BtCGBJrT.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-CtrnkHcj.js.map → CredentialsPage-BtCGBJrT.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-DVjTw5Ri.js → CronLabel-BG1rZK-5.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-DVjTw5Ri.js.map → CronLabel-BG1rZK-5.js.map} +1 -1
- package/dashboard/dist/assets/{DropZone-DefYTYQy.js → DropZone-D8ZVdEb5.js} +2 -2
- package/dashboard/dist/assets/{DropZone-DefYTYQy.js.map → DropZone-D8ZVdEb5.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-gY_mGMTF.js → ElapsedCell-l4m8Yvfv.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-gY_mGMTF.js.map → ElapsedCell-l4m8Yvfv.js.map} +1 -1
- package/dashboard/dist/assets/{EntityTimelinePanel-DJN_ZEQa.js → EntityTimelinePanel-BOHlIaxF.js} +2 -2
- package/dashboard/dist/assets/{EntityTimelinePanel-DJN_ZEQa.js.map → EntityTimelinePanel-BOHlIaxF.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-A4KpTdJA.js → EscalationListSchemaPage-BotlwlX3.js} +3 -3
- package/dashboard/dist/assets/{EscalationListSchemaPage-A4KpTdJA.js.map → EscalationListSchemaPage-BotlwlX3.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-nfCn42hT.js → EscalationSchemaPage-CfZSVOSD.js} +3 -3
- package/dashboard/dist/assets/{EscalationSchemaPage-nfCn42hT.js.map → EscalationSchemaPage-CfZSVOSD.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationTimeline-CLvSr1SD.js → EscalationTimeline-CCKpuRBU.js} +2 -2
- package/dashboard/dist/assets/{EscalationTimeline-CLvSr1SD.js.map → EscalationTimeline-CCKpuRBU.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationTitleSelect-CT7mYHkb.js → EscalationTitleSelect-cpTzPHiW.js} +2 -2
- package/dashboard/dist/assets/{EscalationTitleSelect-CT7mYHkb.js.map → EscalationTitleSelect-cpTzPHiW.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-CKaGRh-E.js → EscalationsOverview-DS-nK0qV.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-CKaGRh-E.js.map → EscalationsOverview-DS-nK0qV.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-2ywJsOLy.js → EventTable-UfebhJf0.js} +2 -2
- package/dashboard/dist/assets/{EventTable-2ywJsOLy.js.map → EventTable-UfebhJf0.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-Dy0b7wwf.js → FilterBar-newA5l-X.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-Dy0b7wwf.js.map → FilterBar-newA5l-X.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-yOVpraAy.js → GraphInvokePage-6SCDyQcK.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-yOVpraAy.js.map → GraphInvokePage-6SCDyQcK.js.map} +1 -1
- package/dashboard/dist/assets/HomePage-BEc-XdKj.js +2 -0
- package/dashboard/dist/assets/{HomePage-67xXjKjN.js.map → HomePage-BEc-XdKj.js.map} +1 -1
- package/dashboard/dist/assets/LabelJobsPage-BO50zXT5.js +2 -0
- package/dashboard/dist/assets/LabelJobsPage-BO50zXT5.js.map +1 -0
- package/dashboard/dist/assets/{LinePage-CMsYtukW.js → LinePage-NYxJQ-ex.js} +3 -3
- package/dashboard/dist/assets/{LinePage-CMsYtukW.js.map → LinePage-NYxJQ-ex.js.map} +1 -1
- package/dashboard/dist/assets/{LinesPage-pwL46mOS.js → LinesPage-RbWTaQRh.js} +3 -3
- package/dashboard/dist/assets/{LinesPage-pwL46mOS.js.map → LinesPage-RbWTaQRh.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-CJmvGy2B.js → ListToolbar-B-E9-toh.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-CJmvGy2B.js.map → ListToolbar-B-E9-toh.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-DA9LLvNG.js → McpOverview-Shcf9QhZ.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-DA9LLvNG.js.map → McpOverview-Shcf9QhZ.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-N7qLmfE8.js → McpQueryDetailPage-D8kmjy2v.js} +3 -3
- package/dashboard/dist/assets/{McpQueryDetailPage-N7qLmfE8.js.map → McpQueryDetailPage-D8kmjy2v.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-CpsP3w7x.js → McpQueryPage-ck-o5m8A.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-CpsP3w7x.js.map → McpQueryPage-ck-o5m8A.js.map} +1 -1
- package/dashboard/dist/assets/McpRunDetailPage-BJKkM9-3.js +2 -0
- package/dashboard/dist/assets/{McpRunDetailPage-qHRQ1pEY.js.map → McpRunDetailPage-BJKkM9-3.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-BRDDYpTM.js → McpRunsPage-DqhHfD5G.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-BRDDYpTM.js.map → McpRunsPage-DqhHfD5G.js.map} +1 -1
- package/dashboard/dist/assets/{NamespacePill-CeSfHH-j.js → NamespacePill--uIaGtrN.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-CeSfHH-j.js.map → NamespacePill--uIaGtrN.js.map} +1 -1
- package/dashboard/dist/assets/{OperationsPage-zUaab-CL.js → OperationsPage-D6B9Vv__.js} +3 -3
- package/dashboard/dist/assets/{OperationsPage-zUaab-CL.js.map → OperationsPage-D6B9Vv__.js.map} +1 -1
- package/dashboard/dist/assets/OperatorDashboard-CIH1cxjQ.js +2 -0
- package/dashboard/dist/assets/{OperatorDashboard-el5BquXN.js.map → OperatorDashboard-CIH1cxjQ.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-DiGWAQlR.js → PageHeader-DClJ33fV.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-DiGWAQlR.js.map → PageHeader-DClJ33fV.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-DwnKQ06j.js → PageHeaderWithStats-C-TrbKQL.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-DwnKQ06j.js.map → PageHeaderWithStats-C-TrbKQL.js.map} +1 -1
- package/dashboard/dist/assets/PersonaDetailPage-DjvfyIph.js +2 -0
- package/dashboard/dist/assets/{PersonaDetailPage-B_tb8gfl.js.map → PersonaDetailPage-DjvfyIph.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-BPI7mqM8.js → PersonasPage-D7ryA8Vc.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-BPI7mqM8.js.map → PersonasPage-D7ryA8Vc.js.map} +1 -1
- package/dashboard/dist/assets/{PortalPage-e_rBb1do.js → PortalPage-D3ybr0mo.js} +2 -2
- package/dashboard/dist/assets/{PortalPage-e_rBb1do.js.map → PortalPage-D3ybr0mo.js.map} +1 -1
- package/dashboard/dist/assets/PrintLabelsPanel-D0HF5x8b.js +2 -0
- package/dashboard/dist/assets/PrintLabelsPanel-D0HF5x8b.js.map +1 -0
- package/dashboard/dist/assets/{ProcessDetailPage-D35RX1bB.js → ProcessDetailPage-0xS9EdHe.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-D35RX1bB.js.map → ProcessDetailPage-0xS9EdHe.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-CT81miI5.js → ProcessesListPage-93SMj1Fd.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-CT81miI5.js.map → ProcessesListPage-93SMj1Fd.js.map} +1 -1
- package/dashboard/dist/assets/{ResolverForm-BxJkoKAO.js → ResolverForm-DfogHDzl.js} +5 -5
- package/dashboard/dist/assets/{ResolverForm-BxJkoKAO.js.map → ResolverForm-DfogHDzl.js.map} +1 -1
- package/dashboard/dist/assets/RoleDetailPage-DlUOJWSB.js +8 -0
- package/dashboard/dist/assets/{RoleDetailPage-DtU7vsJm.js.map → RoleDetailPage-DlUOJWSB.js.map} +1 -1
- package/dashboard/dist/assets/{RolePill-D3hkAdKf.js → RolePill-BjD1Qw5y.js} +2 -2
- package/dashboard/dist/assets/{RolePill-D3hkAdKf.js.map → RolePill-BjD1Qw5y.js.map} +1 -1
- package/dashboard/dist/assets/RolesPage-DqhHSvaw.js +2 -0
- package/dashboard/dist/assets/{RolesPage-BE7RWt9q.js.map → RolesPage-DqhHSvaw.js.map} +1 -1
- package/dashboard/dist/assets/{RosterWidget-BJMx0a8Z.js → RosterWidget-BrIq61HR.js} +2 -2
- package/dashboard/dist/assets/RosterWidget-BrIq61HR.js.map +1 -0
- package/dashboard/dist/assets/RunAsSelector-D6zQrCNr.js +2 -0
- package/dashboard/dist/assets/{RunAsSelector-Co6s9bqA.js.map → RunAsSelector-D6zQrCNr.js.map} +1 -1
- package/dashboard/dist/assets/ScanCodesPage-B2S9DR2f.js +2 -0
- package/dashboard/dist/assets/{ScanCodesPage-C2TETaj5.js.map → ScanCodesPage-B2S9DR2f.js.map} +1 -1
- package/dashboard/dist/assets/ScanSchemeDetailPage-gpxKN-pL.js +5 -0
- package/dashboard/dist/assets/ScanSchemeDetailPage-gpxKN-pL.js.map +1 -0
- package/dashboard/dist/assets/ScanStationPage-B-UTgXsG.js +2 -0
- package/dashboard/dist/assets/ScanStationPage-B-UTgXsG.js.map +1 -0
- package/dashboard/dist/assets/{SchemeMatchFields-9H7SmbED.js → SchemeMatchFields-BK24aa7K.js} +2 -2
- package/dashboard/dist/assets/{SchemeMatchFields-9H7SmbED.js.map → SchemeMatchFields-BK24aa7K.js.map} +1 -1
- package/dashboard/dist/assets/{ScopeBadge-DGz79rmG.js → ScopeBadge-ofLQ6HW-.js} +2 -2
- package/dashboard/dist/assets/{ScopeBadge-DGz79rmG.js.map → ScopeBadge-ofLQ6HW-.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-miUdVAKw.js → StickyPagination-CgVv7vc_.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-miUdVAKw.js.map → StickyPagination-CgVv7vc_.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-D5Rk7pn7.js → StreamMessageDetail-B9sxDVw4.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-D5Rk7pn7.js.map → StreamMessageDetail-B9sxDVw4.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-B1QY1ZzH.js → SwimlaneTimeline-DQc0CYSL.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-B1QY1ZzH.js.map → SwimlaneTimeline-DQc0CYSL.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-DaIdhv3h.js → TagInput-47qVYzke.js} +2 -2
- package/dashboard/dist/assets/{TagInput-DaIdhv3h.js.map → TagInput-47qVYzke.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-DKUM37o8.js → TaskDetailPage-D6VOsA1f.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-DKUM37o8.js.map → TaskDetailPage-D6VOsA1f.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-sUA1nZe-.js → TaskQueuePill-C5KmdXAl.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-sUA1nZe-.js.map → TaskQueuePill-C5KmdXAl.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-CUulwvm-.js → TasksListPage-DG8hvO8G.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-CUulwvm-.js.map → TasksListPage-DG8hvO8G.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-CHTelacB.js → TimeAgo-CL02EhFi.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-CHTelacB.js.map → TimeAgo-CL02EhFi.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-NanLWLKo.js → TimestampCell-BE7oKVJg.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-NanLWLKo.js.map → TimestampCell-BE7oKVJg.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-CpBAFdEX.js → ToolPill-Cp9Drk1s.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-CpBAFdEX.js.map → ToolPill-Cp9Drk1s.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-CF1CHzgz.js → ToolTestPanel-CRecLh6S.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-CF1CHzgz.js.map → ToolTestPanel-CRecLh6S.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-CGO8XV_a.js → TopicDetailPage-QzkinTfN.js} +3 -3
- package/dashboard/dist/assets/{TopicDetailPage-CGO8XV_a.js.map → TopicDetailPage-QzkinTfN.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-Bt8gOKYr.js → TopicsPage-D8dW6J65.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-Bt8gOKYr.js.map → TopicsPage-D8dW6J65.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-DKXnK7DD.js → UserName-Dw3R_zrl.js} +2 -2
- package/dashboard/dist/assets/{UserName-DKXnK7DD.js.map → UserName-Dw3R_zrl.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-BTocv8or.js +2 -0
- package/dashboard/dist/assets/{WorkflowExecutionPage-Crf7AIFc.js.map → WorkflowExecutionPage-BTocv8or.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowPill-CKHip3hH.js → WorkflowPill-BiLYq__w.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill-CKHip3hH.js.map → WorkflowPill-BiLYq__w.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowsDashboard-CIPEt3et.js +2 -0
- package/dashboard/dist/assets/{WorkflowsDashboard--isjt06C.js.map → WorkflowsDashboard-CIPEt3et.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-D7Oqf4-V.js → WorkflowsOverview-Bj4MJIE-.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-D7Oqf4-V.js.map → WorkflowsOverview-Bj4MJIE-.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-B0wxgrGP.js → YamlWorkflowDetailPage-DMEk5k9-.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-B0wxgrGP.js.map → YamlWorkflowDetailPage-DMEk5k9-.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-BVdLnm6K.js → YamlWorkflowsPage-F2yyyoiB.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-BVdLnm6K.js.map → YamlWorkflowsPage-F2yyyoiB.js.map} +1 -1
- package/dashboard/dist/assets/{agents-CHjbjHXA.js → agents-mSgxEPpI.js} +2 -2
- package/dashboard/dist/assets/{agents-CHjbjHXA.js.map → agents-mSgxEPpI.js.map} +1 -1
- package/dashboard/dist/assets/{bots-WrUhEPWs.js → bots-p4Hp0CV6.js} +2 -2
- package/dashboard/dist/assets/{bots-WrUhEPWs.js.map → bots-p4Hp0CV6.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-CunMmkj8.js → capabilities-D_-I_SXR.js} +2 -2
- package/dashboard/dist/assets/{capabilities-CunMmkj8.js.map → capabilities-D_-I_SXR.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-D6IZIZoh.js → controlplane-DjdoQnRU.js} +2 -2
- package/dashboard/dist/assets/{controlplane-D6IZIZoh.js.map → controlplane-DjdoQnRU.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-Bvo6JI4Z.js → escalation-columns-R_IEVQjQ.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-Bvo6JI4Z.js.map → escalation-columns-R_IEVQjQ.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-items-DFGRwo49.js → escalation-items-BGZlJMpk.js} +2 -2
- package/dashboard/dist/assets/{escalation-items-DFGRwo49.js.map → escalation-items-BGZlJMpk.js.map} +1 -1
- package/dashboard/dist/assets/{index-OuKQ_0eB.js → index-BEMdD58x.js} +2 -2
- package/dashboard/dist/assets/{index-OuKQ_0eB.js.map → index-BEMdD58x.js.map} +1 -1
- package/dashboard/dist/assets/index-BUmz0NMg.css +1 -0
- package/dashboard/dist/assets/{index-C7EIu1mG.js → index-BuCEhhnl.js} +2 -2
- package/dashboard/dist/assets/{index-C7EIu1mG.js.map → index-BuCEhhnl.js.map} +1 -1
- package/dashboard/dist/assets/{index-Bo8QU31k.js → index-BxbQmeqh.js} +2 -2
- package/dashboard/dist/assets/{index-Bo8QU31k.js.map → index-BxbQmeqh.js.map} +1 -1
- package/dashboard/dist/assets/index-C5osluV3.js +2 -0
- package/dashboard/dist/assets/{index-DRK7M1_9.js.map → index-C5osluV3.js.map} +1 -1
- package/dashboard/dist/assets/{index-ygxyAKcc.js → index-C_dAJUzh.js} +27 -27
- package/dashboard/dist/assets/index-C_dAJUzh.js.map +1 -0
- package/dashboard/dist/assets/{index-DRw0FXdX.js → index-D-FYj9jT.js} +2 -2
- package/dashboard/dist/assets/{index-DRw0FXdX.js.map → index-D-FYj9jT.js.map} +1 -1
- package/dashboard/dist/assets/{index-B8qrHwp9.js → index-D6K_IgCz.js} +2 -2
- package/dashboard/dist/assets/{index-B8qrHwp9.js.map → index-D6K_IgCz.js.map} +1 -1
- package/dashboard/dist/assets/index-D7L_VoBD.js +2 -0
- package/dashboard/dist/assets/index-D7L_VoBD.js.map +1 -0
- package/dashboard/dist/assets/{index-BZFSXEkr.js → index-D9RAN9sA.js} +2 -2
- package/dashboard/dist/assets/{index-BZFSXEkr.js.map → index-D9RAN9sA.js.map} +1 -1
- package/dashboard/dist/assets/{index-DCJ483vt.js → index-DUYAGxwc.js} +2 -2
- package/dashboard/dist/assets/{index-DCJ483vt.js.map → index-DUYAGxwc.js.map} +1 -1
- package/dashboard/dist/assets/{index-boT612Jo.js → index-Dk2KKo0z.js} +2 -2
- package/dashboard/dist/assets/{index-boT612Jo.js.map → index-Dk2KKo0z.js.map} +1 -1
- package/dashboard/dist/assets/{index-CpCchhQv.js → index-DlJkZ12b.js} +2 -2
- package/dashboard/dist/assets/{index-CpCchhQv.js.map → index-DlJkZ12b.js.map} +1 -1
- package/dashboard/dist/assets/index-FiNThtNU.js +3 -0
- package/dashboard/dist/assets/index-FiNThtNU.js.map +1 -0
- package/dashboard/dist/assets/{knowledge-BubJBTwg.js → knowledge-DSsPTqkK.js} +2 -2
- package/dashboard/dist/assets/{knowledge-BubJBTwg.js.map → knowledge-DSsPTqkK.js.map} +1 -1
- package/dashboard/dist/assets/{machines-DSm5NFgs.js → machines-DSgGtqqr.js} +2 -2
- package/dashboard/dist/assets/{machines-DSm5NFgs.js.map → machines-DSgGtqqr.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-D6MckqOV.js → mcp-Cg-_uLw8.js} +2 -2
- package/dashboard/dist/assets/{mcp-D6MckqOV.js.map → mcp-Cg-_uLw8.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-VyCdOag6.js → mcp-query-DQombEK_.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-VyCdOag6.js.map → mcp-query-DQombEK_.js.map} +1 -1
- package/dashboard/dist/assets/{personas-CyJc10xe.js → personas-DYrcoVBu.js} +2 -2
- package/dashboard/dist/assets/{personas-CyJc10xe.js.map → personas-DYrcoVBu.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-B2inDtx3.js → pipelines-wdb4xsey.js} +2 -2
- package/dashboard/dist/assets/{pipelines-B2inDtx3.js.map → pipelines-wdb4xsey.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-DOP4d3M6.js → tasks-Bil7gvm9.js} +2 -2
- package/dashboard/dist/assets/{tasks-DOP4d3M6.js.map → tasks-Bil7gvm9.js.map} +1 -1
- package/dashboard/dist/assets/{topics-CNOjSWpX.js → topics-wBqaVhRR.js} +2 -2
- package/dashboard/dist/assets/{topics-CNOjSWpX.js.map → topics-wBqaVhRR.js.map} +1 -1
- package/dashboard/dist/assets/{useDebouncedValue-CgO0TGMd.js → useDebouncedValue-CwrY8TpV.js} +2 -2
- package/dashboard/dist/assets/{useDebouncedValue-CgO0TGMd.js.map → useDebouncedValue-CwrY8TpV.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-BWHvUKtK.js → useNamespace-Sod_xApz.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-BWHvUKtK.js.map → useNamespace-Sod_xApz.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-BZQ__ZGD.js → useYamlActivityEvents-CKLInV3C.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-BZQ__ZGD.js.map → useYamlActivityEvents-CKLInV3C.js.map} +1 -1
- package/dashboard/dist/assets/{validate-CAin6WM_.js → validate-CYhW1xMJ.js} +2 -2
- package/dashboard/dist/assets/{validate-CAin6WM_.js.map → validate-CYhW1xMJ.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-en0_uSRD.js → vendor-icons-ed7mYQw4.js} +2 -2
- package/dashboard/dist/assets/{vendor-icons-en0_uSRD.js.map → vendor-icons-ed7mYQw4.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-Dyln3od-.js → yaml-workflows-C20qHo3L.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-Dyln3od-.js.map → yaml-workflows-C20qHo3L.js.map} +1 -1
- package/dashboard/dist/index.html +3 -3
- package/docs/api/http/escalations.md +15 -0
- package/docs/api/http/labels.md +115 -0
- package/docs/api/http/users.md +2 -0
- package/docs/api/mcp/admin.md +76 -1
- package/docs/code-owned-configuration.md +1 -1
- package/docs/dashboard.md +2 -2
- package/docs/hitl/x-lt-roster.md +2 -0
- package/docs/hitl/x-lt-scan.md +12 -0
- package/docs/iam.md +12 -0
- package/docs/label-sheets.md +267 -0
- package/docs/scan-codes.md +93 -9
- package/package.json +4 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-GFn8Sgg1.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-GFn8Sgg1.js.map +0 -1
- package/dashboard/dist/assets/BulkAssignModal-CmLVxkz-.js +0 -2
- package/dashboard/dist/assets/HomePage-67xXjKjN.js +0 -2
- package/dashboard/dist/assets/McpRunDetailPage-qHRQ1pEY.js +0 -2
- package/dashboard/dist/assets/OperatorDashboard-el5BquXN.js +0 -2
- package/dashboard/dist/assets/PersonaDetailPage-B_tb8gfl.js +0 -2
- package/dashboard/dist/assets/RoleDetailPage-DtU7vsJm.js +0 -8
- package/dashboard/dist/assets/RolesPage-BE7RWt9q.js +0 -2
- package/dashboard/dist/assets/RosterWidget-BJMx0a8Z.js.map +0 -1
- package/dashboard/dist/assets/RunAsSelector-Co6s9bqA.js +0 -2
- package/dashboard/dist/assets/ScanCodesPage-C2TETaj5.js +0 -2
- package/dashboard/dist/assets/ScanSchemeDetailPage-C2UgU8l-.js +0 -5
- package/dashboard/dist/assets/ScanSchemeDetailPage-C2UgU8l-.js.map +0 -1
- package/dashboard/dist/assets/ScanStationPage-nWYz-OD3.js +0 -2
- package/dashboard/dist/assets/ScanStationPage-nWYz-OD3.js.map +0 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-Crf7AIFc.js +0 -2
- package/dashboard/dist/assets/WorkflowsDashboard--isjt06C.js +0 -2
- package/dashboard/dist/assets/index-B95LbYhW.js +0 -2
- package/dashboard/dist/assets/index-B95LbYhW.js.map +0 -1
- package/dashboard/dist/assets/index-BmzscsXK.css +0 -1
- package/dashboard/dist/assets/index-DRK7M1_9.js +0 -2
- package/dashboard/dist/assets/index-P-DlgAWj.js +0 -3
- package/dashboard/dist/assets/index-P-DlgAWj.js.map +0 -1
- package/dashboard/dist/assets/index-ygxyAKcc.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"RosterWidget-BJMx0a8Z.js","sources":["../../../shared/form-validation/ctx-path.ts","../../../shared/form-validation/x-lt-show-if.ts","../../src/components/escalation/resolver-form/FieldChrome.tsx","../../src/components/escalation/widgets/OpenDetailButton.tsx","../../src/components/escalation/widgets/InlineConfirm.tsx","../../src/components/escalation/widgets/embed-write.ts","../../src/components/escalation/widgets/InlineCodeEntry.tsx","../../../shared/form-validation/x-lt-roster.ts","../../src/components/escalation/widgets/RosterEntryRow.tsx","../../src/hooks/useRosters.ts","../../../shared/form-validation/x-lt-actions.ts","../../src/components/escalation/widgets/RosterWidget.tsx"],"sourcesContent":["/**\n * Context-path resolution shared by every token that names a `\"domain.path\"`.\n *\n * A path may embed `{{domain.path}}` interpolation segments — the same\n * grammar as x-lt-help tokens — resolved against the live context before the\n * walk. This is what makes cascading selects work: a field can declare\n *\n * x-lt-options: \"lookup.geo.regions.{{resolver.country}}\"\n *\n * and its option list follows the submitter's country answer, re-resolved\n * locally on every edit. An unresolved segment means \"no concrete path yet\",\n * never a literal placeholder.\n */\nimport { getDeep } from './x-lt-bind';\n\nexport const INTERPOLATION_PATTERN = /\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g;\n\n/** Whether a token embeds `{{domain.path}}` interpolation segments. */\nexport function hasInterpolation(token: unknown): token is string {\n return typeof token === 'string' && /\\{\\{[^{}]+\\}\\}/.test(token);\n}\n\n/** Resolve a concrete `\"domain.path\"` (x-lt-bind syntax, `a.b[0].c`) against the context. */\nexport function resolveCtxPath(\n path: string,\n ctx: Record<string, unknown> | undefined,\n): unknown {\n if (!ctx) return undefined;\n const dot = path.indexOf('.');\n const root = ctx[dot === -1 ? path : path.slice(0, dot)];\n if (dot === -1) return root;\n if (root === null || typeof root !== 'object') return undefined;\n return getDeep(root, path.slice(dot + 1));\n}\n\n/**\n * Interpolate every `{{domain.path}}` segment against the context. Returns\n * the concrete path, or null when any segment resolves to nothing (missing,\n * null, empty string) or to a non-scalar — an unanswered cascade parent\n * yields no path, so the dependent field offers nothing.\n */\nexport function interpolatePath(\n template: string,\n ctx: Record<string, unknown> | undefined,\n): string | null {\n let unresolved = false;\n const concrete = template.replace(INTERPOLATION_PATTERN, (_match, rawPath: string) => {\n const value = resolveCtxPath(rawPath, ctx);\n if (typeof value === 'string' && value.trim().length > 0) return value;\n if (typeof value === 'number' && Number.isFinite(value)) return String(value);\n unresolved = true;\n return '';\n });\n return unresolved ? null : concrete;\n}\n","/**\n * x-lt-showIf — conditional field visibility. A form_schema property may\n * declare `x-lt-showIf: \"domain.path\"` to show the field only when the value\n * at that path is present and truthy. Prefix `!` to invert: show when absent\n * or falsy.\n *\n * Equality forms compare the resolved value's string form:\n * \"domain.path=VALUE\" — show when String(value) equals VALUE\n * \"domain.path!=VALUE\" — show when it does not\n * An absent value compares as the empty string, so `=X` is false and `!=X` is\n * true when the path is missing. VALUE is the raw remainder after the operator\n * (trimmed; no quoting). The truthy/! forms are unchanged.\n *\n * Domains follow the same `domain.path` convention as x-lt-help tokens:\n * metadata — the escalation row's metadata dict\n * payload — the escalation context payload (escalation_payload)\n * envelope — the workflow-sent input envelope\n * escalation — top-level escalation row fields\n * resolver — the submitted resolver payload\n * roster (each roster field's counts: `roster.orders.outstanding=0`)\n *\n * A missing or non-string condition always shows the field (opt-in, safe default).\n */\nimport { getDeep } from './x-lt-bind';\nimport { HELP_DOMAINS, type HelpTokenContext } from './x-lt-help';\n\nexport type ShowIfContext = HelpTokenContext;\n\nfunction isTruthy(value: unknown): boolean {\n return value !== null && value !== undefined && value !== '' && value !== false && value !== 0;\n}\n\n/** The value's comparable string form; absent compares as the empty string. */\nfunction asComparable(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'object') return JSON.stringify(value);\n return String(value);\n}\n\nfunction resolvePath(expr: string, ctx: ShowIfContext): { known: boolean; value: unknown } {\n const dot = expr.indexOf('.');\n const domain = (dot === -1 ? expr : expr.slice(0, dot)) as (typeof HELP_DOMAINS)[number];\n if (!(HELP_DOMAINS as readonly string[]).includes(domain)) return { known: false, value: undefined };\n const root = ctx[domain];\n if (dot === -1) return { known: true, value: root };\n try {\n return { known: true, value: getDeep(root, expr.slice(dot + 1)) };\n } catch {\n return { known: true, value: undefined };\n }\n}\n\n/**\n * Evaluates an x-lt-showIf condition. Returns true when the field should be\n * shown. Returns true when condition is absent, non-string, or context is null.\n * An array of conditions shows the field only when every one holds.\n */\nexport function evaluateShowIf(condition: unknown, ctx: ShowIfContext | null | undefined): boolean {\n if (Array.isArray(condition)) return condition.every((c) => evaluateShowIf(c, ctx));\n if (typeof condition !== 'string' || condition.length === 0) return true;\n if (!ctx) return true;\n const negate = condition.startsWith('!');\n const expr = negate ? condition.slice(1) : condition;\n\n // Equality forms — `!=` first so it never parses as `=` with a `!` in the path.\n const neqAt = expr.indexOf('!=');\n const eqAt = expr.indexOf('=');\n if (neqAt !== -1 || (eqAt !== -1 && eqAt !== neqAt + 1)) {\n const isNeq = neqAt !== -1 && (eqAt === -1 || neqAt < eqAt);\n const opAt = isNeq ? neqAt : eqAt;\n const path = expr.slice(0, opAt).trim();\n const expected = expr.slice(opAt + (isNeq ? 2 : 1)).trim();\n const { known, value } = resolvePath(path, ctx);\n if (!known) return true; // unknown domain — safe default, same as truthy form\n const matches = asComparable(value) === expected;\n const result = isNeq ? !matches : matches;\n return negate ? !result : result;\n }\n\n const { known, value } = resolvePath(expr, ctx);\n if (!known) return true;\n return negate ? !isTruthy(value) : isTruthy(value);\n}\n\n/**\n * `x-lt-hide-if-empty`: the field is suppressed while its value is empty\n * (null, undefined, '', false, or 0). Render and validation share this test.\n */\nexport function isHiddenIfEmpty(fieldSchema: Record<string, unknown> | undefined, value: unknown): boolean {\n if (fieldSchema?.['x-lt-hide-if-empty'] !== true) return false;\n return value === null || value === undefined || value === '' || value === false || value === 0;\n}\n\n/**\n * `x-lt-hidden: true`: the field never renders. A value set by the caller\n * (a workflow default, an API submitter) passes through to the payload and\n * is checked against the field's type and enum; the field is never required,\n * since no one on the form can answer it.\n */\nexport const X_LT_HIDDEN = 'x-lt-hidden';\n\nexport function isHiddenField(fieldSchema: Record<string, unknown> | undefined): boolean {\n return fieldSchema?.[X_LT_HIDDEN] === true;\n}\n","/**\n * Shared field chrome for the resolver form: label, helper, error, and the\n * input class recipes. One place styles every generated field.\n */\n\nexport function FieldLabel({ children, isRequired, htmlFor }: {\n children: React.ReactNode;\n isRequired?: boolean;\n htmlFor?: string;\n}) {\n // `block` is load-bearing: a <label> is inline by default, and the\n // label→instruction→control anatomy would then hold only by accident —\n // a full-width control wraps below, but a narrow control (number,\n // max-w-48) with no instruction line sits flush BESIDE the label. The\n // anatomy is a column; the label declares it.\n return (\n <label htmlFor={htmlFor} className=\"block text-2xs font-semibold uppercase tracking-wider text-text-secondary\">\n {children}\n {isRequired && <span className=\"text-status-error ml-0.5\">*</span>}\n </label>\n );\n}\n\nexport function FieldHelper({ id, children }: { id?: string; children: React.ReactNode }) {\n return (\n <p id={id} className=\"text-2xs text-text-tertiary mt-0.5 leading-snug\">\n {children}\n </p>\n );\n}\n\nexport function FieldError({ error, id }: { error?: string; id?: string }) {\n if (!error) return null;\n return (\n <p id={id} role=\"alert\" className=\"text-2xs text-status-error mt-1 animate-[field-error-in_0.3s_ease-out]\">\n {error}\n </p>\n );\n}\n\nexport function inputClass(hasError?: boolean): string {\n return hasError\n ? 'input text-sm w-full mt-1 border-status-error/50 focus:border-status-error animate-[field-shake_0.4s_ease-in-out]'\n : 'input text-sm w-full mt-1';\n}\n\n// Select shares the field recipe but adds the unified chevron (via .select).\n// Width follows the content, floored for presence and capped by the cell —\n// a one-word choice never stretches across the measure. The floor is\n// min(16rem, 100%): CSS lets min-width beat max-width, so a bare min-w-64\n// would overflow a cell narrower than 16rem — the cell always wins.\nexport function selectClass(hasError?: boolean): string {\n return hasError\n ? 'select text-sm mt-1 min-w-[min(16rem,100%)] max-w-full border-status-error/50 focus:border-status-error animate-[field-shake_0.4s_ease-in-out]'\n : 'select text-sm mt-1 min-w-[min(16rem,100%)] max-w-full';\n}\n","import { Link } from 'react-router-dom';\nimport { ArrowUpRight } from 'lucide-react';\n\n/**\n * The one affordance for opening an embedded row's detail page — a clear\n * icon-in-a-button, not a bare glyph, so the gesture reads as \"open this\". The\n * tooltip stays generic (\"View details\") rather than naming the record kind, so\n * the same control fits any embed. Non-focusable: the row/card click and the\n * canned actions carry the keyboard path; this is a pointer shortcut.\n */\nexport function OpenDetailButton({ to, className = '' }: { to: string; className?: string }) {\n return (\n <Link\n to={to}\n title=\"View details\"\n tabIndex={-1}\n className={`inline-flex items-center justify-center w-6 h-6 shrink-0 rounded border border-surface-border text-accent/70 hover:text-accent hover:border-accent/60 hover:bg-accent/5 transition-colors ${className}`}\n >\n <ArrowUpRight className=\"w-3.5 h-3.5\" strokeWidth={2} />\n <span className=\"sr-only\">View details</span>\n </Link>\n );\n}\n","/**\n * A confirmation asked in place, beside the control that asked it. Used by\n * embedded row actions instead of a browser dialog, which blocks a shared\n * station and every other tab.\n */\nexport function InlineConfirm({ message, onConfirm, onCancel, testId }: {\n message: string;\n onConfirm: () => void;\n onCancel: () => void;\n testId?: string;\n}) {\n return (\n <span className=\"inline-flex flex-wrap items-center gap-2\" role=\"group\" aria-label=\"Confirm action\" data-testid={testId}>\n <span className=\"text-xs text-text-primary whitespace-normal\">{message}</span>\n <button\n type=\"button\"\n onClick={onConfirm}\n className=\"px-2 py-0.5 text-2xs font-medium text-text-inverse bg-accent rounded hover:bg-accent/90 transition-colors\"\n data-testid={testId ? `${testId}-yes` : undefined}\n autoFocus\n >\n Confirm\n </button>\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"px-2 py-0.5 text-2xs font-medium text-text-secondary border border-surface-border rounded hover:bg-surface-hover transition-colors\"\n data-testid={testId ? `${testId}-no` : undefined}\n >\n Cancel\n </button>\n </span>\n );\n}\n","import { createContext, useContext } from 'react';\n\nexport interface EmbedWriteOptions {\n /**\n * The action needs a badge (a role the person acting lacks): hold it for\n * the next badge, saying this. A page that takes no badges drops it.\n */\n badge?: string;\n}\n\n/** Runs an embedded row action, or holds it until the page can run it (a badge at a shared station). */\nexport type EmbedWriteGuard = (verb: string, run: () => Promise<void>, options?: EmbedWriteOptions) => void;\n\nconst runNow: EmbedWriteGuard = (_verb, run, options) => {\n if (!options?.badge) void run();\n};\n\n/**\n * The host page's gate for writes an embedded widget makes on other rows\n * (roster and list actions). Absent a provider, actions run directly.\n */\nexport const EmbedWriteContext = createContext<EmbedWriteGuard>(runNow);\n\nexport function useEmbedWrite(): EmbedWriteGuard {\n return useContext(EmbedWriteContext);\n}\n","import { useState } from 'react';\nimport { SCAN_CAPTURE_ATTR, SCAN_CAPTURE_OFF } from '../../../lib/scan-sources/types';\n\n/**\n * A code typed in place, beside the control that asked for it: a key-in for\n * an item whose barcode will not scan. The server checks the code against\n * the entry; Enter confirms. The field keeps its keys, so a code typed or\n * scanned into it is never also run as a scan.\n */\nexport function InlineCodeEntry({ label, onConfirm, onCancel, testId }: {\n label: string;\n onConfirm: (code: string) => void;\n onCancel: () => void;\n testId?: string;\n}) {\n const [code, setCode] = useState('');\n const submit = () => { if (code.trim()) onConfirm(code.trim()); };\n return (\n <span\n className=\"inline-flex flex-wrap items-center gap-2\"\n role=\"group\"\n aria-label={label}\n data-testid={testId}\n {...{ [SCAN_CAPTURE_ATTR]: SCAN_CAPTURE_OFF }}\n >\n <input\n type=\"text\"\n inputMode=\"numeric\"\n value={code}\n onChange={(e) => setCode(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') submit();\n if (e.key === 'Escape') onCancel();\n }}\n placeholder=\"Code on the label\"\n aria-label=\"Code on the label\"\n className=\"input text-xs py-0.5 w-40 font-mono\"\n data-testid={testId ? `${testId}-input` : undefined}\n autoFocus\n />\n <button\n type=\"button\"\n onClick={submit}\n disabled={!code.trim()}\n className=\"px-2 py-0.5 text-2xs font-medium text-text-inverse bg-accent rounded hover:bg-accent/90 disabled:opacity-40 disabled:cursor-not-allowed transition-colors\"\n data-testid={testId ? `${testId}-yes` : undefined}\n >\n {label}\n </button>\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"px-2 py-0.5 text-2xs font-medium text-text-secondary border border-surface-border rounded hover:bg-surface-hover transition-colors\"\n data-testid={testId ? `${testId}-no` : undefined}\n >\n Cancel\n </button>\n </span>\n );\n}\n","/**\n * x-lt-roster: every member a container row expects, each with its state.\n * A form field declares `x-lt-widget: \"roster\"` and an `x-lt-roster` block:\n *\n * \"x-lt-roster\": {\n * \"expected\": { \"query\": { \"roles\": [\"packing\"], \"facets\": { \"box\": \"{{escalation.id}}\" } } },\n * \"key\": \"{{metadata.orderId}}\",\n * \"in\": [\"items\", \"resolver.bags\"],\n * \"flagged\": [{ \"when\": \"resolver.outcome=missing\", \"label\": \"Missing\" }]\n * }\n *\n * The expected set is one of:\n * - `query`: member rows matched by role(s) and facets, any status unless\n * `status` narrows it. `key` names each row's entry (default its id).\n * - `list`: a `domain.path` naming an array of keys on the host row.\n * - `batch`: the host row's batch keys; `labels` names a per-key map.\n *\n * An entry is `in` when its key is held by the host row (`items`: the\n * accumulated keys, or a batch's filled keys) or appears in a named context\n * value (`resolver.<field>`, a string or an array). It is `flagged` when its\n * member row matches a `flagged` rule (or, on a batch set, when its key\n * carries a flag in `envelope.batch_flags`), and `waiting` otherwise. In wins over\n * flagged, so a member flagged on its own row and then added reads in.\n *\n * `countedBy` names the separator of counted keys (`<code>#1`, `<code>#2`):\n * the nth occurrence of a code in a named context value ticks `<code>#n`,\n * so two scans of one code tick both of its keys.\n *\n * Isomorphic: the dashboard renders the widget and the form's `roster.*`\n * context from it, and the API layer computes the same counts to evaluate\n * showIf and the roster submit guard at resolve.\n */\nimport { getDeep } from './x-lt-bind';\nimport { resolveCtxPath } from './ctx-path';\nimport { interpolateHelp, type HelpTokenContext } from './x-lt-help';\nimport { evaluateShowIf } from './x-lt-show-if';\n\nexport const X_LT_ROSTER = 'x-lt-roster';\nexport const ROSTER_WIDGET = 'roster';\n/** The context domain the counts are read from: `roster.<field>.outstanding`. */\nexport const ROSTER_DOMAIN = 'roster';\n/** The most member rows a query set reads. */\nexport const ROSTER_QUERY_LIMIT = 200;\n/** The `in` source naming the host row's held keys. */\nexport const ROSTER_ITEMS_SOURCE = 'items';\n/** `query.status` value that reads every status (the default). */\nexport const ROSTER_ANY_STATUS = 'any';\n\nexport const ROSTER_STATES = { WAITING: 'waiting', IN: 'in', FLAGGED: 'flagged' } as const;\nexport type RosterState = (typeof ROSTER_STATES)[keyof typeof ROSTER_STATES];\n\nexport interface RosterQuery {\n role?: string;\n roles?: string[];\n facets?: Record<string, string>;\n /** A status to narrow to; omitted or `any` reads every status. */\n status?: string;\n}\n\nexport type RosterExpected =\n | { query: RosterQuery }\n | { list: string }\n | { batch: true; labels?: string };\n\nexport interface RosterFlagRule {\n /** An x-lt-showIf condition over the member row's own context. */\n when: string | string[];\n label: string;\n}\n\nexport interface RosterDef {\n expected: RosterExpected;\n key?: string;\n in?: string[];\n flagged?: RosterFlagRule[];\n /** The separator of counted keys: the nth occurrence of a code ticks `<code><sep>n`. */\n countedBy?: string;\n}\n\n/** One member row's token context (the row's own domains). */\nexport type RosterRow = HelpTokenContext & { escalation: Record<string, unknown> };\n\nexport interface RosterEntry {\n key: string;\n state: RosterState;\n /** The matching flag rule's label, when flagged. */\n flag?: string;\n /** The member row, for a query set. */\n row?: RosterRow;\n /** The per-key label value from a batch's `labels` map. */\n label?: unknown;\n}\n\nexport interface RosterCounts {\n expected: number;\n in: number;\n flagged: number;\n waiting: number;\n /** Entries neither in nor flagged: the count a roster guard waits on. */\n outstanding: number;\n}\n\nexport interface RosterResult {\n entries: RosterEntry[];\n counts: RosterCounts;\n}\n\nconst DEFAULT_KEY = '{{escalation.id}}';\nconst MISSING = '—';\nconst BATCH_KEYS = 'batch_keys';\nconst BATCH_PENDING = 'batch_pending';\nconst BATCH_FLAGS = 'batch_flags';\nconst ACCUMULATE_KEYS = 'accumulate_keys';\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return !!v && typeof v === 'object' && !Array.isArray(v);\n}\n\nfunction strings(v: unknown): string[] {\n if (typeof v === 'string') return v ? [v] : [];\n if (!Array.isArray(v)) return [];\n return v.filter((s): s is string => typeof s === 'string' && s.length > 0);\n}\n\n/** The field's roster declaration, or undefined when it declares none or an unusable one. */\nexport function readRosterDef(fieldSchema: Record<string, unknown> | null | undefined): RosterDef | undefined {\n const raw = fieldSchema?.[X_LT_ROSTER];\n if (!isRecord(raw) || !isRecord(raw.expected)) return undefined;\n const e = raw.expected;\n const hasSource = isRecord(e.query) || typeof e.list === 'string' || e.batch === true;\n return hasSource ? (raw as unknown as RosterDef) : undefined;\n}\n\n/** Every roster field of a form schema, by field name. */\nexport function readRosterDefs(schema: Record<string, unknown> | null | undefined): Record<string, RosterDef> {\n const properties = isRecord(schema?.properties) ? (schema!.properties as Record<string, unknown>) : {};\n const defs: Record<string, RosterDef> = {};\n for (const [field, def] of Object.entries(properties)) {\n const roster = isRecord(def) ? readRosterDef(def) : undefined;\n if (roster) defs[field] = roster;\n }\n return defs;\n}\n\n/** The roster's member-row query, or null when its set is not a query. */\nexport function rosterQueryOf(def: RosterDef): RosterQuery | null {\n return 'query' in def.expected && isRecord(def.expected.query) ? def.expected.query : null;\n}\n\n/** The query's concrete params: facets interpolated, `any` status dropped. Null when the scope is empty. */\nexport function resolveRosterQuery(\n query: RosterQuery,\n ctx: HelpTokenContext,\n): { roles?: string[]; facets: Record<string, string>; status?: string; limit: number } | null {\n const facets: Record<string, string> = {};\n for (const [k, v] of Object.entries(query.facets ?? {})) {\n if (typeof v !== 'string') continue;\n const resolved = interpolateHelp(v, ctx);\n if (!resolved || resolved === MISSING) return null;\n facets[k] = resolved;\n }\n const roles = [...(query.role ? [query.role] : []), ...strings(query.roles)];\n if (!roles.length && !Object.keys(facets).length) return null;\n const status = query.status && query.status !== ROSTER_ANY_STATUS ? query.status : undefined;\n return { ...(roles.length ? { roles } : {}), facets, ...(status ? { status } : {}), limit: ROSTER_QUERY_LIMIT };\n}\n\nfunction parseJson(v: unknown): Record<string, unknown> | null {\n if (isRecord(v)) return v;\n if (typeof v !== 'string' || !v) return null;\n try {\n const parsed = JSON.parse(v);\n return isRecord(parsed) ? parsed : null;\n } catch {\n return null;\n }\n}\n\n/** A member row's token context, from a row whose JSON columns are strings or objects. */\nexport function rosterRowContext(row: Record<string, unknown>): RosterRow {\n return {\n escalation: row,\n metadata: isRecord(row.metadata) ? row.metadata : parseJson(row.metadata),\n envelope: parseJson(row.envelope),\n payload: parseJson(row.escalation_payload),\n resolver: parseJson(row.resolver_payload),\n };\n}\n\n/** The keys the host row holds: its accumulated keys, or a batch's filled keys. */\nfunction heldKeys(ctx: HelpTokenContext): Set<string> {\n const metadata = ctx.metadata ?? {};\n const accumulated = metadata[ACCUMULATE_KEYS];\n if (Array.isArray(accumulated)) return new Set(strings(accumulated));\n const envelopeItems = getDeep(ctx.envelope, 'accumulate_items');\n if (isRecord(envelopeItems)) return new Set(Object.keys(envelopeItems));\n if (Array.isArray(metadata[BATCH_PENDING])) {\n const pending = new Set(strings(metadata[BATCH_PENDING]));\n return new Set(strings(metadata[BATCH_KEYS]).filter((k) => !pending.has(k)));\n }\n return new Set();\n}\n\n/** Each value as given, and with `countedBy` its nth occurrence also as `<value><sep>n`. */\nfunction countedKeys(values: string[], separator: string | undefined): string[] {\n if (!separator) return values;\n const seen = new Map<string, number>();\n return values.flatMap((v) => {\n const n = (seen.get(v) ?? 0) + 1;\n seen.set(v, n);\n return [v, `${v}${separator}${n}`];\n });\n}\n\nfunction arrivedKeys(def: RosterDef, ctx: HelpTokenContext): Set<string> {\n const arrived = new Set<string>();\n const separator = typeof def.countedBy === 'string' && def.countedBy ? def.countedBy : undefined;\n for (const source of def.in ?? [ROSTER_ITEMS_SOURCE]) {\n const keys = source === ROSTER_ITEMS_SOURCE\n ? [...heldKeys(ctx)]\n : countedKeys(strings(resolveCtxPath(source, ctx as Record<string, unknown>)), separator);\n keys.forEach((k) => arrived.add(k));\n }\n return arrived;\n}\n\n/** A batch key's flag label, from `envelope.batch_flags[key].label`. */\nfunction batchFlagLabel(ctx: HelpTokenContext, key: string): string | undefined {\n const flags = getDeep(ctx.envelope, BATCH_FLAGS);\n const flag = isRecord(flags) ? flags[key] : undefined;\n return isRecord(flag) && typeof flag.label === 'string' && flag.label ? flag.label : undefined;\n}\n\nfunction flagFor(def: RosterDef, row: RosterRow | undefined): string | undefined {\n if (!row) return undefined;\n for (const rule of def.flagged ?? []) {\n const conditions = strings(rule.when);\n if (!conditions.length || typeof rule.label !== 'string') continue;\n if (evaluateShowIf(conditions, row)) return rule.label;\n }\n return undefined;\n}\n\n/** A row's creation instant in ms; 0 when absent or unreadable. */\nfunction createdAt(row: RosterRow): number {\n const raw = row.escalation.created_at;\n const ms = raw instanceof Date ? raw.getTime() : typeof raw === 'string' ? Date.parse(raw) : NaN;\n return Number.isNaN(ms) ? 0 : ms;\n}\n\n/**\n * The expected keys in order, each with its member row (query) or label\n * (batch). Several rows sharing a key (a member that parked again) read as\n * one entry on the newest row, so its state and actions follow the live row.\n */\nfunction expectedEntries(\n def: RosterDef,\n ctx: HelpTokenContext,\n rows: RosterRow[],\n): Array<{ key: string; row?: RosterRow; label?: unknown }> {\n const seen = new Set<string>();\n const out: Array<{ key: string; row?: RosterRow; label?: unknown }> = [];\n const push = (key: string, extra: { row?: RosterRow; label?: unknown } = {}) => {\n if (!key || key === MISSING || seen.has(key)) return;\n seen.add(key);\n out.push({ key, ...extra });\n };\n const e = def.expected;\n if ('query' in e) {\n const template = def.key ?? DEFAULT_KEY;\n const newest = new Map<string, RosterRow>();\n for (const row of rows) {\n const key = interpolateHelp(template, row);\n const held = newest.get(key);\n if (!held || createdAt(row) > createdAt(held)) newest.set(key, row);\n }\n for (const row of rows) {\n const key = interpolateHelp(template, row);\n push(key, { row: newest.get(key) });\n }\n } else if ('list' in e) {\n strings(resolveCtxPath(e.list, ctx as Record<string, unknown>)).forEach((k) => push(k));\n } else {\n const labels = e.labels ? resolveCtxPath(e.labels, ctx as Record<string, unknown>) : undefined;\n for (const key of strings(ctx.metadata?.[BATCH_KEYS])) {\n push(key, isRecord(labels) && key in labels ? { label: labels[key] } : {});\n }\n }\n return out;\n}\n\n/**\n * Every expected entry with its state, and the counts. `rows` are the\n * member rows a query set read (ignored for list and batch sets). `ctx` is\n * the host row's context with the live form values under `resolver`.\n */\nexport function computeRoster(def: RosterDef, ctx: HelpTokenContext, rows: RosterRow[] = []): RosterResult {\n const arrived = arrivedKeys(def, ctx);\n const batch = 'batch' in def.expected;\n const entries: RosterEntry[] = expectedEntries(def, ctx, rows).map((e) => {\n if (arrived.has(e.key)) return { ...e, state: ROSTER_STATES.IN };\n const flag = batch ? batchFlagLabel(ctx, e.key) : flagFor(def, e.row);\n return flag ? { ...e, state: ROSTER_STATES.FLAGGED, flag } : { ...e, state: ROSTER_STATES.WAITING };\n });\n const count = (s: RosterState) => entries.filter((e) => e.state === s).length;\n const waiting = count(ROSTER_STATES.WAITING);\n return {\n entries,\n counts: {\n expected: entries.length,\n in: count(ROSTER_STATES.IN),\n flagged: count(ROSTER_STATES.FLAGGED),\n waiting,\n outstanding: waiting,\n },\n };\n}\n\n/** The header line: \"3 of 5 in · 1 Missing\". */\nexport function rosterHeadline(result: RosterResult): string {\n const { counts } = result;\n const parts = [`${counts.in} of ${counts.expected} in`];\n const byFlag = new Map<string, number>();\n for (const e of result.entries) {\n if (e.state === ROSTER_STATES.FLAGGED && e.flag) byFlag.set(e.flag, (byFlag.get(e.flag) ?? 0) + 1);\n }\n for (const [flag, n] of byFlag) parts.push(`${n} ${flag}`);\n return parts.join(' · ');\n}\n","import { CheckCircle2, Circle, Flag } from 'lucide-react';\nimport { OpenDetailButton } from './OpenDetailButton';\nimport { InlineConfirm } from './InlineConfirm';\nimport { InlineCodeEntry } from './InlineCodeEntry';\nimport { FormattedValue } from '../../common/display/FormattedValue';\nimport { interpolateHelp } from '../../../lib/x-lt-help';\nimport { interpolateItemTemplate, type EscalationItem } from '../../../lib/escalation-items';\nimport type { EmbedColumnDef } from '../../../lib/embed-row';\nimport type { RosterActionDef } from '../../../lib/x-lt-actions';\nimport { ROSTER_STATES, type RosterEntry, type RosterState } from '../../../lib/x-lt-roster';\nimport type { ShowIfContext } from '../../../lib/x-lt-show-if';\n\n/** An action the entry offers, with its index among the field's actions. */\nexport interface OfferedAction {\n index: number;\n action: RosterActionDef;\n}\n\nconst STATE_TEXT: Record<RosterState, string> = { waiting: 'Waiting', in: 'In', flagged: 'Flagged' };\n\nfunction StateMark({ state }: { state: RosterState }) {\n if (state === ROSTER_STATES.IN) return <CheckCircle2 className=\"w-4 h-4 text-status-success shrink-0\" strokeWidth={2} aria-hidden />;\n if (state === ROSTER_STATES.FLAGGED) return <Flag className=\"w-4 h-4 text-status-warning shrink-0\" strokeWidth={2} aria-hidden />;\n return <Circle className=\"w-4 h-4 text-text-tertiary shrink-0\" strokeWidth={2} aria-hidden />;\n}\n\n/**\n * One roster entry: its state mark, columns, state label, and the actions\n * its state offers. Columns read the member row's domains (a query set) or\n * the host row's, beside `{{item.*}}`: the entry key, a batch label, and\n * the item's payload, actor and time once it is in.\n */\nexport function RosterEntryRow({\n entry, item, hostCtx, columns, offered, asking, pending, error, onAction, onConfirm, onCancel,\n}: {\n entry: RosterEntry;\n item: EscalationItem & { label?: unknown };\n hostCtx: ShowIfContext;\n columns: EmbedColumnDef[];\n offered: OfferedAction[];\n /** The action asking in place: its confirmation, or its code entry. */\n asking: OfferedAction | null;\n pending: boolean;\n error?: string;\n onAction: (offer: OfferedAction) => void;\n onConfirm: (code?: string) => void;\n onCancel: () => void;\n}) {\n const ctx = entry.row ?? hostCtx;\n const done = entry.state === ROSTER_STATES.IN;\n const stateLabel = entry.state === ROSTER_STATES.FLAGGED ? entry.flag ?? STATE_TEXT.flagged : STATE_TEXT[entry.state];\n\n return (\n <li\n className=\"py-2 flex items-start gap-3 border-b border-surface-border/50 last:border-0\"\n data-testid={`roster-entry-${entry.key}`}\n data-state={entry.state}\n >\n <span className=\"pt-0.5\"><StateMark state={entry.state} /></span>\n <div className=\"min-w-0 flex-1 flex flex-wrap items-baseline gap-x-4 gap-y-0.5\">\n {columns.map((col) => (\n <span key={col.label} className={`text-sm min-w-0 ${done ? 'text-text-secondary' : 'text-text-primary'}`}>\n <span className=\"sr-only\">{col.label}: </span>\n <FormattedValue raw={interpolateItemTemplate(col.value, item, ctx)} format={col.format} />\n </span>\n ))}\n </div>\n <span\n className={`text-xs font-medium shrink-0 pt-0.5 ${done ? 'text-status-success' : entry.state === ROSTER_STATES.FLAGGED ? 'text-status-warning' : 'text-text-tertiary'}`}\n data-testid={`roster-state-${entry.key}`}\n >\n {stateLabel}\n </span>\n {(offered.length > 0 || asking || error) && (\n <span className=\"shrink-0 flex flex-col items-end gap-0.5\">\n {asking?.action.fill?.enterCode ? (\n <InlineCodeEntry\n label={asking.action.label}\n onConfirm={(code) => onConfirm(code)}\n onCancel={onCancel}\n testId={`roster-code-${entry.key}`}\n />\n ) : asking ? (\n <InlineConfirm\n message={interpolateHelp(asking.action.confirm ?? '', ctx)}\n onConfirm={() => onConfirm()}\n onCancel={onCancel}\n testId={`roster-confirm-${entry.key}`}\n />\n ) : (\n <span className=\"flex gap-1\">\n {offered.map((offer) => (\n <button\n key={offer.index}\n type=\"button\"\n onClick={() => onAction(offer)}\n disabled={pending}\n className=\"px-2 py-0.5 text-2xs font-medium text-accent border border-accent/40 rounded hover:bg-accent/10 disabled:opacity-40 disabled:cursor-not-allowed transition-colors\"\n data-testid={`roster-action-${entry.key}`}\n >\n {offer.action.label}\n </button>\n ))}\n </span>\n )}\n {error && (\n <span className=\"text-2xs text-status-error max-w-[16rem] text-right\" data-testid={`roster-error-${entry.key}`}>{error}</span>\n )}\n </span>\n )}\n {entry.row && (\n <OpenDetailButton to={`/escalations/detail/${String(entry.row.escalation.id)}`} />\n )}\n </li>\n );\n}\n","import { useQueries } from '@tanstack/react-query';\nimport { escalationListQuery } from '../api/escalations';\nimport { schemaNeedsEnvelope } from '../lib/schema-needs-envelope';\nimport {\n computeRoster,\n readRosterDefs,\n resolveRosterQuery,\n rosterQueryOf,\n rosterRowContext,\n type RosterDef,\n type RosterResult,\n type RosterRow,\n} from '../lib/x-lt-roster';\nimport type { ShowIfContext } from '../lib/x-lt-show-if';\n\n/** A roster's result, or null while its member rows are loading or failed to load. */\nexport type RosterView = RosterResult | null;\n\nfunction listFiltersFor(def: RosterDef, ctx: ShowIfContext) {\n const query = rosterQueryOf(def);\n const scoped = query ? resolveRosterQuery(query, ctx) : null;\n if (!scoped) return null;\n return {\n roles: scoped.roles,\n status: scoped.status,\n facets: scoped.facets,\n limit: scoped.limit,\n include: schemaNeedsEnvelope({ key: def.key, flagged: def.flagged }) ? ('envelope' as const) : undefined,\n };\n}\n\n/**\n * Every roster of a form, by field name. Member rows load through the shared\n * list query, so a roster refreshes on the same escalation events as every\n * list, and the widget and the page read one cached result. `ctx` carries\n * the live form values under `resolver`.\n */\nexport function useRosters(\n schema: Record<string, unknown> | null | undefined,\n ctx: ShowIfContext | undefined,\n): Record<string, RosterView> {\n const defs = Object.entries(readRosterDefs(schema));\n const host = ctx ?? {};\n const filters = defs.map(([, def]) => listFiltersFor(def, host));\n const reads = useQueries({\n queries: filters.map((f) => ({\n ...escalationListQuery(f ?? {}),\n enabled: !!f,\n })),\n });\n\n const views: Record<string, RosterView> = {};\n defs.forEach(([field, def], i) => {\n if (!filters[i]) {\n views[field] = computeRoster(def, host);\n return;\n }\n const read = reads[i];\n if (!read.isSuccess) {\n views[field] = null;\n return;\n }\n const rows: RosterRow[] = read.data.escalations.map((e) => rosterRowContext(e as unknown as Record<string, unknown>));\n views[field] = computeRoster(def, host, rows);\n });\n return views;\n}\n\n/** The `roster` context domain: each loaded roster's counts. */\nexport function rosterContext(views: Record<string, RosterView>): Record<string, unknown> | null {\n const loaded = Object.entries(views).filter(([, v]) => v !== null);\n if (!loaded.length) return null;\n return Object.fromEntries(loaded.map(([field, v]) => [field, v!.counts]));\n}\n","/**\n * x-lt-actions on a roster field: the acts an entry offers, read the same way\n * by the dashboard (which shows them) and the API (which runs them). Each\n * action is exactly one act:\n *\n * { \"label\": \"Missing\", \"resolverPayload\": { \"outcome\": \"missing\" } } resolve the member row\n * { \"label\": \"Key in\", \"fill\": { \"payload\": { \"source\": \"key-in\" }, \"enterCode\": true } }\n * { \"label\": \"Missing\", \"flag\": { \"label\": \"Missing\" } } flag the batch key\n * { \"label\": \"Found it\", \"unflag\": true } clear the flag\n *\n * `when` names the entry states that offer it. `roles` limits who may run it:\n * the action shows to everyone and runs only for a person holding one of the\n * roles; `refuse` is what anyone else is told. The server re-reads the action\n * from the row's form schema and decides; the dashboard only displays.\n */\nimport { interpolateHelp, type HelpTokenContext } from './x-lt-help';\nimport { ROSTER_STATES, type RosterEntry, type RosterState } from './x-lt-roster';\nimport { displayGtin, isValidGtin, normalizeGtin } from '../scan-code/gtin';\n\nexport const X_LT_ACTIONS = 'x-lt-actions';\n\nexport const ROSTER_ACTION_KINDS = {\n RESOLVE: 'resolve',\n FILL: 'fill',\n FLAG: 'flag',\n UNFLAG: 'unflag',\n} as const;\nexport type RosterActionKind = (typeof ROSTER_ACTION_KINDS)[keyof typeof ROSTER_ACTION_KINDS];\n\n/** The separator of counted batch keys when the roster names none. */\nexport const ROSTER_KEY_SEPARATOR_DEFAULT = '#';\n\n/** The payload key a key-in records the entered code under. */\nexport const ENTERED_CODE_KEY = 'enteredCode';\n\nexport interface RosterActionDef {\n label: string;\n /** The entry states that offer it; the default follows the act. */\n when?: RosterState | RosterState[];\n /** A confirmation asked in place before firing; tokens interpolate per entry. */\n confirm?: string;\n /** Resolve the entry's member row with this canned payload (a query set). */\n resolverPayload?: Record<string, unknown>;\n /** Fill the entry's batch key; `enterCode` asks for the code and checks it against the key. */\n fill?: { payload?: Record<string, unknown>; enterCode?: boolean };\n /** Flag the entry's batch key. */\n flag?: { label: string; payload?: Record<string, unknown> };\n /** Clear the entry's flag. */\n unflag?: true;\n /** Runs only for a person holding one of these roles. */\n roles?: string[];\n /** What a person without the roles is told. */\n refuse?: string;\n}\n\nconst DEFAULT_WHEN: Record<RosterActionKind, RosterState[]> = {\n resolve: [ROSTER_STATES.WAITING],\n fill: [ROSTER_STATES.WAITING, ROSTER_STATES.FLAGGED],\n flag: [ROSTER_STATES.WAITING],\n unflag: [ROSTER_STATES.FLAGGED],\n};\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return !!v && typeof v === 'object' && !Array.isArray(v);\n}\n\n/** The one act an action declares, or null when it declares none or several. */\nexport function rosterActionKind(action: RosterActionDef): RosterActionKind | null {\n const kinds: RosterActionKind[] = [];\n if (isRecord(action.resolverPayload)) kinds.push(ROSTER_ACTION_KINDS.RESOLVE);\n if (isRecord(action.fill)) kinds.push(ROSTER_ACTION_KINDS.FILL);\n if (isRecord(action.flag) && typeof action.flag.label === 'string' && action.flag.label) {\n kinds.push(ROSTER_ACTION_KINDS.FLAG);\n }\n if (action.unflag === true) kinds.push(ROSTER_ACTION_KINDS.UNFLAG);\n return kinds.length === 1 ? kinds[0] : null;\n}\n\n/** The field's actions with a label and exactly one act, in declared order. */\nexport function readRosterActions(fieldSchema: Record<string, unknown> | null | undefined): RosterActionDef[] {\n const raw = fieldSchema?.[X_LT_ACTIONS];\n if (!Array.isArray(raw)) return [];\n return raw.filter((a): a is RosterActionDef =>\n isRecord(a) && typeof a.label === 'string' && !!a.label && rosterActionKind(a as unknown as RosterActionDef) !== null);\n}\n\n/**\n * True when the entry offers the action: the entry is in one of its states,\n * and the act fits the entry (a resolve needs a member row; batch acts need\n * a batch set).\n */\nexport function offersAction(action: RosterActionDef, entry: RosterEntry, batch: boolean): boolean {\n const kind = rosterActionKind(action);\n if (!kind) return false;\n if (kind === ROSTER_ACTION_KINDS.RESOLVE ? !entry.row : !batch) return false;\n const when = action.when === undefined ? DEFAULT_WHEN[kind]\n : Array.isArray(action.when) ? action.when : [action.when];\n return when.includes(entry.state);\n}\n\n/** True when a person holding `roles` may run the action. */\nexport function holdsActionRole(action: Pick<RosterActionDef, 'roles'>, roles: string[], superadmin = false): boolean {\n const required = Array.isArray(action.roles) ? action.roles.filter((r) => typeof r === 'string' && r) : [];\n return required.length === 0 || superadmin || required.some((r) => roles.includes(r));\n}\n\n/** What a person without the action's roles is told. */\nexport function actionRefusal(action: Pick<RosterActionDef, 'label' | 'roles' | 'refuse'>): string {\n if (typeof action.refuse === 'string' && action.refuse.trim()) return action.refuse;\n const roles = (action.roles ?? []).filter(Boolean);\n return `${action.label} needs ${roles.length > 1 ? 'one of these roles' : 'the role'}: ${roles.join(', ')}.`;\n}\n\n/** Deep-walk a payload template: string leaves interpolate against the context; other types pass through typed. */\nexport function interpolatePayload(value: unknown, ctx: HelpTokenContext): unknown {\n if (typeof value === 'string') return interpolateHelp(value, ctx);\n if (Array.isArray(value)) return value.map((v) => interpolatePayload(v, ctx));\n if (isRecord(value)) {\n return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, interpolatePayload(v, ctx)]));\n }\n return value;\n}\n\n/** The code a batch key names, without its ordinal suffix. */\nexport function batchKeyCode(key: string, separator = ROSTER_KEY_SEPARATOR_DEFAULT): string {\n const at = key.lastIndexOf(separator);\n return at > 0 && /^[0-9]+$/.test(key.slice(at + 1)) ? key.slice(0, at) : key;\n}\n\n/** The batch key's code as its label prints it: a GTIN in its EAN-13 or EAN-8 form. */\nexport function printedKeyCode(key: string, separator?: string): string {\n const code = batchKeyCode(key, separator);\n return isValidGtin(code) ? displayGtin(normalizeGtin(code)) : code;\n}\n\n/**\n * True when an entered code names the batch key's code. GTINs compare in\n * their 14-digit form, so a UPC-A typed from the label matches its GTIN-14\n * key; anything else compares as trimmed text.\n */\nexport function enteredCodeMatches(entered: string, key: string, separator?: string): boolean {\n const typed = entered.trim();\n const code = batchKeyCode(key, separator);\n if (!typed) return false;\n if (isValidGtin(typed) && isValidGtin(code)) return normalizeGtin(typed) === normalizeGtin(code);\n return typed === code;\n}\n","import { useState } from 'react';\nimport { FieldLabel, FieldHelper } from '../resolver-form/FieldChrome';\nimport { RosterEntryRow, type OfferedAction } from './RosterEntryRow';\nimport { useEmbedWrite } from './embed-write';\nimport { useRosters } from '../../../hooks/useRosters';\nimport { ApiError } from '../../../api/client';\nimport { ROSTER_ACTION_OUTCOMES, useRosterAction } from '../../../api/escalations';\nimport { getDeep } from '../../../lib/x-lt-bind';\nimport type { EmbedColumnDef } from '../../../lib/embed-row';\nimport { offersAction, readRosterActions } from '../../../lib/x-lt-actions';\nimport { readRosterDef, rosterHeadline, type RosterEntry } from '../../../lib/x-lt-roster';\nimport type { EscalationItem } from '../../../lib/escalation-items';\nimport type { ShowIfContext } from '../../../lib/x-lt-show-if';\nimport type { WidgetProps } from './index';\n\nconst DEFAULT_COLUMNS: EmbedColumnDef[] = [{ label: 'Item', value: '{{item.itemKey}}' }];\nconst EMBED_WRITE_VERB = 'continue';\nconst BADGE_OUTCOMES: string[] = [ROSTER_ACTION_OUTCOMES.NEEDS_BADGE, ROSTER_ACTION_OUTCOMES.ROLE_REFUSED];\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return !!v && typeof v === 'object' && !Array.isArray(v);\n}\n\n/** The value a per-key envelope map holds for the entry, when it is a string. */\nfunction keyed(ctx: ShowIfContext, map: string, key: string): string | undefined {\n const values = getDeep(ctx.envelope, map);\n const value = isRecord(values) ? values[key] : undefined;\n return typeof value === 'string' ? value : undefined;\n}\n\n/**\n * The entry's `item` domain: its key, a batch label, and the item once it is\n * in. A held item reads its payload, time and actor from `accumulate_items`;\n * a batch entry reads its payload from `batch_items` and its time and actor\n * from `batch_filled_at` and `batch_filled_by`.\n */\nfunction itemFor(entry: RosterEntry, ctx: ShowIfContext): EscalationItem & { label?: unknown } {\n const held = getDeep(ctx.envelope, 'accumulate_items');\n const batchPayload = getDeep(ctx.envelope, 'batch_items');\n const h = isRecord(held) && isRecord(held[entry.key]) ? held[entry.key] as Record<string, unknown> : null;\n const payload = h && isRecord(h.payload) ? h.payload\n : isRecord(batchPayload) && isRecord(batchPayload[entry.key]) ? batchPayload[entry.key] as Record<string, unknown>\n : undefined;\n const at = typeof h?.at === 'string' ? h.at : h ? undefined : keyed(ctx, 'batch_filled_at', entry.key);\n const actor = typeof h?.actor === 'string' ? h.actor : h ? undefined : keyed(ctx, 'batch_filled_by', entry.key);\n return {\n itemKey: entry.key,\n at: at ?? '',\n ...(payload ? { payload } : {}),\n ...(actor ? { actor } : {}),\n ...(entry.label !== undefined ? { label: entry.label } : {}),\n };\n}\n\n/**\n * Roster widget: every member the host row expects, each marked waiting, in,\n * or flagged, with the count in the heading. The entries come from the same\n * shared computation the page reads for `roster.*` and the roster guard,\n * against the live form, so a scan into a form field ticks its entry in at\n * once and an arrival on any device ticks it in on the next escalation\n * event.\n *\n * Actions run on the server (`/escalations/:id/roster-action`), which\n * re-reads the declaration: a resolve of the entry's member row, or a fill,\n * flag or unflag of its batch key. An action limited to roles asks for a\n * badge of that role when the person acting lacks it.\n *\n * Schema usage:\n * \"x-lt-widget\": \"roster\",\n * \"x-lt-roster\": { \"expected\": { ... }, \"key\": \"...\", \"in\": [...], \"flagged\": [...] },\n * \"x-lt-columns\": [{ \"label\": \"Order\", \"value\": \"{{metadata.orderId}}\" }],\n * \"x-lt-actions\": [{ \"label\": \"Missing\", \"when\": \"waiting\",\n * \"resolverPayload\": { \"outcome\": \"missing\" },\n * \"confirm\": \"Mark {{metadata.orderId}} missing?\" }]\n *\n * Display-only: produces no value of its own in the resolver payload.\n */\nexport function RosterWidget({ fieldKey, schema, escalationContext }: WidgetProps) {\n const ctx = escalationContext ?? {};\n const view = useRosters({ properties: { [fieldKey]: schema ?? {} } }, ctx)[fieldKey];\n const def = readRosterDef(schema);\n const batch = !!def && 'batch' in def.expected;\n const columns = (schema?.['x-lt-columns'] as EmbedColumnDef[] | undefined) ?? DEFAULT_COLUMNS;\n const actions = readRosterActions(schema);\n const label = (schema?.title as string | undefined) ?? 'Expected items';\n const helperText = schema?.description as string | undefined;\n const hostId = String((ctx.escalation as Record<string, unknown> | undefined)?.id ?? '');\n\n const runAction = useRosterAction();\n const guard = useEmbedWrite();\n const [asking, setAsking] = useState<{ key: string; offer: OfferedAction } | null>(null);\n const [pendingKey, setPendingKey] = useState<string | null>(null);\n const [errors, setErrors] = useState<Record<string, string>>({});\n\n const fire = async (entry: RosterEntry, offer: OfferedAction, code?: string): Promise<void> => {\n setPendingKey(entry.key);\n setErrors((prev) => ({ ...prev, [entry.key]: '' }));\n try {\n await runAction.mutateAsync({ id: hostId, field: fieldKey, action: offer.index, entry: entry.key, code });\n } catch (err) {\n const message = (err as Error).message;\n setErrors((prev) => ({ ...prev, [entry.key]: message }));\n const outcome = err instanceof ApiError && isRecord(err.body) ? err.body.outcome : undefined;\n if (typeof outcome === 'string' && BADGE_OUTCOMES.includes(outcome)) {\n guard(EMBED_WRITE_VERB, () => fire(entry, offer, code), { badge: message });\n }\n } finally {\n setPendingKey(null);\n }\n };\n\n const act = (entry: RosterEntry, offer: OfferedAction, code?: string) => {\n setAsking(null);\n guard(EMBED_WRITE_VERB, () => fire(entry, offer, code));\n };\n\n const request = (entry: RosterEntry, offer: OfferedAction) => {\n if (offer.action.confirm || offer.action.fill?.enterCode) setAsking({ key: entry.key, offer });\n else act(entry, offer);\n };\n\n const offeredFor = (entry: RosterEntry): OfferedAction[] =>\n actions\n .map((action, index) => ({ action, index }))\n .filter(({ action }) => offersAction(action, entry, batch));\n\n return (\n <div data-field-key={fieldKey} data-testid={`roster-widget-${fieldKey}`}>\n <div className=\"flex items-baseline justify-between gap-3\">\n <FieldLabel>{label}</FieldLabel>\n {view && (\n <span className=\"text-sm font-medium text-text-primary\" data-testid={`roster-headline-${fieldKey}`}>\n {rosterHeadline(view)}\n </span>\n )}\n </div>\n {helperText && <FieldHelper>{helperText}</FieldHelper>}\n {!view ? (\n <p className=\"text-xs text-text-tertiary py-2\" data-testid={`roster-loading-${fieldKey}`}>Loading expected items…</p>\n ) : view.entries.length === 0 ? (\n <p className=\"text-xs text-text-tertiary italic py-2\" data-testid={`roster-empty-${fieldKey}`}>Nothing expected.</p>\n ) : (\n <ul className=\"mt-1\" data-testid={`roster-list-${fieldKey}`}>\n {view.entries.map((entry) => (\n <RosterEntryRow\n key={entry.key}\n entry={entry}\n item={itemFor(entry, ctx)}\n hostCtx={ctx}\n columns={columns}\n offered={hostId ? offeredFor(entry) : []}\n asking={asking?.key === entry.key ? asking.offer : null}\n pending={pendingKey === entry.key}\n error={errors[entry.key] || undefined}\n onAction={(offer) => request(entry, offer)}\n onConfirm={(code) => asking && act(entry, asking.offer, code)}\n onCancel={() => setAsking(null)}\n />\n ))}\n </ul>\n )}\n </div>\n );\n}\n"],"names":["INTERPOLATION_PATTERN","hasInterpolation","token","resolveCtxPath","path","ctx","dot","root","getDeep","interpolatePath","template","unresolved","concrete","_match","rawPath","value","isTruthy","asComparable","resolvePath","expr","domain","HELP_DOMAINS","evaluateShowIf","condition","c","negate","neqAt","eqAt","isNeq","opAt","expected","known","matches","result","isHiddenIfEmpty","fieldSchema","X_LT_HIDDEN","isHiddenField","FieldLabel","children","isRequired","htmlFor","jsxs","jsx","FieldHelper","id","FieldError","error","inputClass","hasError","selectClass","OpenDetailButton","to","className","Link","ArrowUpRight","InlineConfirm","message","onConfirm","onCancel","testId","runNow","_verb","run","options","EmbedWriteContext","createContext","useEmbedWrite","useContext","InlineCodeEntry","label","code","setCode","useState","submit","SCAN_CAPTURE_ATTR","SCAN_CAPTURE_OFF","e","X_LT_ROSTER","ROSTER_QUERY_LIMIT","ROSTER_ITEMS_SOURCE","ROSTER_ANY_STATUS","ROSTER_STATES","DEFAULT_KEY","MISSING","BATCH_KEYS","BATCH_PENDING","BATCH_FLAGS","ACCUMULATE_KEYS","isRecord","v","strings","s","readRosterDef","raw","readRosterDefs","schema","properties","defs","field","def","roster","rosterQueryOf","resolveRosterQuery","query","facets","k","resolved","interpolateHelp","roles","status","parseJson","parsed","rosterRowContext","row","heldKeys","metadata","accumulated","envelopeItems","pending","countedKeys","values","separator","seen","n","arrivedKeys","arrived","source","batchFlagLabel","key","flags","flag","flagFor","rule","conditions","createdAt","ms","expectedEntries","rows","out","push","extra","newest","held","labels","_a","computeRoster","batch","entries","count","waiting","rosterHeadline","counts","parts","byFlag","STATE_TEXT","StateMark","state","CheckCircle2","Flag","Circle","RosterEntryRow","entry","item","hostCtx","columns","offered","asking","onAction","done","stateLabel","col","FormattedValue","interpolateItemTemplate","offer","listFiltersFor","scoped","schemaNeedsEnvelope","useRosters","host","filters","reads","useQueries","f","escalationListQuery","views","i","read","rosterContext","loaded","X_LT_ACTIONS","ROSTER_ACTION_KINDS","DEFAULT_WHEN","rosterActionKind","action","kinds","readRosterActions","a","offersAction","kind","DEFAULT_COLUMNS","EMBED_WRITE_VERB","BADGE_OUTCOMES","ROSTER_ACTION_OUTCOMES","keyed","map","itemFor","batchPayload","h","payload","at","actor","RosterWidget","fieldKey","escalationContext","view","actions","helperText","hostId","runAction","useRosterAction","guard","setAsking","pendingKey","setPendingKey","errors","setErrors","fire","prev","err","outcome","ApiError","act","request","offeredFor","index"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{j as s}from"./vendor-query-DvWWuNIB.js";import{B as c}from"./BotPicker-Dqpo36dM.js";import{$ as m}from"./index-ygxyAKcc.js";import{g as o,aA as x}from"./vendor-icons-en0_uSRD.js";function j({selected:e,onChange:n}){const{user:t,isSuperAdmin:a,hasRoleType:i}=m(),r=a||i("admin");return s.jsx("div",{children:r?s.jsx(c,{selected:e,onChange:n}):s.jsx("div",{className:"flex items-center gap-1.5",children:e?s.jsxs(s.Fragment,{children:[s.jsx(o,{className:"w-3 h-3 text-accent/75 shrink-0",strokeWidth:1.5}),s.jsxs("span",{className:"text-2xs text-text-secondary",children:["Running as ",s.jsx("span",{className:"font-medium text-accent font-mono",children:e})]})]}):s.jsxs(s.Fragment,{children:[s.jsx(x,{className:"w-3 h-3 text-accent/75 shrink-0",strokeWidth:1.5}),s.jsxs("span",{className:"text-2xs text-text-secondary",children:["Running as ",s.jsx("span",{className:"font-medium text-accent",children:(t==null?void 0:t.displayName)||(t==null?void 0:t.userId)||"you"})]})]})})})}export{j as R};
|
|
2
|
-
//# sourceMappingURL=RunAsSelector-Co6s9bqA.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as n,j as e}from"./vendor-query-DvWWuNIB.js";import{aj as M,bu as m,bv as $,Z as L}from"./index-ygxyAKcc.js";import{p as U,G as H,S as K,a as R}from"./SchemeMatchFields-9H7SmbED.js";import{P as V}from"./PageHeader-DiGWAQlR.js";import{a as q,h as Y}from"./vendor-icons-en0_uSRD.js";import{u as B}from"./vendor-react-_9U4mKFr.js";function O(c){for(let r=10;r<=99;r++)if(!c.has(r))return r;return null}function te(){const c=B(),{data:r,isLoading:o}=M(),[x,i]=n.useState(!1),u=(r==null?void 0:r.schemes)??[],d=new Set(u.map(t=>t.version)),p=O(d);return e.jsxs("div",{children:[e.jsx(V,{title:"Scan Codes"}),e.jsx("p",{className:"text-sm text-text-secondary max-w-form mb-8",children:"A scan code addresses one of your escalations by a value on its label. Add a scheme, name it, and point it at the metadata facet the scanned value matches — then define what each scan does on its detail page."}),o?e.jsx("div",{className:"text-sm text-text-tertiary",children:"Loading…"}):e.jsxs("div",{className:"divide-y divide-surface-border border-y border-surface-border max-w-form",children:[u.map(t=>e.jsxs("div",{role:"button",tabIndex:0,onClick:()=>c(`/admin/scan-codes/${t.version}`),onKeyDown:h=>{(h.key==="Enter"||h.key===" ")&&c(`/admin/scan-codes/${t.version}`)},className:"flex items-center gap-4 py-3 px-2 cursor-pointer hover:bg-surface-sunken transition-colors",children:[e.jsx("span",{className:"w-9 h-8 flex items-center justify-center text-sm font-mono text-accent border border-surface-border rounded shrink-0",children:t.version}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"text-sm text-text-primary truncate",children:t.name}),e.jsxs("div",{className:"text-2xs text-text-tertiary truncate",children:[t.kind===m.IDENTITY&&"identity badge · ","target facet ",e.jsx("span",{className:"font-mono",children:t.target_facet})," · ",t.encoding==="fixed"?`fixed, ${t.target_length} digit target`:t.encoding==="gtin"?"manufacturer barcodes (UPC / EAN)":t.encoding==="pattern"?`${t.patterns.length} ${t.patterns.length===1?"pattern":"patterns"}`:`delimited by "${t.delimiter}"`,t.target_match==="member"&&" · list target"]})]}),e.jsx("span",{className:`text-2xs uppercase tracking-widest ${t.enabled?"text-status-success":"text-text-quaternary"}`,children:t.enabled?"Enabled":"Disabled"})]},t.version)),e.jsxs("div",{className:"flex items-center gap-4 py-3 px-2",children:[e.jsx("span",{className:"w-9 h-8 flex items-center justify-center text-text-quaternary shrink-0",children:e.jsx(q,{className:"w-4 h-4",strokeWidth:1.5})}),p==null?e.jsx("span",{className:"text-2xs text-text-quaternary",children:"All 90 scheme slots are in use."}):x?e.jsx(Q,{version:p,onDone:t=>{i(!1),t!=null&&c(`/admin/scan-codes/${t}`)}}):e.jsxs("button",{type:"button",onClick:()=>i(!0),className:"flex items-center gap-1.5 text-sm text-accent hover:text-accent-hover",children:[e.jsx(Y,{className:"w-3.5 h-3.5"})," Add a scheme"]})]})]})]})}function Q({version:c,onDone:r}){const o=$(),{data:x}=L(),[i,u]=n.useState(""),[d,p]=n.useState(m.ACTION),[t,h]=n.useState(""),[l,C]=n.useState(""),[f,T]=n.useState("value"),[b,_]=n.useState(""),[y,A]=n.useState(null),[v,P]=n.useState(8),[g,E]=n.useState(3600),[k,I]=n.useState(0),[S,D]=n.useState("action"),G=Array.from(new Set(((x==null?void 0:x.roles)??[]).map(s=>s.priority_facet).filter(Boolean))),a=d===m.IDENTITY,j=g>=1&&g<=86400,N=l==="pattern",w=!N||U(b),F=async()=>{!i||!t||!l||a&&!j||!w||(await o.mutateAsync({version:c,name:i,kind:d,target_facet:t,encoding:l,target_length:l==="fixed"?v:null,patterns:N?R(b):[],precedes_gtin:N?y:null,target_match:a?"value":f,grant_ttl_seconds:a?g:null,grant_max_uses:a?k:0,grant_scope:a?S:"action"}),r(c))};return e.jsxs("div",{className:"flex-1 space-y-3",children:[e.jsxs("p",{className:"text-2xs text-text-tertiary",children:["Codes for this scheme start with ",e.jsx("span",{className:"font-mono text-text-secondary",children:c})," — assigned for you."]}),e.jsxs("div",{className:"flex flex-wrap gap-4",children:[e.jsxs("label",{className:"block",children:[e.jsxs("span",{className:"block text-xs text-text-secondary mb-1",children:["Kind ",e.jsx("span",{className:"text-status-error",children:"*"})]}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:a?"A badge — scanning it primes who acts next.":"An item code — scanning it acts on the item."}),e.jsxs("select",{value:d,onChange:s=>p(s.target.value),className:"select",children:[e.jsx("option",{value:m.ACTION,children:"Action"}),e.jsx("option",{value:m.IDENTITY,children:"Identity"})]})]}),e.jsxs("label",{className:"block flex-1 min-w-[16rem]",children:[e.jsxs("span",{className:"block text-xs text-text-secondary mb-1",children:["Name ",e.jsx("span",{className:"text-status-error",children:"*"})]}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:a?'Say who the badge identifies — "Associate badge".':'Say what the target identifies — "Printer serial".'}),e.jsx("input",{value:i,onChange:s=>u(s.target.value),className:"input w-full",placeholder:a?"Associate badge":"Printer serial",autoFocus:!0})]}),e.jsxs("label",{className:"block flex-1 min-w-[16rem]",children:[e.jsxs("span",{className:"block text-xs text-text-secondary mb-1",children:["Target facet ",e.jsx("span",{className:"text-status-error",children:"*"})]}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:a?"The user-metadata key the badge matches (e.g. badge_id).":"The escalation metadata key the scanned value matches."}),e.jsx("input",{value:t,onChange:s=>h(s.target.value),className:"input w-full font-mono",placeholder:a?"badge_id":"serialNumber",list:"scan-facet-suggestions"}),e.jsx("datalist",{id:"scan-facet-suggestions",children:G.map(s=>e.jsx("option",{value:s},s))})]})]}),a&&e.jsxs("div",{className:"flex flex-wrap gap-4",children:[e.jsxs("label",{className:"block",children:[e.jsxs("span",{className:"block text-xs text-text-secondary mb-1",children:["Grant TTL (seconds) ",e.jsx("span",{className:"text-status-error",children:"*"})]}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"How long a badge scan stays primed (1–86400)."}),e.jsx("input",{type:"number",min:1,max:86400,value:g,onChange:s=>E(Number(s.target.value)),className:"input w-[12rem]"}),!j&&e.jsx("span",{className:"block text-2xs text-status-error mt-1",children:"Enter 1–86400 seconds."})]}),e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Grant max uses"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"0 = TTL-bound; n = the grant covers n acts."}),e.jsx("input",{type:"number",min:0,value:k,onChange:s=>I(Number(s.target.value)),className:"input w-[12rem]"})]}),e.jsx(H,{value:S,onChange:D})]}),e.jsxs("div",{className:"flex flex-wrap gap-4",children:[e.jsxs("label",{className:"block",children:[e.jsxs("span",{className:"block text-xs text-text-secondary mb-1",children:["Code style ",e.jsx("span",{className:"text-status-error",children:"*"})]}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"Delimited for QR / Code 128, fixed digits for numeric labels, manufacturer barcodes for the codes printed on products, patterns for codes another system prints (carrier tracking numbers)."}),e.jsxs("select",{value:l,onChange:s=>C(s.target.value),className:"select",children:[e.jsx("option",{value:"",disabled:!0,children:"Choose…"}),e.jsx("option",{value:"delimited",children:"Delimited text (QR / Code 128)"}),e.jsx("option",{value:"fixed",children:"Fixed digits (UPC)"}),!a&&e.jsx("option",{value:"gtin",children:"Manufacturer barcode (UPC / EAN)"}),e.jsx("option",{value:"pattern",children:"Patterns (tracking numbers)"})]})]}),l==="fixed"&&e.jsxs("label",{className:"block",children:[e.jsxs("span",{className:"block text-xs text-text-secondary mb-1",children:["Target digits ",e.jsx("span",{className:"text-status-error",children:"*"})]}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"How many digits the target occupies."}),e.jsx("input",{type:"number",min:1,max:20,value:v,onChange:s=>P(Number(s.target.value)),className:"input w-[12rem]"})]}),e.jsx(K,{encoding:l,isIdentity:a,targetMatch:f,onTargetMatch:T,patternsText:b,onPatternsText:_,precedesGtin:y,onPrecedesGtin:A})]}),o.error&&e.jsx("p",{className:"text-xs text-status-error",children:o.error.message}),e.jsxs("div",{className:"flex gap-3",children:[e.jsx("button",{type:"button",onClick:()=>r(null),className:"btn-secondary text-xs",children:"Discard"}),e.jsx("button",{type:"button",onClick:F,disabled:!i||!t||!l||a&&!j||!w||o.isPending,className:"btn-primary text-xs",children:"Create scheme"})]})]})}export{te as ScanCodesPage};
|
|
2
|
-
//# sourceMappingURL=ScanCodesPage-C2TETaj5.js.map
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import{j as e,a as v}from"./vendor-query-DvWWuNIB.js";import{ac as u,bx as ee,by as ce,bz as re,Z as ie,bu as W,bv as oe,bA as xe,bB as de}from"./index-ygxyAKcc.js";import{P as me}from"./PageHeader-DiGWAQlR.js";import{h as F,H as P,bH as he,bG as ue,j as be,l as pe,a as te}from"./vendor-icons-en0_uSRD.js";import{C as je}from"./ConfirmDeleteModal-CpJNP-8w.js";import{p as ge,a as se,G as Ne,S as fe}from"./SchemeMatchFields-9H7SmbED.js";import{u as ve,e as ye,f as ke}from"./vendor-react-_9U4mKFr.js";const we=[u.SHOW_DETAIL,u.CLAIM,u.CLAIM_SHOW_DETAIL,u.RELEASE,u.RESOLVE,u.ESCALATE,u.CANCEL],Se=()=>({label:"",verb:u.RESOLVE});function Ce({choices:t,onChange:s}){const d=(r,m)=>s(t.map((l,p)=>p===r?{...l,...m}:l)),x=r=>s(t.filter((m,l)=>l!==r));return e.jsxs("div",{className:"space-y-1",children:[e.jsxs("span",{className:"block text-xs text-text-secondary",children:["Choices ",e.jsx("span",{className:"text-status-error",children:"*"})]}),e.jsx("span",{className:"block text-2xs text-text-tertiary",children:"The buttons the station screen offers under the item's reality. A code makes a choice double-scannable — scan the item, then the printed action card."}),e.jsx("div",{className:"divide-y divide-surface-border border-y border-surface-border",children:t.map((r,m)=>e.jsx(Te,{index:m,choice:r,onPatch:l=>d(m,l),onRemove:()=>x(m)},m))}),e.jsxs("button",{type:"button",onClick:()=>s([...t,Se()]),className:"flex items-center gap-1.5 text-sm text-accent hover:text-accent-hover pt-2",children:[e.jsx(F,{className:"w-3.5 h-3.5"})," Add a choice"]})]})}function Te({index:t,choice:s,onPatch:d,onRemove:x}){var h;const[r,m]=v.useState(s.params?JSON.stringify(s.params,null,2):""),[l,p]=v.useState(null),i=c=>{if(m(c),!c.trim()){p(null),d({params:void 0});return}try{d({params:JSON.parse(c)}),p(null)}catch{p("Fix the JSON to save these params.")}};return e.jsxs("div",{className:"pt-8 pb-5 space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"text-xs font-semibold uppercase tracking-widest text-text-tertiary",children:["Choice ",t+1]}),e.jsx("button",{type:"button",onClick:x,className:"icon-link ml-auto",title:"Remove choice",children:e.jsx(P,{className:"w-3.5 h-3.5"})})]}),e.jsxs("div",{className:"flex flex-wrap gap-4",children:[e.jsxs("label",{className:"block flex-1 min-w-[12rem]",children:[e.jsxs("span",{className:"block text-xs text-text-secondary mb-1",children:["Label ",e.jsx("span",{className:"text-status-error",children:"*"})]}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"Button text — what the associate reads."}),e.jsx("input",{value:s.label,onChange:c=>d({label:c.target.value}),className:"input w-full",placeholder:"Collected"})]}),e.jsxs("label",{className:"block",children:[e.jsxs("span",{className:"block text-xs text-text-secondary mb-1",children:["Runs ",e.jsx("span",{className:"text-status-error",children:"*"})]}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"The action this choice performs."}),e.jsx("select",{value:s.verb,onChange:c=>d({verb:c.target.value}),className:"select",children:we.map(c=>e.jsx("option",{value:c,children:c},c))})]}),e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Code"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"Short token for double-scan selection."}),e.jsx("input",{value:s.code??"",onChange:c=>d({code:c.target.value||void 0}),className:"input w-[10rem] font-mono",placeholder:"COLLECT"})]}),e.jsxs("label",{className:"block flex-1 min-w-[14rem]",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Confirmation"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"Ask before running — empty runs on tap."}),e.jsx("input",{value:((h=s.confirm)==null?void 0:h.prompt)??"",onChange:c=>d({confirm:c.target.value?{prompt:c.target.value}:void 0}),className:"input w-full",placeholder:"Run without asking"})]}),e.jsxs("label",{className:"flex items-end gap-2 pb-2",children:[e.jsx("input",{type:"checkbox",checked:!!s.requireActingIdentity,onChange:c=>d({requireActingIdentity:c.target.checked||void 0})}),e.jsx("span",{className:"text-xs text-text-secondary",title:"This choice runs only for a badged (or write-capable) user.",children:"Requires acting identity"})]})]}),e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Params (JSON)"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"The verb's parameters — resolverPayload, targetRole, metadata, durationMinutes."}),e.jsx("textarea",{value:r,onChange:c=>i(c.target.value),rows:3,className:"textarea w-full font-mono text-sm",placeholder:'{ "resolverPayload": { "outcome": "collected" } }'}),l&&e.jsx("span",{className:"block text-2xs text-status-error mt-1",children:l})]})]})}function ae(t){return t.split(",").map(s=>s.trim()).filter(Boolean)}function Ae({step:t,onPatch:s}){const d=t.params??{},x=d.accumulate??{},r=x.item,m=l=>{var h;const{item:p,...i}=x;s({params:{...d,accumulate:l?{...i,item:l}:i},...!l&&((h=t.refuse)!=null&&h.missing)?{refuse:{...t.refuse,missing:void 0}}:{}})};return e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"flex items-center gap-2 basis-full cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:!!r,onChange:l=>m(l.target.checked?{}:void 0),className:"w-4 h-4 rounded border-border accent-accent"}),e.jsx("span",{className:"text-xs text-text-secondary",children:"Also record it on the scanned item's own row"})]}),r&&e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Item queues"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"Where the item's row waits, comma-separated. Empty: any I can read."}),e.jsx("input",{value:(r.roles??[]).join(", "),onChange:l=>{const p=ae(l.target.value),{roles:i,...h}=r;m(p.length?{...h,roles:p}:h)},className:"input w-[14rem] font-mono",placeholder:"packing","aria-label":"Item queues"})]}),r&&e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Item row has"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"facet=value pairs, comma-separated."}),e.jsx("input",{value:Object.entries(r.facets??{}).map(([l,p])=>`${l}=${p}`).join(", "),onChange:l=>{const p=Object.fromEntries(ae(l.target.value).map(c=>c.split("=").map(N=>N.trim())).filter(([c,N])=>c&&N!==void 0&&N!=="")),{facets:i,...h}=r;m(Object.keys(p).length?{...h,facets:p}:h)},className:"input w-[14rem] font-mono",placeholder:"shape=consolidated","aria-label":"Item row has"})]}),r&&t.refuse&&e.jsxs("label",{className:"block basis-full",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"When the item is not waiting"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"What the station says when the scan is right but the item has no waiting row. Empty: the next step runs."}),e.jsx("input",{value:t.refuse.missing??"",onChange:l=>s({refuse:{...t.refuse,missing:l.target.value||void 0}}),className:"input w-full",placeholder:"That one is not waiting to be packed.","aria-label":"When the item is not waiting"})]})]})}function ne(t){return t.split(/[\s,]+/).map(Number).filter(s=>Number.isInteger(s)&&s>=10&&s<=99)}function $(t){return t.split(",").map(s=>s.trim()).filter(Boolean)}function Ee({step:t,onPatch:s}){var c,N,w,S,A,b,E,f;const d=t.params??{},x=a=>s({params:{...d,...a}}),r=d.accumulate??{},m=r.from?"from":r.into?"into":"";if(t.verb===u.HOLD){const a=d.hold??{},j=g=>x({hold:{...a,...g}});return e.jsxs("div",{className:"flex flex-wrap gap-4",children:[e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Hold for (seconds)"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"How long the station waits for the next scan (5–600, default 45)."}),e.jsx("input",{type:"number",min:5,max:600,value:a.ttlSeconds??"",onChange:g=>j({ttlSeconds:g.target.value?Number(g.target.value):void 0}),className:"input w-[10rem]",placeholder:"45"})]}),e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Next scan schemes"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"The scheme versions expected next, e.g. 14."}),e.jsx("input",{value:(((c=a.expect)==null?void 0:c.schemes)??[]).join(", "),onChange:g=>{const k=ne(g.target.value);j({expect:k.length?{...a.expect,schemes:k}:void 0})},className:"input w-[10rem] font-mono",placeholder:"14","aria-label":"Next scan schemes"})]}),e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Headline"}),e.jsxs("span",{className:"block text-2xs text-text-tertiary mb-1",children:["Where it goes, shown largest. ","{item.<facet>}"," reads the held row."]}),e.jsx("input",{value:a.headline??"",onChange:g=>j({headline:g.target.value||void 0}),className:"input w-[14rem] font-mono",placeholder:"{item.containerCode}","aria-label":"Headline"})]}),e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Under the headline"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"A place name, e.g. the facility."}),e.jsx("input",{value:a.subline??"",onChange:g=>j({subline:g.target.value||void 0}),className:"input w-[14rem] font-mono",placeholder:"{item.locationName}","aria-label":"Under the headline"})]}),e.jsxs("label",{className:"block flex-1 min-w-[16rem]",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Ask for it"}),e.jsxs("span",{className:"block text-2xs text-text-tertiary mb-1",children:["Markdown the station shows while holding. ","{item.<facet>}"," reads the held row."]}),e.jsx("input",{value:((N=a.expect)==null?void 0:N.prompt)??"",onChange:g=>a.expect&&j({expect:{...a.expect,prompt:g.target.value||void 0}}),disabled:!a.expect,className:"input w-full",placeholder:"Walk to **{item.containerCode}** and scan it.","aria-label":"Ask for it"})]})]})}const l=t.verb===u.FILL;if(t.verb!==u.ACCUMULATE&&!l)return null;const p=a=>{const{from:j,into:g,item:k,..._}=r;s({params:{...d,accumulate:{..._,...a==="from"?{from:"subject"}:{},...a==="into"?{into:"subject",...k?{item:k}:{}}:{}}},subject:a?t.subject??{schemes:[]}:void 0,match:a?t.match:void 0,refuse:a?t.refuse:void 0})},i=d.fill??{into:"subject"},h=l?i.into==="subject":!!m;return e.jsxs("div",{className:"flex flex-wrap gap-4",children:[l?e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Check off on"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"The row whose expected items the scan checks off."}),e.jsxs("select",{value:i.into,onChange:a=>s({params:{...d,fill:{...i,into:a.target.value}},subject:a.target.value==="subject"?t.subject??{schemes:[]}:void 0}),className:"select",children:[e.jsx("option",{value:"subject",children:"The held item"}),e.jsx("option",{value:"scanned",children:"The scanned row"})]})]}):e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Held item"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"Pair this scan with the item the station is holding."}),e.jsxs("select",{value:m,onChange:a=>p(a.target.value),className:"select",children:[e.jsx("option",{value:"",children:"Not used"}),e.jsx("option",{value:"from",children:"Goes into the scanned container"}),e.jsx("option",{value:"into",children:"Takes the scanned code"})]})]}),h&&e.jsxs("label",{className:"block",children:[e.jsxs("span",{className:"block text-xs text-text-secondary mb-1",children:["Held from schemes ",e.jsx("span",{className:"text-status-error",children:"*"})]}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"The schemes the held item was scanned under, e.g. 11."}),e.jsx("input",{value:(((w=t.subject)==null?void 0:w.schemes)??[]).join(", "),onChange:a=>s({subject:{...t.subject,schemes:ne(a.target.value)}}),className:"input w-[10rem] font-mono",placeholder:"11","aria-label":"Held from schemes"})]}),h&&e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Only when the held item has"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"facet=value pairs, comma-separated; otherwise the next step runs."}),e.jsx("input",{value:Object.entries(((S=t.subject)==null?void 0:S.facets)??{}).map(([a,j])=>`${a}=${j}`).join(", "),onChange:a=>{const j=Object.fromEntries($(a.target.value).map(_=>_.split("=").map(I=>I.trim())).filter(([_,I])=>_&&I!==void 0&&I!=="")),{facets:g,...k}=t.subject??{schemes:[]};s({subject:Object.keys(j).length?{...k,facets:j}:k})},className:"input w-[14rem] font-mono",placeholder:"placement=unassigned","aria-label":"Only when the held item has"})]}),h&&!l&&e.jsxs("label",{className:"block flex-1 min-w-[14rem]",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Must match"}),e.jsxs("span",{className:"block text-2xs text-text-tertiary mb-1",children:["The scanned code must equal one of these, comma-separated, e.g. ","{subject.containerCode}","; a list facet such as ","{subject.offeredContainers}"," allows every entry."]}),e.jsx("input",{value:(((A=t.match)==null?void 0:A.target)??[]).join(", "),onChange:a=>{var g;const j=$(a.target.value);s({match:j.length||(g=t.match)!=null&&g.facets?{...t.match,target:j.length?j:void 0}:void 0})},className:"input w-full font-mono",placeholder:"{subject.containerCode}","aria-label":"Must match"})]}),m==="from"&&e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Shared facets"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"The container must carry the held item's value for these."}),e.jsx("input",{value:(((b=t.match)==null?void 0:b.facets)??[]).join(", "),onChange:a=>{var g;const j=$(a.target.value);s({match:j.length||(g=t.match)!=null&&g.target?{...t.match,facets:j.length?j:void 0}:void 0})},className:"input w-[12rem] font-mono",placeholder:"containerKey","aria-label":"Shared facets"})]}),m==="from"&&t.refuse&&e.jsxs("label",{className:"block basis-full",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"When no open container carries it"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"What the station says when the scan is right but nothing is open under that code. Empty: the next step runs."}),e.jsx("input",{value:t.refuse.missing??"",onChange:a=>s({refuse:{...t.refuse,missing:a.target.value||void 0}}),className:"input w-full",placeholder:"That container was just taken. Scan the item again.","aria-label":"When no open container carries it"})]}),m==="into"&&e.jsx(Ae,{step:t,onPatch:s}),h&&e.jsxs("label",{className:"block basis-full",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"When it lands"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"What the station shows, large, once the write lands. Same tokens as the line below."}),e.jsx("input",{value:((E=t.done)==null?void 0:E.markdown)??"",onChange:a=>s({done:a.target.value?{markdown:a.target.value}:void 0}),className:"input w-full",placeholder:l?"{fill.filled} of {fill.total} checked off.":"Place it in **{container.containerCode}**. All good.","aria-label":"When it lands"})]}),h&&e.jsxs("label",{className:"block basis-full",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"When it is the wrong one"}),e.jsxs("span",{className:"block text-2xs text-text-tertiary mb-1",children:["What the station says. ","{subject.<facet>}"," reads the held item",m==="from"?e.jsxs(e.Fragment,{children:[", ","{container.<facet>}"," the scanned container"]}):null,m==="into"&&r.item?e.jsxs(e.Fragment,{children:[", ","{item.<facet>}"," the scanned item's row"]}):null,l?e.jsxs(e.Fragment,{children:[", ","{fill.pending}"," what is still expected"]}):null,"."]}),e.jsx("input",{value:((f=t.refuse)==null?void 0:f.markdown)??"",onChange:a=>s({refuse:a.target.value?{...t.refuse,markdown:a.target.value}:void 0}),className:"input w-full",placeholder:"This one goes in **{subject.containerCode}**.","aria-label":"When it is the wrong one"})]})]})}const Le={[u.SHOW_DETAIL]:"Show the item",[u.SHOW_LIST]:"Show all matches as a list",[u.CLAIM]:"Claim",[u.CLAIM_SHOW_DETAIL]:"Claim and show the item",[u.RELEASE]:"Release my claim",[u.RESOLVE]:"Resolve with a canned payload",[u.ESCALATE]:"Send to another queue",[u.CANCEL]:"Cancel",[u.ACCUMULATE]:"Add to an accumulator",[u.PRESENT]:"Show reality + choices",[u.HOLD]:"Hold it for the next scan",[u.FILL]:"Check off one expected item"};function Ie({index:t,step:s,roleKeys:d,isLast:x,onPatch:r,onMove:m,onRemove:l}){var _,I,D,q,O,o,y,C,T,R,L,U,G,B,J,V,K,Y,z,Q,Z;const[p,i]=v.useState((_=s.params)!=null&&_.resolverPayload?JSON.stringify(s.params.resolverPayload,null,2):""),[h,c]=v.useState(null),N=n=>r({query:{...s.query,...n}}),w=n=>r({params:{...s.params,...n}}),S=n=>{if(i(n),!n.trim()){c(null),w({resolverPayload:void 0});return}try{w({resolverPayload:JSON.parse(n)}),c(null)}catch{c("Fix the JSON to save this payload.")}},A=s.query.roles??[],b=s.verb===u.PRESENT,E=s.verb===u.ESCALATE,f=s.verb===u.ACCUMULATE,a=f&&!!((D=(I=s.params)==null?void 0:I.accumulate)!=null&&D.containerFacet),j=f&&!!((O=(q=s.params)==null?void 0:q.accumulate)!=null&&O.from||(y=(o=s.params)==null?void 0:o.accumulate)!=null&&y.into),g=n=>{var M;return w({accumulate:{...(M=s.params)==null?void 0:M.accumulate,...n}})},k=s.verb===u.RESOLVE||s.verb===u.ESCALATE&&((C=s.params)==null?void 0:C.closeCurrent)==="resolve"||f;return e.jsxs("div",{className:"py-4 space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"text-2xs font-semibold uppercase tracking-widest text-text-quaternary",children:["Step ",t+1]}),e.jsxs("div",{className:"ml-auto flex items-center gap-1",children:[e.jsx("button",{type:"button",onClick:()=>m(-1),disabled:t===0,className:"icon-link disabled:opacity-30",title:"Move up",children:e.jsx(he,{className:"w-3.5 h-3.5"})}),e.jsx("button",{type:"button",onClick:()=>m(1),disabled:x,className:"icon-link disabled:opacity-30",title:"Move down",children:e.jsx(ue,{className:"w-3.5 h-3.5"})}),e.jsx("button",{type:"button",onClick:l,className:"icon-link",title:"Remove step",children:e.jsx(P,{className:"w-3.5 h-3.5"})})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-4",children:[e.jsxs("div",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Look in"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"The queues the item is expected in — empty means any."}),e.jsx(ee,{values:A,options:d,onChange:n=>N({roles:n.length?n:void 0}),addLabel:"Add a queue…",emptyText:"Any queue I can see",ariaLabel:"Add a queue"})]}),e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Held by"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"Narrow to claimed, unclaimed, or my items."}),e.jsxs("select",{value:s.query.availability??"any",onChange:n=>N({availability:n.target.value==="any"?void 0:n.target.value}),className:"select",children:[e.jsx("option",{value:"any",children:"Anyone / unheld"}),e.jsx("option",{value:"available",children:"Unclaimed only"}),e.jsx("option",{value:"claimed",children:"Claimed only"}),e.jsx("option",{value:"mine",children:"Mine only"})]})]}),e.jsxs("label",{className:"block",children:[e.jsxs("span",{className:"block text-xs text-text-secondary mb-1",children:["Then ",e.jsx("span",{className:"text-status-error",children:"*"})]}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"The action this step performs on a match."}),e.jsx("select",{value:s.verb,onChange:n=>{const M=n.target.value,X=M===u.FILL;r({verb:M,params:X?{fill:{into:"subject"}}:void 0,confirm:void 0,choices:void 0,autoSelectSingle:void 0,subject:X?{schemes:[]}:void 0,match:void 0,refuse:void 0})},className:"select",children:Object.entries(Le).map(([n,M])=>e.jsx("option",{value:n,children:M},n))})]}),E&&e.jsxs("label",{className:"block",children:[e.jsxs("span",{className:"block text-xs text-text-secondary mb-1",children:["Send to ",e.jsx("span",{className:"text-status-error",children:"*"})]}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"The queue the item re-homes to."}),e.jsxs("select",{value:((T=s.params)==null?void 0:T.targetRole)??"",onChange:n=>w({targetRole:n.target.value||void 0}),className:"select font-mono",children:[e.jsx("option",{value:"",disabled:!0,children:"Choose…"}),d.map(n=>e.jsx("option",{value:n,children:n},n))]})]}),E&&e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Current item"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"Close out the located item first."}),e.jsxs("select",{value:((R=s.params)==null?void 0:R.closeCurrent)??"",onChange:n=>w({closeCurrent:n.target.value||void 0}),className:"select",children:[e.jsx("option",{value:"",children:"Leave it open"}),e.jsx("option",{value:"resolve",children:"Resolve it"}),e.jsx("option",{value:"cancel",children:"Cancel it"})]})]}),f&&!j&&e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Container facet"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"Item mode: the scanned item's row carries this facet, and the container that shares its value receives the item. Empty means the scan names the container."}),e.jsx("input",{value:((U=(L=s.params)==null?void 0:L.accumulate)==null?void 0:U.containerFacet)??"",onChange:n=>g({containerFacet:n.target.value||void 0}),className:"input w-full min-w-[12rem] font-mono",placeholder:"binKey","aria-label":"Container facet"})]}),f&&!a&&!((B=(G=s.params)==null?void 0:G.accumulate)!=null&&B.into)&&e.jsxs("label",{className:"block",children:[e.jsxs("span",{className:"block text-xs text-text-secondary mb-1",children:["Item key ",e.jsx("span",{className:"text-status-error",children:"*"})]}),e.jsxs("span",{className:"block text-2xs text-text-tertiary mb-1",children:["The key the item is held under. ","{scan.target}"," fills from the scan; ","{subject.<facet>}"," reads the held item; ","{claim.<facet>}"," the acting user's live claim."]}),e.jsx("input",{value:((J=s.params)==null?void 0:J.itemKey)??"",onChange:n=>w({itemKey:n.target.value||void 0}),className:"input w-full min-w-[16rem] font-mono",placeholder:"{claim.orderId}","aria-label":"Item key"})]}),a&&e.jsxs("div",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Container queues"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"The queues the container is expected in — empty means any I can act on."}),e.jsx(ee,{values:((K=(V=s.params)==null?void 0:V.accumulate)==null?void 0:K.containerRoles)??[],options:d,onChange:n=>g({containerRoles:n.length?n:void 0}),addLabel:"Add a queue…",emptyText:"Any queue I can act on",ariaLabel:"Add a container queue"})]}),a&&e.jsxs("label",{className:"flex items-end gap-2 pb-2",children:[e.jsx("input",{type:"checkbox",checked:((z=(Y=s.params)==null?void 0:Y.accumulate)==null?void 0:z.reciprocal)!==!1,onChange:n=>g({reciprocal:n.target.checked?void 0:!1})}),e.jsx("span",{className:"text-xs text-text-secondary",title:"Write the item's own row in the same statement, so it records which container holds it.",children:"Also record the container on the item"})]}),!b&&!s.subject&&s.verb!==u.HOLD&&s.verb!==u.FILL&&e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Confirmation"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"Ask before acting — the prompt shows on the item."}),e.jsx("input",{value:((Q=s.confirm)==null?void 0:Q.prompt)??"",onChange:n=>r({confirm:n.target.value?{prompt:n.target.value}:void 0}),className:"input w-full min-w-[16rem]",placeholder:"Run without asking"})]}),e.jsxs("label",{className:"flex items-end gap-2 pb-2",children:[e.jsx("input",{type:"checkbox",checked:!!s.requireActingIdentity,onChange:n=>r({requireActingIdentity:n.target.checked||void 0})}),e.jsx("span",{className:"text-xs text-text-secondary",title:"This step runs only for a badged (or write-capable) user.",children:"Requires acting identity"})]}),b&&((Z=s.choices)==null?void 0:Z.length)===1&&e.jsxs("label",{className:"flex items-end gap-2 pb-2",children:[e.jsx("input",{type:"checkbox",checked:!!s.autoSelectSingle,onChange:n=>r({autoSelectSingle:n.target.checked||void 0})}),e.jsx("span",{className:"text-xs text-text-secondary",title:"With one choice, the scan runs it directly instead of presenting; a badge is still collected first when required.",children:"Auto-select the single choice"})]})]}),e.jsx(Ee,{step:s,onPatch:r}),k&&e.jsxs("label",{className:"block",children:[e.jsxs("span",{className:"block text-xs text-text-secondary mb-1",children:[f?"Item payload":"Resolver payload"," ",!f&&e.jsx("span",{className:"text-status-error",children:"*"})]}),e.jsxs("span",{className:"block text-2xs text-text-tertiary mb-1",children:[f?"Optional JSON stored on the item.":"JSON submitted as the resolution."," ","{scan.target}",", ","{scan.category}"," and ","{scan.scannedAt}"," fill in from the scan; ","{claim.<facet>}"," reads the acting user's live claim",a?e.jsxs(e.Fragment,{children:[", ","{item.<facet>}"," the scanned item's row"]}):null,"."]}),e.jsx("textarea",{value:p,onChange:n=>S(n.target.value),rows:3,className:"textarea w-full font-mono text-sm",placeholder:'{ "outcome": "collected", "serial": "{scan.target}" }'}),h&&e.jsx("span",{className:"block text-2xs text-status-error mt-1",children:h})]}),b&&e.jsx(Ce,{choices:s.choices??[],onChange:n=>r({choices:n.length?n:void 0,...n.length===1?{}:{autoSelectSingle:void 0}})})]})}const le=()=>({query:{},verb:u.SHOW_DETAIL});function _e({schemeVersion:t,schemeKind:s,category:d,rule:x,codePreview:r,onDeleted:m}){var q,O;const l=ce(),p=re(),{data:i}=ie(),h=((i==null?void 0:i.roles)??[]).map(o=>o.role),c=s===W.IDENTITY,[N,w]=v.useState((x==null?void 0:x.name)??""),[S,A]=v.useState((x==null?void 0:x.steps)??(c?[]:[le()])),[b,E]=v.useState(((q=x==null?void 0:x.fallback)==null?void 0:q.markdown)??""),[f,a]=v.useState(((O=x==null?void 0:x.notPrimed)==null?void 0:O.markdown)??""),[j,g]=v.useState((x==null?void 0:x.enabled)??!0),k=(o,y)=>A(C=>C.map((T,R)=>R===o?{...T,...y}:T)),_=(o,y)=>A(C=>{const T=[...C],R=o+y;return R<0||R>=T.length?C:([T[o],T[R]]=[T[R],T[o]],T)}),I=o=>A(y=>y.filter((C,T)=>T!==o)),D=()=>l.mutate({scheme_version:t,category:d,name:N,steps:c?[]:S,fallback:{markdown:b||void 0},notPrimed:{markdown:f||void 0},enabled:j});return e.jsxs("div",{className:"space-y-8 max-w-form",children:[e.jsxs("div",{className:"flex flex-wrap items-end gap-4",children:[e.jsxs("label",{className:"block flex-1 min-w-[16rem]",children:[e.jsxs("span",{className:"block text-xs text-text-secondary mb-1",children:["1 · Friendly name ",e.jsx("span",{className:"text-status-error",children:"*"})]}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:c?'Name the badge population — "Associate badge".':'Print this beside the code — "Send Printer to Servicing".'}),e.jsx("input",{value:N,onChange:o=>w(o.target.value),className:"input w-full"})]}),e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Status"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"Disabled rules report unconfigured."}),e.jsxs("select",{value:j?"enabled":"disabled",onChange:o=>g(o.target.value==="enabled"),className:"select",children:[e.jsx("option",{value:"enabled",children:"Enabled"}),e.jsx("option",{value:"disabled",children:"Disabled"})]})]})]}),!c&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-1",children:[e.jsxs("span",{className:"block text-xs text-text-secondary",children:["2 · Conditions and actions ",e.jsx("span",{className:"text-status-error",children:"*"})]}),e.jsx("span",{className:"block text-2xs text-text-tertiary",children:'Scanning walks the steps in order — the first query that finds the item runs its action. Put the expected state first and a broad "show the item" last so a misplaced item still reports where it is.'})]}),e.jsx("div",{className:"divide-y divide-surface-border border-y border-surface-border",children:S.map((o,y)=>e.jsx(Ie,{index:y,step:o,roleKeys:h,isLast:y===S.length-1,onPatch:C=>k(y,C),onMove:C=>_(y,C),onRemove:()=>I(y)},y))}),e.jsxs("button",{type:"button",onClick:()=>A(o=>[...o,le()]),className:"flex items-center gap-1.5 text-sm text-accent hover:text-accent-hover",children:[e.jsx(F,{className:"w-3.5 h-3.5"})," Add a step"]})]}),e.jsxs("div",{className:"flex flex-wrap gap-4",children:[e.jsxs("label",{className:"block flex-1 min-w-[16rem]",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:c?"2 · When the badge is unknown":"3 · When nothing matches"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:c?"Markdown shown when a scanned badge matches no user.":"Markdown shown to the scanner operator when no step finds the item."}),e.jsx("textarea",{value:b,onChange:o=>E(o.target.value),rows:3,className:"textarea w-full font-mono text-sm",placeholder:c?"**Badge not recognized.** See your lead to get it registered.":"**Nothing here.** The item this code points at is not in any queue."})]}),!c&&e.jsxs("label",{className:"block flex-1 min-w-[16rem]",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"When a badge is required"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"Markdown shown when a step or choice needs an acting identity and none is primed."}),e.jsx("textarea",{value:f,onChange:o=>a(o.target.value),rows:3,className:"textarea w-full font-mono text-sm",placeholder:"**Scan your badge** to run this action."})]})]}),l.error&&e.jsx("p",{className:"text-xs text-status-error",children:l.error.message}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("button",{type:"button",onClick:D,disabled:!N||!c&&S.length===0||l.isPending,className:"btn-primary text-xs",children:x?"Save rule":`Create rule ${t}:${d}`}),e.jsx("span",{className:"text-2xs text-text-quaternary font-mono",children:r}),x&&e.jsxs("button",{type:"button",onClick:()=>p.mutate({scheme_version:t,category:d},{onSuccess:m}),className:"ml-auto flex items-center gap-1 text-xs text-status-error/80 hover:text-status-error",children:[e.jsx(P,{className:"w-3.5 h-3.5"})," Delete rule"]})]})]})}function H({icon:t,label:s,annotation:d,aside:x,children:r}){return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-5",children:[e.jsxs("div",{className:"flex items-center gap-1.5 min-w-0",children:[e.jsx(t,{className:"w-3 h-3 text-text-tertiary shrink-0",strokeWidth:1.5}),e.jsx("span",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary",children:s}),d&&e.jsxs("span",{className:"text-2xs text-text-quaternary truncate",children:["— ",d]})]}),x]}),e.jsx("div",{className:"border-l-2 pl-5 border-surface-border/60",children:r})]})}function Re({scheme:t,ruleCount:s}){const d=ve(),x=oe(),r=xe(),[m,l]=v.useState(t.name),[p,i]=v.useState(t.kind),[h,c]=v.useState(t.target_facet),[N,w]=v.useState(t.grant_ttl_seconds??3600),[S,A]=v.useState(t.grant_max_uses??0),[b,E]=v.useState(t.grant_scope??"action"),[f,a]=v.useState(t.enabled),[j,g]=v.useState(t.target_match??"value"),[k,_]=v.useState((t.patterns??[]).join(`
|
|
2
|
-
`)),[I,D]=v.useState(t.precedes_gtin??null),[q,O]=v.useState(!1),o=p===W.IDENTITY,y=!o||N>=1&&N<=86400,C=t.encoding==="pattern",T=!C||ge(k),R=m!==t.name||j!==(t.target_match??"value")||se(k).join(`
|
|
3
|
-
`)!==(t.patterns??[]).join(`
|
|
4
|
-
`)||I!==(t.precedes_gtin??null)||h!==t.target_facet||f!==t.enabled||p!==t.kind||o&&(N!==t.grant_ttl_seconds||S!==t.grant_max_uses||b!==(t.grant_scope??"action"));return e.jsxs(H,{icon:be,label:"Scheme",annotation:`version digit ${t.version}`,aside:e.jsxs("button",{type:"button",onClick:()=>O(!0),className:"flex items-center gap-1 text-xs text-status-error/80 hover:text-status-error",children:[e.jsx(P,{className:"w-3.5 h-3.5"})," Delete scheme"]}),children:[e.jsxs("div",{className:"flex flex-wrap items-end gap-4 max-w-form",children:[e.jsxs("label",{className:"block",children:[e.jsxs("span",{className:"block text-xs text-text-secondary mb-1",children:["Kind ",e.jsx("span",{className:"text-status-error",children:"*"})]}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:o?"A badge — scanning it primes who acts next.":"An item code — scanning it acts on the item."}),e.jsxs("select",{value:p,onChange:L=>i(L.target.value),className:"select",children:[e.jsx("option",{value:W.ACTION,children:"Action"}),e.jsx("option",{value:W.IDENTITY,children:"Identity"})]})]}),e.jsxs("label",{className:"block flex-1 min-w-[16rem]",children:[e.jsxs("span",{className:"block text-xs text-text-secondary mb-1",children:["Name ",e.jsx("span",{className:"text-status-error",children:"*"})]}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:o?"Say who the badge identifies.":"Say what the target identifies."}),e.jsx("input",{value:m,onChange:L=>l(L.target.value),className:"input w-full"})]}),e.jsxs("label",{className:"block flex-1 min-w-[16rem]",children:[e.jsxs("span",{className:"block text-xs text-text-secondary mb-1",children:["Target facet ",e.jsx("span",{className:"text-status-error",children:"*"})]}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:o?"The user-metadata key the badge matches (e.g. badge_id).":"The metadata key the scanned value matches."}),e.jsx("input",{value:h,onChange:L=>c(L.target.value),className:"input w-full font-mono"})]}),o&&e.jsxs("label",{className:"block",children:[e.jsxs("span",{className:"block text-xs text-text-secondary mb-1",children:["Grant TTL (seconds) ",e.jsx("span",{className:"text-status-error",children:"*"})]}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"How long a badge scan stays primed (1–86400)."}),e.jsx("input",{type:"number",min:1,max:86400,value:N,onChange:L=>w(Number(L.target.value)),className:"input w-[12rem]"}),!y&&e.jsx("span",{className:"block text-2xs text-status-error mt-1",children:"Enter 1–86400 seconds."})]}),o&&e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Grant max uses"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"0 = TTL-bound; n = the grant covers n acts."}),e.jsx("input",{type:"number",min:0,value:S,onChange:L=>A(Number(L.target.value)),className:"input w-[12rem]"})]}),o&&e.jsx(Ne,{value:b,onChange:E}),e.jsx(fe,{encoding:t.encoding,isIdentity:o,targetMatch:j,onTargetMatch:g,patternsText:k,onPatternsText:_,precedesGtin:I,onPrecedesGtin:D}),e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs text-text-secondary mb-1",children:"Status"}),e.jsx("span",{className:"block text-2xs text-text-tertiary mb-1",children:"Disable to reject every scan of this version."}),e.jsxs("select",{value:f?"enabled":"disabled",onChange:L=>a(L.target.value==="enabled"),className:"select",children:[e.jsx("option",{value:"enabled",children:"Enabled"}),e.jsx("option",{value:"disabled",children:"Disabled"})]})]}),R&&e.jsx("button",{type:"button",disabled:x.isPending||!m||!h||!y||!T,onClick:()=>x.mutate({version:t.version,name:m,description:t.description,target_facet:h,encoding:t.encoding,delimiter:t.delimiter,target_length:t.target_length,patterns:C?se(k):[],precedes_gtin:C?I:null,target_match:o?"value":j,kind:p,grant_ttl_seconds:o?N:null,grant_max_uses:o?S:0,grant_scope:o?b:"action",enabled:f}),className:"btn-primary text-xs",children:"Save"})]}),x.error&&e.jsx("p",{className:"text-xs text-status-error mt-2",children:x.error.message}),e.jsx(je,{open:q,onClose:()=>O(!1),onConfirm:()=>r.mutate(t.version,{onSuccess:()=>d("/admin/scan-codes")}),title:`Delete scheme ${t.version}`,description:s>0?`This deletes "${t.name}" and its ${s} ${s===1?"rule":"rules"}. Codes starting with ${t.version} stop resolving, and labels already printed with them report unconfigured.`:`This deletes "${t.name}". Codes starting with ${t.version} stop resolving.`,isPending:r.isPending,error:r.error})]})}function Oe(t){for(let s=0;s<=9;s++)if(!t.has(String(s)))return String(s);return null}function Fe(){const{version:t}=ye(),s=Number(t),[d,x]=ke(),{data:r,isLoading:m}=de(Number.isInteger(s)?s:null),l=d.get("category"),p=b=>{x(E=>{const f=new URLSearchParams(E);return b?f.set("category",b):f.delete("category"),f})};if(m)return e.jsx("div",{className:"text-sm text-text-tertiary",children:"Loading…"});if(!r)return e.jsxs("div",{className:"text-sm text-text-tertiary",children:["No scheme for version ",t,"."]});const{scheme:i,rules:h}=r,c=new Map(h.map(b=>[b.category,b])),N=l?c.get(l)??null:null,w=Oe(new Set(h.map(b=>b.category))),S=i.encoding==="fixed"?"7".repeat(i.target_length??8):"SN-1234",A=b=>i.encoding==="gtin"?"036000291452":i.encoding==="pattern"?i.patterns[0]??"":i.encoding==="fixed"?`${i.version}${b}${S}`:`${i.version}${i.delimiter}${b}${i.delimiter}${S}`;return e.jsxs("div",{className:"space-y-10",children:[e.jsx(me,{title:i.name}),e.jsxs("p",{className:"text-sm text-text-secondary max-w-form -mt-4",children:[i.encoding==="gtin"||i.encoding==="pattern"?"Codes for this scheme carry no prefix; the code itself is the target.":e.jsxs(e.Fragment,{children:["Codes for this scheme start with ",e.jsx("span",{className:"font-mono text-text-primary",children:i.version}),"."]}),i.kind===W.IDENTITY?" Scanning a badge primes who acts next; each slot names the badge and its unknown-badge message.":" Add an action, name it, and configure what a scan does — each action gets its own slot automatically."]}),e.jsx(Re,{scheme:i,ruleCount:h.length},i.version),e.jsx(H,{icon:pe,label:"Actions",annotation:i.kind===W.IDENTITY?"named badge slots — each carries its unknown-badge message":"what a scan of this scheme does — named, in the order you add them",children:e.jsxs("div",{className:"divide-y divide-surface-border border-y border-surface-border max-w-form",children:[h.map(b=>{const E=l===b.category;return e.jsxs("button",{type:"button",onClick:()=>p(E?null:b.category),className:`w-full flex items-center gap-4 py-3 px-2 text-left transition-colors ${E?"bg-accent/10":"hover:bg-surface-sunken"}`,children:[e.jsx("span",{className:"w-9 h-8 flex items-center justify-center text-xs font-mono text-accent border border-surface-border rounded shrink-0",children:b.category}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"text-sm text-text-primary truncate",children:b.name}),e.jsx("div",{className:"text-2xs text-text-tertiary font-mono truncate",children:A(b.category)})]})]},b.category)}),e.jsxs("div",{className:"flex items-center gap-4 py-3 px-2",children:[e.jsx("span",{className:"w-9 h-8 flex items-center justify-center text-text-quaternary shrink-0",children:e.jsx(te,{className:"w-4 h-4",strokeWidth:1.5})}),w==null?e.jsx("span",{className:"text-2xs text-text-quaternary",children:"All 10 action slots are in use."}):e.jsxs("button",{type:"button",onClick:()=>p(w),className:"flex items-center gap-1.5 text-sm text-accent hover:text-accent-hover",children:[e.jsx(F,{className:"w-3.5 h-3.5"})," Add an action"]})]})]})}),l&&e.jsx(H,{icon:te,label:N?N.name:"New action",annotation:`this label prints beside the code — e.g. ${A(l)}`,children:e.jsx(_e,{schemeVersion:i.version,schemeKind:i.kind,category:l,rule:N,codePreview:A(l),onDeleted:()=>p(null)},`${i.version}:${l}`)})]})}export{Fe as ScanSchemeDetailPage};
|
|
5
|
-
//# sourceMappingURL=ScanSchemeDetailPage-C2UgU8l-.js.map
|