@hotmeshio/long-tail 0.29.0 → 0.30.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. package/build/api/roles.js +4 -0
  2. package/build/api/scan-codes/choice.js +6 -3
  3. package/build/api/scan-codes/context.d.ts +7 -1
  4. package/build/api/scan-codes/context.js +24 -0
  5. package/build/api/scan-codes/execute.js +4 -2
  6. package/build/api/scan-codes/present.d.ts +3 -1
  7. package/build/api/scan-codes/present.js +25 -12
  8. package/build/routes/oauth.js +9 -6
  9. package/build/services/oauth/providers/github.js +2 -1
  10. package/build/services/oauth/providers/google.js +3 -3
  11. package/build/services/oauth/providers/microsoft.js +4 -1
  12. package/build/services/oauth/providers/mock.js +1 -1
  13. package/build/services/role/scan-done.d.ts +7 -0
  14. package/build/services/role/scan-done.js +36 -0
  15. package/build/services/role/seed.js +4 -0
  16. package/build/services/role/types.d.ts +11 -0
  17. package/build/services/role/types.js +4 -0
  18. package/build/services/scan-code/validate.js +50 -0
  19. package/build/tsconfig.tsbuildinfo +1 -1
  20. package/build/types/index.d.ts +2 -2
  21. package/build/types/index.js +3 -1
  22. package/build/types/oauth.d.ts +1 -0
  23. package/build/types/scan-choice.d.ts +8 -0
  24. package/build/types/scan-code/constants.d.ts +3 -0
  25. package/build/types/scan-code/constants.js +4 -1
  26. package/build/types/scan-code/response.d.ts +14 -0
  27. package/build/types/scan-code/rule.d.ts +11 -0
  28. package/dashboard/dist/assets/{AdminDashboard-DRE0hSDS.js → AdminDashboard-CZIeiLe0.js} +2 -2
  29. package/dashboard/dist/assets/{AdminDashboard-DRE0hSDS.js.map → AdminDashboard-CZIeiLe0.js.map} +1 -1
  30. package/dashboard/dist/assets/{AgentConfigPage-BuflQGgy.js → AgentConfigPage-DO3ATfCU.js} +6 -6
  31. package/dashboard/dist/assets/{AgentConfigPage-BuflQGgy.js.map → AgentConfigPage-DO3ATfCU.js.map} +1 -1
  32. package/dashboard/dist/assets/{AgentDetailPage-BiL9FB7i.js → AgentDetailPage-BWAlHQfB.js} +3 -3
  33. package/dashboard/dist/assets/{AgentDetailPage-BiL9FB7i.js.map → AgentDetailPage-BWAlHQfB.js.map} +1 -1
  34. package/dashboard/dist/assets/{AgentsPage-C4ZxCNxt.js → AgentsPage-Cs4IKeec.js} +2 -2
  35. package/dashboard/dist/assets/{AgentsPage-C4ZxCNxt.js.map → AgentsPage-Cs4IKeec.js.map} +1 -1
  36. package/dashboard/dist/assets/{AvailableEscalationsPage-B5p8QJvI.js → AvailableEscalationsPage-CiRxaing.js} +2 -2
  37. package/dashboard/dist/assets/{AvailableEscalationsPage-B5p8QJvI.js.map → AvailableEscalationsPage-CiRxaing.js.map} +1 -1
  38. package/dashboard/dist/assets/{BotPicker-B7V77PnY.js → BotPicker-DGLkc9PQ.js} +2 -2
  39. package/dashboard/dist/assets/{BotPicker-B7V77PnY.js.map → BotPicker-DGLkc9PQ.js.map} +1 -1
  40. package/dashboard/dist/assets/{BulkAssignModal-DcGVMQqm.js → BulkAssignModal-C4LV8s0y.js} +2 -2
  41. package/dashboard/dist/assets/{BulkAssignModal-DcGVMQqm.js.map → BulkAssignModal-C4LV8s0y.js.map} +1 -1
  42. package/dashboard/dist/assets/{CapabilitiesPage-DmbC1pEs.js → CapabilitiesPage-BLMMV3-W.js} +2 -2
  43. package/dashboard/dist/assets/{CapabilitiesPage-DmbC1pEs.js.map → CapabilitiesPage-BLMMV3-W.js.map} +1 -1
  44. package/dashboard/dist/assets/{CollapsibleSection-C81S1qic.js → CollapsibleSection-BAizcNCt.js} +2 -2
  45. package/dashboard/dist/assets/{CollapsibleSection-C81S1qic.js.map → CollapsibleSection-BAizcNCt.js.map} +1 -1
  46. package/dashboard/dist/assets/{ConfirmDeleteModal-3RFyWN9Q.js → ConfirmDeleteModal-DlNWHVxi.js} +2 -2
  47. package/dashboard/dist/assets/{ConfirmDeleteModal-3RFyWN9Q.js.map → ConfirmDeleteModal-DlNWHVxi.js.map} +1 -1
  48. package/dashboard/dist/assets/{ConnectedAppsPage-B0D2OvTD.js → ConnectedAppsPage-D94kx0v3.js} +2 -2
  49. package/dashboard/dist/assets/{ConnectedAppsPage-B0D2OvTD.js.map → ConnectedAppsPage-D94kx0v3.js.map} +1 -1
  50. package/dashboard/dist/assets/{CountdownTimer-iAG28fzG.js → CountdownTimer-CSdAwgwZ.js} +2 -2
  51. package/dashboard/dist/assets/{CountdownTimer-iAG28fzG.js.map → CountdownTimer-CSdAwgwZ.js.map} +1 -1
  52. package/dashboard/dist/assets/{CredentialsPage-DoFwNvFv.js → CredentialsPage-pOyC1GfC.js} +2 -2
  53. package/dashboard/dist/assets/{CredentialsPage-DoFwNvFv.js.map → CredentialsPage-pOyC1GfC.js.map} +1 -1
  54. package/dashboard/dist/assets/{CronLabel-C1Bb2wo4.js → CronLabel-BVlOOcyo.js} +2 -2
  55. package/dashboard/dist/assets/{CronLabel-C1Bb2wo4.js.map → CronLabel-BVlOOcyo.js.map} +1 -1
  56. package/dashboard/dist/assets/{DropZone-Cl_Flb16.js → DropZone-DefYTYQy.js} +2 -2
  57. package/dashboard/dist/assets/{DropZone-Cl_Flb16.js.map → DropZone-DefYTYQy.js.map} +1 -1
  58. package/dashboard/dist/assets/{ElapsedCell-DZs1I1JW.js → ElapsedCell-Bnjp3onG.js} +2 -2
  59. package/dashboard/dist/assets/{ElapsedCell-DZs1I1JW.js.map → ElapsedCell-Bnjp3onG.js.map} +1 -1
  60. package/dashboard/dist/assets/{EntityTimelinePanel-Du1O6Oly.js → EntityTimelinePanel-D6Z7YXuY.js} +2 -2
  61. package/dashboard/dist/assets/{EntityTimelinePanel-Du1O6Oly.js.map → EntityTimelinePanel-D6Z7YXuY.js.map} +1 -1
  62. package/dashboard/dist/assets/{EscalationListSchemaPage-CrpBhC0e.js → EscalationListSchemaPage-D2aa_arC.js} +2 -2
  63. package/dashboard/dist/assets/{EscalationListSchemaPage-CrpBhC0e.js.map → EscalationListSchemaPage-D2aa_arC.js.map} +1 -1
  64. package/dashboard/dist/assets/{EscalationSchemaPage-Co59lcuD.js → EscalationSchemaPage-DuOje0Ke.js} +2 -2
  65. package/dashboard/dist/assets/{EscalationSchemaPage-Co59lcuD.js.map → EscalationSchemaPage-DuOje0Ke.js.map} +1 -1
  66. package/dashboard/dist/assets/{EscalationTimeline-B_fzNsX5.js → EscalationTimeline-DFkhU2Z2.js} +2 -2
  67. package/dashboard/dist/assets/{EscalationTimeline-B_fzNsX5.js.map → EscalationTimeline-DFkhU2Z2.js.map} +1 -1
  68. package/dashboard/dist/assets/{EscalationTitleSelect-C2Goebjo.js → EscalationTitleSelect-CgYnMM_O.js} +2 -2
  69. package/dashboard/dist/assets/{EscalationTitleSelect-C2Goebjo.js.map → EscalationTitleSelect-CgYnMM_O.js.map} +1 -1
  70. package/dashboard/dist/assets/{EscalationsOverview-Cgmrl8Zc.js → EscalationsOverview-BTkFoklS.js} +2 -2
  71. package/dashboard/dist/assets/{EscalationsOverview-Cgmrl8Zc.js.map → EscalationsOverview-BTkFoklS.js.map} +1 -1
  72. package/dashboard/dist/assets/{EventTable-BdEiu3Fv.js → EventTable-MJmAbu6N.js} +2 -2
  73. package/dashboard/dist/assets/{EventTable-BdEiu3Fv.js.map → EventTable-MJmAbu6N.js.map} +1 -1
  74. package/dashboard/dist/assets/{FilterBar-CzKYBOMC.js → FilterBar-Blt7qcUc.js} +2 -2
  75. package/dashboard/dist/assets/{FilterBar-CzKYBOMC.js.map → FilterBar-Blt7qcUc.js.map} +1 -1
  76. package/dashboard/dist/assets/{GraphInvokePage-CcDFhY53.js → GraphInvokePage-B4K3mT_c.js} +2 -2
  77. package/dashboard/dist/assets/{GraphInvokePage-CcDFhY53.js.map → GraphInvokePage-B4K3mT_c.js.map} +1 -1
  78. package/dashboard/dist/assets/{HomePage-Xahqcdu9.js → HomePage-BN5wXq6V.js} +2 -2
  79. package/dashboard/dist/assets/{HomePage-Xahqcdu9.js.map → HomePage-BN5wXq6V.js.map} +1 -1
  80. package/dashboard/dist/assets/{LinePage-DKwhGunp.js → LinePage-CuHHHwBy.js} +3 -3
  81. package/dashboard/dist/assets/{LinePage-DKwhGunp.js.map → LinePage-CuHHHwBy.js.map} +1 -1
  82. package/dashboard/dist/assets/{LinesPage-BXZVO4MC.js → LinesPage-D9TRHWyt.js} +2 -2
  83. package/dashboard/dist/assets/{LinesPage-BXZVO4MC.js.map → LinesPage-D9TRHWyt.js.map} +1 -1
  84. package/dashboard/dist/assets/{ListToolbar-orQsOdl_.js → ListToolbar-GGj6X36p.js} +2 -2
  85. package/dashboard/dist/assets/{ListToolbar-orQsOdl_.js.map → ListToolbar-GGj6X36p.js.map} +1 -1
  86. package/dashboard/dist/assets/{McpOverview-pSnadtSM.js → McpOverview-Do31A1jL.js} +2 -2
  87. package/dashboard/dist/assets/{McpOverview-pSnadtSM.js.map → McpOverview-Do31A1jL.js.map} +1 -1
  88. package/dashboard/dist/assets/{McpQueryDetailPage-BCAJ3rKO.js → McpQueryDetailPage-D6FSB1bS.js} +2 -2
  89. package/dashboard/dist/assets/{McpQueryDetailPage-BCAJ3rKO.js.map → McpQueryDetailPage-D6FSB1bS.js.map} +1 -1
  90. package/dashboard/dist/assets/{McpQueryPage-CRyXeRp5.js → McpQueryPage-CyT2d0Y_.js} +2 -2
  91. package/dashboard/dist/assets/{McpQueryPage-CRyXeRp5.js.map → McpQueryPage-CyT2d0Y_.js.map} +1 -1
  92. package/dashboard/dist/assets/{McpRunDetailPage-BHppCztI.js → McpRunDetailPage-C3mmTl4Y.js} +2 -2
  93. package/dashboard/dist/assets/{McpRunDetailPage-BHppCztI.js.map → McpRunDetailPage-C3mmTl4Y.js.map} +1 -1
  94. package/dashboard/dist/assets/{McpRunsPage-Cd9yCT-_.js → McpRunsPage-CTeFFUE2.js} +2 -2
  95. package/dashboard/dist/assets/{McpRunsPage-Cd9yCT-_.js.map → McpRunsPage-CTeFFUE2.js.map} +1 -1
  96. package/dashboard/dist/assets/{NamespacePill-OTZD2hzt.js → NamespacePill-CeSfHH-j.js} +2 -2
  97. package/dashboard/dist/assets/{NamespacePill-OTZD2hzt.js.map → NamespacePill-CeSfHH-j.js.map} +1 -1
  98. package/dashboard/dist/assets/{OperationsPage-BtnthZgj.js → OperationsPage-BUtQP5dm.js} +2 -2
  99. package/dashboard/dist/assets/{OperationsPage-BtnthZgj.js.map → OperationsPage-BUtQP5dm.js.map} +1 -1
  100. package/dashboard/dist/assets/{OperatorDashboard-B4_OBhYh.js → OperatorDashboard-BwYOXyUV.js} +2 -2
  101. package/dashboard/dist/assets/{OperatorDashboard-B4_OBhYh.js.map → OperatorDashboard-BwYOXyUV.js.map} +1 -1
  102. package/dashboard/dist/assets/{PageHeader-Hx8APPwE.js → PageHeader-DiGWAQlR.js} +2 -2
  103. package/dashboard/dist/assets/{PageHeader-Hx8APPwE.js.map → PageHeader-DiGWAQlR.js.map} +1 -1
  104. package/dashboard/dist/assets/{PageHeaderWithStats-BEQYYBJv.js → PageHeaderWithStats-DwnKQ06j.js} +2 -2
  105. package/dashboard/dist/assets/{PageHeaderWithStats-BEQYYBJv.js.map → PageHeaderWithStats-DwnKQ06j.js.map} +1 -1
  106. package/dashboard/dist/assets/{PersonaDetailPage-BAYjM9qf.js → PersonaDetailPage-CkrKJLNv.js} +2 -2
  107. package/dashboard/dist/assets/{PersonaDetailPage-BAYjM9qf.js.map → PersonaDetailPage-CkrKJLNv.js.map} +1 -1
  108. package/dashboard/dist/assets/{PersonasPage-6HsOp-1y.js → PersonasPage-BS8aBeOv.js} +2 -2
  109. package/dashboard/dist/assets/{PersonasPage-6HsOp-1y.js.map → PersonasPage-BS8aBeOv.js.map} +1 -1
  110. package/dashboard/dist/assets/{PortalPage-6OMr7KtJ.js → PortalPage-PEBk6VVu.js} +2 -2
  111. package/dashboard/dist/assets/{PortalPage-6OMr7KtJ.js.map → PortalPage-PEBk6VVu.js.map} +1 -1
  112. package/dashboard/dist/assets/{ProcessDetailPage-AidH_h7z.js → ProcessDetailPage-CJ71bxDs.js} +2 -2
  113. package/dashboard/dist/assets/{ProcessDetailPage-AidH_h7z.js.map → ProcessDetailPage-CJ71bxDs.js.map} +1 -1
  114. package/dashboard/dist/assets/{ProcessesListPage-BWKoKbXk.js → ProcessesListPage-ov_HLxz5.js} +2 -2
  115. package/dashboard/dist/assets/{ProcessesListPage-BWKoKbXk.js.map → ProcessesListPage-ov_HLxz5.js.map} +1 -1
  116. package/dashboard/dist/assets/{ResolverForm-BaSvhLoT.js → ResolverForm-BKiUY-lN.js} +2 -2
  117. package/dashboard/dist/assets/{ResolverForm-BaSvhLoT.js.map → ResolverForm-BKiUY-lN.js.map} +1 -1
  118. package/dashboard/dist/assets/RoleDetailPage-CmfWwjtG.js +8 -0
  119. package/dashboard/dist/assets/RoleDetailPage-CmfWwjtG.js.map +1 -0
  120. package/dashboard/dist/assets/{RolePill-R5_ctGFy.js → RolePill-D3hkAdKf.js} +2 -2
  121. package/dashboard/dist/assets/{RolePill-R5_ctGFy.js.map → RolePill-D3hkAdKf.js.map} +1 -1
  122. package/dashboard/dist/assets/{RolesPage-T2hH_MV5.js → RolesPage-DvO5DJWY.js} +2 -2
  123. package/dashboard/dist/assets/{RolesPage-T2hH_MV5.js.map → RolesPage-DvO5DJWY.js.map} +1 -1
  124. package/dashboard/dist/assets/{RosterWidget-DG6Rcx4P.js → RosterWidget-Cs6OTbST.js} +2 -2
  125. package/dashboard/dist/assets/{RosterWidget-DG6Rcx4P.js.map → RosterWidget-Cs6OTbST.js.map} +1 -1
  126. package/dashboard/dist/assets/{RunAsSelector-M2h9U6PP.js → RunAsSelector-VNjUn9Zp.js} +2 -2
  127. package/dashboard/dist/assets/{RunAsSelector-M2h9U6PP.js.map → RunAsSelector-VNjUn9Zp.js.map} +1 -1
  128. package/dashboard/dist/assets/{ScanCodesPage-lB_WxoZw.js → ScanCodesPage-Dbaud0fc.js} +2 -2
  129. package/dashboard/dist/assets/{ScanCodesPage-lB_WxoZw.js.map → ScanCodesPage-Dbaud0fc.js.map} +1 -1
  130. package/dashboard/dist/assets/{ScanSchemeDetailPage-C3VLg61H.js → ScanSchemeDetailPage-BfDw_Eke.js} +2 -2
  131. package/dashboard/dist/assets/{ScanSchemeDetailPage-C3VLg61H.js.map → ScanSchemeDetailPage-BfDw_Eke.js.map} +1 -1
  132. package/dashboard/dist/assets/ScanStationPage-DE-zJTiD.js +2 -0
  133. package/dashboard/dist/assets/ScanStationPage-DE-zJTiD.js.map +1 -0
  134. package/dashboard/dist/assets/{ScopeBadge-BXZ084nD.js → ScopeBadge-DGz79rmG.js} +2 -2
  135. package/dashboard/dist/assets/{ScopeBadge-BXZ084nD.js.map → ScopeBadge-DGz79rmG.js.map} +1 -1
  136. package/dashboard/dist/assets/{StickyPagination-BdjseWXr.js → StickyPagination-CJ3jjlDX.js} +2 -2
  137. package/dashboard/dist/assets/{StickyPagination-BdjseWXr.js.map → StickyPagination-CJ3jjlDX.js.map} +1 -1
  138. package/dashboard/dist/assets/{StreamMessageDetail-DJCBxETh.js → StreamMessageDetail-yOdyJGHR.js} +2 -2
  139. package/dashboard/dist/assets/{StreamMessageDetail-DJCBxETh.js.map → StreamMessageDetail-yOdyJGHR.js.map} +1 -1
  140. package/dashboard/dist/assets/{SwimlaneTimeline-DiXm9jIk.js → SwimlaneTimeline-DeFWNFrL.js} +2 -2
  141. package/dashboard/dist/assets/{SwimlaneTimeline-DiXm9jIk.js.map → SwimlaneTimeline-DeFWNFrL.js.map} +1 -1
  142. package/dashboard/dist/assets/{TagInput-DjPUDp2M.js → TagInput-DaIdhv3h.js} +2 -2
  143. package/dashboard/dist/assets/{TagInput-DjPUDp2M.js.map → TagInput-DaIdhv3h.js.map} +1 -1
  144. package/dashboard/dist/assets/{TaskDetailPage-m8CQFN4w.js → TaskDetailPage-BPL_Zx-L.js} +2 -2
  145. package/dashboard/dist/assets/{TaskDetailPage-m8CQFN4w.js.map → TaskDetailPage-BPL_Zx-L.js.map} +1 -1
  146. package/dashboard/dist/assets/{TaskQueuePill-D-4Ynf3K.js → TaskQueuePill-sUA1nZe-.js} +2 -2
  147. package/dashboard/dist/assets/{TaskQueuePill-D-4Ynf3K.js.map → TaskQueuePill-sUA1nZe-.js.map} +1 -1
  148. package/dashboard/dist/assets/{TasksListPage-DHBSUhZC.js → TasksListPage-Bc3S63_O.js} +2 -2
  149. package/dashboard/dist/assets/{TasksListPage-DHBSUhZC.js.map → TasksListPage-Bc3S63_O.js.map} +1 -1
  150. package/dashboard/dist/assets/{TimeAgo-Cq3bKUd-.js → TimeAgo-DAtnJQwU.js} +2 -2
  151. package/dashboard/dist/assets/{TimeAgo-Cq3bKUd-.js.map → TimeAgo-DAtnJQwU.js.map} +1 -1
  152. package/dashboard/dist/assets/{TimestampCell-e5gRR_FY.js → TimestampCell-CG0erHqq.js} +2 -2
  153. package/dashboard/dist/assets/{TimestampCell-e5gRR_FY.js.map → TimestampCell-CG0erHqq.js.map} +1 -1
  154. package/dashboard/dist/assets/{ToolPill-GsKQ80CO.js → ToolPill-CpBAFdEX.js} +2 -2
  155. package/dashboard/dist/assets/{ToolPill-GsKQ80CO.js.map → ToolPill-CpBAFdEX.js.map} +1 -1
  156. package/dashboard/dist/assets/{ToolTestPanel-Bg0ss9oN.js → ToolTestPanel-c71yqZv7.js} +2 -2
  157. package/dashboard/dist/assets/{ToolTestPanel-Bg0ss9oN.js.map → ToolTestPanel-c71yqZv7.js.map} +1 -1
  158. package/dashboard/dist/assets/{TopicDetailPage-DhPiCfOO.js → TopicDetailPage-BlUP0bb1.js} +2 -2
  159. package/dashboard/dist/assets/{TopicDetailPage-DhPiCfOO.js.map → TopicDetailPage-BlUP0bb1.js.map} +1 -1
  160. package/dashboard/dist/assets/{TopicsPage-BqZaVv3d.js → TopicsPage-lQ9HNzOq.js} +2 -2
  161. package/dashboard/dist/assets/{TopicsPage-BqZaVv3d.js.map → TopicsPage-lQ9HNzOq.js.map} +1 -1
  162. package/dashboard/dist/assets/{UserName-C6ZNHHKN.js → UserName-Vf97ofcW.js} +2 -2
  163. package/dashboard/dist/assets/{UserName-C6ZNHHKN.js.map → UserName-Vf97ofcW.js.map} +1 -1
  164. package/dashboard/dist/assets/{WorkflowExecutionPage-BUqIhtcr.js → WorkflowExecutionPage-B195cnHb.js} +2 -2
  165. package/dashboard/dist/assets/{WorkflowExecutionPage-BUqIhtcr.js.map → WorkflowExecutionPage-B195cnHb.js.map} +1 -1
  166. package/dashboard/dist/assets/{WorkflowPill-D7244fKp.js → WorkflowPill-CKHip3hH.js} +2 -2
  167. package/dashboard/dist/assets/{WorkflowPill-D7244fKp.js.map → WorkflowPill-CKHip3hH.js.map} +1 -1
  168. package/dashboard/dist/assets/{WorkflowsDashboard-BKxhC_hT.js → WorkflowsDashboard-gH-PGsKq.js} +2 -2
  169. package/dashboard/dist/assets/{WorkflowsDashboard-BKxhC_hT.js.map → WorkflowsDashboard-gH-PGsKq.js.map} +1 -1
  170. package/dashboard/dist/assets/{WorkflowsOverview-018s2q_p.js → WorkflowsOverview-D_wYDqw3.js} +2 -2
  171. package/dashboard/dist/assets/{WorkflowsOverview-018s2q_p.js.map → WorkflowsOverview-D_wYDqw3.js.map} +1 -1
  172. package/dashboard/dist/assets/{YamlWorkflowDetailPage-C2zcXDr1.js → YamlWorkflowDetailPage-Imob5F8H.js} +2 -2
  173. package/dashboard/dist/assets/{YamlWorkflowDetailPage-C2zcXDr1.js.map → YamlWorkflowDetailPage-Imob5F8H.js.map} +1 -1
  174. package/dashboard/dist/assets/{YamlWorkflowsPage-aVcNZNu6.js → YamlWorkflowsPage-DVEVSKKJ.js} +2 -2
  175. package/dashboard/dist/assets/{YamlWorkflowsPage-aVcNZNu6.js.map → YamlWorkflowsPage-DVEVSKKJ.js.map} +1 -1
  176. package/dashboard/dist/assets/{agents-DRaaJUue.js → agents-B-8z_DV8.js} +2 -2
  177. package/dashboard/dist/assets/{agents-DRaaJUue.js.map → agents-B-8z_DV8.js.map} +1 -1
  178. package/dashboard/dist/assets/{bots-C4N90NCj.js → bots-Clm-wZeG.js} +2 -2
  179. package/dashboard/dist/assets/{bots-C4N90NCj.js.map → bots-Clm-wZeG.js.map} +1 -1
  180. package/dashboard/dist/assets/{capabilities-BoRWifSC.js → capabilities-CBwgv5tr.js} +2 -2
  181. package/dashboard/dist/assets/{capabilities-BoRWifSC.js.map → capabilities-CBwgv5tr.js.map} +1 -1
  182. package/dashboard/dist/assets/{controlplane-DGZAxi7J.js → controlplane-B96o1-zT.js} +2 -2
  183. package/dashboard/dist/assets/{controlplane-DGZAxi7J.js.map → controlplane-B96o1-zT.js.map} +1 -1
  184. package/dashboard/dist/assets/{escalation-columns-DJbfsH_m.js → escalation-columns-CFoFILF1.js} +2 -2
  185. package/dashboard/dist/assets/{escalation-columns-DJbfsH_m.js.map → escalation-columns-CFoFILF1.js.map} +1 -1
  186. package/dashboard/dist/assets/{escalation-items-C8iJZEA8.js → escalation-items-BCUiPsfS.js} +2 -2
  187. package/dashboard/dist/assets/{escalation-items-C8iJZEA8.js.map → escalation-items-BCUiPsfS.js.map} +1 -1
  188. package/dashboard/dist/assets/{index-DhKGp4QK.js → index-BOuGMe78.js} +2 -2
  189. package/dashboard/dist/assets/{index-DhKGp4QK.js.map → index-BOuGMe78.js.map} +1 -1
  190. package/dashboard/dist/assets/{index-CeeSFnl-.js → index-BXKDpLk5.js} +2 -2
  191. package/dashboard/dist/assets/{index-CeeSFnl-.js.map → index-BXKDpLk5.js.map} +1 -1
  192. package/dashboard/dist/assets/{index-BuSUevzO.js → index-B_z-OFwk.js} +2 -2
  193. package/dashboard/dist/assets/{index-BuSUevzO.js.map → index-B_z-OFwk.js.map} +1 -1
  194. package/dashboard/dist/assets/{index-CyL-6CAa.js → index-C1WJs6IZ.js} +2 -2
  195. package/dashboard/dist/assets/{index-CyL-6CAa.js.map → index-C1WJs6IZ.js.map} +1 -1
  196. package/dashboard/dist/assets/{index-pzbGpihI.js → index-CXNh7LuG.js} +25 -25
  197. package/dashboard/dist/assets/index-CXNh7LuG.js.map +1 -0
  198. package/dashboard/dist/assets/index-C_dp4WgY.css +1 -0
  199. package/dashboard/dist/assets/{index-DMKLnxt8.js → index-CnhNCVPc.js} +2 -2
  200. package/dashboard/dist/assets/{index-DMKLnxt8.js.map → index-CnhNCVPc.js.map} +1 -1
  201. package/dashboard/dist/assets/{index-BFxHIfQ_.js → index-Czb9O4Ns.js} +2 -2
  202. package/dashboard/dist/assets/{index-BFxHIfQ_.js.map → index-Czb9O4Ns.js.map} +1 -1
  203. package/dashboard/dist/assets/{index-BhS9XSy8.js → index-DvgjLvvn.js} +2 -2
  204. package/dashboard/dist/assets/{index-BhS9XSy8.js.map → index-DvgjLvvn.js.map} +1 -1
  205. package/dashboard/dist/assets/{index-CjjRxpVe.js → index-EZkdUZwM.js} +2 -2
  206. package/dashboard/dist/assets/{index-CjjRxpVe.js.map → index-EZkdUZwM.js.map} +1 -1
  207. package/dashboard/dist/assets/{index-DeyA88jq.js → index-IedmSPp1.js} +2 -2
  208. package/dashboard/dist/assets/{index-DeyA88jq.js.map → index-IedmSPp1.js.map} +1 -1
  209. package/dashboard/dist/assets/{index-CXXc9sUr.js → index-MGquOb7J.js} +2 -2
  210. package/dashboard/dist/assets/{index-CXXc9sUr.js.map → index-MGquOb7J.js.map} +1 -1
  211. package/dashboard/dist/assets/{index-3HaFP00M.js → index-P22vmuEu.js} +2 -2
  212. package/dashboard/dist/assets/{index-3HaFP00M.js.map → index-P22vmuEu.js.map} +1 -1
  213. package/dashboard/dist/assets/{index-DIU89TX3.js → index-XS-6UjQd.js} +2 -2
  214. package/dashboard/dist/assets/{index-DIU89TX3.js.map → index-XS-6UjQd.js.map} +1 -1
  215. package/dashboard/dist/assets/{knowledge-BWo3OCJc.js → knowledge-d92ncKgf.js} +2 -2
  216. package/dashboard/dist/assets/{knowledge-BWo3OCJc.js.map → knowledge-d92ncKgf.js.map} +1 -1
  217. package/dashboard/dist/assets/{machines-LEYY_yar.js → machines-BG9laURp.js} +2 -2
  218. package/dashboard/dist/assets/{machines-LEYY_yar.js.map → machines-BG9laURp.js.map} +1 -1
  219. package/dashboard/dist/assets/{mcp-_0kFRcyT.js → mcp-CsZdpCEf.js} +2 -2
  220. package/dashboard/dist/assets/{mcp-_0kFRcyT.js.map → mcp-CsZdpCEf.js.map} +1 -1
  221. package/dashboard/dist/assets/{mcp-query-BzmN0lc5.js → mcp-query-o2xqrZJv.js} +2 -2
  222. package/dashboard/dist/assets/{mcp-query-BzmN0lc5.js.map → mcp-query-o2xqrZJv.js.map} +1 -1
  223. package/dashboard/dist/assets/{personas-kE4PMrgo.js → personas-EYROtAxm.js} +2 -2
  224. package/dashboard/dist/assets/{personas-kE4PMrgo.js.map → personas-EYROtAxm.js.map} +1 -1
  225. package/dashboard/dist/assets/{pipelines-DYDNaypF.js → pipelines-C17xZZsa.js} +2 -2
  226. package/dashboard/dist/assets/{pipelines-DYDNaypF.js.map → pipelines-C17xZZsa.js.map} +1 -1
  227. package/dashboard/dist/assets/{tasks-ClJ-mbj9.js → tasks-CUppIhu6.js} +2 -2
  228. package/dashboard/dist/assets/{tasks-ClJ-mbj9.js.map → tasks-CUppIhu6.js.map} +1 -1
  229. package/dashboard/dist/assets/{topics-oHX4vbqe.js → topics-B-lCJzVc.js} +2 -2
  230. package/dashboard/dist/assets/{topics-oHX4vbqe.js.map → topics-B-lCJzVc.js.map} +1 -1
  231. package/dashboard/dist/assets/{useDebouncedValue-C97KADrj.js → useDebouncedValue-C5mMbYoU.js} +2 -2
  232. package/dashboard/dist/assets/{useDebouncedValue-C97KADrj.js.map → useDebouncedValue-C5mMbYoU.js.map} +1 -1
  233. package/dashboard/dist/assets/{useNamespace-Kje0Rn7j.js → useNamespace-Bu42ipvu.js} +2 -2
  234. package/dashboard/dist/assets/{useNamespace-Kje0Rn7j.js.map → useNamespace-Bu42ipvu.js.map} +1 -1
  235. package/dashboard/dist/assets/{useYamlActivityEvents-DMz-HKFv.js → useYamlActivityEvents-C29uM9Qp.js} +2 -2
  236. package/dashboard/dist/assets/{useYamlActivityEvents-DMz-HKFv.js.map → useYamlActivityEvents-C29uM9Qp.js.map} +1 -1
  237. package/dashboard/dist/assets/{validate-hUqjWN63.js → validate-Bt5QGwSc.js} +2 -2
  238. package/dashboard/dist/assets/{validate-hUqjWN63.js.map → validate-Bt5QGwSc.js.map} +1 -1
  239. package/dashboard/dist/assets/{vendor-icons-fxBvvHBi.js → vendor-icons-en0_uSRD.js} +191 -186
  240. package/dashboard/dist/assets/vendor-icons-en0_uSRD.js.map +1 -0
  241. package/dashboard/dist/assets/{yaml-workflows-64vfmKJx.js → yaml-workflows-DgrmL_Kt.js} +2 -2
  242. package/dashboard/dist/assets/{yaml-workflows-64vfmKJx.js.map → yaml-workflows-DgrmL_Kt.js.map} +1 -1
  243. package/dashboard/dist/index.html +3 -3
  244. package/docs/api/http/roles.md +1 -1
  245. package/docs/dashboard.md +2 -2
  246. package/docs/oauth-and-delegation.md +5 -1
  247. package/docs/scan-codes.md +59 -0
  248. package/package.json +1 -1
  249. package/dashboard/dist/assets/RoleDetailPage-D_30TDVh.js +0 -8
  250. package/dashboard/dist/assets/RoleDetailPage-D_30TDVh.js.map +0 -1
  251. package/dashboard/dist/assets/ScanStationPage-CVET1_4r.js +0 -2
  252. package/dashboard/dist/assets/ScanStationPage-CVET1_4r.js.map +0 -1
  253. package/dashboard/dist/assets/index-B9uv-euR.css +0 -1
  254. package/dashboard/dist/assets/index-pzbGpihI.js.map +0 -1
  255. package/dashboard/dist/assets/vendor-icons-fxBvvHBi.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"escalation-columns-DJbfsH_m.js","sources":["../../src/lib/type-color.ts","../../src/components/escalation/RefineDialog.tsx","../../src/api/escalation-related.ts","../../../shared/list-schema/template.ts","../../src/components/escalation/list-view/RelatedCell.tsx","../../src/components/escalation/list-view/RowDetail.tsx","../../src/components/escalation/list-view/group-rows.ts","../../src/components/escalation/list-view/FacetTable.tsx","../../src/components/escalation/EscalationListView.tsx","../../src/pages/operator/escalation-columns.tsx"],"sourcesContent":["/**\n * Deterministic color assignment for workflow type names.\n *\n * Maps any string to a consistent color from a curated 24-color palette.\n * The same type name always produces the same color across the entire UI.\n * Uses a simple hash to distribute names evenly across the palette.\n *\n * Each entry provides:\n * text — icon and text color (Tailwind class)\n * bg — subtle background tint (Tailwind class)\n */\n\nconst PALETTE: Array<{ text: string; bg: string }> = [\n { text: 'text-rose-400', bg: 'bg-rose-400/[0.08]' },\n { text: 'text-pink-400', bg: 'bg-pink-400/[0.08]' },\n { text: 'text-fuchsia-400', bg: 'bg-fuchsia-400/[0.08]' },\n { text: 'text-purple-400', bg: 'bg-purple-400/[0.08]' },\n { text: 'text-violet-400', bg: 'bg-violet-400/[0.08]' },\n { text: 'text-indigo-400', bg: 'bg-indigo-400/[0.08]' },\n { text: 'text-blue-400', bg: 'bg-blue-400/[0.08]' },\n { text: 'text-sky-400', bg: 'bg-sky-400/[0.08]' },\n { text: 'text-cyan-400', bg: 'bg-cyan-400/[0.08]' },\n { text: 'text-teal-400', bg: 'bg-teal-400/[0.08]' },\n { text: 'text-emerald-400', bg: 'bg-emerald-400/[0.08]' },\n { text: 'text-green-400', bg: 'bg-green-400/[0.08]' },\n { text: 'text-lime-400', bg: 'bg-lime-400/[0.08]' },\n { text: 'text-yellow-400', bg: 'bg-yellow-400/[0.08]' },\n { text: 'text-amber-400', bg: 'bg-amber-400/[0.08]' },\n { text: 'text-orange-400', bg: 'bg-orange-400/[0.08]' },\n { text: 'text-red-400', bg: 'bg-red-400/[0.08]' },\n { text: 'text-stone-400', bg: 'bg-stone-400/[0.08]' },\n { text: 'text-rose-300', bg: 'bg-rose-300/[0.08]' },\n { text: 'text-violet-300', bg: 'bg-violet-300/[0.08]' },\n { text: 'text-sky-300', bg: 'bg-sky-300/[0.08]' },\n { text: 'text-teal-300', bg: 'bg-teal-300/[0.08]' },\n { text: 'text-amber-300', bg: 'bg-amber-300/[0.08]' },\n { text: 'text-pink-300', bg: 'bg-pink-300/[0.08]' },\n];\n\nfunction hash(str: string): number {\n let h = 0;\n for (let i = 0; i < str.length; i++) {\n h = ((h << 5) - h + str.charCodeAt(i)) | 0;\n }\n return Math.abs(h);\n}\n\nexport function typeColor(typeName: string): { text: string; bg: string } {\n return PALETTE[hash(typeName) % PALETTE.length];\n}\n","import { useState } from 'react';\nimport { Check, Search } from 'lucide-react';\nimport { Modal } from '../common/modal/Modal';\nimport { metadataFacetsUrl } from '../../lib/facet-url';\n\n/** One refinable fact from a row: a metadata key with its authored label and value. */\nexport interface RefinePair {\n key: string;\n label: string;\n value: unknown;\n /** The author put this fact in the row's columns; a lone bound fact arrives preselected. */\n bound?: boolean;\n}\n\n/**\n * The row-level refine gesture for authored lists (facet-table rows, board\n * cards): the row's metadata-bound facts as full-width touch rows, each a\n * toggle. Pick one or several (multi-select ANDs the facets) and drill —\n * filter this role's queue, search every role, or merge into the live filter\n * set. One dialog replaces per-cell icon pairs, so table cells spend their\n * width on data and the affordance stays tappable on the iPad floor. The\n * list is the row's whole metadata; past a handful of facts a find box\n * narrows it by label, key, or value.\n */\nconst FIND_THRESHOLD = 6;\nexport function RefineDialog({ open, onClose, role, pairs, onNavigate, onAddFacet }: {\n open: boolean;\n onClose: () => void;\n role: string;\n pairs: RefinePair[];\n /** Receives the facet deep-link. Hosts navigate (or open a panel). */\n onNavigate: (url: string) => void;\n /** When provided, \"Add to filters\" merges the selection into the live set. */\n onAddFacet?: (key: string, value: unknown) => void;\n}) {\n // A single fact, or a single column-bound fact, arrives selected — the\n // one-glance, two-tap path — while the rest of the record waits below.\n const [selected, setSelected] = useState<Set<string>>(new Set());\n const [find, setFind] = useState('');\n const [prevOpen, setPrevOpen] = useState(open);\n if (open !== prevOpen) {\n setPrevOpen(open);\n if (open) {\n const bound = pairs.filter((p) => p.bound);\n const preset = bound.length === 1 ? [bound[0].key] : pairs.length === 1 ? [pairs[0].key] : [];\n setSelected(new Set(preset));\n setFind('');\n }\n }\n const needle = find.trim().toLowerCase();\n const visible = needle\n ? pairs.filter((p) => [p.label, p.key, String(p.value)].some((t) => t.toLowerCase().includes(needle)))\n : pairs;\n\n const toggle = (key: string) => {\n setSelected((prev) => {\n const next = new Set(prev);\n if (next.has(key)) next.delete(key); else next.add(key);\n return next;\n });\n };\n\n const chosen = pairs.filter((p) => selected.has(p.key));\n const facets = Object.fromEntries(chosen.map((p) => [p.key, p.value]));\n const none = chosen.length === 0;\n\n const go = (url: string) => {\n onClose();\n onNavigate(url);\n };\n\n return (\n <Modal open={open} onClose={onClose} title=\"Refine\">\n <div className=\"space-y-4\">\n <p className=\"text-2xs text-text-tertiary\">\n Pick the facts to match — several combine into one narrower query.\n </p>\n\n {pairs.length > FIND_THRESHOLD && (\n <label className=\"flex items-center gap-2 input text-xs py-1.5\">\n <Search className=\"w-3.5 h-3.5 shrink-0 text-text-quaternary\" strokeWidth={1.5} />\n <input\n type=\"text\"\n value={find}\n onChange={(e) => setFind(e.target.value)}\n placeholder=\"Find a fact…\"\n className=\"flex-1 min-w-0 bg-transparent outline-none placeholder:text-text-quaternary\"\n aria-label=\"Find a fact\"\n data-testid=\"refine-find\"\n />\n <span className=\"text-2xs tabular-nums text-text-quaternary\">{visible.length}/{pairs.length}</span>\n </label>\n )}\n\n <div className=\"divide-y divide-surface-border/40 -mx-1 max-h-[50vh] overflow-y-auto\">\n {visible.map((p) => {\n const on = selected.has(p.key);\n return (\n <button\n key={p.key}\n type=\"button\"\n onClick={() => toggle(p.key)}\n aria-pressed={on}\n className=\"w-full flex items-center gap-3 px-1 py-2.5 text-left group min-w-0\"\n data-testid=\"refine-pair\"\n >\n <span\n className={`w-4 h-4 rounded-[3px] border flex items-center justify-center shrink-0 transition-colors ${\n on ? 'bg-accent border-accent' : 'border-surface-border group-hover:border-accent/50'\n }`}\n aria-hidden\n >\n {on && <Check className=\"w-3 h-3 text-text-inverse\" strokeWidth={3} />}\n </span>\n <span className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary w-28 shrink-0 truncate\" title={p.key}>\n {p.label}\n </span>\n <span className=\"text-xs text-text-primary truncate flex-1 min-w-0\" title={String(p.value)}>\n {String(p.value)}\n </span>\n </button>\n );\n })}\n </div>\n\n <div className=\"flex items-center justify-end gap-3 pt-2 flex-wrap\">\n {onAddFacet && (\n <button\n onClick={() => {\n chosen.forEach((p) => onAddFacet(p.key, p.value));\n onClose();\n }}\n disabled={none}\n className=\"text-xs text-text-secondary hover:text-accent transition-colors disabled:opacity-40 disabled:cursor-not-allowed mr-auto\"\n data-testid=\"refine-add-filters\"\n >\n Add to filters\n </button>\n )}\n <button\n onClick={() => go(metadataFacetsUrl(facets))}\n disabled={none}\n className=\"btn-secondary text-xs disabled:opacity-40 disabled:cursor-not-allowed\"\n data-testid=\"refine-search-all\"\n >\n Search everywhere\n </button>\n <button\n onClick={() => go(metadataFacetsUrl(facets, role))}\n disabled={none}\n className=\"btn-primary text-xs disabled:opacity-40 disabled:cursor-not-allowed\"\n data-testid=\"refine-filter-role\"\n >\n Filter {role}\n </button>\n </div>\n </div>\n </Modal>\n );\n}\n","import { useQuery } from '@tanstack/react-query';\nimport { apiFetch } from './client';\nimport type { RelatedAggregatesResponse, RelatedRowsResponse } from '../lib/list-schema';\n\n/**\n * Every related set a role's list schema declares, aggregated for one page\n * of host rows. Keyed under `escalations`, so the list's live invalidation\n * refreshes it with the rows.\n */\nexport function useRelatedAggregates(role: string, ids: string[], version: number | null | undefined, enabled = true) {\n const sorted = [...ids].sort();\n return useQuery<RelatedAggregatesResponse>({\n queryKey: ['escalations', 'related', role, version ?? 'latest', sorted],\n queryFn: () =>\n apiFetch('/escalations/related', {\n method: 'POST',\n body: JSON.stringify({ role, ids: sorted, ...(version != null ? { version } : {}) }),\n }),\n enabled: enabled && !!role && sorted.length > 0,\n placeholderData: (prev) => prev,\n });\n}\n\n/** One host row's rows in one related set, loaded when its detail opens. */\nexport function useRelatedRows(\n role: string,\n id: string,\n set: string,\n version: number | null | undefined,\n limit?: number,\n enabled = true,\n) {\n return useQuery<RelatedRowsResponse>({\n queryKey: ['escalations', 'related-rows', role, version ?? 'latest', id, set, limit ?? null],\n queryFn: () =>\n apiFetch('/escalations/related/rows', {\n method: 'POST',\n body: JSON.stringify({ role, id, set, ...(version != null ? { version } : {}), ...(limit ? { limit } : {}) }),\n }),\n enabled: enabled && !!role && !!id && !!set,\n });\n}\n","import { getDeep } from '../form-validation/x-lt-bind';\nimport { HELP_DOMAINS, interpolateHelp, type HelpDomain, type HelpTokenContext } from '../form-validation/x-lt-help';\n\nconst SINGLE_TOKEN = /^\\{\\{\\s*([^{}]+?)\\s*\\}\\}$/;\nconst ANY_TOKEN = /\\{\\{\\s*[^{}]+?\\s*\\}\\}/;\nconst MISSING_VALUE = '—';\n\nfunction parseJsonObject(value: unknown): Record<string, unknown> | null {\n if (value && typeof value === 'object') return value as Record<string, unknown>;\n if (typeof value !== 'string' || !value) return null;\n try {\n const parsed = JSON.parse(value);\n return parsed && typeof parsed === 'object' ? parsed : null;\n } catch {\n return null;\n }\n}\n\n/** The template domains of one escalation row, JSON-string columns parsed. */\nexport function rowTemplateContext(row: Record<string, unknown>): HelpTokenContext {\n return {\n escalation: row,\n metadata: (row.metadata as Record<string, unknown> | null) ?? {},\n envelope: parseJsonObject(row.envelope) ?? {},\n payload: parseJsonObject(row.escalation_payload) ?? {},\n resolver: parseJsonObject(row.resolver_payload) ?? {},\n };\n}\n\nfunction readToken(path: string, ctx: HelpTokenContext): unknown {\n const dot = path.indexOf('.');\n const domain = (dot === -1 ? path : path.slice(0, dot)) as HelpDomain;\n if (!HELP_DOMAINS.includes(domain)) return undefined;\n const root = ctx[domain];\n if (dot === -1) return root ?? undefined;\n try {\n return getDeep(root, path.slice(dot + 1));\n } catch {\n return undefined;\n }\n}\n\n/**\n * Resolve one facet value. A lone `{{token}}` keeps the value's own JSON type\n * (a numeric facet matches a numeric facet); a mixed template interpolates to\n * a string; a literal passes through. Undefined when a token is missing.\n */\nexport function resolveTemplateValue(value: unknown, ctx: HelpTokenContext): unknown {\n if (typeof value !== 'string') return value;\n const single = value.match(SINGLE_TOKEN);\n if (single) {\n const raw = readToken(single[1], ctx);\n return raw === null || raw === '' ? undefined : raw;\n }\n if (!ANY_TOKEN.test(value)) return value;\n const text = interpolateHelp(value, ctx);\n return text.includes(MISSING_VALUE) ? undefined : text;\n}\n\n/**\n * Resolve a related query's match against a host row: every required facet\n * (null when any is missing), plus each `narrow` facet the row resolves.\n */\nexport function resolveRelatedFacets(\n facets: Record<string, unknown>,\n ctx: HelpTokenContext,\n narrow?: Record<string, unknown>,\n): Record<string, unknown> | null {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(facets)) {\n const resolved = resolveTemplateValue(value, ctx);\n if (resolved === undefined) return null;\n out[key] = resolved;\n }\n for (const [key, value] of Object.entries(narrow ?? {})) {\n const resolved = resolveTemplateValue(value, ctx);\n if (resolved !== undefined) out[key] = resolved;\n }\n return out;\n}\n","import { Link } from 'react-router-dom';\nimport { EM_DASH, FormattedValue } from '../../common/display/FormattedValue';\nimport {\n SPLIT_PATHS,\n isExtremeAggregate,\n relatedCountText,\n type RelatedColumnDecl,\n type RelatedHostAggregate,\n type RelatedSetResult,\n} from '../../../lib/list-schema';\n\n/** A split value's display text: the declared label, a role title, or the value. */\nexport function splitLabel(value: string, col: RelatedColumnDecl, set?: RelatedSetResult): string {\n if (col.labels?.[value]) return col.labels[value];\n if (col.splitBy === SPLIT_PATHS.ROLE && set?.roleLabels?.[value]) return set.roleLabels[value];\n return value === '' ? 'None' : value;\n}\n\n/**\n * A related column cell: the count (or its `display` text), then each split\n * value as a chip in declaration order (role order for a role split), largest\n * first otherwise. A min or max column shows its value. Splits the viewer\n * cannot read show as a muted note, never a wrong split.\n */\nexport function RelatedCell({ col, set, agg, drillUrl }: {\n col: RelatedColumnDecl;\n set?: RelatedSetResult;\n agg?: RelatedHostAggregate;\n /** Query role splits: where a chip leads (the role list with the host's facets). */\n drillUrl?: (role: string) => string | null;\n}) {\n if (!agg || agg.unresolved) return <span className=\"text-text-quaternary\">{EM_DASH}</span>;\n if (isExtremeAggregate(col.aggregate)) {\n if (agg.value === undefined) return <span className=\"text-text-quaternary\">{EM_DASH}</span>;\n return (\n <span className=\"tabular-nums text-text-primary\" data-testid=\"related-cell\">\n <FormattedValue raw={String(agg.value)} format={col.format} />\n </span>\n );\n }\n const countText = relatedCountText(col.display, agg.count);\n const order = col.splitBy === SPLIT_PATHS.ROLE && set?.roles ? set.roles : null;\n const splits = Object.entries(agg.splits ?? {})\n .filter(([, n]) => n > 0)\n .sort(([a, x], [b, y]) => (order ? order.indexOf(a) - order.indexOf(b) : y - x));\n const restricted = col.splitBy === SPLIT_PATHS.ROLE ? (set?.restricted ?? []) : [];\n const title = [\n countText !== null ? String(agg.count) : '',\n agg.hidden ? `${agg.hidden} not readable by you` : '',\n restricted.length ? `Not counted (outside your view): ${restricted.map((r) => set?.roleLabels?.[r] ?? r).join(', ')}` : '',\n ].filter(Boolean).join(' · ');\n\n return (\n <span className=\"inline-flex flex-wrap items-center gap-1 min-w-0\" title={title || undefined} data-testid=\"related-cell\">\n <span className=\"tabular-nums font-medium text-text-primary\" data-testid=\"related-count\">{countText ?? agg.count}</span>\n {splits.map(([value, n]) => {\n const text = `${splitLabel(value, col, set)} ${n}`;\n const href = order && drillUrl ? drillUrl(value) : null;\n const chip = 'px-1.5 py-0.5 rounded bg-surface-sunken text-2xs text-text-secondary whitespace-nowrap tabular-nums';\n return href ? (\n <Link key={value} to={href} onClick={(e) => e.stopPropagation()} className={`${chip} hover:text-accent`} data-testid=\"related-chip\">\n {text}\n </Link>\n ) : (\n <span key={value} className={chip} data-testid=\"related-chip\">{text}</span>\n );\n })}\n {(agg.hidden || restricted.length > 0) && (\n <span className=\"text-2xs text-text-quaternary italic\" data-testid=\"related-restricted\">\n {agg.hidden && !splits.length ? 'split restricted' : 'partial'}\n </span>\n )}\n </span>\n );\n}\n","import { useNavigate } from 'react-router-dom';\nimport { DataTable, type Column } from '../../common/data/DataTable';\nimport { FormattedValue, EM_DASH } from '../../common/display/FormattedValue';\nimport { useRelatedRows } from '../../../api/escalation-related';\nimport { interpolateItemTemplate, type EscalationItem } from '../../../lib/escalation-items';\nimport { displayRoleTitle } from '../../../lib/role-display';\nimport type { RelatedRow, RowDetailSectionDecl } from '../../../lib/list-schema';\nimport { rowContext } from './row-parts';\nimport type { LTEscalationRecord } from '../../../api/types';\n\n/** `format: \"role\"` renders a role name as its title. */\nconst ROLE_FORMAT = 'role';\n\nfunction cellText(template: string, row: RelatedRow): string {\n const ctx = row.escalation ? rowContext(row.escalation as unknown as LTEscalationRecord) : {};\n return interpolateItemTemplate(template, row.item as EscalationItem | undefined, ctx);\n}\n\nfunction DetailSection({ role, host, version, section, roleLabels }: {\n role: string;\n host: LTEscalationRecord;\n version: number | null | undefined;\n section: RowDetailSectionDecl;\n roleLabels?: Record<string, string>;\n}) {\n const navigate = useNavigate();\n const query = useRelatedRows(role, host.id, section.related, version, section.limit);\n const rows = query.data?.rows ?? [];\n const labels = query.data?.roleLabels ?? roleLabels ?? {};\n const restricted = query.data?.restricted ?? [];\n\n // A column whose every row restates a facet the opened row carries says\n // nothing new beneath it: the row already shows that facet.\n const hostValues = new Set(\n Object.values(host.metadata ?? {})\n .filter((v) => (typeof v === 'string' && v !== '') || typeof v === 'number' || typeof v === 'boolean')\n .map(String),\n );\n const shown = section.columns.filter((col, i) => {\n // The first column names each row; it always stays.\n if (i === 0 || rows.length === 0) return true;\n const values = new Set(rows.map((row) => cellText(col.value, row)));\n return !(values.size === 1 && hostValues.has([...values][0]));\n });\n\n const columns: Column<RelatedRow>[] = shown.map((col, i) => ({\n key: `d-${i}`,\n label: col.label,\n priority: col.priority ?? (i === 0 ? 1 : 2),\n render: (row) => {\n const text = cellText(col.value, row);\n if (col.format === ROLE_FORMAT && text !== EM_DASH) {\n return <span className=\"block truncate\">{labels[text] ?? displayRoleTitle({ role: text })}</span>;\n }\n return (\n <span className=\"block truncate\" title={text !== EM_DASH ? text : undefined}>\n <FormattedValue raw={text} format={col.format} />\n </span>\n );\n },\n }));\n\n const target = (row: RelatedRow): string | null =>\n (row.escalation?.id as string | undefined) ?? row.item?.reciprocalId ?? null;\n\n return (\n <div data-testid=\"row-detail-section\">\n <p className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary pt-3 pb-1\">\n {section.label ?? section.related}\n {query.data && <span className=\"ml-2 font-normal normal-case tracking-normal tabular-nums\">{query.data.total}</span>}\n </p>\n {query.isLoading ? (\n <p className=\"text-2xs text-text-tertiary italic pb-2\">Loading…</p>\n ) : (\n <DataTable\n columns={columns}\n data={rows}\n keyFn={(row) => row.item?.itemKey ?? String(row.escalation?.id)}\n onRowClick={(row) => {\n const id = target(row);\n if (id) navigate(`/escalations/detail/${id}`);\n }}\n layout=\"fixed\"\n density=\"compact\"\n inline\n emptyMessage=\"\"\n />\n )}\n {!query.isLoading && rows.length === 0 && (\n <p className=\"text-2xs text-text-quaternary italic pb-2\">None.</p>\n )}\n {query.data && query.data.total > rows.length && (\n <p className=\"text-2xs text-text-quaternary pb-2\">Showing {rows.length} of {query.data.total}.</p>\n )}\n {restricted.length > 0 && (\n <p className=\"text-2xs text-text-quaternary italic pb-2\">\n Not shown (outside your view): {restricted.map((r) => labels[r] ?? r).join(', ')}\n </p>\n )}\n </div>\n );\n}\n\n/** A host row's declared detail sections, each loaded when the row opens. */\nexport function RowDetail({ role, host, version, sections }: {\n role: string;\n host: LTEscalationRecord;\n version: number | null | undefined;\n sections: RowDetailSectionDecl[];\n}) {\n return (\n <div className=\"space-y-1\" data-testid=\"row-detail\">\n {sections.map((section, i) => (\n <DetailSection key={i} role={role} host={host} version={version} section={section} />\n ))}\n </div>\n );\n}\n","import { interpolateHelp } from '../../../lib/x-lt-help';\nimport { GROUP_FOLDS, foldExtreme, isExtremeAggregate, type GroupFold, type RelatedAggregate, type RelatedHostAggregate } from '../../../lib/list-schema';\nimport { EM_DASH } from '../../common/display/FormattedValue';\nimport { rowContext, type ColumnDef } from './row-parts';\nimport type { LTEscalationRecord } from '../../../api/types';\n\n/** One page group from the grouped list read. */\nexport interface EscalationGroup {\n key: string | null;\n ids: string[];\n}\n\n/** A facet-table row: one escalation, or a group of rows sharing a facet. */\nexport interface TableRow {\n key: string;\n rows: LTEscalationRecord[];\n /** The shared facet value; null for an ungrouped row or a row without the facet. */\n groupKey: string | null;\n /** 0 for a top-level line; 1 for a member shown under its open group. */\n depth?: number;\n /** A member that closes its group's block. */\n lastChild?: boolean;\n /** A member's group line. */\n parent?: TableRow;\n}\n\n/** The lines the table draws: each open group followed by its members. */\nexport function withOpenMembers(rows: TableRow[], open: ReadonlySet<string>): TableRow[] {\n return rows.flatMap((row) => {\n if (row.rows.length < 2 || !open.has(row.key)) return [row];\n const members = row.rows.map((m, i): TableRow => ({\n key: `${row.key}/${m.id}`,\n rows: [m],\n groupKey: row.groupKey,\n depth: 1,\n lastChild: i === row.rows.length - 1,\n parent: row,\n }));\n return [row, ...members];\n });\n}\n\n/** Table rows in page order: one per group when grouped, else one per row. */\nexport function buildTableRows(rows: LTEscalationRecord[], groups?: EscalationGroup[] | null): TableRow[] {\n if (!groups) return rows.map((r) => ({ key: r.id, rows: [r], groupKey: null }));\n const byId = new Map(rows.map((r) => [r.id, r]));\n return groups\n .map((g) => ({\n key: g.key != null ? `group:${g.key}` : g.ids[0],\n rows: g.ids.map((id) => byId.get(id)).filter((r): r is LTEscalationRecord => !!r),\n groupKey: g.key,\n }))\n .filter((g) => g.rows.length > 0);\n}\n\nfunction numeric(values: string[]): number[] | null {\n const nums = values.map((v) => Number(v));\n return nums.every((n) => Number.isFinite(n)) ? nums : null;\n}\n\n/**\n * A plain column's text across a group's rows. `first` reads the lead row;\n * `min`/`max` compare numerically when every value is a number, else as text\n * (ISO instants order as text); `sum` adds numbers; `count` counts rows.\n */\nexport function foldColumnText(col: ColumnDef & { group?: GroupFold }, rows: LTEscalationRecord[]): string {\n const fold = col.group ?? GROUP_FOLDS.FIRST;\n if (fold === GROUP_FOLDS.COUNT) return String(rows.length);\n const values = rows.map((r) => interpolateHelp(col.value, rowContext(r))).filter((v) => v && v !== EM_DASH);\n if (fold === GROUP_FOLDS.DISTINCT) return values.length ? [...new Set(values)].join(', ') : EM_DASH;\n if (fold === GROUP_FOLDS.FIRST || rows.length === 1) return values[0] ?? EM_DASH;\n if (!values.length) return EM_DASH;\n const nums = numeric(values);\n if (fold === GROUP_FOLDS.SUM) return nums ? String(nums.reduce((a, b) => a + b, 0)) : EM_DASH;\n if (nums) return String(fold === GROUP_FOLDS.MIN ? Math.min(...nums) : Math.max(...nums));\n const sorted = [...values].sort();\n return fold === GROUP_FOLDS.MIN ? sorted[0] : sorted[sorted.length - 1];\n}\n\n/** One aggregate across several host rows: counts and splits sum; a min or max folds its values. */\nexport function mergeAggregates(\n aggs: Array<RelatedHostAggregate | undefined>,\n aggregate?: RelatedAggregate,\n): RelatedHostAggregate | undefined {\n const present = aggs.filter((a): a is RelatedHostAggregate => !!a);\n if (!present.length) return undefined;\n if (present.every((a) => a.unresolved)) return { count: 0, unresolved: true };\n const out: RelatedHostAggregate = { count: 0 };\n for (const a of present) {\n if (a.unresolved) continue;\n out.count += a.count;\n if (a.hidden) out.hidden = (out.hidden ?? 0) + a.hidden;\n if (a.splits) {\n out.splits ??= {};\n for (const [k, n] of Object.entries(a.splits)) out.splits[k] = (out.splits[k] ?? 0) + n;\n }\n }\n if (isExtremeAggregate(aggregate)) {\n const value = foldExtreme(aggregate, present.flatMap((a) => (a.value === undefined ? [] : [a.value])));\n if (value !== undefined) out.value = value;\n }\n return out;\n}\n","import { useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { ChevronRight } from 'lucide-react';\nimport { interpolateHelp } from '../../../lib/x-lt-help';\nimport { DataTable, type Column as TableColumn } from '../../common/data/DataTable';\nimport { FormattedValue, EM_DASH } from '../../common/display/FormattedValue';\nimport { RefineDialog } from '../RefineDialog';\nimport { useRelatedAggregates } from '../../../api/escalation-related';\nimport { useRelatedSetEvents } from '../../../hooks/useEventHooks';\nimport { metadataFacetsUrl } from '../../../lib/facet-url';\nimport {\n readListSchemaRelations,\n relatedAggregateKey,\n resolveRelatedFacets,\n rowTemplateContext,\n type GroupFold,\n type ListSchemaRelations,\n type RelatedColumnDecl,\n type RelatedSetResult,\n} from '../../../lib/list-schema';\nimport {\n escalationDotClass,\n rowContext,\n rowRefinePairs,\n RowActionButton,\n RefineTrigger,\n IDENTITY_COLUMN_WIDTH,\n actionColumnWidth,\n type ColumnDef,\n type RowActionDef,\n} from './row-parts';\nimport { RelatedCell } from './RelatedCell';\nimport { RowDetail } from './RowDetail';\nimport { buildTableRows, foldColumnText, mergeAggregates, withOpenMembers, type EscalationGroup, type TableRow } from './group-rows';\nimport type { LTEscalationRecord } from '../../../api/types';\n\nexport type { EscalationGroup } from './group-rows';\n\n/** A plain column (a `value` template) or a related column (a `related` set). */\ntype TableColumnDecl = ColumnDef & Partial<Omit<RelatedColumnDecl, 'label'>> & { group?: GroupFold };\n\nexport interface FacetTableSchema {\n 'x-lt-columns'?: Array<ColumnDef | (Omit<ColumnDef, 'value'> & RelatedColumnDecl)>;\n 'x-lt-row-action'?: RowActionDef;\n [key: string]: unknown;\n}\n\n/** One member per distinct resolved facet match (members whose facets do not resolve stay). */\nfunction distinctByMatch(members: LTEscalationRecord[], facets: Record<string, unknown>, narrow?: Record<string, unknown>): LTEscalationRecord[] {\n const seen = new Set<string>();\n return members.filter((m) => {\n const match = resolveRelatedFacets(facets, rowTemplateContext(m as unknown as Record<string, unknown>), narrow);\n if (!match) return true;\n const key = JSON.stringify(match);\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\n/** The related declaration, or none when the stored schema does not validate. */\nfunction safeRelations(schema: FacetTableSchema): ListSchemaRelations | null {\n try {\n return readListSchemaRelations(schema);\n } catch {\n return null;\n }\n}\n\n/**\n * The pending queue as a facet table. Plain columns template over each row;\n * related columns aggregate the row's related sets (one request per page);\n * a declared row detail expands each row into its related rows; grouped\n * rows fold their columns and expand to their members.\n */\ninterface FacetTableProps {\n schema: FacetTableSchema;\n rows: LTEscalationRecord[];\n /** Grouped reads: the page's groups, in order. */\n groups?: EscalationGroup[] | null;\n role: string;\n /** The list schema version the page rendered. */\n version?: number | null;\n onRowClick?: (row: LTEscalationRecord) => void;\n /** RefineDialog \"Add to filters\": merge into the live filter set. */\n onAddFacet?: (key: string, value: unknown) => void;\n forceView?: boolean;\n}\n\n/** Reads the page's related sets and keeps them live; mounted only when the schema declares sets. */\nfunction RelatedFacetTable(props: FacetTableProps & { relations: ListSchemaRelations }) {\n const related = useRelatedAggregates(props.role, props.rows.map((r) => r.id), props.version);\n const sets = related.data?.sets ?? {};\n useRelatedSetEvents(Object.values(sets).flatMap((set) => set.roles ?? []));\n return <FacetTableBody {...props} sets={sets} setsLoading={related.isLoading} />;\n}\n\nexport function FacetTable(props: FacetTableProps) {\n const relations = useMemo(() => safeRelations(props.schema), [props.schema]);\n return relations && Object.keys(relations.sets).length > 0\n ? <RelatedFacetTable {...props} relations={relations} />\n : <FacetTableBody {...props} relations={relations} sets={{}} setsLoading={false} />;\n}\n\nfunction FacetTableBody({ schema, rows, groups, role, version, onRowClick, onAddFacet, forceView, relations, sets, setsLoading }: FacetTableProps & {\n relations: ListSchemaRelations | null;\n sets: Record<string, RelatedSetResult>;\n setsLoading: boolean;\n}) {\n const navigate = useNavigate();\n const columnDefs = (schema['x-lt-columns'] ?? []) as TableColumnDecl[];\n const rowAction = schema['x-lt-row-action'];\n const sections = relations?.rowDetail ?? [];\n const [refineRow, setRefineRow] = useState<LTEscalationRecord | null>(null);\n const [open, setOpen] = useState<Set<string>>(() => new Set());\n\n const tableRows = useMemo(() => buildTableRows(rows, groups), [rows, groups]);\n const lines = useMemo(() => withOpenMembers(tableRows, open), [tableRows, open]);\n const grouped = !!groups;\n const expandable = sections.length > 0 || grouped;\n // A row opens when it has something beneath it: a group its members, a row its detail.\n const opens = (r: TableRow) => r.rows.length > 1 || sections.length > 0;\n\n const toggle = (key: string) =>\n setOpen((prev) => {\n const next = new Set(prev);\n if (next.has(key)) next.delete(key); else next.add(key);\n return next;\n });\n\n const relatedCell = (col: TableColumnDecl, members: LTEscalationRecord[]) => {\n const name = col.related!;\n const set = sets[name];\n const query = relations?.sets[name]?.query;\n // Members that share a facet match read the same related rows: count them once.\n const counted = query?.facets ? distinctByMatch(members, query.facets, query.narrow) : members;\n const key = relatedAggregateKey(col as RelatedColumnDecl, relations?.sets[name]?.source ?? '');\n const agg = mergeAggregates(counted.map((m) => set?.aggregates[key]?.[m.id]), (col as RelatedColumnDecl).aggregate);\n const drillUrl = query?.facets && members.length === 1\n ? (relatedRole: string) => {\n const match = resolveRelatedFacets(query.facets!, rowTemplateContext(members[0] as unknown as Record<string, unknown>), query.narrow);\n return match ? metadataFacetsUrl(match, relatedRole) : null;\n }\n : undefined;\n return <RelatedCell col={col as RelatedColumnDecl} set={set} agg={setsLoading ? undefined : agg} drillUrl={drillUrl} />;\n };\n\n // The authored columns render through the same dense table the engineer\n // views use: the card fold at narrow widths, never a horizontal scroll.\n // Authors steer the fold with `priority` (1 title, 2 folds, 3 dropped).\n const actionLabel = rowAction?.label ?? (forceView ? 'View' : 'Claim');\n const lead = (r: TableRow) => r.rows[0];\n const columns: TableColumn<TableRow>[] = [\n ...(expandable ? [{\n key: '_expand',\n label: '',\n priority: 1 as const,\n className: 'w-12 px-1',\n render: (r: TableRow) => (\n // A member's chevron steps in under its group's, so depth reads at a glance.\n <span className={`flex ${r.depth ? 'pl-5' : ''}`}>\n {opens(r) && (\n <button\n type=\"button\"\n onClick={(e) => { e.stopPropagation(); toggle(r.key); }}\n className=\"p-1 rounded icon-link hover:bg-surface-hover transition-colors\"\n aria-expanded={open.has(r.key)}\n aria-label={open.has(r.key) ? 'Collapse row' : 'Expand row'}\n data-testid=\"row-expand\"\n >\n <ChevronRight className={`w-3.5 h-3.5 transition-transform ${open.has(r.key) ? 'rotate-90' : ''}`} strokeWidth={1.75} />\n </button>\n )}\n </span>\n ),\n }] : []),\n {\n key: '_status',\n label: '',\n priority: 1,\n className: 'w-8',\n render: (r) => (\n <span className=\"inline-flex items-center gap-1\">\n <span className={`w-2.5 h-2.5 inline-block rounded-full dot-ring ${escalationDotClass(lead(r))}`} title={lead(r).status} />\n {r.rows.length > 1 && (\n <span className=\"text-2xs tabular-nums text-text-tertiary\" title={`${r.rows.length} rows in this group`} data-testid=\"group-size\">\n {r.rows.length}\n </span>\n )}\n </span>\n ),\n },\n ...columnDefs.map((col, i): TableColumn<TableRow> => ({\n key: `col-${i}`,\n label: col.label,\n priority: col.priority ?? (i === 0 ? 1 : 2),\n width: col.width ?? (i === 0 && !columnDefs.some((c) => c.width) ? IDENTITY_COLUMN_WIDTH : undefined),\n render: (r) => {\n if (col.related) return relatedCell(col, r.rows);\n const text = r.rows.length > 1 ? foldColumnText(col, r.rows) : interpolateHelp(col.value, rowContext(lead(r)));\n // A member shows only what differs from its group: the group line already states the rest.\n if (r.parent && text === foldColumnText(col, r.parent.rows)) return null;\n // The identity steps in for a member, so the tree reads in the data too.\n const indent = i === 0 && r.depth ? 'pl-4' : '';\n return (\n <span className={`block truncate ${indent}`} title={text && text !== EM_DASH ? text : undefined}>\n <FormattedValue raw={text} format={col.format} />\n </span>\n );\n },\n })),\n {\n key: '_refine',\n label: '',\n priority: 1,\n className: 'w-8 px-1',\n render: (r) =>\n r.rows.length === 1 && rowRefinePairs(lead(r), columnDefs).length > 0\n ? <RefineTrigger onOpen={() => setRefineRow(lead(r))} />\n : null,\n },\n {\n // The action column sizes to its label so the button never wraps.\n key: '_action',\n label: '',\n priority: 1,\n width: actionColumnWidth(actionLabel),\n className: 'text-right whitespace-nowrap',\n render: (r) => r.rows.length === 1\n ? <RowActionButton row={lead(r)} def={rowAction} onView={() => onRowClick?.(lead(r))} forceView={forceView} />\n : null,\n },\n ];\n\n // Containment by depth: an open line takes a light band, its members a\n // stronger band stepped in under it, and a row's detail the band of its\n // row, indented past it. No rules: indentation and value carry the tree.\n const rowClassName = (r: TableRow) => {\n if (r.depth) return 'bg-surface-sunken border-b-surface-border/40';\n return open.has(r.key) && opens(r) ? 'bg-surface-sunken/50 border-b-surface-border/40' : '';\n };\n\n const renderExpansion = (r: TableRow) => {\n if (!open.has(r.key) || r.rows.length > 1 || sections.length === 0) return null;\n return (\n <div\n onClick={(e) => e.stopPropagation()}\n className={`${r.depth ? 'bg-surface-sunken pl-20' : 'bg-surface-sunken/50 pl-12'} pr-3 pt-1 pb-4`}\n data-testid=\"row-detail-block\"\n >\n <RowDetail role={role} host={lead(r)} version={version} sections={sections} />\n </div>\n );\n };\n\n return (\n <>\n <DataTable\n columns={columns}\n data={lines}\n layout=\"fixed\"\n density=\"dense\"\n keyFn={(r) => r.key}\n onRowClick={onRowClick ? (r) => (r.rows.length === 1 ? onRowClick(lead(r)) : toggle(r.key)) : undefined}\n rowClassName={expandable ? rowClassName : undefined}\n emptyMessage=\"No pending items.\"\n renderExpansion={expandable ? renderExpansion : undefined}\n />\n <RefineDialog\n open={!!refineRow}\n onClose={() => setRefineRow(null)}\n role={role}\n pairs={refineRow ? rowRefinePairs(refineRow, columnDefs) : []}\n onNavigate={navigate}\n onAddFacet={onAddFacet}\n />\n </>\n );\n}\n","import { useState, useEffect } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { interpolateHelp } from '../../lib/x-lt-help';\nimport { MarkdownRenderer } from '../common/display/MarkdownRenderer';\nimport { DateValue } from '../common/display/DateValue';\nimport { FormattedValue as FieldValue, EM_DASH, isAgeFormat } from '../common/display/FormattedValue';\nimport { StickyPagination } from '../common/data/StickyPagination';\nimport { useEscalations } from '../../api/escalations';\nimport { schemaNeedsEnvelope } from '../../lib/schema-needs-envelope';\nimport { getDeep } from '../../lib/x-lt-bind';\nimport { typeColor } from '../../lib/type-color';\nimport { RefineDialog, type RefinePair } from './RefineDialog';\nimport {\n escalationDotClass,\n rowContext,\n RowActionButton,\n RefineTrigger,\n METADATA_TOKEN,\n type ColumnDef,\n type RowActionDef,\n} from './list-view/row-parts';\nimport { FacetTable, type EscalationGroup } from './list-view/FacetTable';\nimport type { LTEscalationRecord } from '../../api/types';\n\nexport { rowContext, rowRefinePairs } from './list-view/row-parts';\nexport type { ColumnDef, RowActionDef } from './list-view/row-parts';\nexport { FIELD_FORMATS } from '../common/display/FormattedValue';\n\n/**\n * EscalationListView — the role-authored rich view of an escalation list, driven\n * by a versioned `list_schema` (x-lt-* markup). The list-page analog of the\n * resolve form: the same `{{domain.path}}` token binding (via interpolateHelp)\n * against each row's context, and MarkdownRenderer for rich bodies.\n *\n * Layouts:\n * active-history — single live item as a card on the left + history column on right\n * active — just the single live item card (no history)\n * facet-table — full pending queue as a table, columns from x-lt-columns\n * facet-board — one card per x-lt-group-by facet value (an entity board:\n * machines, stations), rendered from each group's latest row\n */\n\ninterface CardDef {\n title?: string;\n subtitle?: string;\n body?: string;\n fields?: { label: string; value: string; format?: string }[];\n}\n\ninterface HistoryDef {\n row?: { title?: string; subtitle?: string; meta?: string };\n limit?: number;\n status?: string;\n}\n\n\ninterface BoardCardDef {\n title?: string;\n /** Status chip — any token (commonly {{escalation.subtype}}). */\n state?: string;\n fields?: { label: string; value: string; format?: string }[];\n}\n\n\nexport interface ListSchema {\n 'x-lt-layout'?: string;\n 'x-lt-help'?: string;\n 'x-lt-active'?: CardDef;\n 'x-lt-history'?: HistoryDef;\n 'x-lt-columns'?: ColumnDef[];\n /** facet-board: the \"domain.path\" whose value identifies each entity. */\n 'x-lt-group-by'?: string;\n /** facet-board: the per-entity card definition. */\n 'x-lt-card'?: BoardCardDef;\n /** The per-row action button (claim | view, label, claim duration). */\n 'x-lt-row-action'?: RowActionDef;\n /** facet-table: related sets, row detail sections (see shared/list-schema). */\n 'x-lt-related'?: Record<string, unknown>;\n 'x-lt-row-detail'?: unknown[];\n}\n\n/**\n * Repaint-only minute tick so `format: \"age\"` values stay current. Pure\n * re-render — no network. Mounted once at the view root, only when the\n * schema actually uses ages.\n */\nfunction useAgeTick(enabled: boolean): void {\n const [, setTick] = useState(0);\n useEffect(() => {\n if (!enabled) return;\n const t = window.setInterval(() => setTick((n) => n + 1), 60_000);\n return () => window.clearInterval(t);\n }, [enabled]);\n}\n\nfunction schemaUsesAge(schema: ListSchema): boolean {\n return [...(schema['x-lt-columns'] ?? []), ...(schema['x-lt-card']?.fields ?? [])]\n .some((f) => isAgeFormat(f.format));\n}\n\n\n\n\n\nfunction ActiveCard({ esc, card, rowAction, onOpen, forceView }: {\n esc: LTEscalationRecord;\n card: CardDef;\n rowAction?: RowActionDef;\n onOpen?: () => void;\n forceView?: boolean;\n}) {\n const ctx = rowContext(esc);\n const title = card.title ? interpolateHelp(card.title, ctx) : esc.type;\n return (\n <div>\n <div className=\"flex items-start justify-between gap-6\">\n <button onClick={onOpen} className=\"text-left group min-w-0\">\n <h3 className=\"heading-2 group-hover:text-accent transition-colors leading-tight\">\n {title}\n </h3>\n {card.subtitle && (\n <p className=\"text-xs text-text-tertiary mt-1.5\">{interpolateHelp(card.subtitle, ctx)}</p>\n )}\n </button>\n\n {/* The row action — one-click claim (then the detail page opens already\n claimed), or view for read-only templates. */}\n <RowActionButton row={esc} def={rowAction} onView={onOpen} prominent forceView={forceView} />\n </div>\n\n {card.fields && card.fields.length > 0 && (\n <dl className=\"flex flex-wrap gap-x-10 gap-y-4 mt-6\">\n {card.fields.map((f, i) => (\n <div key={i}>\n <dt className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary\">{f.label}</dt>\n <dd className=\"text-xs text-text-primary mt-1\"><FieldValue raw={interpolateHelp(f.value, ctx)} /></dd>\n </div>\n ))}\n </dl>\n )}\n\n {card.body && (\n <div className=\"mt-7 pt-6 border-t border-surface-border/50\">\n <MarkdownRenderer content={interpolateHelp(card.body, ctx)} />\n </div>\n )}\n </div>\n );\n}\n\nfunction HistoryColumn({ role, def, onRowClick }: {\n role: string;\n def: HistoryDef;\n onRowClick?: (row: LTEscalationRecord) => void;\n}) {\n const [show, setShow] = useState(false);\n const query = useEscalations({\n role,\n status: def.status ?? 'resolved',\n sort_by: 'resolved_at',\n order: 'desc',\n limit: def.limit ?? 25,\n enabled: show,\n include: schemaNeedsEnvelope(def) ? 'envelope' : undefined,\n });\n const rows = query.data?.escalations ?? [];\n const total = query.data?.total ?? 0;\n const rowDef = def.row ?? {};\n\n if (!show) {\n return (\n <button\n onClick={() => setShow(true)}\n className=\"text-xs text-accent hover:underline\"\n data-testid=\"load-history\"\n >\n Load full history →\n </button>\n );\n }\n\n if (query.isLoading) {\n return <p className=\"text-xs text-text-tertiary italic\">Loading history…</p>;\n }\n\n if (rows.length === 0) {\n return <p className=\"text-xs text-text-tertiary italic\">No past revisions.</p>;\n }\n\n return (\n <div>\n <div className=\"divide-y divide-surface-border/40\">\n {rows.map((e) => {\n const ctx = rowContext(e);\n return (\n <button\n key={e.id}\n onClick={() => onRowClick?.(e)}\n className=\"w-full text-left py-2.5 group flex items-center gap-3\"\n >\n {/* Status as a bare outlined dot — colour carries the meaning. */}\n <span\n className={`w-2.5 h-2.5 shrink-0 rounded-full dot-ring ${escalationDotClass(e)}`}\n title={e.status}\n />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block text-xs text-text-primary group-hover:text-accent transition-colors truncate\">\n {rowDef.title ? interpolateHelp(rowDef.title, ctx) : e.type}\n </span>\n {rowDef.subtitle && (\n <span className=\"block text-2xs text-text-tertiary truncate\">\n {interpolateHelp(rowDef.subtitle, ctx)}\n </span>\n )}\n </span>\n {rowDef.meta\n ? <span className=\"text-2xs text-text-tertiary shrink-0\">{interpolateHelp(rowDef.meta, ctx)}</span>\n : e.resolved_at && <DateValue date={e.resolved_at} format=\"relative\" className=\"text-2xs text-text-tertiary shrink-0 whitespace-nowrap\" />}\n </button>\n );\n })}\n </div>\n {total > rows.length && (\n <p className=\"text-2xs text-text-quaternary mt-3\">Showing {rows.length} of {total}.</p>\n )}\n </div>\n );\n}\n\n\n\nfunction SectionLabel({ children }: { children: React.ReactNode }) {\n return (\n <p className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-3\">{children}</p>\n );\n}\n\n// ── facet-board — one card per entity (machine, station) ─────────────────────\n\ninterface BoardGroup {\n key: string;\n /** The group's identity as stored (native type preserved for the facet URL). */\n rawValue: unknown;\n latest: LTEscalationRecord;\n count: number;\n}\n\n/**\n * Group rows by the resolved x-lt-group-by value; each card renders from the\n * group's most recent row (by created_at). Rows without the facet are skipped —\n * the board reflects the scope, it doesn't invent entities.\n */\nexport function groupBoardRows(rows: LTEscalationRecord[], groupBy: string): BoardGroup[] {\n const dot = groupBy.indexOf('.');\n const facetKey = groupBy.startsWith('metadata.') ? groupBy.slice('metadata.'.length) : null;\n const groups = new Map<string, BoardGroup>();\n for (const row of rows) {\n const ctx = rowContext(row);\n let v: unknown;\n try {\n v = dot === -1\n ? (ctx as unknown as Record<string, unknown>)[groupBy]\n : getDeep((ctx as unknown as Record<string, unknown>)[groupBy.slice(0, dot)], groupBy.slice(dot + 1));\n } catch {\n v = undefined;\n }\n if (v === undefined || v === null || v === '') continue;\n const key = String(v);\n const rawValue = facetKey ? (row.metadata?.[facetKey] ?? v) : v;\n const existing = groups.get(key);\n if (!existing) {\n groups.set(key, { key, rawValue, latest: row, count: 1 });\n } else {\n existing.count += 1;\n if (new Date(row.created_at) > new Date(existing.latest.created_at)) existing.latest = row;\n }\n }\n return [...groups.values()].sort((a, b) => a.key.localeCompare(b.key));\n}\n\n\nfunction FacetBoard({ schema, rows, role, onOpenDetail, onOpenGroup, onAddFacet, forceView }: {\n schema: ListSchema;\n rows: LTEscalationRecord[];\n role: string;\n forceView?: boolean;\n /** Plain card click — the group's latest row opens in the detail view. */\n onOpenDetail?: (row: LTEscalationRecord) => void;\n /** History affordances — receive a filtered table/timeline deep link. */\n onOpenGroup?: (url: string) => void;\n /** Shift+click — merge one facet into the live filter set (additive). */\n onAddFacet?: (key: string, value: unknown) => void;\n}) {\n const navigate = useNavigate();\n const groupBy = schema['x-lt-group-by'];\n const card = schema['x-lt-card'] ?? {};\n const rowAction = schema['x-lt-row-action'];\n const [refineGroup, setRefineGroup] = useState<BoardGroup | null>(null);\n\n if (!groupBy) {\n return <p className=\"text-xs text-text-tertiary italic\">facet-board needs an x-lt-group-by path.</p>;\n }\n const facetKey = groupBy.startsWith('metadata.') ? groupBy.slice('metadata.'.length) : null;\n const groups = groupBoardRows(rows, groupBy);\n if (groups.length === 0) {\n return <p className=\"text-xs text-text-tertiary italic\">No entities in scope.</p>;\n }\n\n // The card's refinable facts: the entity identity (the group-by facet)\n // plus every metadata-bound card field — one dialog per card, replacing\n // hover-revealed per-field icons (hover-only fails the iPad floor).\n const groupRefinePairs = (g: BoardGroup): RefinePair[] => {\n const pairs: RefinePair[] = [];\n if (facetKey) pairs.push({ key: facetKey, label: facetKey, value: g.rawValue });\n const seen = new Set(pairs.map((p) => p.key));\n for (const f of card.fields ?? []) {\n const bound = f.value.match(METADATA_TOKEN)?.[1];\n if (!bound || seen.has(bound)) continue;\n const raw = g.latest.metadata?.[bound];\n if (raw === undefined || raw === null || raw === '') continue;\n seen.add(bound);\n pairs.push({ key: bound, label: f.label, value: raw });\n }\n return pairs;\n };\n\n return (\n <div className=\"grid grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] gap-4\" data-testid=\"facet-board\">\n {groups.map((g) => {\n const ctx = rowContext(g.latest);\n const title = card.title ? interpolateHelp(card.title, ctx) : g.key;\n const state = card.state ? interpolateHelp(card.state, ctx) : (g.latest.subtype || g.latest.status);\n const stateHue = typeColor(state);\n const refinable = groupRefinePairs(g).length > 0;\n\n const activate = (e: { shiftKey: boolean }) => {\n if (e.shiftKey && facetKey && onAddFacet) {\n onAddFacet(facetKey, g.rawValue);\n return;\n }\n onOpenDetail?.(g.latest);\n };\n\n return (\n <div\n key={g.key}\n role=\"button\"\n tabIndex={0}\n onClick={activate}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); activate(e); }\n }}\n title={facetKey ? 'Open the latest item · ⇧ click to filter the board' : 'Open the latest item'}\n className=\"group/card border-l-2 border-accent/30 bg-surface-sunken/40 rounded-[0.125em] px-4 py-3.5 cursor-pointer transition-colors hover:bg-surface-sunken/70 focus:outline-none focus-visible:ring-1 focus-visible:ring-accent/40\"\n data-testid=\"facet-board-card\"\n >\n <div className=\"flex items-center justify-between gap-2 mb-2.5\">\n <span className=\"text-2xs font-semibold uppercase tracking-wider text-text-secondary truncate\">\n {title}\n </span>\n <span className=\"flex items-center gap-1 shrink-0\">\n <span\n className=\"px-1.5 py-0.5 rounded text-2xs font-mono font-medium\"\n style={{ color: stateHue.text, backgroundColor: stateHue.bg }}\n title={state}\n >\n {state}\n </span>\n {refinable && <RefineTrigger onOpen={() => setRefineGroup(g)} className=\"-my-1 -mr-1\" />}\n </span>\n </div>\n {card.fields && card.fields.length > 0 && (\n <dl className=\"space-y-1\">\n {card.fields.map((f, i) => {\n const text = interpolateHelp(f.value, ctx);\n return (\n <div key={i} className=\"flex items-baseline justify-between gap-3\">\n <dt className=\"text-2xs uppercase tracking-wider text-text-quaternary shrink-0\">{f.label}</dt>\n <dd\n className=\"min-w-0 truncate text-2xs text-text-primary\"\n title={text && text !== EM_DASH ? text : undefined}\n >\n <FieldValue raw={text} format={f.format} />\n </dd>\n </div>\n );\n })}\n </dl>\n )}\n\n <div className=\"mt-3 flex justify-end\">\n <RowActionButton row={g.latest} def={rowAction} onView={() => onOpenDetail?.(g.latest)} forceView={forceView} />\n </div>\n </div>\n );\n })}\n\n <RefineDialog\n open={!!refineGroup}\n onClose={() => setRefineGroup(null)}\n role={role}\n pairs={refineGroup ? groupRefinePairs(refineGroup) : []}\n onNavigate={onOpenGroup ?? navigate}\n onAddFacet={onAddFacet}\n />\n </div>\n );\n}\n\nexport function EscalationListView({ role, listSchema, listSchemaVersion, activeEscalations, groups, onRowClick, onOpenGroup, onAddFacet, forceViewAction, total, page, totalPages, pageSize, onPageChange, onPageSizeChange }: {\n role: string;\n listSchema: ListSchema;\n /** The list schema version rendered; related sets read the same version. */\n listSchemaVersion?: number | null;\n activeEscalations: LTEscalationRecord[];\n /** facet-table grouped reads: the page's groups, in order. */\n groups?: EscalationGroup[] | null;\n onRowClick?: (row: LTEscalationRecord) => void;\n /** facet-board history affordances — receive a filtered deep link. */\n onOpenGroup?: (url: string) => void;\n /** facet-board ⇧ click — merge one facet into the live filter set. */\n onAddFacet?: (key: string, value: unknown) => void;\n /** Render claim row-actions as view actions. For surfaces listing rows the\n * viewer already holds (e.g. My Escalations), where a claim gesture is\n * inapplicable — the button opens the detail page instead. */\n forceViewAction?: boolean;\n total?: number;\n page?: number;\n totalPages?: number;\n pageSize?: number;\n onPageChange?: (page: number) => void;\n onPageSizeChange?: (size: number) => void;\n}) {\n const layout = listSchema['x-lt-layout'];\n const card = listSchema['x-lt-active'] ?? {};\n const rowAction = listSchema['x-lt-row-action'];\n const active = activeEscalations[0];\n const help = listSchema['x-lt-help'];\n useAgeTick(schemaUsesAge(listSchema));\n\n // The active item is a distinct surface on the page wash — the same card\n // treatment the detail page gives its form sections. The label heads the\n // card; the history column beside it stays a quiet chronicle on the wash.\n const activeBlock = (\n <div className=\"border border-surface-border/60 bg-surface-sunken rounded-[0.25em] p-4\">\n <SectionLabel>Active</SectionLabel>\n {active ? (\n <ActiveCard esc={active} card={card} rowAction={rowAction} onOpen={() => onRowClick?.(active)} forceView={forceViewAction} />\n ) : (\n <p className=\"text-xs text-text-tertiary italic\">No active item right now.</p>\n )}\n </div>\n );\n\n const header = help && active ? (\n <div className=\"mb-8\"><MarkdownRenderer content={interpolateHelp(help, rowContext(active))} /></div>\n ) : help ? (\n <div className=\"mb-8\"><MarkdownRenderer content={help} /></div>\n ) : null;\n\n if (layout === 'facet-table') {\n // The table stands alone — no header text above it. Instructions belong\n // in the form's help surfaces; totals live in the pagination bar.\n const resolvedTotal = total ?? activeEscalations.length;\n return (\n <div>\n <FacetTable schema={listSchema as Record<string, unknown>} rows={activeEscalations} groups={groups} role={role} version={listSchemaVersion} onRowClick={onRowClick} onAddFacet={onAddFacet} forceView={forceViewAction} />\n {page !== undefined && totalPages !== undefined && onPageChange && (\n <StickyPagination\n page={page}\n totalPages={totalPages}\n onPageChange={onPageChange}\n total={resolvedTotal}\n pageSize={pageSize ?? 25}\n onPageSizeChange={onPageSizeChange}\n />\n )}\n </div>\n );\n }\n\n if (layout === 'facet-board') {\n return (\n <div>\n {header}\n <FacetBoard\n schema={listSchema}\n rows={activeEscalations}\n role={role}\n onOpenDetail={onRowClick}\n onOpenGroup={onOpenGroup}\n onAddFacet={onAddFacet}\n forceView={forceViewAction}\n />\n {page !== undefined && totalPages !== undefined && onPageChange && totalPages > 1 && (\n <StickyPagination\n page={page}\n totalPages={totalPages}\n onPageChange={onPageChange}\n total={total ?? activeEscalations.length}\n pageSize={pageSize ?? 25}\n onPageSizeChange={onPageSizeChange}\n />\n )}\n </div>\n );\n }\n\n if (layout === 'active-history') {\n return (\n <div>\n {header}\n <div className=\"grid grid-cols-1 @split:grid-cols-[1.6fr_1fr] gap-8 @split:gap-12 items-start\">\n {activeBlock}\n {/* pt-4 seats the History label on the Active label's optical line\n (the card's own padding provides that inset on the left). */}\n <div className=\"@split:pt-4\">\n <SectionLabel>History</SectionLabel>\n <HistoryColumn role={role} def={listSchema['x-lt-history'] ?? {}} onRowClick={onRowClick} />\n </div>\n </div>\n </div>\n );\n }\n\n // \"active\" (or any non-table layout): just the active card.\n return (\n <div>\n {header}\n {activeBlock}\n </div>\n );\n}\n","import { useState } from 'react';\nimport { Link } from 'react-router-dom';\nimport { Circle, Bell, Clock, ListFilter, Search, History } from 'lucide-react';\nimport { EntityTimelinePanel } from '../../components/escalation/EntityTimelinePanel';\nimport { useShellPanelOptional } from '../../hooks/useShellPanel';\nimport type { Column } from '../../components/common/data/DataTable';\nimport { FilterBar, FilterSelect, FilterInput, FilterDivider } from '../../components/common/data/FilterBar';\nimport { PriorityBadge } from '../../components/common/display/PriorityBadge';\nimport { RolePill } from '../../components/common/display/RolePill';\nimport { WorkflowPill } from '../../components/common/display/WorkflowPill';\nimport { UserName } from '../../components/common/display/UserName';\nimport { CountdownTimer } from '../../components/common/display/CountdownTimer';\nimport { formatAgoCompact } from '../../lib/format';\nimport { isEffectivelyClaimed, isAckEscalation } from '../../lib/escalation';\nimport { metadataFacetUrl } from '../../lib/facet-url';\nimport type { LTEscalationRecord } from '../../api/types';\n\nexport interface EscalationColumnOpts {\n highlightKeys?: string[];\n}\n\n// Shared cell text: a consistent resting shade for every cell, sharpening to\n// the primary text colour when the row is hovered. Cells (and pills via their\n// `inherit` tone) all read this single source so the whole row darkens as one.\nconst CELL_TEXT = 'text-text-secondary transition-colors group-hover/row:text-text-primary';\n\n/** Status dot — rendered inline before summary. */\nfunction StatusDot({ row }: { row: LTEscalationRecord }) {\n if (isAckEscalation(row)) {\n const color = row.status === 'resolved' ? 'text-status-success' : 'text-text-tertiary';\n return <Bell className={`w-3 h-3 shrink-0 ${color}`} />;\n }\n if (row.status === 'resolved') {\n return <Circle className=\"w-2.5 h-2.5 shrink-0 text-status-success\" strokeWidth={2.5} />;\n }\n if (row.status === 'cancelled') {\n return <Circle className=\"w-2.5 h-2.5 shrink-0 text-status-error\" strokeWidth={2.5} />;\n }\n if (row.status === 'expired') {\n return <Circle className=\"w-2.5 h-2.5 shrink-0 text-text-tertiary\" strokeWidth={2.5} />;\n }\n if (isEffectivelyClaimed(row)) {\n return <Circle className=\"w-2.5 h-2.5 shrink-0 text-status-warning\" strokeWidth={2.5} />;\n }\n // pending (unclaimed)\n return <Circle className=\"w-2.5 h-2.5 shrink-0 text-status-active\" strokeWidth={2.5} />;\n}\n\n/** Key/value metadata dict with 1 row collapsed by default, expand for the rest. */\nexport function MetadataCell({\n metadata,\n role,\n highlightKeys,\n}: {\n metadata: Record<string, unknown> | null;\n role: string;\n highlightKeys?: string[];\n}) {\n const [expanded, setExpanded] = useState(false);\n // Null outside the shell (tests, standalone renders) — the timeline\n // affordance simply doesn't render there.\n const shell = useShellPanelOptional();\n\n if (!metadata || Object.keys(metadata).length === 0) {\n return <span className=\"text-2xs text-text-tertiary\">—</span>;\n }\n\n const hl = highlightKeys ?? [];\n // Highlighted keys first, then the rest in insertion order.\n const allKeys = [\n ...hl.filter((k) => k in metadata),\n ...Object.keys(metadata).filter((k) => !hl.includes(k)),\n ];\n\n const shown = expanded ? allKeys : allKeys.slice(0, 1);\n const hiddenCount = allKeys.length - 1;\n\n return (\n <div className=\"w-full\" onClick={(e) => e.stopPropagation()}>\n <div className=\"space-y-px\">\n {shown.map((k, i) => {\n const sv = typeof metadata[k] === 'object' && metadata[k] !== null\n ? JSON.stringify(metadata[k])\n : String(metadata[k]);\n const isHl = hl.includes(k);\n const isLastShown = i === shown.length - 1;\n return (\n <div key={k} className=\"group/mrow flex items-center gap-1 min-w-0\">\n <span\n className={`shrink-0 w-14 text-2xs font-mono uppercase tracking-wide truncate ${isHl ? 'text-accent' : 'text-text-tertiary'}`}\n title={k}\n >\n {k}\n </span>\n <span\n className={`flex-1 min-w-0 text-2xs font-medium truncate ${isHl ? 'text-text-primary' : 'text-text-secondary'}`}\n title={sv}\n >\n {sv}\n </span>\n <span className=\"flex items-center gap-px shrink-0 opacity-50 group-hover/mrow:opacity-100 transition-opacity\">\n <Link\n to={metadataFacetUrl(k, metadata[k], role)}\n className=\"p-0.5 rounded text-text-quaternary hover:text-accent transition-colors\"\n title={`Filter ${role}: ${k} = ${sv}`}\n onClick={(ev) => ev.stopPropagation()}\n >\n <ListFilter className=\"w-3 h-3\" />\n </Link>\n <Link\n to={metadataFacetUrl(k, metadata[k])}\n className=\"p-0.5 rounded text-text-quaternary hover:text-accent transition-colors\"\n title={`Search all: ${k} = ${sv}`}\n onClick={(ev) => ev.stopPropagation()}\n >\n <Search className=\"w-3 h-3\" />\n </Link>\n {/* filter-present / search-present / history-past — the third\n verb of the triad. String values only: the timeline's GIN\n containment match only serves JSON-string facets. */}\n {shell && typeof metadata[k] === 'string' && (\n <button\n className=\"p-0.5 rounded text-text-quaternary hover:text-accent transition-colors\"\n title={`Timeline: every station ${sv} has moved through`}\n onClick={(ev) => {\n ev.stopPropagation();\n shell.setPanel(\n <EntityTimelinePanel facetKey={k} value={metadata[k] as string} role={role} />,\n { key: 'entity-timeline', width: 420 },\n );\n }}\n >\n <History className=\"w-3 h-3\" />\n </button>\n )}\n </span>\n {/* +N inline at end of single visible row when collapsed */}\n {!expanded && hiddenCount > 0 && (\n <button\n onClick={(ev) => { ev.stopPropagation(); setExpanded(true); }}\n className=\"shrink-0 text-2xs text-text-quaternary hover:text-accent transition-colors font-mono\"\n title={`Show ${hiddenCount} more fields`}\n >\n +{hiddenCount}\n </button>\n )}\n {/* ↑ inline at end of last row when expanded */}\n {expanded && isLastShown && hiddenCount > 0 && (\n <button\n onClick={(ev) => { ev.stopPropagation(); setExpanded(false); }}\n className=\"shrink-0 text-2xs text-text-quaternary hover:text-accent transition-colors\"\n title=\"Show less\"\n >\n ↑\n </button>\n )}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\n/** Build the shared column set, optionally wiring metadata filter callbacks. */\nexport function makeEscalationColumns(opts: EscalationColumnOpts = {}): Column<LTEscalationRecord>[] {\n return [\n {\n key: 'description',\n label: 'Summary',\n priority: 1,\n render: (row) => (\n <div className=\"flex items-center gap-2 overflow-hidden\">\n <span className=\"shrink-0\"><StatusDot row={row} /></span>\n <span className={`truncate text-xs ${CELL_TEXT}`}>{row.description || row.type}</span>\n </div>\n ),\n className: 'max-w-0',\n },\n // The manufacturing-floor column budget: identity, owner, urgency, age.\n // Everything else (workflow type, metadata, exact timestamps) lives in\n // the facet drawer and the detail page — never as a scrolling column.\n {\n key: 'assigned_to',\n label: 'Assignee',\n priority: 2,\n render: (row) => (row.assigned_to\n ? <UserName userId={row.assigned_to} className={`block truncate text-xs ${CELL_TEXT}`} />\n : <span className=\"text-xs text-text-quaternary\">—</span>),\n className: 'w-36 max-w-[9rem]',\n },\n {\n key: 'role',\n label: 'Role',\n priority: 2,\n render: (row) => (\n <span className={CELL_TEXT}>\n <RolePill role={row.role} size=\"md\" tone=\"inherit\" />\n </span>\n ),\n className: 'w-44 min-w-[11rem]',\n },\n {\n key: 'priority',\n label: 'Pri',\n priority: 2,\n render: (row) => (\n <span className={CELL_TEXT}>\n <PriorityBadge priority={row.priority} size=\"sm\" tone=\"inherit\" />\n </span>\n ),\n className: 'w-10',\n },\n // Enrichment columns — the jumping-off facets. The budget governs the\n // floor: these return only when the table has room (@split / @wall),\n // and in card mode they fold to pairs. The metadata cell carries the\n // clickable refine icons: filter within the role, search across roles\n // (admins), shift+click to AND facets.\n {\n key: 'workflow_type',\n label: 'Workflow',\n priority: 2,\n showFrom: 'split',\n render: (row) => <WorkflowPill type={row.workflow_type || row.type} />,\n className: 'w-40 whitespace-nowrap',\n },\n {\n key: 'metadata',\n label: 'Metadata',\n priority: 2,\n showFrom: 'wall',\n render: (row) => (\n <MetadataCell\n metadata={row.metadata}\n role={row.role}\n highlightKeys={opts.highlightKeys}\n />\n ),\n className: 'w-80 max-w-[19rem] align-top',\n },\n {\n key: 'created_at',\n label: 'Ago',\n priority: 1,\n render: (row) => (\n <span className={`text-xs tabular-nums ${CELL_TEXT}`} title={row.created_at}>\n {formatAgoCompact(row.created_at)}\n </span>\n ),\n className: 'w-14 whitespace-nowrap',\n },\n ];\n}\n\n/** Base columns shared by all escalation list pages (no filter callback). */\nexport const ESCALATION_COLUMNS: Column<LTEscalationRecord>[] = makeEscalationColumns();\n\n/** Time-remaining column for claimed escalations — aligns with checkbox column on All Escalations. */\nexport const TIME_LEFT_COLUMN: Column<LTEscalationRecord> = {\n key: 'expires',\n label: (<Clock className=\"w-3.5 h-3.5 text-text-tertiary\" />) as any,\n render: (row) =>\n row.assigned_until ? (\n <CountdownTimer until={row.assigned_until} />\n ) : (\n <span className=\"text-xs text-text-tertiary\">—</span>\n ),\n className: 'w-16 whitespace-nowrap',\n priority: 1,\n};\n\n/** Status icon column — color-coded filled circle, or bell for ACK/notification escalations. */\nexport const STATUS_COLUMN: Column<LTEscalationRecord> = {\n key: 'status',\n label: '',\n render: (row) => {\n if (isAckEscalation(row)) {\n const color = row.status === 'resolved' ? 'text-status-success' : 'text-text-tertiary';\n return <Bell className={`w-3 h-3 ${color}`} />;\n }\n if (row.status === 'resolved') {\n return <Circle className=\"w-2.5 h-2.5 text-status-success\" strokeWidth={2.5} />;\n }\n if (isEffectivelyClaimed(row)) {\n return <Circle className=\"w-2.5 h-2.5 text-status-warning\" strokeWidth={2.5} />;\n }\n // pending (unclaimed)\n return <Circle className=\"w-2.5 h-2.5 text-text-tertiary\" strokeWidth={2.5} />;\n },\n className: 'w-8',\n priority: 1,\n};\n\n/** Claimed-only status icon (always orange, or bell for ACK). */\nexport const CLAIMED_STATUS_COLUMN: Column<LTEscalationRecord> = {\n key: 'status',\n label: '',\n render: (row) =>\n isAckEscalation(row)\n ? <Bell className=\"w-3 h-3 text-status-warning\" />\n : <Circle className=\"w-2.5 h-2.5 text-status-warning\" strokeWidth={2.5} />,\n className: 'w-8',\n priority: 1,\n};\n\n/** Priority filter options shared by both pages. */\nexport const PRIORITY_OPTIONS = [\n { value: '1', label: 'P1' },\n { value: '2', label: 'P2' },\n { value: '3', label: 'P3' },\n { value: '4', label: 'P4' },\n];\n\n/** Status filter options for escalation list pages. `all` spans every status so a\n * metadata search (e.g. one order id) returns its escalations regardless of status. */\nexport const STATUS_OPTIONS = [\n { value: 'all', label: 'All' },\n { value: 'available', label: 'Available' },\n { value: 'claimed', label: 'Claimed' },\n { value: 'resolved', label: 'Resolved' },\n { value: 'cancelled', label: 'Cancelled' },\n { value: 'expired', label: 'Expired' },\n];\n\n/** Shared filter bar for escalation list pages. */\nexport function EscalationFilterBar({\n filters,\n setFilter,\n roles,\n types,\n showStatus = false,\n showSearch = true,\n showRole = true,\n actions,\n}: {\n filters: { role: string; type: string; priority: string; status?: string; search?: string };\n setFilter: (key: any, value: string) => void;\n roles: string[];\n types: string[];\n showStatus?: boolean;\n // Free-text search lives here by default, but the faceted page folds it into\n // the drawer instead so there's a single search surface.\n showSearch?: boolean;\n /** Kiosk sessions hide the role filter — the session IS the role. */\n showRole?: boolean;\n actions?: React.ReactNode;\n}) {\n // Non-default filters power the folded Filters button's badge.\n const activeFilterCount = [\n filters.role,\n filters.type,\n filters.priority,\n filters.status && filters.status !== 'all' ? filters.status : '',\n filters.search ?? '',\n ].filter(Boolean).length;\n\n return (\n <FilterBar actions={actions} activeFilterCount={activeFilterCount}>\n {showStatus && (\n <>\n <FilterSelect\n label=\"Status\"\n value={filters.status ?? ''}\n onChange={(v) => setFilter('status', v)}\n options={STATUS_OPTIONS}\n />\n <FilterDivider />\n </>\n )}\n {/* Role is the queue's primary facet — URL-driven (?role=). Pages whose\n title doubles as a queue selector share the same param, so the two\n controls mirror each other. Kiosk sessions hide it: the session IS\n the role. */}\n {showRole && (\n <>\n <FilterSelect\n label=\"Role\"\n value={filters.role}\n onChange={(v) => setFilter('role', v)}\n options={roles.map((r) => ({ value: r, label: r }))}\n />\n <FilterDivider />\n </>\n )}\n <FilterSelect\n label=\"Priority\"\n value={filters.priority}\n onChange={(v) => setFilter('priority', v)}\n options={PRIORITY_OPTIONS}\n />\n <FilterDivider />\n <FilterSelect\n label=\"Workflow Type\"\n value={filters.type}\n onChange={(v) => setFilter('type', v)}\n options={types.map((t) => ({ value: t, label: t }))}\n />\n {showSearch && (\n <>\n <FilterDivider />\n <FilterInput\n label=\"Search\"\n value={filters.search ?? ''}\n onChange={(v) => setFilter('search', v)}\n placeholder=\"ID, workflow, origin…\"\n />\n </>\n )}\n </FilterBar>\n );\n}\n"],"names":["PALETTE","hash","str","h","i","typeColor","typeName","FIND_THRESHOLD","RefineDialog","open","onClose","role","pairs","onNavigate","onAddFacet","selected","setSelected","useState","find","setFind","prevOpen","setPrevOpen","bound","p","preset","needle","visible","t","toggle","key","prev","next","chosen","facets","none","go","url","jsx","Modal","jsxs","Search","e","on","Check","metadataFacetsUrl","useRelatedAggregates","ids","version","enabled","sorted","useQuery","apiFetch","useRelatedRows","id","set","limit","SINGLE_TOKEN","ANY_TOKEN","MISSING_VALUE","parseJsonObject","value","parsed","rowTemplateContext","row","readToken","path","ctx","dot","domain","HELP_DOMAINS","root","getDeep","resolveTemplateValue","single","raw","text","interpolateHelp","resolveRelatedFacets","narrow","out","resolved","splitLabel","col","_a","SPLIT_PATHS","_b","RelatedCell","agg","drillUrl","EM_DASH","isExtremeAggregate","FormattedValue","countText","relatedCountText","order","splits","n","a","x","b","y","restricted","title","r","href","chip","Link","ROLE_FORMAT","cellText","template","rowContext","interpolateItemTemplate","DetailSection","host","section","roleLabels","navigate","useNavigate","query","rows","labels","_c","hostValues","v","columns","values","displayRoleTitle","target","DataTable","RowDetail","sections","withOpenMembers","members","m","buildTableRows","groups","byId","g","numeric","nums","foldColumnText","fold","GROUP_FOLDS","mergeAggregates","aggs","aggregate","present","k","foldExtreme","distinctByMatch","seen","match","safeRelations","schema","readListSchemaRelations","RelatedFacetTable","props","related","sets","useRelatedSetEvents","FacetTableBody","FacetTable","relations","useMemo","onRowClick","forceView","setsLoading","columnDefs","rowAction","refineRow","setRefineRow","setOpen","tableRows","lines","grouped","expandable","opens","relatedCell","name","counted","relatedAggregateKey","relatedRole","actionLabel","lead","ChevronRight","escalationDotClass","c","IDENTITY_COLUMN_WIDTH","indent","rowRefinePairs","RefineTrigger","actionColumnWidth","RowActionButton","rowClassName","renderExpansion","Fragment","useAgeTick","setTick","useEffect","schemaUsesAge","f","isAgeFormat","ActiveCard","esc","card","onOpen","FieldValue","MarkdownRenderer","HistoryColumn","def","show","setShow","useEscalations","schemaNeedsEnvelope","total","rowDef","DateValue","SectionLabel","children","groupBoardRows","groupBy","facetKey","rawValue","existing","FacetBoard","onOpenDetail","onOpenGroup","refineGroup","setRefineGroup","groupRefinePairs","METADATA_TOKEN","state","stateHue","refinable","activate","EscalationListView","listSchema","listSchemaVersion","activeEscalations","forceViewAction","page","totalPages","pageSize","onPageChange","onPageSizeChange","layout","active","help","activeBlock","header","resolvedTotal","StickyPagination","CELL_TEXT","StatusDot","isAckEscalation","color","Bell","Circle","isEffectivelyClaimed","MetadataCell","metadata","highlightKeys","expanded","setExpanded","shell","useShellPanelOptional","hl","allKeys","shown","hiddenCount","sv","isHl","isLastShown","metadataFacetUrl","ev","ListFilter","EntityTimelinePanel","History","makeEscalationColumns","opts","UserName","RolePill","PriorityBadge","WorkflowPill","formatAgoCompact","ESCALATION_COLUMNS","TIME_LEFT_COLUMN","Clock","CountdownTimer","PRIORITY_OPTIONS","STATUS_OPTIONS","EscalationFilterBar","filters","setFilter","roles","types","showStatus","showSearch","showRole","actions","activeFilterCount","FilterBar","FilterSelect","FilterDivider","FilterInput"],"mappings":"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"}
1
+ {"version":3,"file":"escalation-columns-CFoFILF1.js","sources":["../../src/lib/type-color.ts","../../src/components/escalation/RefineDialog.tsx","../../src/api/escalation-related.ts","../../../shared/list-schema/template.ts","../../src/components/escalation/list-view/RelatedCell.tsx","../../src/components/escalation/list-view/RowDetail.tsx","../../src/components/escalation/list-view/group-rows.ts","../../src/components/escalation/list-view/FacetTable.tsx","../../src/components/escalation/EscalationListView.tsx","../../src/pages/operator/escalation-columns.tsx"],"sourcesContent":["/**\n * Deterministic color assignment for workflow type names.\n *\n * Maps any string to a consistent color from a curated 24-color palette.\n * The same type name always produces the same color across the entire UI.\n * Uses a simple hash to distribute names evenly across the palette.\n *\n * Each entry provides:\n * text — icon and text color (Tailwind class)\n * bg — subtle background tint (Tailwind class)\n */\n\nconst PALETTE: Array<{ text: string; bg: string }> = [\n { text: 'text-rose-400', bg: 'bg-rose-400/[0.08]' },\n { text: 'text-pink-400', bg: 'bg-pink-400/[0.08]' },\n { text: 'text-fuchsia-400', bg: 'bg-fuchsia-400/[0.08]' },\n { text: 'text-purple-400', bg: 'bg-purple-400/[0.08]' },\n { text: 'text-violet-400', bg: 'bg-violet-400/[0.08]' },\n { text: 'text-indigo-400', bg: 'bg-indigo-400/[0.08]' },\n { text: 'text-blue-400', bg: 'bg-blue-400/[0.08]' },\n { text: 'text-sky-400', bg: 'bg-sky-400/[0.08]' },\n { text: 'text-cyan-400', bg: 'bg-cyan-400/[0.08]' },\n { text: 'text-teal-400', bg: 'bg-teal-400/[0.08]' },\n { text: 'text-emerald-400', bg: 'bg-emerald-400/[0.08]' },\n { text: 'text-green-400', bg: 'bg-green-400/[0.08]' },\n { text: 'text-lime-400', bg: 'bg-lime-400/[0.08]' },\n { text: 'text-yellow-400', bg: 'bg-yellow-400/[0.08]' },\n { text: 'text-amber-400', bg: 'bg-amber-400/[0.08]' },\n { text: 'text-orange-400', bg: 'bg-orange-400/[0.08]' },\n { text: 'text-red-400', bg: 'bg-red-400/[0.08]' },\n { text: 'text-stone-400', bg: 'bg-stone-400/[0.08]' },\n { text: 'text-rose-300', bg: 'bg-rose-300/[0.08]' },\n { text: 'text-violet-300', bg: 'bg-violet-300/[0.08]' },\n { text: 'text-sky-300', bg: 'bg-sky-300/[0.08]' },\n { text: 'text-teal-300', bg: 'bg-teal-300/[0.08]' },\n { text: 'text-amber-300', bg: 'bg-amber-300/[0.08]' },\n { text: 'text-pink-300', bg: 'bg-pink-300/[0.08]' },\n];\n\nfunction hash(str: string): number {\n let h = 0;\n for (let i = 0; i < str.length; i++) {\n h = ((h << 5) - h + str.charCodeAt(i)) | 0;\n }\n return Math.abs(h);\n}\n\nexport function typeColor(typeName: string): { text: string; bg: string } {\n return PALETTE[hash(typeName) % PALETTE.length];\n}\n","import { useState } from 'react';\nimport { Check, Search } from 'lucide-react';\nimport { Modal } from '../common/modal/Modal';\nimport { metadataFacetsUrl } from '../../lib/facet-url';\n\n/** One refinable fact from a row: a metadata key with its authored label and value. */\nexport interface RefinePair {\n key: string;\n label: string;\n value: unknown;\n /** The author put this fact in the row's columns; a lone bound fact arrives preselected. */\n bound?: boolean;\n}\n\n/**\n * The row-level refine gesture for authored lists (facet-table rows, board\n * cards): the row's metadata-bound facts as full-width touch rows, each a\n * toggle. Pick one or several (multi-select ANDs the facets) and drill —\n * filter this role's queue, search every role, or merge into the live filter\n * set. One dialog replaces per-cell icon pairs, so table cells spend their\n * width on data and the affordance stays tappable on the iPad floor. The\n * list is the row's whole metadata; past a handful of facts a find box\n * narrows it by label, key, or value.\n */\nconst FIND_THRESHOLD = 6;\nexport function RefineDialog({ open, onClose, role, pairs, onNavigate, onAddFacet }: {\n open: boolean;\n onClose: () => void;\n role: string;\n pairs: RefinePair[];\n /** Receives the facet deep-link. Hosts navigate (or open a panel). */\n onNavigate: (url: string) => void;\n /** When provided, \"Add to filters\" merges the selection into the live set. */\n onAddFacet?: (key: string, value: unknown) => void;\n}) {\n // A single fact, or a single column-bound fact, arrives selected — the\n // one-glance, two-tap path — while the rest of the record waits below.\n const [selected, setSelected] = useState<Set<string>>(new Set());\n const [find, setFind] = useState('');\n const [prevOpen, setPrevOpen] = useState(open);\n if (open !== prevOpen) {\n setPrevOpen(open);\n if (open) {\n const bound = pairs.filter((p) => p.bound);\n const preset = bound.length === 1 ? [bound[0].key] : pairs.length === 1 ? [pairs[0].key] : [];\n setSelected(new Set(preset));\n setFind('');\n }\n }\n const needle = find.trim().toLowerCase();\n const visible = needle\n ? pairs.filter((p) => [p.label, p.key, String(p.value)].some((t) => t.toLowerCase().includes(needle)))\n : pairs;\n\n const toggle = (key: string) => {\n setSelected((prev) => {\n const next = new Set(prev);\n if (next.has(key)) next.delete(key); else next.add(key);\n return next;\n });\n };\n\n const chosen = pairs.filter((p) => selected.has(p.key));\n const facets = Object.fromEntries(chosen.map((p) => [p.key, p.value]));\n const none = chosen.length === 0;\n\n const go = (url: string) => {\n onClose();\n onNavigate(url);\n };\n\n return (\n <Modal open={open} onClose={onClose} title=\"Refine\">\n <div className=\"space-y-4\">\n <p className=\"text-2xs text-text-tertiary\">\n Pick the facts to match — several combine into one narrower query.\n </p>\n\n {pairs.length > FIND_THRESHOLD && (\n <label className=\"flex items-center gap-2 input text-xs py-1.5\">\n <Search className=\"w-3.5 h-3.5 shrink-0 text-text-quaternary\" strokeWidth={1.5} />\n <input\n type=\"text\"\n value={find}\n onChange={(e) => setFind(e.target.value)}\n placeholder=\"Find a fact…\"\n className=\"flex-1 min-w-0 bg-transparent outline-none placeholder:text-text-quaternary\"\n aria-label=\"Find a fact\"\n data-testid=\"refine-find\"\n />\n <span className=\"text-2xs tabular-nums text-text-quaternary\">{visible.length}/{pairs.length}</span>\n </label>\n )}\n\n <div className=\"divide-y divide-surface-border/40 -mx-1 max-h-[50vh] overflow-y-auto\">\n {visible.map((p) => {\n const on = selected.has(p.key);\n return (\n <button\n key={p.key}\n type=\"button\"\n onClick={() => toggle(p.key)}\n aria-pressed={on}\n className=\"w-full flex items-center gap-3 px-1 py-2.5 text-left group min-w-0\"\n data-testid=\"refine-pair\"\n >\n <span\n className={`w-4 h-4 rounded-[3px] border flex items-center justify-center shrink-0 transition-colors ${\n on ? 'bg-accent border-accent' : 'border-surface-border group-hover:border-accent/50'\n }`}\n aria-hidden\n >\n {on && <Check className=\"w-3 h-3 text-text-inverse\" strokeWidth={3} />}\n </span>\n <span className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary w-28 shrink-0 truncate\" title={p.key}>\n {p.label}\n </span>\n <span className=\"text-xs text-text-primary truncate flex-1 min-w-0\" title={String(p.value)}>\n {String(p.value)}\n </span>\n </button>\n );\n })}\n </div>\n\n <div className=\"flex items-center justify-end gap-3 pt-2 flex-wrap\">\n {onAddFacet && (\n <button\n onClick={() => {\n chosen.forEach((p) => onAddFacet(p.key, p.value));\n onClose();\n }}\n disabled={none}\n className=\"text-xs text-text-secondary hover:text-accent transition-colors disabled:opacity-40 disabled:cursor-not-allowed mr-auto\"\n data-testid=\"refine-add-filters\"\n >\n Add to filters\n </button>\n )}\n <button\n onClick={() => go(metadataFacetsUrl(facets))}\n disabled={none}\n className=\"btn-secondary text-xs disabled:opacity-40 disabled:cursor-not-allowed\"\n data-testid=\"refine-search-all\"\n >\n Search everywhere\n </button>\n <button\n onClick={() => go(metadataFacetsUrl(facets, role))}\n disabled={none}\n className=\"btn-primary text-xs disabled:opacity-40 disabled:cursor-not-allowed\"\n data-testid=\"refine-filter-role\"\n >\n Filter {role}\n </button>\n </div>\n </div>\n </Modal>\n );\n}\n","import { useQuery } from '@tanstack/react-query';\nimport { apiFetch } from './client';\nimport type { RelatedAggregatesResponse, RelatedRowsResponse } from '../lib/list-schema';\n\n/**\n * Every related set a role's list schema declares, aggregated for one page\n * of host rows. Keyed under `escalations`, so the list's live invalidation\n * refreshes it with the rows.\n */\nexport function useRelatedAggregates(role: string, ids: string[], version: number | null | undefined, enabled = true) {\n const sorted = [...ids].sort();\n return useQuery<RelatedAggregatesResponse>({\n queryKey: ['escalations', 'related', role, version ?? 'latest', sorted],\n queryFn: () =>\n apiFetch('/escalations/related', {\n method: 'POST',\n body: JSON.stringify({ role, ids: sorted, ...(version != null ? { version } : {}) }),\n }),\n enabled: enabled && !!role && sorted.length > 0,\n placeholderData: (prev) => prev,\n });\n}\n\n/** One host row's rows in one related set, loaded when its detail opens. */\nexport function useRelatedRows(\n role: string,\n id: string,\n set: string,\n version: number | null | undefined,\n limit?: number,\n enabled = true,\n) {\n return useQuery<RelatedRowsResponse>({\n queryKey: ['escalations', 'related-rows', role, version ?? 'latest', id, set, limit ?? null],\n queryFn: () =>\n apiFetch('/escalations/related/rows', {\n method: 'POST',\n body: JSON.stringify({ role, id, set, ...(version != null ? { version } : {}), ...(limit ? { limit } : {}) }),\n }),\n enabled: enabled && !!role && !!id && !!set,\n });\n}\n","import { getDeep } from '../form-validation/x-lt-bind';\nimport { HELP_DOMAINS, interpolateHelp, type HelpDomain, type HelpTokenContext } from '../form-validation/x-lt-help';\n\nconst SINGLE_TOKEN = /^\\{\\{\\s*([^{}]+?)\\s*\\}\\}$/;\nconst ANY_TOKEN = /\\{\\{\\s*[^{}]+?\\s*\\}\\}/;\nconst MISSING_VALUE = '—';\n\nfunction parseJsonObject(value: unknown): Record<string, unknown> | null {\n if (value && typeof value === 'object') return value as Record<string, unknown>;\n if (typeof value !== 'string' || !value) return null;\n try {\n const parsed = JSON.parse(value);\n return parsed && typeof parsed === 'object' ? parsed : null;\n } catch {\n return null;\n }\n}\n\n/** The template domains of one escalation row, JSON-string columns parsed. */\nexport function rowTemplateContext(row: Record<string, unknown>): HelpTokenContext {\n return {\n escalation: row,\n metadata: (row.metadata as Record<string, unknown> | null) ?? {},\n envelope: parseJsonObject(row.envelope) ?? {},\n payload: parseJsonObject(row.escalation_payload) ?? {},\n resolver: parseJsonObject(row.resolver_payload) ?? {},\n };\n}\n\nfunction readToken(path: string, ctx: HelpTokenContext): unknown {\n const dot = path.indexOf('.');\n const domain = (dot === -1 ? path : path.slice(0, dot)) as HelpDomain;\n if (!HELP_DOMAINS.includes(domain)) return undefined;\n const root = ctx[domain];\n if (dot === -1) return root ?? undefined;\n try {\n return getDeep(root, path.slice(dot + 1));\n } catch {\n return undefined;\n }\n}\n\n/**\n * Resolve one facet value. A lone `{{token}}` keeps the value's own JSON type\n * (a numeric facet matches a numeric facet); a mixed template interpolates to\n * a string; a literal passes through. Undefined when a token is missing.\n */\nexport function resolveTemplateValue(value: unknown, ctx: HelpTokenContext): unknown {\n if (typeof value !== 'string') return value;\n const single = value.match(SINGLE_TOKEN);\n if (single) {\n const raw = readToken(single[1], ctx);\n return raw === null || raw === '' ? undefined : raw;\n }\n if (!ANY_TOKEN.test(value)) return value;\n const text = interpolateHelp(value, ctx);\n return text.includes(MISSING_VALUE) ? undefined : text;\n}\n\n/**\n * Resolve a related query's match against a host row: every required facet\n * (null when any is missing), plus each `narrow` facet the row resolves.\n */\nexport function resolveRelatedFacets(\n facets: Record<string, unknown>,\n ctx: HelpTokenContext,\n narrow?: Record<string, unknown>,\n): Record<string, unknown> | null {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(facets)) {\n const resolved = resolveTemplateValue(value, ctx);\n if (resolved === undefined) return null;\n out[key] = resolved;\n }\n for (const [key, value] of Object.entries(narrow ?? {})) {\n const resolved = resolveTemplateValue(value, ctx);\n if (resolved !== undefined) out[key] = resolved;\n }\n return out;\n}\n","import { Link } from 'react-router-dom';\nimport { EM_DASH, FormattedValue } from '../../common/display/FormattedValue';\nimport {\n SPLIT_PATHS,\n isExtremeAggregate,\n relatedCountText,\n type RelatedColumnDecl,\n type RelatedHostAggregate,\n type RelatedSetResult,\n} from '../../../lib/list-schema';\n\n/** A split value's display text: the declared label, a role title, or the value. */\nexport function splitLabel(value: string, col: RelatedColumnDecl, set?: RelatedSetResult): string {\n if (col.labels?.[value]) return col.labels[value];\n if (col.splitBy === SPLIT_PATHS.ROLE && set?.roleLabels?.[value]) return set.roleLabels[value];\n return value === '' ? 'None' : value;\n}\n\n/**\n * A related column cell: the count (or its `display` text), then each split\n * value as a chip in declaration order (role order for a role split), largest\n * first otherwise. A min or max column shows its value. Splits the viewer\n * cannot read show as a muted note, never a wrong split.\n */\nexport function RelatedCell({ col, set, agg, drillUrl }: {\n col: RelatedColumnDecl;\n set?: RelatedSetResult;\n agg?: RelatedHostAggregate;\n /** Query role splits: where a chip leads (the role list with the host's facets). */\n drillUrl?: (role: string) => string | null;\n}) {\n if (!agg || agg.unresolved) return <span className=\"text-text-quaternary\">{EM_DASH}</span>;\n if (isExtremeAggregate(col.aggregate)) {\n if (agg.value === undefined) return <span className=\"text-text-quaternary\">{EM_DASH}</span>;\n return (\n <span className=\"tabular-nums text-text-primary\" data-testid=\"related-cell\">\n <FormattedValue raw={String(agg.value)} format={col.format} />\n </span>\n );\n }\n const countText = relatedCountText(col.display, agg.count);\n const order = col.splitBy === SPLIT_PATHS.ROLE && set?.roles ? set.roles : null;\n const splits = Object.entries(agg.splits ?? {})\n .filter(([, n]) => n > 0)\n .sort(([a, x], [b, y]) => (order ? order.indexOf(a) - order.indexOf(b) : y - x));\n const restricted = col.splitBy === SPLIT_PATHS.ROLE ? (set?.restricted ?? []) : [];\n const title = [\n countText !== null ? String(agg.count) : '',\n agg.hidden ? `${agg.hidden} not readable by you` : '',\n restricted.length ? `Not counted (outside your view): ${restricted.map((r) => set?.roleLabels?.[r] ?? r).join(', ')}` : '',\n ].filter(Boolean).join(' · ');\n\n return (\n <span className=\"inline-flex flex-wrap items-center gap-1 min-w-0\" title={title || undefined} data-testid=\"related-cell\">\n <span className=\"tabular-nums font-medium text-text-primary\" data-testid=\"related-count\">{countText ?? agg.count}</span>\n {splits.map(([value, n]) => {\n const text = `${splitLabel(value, col, set)} ${n}`;\n const href = order && drillUrl ? drillUrl(value) : null;\n const chip = 'px-1.5 py-0.5 rounded bg-surface-sunken text-2xs text-text-secondary whitespace-nowrap tabular-nums';\n return href ? (\n <Link key={value} to={href} onClick={(e) => e.stopPropagation()} className={`${chip} hover:text-accent`} data-testid=\"related-chip\">\n {text}\n </Link>\n ) : (\n <span key={value} className={chip} data-testid=\"related-chip\">{text}</span>\n );\n })}\n {(agg.hidden || restricted.length > 0) && (\n <span className=\"text-2xs text-text-quaternary italic\" data-testid=\"related-restricted\">\n {agg.hidden && !splits.length ? 'split restricted' : 'partial'}\n </span>\n )}\n </span>\n );\n}\n","import { useNavigate } from 'react-router-dom';\nimport { DataTable, type Column } from '../../common/data/DataTable';\nimport { FormattedValue, EM_DASH } from '../../common/display/FormattedValue';\nimport { useRelatedRows } from '../../../api/escalation-related';\nimport { interpolateItemTemplate, type EscalationItem } from '../../../lib/escalation-items';\nimport { displayRoleTitle } from '../../../lib/role-display';\nimport type { RelatedRow, RowDetailSectionDecl } from '../../../lib/list-schema';\nimport { rowContext } from './row-parts';\nimport type { LTEscalationRecord } from '../../../api/types';\n\n/** `format: \"role\"` renders a role name as its title. */\nconst ROLE_FORMAT = 'role';\n\nfunction cellText(template: string, row: RelatedRow): string {\n const ctx = row.escalation ? rowContext(row.escalation as unknown as LTEscalationRecord) : {};\n return interpolateItemTemplate(template, row.item as EscalationItem | undefined, ctx);\n}\n\nfunction DetailSection({ role, host, version, section, roleLabels }: {\n role: string;\n host: LTEscalationRecord;\n version: number | null | undefined;\n section: RowDetailSectionDecl;\n roleLabels?: Record<string, string>;\n}) {\n const navigate = useNavigate();\n const query = useRelatedRows(role, host.id, section.related, version, section.limit);\n const rows = query.data?.rows ?? [];\n const labels = query.data?.roleLabels ?? roleLabels ?? {};\n const restricted = query.data?.restricted ?? [];\n\n // A column whose every row restates a facet the opened row carries says\n // nothing new beneath it: the row already shows that facet.\n const hostValues = new Set(\n Object.values(host.metadata ?? {})\n .filter((v) => (typeof v === 'string' && v !== '') || typeof v === 'number' || typeof v === 'boolean')\n .map(String),\n );\n const shown = section.columns.filter((col, i) => {\n // The first column names each row; it always stays.\n if (i === 0 || rows.length === 0) return true;\n const values = new Set(rows.map((row) => cellText(col.value, row)));\n return !(values.size === 1 && hostValues.has([...values][0]));\n });\n\n const columns: Column<RelatedRow>[] = shown.map((col, i) => ({\n key: `d-${i}`,\n label: col.label,\n priority: col.priority ?? (i === 0 ? 1 : 2),\n render: (row) => {\n const text = cellText(col.value, row);\n if (col.format === ROLE_FORMAT && text !== EM_DASH) {\n return <span className=\"block truncate\">{labels[text] ?? displayRoleTitle({ role: text })}</span>;\n }\n return (\n <span className=\"block truncate\" title={text !== EM_DASH ? text : undefined}>\n <FormattedValue raw={text} format={col.format} />\n </span>\n );\n },\n }));\n\n const target = (row: RelatedRow): string | null =>\n (row.escalation?.id as string | undefined) ?? row.item?.reciprocalId ?? null;\n\n return (\n <div data-testid=\"row-detail-section\">\n <p className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary pt-3 pb-1\">\n {section.label ?? section.related}\n {query.data && <span className=\"ml-2 font-normal normal-case tracking-normal tabular-nums\">{query.data.total}</span>}\n </p>\n {query.isLoading ? (\n <p className=\"text-2xs text-text-tertiary italic pb-2\">Loading…</p>\n ) : (\n <DataTable\n columns={columns}\n data={rows}\n keyFn={(row) => row.item?.itemKey ?? String(row.escalation?.id)}\n onRowClick={(row) => {\n const id = target(row);\n if (id) navigate(`/escalations/detail/${id}`);\n }}\n layout=\"fixed\"\n density=\"compact\"\n inline\n emptyMessage=\"\"\n />\n )}\n {!query.isLoading && rows.length === 0 && (\n <p className=\"text-2xs text-text-quaternary italic pb-2\">None.</p>\n )}\n {query.data && query.data.total > rows.length && (\n <p className=\"text-2xs text-text-quaternary pb-2\">Showing {rows.length} of {query.data.total}.</p>\n )}\n {restricted.length > 0 && (\n <p className=\"text-2xs text-text-quaternary italic pb-2\">\n Not shown (outside your view): {restricted.map((r) => labels[r] ?? r).join(', ')}\n </p>\n )}\n </div>\n );\n}\n\n/** A host row's declared detail sections, each loaded when the row opens. */\nexport function RowDetail({ role, host, version, sections }: {\n role: string;\n host: LTEscalationRecord;\n version: number | null | undefined;\n sections: RowDetailSectionDecl[];\n}) {\n return (\n <div className=\"space-y-1\" data-testid=\"row-detail\">\n {sections.map((section, i) => (\n <DetailSection key={i} role={role} host={host} version={version} section={section} />\n ))}\n </div>\n );\n}\n","import { interpolateHelp } from '../../../lib/x-lt-help';\nimport { GROUP_FOLDS, foldExtreme, isExtremeAggregate, type GroupFold, type RelatedAggregate, type RelatedHostAggregate } from '../../../lib/list-schema';\nimport { EM_DASH } from '../../common/display/FormattedValue';\nimport { rowContext, type ColumnDef } from './row-parts';\nimport type { LTEscalationRecord } from '../../../api/types';\n\n/** One page group from the grouped list read. */\nexport interface EscalationGroup {\n key: string | null;\n ids: string[];\n}\n\n/** A facet-table row: one escalation, or a group of rows sharing a facet. */\nexport interface TableRow {\n key: string;\n rows: LTEscalationRecord[];\n /** The shared facet value; null for an ungrouped row or a row without the facet. */\n groupKey: string | null;\n /** 0 for a top-level line; 1 for a member shown under its open group. */\n depth?: number;\n /** A member that closes its group's block. */\n lastChild?: boolean;\n /** A member's group line. */\n parent?: TableRow;\n}\n\n/** The lines the table draws: each open group followed by its members. */\nexport function withOpenMembers(rows: TableRow[], open: ReadonlySet<string>): TableRow[] {\n return rows.flatMap((row) => {\n if (row.rows.length < 2 || !open.has(row.key)) return [row];\n const members = row.rows.map((m, i): TableRow => ({\n key: `${row.key}/${m.id}`,\n rows: [m],\n groupKey: row.groupKey,\n depth: 1,\n lastChild: i === row.rows.length - 1,\n parent: row,\n }));\n return [row, ...members];\n });\n}\n\n/** Table rows in page order: one per group when grouped, else one per row. */\nexport function buildTableRows(rows: LTEscalationRecord[], groups?: EscalationGroup[] | null): TableRow[] {\n if (!groups) return rows.map((r) => ({ key: r.id, rows: [r], groupKey: null }));\n const byId = new Map(rows.map((r) => [r.id, r]));\n return groups\n .map((g) => ({\n key: g.key != null ? `group:${g.key}` : g.ids[0],\n rows: g.ids.map((id) => byId.get(id)).filter((r): r is LTEscalationRecord => !!r),\n groupKey: g.key,\n }))\n .filter((g) => g.rows.length > 0);\n}\n\nfunction numeric(values: string[]): number[] | null {\n const nums = values.map((v) => Number(v));\n return nums.every((n) => Number.isFinite(n)) ? nums : null;\n}\n\n/**\n * A plain column's text across a group's rows. `first` reads the lead row;\n * `min`/`max` compare numerically when every value is a number, else as text\n * (ISO instants order as text); `sum` adds numbers; `count` counts rows.\n */\nexport function foldColumnText(col: ColumnDef & { group?: GroupFold }, rows: LTEscalationRecord[]): string {\n const fold = col.group ?? GROUP_FOLDS.FIRST;\n if (fold === GROUP_FOLDS.COUNT) return String(rows.length);\n const values = rows.map((r) => interpolateHelp(col.value, rowContext(r))).filter((v) => v && v !== EM_DASH);\n if (fold === GROUP_FOLDS.DISTINCT) return values.length ? [...new Set(values)].join(', ') : EM_DASH;\n if (fold === GROUP_FOLDS.FIRST || rows.length === 1) return values[0] ?? EM_DASH;\n if (!values.length) return EM_DASH;\n const nums = numeric(values);\n if (fold === GROUP_FOLDS.SUM) return nums ? String(nums.reduce((a, b) => a + b, 0)) : EM_DASH;\n if (nums) return String(fold === GROUP_FOLDS.MIN ? Math.min(...nums) : Math.max(...nums));\n const sorted = [...values].sort();\n return fold === GROUP_FOLDS.MIN ? sorted[0] : sorted[sorted.length - 1];\n}\n\n/** One aggregate across several host rows: counts and splits sum; a min or max folds its values. */\nexport function mergeAggregates(\n aggs: Array<RelatedHostAggregate | undefined>,\n aggregate?: RelatedAggregate,\n): RelatedHostAggregate | undefined {\n const present = aggs.filter((a): a is RelatedHostAggregate => !!a);\n if (!present.length) return undefined;\n if (present.every((a) => a.unresolved)) return { count: 0, unresolved: true };\n const out: RelatedHostAggregate = { count: 0 };\n for (const a of present) {\n if (a.unresolved) continue;\n out.count += a.count;\n if (a.hidden) out.hidden = (out.hidden ?? 0) + a.hidden;\n if (a.splits) {\n out.splits ??= {};\n for (const [k, n] of Object.entries(a.splits)) out.splits[k] = (out.splits[k] ?? 0) + n;\n }\n }\n if (isExtremeAggregate(aggregate)) {\n const value = foldExtreme(aggregate, present.flatMap((a) => (a.value === undefined ? [] : [a.value])));\n if (value !== undefined) out.value = value;\n }\n return out;\n}\n","import { useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { ChevronRight } from 'lucide-react';\nimport { interpolateHelp } from '../../../lib/x-lt-help';\nimport { DataTable, type Column as TableColumn } from '../../common/data/DataTable';\nimport { FormattedValue, EM_DASH } from '../../common/display/FormattedValue';\nimport { RefineDialog } from '../RefineDialog';\nimport { useRelatedAggregates } from '../../../api/escalation-related';\nimport { useRelatedSetEvents } from '../../../hooks/useEventHooks';\nimport { metadataFacetsUrl } from '../../../lib/facet-url';\nimport {\n readListSchemaRelations,\n relatedAggregateKey,\n resolveRelatedFacets,\n rowTemplateContext,\n type GroupFold,\n type ListSchemaRelations,\n type RelatedColumnDecl,\n type RelatedSetResult,\n} from '../../../lib/list-schema';\nimport {\n escalationDotClass,\n rowContext,\n rowRefinePairs,\n RowActionButton,\n RefineTrigger,\n IDENTITY_COLUMN_WIDTH,\n actionColumnWidth,\n type ColumnDef,\n type RowActionDef,\n} from './row-parts';\nimport { RelatedCell } from './RelatedCell';\nimport { RowDetail } from './RowDetail';\nimport { buildTableRows, foldColumnText, mergeAggregates, withOpenMembers, type EscalationGroup, type TableRow } from './group-rows';\nimport type { LTEscalationRecord } from '../../../api/types';\n\nexport type { EscalationGroup } from './group-rows';\n\n/** A plain column (a `value` template) or a related column (a `related` set). */\ntype TableColumnDecl = ColumnDef & Partial<Omit<RelatedColumnDecl, 'label'>> & { group?: GroupFold };\n\nexport interface FacetTableSchema {\n 'x-lt-columns'?: Array<ColumnDef | (Omit<ColumnDef, 'value'> & RelatedColumnDecl)>;\n 'x-lt-row-action'?: RowActionDef;\n [key: string]: unknown;\n}\n\n/** One member per distinct resolved facet match (members whose facets do not resolve stay). */\nfunction distinctByMatch(members: LTEscalationRecord[], facets: Record<string, unknown>, narrow?: Record<string, unknown>): LTEscalationRecord[] {\n const seen = new Set<string>();\n return members.filter((m) => {\n const match = resolveRelatedFacets(facets, rowTemplateContext(m as unknown as Record<string, unknown>), narrow);\n if (!match) return true;\n const key = JSON.stringify(match);\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\n/** The related declaration, or none when the stored schema does not validate. */\nfunction safeRelations(schema: FacetTableSchema): ListSchemaRelations | null {\n try {\n return readListSchemaRelations(schema);\n } catch {\n return null;\n }\n}\n\n/**\n * The pending queue as a facet table. Plain columns template over each row;\n * related columns aggregate the row's related sets (one request per page);\n * a declared row detail expands each row into its related rows; grouped\n * rows fold their columns and expand to their members.\n */\ninterface FacetTableProps {\n schema: FacetTableSchema;\n rows: LTEscalationRecord[];\n /** Grouped reads: the page's groups, in order. */\n groups?: EscalationGroup[] | null;\n role: string;\n /** The list schema version the page rendered. */\n version?: number | null;\n onRowClick?: (row: LTEscalationRecord) => void;\n /** RefineDialog \"Add to filters\": merge into the live filter set. */\n onAddFacet?: (key: string, value: unknown) => void;\n forceView?: boolean;\n}\n\n/** Reads the page's related sets and keeps them live; mounted only when the schema declares sets. */\nfunction RelatedFacetTable(props: FacetTableProps & { relations: ListSchemaRelations }) {\n const related = useRelatedAggregates(props.role, props.rows.map((r) => r.id), props.version);\n const sets = related.data?.sets ?? {};\n useRelatedSetEvents(Object.values(sets).flatMap((set) => set.roles ?? []));\n return <FacetTableBody {...props} sets={sets} setsLoading={related.isLoading} />;\n}\n\nexport function FacetTable(props: FacetTableProps) {\n const relations = useMemo(() => safeRelations(props.schema), [props.schema]);\n return relations && Object.keys(relations.sets).length > 0\n ? <RelatedFacetTable {...props} relations={relations} />\n : <FacetTableBody {...props} relations={relations} sets={{}} setsLoading={false} />;\n}\n\nfunction FacetTableBody({ schema, rows, groups, role, version, onRowClick, onAddFacet, forceView, relations, sets, setsLoading }: FacetTableProps & {\n relations: ListSchemaRelations | null;\n sets: Record<string, RelatedSetResult>;\n setsLoading: boolean;\n}) {\n const navigate = useNavigate();\n const columnDefs = (schema['x-lt-columns'] ?? []) as TableColumnDecl[];\n const rowAction = schema['x-lt-row-action'];\n const sections = relations?.rowDetail ?? [];\n const [refineRow, setRefineRow] = useState<LTEscalationRecord | null>(null);\n const [open, setOpen] = useState<Set<string>>(() => new Set());\n\n const tableRows = useMemo(() => buildTableRows(rows, groups), [rows, groups]);\n const lines = useMemo(() => withOpenMembers(tableRows, open), [tableRows, open]);\n const grouped = !!groups;\n const expandable = sections.length > 0 || grouped;\n // A row opens when it has something beneath it: a group its members, a row its detail.\n const opens = (r: TableRow) => r.rows.length > 1 || sections.length > 0;\n\n const toggle = (key: string) =>\n setOpen((prev) => {\n const next = new Set(prev);\n if (next.has(key)) next.delete(key); else next.add(key);\n return next;\n });\n\n const relatedCell = (col: TableColumnDecl, members: LTEscalationRecord[]) => {\n const name = col.related!;\n const set = sets[name];\n const query = relations?.sets[name]?.query;\n // Members that share a facet match read the same related rows: count them once.\n const counted = query?.facets ? distinctByMatch(members, query.facets, query.narrow) : members;\n const key = relatedAggregateKey(col as RelatedColumnDecl, relations?.sets[name]?.source ?? '');\n const agg = mergeAggregates(counted.map((m) => set?.aggregates[key]?.[m.id]), (col as RelatedColumnDecl).aggregate);\n const drillUrl = query?.facets && members.length === 1\n ? (relatedRole: string) => {\n const match = resolveRelatedFacets(query.facets!, rowTemplateContext(members[0] as unknown as Record<string, unknown>), query.narrow);\n return match ? metadataFacetsUrl(match, relatedRole) : null;\n }\n : undefined;\n return <RelatedCell col={col as RelatedColumnDecl} set={set} agg={setsLoading ? undefined : agg} drillUrl={drillUrl} />;\n };\n\n // The authored columns render through the same dense table the engineer\n // views use: the card fold at narrow widths, never a horizontal scroll.\n // Authors steer the fold with `priority` (1 title, 2 folds, 3 dropped).\n const actionLabel = rowAction?.label ?? (forceView ? 'View' : 'Claim');\n const lead = (r: TableRow) => r.rows[0];\n const columns: TableColumn<TableRow>[] = [\n ...(expandable ? [{\n key: '_expand',\n label: '',\n priority: 1 as const,\n className: 'w-12 px-1',\n render: (r: TableRow) => (\n // A member's chevron steps in under its group's, so depth reads at a glance.\n <span className={`flex ${r.depth ? 'pl-5' : ''}`}>\n {opens(r) && (\n <button\n type=\"button\"\n onClick={(e) => { e.stopPropagation(); toggle(r.key); }}\n className=\"p-1 rounded icon-link hover:bg-surface-hover transition-colors\"\n aria-expanded={open.has(r.key)}\n aria-label={open.has(r.key) ? 'Collapse row' : 'Expand row'}\n data-testid=\"row-expand\"\n >\n <ChevronRight className={`w-3.5 h-3.5 transition-transform ${open.has(r.key) ? 'rotate-90' : ''}`} strokeWidth={1.75} />\n </button>\n )}\n </span>\n ),\n }] : []),\n {\n key: '_status',\n label: '',\n priority: 1,\n className: 'w-8',\n render: (r) => (\n <span className=\"inline-flex items-center gap-1\">\n <span className={`w-2.5 h-2.5 inline-block rounded-full dot-ring ${escalationDotClass(lead(r))}`} title={lead(r).status} />\n {r.rows.length > 1 && (\n <span className=\"text-2xs tabular-nums text-text-tertiary\" title={`${r.rows.length} rows in this group`} data-testid=\"group-size\">\n {r.rows.length}\n </span>\n )}\n </span>\n ),\n },\n ...columnDefs.map((col, i): TableColumn<TableRow> => ({\n key: `col-${i}`,\n label: col.label,\n priority: col.priority ?? (i === 0 ? 1 : 2),\n width: col.width ?? (i === 0 && !columnDefs.some((c) => c.width) ? IDENTITY_COLUMN_WIDTH : undefined),\n render: (r) => {\n if (col.related) return relatedCell(col, r.rows);\n const text = r.rows.length > 1 ? foldColumnText(col, r.rows) : interpolateHelp(col.value, rowContext(lead(r)));\n // A member shows only what differs from its group: the group line already states the rest.\n if (r.parent && text === foldColumnText(col, r.parent.rows)) return null;\n // The identity steps in for a member, so the tree reads in the data too.\n const indent = i === 0 && r.depth ? 'pl-4' : '';\n return (\n <span className={`block truncate ${indent}`} title={text && text !== EM_DASH ? text : undefined}>\n <FormattedValue raw={text} format={col.format} />\n </span>\n );\n },\n })),\n {\n key: '_refine',\n label: '',\n priority: 1,\n className: 'w-8 px-1',\n render: (r) =>\n r.rows.length === 1 && rowRefinePairs(lead(r), columnDefs).length > 0\n ? <RefineTrigger onOpen={() => setRefineRow(lead(r))} />\n : null,\n },\n {\n // The action column sizes to its label so the button never wraps.\n key: '_action',\n label: '',\n priority: 1,\n width: actionColumnWidth(actionLabel),\n className: 'text-right whitespace-nowrap',\n render: (r) => r.rows.length === 1\n ? <RowActionButton row={lead(r)} def={rowAction} onView={() => onRowClick?.(lead(r))} forceView={forceView} />\n : null,\n },\n ];\n\n // Containment by depth: an open line takes a light band, its members a\n // stronger band stepped in under it, and a row's detail the band of its\n // row, indented past it. No rules: indentation and value carry the tree.\n const rowClassName = (r: TableRow) => {\n if (r.depth) return 'bg-surface-sunken border-b-surface-border/40';\n return open.has(r.key) && opens(r) ? 'bg-surface-sunken/50 border-b-surface-border/40' : '';\n };\n\n const renderExpansion = (r: TableRow) => {\n if (!open.has(r.key) || r.rows.length > 1 || sections.length === 0) return null;\n return (\n <div\n onClick={(e) => e.stopPropagation()}\n className={`${r.depth ? 'bg-surface-sunken pl-20' : 'bg-surface-sunken/50 pl-12'} pr-3 pt-1 pb-4`}\n data-testid=\"row-detail-block\"\n >\n <RowDetail role={role} host={lead(r)} version={version} sections={sections} />\n </div>\n );\n };\n\n return (\n <>\n <DataTable\n columns={columns}\n data={lines}\n layout=\"fixed\"\n density=\"dense\"\n keyFn={(r) => r.key}\n onRowClick={onRowClick ? (r) => (r.rows.length === 1 ? onRowClick(lead(r)) : toggle(r.key)) : undefined}\n rowClassName={expandable ? rowClassName : undefined}\n emptyMessage=\"No pending items.\"\n renderExpansion={expandable ? renderExpansion : undefined}\n />\n <RefineDialog\n open={!!refineRow}\n onClose={() => setRefineRow(null)}\n role={role}\n pairs={refineRow ? rowRefinePairs(refineRow, columnDefs) : []}\n onNavigate={navigate}\n onAddFacet={onAddFacet}\n />\n </>\n );\n}\n","import { useState, useEffect } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { interpolateHelp } from '../../lib/x-lt-help';\nimport { MarkdownRenderer } from '../common/display/MarkdownRenderer';\nimport { DateValue } from '../common/display/DateValue';\nimport { FormattedValue as FieldValue, EM_DASH, isAgeFormat } from '../common/display/FormattedValue';\nimport { StickyPagination } from '../common/data/StickyPagination';\nimport { useEscalations } from '../../api/escalations';\nimport { schemaNeedsEnvelope } from '../../lib/schema-needs-envelope';\nimport { getDeep } from '../../lib/x-lt-bind';\nimport { typeColor } from '../../lib/type-color';\nimport { RefineDialog, type RefinePair } from './RefineDialog';\nimport {\n escalationDotClass,\n rowContext,\n RowActionButton,\n RefineTrigger,\n METADATA_TOKEN,\n type ColumnDef,\n type RowActionDef,\n} from './list-view/row-parts';\nimport { FacetTable, type EscalationGroup } from './list-view/FacetTable';\nimport type { LTEscalationRecord } from '../../api/types';\n\nexport { rowContext, rowRefinePairs } from './list-view/row-parts';\nexport type { ColumnDef, RowActionDef } from './list-view/row-parts';\nexport { FIELD_FORMATS } from '../common/display/FormattedValue';\n\n/**\n * EscalationListView — the role-authored rich view of an escalation list, driven\n * by a versioned `list_schema` (x-lt-* markup). The list-page analog of the\n * resolve form: the same `{{domain.path}}` token binding (via interpolateHelp)\n * against each row's context, and MarkdownRenderer for rich bodies.\n *\n * Layouts:\n * active-history — single live item as a card on the left + history column on right\n * active — just the single live item card (no history)\n * facet-table — full pending queue as a table, columns from x-lt-columns\n * facet-board — one card per x-lt-group-by facet value (an entity board:\n * machines, stations), rendered from each group's latest row\n */\n\ninterface CardDef {\n title?: string;\n subtitle?: string;\n body?: string;\n fields?: { label: string; value: string; format?: string }[];\n}\n\ninterface HistoryDef {\n row?: { title?: string; subtitle?: string; meta?: string };\n limit?: number;\n status?: string;\n}\n\n\ninterface BoardCardDef {\n title?: string;\n /** Status chip — any token (commonly {{escalation.subtype}}). */\n state?: string;\n fields?: { label: string; value: string; format?: string }[];\n}\n\n\nexport interface ListSchema {\n 'x-lt-layout'?: string;\n 'x-lt-help'?: string;\n 'x-lt-active'?: CardDef;\n 'x-lt-history'?: HistoryDef;\n 'x-lt-columns'?: ColumnDef[];\n /** facet-board: the \"domain.path\" whose value identifies each entity. */\n 'x-lt-group-by'?: string;\n /** facet-board: the per-entity card definition. */\n 'x-lt-card'?: BoardCardDef;\n /** The per-row action button (claim | view, label, claim duration). */\n 'x-lt-row-action'?: RowActionDef;\n /** facet-table: related sets, row detail sections (see shared/list-schema). */\n 'x-lt-related'?: Record<string, unknown>;\n 'x-lt-row-detail'?: unknown[];\n}\n\n/**\n * Repaint-only minute tick so `format: \"age\"` values stay current. Pure\n * re-render — no network. Mounted once at the view root, only when the\n * schema actually uses ages.\n */\nfunction useAgeTick(enabled: boolean): void {\n const [, setTick] = useState(0);\n useEffect(() => {\n if (!enabled) return;\n const t = window.setInterval(() => setTick((n) => n + 1), 60_000);\n return () => window.clearInterval(t);\n }, [enabled]);\n}\n\nfunction schemaUsesAge(schema: ListSchema): boolean {\n return [...(schema['x-lt-columns'] ?? []), ...(schema['x-lt-card']?.fields ?? [])]\n .some((f) => isAgeFormat(f.format));\n}\n\n\n\n\n\nfunction ActiveCard({ esc, card, rowAction, onOpen, forceView }: {\n esc: LTEscalationRecord;\n card: CardDef;\n rowAction?: RowActionDef;\n onOpen?: () => void;\n forceView?: boolean;\n}) {\n const ctx = rowContext(esc);\n const title = card.title ? interpolateHelp(card.title, ctx) : esc.type;\n return (\n <div>\n <div className=\"flex items-start justify-between gap-6\">\n <button onClick={onOpen} className=\"text-left group min-w-0\">\n <h3 className=\"heading-2 group-hover:text-accent transition-colors leading-tight\">\n {title}\n </h3>\n {card.subtitle && (\n <p className=\"text-xs text-text-tertiary mt-1.5\">{interpolateHelp(card.subtitle, ctx)}</p>\n )}\n </button>\n\n {/* The row action — one-click claim (then the detail page opens already\n claimed), or view for read-only templates. */}\n <RowActionButton row={esc} def={rowAction} onView={onOpen} prominent forceView={forceView} />\n </div>\n\n {card.fields && card.fields.length > 0 && (\n <dl className=\"flex flex-wrap gap-x-10 gap-y-4 mt-6\">\n {card.fields.map((f, i) => (\n <div key={i}>\n <dt className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary\">{f.label}</dt>\n <dd className=\"text-xs text-text-primary mt-1\"><FieldValue raw={interpolateHelp(f.value, ctx)} /></dd>\n </div>\n ))}\n </dl>\n )}\n\n {card.body && (\n <div className=\"mt-7 pt-6 border-t border-surface-border/50\">\n <MarkdownRenderer content={interpolateHelp(card.body, ctx)} />\n </div>\n )}\n </div>\n );\n}\n\nfunction HistoryColumn({ role, def, onRowClick }: {\n role: string;\n def: HistoryDef;\n onRowClick?: (row: LTEscalationRecord) => void;\n}) {\n const [show, setShow] = useState(false);\n const query = useEscalations({\n role,\n status: def.status ?? 'resolved',\n sort_by: 'resolved_at',\n order: 'desc',\n limit: def.limit ?? 25,\n enabled: show,\n include: schemaNeedsEnvelope(def) ? 'envelope' : undefined,\n });\n const rows = query.data?.escalations ?? [];\n const total = query.data?.total ?? 0;\n const rowDef = def.row ?? {};\n\n if (!show) {\n return (\n <button\n onClick={() => setShow(true)}\n className=\"text-xs text-accent hover:underline\"\n data-testid=\"load-history\"\n >\n Load full history →\n </button>\n );\n }\n\n if (query.isLoading) {\n return <p className=\"text-xs text-text-tertiary italic\">Loading history…</p>;\n }\n\n if (rows.length === 0) {\n return <p className=\"text-xs text-text-tertiary italic\">No past revisions.</p>;\n }\n\n return (\n <div>\n <div className=\"divide-y divide-surface-border/40\">\n {rows.map((e) => {\n const ctx = rowContext(e);\n return (\n <button\n key={e.id}\n onClick={() => onRowClick?.(e)}\n className=\"w-full text-left py-2.5 group flex items-center gap-3\"\n >\n {/* Status as a bare outlined dot — colour carries the meaning. */}\n <span\n className={`w-2.5 h-2.5 shrink-0 rounded-full dot-ring ${escalationDotClass(e)}`}\n title={e.status}\n />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block text-xs text-text-primary group-hover:text-accent transition-colors truncate\">\n {rowDef.title ? interpolateHelp(rowDef.title, ctx) : e.type}\n </span>\n {rowDef.subtitle && (\n <span className=\"block text-2xs text-text-tertiary truncate\">\n {interpolateHelp(rowDef.subtitle, ctx)}\n </span>\n )}\n </span>\n {rowDef.meta\n ? <span className=\"text-2xs text-text-tertiary shrink-0\">{interpolateHelp(rowDef.meta, ctx)}</span>\n : e.resolved_at && <DateValue date={e.resolved_at} format=\"relative\" className=\"text-2xs text-text-tertiary shrink-0 whitespace-nowrap\" />}\n </button>\n );\n })}\n </div>\n {total > rows.length && (\n <p className=\"text-2xs text-text-quaternary mt-3\">Showing {rows.length} of {total}.</p>\n )}\n </div>\n );\n}\n\n\n\nfunction SectionLabel({ children }: { children: React.ReactNode }) {\n return (\n <p className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-3\">{children}</p>\n );\n}\n\n// ── facet-board — one card per entity (machine, station) ─────────────────────\n\ninterface BoardGroup {\n key: string;\n /** The group's identity as stored (native type preserved for the facet URL). */\n rawValue: unknown;\n latest: LTEscalationRecord;\n count: number;\n}\n\n/**\n * Group rows by the resolved x-lt-group-by value; each card renders from the\n * group's most recent row (by created_at). Rows without the facet are skipped —\n * the board reflects the scope, it doesn't invent entities.\n */\nexport function groupBoardRows(rows: LTEscalationRecord[], groupBy: string): BoardGroup[] {\n const dot = groupBy.indexOf('.');\n const facetKey = groupBy.startsWith('metadata.') ? groupBy.slice('metadata.'.length) : null;\n const groups = new Map<string, BoardGroup>();\n for (const row of rows) {\n const ctx = rowContext(row);\n let v: unknown;\n try {\n v = dot === -1\n ? (ctx as unknown as Record<string, unknown>)[groupBy]\n : getDeep((ctx as unknown as Record<string, unknown>)[groupBy.slice(0, dot)], groupBy.slice(dot + 1));\n } catch {\n v = undefined;\n }\n if (v === undefined || v === null || v === '') continue;\n const key = String(v);\n const rawValue = facetKey ? (row.metadata?.[facetKey] ?? v) : v;\n const existing = groups.get(key);\n if (!existing) {\n groups.set(key, { key, rawValue, latest: row, count: 1 });\n } else {\n existing.count += 1;\n if (new Date(row.created_at) > new Date(existing.latest.created_at)) existing.latest = row;\n }\n }\n return [...groups.values()].sort((a, b) => a.key.localeCompare(b.key));\n}\n\n\nfunction FacetBoard({ schema, rows, role, onOpenDetail, onOpenGroup, onAddFacet, forceView }: {\n schema: ListSchema;\n rows: LTEscalationRecord[];\n role: string;\n forceView?: boolean;\n /** Plain card click — the group's latest row opens in the detail view. */\n onOpenDetail?: (row: LTEscalationRecord) => void;\n /** History affordances — receive a filtered table/timeline deep link. */\n onOpenGroup?: (url: string) => void;\n /** Shift+click — merge one facet into the live filter set (additive). */\n onAddFacet?: (key: string, value: unknown) => void;\n}) {\n const navigate = useNavigate();\n const groupBy = schema['x-lt-group-by'];\n const card = schema['x-lt-card'] ?? {};\n const rowAction = schema['x-lt-row-action'];\n const [refineGroup, setRefineGroup] = useState<BoardGroup | null>(null);\n\n if (!groupBy) {\n return <p className=\"text-xs text-text-tertiary italic\">facet-board needs an x-lt-group-by path.</p>;\n }\n const facetKey = groupBy.startsWith('metadata.') ? groupBy.slice('metadata.'.length) : null;\n const groups = groupBoardRows(rows, groupBy);\n if (groups.length === 0) {\n return <p className=\"text-xs text-text-tertiary italic\">No entities in scope.</p>;\n }\n\n // The card's refinable facts: the entity identity (the group-by facet)\n // plus every metadata-bound card field — one dialog per card, replacing\n // hover-revealed per-field icons (hover-only fails the iPad floor).\n const groupRefinePairs = (g: BoardGroup): RefinePair[] => {\n const pairs: RefinePair[] = [];\n if (facetKey) pairs.push({ key: facetKey, label: facetKey, value: g.rawValue });\n const seen = new Set(pairs.map((p) => p.key));\n for (const f of card.fields ?? []) {\n const bound = f.value.match(METADATA_TOKEN)?.[1];\n if (!bound || seen.has(bound)) continue;\n const raw = g.latest.metadata?.[bound];\n if (raw === undefined || raw === null || raw === '') continue;\n seen.add(bound);\n pairs.push({ key: bound, label: f.label, value: raw });\n }\n return pairs;\n };\n\n return (\n <div className=\"grid grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] gap-4\" data-testid=\"facet-board\">\n {groups.map((g) => {\n const ctx = rowContext(g.latest);\n const title = card.title ? interpolateHelp(card.title, ctx) : g.key;\n const state = card.state ? interpolateHelp(card.state, ctx) : (g.latest.subtype || g.latest.status);\n const stateHue = typeColor(state);\n const refinable = groupRefinePairs(g).length > 0;\n\n const activate = (e: { shiftKey: boolean }) => {\n if (e.shiftKey && facetKey && onAddFacet) {\n onAddFacet(facetKey, g.rawValue);\n return;\n }\n onOpenDetail?.(g.latest);\n };\n\n return (\n <div\n key={g.key}\n role=\"button\"\n tabIndex={0}\n onClick={activate}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); activate(e); }\n }}\n title={facetKey ? 'Open the latest item · ⇧ click to filter the board' : 'Open the latest item'}\n className=\"group/card border-l-2 border-accent/30 bg-surface-sunken/40 rounded-[0.125em] px-4 py-3.5 cursor-pointer transition-colors hover:bg-surface-sunken/70 focus:outline-none focus-visible:ring-1 focus-visible:ring-accent/40\"\n data-testid=\"facet-board-card\"\n >\n <div className=\"flex items-center justify-between gap-2 mb-2.5\">\n <span className=\"text-2xs font-semibold uppercase tracking-wider text-text-secondary truncate\">\n {title}\n </span>\n <span className=\"flex items-center gap-1 shrink-0\">\n <span\n className=\"px-1.5 py-0.5 rounded text-2xs font-mono font-medium\"\n style={{ color: stateHue.text, backgroundColor: stateHue.bg }}\n title={state}\n >\n {state}\n </span>\n {refinable && <RefineTrigger onOpen={() => setRefineGroup(g)} className=\"-my-1 -mr-1\" />}\n </span>\n </div>\n {card.fields && card.fields.length > 0 && (\n <dl className=\"space-y-1\">\n {card.fields.map((f, i) => {\n const text = interpolateHelp(f.value, ctx);\n return (\n <div key={i} className=\"flex items-baseline justify-between gap-3\">\n <dt className=\"text-2xs uppercase tracking-wider text-text-quaternary shrink-0\">{f.label}</dt>\n <dd\n className=\"min-w-0 truncate text-2xs text-text-primary\"\n title={text && text !== EM_DASH ? text : undefined}\n >\n <FieldValue raw={text} format={f.format} />\n </dd>\n </div>\n );\n })}\n </dl>\n )}\n\n <div className=\"mt-3 flex justify-end\">\n <RowActionButton row={g.latest} def={rowAction} onView={() => onOpenDetail?.(g.latest)} forceView={forceView} />\n </div>\n </div>\n );\n })}\n\n <RefineDialog\n open={!!refineGroup}\n onClose={() => setRefineGroup(null)}\n role={role}\n pairs={refineGroup ? groupRefinePairs(refineGroup) : []}\n onNavigate={onOpenGroup ?? navigate}\n onAddFacet={onAddFacet}\n />\n </div>\n );\n}\n\nexport function EscalationListView({ role, listSchema, listSchemaVersion, activeEscalations, groups, onRowClick, onOpenGroup, onAddFacet, forceViewAction, total, page, totalPages, pageSize, onPageChange, onPageSizeChange }: {\n role: string;\n listSchema: ListSchema;\n /** The list schema version rendered; related sets read the same version. */\n listSchemaVersion?: number | null;\n activeEscalations: LTEscalationRecord[];\n /** facet-table grouped reads: the page's groups, in order. */\n groups?: EscalationGroup[] | null;\n onRowClick?: (row: LTEscalationRecord) => void;\n /** facet-board history affordances — receive a filtered deep link. */\n onOpenGroup?: (url: string) => void;\n /** facet-board ⇧ click — merge one facet into the live filter set. */\n onAddFacet?: (key: string, value: unknown) => void;\n /** Render claim row-actions as view actions. For surfaces listing rows the\n * viewer already holds (e.g. My Escalations), where a claim gesture is\n * inapplicable — the button opens the detail page instead. */\n forceViewAction?: boolean;\n total?: number;\n page?: number;\n totalPages?: number;\n pageSize?: number;\n onPageChange?: (page: number) => void;\n onPageSizeChange?: (size: number) => void;\n}) {\n const layout = listSchema['x-lt-layout'];\n const card = listSchema['x-lt-active'] ?? {};\n const rowAction = listSchema['x-lt-row-action'];\n const active = activeEscalations[0];\n const help = listSchema['x-lt-help'];\n useAgeTick(schemaUsesAge(listSchema));\n\n // The active item is a distinct surface on the page wash — the same card\n // treatment the detail page gives its form sections. The label heads the\n // card; the history column beside it stays a quiet chronicle on the wash.\n const activeBlock = (\n <div className=\"border border-surface-border/60 bg-surface-sunken rounded-[0.25em] p-4\">\n <SectionLabel>Active</SectionLabel>\n {active ? (\n <ActiveCard esc={active} card={card} rowAction={rowAction} onOpen={() => onRowClick?.(active)} forceView={forceViewAction} />\n ) : (\n <p className=\"text-xs text-text-tertiary italic\">No active item right now.</p>\n )}\n </div>\n );\n\n const header = help && active ? (\n <div className=\"mb-8\"><MarkdownRenderer content={interpolateHelp(help, rowContext(active))} /></div>\n ) : help ? (\n <div className=\"mb-8\"><MarkdownRenderer content={help} /></div>\n ) : null;\n\n if (layout === 'facet-table') {\n // The table stands alone — no header text above it. Instructions belong\n // in the form's help surfaces; totals live in the pagination bar.\n const resolvedTotal = total ?? activeEscalations.length;\n return (\n <div>\n <FacetTable schema={listSchema as Record<string, unknown>} rows={activeEscalations} groups={groups} role={role} version={listSchemaVersion} onRowClick={onRowClick} onAddFacet={onAddFacet} forceView={forceViewAction} />\n {page !== undefined && totalPages !== undefined && onPageChange && (\n <StickyPagination\n page={page}\n totalPages={totalPages}\n onPageChange={onPageChange}\n total={resolvedTotal}\n pageSize={pageSize ?? 25}\n onPageSizeChange={onPageSizeChange}\n />\n )}\n </div>\n );\n }\n\n if (layout === 'facet-board') {\n return (\n <div>\n {header}\n <FacetBoard\n schema={listSchema}\n rows={activeEscalations}\n role={role}\n onOpenDetail={onRowClick}\n onOpenGroup={onOpenGroup}\n onAddFacet={onAddFacet}\n forceView={forceViewAction}\n />\n {page !== undefined && totalPages !== undefined && onPageChange && totalPages > 1 && (\n <StickyPagination\n page={page}\n totalPages={totalPages}\n onPageChange={onPageChange}\n total={total ?? activeEscalations.length}\n pageSize={pageSize ?? 25}\n onPageSizeChange={onPageSizeChange}\n />\n )}\n </div>\n );\n }\n\n if (layout === 'active-history') {\n return (\n <div>\n {header}\n <div className=\"grid grid-cols-1 @split:grid-cols-[1.6fr_1fr] gap-8 @split:gap-12 items-start\">\n {activeBlock}\n {/* pt-4 seats the History label on the Active label's optical line\n (the card's own padding provides that inset on the left). */}\n <div className=\"@split:pt-4\">\n <SectionLabel>History</SectionLabel>\n <HistoryColumn role={role} def={listSchema['x-lt-history'] ?? {}} onRowClick={onRowClick} />\n </div>\n </div>\n </div>\n );\n }\n\n // \"active\" (or any non-table layout): just the active card.\n return (\n <div>\n {header}\n {activeBlock}\n </div>\n );\n}\n","import { useState } from 'react';\nimport { Link } from 'react-router-dom';\nimport { Circle, Bell, Clock, ListFilter, Search, History } from 'lucide-react';\nimport { EntityTimelinePanel } from '../../components/escalation/EntityTimelinePanel';\nimport { useShellPanelOptional } from '../../hooks/useShellPanel';\nimport type { Column } from '../../components/common/data/DataTable';\nimport { FilterBar, FilterSelect, FilterInput, FilterDivider } from '../../components/common/data/FilterBar';\nimport { PriorityBadge } from '../../components/common/display/PriorityBadge';\nimport { RolePill } from '../../components/common/display/RolePill';\nimport { WorkflowPill } from '../../components/common/display/WorkflowPill';\nimport { UserName } from '../../components/common/display/UserName';\nimport { CountdownTimer } from '../../components/common/display/CountdownTimer';\nimport { formatAgoCompact } from '../../lib/format';\nimport { isEffectivelyClaimed, isAckEscalation } from '../../lib/escalation';\nimport { metadataFacetUrl } from '../../lib/facet-url';\nimport type { LTEscalationRecord } from '../../api/types';\n\nexport interface EscalationColumnOpts {\n highlightKeys?: string[];\n}\n\n// Shared cell text: a consistent resting shade for every cell, sharpening to\n// the primary text colour when the row is hovered. Cells (and pills via their\n// `inherit` tone) all read this single source so the whole row darkens as one.\nconst CELL_TEXT = 'text-text-secondary transition-colors group-hover/row:text-text-primary';\n\n/** Status dot — rendered inline before summary. */\nfunction StatusDot({ row }: { row: LTEscalationRecord }) {\n if (isAckEscalation(row)) {\n const color = row.status === 'resolved' ? 'text-status-success' : 'text-text-tertiary';\n return <Bell className={`w-3 h-3 shrink-0 ${color}`} />;\n }\n if (row.status === 'resolved') {\n return <Circle className=\"w-2.5 h-2.5 shrink-0 text-status-success\" strokeWidth={2.5} />;\n }\n if (row.status === 'cancelled') {\n return <Circle className=\"w-2.5 h-2.5 shrink-0 text-status-error\" strokeWidth={2.5} />;\n }\n if (row.status === 'expired') {\n return <Circle className=\"w-2.5 h-2.5 shrink-0 text-text-tertiary\" strokeWidth={2.5} />;\n }\n if (isEffectivelyClaimed(row)) {\n return <Circle className=\"w-2.5 h-2.5 shrink-0 text-status-warning\" strokeWidth={2.5} />;\n }\n // pending (unclaimed)\n return <Circle className=\"w-2.5 h-2.5 shrink-0 text-status-active\" strokeWidth={2.5} />;\n}\n\n/** Key/value metadata dict with 1 row collapsed by default, expand for the rest. */\nexport function MetadataCell({\n metadata,\n role,\n highlightKeys,\n}: {\n metadata: Record<string, unknown> | null;\n role: string;\n highlightKeys?: string[];\n}) {\n const [expanded, setExpanded] = useState(false);\n // Null outside the shell (tests, standalone renders) — the timeline\n // affordance simply doesn't render there.\n const shell = useShellPanelOptional();\n\n if (!metadata || Object.keys(metadata).length === 0) {\n return <span className=\"text-2xs text-text-tertiary\">—</span>;\n }\n\n const hl = highlightKeys ?? [];\n // Highlighted keys first, then the rest in insertion order.\n const allKeys = [\n ...hl.filter((k) => k in metadata),\n ...Object.keys(metadata).filter((k) => !hl.includes(k)),\n ];\n\n const shown = expanded ? allKeys : allKeys.slice(0, 1);\n const hiddenCount = allKeys.length - 1;\n\n return (\n <div className=\"w-full\" onClick={(e) => e.stopPropagation()}>\n <div className=\"space-y-px\">\n {shown.map((k, i) => {\n const sv = typeof metadata[k] === 'object' && metadata[k] !== null\n ? JSON.stringify(metadata[k])\n : String(metadata[k]);\n const isHl = hl.includes(k);\n const isLastShown = i === shown.length - 1;\n return (\n <div key={k} className=\"group/mrow flex items-center gap-1 min-w-0\">\n <span\n className={`shrink-0 w-14 text-2xs font-mono uppercase tracking-wide truncate ${isHl ? 'text-accent' : 'text-text-tertiary'}`}\n title={k}\n >\n {k}\n </span>\n <span\n className={`flex-1 min-w-0 text-2xs font-medium truncate ${isHl ? 'text-text-primary' : 'text-text-secondary'}`}\n title={sv}\n >\n {sv}\n </span>\n <span className=\"flex items-center gap-px shrink-0 opacity-50 group-hover/mrow:opacity-100 transition-opacity\">\n <Link\n to={metadataFacetUrl(k, metadata[k], role)}\n className=\"p-0.5 rounded text-text-quaternary hover:text-accent transition-colors\"\n title={`Filter ${role}: ${k} = ${sv}`}\n onClick={(ev) => ev.stopPropagation()}\n >\n <ListFilter className=\"w-3 h-3\" />\n </Link>\n <Link\n to={metadataFacetUrl(k, metadata[k])}\n className=\"p-0.5 rounded text-text-quaternary hover:text-accent transition-colors\"\n title={`Search all: ${k} = ${sv}`}\n onClick={(ev) => ev.stopPropagation()}\n >\n <Search className=\"w-3 h-3\" />\n </Link>\n {/* filter-present / search-present / history-past — the third\n verb of the triad. String values only: the timeline's GIN\n containment match only serves JSON-string facets. */}\n {shell && typeof metadata[k] === 'string' && (\n <button\n className=\"p-0.5 rounded text-text-quaternary hover:text-accent transition-colors\"\n title={`Timeline: every station ${sv} has moved through`}\n onClick={(ev) => {\n ev.stopPropagation();\n shell.setPanel(\n <EntityTimelinePanel facetKey={k} value={metadata[k] as string} role={role} />,\n { key: 'entity-timeline', width: 420 },\n );\n }}\n >\n <History className=\"w-3 h-3\" />\n </button>\n )}\n </span>\n {/* +N inline at end of single visible row when collapsed */}\n {!expanded && hiddenCount > 0 && (\n <button\n onClick={(ev) => { ev.stopPropagation(); setExpanded(true); }}\n className=\"shrink-0 text-2xs text-text-quaternary hover:text-accent transition-colors font-mono\"\n title={`Show ${hiddenCount} more fields`}\n >\n +{hiddenCount}\n </button>\n )}\n {/* ↑ inline at end of last row when expanded */}\n {expanded && isLastShown && hiddenCount > 0 && (\n <button\n onClick={(ev) => { ev.stopPropagation(); setExpanded(false); }}\n className=\"shrink-0 text-2xs text-text-quaternary hover:text-accent transition-colors\"\n title=\"Show less\"\n >\n ↑\n </button>\n )}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\n/** Build the shared column set, optionally wiring metadata filter callbacks. */\nexport function makeEscalationColumns(opts: EscalationColumnOpts = {}): Column<LTEscalationRecord>[] {\n return [\n {\n key: 'description',\n label: 'Summary',\n priority: 1,\n render: (row) => (\n <div className=\"flex items-center gap-2 overflow-hidden\">\n <span className=\"shrink-0\"><StatusDot row={row} /></span>\n <span className={`truncate text-xs ${CELL_TEXT}`}>{row.description || row.type}</span>\n </div>\n ),\n className: 'max-w-0',\n },\n // The manufacturing-floor column budget: identity, owner, urgency, age.\n // Everything else (workflow type, metadata, exact timestamps) lives in\n // the facet drawer and the detail page — never as a scrolling column.\n {\n key: 'assigned_to',\n label: 'Assignee',\n priority: 2,\n render: (row) => (row.assigned_to\n ? <UserName userId={row.assigned_to} className={`block truncate text-xs ${CELL_TEXT}`} />\n : <span className=\"text-xs text-text-quaternary\">—</span>),\n className: 'w-36 max-w-[9rem]',\n },\n {\n key: 'role',\n label: 'Role',\n priority: 2,\n render: (row) => (\n <span className={CELL_TEXT}>\n <RolePill role={row.role} size=\"md\" tone=\"inherit\" />\n </span>\n ),\n className: 'w-44 min-w-[11rem]',\n },\n {\n key: 'priority',\n label: 'Pri',\n priority: 2,\n render: (row) => (\n <span className={CELL_TEXT}>\n <PriorityBadge priority={row.priority} size=\"sm\" tone=\"inherit\" />\n </span>\n ),\n className: 'w-10',\n },\n // Enrichment columns — the jumping-off facets. The budget governs the\n // floor: these return only when the table has room (@split / @wall),\n // and in card mode they fold to pairs. The metadata cell carries the\n // clickable refine icons: filter within the role, search across roles\n // (admins), shift+click to AND facets.\n {\n key: 'workflow_type',\n label: 'Workflow',\n priority: 2,\n showFrom: 'split',\n render: (row) => <WorkflowPill type={row.workflow_type || row.type} />,\n className: 'w-40 whitespace-nowrap',\n },\n {\n key: 'metadata',\n label: 'Metadata',\n priority: 2,\n showFrom: 'wall',\n render: (row) => (\n <MetadataCell\n metadata={row.metadata}\n role={row.role}\n highlightKeys={opts.highlightKeys}\n />\n ),\n className: 'w-80 max-w-[19rem] align-top',\n },\n {\n key: 'created_at',\n label: 'Ago',\n priority: 1,\n render: (row) => (\n <span className={`text-xs tabular-nums ${CELL_TEXT}`} title={row.created_at}>\n {formatAgoCompact(row.created_at)}\n </span>\n ),\n className: 'w-14 whitespace-nowrap',\n },\n ];\n}\n\n/** Base columns shared by all escalation list pages (no filter callback). */\nexport const ESCALATION_COLUMNS: Column<LTEscalationRecord>[] = makeEscalationColumns();\n\n/** Time-remaining column for claimed escalations — aligns with checkbox column on All Escalations. */\nexport const TIME_LEFT_COLUMN: Column<LTEscalationRecord> = {\n key: 'expires',\n label: (<Clock className=\"w-3.5 h-3.5 text-text-tertiary\" />) as any,\n render: (row) =>\n row.assigned_until ? (\n <CountdownTimer until={row.assigned_until} />\n ) : (\n <span className=\"text-xs text-text-tertiary\">—</span>\n ),\n className: 'w-16 whitespace-nowrap',\n priority: 1,\n};\n\n/** Status icon column — color-coded filled circle, or bell for ACK/notification escalations. */\nexport const STATUS_COLUMN: Column<LTEscalationRecord> = {\n key: 'status',\n label: '',\n render: (row) => {\n if (isAckEscalation(row)) {\n const color = row.status === 'resolved' ? 'text-status-success' : 'text-text-tertiary';\n return <Bell className={`w-3 h-3 ${color}`} />;\n }\n if (row.status === 'resolved') {\n return <Circle className=\"w-2.5 h-2.5 text-status-success\" strokeWidth={2.5} />;\n }\n if (isEffectivelyClaimed(row)) {\n return <Circle className=\"w-2.5 h-2.5 text-status-warning\" strokeWidth={2.5} />;\n }\n // pending (unclaimed)\n return <Circle className=\"w-2.5 h-2.5 text-text-tertiary\" strokeWidth={2.5} />;\n },\n className: 'w-8',\n priority: 1,\n};\n\n/** Claimed-only status icon (always orange, or bell for ACK). */\nexport const CLAIMED_STATUS_COLUMN: Column<LTEscalationRecord> = {\n key: 'status',\n label: '',\n render: (row) =>\n isAckEscalation(row)\n ? <Bell className=\"w-3 h-3 text-status-warning\" />\n : <Circle className=\"w-2.5 h-2.5 text-status-warning\" strokeWidth={2.5} />,\n className: 'w-8',\n priority: 1,\n};\n\n/** Priority filter options shared by both pages. */\nexport const PRIORITY_OPTIONS = [\n { value: '1', label: 'P1' },\n { value: '2', label: 'P2' },\n { value: '3', label: 'P3' },\n { value: '4', label: 'P4' },\n];\n\n/** Status filter options for escalation list pages. `all` spans every status so a\n * metadata search (e.g. one order id) returns its escalations regardless of status. */\nexport const STATUS_OPTIONS = [\n { value: 'all', label: 'All' },\n { value: 'available', label: 'Available' },\n { value: 'claimed', label: 'Claimed' },\n { value: 'resolved', label: 'Resolved' },\n { value: 'cancelled', label: 'Cancelled' },\n { value: 'expired', label: 'Expired' },\n];\n\n/** Shared filter bar for escalation list pages. */\nexport function EscalationFilterBar({\n filters,\n setFilter,\n roles,\n types,\n showStatus = false,\n showSearch = true,\n showRole = true,\n actions,\n}: {\n filters: { role: string; type: string; priority: string; status?: string; search?: string };\n setFilter: (key: any, value: string) => void;\n roles: string[];\n types: string[];\n showStatus?: boolean;\n // Free-text search lives here by default, but the faceted page folds it into\n // the drawer instead so there's a single search surface.\n showSearch?: boolean;\n /** Kiosk sessions hide the role filter — the session IS the role. */\n showRole?: boolean;\n actions?: React.ReactNode;\n}) {\n // Non-default filters power the folded Filters button's badge.\n const activeFilterCount = [\n filters.role,\n filters.type,\n filters.priority,\n filters.status && filters.status !== 'all' ? filters.status : '',\n filters.search ?? '',\n ].filter(Boolean).length;\n\n return (\n <FilterBar actions={actions} activeFilterCount={activeFilterCount}>\n {showStatus && (\n <>\n <FilterSelect\n label=\"Status\"\n value={filters.status ?? ''}\n onChange={(v) => setFilter('status', v)}\n options={STATUS_OPTIONS}\n />\n <FilterDivider />\n </>\n )}\n {/* Role is the queue's primary facet — URL-driven (?role=). Pages whose\n title doubles as a queue selector share the same param, so the two\n controls mirror each other. Kiosk sessions hide it: the session IS\n the role. */}\n {showRole && (\n <>\n <FilterSelect\n label=\"Role\"\n value={filters.role}\n onChange={(v) => setFilter('role', v)}\n options={roles.map((r) => ({ value: r, label: r }))}\n />\n <FilterDivider />\n </>\n )}\n <FilterSelect\n label=\"Priority\"\n value={filters.priority}\n onChange={(v) => setFilter('priority', v)}\n options={PRIORITY_OPTIONS}\n />\n <FilterDivider />\n <FilterSelect\n label=\"Workflow Type\"\n value={filters.type}\n onChange={(v) => setFilter('type', v)}\n options={types.map((t) => ({ value: t, label: t }))}\n />\n {showSearch && (\n <>\n <FilterDivider />\n <FilterInput\n label=\"Search\"\n value={filters.search ?? ''}\n onChange={(v) => setFilter('search', v)}\n placeholder=\"ID, workflow, origin…\"\n />\n </>\n )}\n </FilterBar>\n );\n}\n"],"names":["PALETTE","hash","str","h","i","typeColor","typeName","FIND_THRESHOLD","RefineDialog","open","onClose","role","pairs","onNavigate","onAddFacet","selected","setSelected","useState","find","setFind","prevOpen","setPrevOpen","bound","p","preset","needle","visible","t","toggle","key","prev","next","chosen","facets","none","go","url","jsx","Modal","jsxs","Search","e","on","Check","metadataFacetsUrl","useRelatedAggregates","ids","version","enabled","sorted","useQuery","apiFetch","useRelatedRows","id","set","limit","SINGLE_TOKEN","ANY_TOKEN","MISSING_VALUE","parseJsonObject","value","parsed","rowTemplateContext","row","readToken","path","ctx","dot","domain","HELP_DOMAINS","root","getDeep","resolveTemplateValue","single","raw","text","interpolateHelp","resolveRelatedFacets","narrow","out","resolved","splitLabel","col","_a","SPLIT_PATHS","_b","RelatedCell","agg","drillUrl","EM_DASH","isExtremeAggregate","FormattedValue","countText","relatedCountText","order","splits","n","a","x","b","y","restricted","title","r","href","chip","Link","ROLE_FORMAT","cellText","template","rowContext","interpolateItemTemplate","DetailSection","host","section","roleLabels","navigate","useNavigate","query","rows","labels","_c","hostValues","v","columns","values","displayRoleTitle","target","DataTable","RowDetail","sections","withOpenMembers","members","m","buildTableRows","groups","byId","g","numeric","nums","foldColumnText","fold","GROUP_FOLDS","mergeAggregates","aggs","aggregate","present","k","foldExtreme","distinctByMatch","seen","match","safeRelations","schema","readListSchemaRelations","RelatedFacetTable","props","related","sets","useRelatedSetEvents","FacetTableBody","FacetTable","relations","useMemo","onRowClick","forceView","setsLoading","columnDefs","rowAction","refineRow","setRefineRow","setOpen","tableRows","lines","grouped","expandable","opens","relatedCell","name","counted","relatedAggregateKey","relatedRole","actionLabel","lead","ChevronRight","escalationDotClass","c","IDENTITY_COLUMN_WIDTH","indent","rowRefinePairs","RefineTrigger","actionColumnWidth","RowActionButton","rowClassName","renderExpansion","Fragment","useAgeTick","setTick","useEffect","schemaUsesAge","f","isAgeFormat","ActiveCard","esc","card","onOpen","FieldValue","MarkdownRenderer","HistoryColumn","def","show","setShow","useEscalations","schemaNeedsEnvelope","total","rowDef","DateValue","SectionLabel","children","groupBoardRows","groupBy","facetKey","rawValue","existing","FacetBoard","onOpenDetail","onOpenGroup","refineGroup","setRefineGroup","groupRefinePairs","METADATA_TOKEN","state","stateHue","refinable","activate","EscalationListView","listSchema","listSchemaVersion","activeEscalations","forceViewAction","page","totalPages","pageSize","onPageChange","onPageSizeChange","layout","active","help","activeBlock","header","resolvedTotal","StickyPagination","CELL_TEXT","StatusDot","isAckEscalation","color","Bell","Circle","isEffectivelyClaimed","MetadataCell","metadata","highlightKeys","expanded","setExpanded","shell","useShellPanelOptional","hl","allKeys","shown","hiddenCount","sv","isHl","isLastShown","metadataFacetUrl","ev","ListFilter","EntityTimelinePanel","History","makeEscalationColumns","opts","UserName","RolePill","PriorityBadge","WorkflowPill","formatAgoCompact","ESCALATION_COLUMNS","TIME_LEFT_COLUMN","Clock","CountdownTimer","PRIORITY_OPTIONS","STATUS_OPTIONS","EscalationFilterBar","filters","setFilter","roles","types","showStatus","showSearch","showRole","actions","activeFilterCount","FilterBar","FilterSelect","FilterDivider","FilterInput"],"mappings":"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"}