@alfadocs/ui-kit-debug 1.48.0 → 1.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/dist/_chunks/{agenda-card-C4h0xMGi.js → agenda-card-CjjxlA9K.js} +2 -2
  2. package/dist/_chunks/{agenda-card-C4h0xMGi.js.map → agenda-card-CjjxlA9K.js.map} +1 -1
  3. package/dist/_chunks/{agenda-tray-DNZYW2xt.js → agenda-tray-BhZASyJm.js} +2 -2
  4. package/dist/_chunks/{agenda-tray-DNZYW2xt.js.map → agenda-tray-BhZASyJm.js.map} +1 -1
  5. package/dist/_chunks/{alia-sidebar-Crn8OGPF.js → alia-sidebar-Dx-oeOV2.js} +3 -3
  6. package/dist/_chunks/{alia-sidebar-Crn8OGPF.js.map → alia-sidebar-Dx-oeOV2.js.map} +1 -1
  7. package/dist/_chunks/{appointment-card-CvGU0QP6.js → appointment-card-BgLpE6T5.js} +2 -2
  8. package/dist/_chunks/{appointment-card-CvGU0QP6.js.map → appointment-card-BgLpE6T5.js.map} +1 -1
  9. package/dist/_chunks/{appointment-peek--dmWznLZ.js → appointment-peek-BDiCIBb-.js} +2 -2
  10. package/dist/_chunks/{appointment-peek--dmWznLZ.js.map → appointment-peek-BDiCIBb-.js.map} +1 -1
  11. package/dist/_chunks/{appointment-timeline-y9uYZMUd.js → appointment-timeline-wQ-PdkFV.js} +2 -2
  12. package/dist/_chunks/{appointment-timeline-y9uYZMUd.js.map → appointment-timeline-wQ-PdkFV.js.map} +1 -1
  13. package/dist/_chunks/{appointment-tray-BTecNeSb.js → appointment-tray-D7Gt6m8x.js} +2 -2
  14. package/dist/_chunks/{appointment-tray-BTecNeSb.js.map → appointment-tray-D7Gt6m8x.js.map} +1 -1
  15. package/dist/_chunks/{avatar-CkDeQOSI.js → avatar-BVvjKNTp.js} +2 -2
  16. package/dist/_chunks/avatar-BVvjKNTp.js.map +1 -0
  17. package/dist/_chunks/{balance-badge-cell-CA0YNJMR.js → balance-badge-cell-klaxFNL_.js} +3 -3
  18. package/dist/_chunks/{balance-badge-cell-CA0YNJMR.js.map → balance-badge-cell-klaxFNL_.js.map} +1 -1
  19. package/dist/_chunks/{booking-BQYFDcrz.js → booking-BF9pVa2n.js} +377 -381
  20. package/dist/_chunks/booking-BF9pVa2n.js.map +1 -0
  21. package/dist/_chunks/{calendar-DjoJ9ovF.js → calendar-Bt44KMNO.js} +3 -2
  22. package/dist/_chunks/{calendar-DjoJ9ovF.js.map → calendar-Bt44KMNO.js.map} +1 -1
  23. package/dist/_chunks/calendar-workspace-C_eXL1by.js +10464 -0
  24. package/dist/_chunks/{calendar-workspace-D8zX9JWm.js.map → calendar-workspace-C_eXL1by.js.map} +1 -1
  25. package/dist/_chunks/{chat-message-Co_NRGM4.js → chat-message-B4ihjNy3.js} +2 -2
  26. package/dist/_chunks/{chat-message-Co_NRGM4.js.map → chat-message-B4ihjNy3.js.map} +1 -1
  27. package/dist/_chunks/{clinical-note-card-DYDQ3q2x.js → clinical-note-card-B7s5BtEl.js} +2 -2
  28. package/dist/_chunks/{clinical-note-card-DYDQ3q2x.js.map → clinical-note-card-B7s5BtEl.js.map} +1 -1
  29. package/dist/_chunks/{data-table-DWOSxlsy.js → data-table-CrI3_bjH.js} +411 -410
  30. package/dist/_chunks/data-table-CrI3_bjH.js.map +1 -0
  31. package/dist/_chunks/{dependent-selector-BR_8D2Qu.js → dependent-selector-58hTg5rB.js} +2 -2
  32. package/dist/_chunks/{dependent-selector-BR_8D2Qu.js.map → dependent-selector-58hTg5rB.js.map} +1 -1
  33. package/dist/_chunks/{entity-summary-Ckz_U00H.js → entity-summary-CFJfBdVP.js} +2 -2
  34. package/dist/_chunks/{entity-summary-Ckz_U00H.js.map → entity-summary-CFJfBdVP.js.map} +1 -1
  35. package/dist/_chunks/{file-manager-CqgxLqoA.js → file-manager-C6QQPQV5.js} +2 -2
  36. package/dist/_chunks/{file-manager-CqgxLqoA.js.map → file-manager-C6QQPQV5.js.map} +1 -1
  37. package/dist/_chunks/link-cell-renderer-CkNbUsBM.js +867 -0
  38. package/dist/_chunks/link-cell-renderer-CkNbUsBM.js.map +1 -0
  39. package/dist/_chunks/{marketplace-app-shell-Dehuxbi-.js → marketplace-app-shell-1uKqs4gD.js} +2 -2
  40. package/dist/_chunks/{marketplace-app-shell-Dehuxbi-.js.map → marketplace-app-shell-1uKqs4gD.js.map} +1 -1
  41. package/dist/_chunks/{message-card-DKOtnBHy.js → message-card-C2zsvyj0.js} +2 -2
  42. package/dist/_chunks/{message-card-DKOtnBHy.js.map → message-card-C2zsvyj0.js.map} +1 -1
  43. package/dist/_chunks/{message-tray-COMEtmyr.js → message-tray-CMlmxdH2.js} +2 -2
  44. package/dist/_chunks/{message-tray-COMEtmyr.js.map → message-tray-CMlmxdH2.js.map} +1 -1
  45. package/dist/_chunks/{notes-panel-BiOxZL_0.js → notes-panel-xxpFt-I1.js} +2 -2
  46. package/dist/_chunks/{notes-panel-BiOxZL_0.js.map → notes-panel-xxpFt-I1.js.map} +1 -1
  47. package/dist/_chunks/{operator-hero-5061fkY5.js → operator-hero-DyrNLoRO.js} +2 -2
  48. package/dist/_chunks/{operator-hero-5061fkY5.js.map → operator-hero-DyrNLoRO.js.map} +1 -1
  49. package/dist/_chunks/{patient-details-C23Hdm8v.js → patient-details-tTlvrJSU.js} +2 -2
  50. package/dist/_chunks/{patient-details-C23Hdm8v.js.map → patient-details-tTlvrJSU.js.map} +1 -1
  51. package/dist/_chunks/{patient-summary-card-C36L3h7h.js → patient-summary-card-DQ__6DR-.js} +2 -2
  52. package/dist/_chunks/{patient-summary-card-C36L3h7h.js.map → patient-summary-card-DQ__6DR-.js.map} +1 -1
  53. package/dist/_chunks/{practice-profile-hero-CPy5h2yI.js → practice-profile-hero-B-WcJYNH.js} +2 -2
  54. package/dist/_chunks/{practice-profile-hero-CPy5h2yI.js.map → practice-profile-hero-B-WcJYNH.js.map} +1 -1
  55. package/dist/_chunks/{practice-results-t2BHht91.js → practice-results-EKRiqWtQ.js} +2 -2
  56. package/dist/_chunks/{practice-results-t2BHht91.js.map → practice-results-EKRiqWtQ.js.map} +1 -1
  57. package/dist/_chunks/{signature-request-15D363w5.js → signature-request-BUGeG8oD.js} +2 -2
  58. package/dist/_chunks/{signature-request-15D363w5.js.map → signature-request-BUGeG8oD.js.map} +1 -1
  59. package/dist/_chunks/{task-card-CTTQfPS6.js → task-card-jaOhnj_q.js} +31 -30
  60. package/dist/_chunks/task-card-jaOhnj_q.js.map +1 -0
  61. package/dist/_chunks/{task-tray-JA-qp_pB.js → task-tray-HHyxi9ga.js} +2 -2
  62. package/dist/_chunks/{task-tray-JA-qp_pB.js.map → task-tray-HHyxi9ga.js.map} +1 -1
  63. package/dist/_chunks/{tasks-panel-C_dVDQKJ.js → tasks-panel-DbSjq_mz.js} +2 -2
  64. package/dist/_chunks/{tasks-panel-C_dVDQKJ.js.map → tasks-panel-DbSjq_mz.js.map} +1 -1
  65. package/dist/_chunks/{timeline-61AihzYz.js → timeline-ChY7iZrs.js} +2 -2
  66. package/dist/_chunks/{timeline-61AihzYz.js.map → timeline-ChY7iZrs.js.map} +1 -1
  67. package/dist/_chunks/{use-appointment-details-read-D2FH-cHF.js → use-appointment-details-read-5-hV-2xA.js} +4 -4
  68. package/dist/_chunks/{use-appointment-details-read-D2FH-cHF.js.map → use-appointment-details-read-5-hV-2xA.js.map} +1 -1
  69. package/dist/agent-catalog.json +1 -1
  70. package/dist/components/agenda-card/index.js +1 -1
  71. package/dist/components/agenda-tray/index.js +1 -1
  72. package/dist/components/appointment-card/index.js +2 -2
  73. package/dist/components/appointment-details-panel/index.js +1 -1
  74. package/dist/components/appointment-peek/index.js +1 -1
  75. package/dist/components/appointment-timeline/index.js +1 -1
  76. package/dist/components/avatar/avatar.d.ts.map +1 -1
  77. package/dist/components/avatar/index.js +1 -1
  78. package/dist/components/booking/booking.d.ts.map +1 -1
  79. package/dist/components/booking/cascade.d.ts +5 -0
  80. package/dist/components/booking/cascade.d.ts.map +1 -1
  81. package/dist/components/booking/index.js +1 -1
  82. package/dist/components/calendar/calendar.d.ts.map +1 -1
  83. package/dist/components/calendar/index.js +1 -1
  84. package/dist/components/chat-message/index.js +1 -1
  85. package/dist/components/clinical-note-card/index.js +1 -1
  86. package/dist/components/data-table/filters/number-filter.d.ts +26 -12
  87. package/dist/components/data-table/filters/number-filter.d.ts.map +1 -1
  88. package/dist/components/data-table/index.js +2 -2
  89. package/dist/components/data-table/toolbar.d.ts.map +1 -1
  90. package/dist/components/dependent-selector/index.js +1 -1
  91. package/dist/components/entity-summary/index.js +1 -1
  92. package/dist/components/file-manager/index.js +1 -1
  93. package/dist/components/message-card/index.js +1 -1
  94. package/dist/components/message-tray/index.js +1 -1
  95. package/dist/components/notes-panel/index.js +1 -1
  96. package/dist/components/operator-hero/index.js +1 -1
  97. package/dist/components/patient-details/index.js +1 -1
  98. package/dist/components/patient-summary-card/index.js +1 -1
  99. package/dist/components/patient-table/index.js +1 -1
  100. package/dist/components/practice-profile-hero/index.js +1 -1
  101. package/dist/components/practice-results/index.js +1 -1
  102. package/dist/components/task-card/index.js +1 -1
  103. package/dist/components/task-card/task-card.d.ts +3 -2
  104. package/dist/components/task-card/task-card.d.ts.map +1 -1
  105. package/dist/components/task-tray/index.js +1 -1
  106. package/dist/components/tasks-panel/index.js +1 -1
  107. package/dist/components/timeline/index.js +1 -1
  108. package/dist/i18n/locales/ar.d.ts +19 -14
  109. package/dist/i18n/locales/ar.d.ts.map +1 -1
  110. package/dist/i18n/locales/ar.js +19 -14
  111. package/dist/i18n/locales/ar.js.map +1 -1
  112. package/dist/i18n/locales/de.d.ts +19 -14
  113. package/dist/i18n/locales/de.d.ts.map +1 -1
  114. package/dist/i18n/locales/de.js +19 -14
  115. package/dist/i18n/locales/de.js.map +1 -1
  116. package/dist/i18n/locales/el.d.ts +19 -14
  117. package/dist/i18n/locales/el.d.ts.map +1 -1
  118. package/dist/i18n/locales/el.js +19 -14
  119. package/dist/i18n/locales/el.js.map +1 -1
  120. package/dist/i18n/locales/en.d.ts +5 -0
  121. package/dist/i18n/locales/en.d.ts.map +1 -1
  122. package/dist/i18n/locales/en.js +6 -0
  123. package/dist/i18n/locales/en.js.map +1 -1
  124. package/dist/i18n/locales/es.d.ts +19 -14
  125. package/dist/i18n/locales/es.d.ts.map +1 -1
  126. package/dist/i18n/locales/es.js +19 -14
  127. package/dist/i18n/locales/es.js.map +1 -1
  128. package/dist/i18n/locales/fr.d.ts +19 -14
  129. package/dist/i18n/locales/fr.d.ts.map +1 -1
  130. package/dist/i18n/locales/fr.js +19 -14
  131. package/dist/i18n/locales/fr.js.map +1 -1
  132. package/dist/i18n/locales/hi.d.ts +19 -14
  133. package/dist/i18n/locales/hi.d.ts.map +1 -1
  134. package/dist/i18n/locales/hi.js +19 -14
  135. package/dist/i18n/locales/hi.js.map +1 -1
  136. package/dist/i18n/locales/it.d.ts +5 -0
  137. package/dist/i18n/locales/it.d.ts.map +1 -1
  138. package/dist/i18n/locales/it.js +6 -0
  139. package/dist/i18n/locales/it.js.map +1 -1
  140. package/dist/i18n/locales/ja.d.ts +19 -14
  141. package/dist/i18n/locales/ja.d.ts.map +1 -1
  142. package/dist/i18n/locales/ja.js +19 -14
  143. package/dist/i18n/locales/ja.js.map +1 -1
  144. package/dist/i18n/locales/nl.d.ts +19 -14
  145. package/dist/i18n/locales/nl.d.ts.map +1 -1
  146. package/dist/i18n/locales/nl.js +19 -14
  147. package/dist/i18n/locales/nl.js.map +1 -1
  148. package/dist/i18n/locales/pl.d.ts +19 -14
  149. package/dist/i18n/locales/pl.d.ts.map +1 -1
  150. package/dist/i18n/locales/pl.js +19 -14
  151. package/dist/i18n/locales/pl.js.map +1 -1
  152. package/dist/i18n/locales/pt.d.ts +19 -14
  153. package/dist/i18n/locales/pt.d.ts.map +1 -1
  154. package/dist/i18n/locales/pt.js +19 -14
  155. package/dist/i18n/locales/pt.js.map +1 -1
  156. package/dist/i18n/locales/ro.d.ts +19 -14
  157. package/dist/i18n/locales/ro.d.ts.map +1 -1
  158. package/dist/i18n/locales/ro.js +19 -14
  159. package/dist/i18n/locales/ro.js.map +1 -1
  160. package/dist/i18n/locales/ru.d.ts +19 -14
  161. package/dist/i18n/locales/ru.d.ts.map +1 -1
  162. package/dist/i18n/locales/ru.js +19 -14
  163. package/dist/i18n/locales/ru.js.map +1 -1
  164. package/dist/i18n/locales/sq.d.ts +19 -14
  165. package/dist/i18n/locales/sq.d.ts.map +1 -1
  166. package/dist/i18n/locales/sq.js +19 -14
  167. package/dist/i18n/locales/sq.js.map +1 -1
  168. package/dist/i18n/locales/sv.d.ts +19 -14
  169. package/dist/i18n/locales/sv.d.ts.map +1 -1
  170. package/dist/i18n/locales/sv.js +19 -14
  171. package/dist/i18n/locales/sv.js.map +1 -1
  172. package/dist/i18n/locales/tr.d.ts +19 -14
  173. package/dist/i18n/locales/tr.d.ts.map +1 -1
  174. package/dist/i18n/locales/tr.js +19 -14
  175. package/dist/i18n/locales/tr.js.map +1 -1
  176. package/dist/i18n/locales/zh.d.ts +19 -14
  177. package/dist/i18n/locales/zh.d.ts.map +1 -1
  178. package/dist/i18n/locales/zh.js +19 -14
  179. package/dist/i18n/locales/zh.js.map +1 -1
  180. package/dist/index.js +34 -34
  181. package/dist/locales/ar.json +19 -14
  182. package/dist/locales/de.json +19 -14
  183. package/dist/locales/el.json +19 -14
  184. package/dist/locales/en.json +5 -0
  185. package/dist/locales/es.json +19 -14
  186. package/dist/locales/fr.json +19 -14
  187. package/dist/locales/hi.json +19 -14
  188. package/dist/locales/it.json +5 -0
  189. package/dist/locales/ja.json +19 -14
  190. package/dist/locales/nl.json +19 -14
  191. package/dist/locales/pl.json +19 -14
  192. package/dist/locales/pt.json +19 -14
  193. package/dist/locales/ro.json +19 -14
  194. package/dist/locales/ru.json +19 -14
  195. package/dist/locales/sq.json +19 -14
  196. package/dist/locales/sv.json +19 -14
  197. package/dist/locales/tr.json +19 -14
  198. package/dist/locales/zh.json +19 -14
  199. package/dist/patterns/alia-assistant/index.js +1 -1
  200. package/dist/patterns/calendar/calendar-workspace.d.ts +10 -0
  201. package/dist/patterns/calendar/calendar-workspace.d.ts.map +1 -1
  202. package/dist/patterns/calendar/calendar.surface.d.ts +4 -1
  203. package/dist/patterns/calendar/calendar.surface.d.ts.map +1 -1
  204. package/dist/patterns/calendar/index.js +1 -1
  205. package/dist/patterns/marketplace-app-shell/index.js +1 -1
  206. package/dist/patterns/signature-request/index.js +1 -1
  207. package/dist/tokens.css +1 -1
  208. package/package.json +12 -12
  209. package/dist/_chunks/avatar-CkDeQOSI.js.map +0 -1
  210. package/dist/_chunks/booking-BQYFDcrz.js.map +0 -1
  211. package/dist/_chunks/calendar-workspace-D8zX9JWm.js +0 -10423
  212. package/dist/_chunks/data-table-DWOSxlsy.js.map +0 -1
  213. package/dist/_chunks/link-cell-renderer-Tswqf6BT.js +0 -778
  214. package/dist/_chunks/link-cell-renderer-Tswqf6BT.js.map +0 -1
  215. package/dist/_chunks/task-card-CTTQfPS6.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"tasks-panel-C_dVDQKJ.js","sources":["../../node_modules/lucide-react/dist/esm/icons/coins.mjs","../../node_modules/lucide-react/dist/esm/icons/gem.mjs","../../node_modules/lucide-react/dist/esm/icons/megaphone.mjs","../../node_modules/lucide-react/dist/esm/icons/tag.mjs","../../src/components/tasks-panel/tasks-panel.agent.ts","../../src/components/tasks-panel/tasks-panel.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M13.744 17.736a6 6 0 1 1-7.48-7.48\", key: \"bq4yh3\" }],\n [\"path\", { d: \"M15 6h1v4\", key: \"11y1tn\" }],\n [\"path\", { d: \"m6.134 14.768.866-.5 2 3.464\", key: \"17snzx\" }],\n [\"circle\", { cx: \"16\", cy: \"8\", r: \"6\", key: \"14bfc9\" }]\n];\nconst Coins = createLucideIcon(\"coins\", __iconNode);\n\nexport { __iconNode, Coins as default };\n//# sourceMappingURL=coins.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M10.5 3 8 9l4 13 4-13-2.5-6\", key: \"b3dvk1\" }],\n [\n \"path\",\n {\n d: \"M17 3a2 2 0 0 1 1.6.8l3 4a2 2 0 0 1 .013 2.382l-7.99 10.986a2 2 0 0 1-3.247 0l-7.99-10.986A2 2 0 0 1 2.4 7.8l2.998-3.997A2 2 0 0 1 7 3z\",\n key: \"7w4byz\"\n }\n ],\n [\"path\", { d: \"M2 9h20\", key: \"16fsjt\" }]\n];\nconst Gem = createLucideIcon(\"gem\", __iconNode);\n\nexport { __iconNode, Gem as default };\n//# sourceMappingURL=gem.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M11 6a13 13 0 0 0 8.4-2.8A1 1 0 0 1 21 4v12a1 1 0 0 1-1.6.8A13 13 0 0 0 11 14H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2z\",\n key: \"q8bfy3\"\n }\n ],\n [\"path\", { d: \"M6 14a12 12 0 0 0 2.4 7.2 2 2 0 0 0 3.2-2.4A8 8 0 0 1 10 14\", key: \"1853fq\" }],\n [\"path\", { d: \"M8 6v8\", key: \"15ugcq\" }]\n];\nconst Megaphone = createLucideIcon(\"megaphone\", __iconNode);\n\nexport { __iconNode, Megaphone as default };\n//# sourceMappingURL=megaphone.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z\",\n key: \"vktsd0\"\n }\n ],\n [\"circle\", { cx: \"7.5\", cy: \"7.5\", r: \".5\", fill: \"currentColor\", key: \"kqv944\" }]\n];\nconst Tag = createLucideIcon(\"tag\", __iconNode);\n\nexport { __iconNode, Tag as default };\n//# sourceMappingURL=tag.mjs.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — TasksPanel. */\n/* */\n/* Rail Tasks surface: read task ids + status (never note / patient), */\n/* activate a row, toggle done / dismiss a task, re-anchor the scroll on */\n/* the overdue bucket, and drive the filter bar — all through the curated */\n/* handle. In-page within the rail panel (no open/close — the rail owns */\n/* panel open state). Mirrors taskTrayAgent's safety mapping (select=read, */\n/* toggle_done=write, dismiss=destructive) plus AppointmentTimeline's */\n/* scroll capability; the stateful filter bar adds the `filter` capability */\n/* backed by `set_filter`. toggle_done and dismiss settle with the host's */\n/* answer (in client mode, after the row's fade), so a refusal reaches */\n/* the agent as a rejection. They also reject, without calling the host, */\n/* when nothing was started, including on a read-only panel. */\n/* In server-filtered panels `items` leaves out rows on their way out and */\n/* reports a ticked row's new status before the host confirms it. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { TasksPanelHandle } from './tasks-panel';\n\nexport const tasksPanelAgent: AgentAdapter<TasksPanelHandle> = {\n id: 'tasks-panel',\n // 'pick' backs select_item (non-persisting activation, matching\n // AppointmentTimeline); 'dismiss' backs dismiss; 'scroll' backs\n // jump_to_overdue (re-anchors the viewport); 'filter' backs set_filter (the\n // status / type / assignee / overdue filter bar is genuinely stateful);\n // 'view_change' backs change_scope (the patient ↔ mine segment); 'paginate'\n // backs load_more (append the next page of tasks).\n capabilities: [\n 'pick',\n 'dismiss',\n 'scroll',\n 'filter',\n 'view_change',\n 'paginate',\n ],\n state: {\n items: {\n type: 'Array<{ id: string; status: string }>',\n descriptionKey: 'ui.agent.tasksPanel.state.items',\n description:\n 'Currently-rendered tasks. Ids + status only — never task note / patient.',\n read: (handle) => handle.getItems(),\n },\n },\n actions: {\n select_item: {\n safety: 'read',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: { id: { type: 'string' } },\n required: ['id'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.selectItem',\n description: 'Activate the task with the given id.',\n invoke: (handle, args: { id: string }) => {\n handle.selectItem(args.id);\n },\n },\n toggle_done: {\n safety: 'write',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: { id: { type: 'string' } },\n required: ['id'],\n },\n // Reaches the host's data source; settles with the host's answer.\n openWorld: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.toggleDone',\n description: 'Request the host to toggle the done state of a task.',\n invoke: (handle, args: { id: string }) => handle.toggleDone(args.id),\n },\n dismiss: {\n safety: 'destructive',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: { id: { type: 'string' } },\n required: ['id'],\n },\n idempotent: true,\n // Reaches the host's data source; settles with the host's answer.\n openWorld: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.dismiss',\n description:\n 'Request the host to dismiss / remove the task with the given id.',\n invoke: (handle, args: { id: string }) => handle.dismiss(args.id),\n },\n jump_to_overdue: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.jumpToOverdue',\n description: 'Re-anchor the panel scroll on the overdue tasks.',\n invoke: (handle) => {\n handle.jumpToOverdue();\n },\n },\n set_filter: {\n safety: 'read',\n argsType:\n \"{ status?: 'todo' | 'done' | 'all'; type?: string | null; assignee?: string | null; overdueOnly?: boolean }\",\n argsSchema: {\n type: 'object',\n properties: {\n status: { type: 'string', enum: ['todo', 'done', 'all'] },\n type: { type: ['string', 'null'] },\n assignee: { type: ['string', 'null'] },\n overdueOnly: { type: 'boolean' },\n },\n },\n idempotent: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.setFilter',\n description:\n \"Set the task filters (status segment, type, assignee, overdue-only). Omitted keys are left unchanged. Unchanged values are not re-sent. In server-filtered panels, choosing status 'done' clears overdueOnly.\",\n invoke: (\n handle,\n args: {\n status?: 'todo' | 'done' | 'all';\n type?: string | null;\n assignee?: string | null;\n overdueOnly?: boolean;\n },\n ) => {\n handle.setFilter(args);\n },\n },\n change_scope: {\n safety: 'read',\n argsType: \"{ scope: 'patient' | 'mine' }\",\n argsSchema: {\n type: 'object',\n properties: { scope: { type: 'string', enum: ['patient', 'mine'] } },\n required: ['scope'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.changeScope',\n description:\n \"Switch the task scope segment between this patient ('patient') and the operator's own tasks ('mine'). The host re-feeds the items.\",\n invoke: (handle, args: { scope: 'patient' | 'mine' }) => {\n handle.changeScope(args.scope);\n },\n },\n load_more: {\n safety: 'read',\n // Requests the host to append the next page — not idempotent (each call\n // advances the page) and reaches the host data source.\n openWorld: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.loadMore',\n description: 'Request the host to append the next page of tasks.',\n invoke: (handle) => {\n handle.loadMore();\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'tasks-panel',\n description: 'Marks the TasksPanel wrapper.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description:\n 'Sourced from the id prop. Required to address a specific panel from the agent.',\n },\n item: {\n attr: 'data-task-id',\n description:\n 'Stable task id emitted on each rendered TaskCard inside the panel.',\n },\n },\n};\n","import {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport {\n Coins,\n Gem,\n ClipboardCheck,\n Megaphone,\n Pencil,\n Plus,\n Tag,\n X,\n} from 'lucide-react';\nimport { Alert } from '../alert';\nimport { Badge, type BadgeProps } from '../badge';\nimport { Button } from '../button';\nimport { IconButton } from '../button/icon-button';\nimport { ButtonGroup } from '../button-group';\nimport { PanelHeader } from '../panel-header';\nimport { Select } from '../select';\nimport { Switch } from '../switch';\nimport { Skeleton } from '../skeleton/skeleton';\nimport { EmptyState } from '../empty-state/empty-state';\nimport { TaskCard, type TaskItem } from '../task-card';\nimport { VisuallyHidden } from '../visually-hidden';\nimport { useCheckAnimation } from '../../hooks/use-check-animation';\nimport { useExitTransition } from '../../hooks/use-exit-transition';\nimport { REFLOW_ROW_CLASS, useListReflow } from '../../hooks/use-list-reflow';\nimport { useTheme } from '../../hooks/use-theme';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { tasksPanelAgent } from './tasks-panel.agent';\n\n/* -------------------------------------------------------------------- */\n/* TasksPanel */\n/* */\n/* The Tasks tool for the Control Room rail — the next surface after */\n/* AppointmentTimeline (Appointments) and NotesPanel (Notes). It is the */\n/* rail equivalent of the in-page TaskTray: a fill-mode panel that owns */\n/* its own scroll, groups a flat task list into DUE-DATE buckets */\n/* (Overdue / Today / Tomorrow / This week / Later, with Done sunk to */\n/* the bottom), pins a filter header + per-bucket headers, and fades at */\n/* each scroll edge. Unlike AppointmentTimeline it does NOT scroll a */\n/* continuous calendar stream — platform tasks are a bounded, date-ASC */\n/* list — so there is no bidirectional infinite scroll or today-anchor, */\n/* only an optional one-way `onLoadMore`. */\n/* */\n/* Each row reuses TaskCard (no reinvention); the panel adds a coloured */\n/* type Badge (the platform's primary per-task signal) + elevation via */\n/* the card's className. All visible text flows through */\n/* useTranslation('ui') against `tasksPanel.*`; only ids + status reach */\n/* the agent adapter (no PHI). */\n/* */\n/* Two filtering modes. 'client' (default) filters `items` itself. */\n/* 'server' shows `items` as the host filtered and paged them, calls the */\n/* host when the done box is clicked, and hides a row it expects to */\n/* leave until the host's list catches up. */\n/* -------------------------------------------------------------------- */\n\n/* How close (px) to the bottom edge before `onLoadMore` fires. */\nconst EDGE_LOAD_THRESHOLD = 96;\n\n/* -------------------------------------------------------------------- */\n/* Types */\n/* -------------------------------------------------------------------- */\n\n/** Which set of tasks the panel shows — the host owns the actual feed. */\nexport type TasksPanelScope = 'patient' | 'mine';\n\n/** Status segment value. Mirrors the platform `done` filter (default `todo`). */\nexport type TasksPanelStatusFilter = 'todo' | 'done' | 'all';\n\n/** Who filters the list: the panel ('client') or the host ('server'). */\nexport type TasksPanelFiltering = 'client' | 'server';\n\n/** The whole filter state, as `onFiltersChange` reports it. */\nexport interface TasksPanelFilters {\n status: TasksPanelStatusFilter;\n type: string | null;\n assignee: string | null;\n overdueOnly: boolean;\n}\n\n/**\n * Panel-local extension of the card's `TaskItem`. The extra fields here drive\n * bucketing + filtering; the row's display fields (the typed link via\n * `linkType` + `linkedLabel`, the `assigneeLabel`, `dueLabel`) live on\n * `TaskItem` and are rendered by `TaskCard` itself. The host maps the platform\n * `DoctorReminder` → this shape — composing `title` (a summary, NOT the bare\n * type), `note`, the linked entity, the assignee, and `dueLabel`.\n */\nexport interface TasksPanelItem extends TaskItem {\n /** ISO-8601 due/scheduled instant (platform `DoctorReminder.date`). Buckets + orders the list. */\n dueIso: string;\n /** System or custom task-type key (`recall` | `payment` | `collection` | `other` | `custom-*`). Drives the type filter + badge. */\n type?: string;\n /**\n * Localised type label, required for CUSTOM types (the panel resolves system\n * keys itself). Falls back to the system label for the four known keys,\n * then to \"Other\". The raw key is never shown.\n */\n typeLabel?: string;\n /**\n * Assignee id (the platform `practiceUser`). Omit ⇒ unassigned; give pool\n * tasks a shared sentinel value (e.g. `'unassigned'`) if you want the pool\n * itself filterable. Drives the assignee FILTER (exact match); the displayed\n * name is `TaskItem.assigneeLabel`.\n */\n assignee?: string;\n /** Provenance — manual vs workflow-created. Filter only. */\n createdBy?: 'user' | 'workflow';\n}\n\n/** Curated imperative handle — identifiers + structural state only, no PHI. */\nexport interface TasksPanelHandle {\n getItems: () => Array<{ id: string; status: string }>;\n selectItem: (id: string) => void;\n /**\n * Same path as a click on the done box. Resolves once the host has\n * answered (in client mode, after the row's fade) and rejects if the\n * host refuses, or if nothing was started: an unknown id, a read-only\n * panel, no `onToggleDone`, or a change to that task already pending.\n */\n toggleDone: (id: string) => Promise<void>;\n /** Same path as the row's dismiss action, and settles in the same way. */\n dismiss: (id: string) => Promise<void>;\n jumpToOverdue: () => void;\n setFilter: (next: {\n status?: TasksPanelStatusFilter;\n type?: string | null;\n assignee?: string | null;\n overdueOnly?: boolean;\n }) => void;\n /** Switch the task scope segment (patient ↔ mine). The host re-feeds items. */\n changeScope: (next: TasksPanelScope) => void;\n /** Request the host to append the next page of tasks (mirrors onLoadMore). */\n loadMore: () => void;\n}\n\ninterface FilterOption {\n /** Stable value passed back through the matching `on…Change`. */\n value: string;\n /** Localised label. */\n label: string;\n}\n\nexport interface TasksPanelProps extends Omit<\n HTMLAttributes<HTMLElement>,\n 'onClick' | 'id' | 'title'\n> {\n /** Stable instance id, surfaced as `data-component-id`. */\n id?: string;\n /** Tasks to render — any order; bucketed + sorted internally (due ASC, Done last). */\n items: TasksPanelItem[];\n /** ISO-8601 \"now\" anchor — buckets + overdue compute against it. Defaults to the current instant; stories pass a fixed value. */\n nowIso?: string;\n /** Panel heading. Defaults to the localised \"Tasks\". */\n title?: string;\n /** PanelHeader glyph. Default <ClipboardCheck />. */\n icon?: ReactNode;\n /**\n * A total the host counted, shown as given after the title (\"Tasks (42)\")\n * and read as \"42 tasks\". Omitted: nothing shown. The panel never\n * computes it.\n */\n totalCount?: number;\n /** Visual density forwarded to each TaskCard. Defaults to `sm`, matching the note and appointment rows. */\n size?: 'xs' | 'sm' | 'md';\n /**\n * 'client' (default): the panel filters `items`. 'server': the host has\n * already filtered and paged `items`; the panel shows them as given. In\n * server mode a filter control shows only when `onFiltersChange` or its\n * own `on…Change` is set, since only the host can re-query.\n */\n filtering?: TasksPanelFiltering;\n /** Fires when a row is activated. */\n onOpenTask?: (item: TasksPanelItem) => void;\n /**\n * Fires when the host should set a task's done state to `nextDone`. In\n * server mode it fires on the click. In client mode it fires on the click\n * for a row that stays in view, and once the row has faded for one that\n * leaves. Either way, the box ignores clicks until a returned promise\n * settles, and a promise that rejects puts the row back, unticked. The\n * panel does not announce a refusal: report it yourself (for example\n * `toastError` with a translated message) and rethrow, so the row still\n * rolls back.\n */\n onToggleDone?: (\n item: TasksPanelItem,\n nextDone: boolean,\n ) => void | Promise<void>;\n /** Fires when the host should open the task editor. Omit to hide the per-row edit action. */\n onEditTask?: (item: TasksPanelItem) => void;\n /**\n * Fires when the host should dismiss / remove a task. Omit to hide the\n * per-row dismiss action. In server mode it fires on the click, in client\n * mode once the row has faded. A returned promise that rejects restores\n * the row. The panel does not announce a refusal: report it yourself and\n * rethrow, as for `onToggleDone`.\n */\n onDismissTask?: (item: TasksPanelItem) => void | Promise<void>;\n /** Fires when the header \"Add\" affordance is activated. Omit to hide it. */\n onAddTask?: () => void;\n /**\n * Read-only mode — hides every write affordance (toggle / edit / dismiss /\n * add), and the handle's `toggleDone` and `dismiss` reject without calling\n * the host. Mirrors the platform gating writes behind `practice_task_edit`.\n */\n readOnly?: boolean;\n /**\n * Per-row trailing action toolbar, forwarded to each TaskCard's `actions`\n * slot. Overrides the default toggle / edit / dismiss buttons (the type Badge\n * is always prepended by the panel). Ignored when `readOnly`.\n */\n renderItemActions?: (item: TasksPanelItem) => ReactNode;\n /**\n * Extra per-row actions, rendered before the toggle / edit / dismiss\n * actions (or before `renderItemActions`, which still replaces those).\n * Not a task write, so `readOnly` does not hide them: withhold them from\n * the host side when they do not apply.\n */\n renderItemExtraActions?: (item: TasksPanelItem) => ReactNode;\n\n /* ----- Scope (host-driven feed switch) ----- */\n /** Controlled scope segment. */\n scope?: TasksPanelScope;\n /** Uncontrolled initial scope. Default `'patient'` when both scopes are available, else the only one. */\n defaultScope?: TasksPanelScope;\n /** Fires when the user switches scope — the host re-feeds `items`. */\n onScopeChange?: (next: TasksPanelScope) => void;\n /** Which scopes the segment offers. Omit ⇒ no scope segment (single-scope panel). */\n availableScopes?: TasksPanelScope[];\n\n /* ----- One-way pagination ----- */\n /** Load the next page — fired once per page when the bottom edge is reached, and via the footer button. */\n onLoadMore?: () => void;\n /** Whether more tasks exist. Defaults to `true` when `onLoadMore` is set (client mode only; server mode needs `true`). */\n hasMore?: boolean;\n /** Show the bottom loading row while the next page is fetched. */\n loadingMore?: boolean;\n /** Loading state. Skeleton rows while there are none to show; in server mode, rows already shown stay. */\n loading?: boolean;\n /** Error surface — `true` for the default error EmptyState, or a custom node. */\n error?: boolean | ReactNode;\n /** Adds a Retry action to the default error state (`error === true`). */\n onRetry?: () => void;\n\n /* ----- Filters (mirror platform TaskFilterType) ----- */\n /**\n * Show the filter header (status segment + type / assignee selects +\n * overdue toggle). Default `true`. In server mode each control also needs\n * `onFiltersChange` or its own `on…Change`.\n */\n showFilters?: boolean;\n /**\n * The host's default query: the uncontrolled start, what Clear filters\n * returns to, and what server mode judges \"filtered empty\" against.\n * Absent: To do, any type, anyone, not overdue-only.\n */\n defaultFilters?: TasksPanelFilters;\n /**\n * Once per user action, with the whole next filter state. Never fires\n * when nothing changed. Fires in both modes.\n */\n onFiltersChange?: (next: TasksPanelFilters) => void;\n /** Controlled status segment. */\n statusFilter?: TasksPanelStatusFilter;\n /** Uncontrolled initial status segment. Default `'todo'` (the platform default). */\n defaultStatusFilter?: TasksPanelStatusFilter;\n onStatusFilterChange?: (next: TasksPanelStatusFilter) => void;\n /** Task types for the type filter. Omit ⇒ no type filter. */\n typeOptions?: FilterOption[];\n /** Controlled type filter (`null`/empty ⇒ all). */\n typeFilter?: string | null;\n onTypeFilterChange?: (next: string | null) => void;\n /** Assignees for the assignee filter. Pass an explicit Unassigned option if wanted. Omit ⇒ no assignee filter. */\n assigneeOptions?: FilterOption[];\n /** Controlled assignee filter (`null`/empty ⇒ anyone). */\n assigneeFilter?: string | null;\n onAssigneeFilterChange?: (next: string | null) => void;\n /** Controlled overdue-only toggle. */\n overdueOnly?: boolean;\n /** Uncontrolled initial overdue-only state. Default `false`. */\n defaultOverdueOnly?: boolean;\n onOverdueOnlyChange?: (next: boolean) => void;\n\n /* ----- Empty ----- */\n emptyTitle?: string;\n emptyDescription?: string;\n /** CTA wired into the first-use empty state (e.g. Create task). */\n emptyAction?: { label: string; onClick: () => void };\n\n /** Accessible name for the panel region (defaults to `title`). */\n 'aria-label'?: string;\n}\n\n/* A write the host has been asked for and the list has not caught up with. */\ninterface PendingWrite {\n kind: 'done' | 'dismiss';\n /** Done only: the value the box flipped to. Absent when it only guards. */\n next?: boolean;\n /** The row leaves the current view once the write lands. */\n leaves: boolean;\n /** The host's promise has resolved. */\n settled: boolean;\n /** Loads finished when it resolved. */\n edgeAtSettle: number;\n /** The id:status list when it resolved. */\n sigAtSettle: string;\n}\n\n/* What a click or a handle call did. `started` false means nothing changed.\n `result` settles with the host's answer, and rejects when nothing started;\n the handle hands it back to its caller. */\ninterface WriteAttempt {\n started: boolean;\n result: Promise<void>;\n}\n\n/* Where focus was, so it can be put back near there when its row leaves. */\ninterface FocusRecord {\n el: HTMLElement;\n rowId: string | null;\n action: string | null;\n index: number;\n}\n\n/* What the stable agent handle reaches through to, refreshed each render. */\ninterface PanelActions {\n toggleDone: (item: TasksPanelItem) => WriteAttempt;\n dismiss: (item: TasksPanelItem) => WriteAttempt;\n onOpenTask?: (item: TasksPanelItem) => void;\n loadMore: () => void;\n changeScope: (next: TasksPanelScope) => void;\n commitFilters: (patch: Partial<TasksPanelFilters>) => void;\n serverMode: boolean;\n}\n\nconst DEFAULT_FILTERS: TasksPanelFilters = {\n status: 'todo',\n type: null,\n assignee: null,\n overdueOnly: false,\n};\n\nconst EMPTY_PENDING: ReadonlyMap<string, PendingWrite> = new Map();\nconst EMPTY_HIDDEN: ReadonlySet<string> = new Set();\n\n/* One string per list state that changes when an id or a status does. */\nfunction sigOf(items: readonly TasksPanelItem[]): string {\n return items.map((i) => `${i.id}:${i.status ?? 'open'}`).join('|');\n}\n\nfunction sameFilters(a: TasksPanelFilters, b: TasksPanelFilters): boolean {\n return (\n a.status === b.status &&\n a.type === b.type &&\n a.assignee === b.assignee &&\n a.overdueOnly === b.overdueOnly\n );\n}\n\n/* The same query, reading an empty select value as \"any\". */\nfunction sameQuery(a: TasksPanelFilters, b: TasksPanelFilters): boolean {\n return (\n a.status === b.status &&\n (a.type || null) === (b.type || null) &&\n (a.assignee || null) === (b.assignee || null) &&\n a.overdueOnly === b.overdueOnly\n );\n}\n\n/* A rejection the caller may await; marked handled so a click that ignores\n it does not raise an unhandled-rejection warning. */\nfunction handledRejection(reason: unknown): Promise<void> {\n const rejected = Promise.reject(reason);\n rejected.catch(() => undefined);\n return rejected;\n}\n\n/* Locale digits and grouping. An unusable language tag falls back to the\n runtime default rather than throwing. */\nfunction numberFormatFor(language: string | undefined): Intl.NumberFormat {\n try {\n return new Intl.NumberFormat(language);\n } catch {\n return new Intl.NumberFormat();\n }\n}\n\n/* The host's answer as a promise, marked handled in the same way. */\nfunction handledAnswer(result: void | Promise<void>): Promise<void> {\n const answer = Promise.resolve(result);\n answer.catch(() => undefined);\n return answer;\n}\n\n/* -------------------------------------------------------------------- */\n/* CVA */\n/* -------------------------------------------------------------------- */\n\nconst rootVariants = cva(\n [\n 'ds:flex ds:flex-col ds:h-full ds:min-h-0',\n 'ds:bg-[color:var(--card)] ds:text-[color:var(--card-foreground)]',\n ].join(' '),\n {\n variants: { size: { xs: '', sm: '', md: '' } },\n defaultVariants: { size: 'sm' },\n },\n);\n\n/* Scroll region with a block-axis fade mask — identical technique to\n AppointmentTimeline, single-direction load. Disabled under reduced-motion,\n the accessible theme, and forced-colors. */\nconst scrollRegionClasses = [\n 'ds:flex-1 ds:min-h-0 ds:overflow-y-auto',\n 'ds:flex ds:flex-col ds:gap-[var(--spacing-md)]',\n 'ds:px-[var(--spacing-md)] ds:py-[var(--spacing-xs)]',\n 'ds:[--tpl-mask-top:black] ds:[--tpl-mask-bottom:black]',\n 'ds:data-[fade-top=true]:[--tpl-mask-top:transparent]',\n 'ds:data-[fade-bottom=true]:[--tpl-mask-bottom:transparent]',\n 'ds:[mask-image:linear-gradient(to_bottom,var(--tpl-mask-top)_0,black_var(--tpl-fade-distance,var(--spacing-lg)),black_calc(100%-var(--tpl-fade-distance,var(--spacing-lg))),var(--tpl-mask-bottom)_100%)]',\n 'ds:motion-reduce:[mask-image:none]',\n 'ds:[.theme-accessible_&]:[mask-image:none]',\n 'ds:forced-colors:[mask-image:none]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[color:var(--ring)] ds:focus-visible:[outline-offset:-2px]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n].join(' ');\n\n/* Elevation for each reused TaskCard row: the same `--shadow-card` as the\n elevated Card that NotesPanel note rows use, so tasks and notes read as one\n family. TaskCard owns its own border + radius. The scroll region clips\n `overflow-x`, so its inline gutter is `--spacing-md` to fit the shadow. */\nconst rowElevationClass = [\n 'ds:shadow-[var(--shadow-card)] ds:bg-[color:var(--card)]',\n // Declared at rest, not only while leaving: a transition added at the\n // same moment as the value it animates has nothing to move from.\n 'ds:transition-opacity ds:duration-[var(--animation-duration)]',\n 'ds:ease-[var(--ease-out)] ds:motion-reduce:transition-none',\n].join(' ');\n\n/* A row on its way out. It keeps its space until the host drops it, so the\n list settles once rather than twice. */\nconst rowLeavingClass = 'ds:opacity-0';\n\n/* Length of the tick path below, so the dash can be drawn from nothing. */\nconst TICK_LENGTH = 12;\n\n/* The leading done control. A checkbox, not a status glyph: the row can be\n completed here, which is where people reach first. Its name never\n changes; the state is carried by `aria-checked` alone. */\nfunction TaskDoneCheckbox({\n item,\n checked,\n pending,\n label,\n reduceMotion,\n onToggle,\n}: {\n item: TasksPanelItem;\n /** The value to show: the pending target while a write is in flight. */\n checked: boolean;\n /** A write is in flight, so a second click does nothing. */\n pending: boolean;\n label: string;\n reduceMotion?: boolean;\n /** Starts the write, and says whether it started and how it ended. */\n onToggle: (item: TasksPanelItem, next: boolean) => WriteAttempt;\n}) {\n const {\n checked: shown,\n drawing,\n toggle,\n } = useCheckAnimation({\n checked,\n reduceMotion,\n });\n // Read when the host answers, which is after later renders.\n const latestRef = useRef({ shown, checked, toggle });\n latestRef.current = { shown, checked, toggle };\n const tone = shown\n ? // `--accent` is magenta-700 in light, the step that clears AA there.\n 'ds:text-[color:var(--accent)]'\n : item.priority === 'high'\n ? 'ds:text-[color:var(--destructive)]'\n : 'ds:text-[color:var(--muted-foreground)]';\n return (\n <button\n type=\"button\"\n role=\"checkbox\"\n aria-checked={shown}\n aria-label={label}\n aria-disabled={pending || undefined}\n data-action=\"toggle-done\"\n data-drawing={drawing ? '' : undefined}\n onClick={() => {\n if (pending) return;\n // The host hears first, so a write it refuses on the spot never\n // ticks the box. The target is what `toggle()` would flip to.\n const next = !shown;\n const attempt = onToggle(item, next);\n if (!attempt.started) return;\n toggle();\n // A later refusal that `checked` does not show (client mode, a row\n // that stays) would leave the tick up, so take it back down.\n attempt.result.catch(() => {\n const now = latestRef.current;\n if (now.shown === next && now.checked !== next) now.toggle();\n });\n }}\n className={[\n 'ds:group/check ds:flex ds:items-center ds:justify-center ds:rounded-[var(--radius-sm)]',\n // 16px glyph + 4px each side = 24px; the accessible theme lifts it\n // to the full target size.\n 'ds:p-[var(--spacing-xs)]',\n 'ds:[.theme-accessible_&]:min-h-[var(--min-target-size)] ds:[.theme-accessible_&]:min-w-[var(--min-target-size)]',\n 'ds:hover:bg-[color:var(--muted)]/40 ds:aria-disabled:cursor-progress',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-[color:var(--ring)] ds:forced-colors:focus-visible:outline-[CanvasText]',\n tone,\n ].join(' ')}\n >\n <svg\n viewBox=\"0 0 18 18\"\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:transition-transform ds:duration-[var(--animation-duration)] ds:ease-[var(--ease-out)] ds:group-data-[drawing]/check:scale-110 ds:motion-reduce:transition-none\"\n >\n <rect\n x=\"1.5\"\n y=\"1.5\"\n width=\"15\"\n height=\"15\"\n rx=\"4\"\n className=\"ds:fill-none ds:stroke-current ds:[stroke-width:1.5]\"\n />\n {/* The tick is drawn by retracting its dash, so it sweeps on rather\n than appearing whole. */}\n <path\n d=\"M5 9.25 L7.75 12 L13 6.25\"\n strokeDashoffset={shown ? 0 : TICK_LENGTH}\n className=\"ds:fill-none ds:stroke-current ds:[stroke-width:2] ds:[stroke-linecap:round] ds:[stroke-linejoin:round] ds:[stroke-dasharray:12] ds:transition-[stroke-dashoffset] ds:duration-[var(--animation-duration)] ds:ease-[var(--ease-out)] ds:motion-reduce:transition-none\"\n />\n </svg>\n </button>\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* Type → Badge variant + icon (system keys only; custom ⇒ neutral) */\n/* -------------------------------------------------------------------- */\n\nconst SYSTEM_TYPE_META: Record<\n string,\n { variant: NonNullable<BadgeProps['variant']>; Icon: typeof Tag }\n> = {\n recall: { variant: 'info', Icon: Megaphone },\n payment: { variant: 'warning', Icon: Gem },\n collection: { variant: 'error', Icon: Coins },\n other: { variant: 'neutral', Icon: Tag },\n};\n\n/* -------------------------------------------------------------------- */\n/* Due-bucket grouping */\n/* -------------------------------------------------------------------- */\n\ntype BucketKey =\n | 'overdue'\n | 'today'\n | 'tomorrow'\n | 'thisWeek'\n | 'later'\n | 'done';\n\nconst BUCKET_ORDER: BucketKey[] = [\n 'overdue',\n 'today',\n 'tomorrow',\n 'thisWeek',\n 'later',\n 'done',\n];\n\ninterface Bucket {\n key: BucketKey;\n items: TasksPanelItem[];\n}\n\nfunction startOfDay(d: Date): Date {\n return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n}\n\n/** Boundary timestamps the buckets + the overdue notion are computed against. */\nfunction dayBoundaries(now: Date) {\n const today = startOfDay(now);\n const tomorrow = new Date(today);\n tomorrow.setDate(today.getDate() + 1);\n const dayAfter = new Date(today);\n dayAfter.setDate(today.getDate() + 2);\n // Monday-based week — start of NEXT week is the upper bound of \"This week\".\n const dow = (today.getDay() + 6) % 7;\n const nextWeek = new Date(today);\n nextWeek.setDate(today.getDate() + (7 - dow));\n return {\n startOfToday: +today,\n startOfTomorrow: +tomorrow,\n startOfDayAfter: +dayAfter,\n startOfNextWeek: +nextWeek,\n };\n}\n\nfunction bucketFor(item: TasksPanelItem, done: boolean, now: Date): BucketKey {\n if (done) return 'done';\n const { startOfToday, startOfTomorrow, startOfDayAfter, startOfNextWeek } =\n dayBoundaries(now);\n const due = +new Date(item.dueIso);\n if (due < startOfToday) return 'overdue';\n if (due < startOfTomorrow) return 'today';\n if (due < startOfDayAfter) return 'tomorrow';\n if (due < startOfNextWeek) return 'thisWeek';\n return 'later';\n}\n\n/** A task is overdue when it is not done and due before tomorrow (platform notion). */\nfunction isOverdue(item: TasksPanelItem, now: Date): boolean {\n if (item.status === 'done') return false;\n return +new Date(item.dueIso) < dayBoundaries(now).startOfTomorrow;\n}\n\nfunction groupByDueBucket(\n items: TasksPanelItem[],\n now: Date,\n isDone: (item: TasksPanelItem) => boolean,\n): Bucket[] {\n const map = new Map<BucketKey, TasksPanelItem[]>();\n for (const item of items) {\n const key = bucketFor(item, isDone(item), now);\n const list = map.get(key);\n if (list) list.push(item);\n else map.set(key, [item]);\n }\n const buckets: Bucket[] = [];\n for (const key of BUCKET_ORDER) {\n const list = map.get(key);\n if (!list || list.length === 0) continue;\n // Due ASC (most-overdue-first), mirroring the platform's ORDER BY date ASC.\n list.sort((a, b) => +new Date(a.dueIso) - +new Date(b.dueIso));\n buckets.push({ key, items: list });\n }\n return buckets;\n}\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\nexport const TasksPanel = forwardRef<HTMLElement, TasksPanelProps>(\n (\n {\n id,\n items,\n nowIso,\n title,\n icon,\n totalCount,\n size = 'sm',\n filtering = 'client',\n onOpenTask,\n onToggleDone,\n onEditTask,\n onDismissTask,\n onAddTask,\n readOnly = false,\n renderItemActions,\n renderItemExtraActions,\n scope,\n defaultScope,\n onScopeChange,\n availableScopes,\n onLoadMore,\n hasMore,\n loadingMore = false,\n loading = false,\n error = false,\n onRetry,\n showFilters = true,\n defaultFilters,\n onFiltersChange,\n statusFilter,\n defaultStatusFilter,\n onStatusFilterChange,\n typeOptions,\n typeFilter,\n onTypeFilterChange,\n assigneeOptions,\n assigneeFilter,\n onAssigneeFilterChange,\n overdueOnly,\n defaultOverdueOnly,\n onOverdueOnlyChange,\n emptyTitle,\n emptyDescription,\n emptyAction,\n className,\n 'aria-label': ariaLabel,\n ...rest\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation();\n const headingId = useId();\n const overdueSwitchId = useId();\n const heading = title ?? t('tasksPanel.title');\n const serverMode = filtering === 'server';\n /* In server mode a filter only works if the host re-queries, so a\n field with no seam (`onFiltersChange` or its own callback) is\n withheld, from the header and from the agent alike. */\n const filterSeams: Record<keyof TasksPanelFilters, boolean> = {\n status: !serverMode || !!onFiltersChange || !!onStatusFilterChange,\n type: !serverMode || !!onFiltersChange || !!onTypeFilterChange,\n assignee: !serverMode || !!onFiltersChange || !!onAssigneeFilterChange,\n overdueOnly: !serverMode || !!onFiltersChange || !!onOverdueOnlyChange,\n };\n\n // Static key lookups — every label is a literal `t()` call so the i18n\n // coverage gate can see each key (template-literal keys are invisible to it).\n const statusLabels: Record<TasksPanelStatusFilter, string> = {\n todo: t('tasksPanel.status.todo'),\n done: t('tasksPanel.status.done'),\n all: t('tasksPanel.status.all'),\n };\n const scopeLabels: Record<TasksPanelScope, string> = {\n patient: t('tasksPanel.scope.patient'),\n mine: t('tasksPanel.scope.mine'),\n };\n const bucketLabels: Record<BucketKey, string> = {\n overdue: t('tasksPanel.buckets.overdue'),\n today: t('tasksPanel.buckets.today'),\n tomorrow: t('tasksPanel.buckets.tomorrow'),\n thisWeek: t('tasksPanel.buckets.thisWeek'),\n later: t('tasksPanel.buckets.later'),\n done: t('tasksPanel.buckets.done'),\n };\n const systemTypeLabels: Record<string, string> = {\n recall: t('tasksPanel.types.recall'),\n payment: t('tasksPanel.types.payment'),\n collection: t('tasksPanel.types.collection'),\n other: t('tasksPanel.types.other'),\n };\n\n const now = useMemo(\n () => (nowIso ? new Date(nowIso) : new Date()),\n [nowIso],\n );\n\n // A count in the locale's digits and its own brackets: \"(1.234)\",\n // \"(42)\".\n const numbers = useMemo(\n () => numberFormatFor(i18n.language),\n [i18n.language],\n );\n const bracketed = (count: number): string =>\n t('tasksPanel.bracketedCount', { value: numbers.format(count) });\n\n /* ----- Controlled / uncontrolled scope state ----- */\n const [scopeState, setScopeState] = useState<TasksPanelScope>(\n defaultScope ?? availableScopes?.[0] ?? 'patient',\n );\n const currentScope = scope ?? scopeState;\n const changeScope = useCallback(\n (next: TasksPanelScope) => {\n if (scope === undefined) setScopeState(next);\n onScopeChange?.(next);\n },\n [scope, onScopeChange],\n );\n\n /* ----- Controlled / uncontrolled filter state ----- */\n const baseline = defaultFilters ?? DEFAULT_FILTERS;\n const [statusState, setStatusState] = useState<TasksPanelStatusFilter>(\n defaultStatusFilter ?? baseline.status,\n );\n const [typeState, setTypeState] = useState<string | null>(baseline.type);\n const [assigneeState, setAssigneeState] = useState<string | null>(\n baseline.assignee,\n );\n const [overdueState, setOverdueState] = useState<boolean>(\n defaultOverdueOnly ?? baseline.overdueOnly,\n );\n const currentStatus = statusFilter ?? statusState;\n const currentType = typeFilter !== undefined ? typeFilter : typeState;\n const currentAssignee =\n assigneeFilter !== undefined ? assigneeFilter : assigneeState;\n const currentOverdueOnly = overdueOnly ?? overdueState;\n // In server mode Done and Overdue never combine: the switch reads off\n // while Done is chosen.\n const effectiveOverdue = serverMode\n ? currentOverdueOnly && currentStatus !== 'done'\n : currentOverdueOnly;\n\n /* Every filter change reads the latest state from here and writes the\n result straight back, so two changes in one tick compose rather than\n the second undoing the first. Refreshed from props and state on\n every render. */\n const filtersRef = useRef<TasksPanelFilters>({\n status: currentStatus,\n type: currentType,\n assignee: currentAssignee,\n overdueOnly: currentOverdueOnly,\n });\n filtersRef.current = {\n status: currentStatus,\n type: currentType,\n assignee: currentAssignee,\n overdueOnly: currentOverdueOnly,\n };\n\n /* One path for every filter change: segments, selects, the switch,\n Clear filters and the agent. Each touched field fires its own\n callback as before; `onFiltersChange` fires once, and only when the\n state actually moved. */\n const commitFilters = (requested: Partial<TasksPanelFilters>): void => {\n const patch = Object.fromEntries(\n Object.entries(requested).filter(\n ([field]) => filterSeams[field as keyof TasksPanelFilters],\n ),\n ) as Partial<TasksPanelFilters>;\n // Every field asked for has no seam: nothing can change.\n if (\n Object.keys(requested).length > 0 &&\n Object.keys(patch).length === 0\n ) {\n return;\n }\n const prev = filtersRef.current;\n // In server mode the switch shows off while Done is chosen, so start\n // from that: changing anything else must not bring Overdue back.\n const shown =\n serverMode && prev.status === 'done' && prev.overdueOnly\n ? { ...prev, overdueOnly: false }\n : prev;\n const next: TasksPanelFilters = { ...shown, ...patch };\n const touched = new Set(Object.keys(patch));\n if (shown !== prev) touched.add('overdueOnly');\n // The server refuses Done with Overdue. Choosing Done clears Overdue;\n // asking for Overdue while Done shows resets the status to the\n // default one (To do if the default is Done).\n if (serverMode && next.status === 'done' && next.overdueOnly) {\n if (patch.status !== undefined) {\n next.overdueOnly = false;\n touched.add('overdueOnly');\n } else {\n next.status = baseline.status === 'done' ? 'todo' : baseline.status;\n touched.add('status');\n }\n }\n filtersRef.current = next;\n if (statusFilter === undefined) setStatusState(next.status);\n if (typeFilter === undefined) setTypeState(next.type);\n if (assigneeFilter === undefined) setAssigneeState(next.assignee);\n if (overdueOnly === undefined) setOverdueState(next.overdueOnly);\n if (touched.has('status')) onStatusFilterChange?.(next.status);\n if (touched.has('type')) onTypeFilterChange?.(next.type);\n if (touched.has('assignee')) onAssigneeFilterChange?.(next.assignee);\n if (touched.has('overdueOnly')) onOverdueOnlyChange?.(next.overdueOnly);\n if (!sameFilters(prev, next)) onFiltersChange?.(next);\n };\n\n // Back to the host's default query, not a hard-coded one.\n const clearFilters = (): void => commitFilters({ ...baseline });\n\n /* ----- Pending writes (server mode; client mode guards the fade) ----- */\n const [pending, setPendingState] =\n useState<ReadonlyMap<string, PendingWrite>>(EMPTY_PENDING);\n const pendingRef = useRef<ReadonlyMap<string, PendingWrite>>(EMPTY_PENDING);\n const [hidden, setHiddenState] =\n useState<ReadonlySet<string>>(EMPTY_HIDDEN);\n const hiddenRef = useRef<ReadonlySet<string>>(EMPTY_HIDDEN);\n const mountedRef = useRef(true);\n /* Client-mode writes still waiting for their fade, so the host has not\n been told yet. Closing the panel stops the fade, so it ends them. */\n const unsettledRef = useRef(new Set<(reason: unknown) => void>());\n useEffect(() => {\n mountedRef.current = true;\n const unsettled = unsettledRef.current;\n return () => {\n mountedRef.current = false;\n unsettled.forEach((reject) =>\n reject(new Error('TasksPanel: closed before the host was told.')),\n );\n unsettled.clear();\n };\n }, []);\n\n // The refs are written first, so a guard read in the same tick sees the\n // change before React re-renders.\n const updatePending = (edit: (m: Map<string, PendingWrite>) => void) => {\n const next = new Map(pendingRef.current);\n edit(next);\n pendingRef.current = next;\n setPendingState(next);\n };\n const updateHidden = (edit: (s: Set<string>) => void) => {\n const next = new Set(hiddenRef.current);\n edit(next);\n hiddenRef.current = next;\n setHiddenState(next);\n };\n\n /* ----- Filter → bucket ----- */\n const visible = useMemo(() => {\n // Server mode shows the host's rows as given, less any it has been\n // asked to drop and has not dropped yet.\n if (serverMode) return items.filter((item) => !hidden.has(item.id));\n return items.filter((item) => {\n const isDone = item.status === 'done';\n if (currentStatus === 'todo' && isDone) return false;\n if (currentStatus === 'done' && !isDone) return false;\n if (currentType && item.type !== currentType) return false;\n if (currentAssignee) {\n const assignee = item.assignee ?? '';\n if (assignee !== currentAssignee) return false;\n }\n if (currentOverdueOnly && !isOverdue(item, now)) return false;\n return true;\n });\n }, [\n serverMode,\n hidden,\n items,\n currentStatus,\n currentType,\n currentAssignee,\n currentOverdueOnly,\n now,\n ]);\n\n const buckets = useMemo(() => {\n // In server mode a ticked row that stays in view (under All) moves to\n // Done at once, before the host confirms. A row on its way out fades\n // where it is instead.\n const isDone = (item: TasksPanelItem): boolean => {\n if (serverMode) {\n const write = pending.get(item.id);\n if (\n write?.kind === 'done' &&\n write.next !== undefined &&\n !write.leaves\n ) {\n return write.next;\n }\n }\n return item.status === 'done';\n };\n return groupByDueBucket(visible, now, isDone);\n }, [visible, now, serverMode, pending]);\n\n // Display order, top to bottom.\n const orderedIds = useMemo(\n () => buckets.flatMap((bucket) => bucket.items.map((item) => item.id)),\n [buckets],\n );\n\n /* ----- Scroll region: edge fades + one-way load-more ----- */\n const scrollRef = useRef<HTMLDivElement>(null);\n const overdueHeaderRef = useRef<HTMLElement | null>(null);\n const [fadeTop, setFadeTop] = useState(false);\n const [fadeBottom, setFadeBottom] = useState(false);\n\n const updateEdges = useCallback(() => {\n const region = scrollRef.current;\n if (!region) return;\n const { scrollTop, scrollHeight, clientHeight } = region;\n setFadeTop(scrollTop > 1);\n setFadeBottom(scrollTop + clientHeight < scrollHeight - 1);\n }, []);\n\n useIsomorphicLayoutEffect(() => {\n updateEdges();\n }, [buckets, updateEdges]);\n\n useIsomorphicLayoutEffect(() => {\n const region = scrollRef.current;\n if (!region || typeof ResizeObserver === 'undefined') return undefined;\n const observer = new ResizeObserver(updateEdges);\n observer.observe(region);\n return () => observer.disconnect();\n }, [updateEdges]);\n\n // Server mode needs the host to say so; a partial page is not proof.\n const moreAvailable = serverMode\n ? hasMore === true\n : (hasMore ?? !!onLoadMore);\n\n /* Loads finished: +1 each time `loading` goes true → false without an\n error. A write that settled before a load finished can then let go. */\n const itemsRef = useRef<TasksPanelItem[]>(items);\n itemsRef.current = items;\n const itemsSig = useMemo(() => sigOf(items), [items]);\n const idsSig = useMemo(\n () => items.map((item) => item.id).join('|'),\n [items],\n );\n const idsSigRef = useRef(idsSig);\n idsSigRef.current = idsSig;\n const loadEdgesRef = useRef(0);\n const prevLoadingRef = useRef(loading);\n useEffect(() => {\n if (prevLoadingRef.current && !loading && !error) {\n loadEdgesRef.current += 1;\n }\n prevLoadingRef.current = loading;\n }, [loading, error]);\n\n /* The load-more latch: the bottom edge asks for one page, then waits\n until that page arrives (the ids change) or a reload finishes. A page\n that fails changes neither, so it does not ask again on its own. */\n const armedRef = useRef(true);\n const idsAtFireRef = useRef('');\n const edgesAtFireRef = useRef(0);\n const requestMore = (): void => {\n armedRef.current = false;\n idsAtFireRef.current = idsSigRef.current;\n edgesAtFireRef.current = loadEdgesRef.current;\n onLoadMore?.();\n };\n useEffect(() => {\n if (armedRef.current) return;\n if (\n idsSig !== idsAtFireRef.current ||\n loadEdgesRef.current > edgesAtFireRef.current\n ) {\n armedRef.current = true;\n }\n }, [idsSig, loading, error]);\n\n const handleScroll = (): void => {\n updateEdges();\n const region = scrollRef.current;\n if (!region) return;\n const { scrollTop, scrollHeight, clientHeight } = region;\n if (\n onLoadMore &&\n moreAvailable &&\n !loading &&\n !loadingMore &&\n armedRef.current &&\n scrollHeight - scrollTop - clientHeight <= EDGE_LOAD_THRESHOLD\n ) {\n requestMore();\n }\n };\n\n /* The accessible theme zeroes `--animation-duration`, so its CSS plays\n nothing — the JS must agree, or a row would sit still for the delay\n and then vanish anyway. `undefined` leaves the media query in charge. */\n const { resolvedTheme } = useTheme();\n const reduceMotion = resolvedTheme.endsWith('-accessible') || undefined;\n\n /* Closing the gap a removed row leaves: the rows below slide up rather\n than jumping, so the eye keeps its place in the list. */\n const { containerRef: reflowRef } = useListReflow<HTMLDivElement>({\n key: orderedIds.join(),\n reduceMotion,\n });\n\n /* A row leaves on two paths, which want different timing: a completed\n row waits for its tick to finish drawing, a dismissed one goes at\n once. */\n const doneExit = useExitTransition({ delayMs: 200, reduceMotion });\n const dismissExit = useExitTransition({ reduceMotion });\n const isLeaving = (rowId: string): boolean =>\n doneExit.isLeaving(rowId) || dismissExit.isLeaving(rowId);\n\n /* Whether a row ticked to `next` leaves the current view. */\n const leavesOnDone = (next: boolean): boolean => {\n const { status, overdueOnly: overdue } = filtersRef.current;\n const overdueShown = serverMode ? overdue && status !== 'done' : overdue;\n return (\n (status === 'todo' && next) ||\n (status === 'done' && !next) ||\n (overdueShown && next)\n );\n };\n\n /* Undo a write the host refused: the row comes back and the box\n reverts, because both read from `pending`. Focus stays where it is. */\n const rollback = (rowId: string): void => {\n if (pendingRef.current.has(rowId)) updatePending((m) => m.delete(rowId));\n if (hiddenRef.current.has(rowId)) updateHidden((s) => s.delete(rowId));\n doneExit.cancel(rowId);\n dismissExit.cancel(rowId);\n };\n\n /* Let go of writes the host's list has caught up with. Never keyed on\n the identity of the `items` array. */\n const reconcile = (): void => {\n const list = itemsRef.current;\n const sig = sigOf(list);\n const byId = new Map(list.map((item) => [item.id, item]));\n const dropped: string[] = [];\n const stillListed: string[] = [];\n pendingRef.current.forEach((write, rowId) => {\n const item = byId.get(rowId);\n if (!item) {\n dropped.push(rowId);\n return;\n }\n if (!write.settled) return;\n const hostAgrees =\n write.kind === 'done' && (item.status === 'done') === write.next;\n const listMoved =\n loadEdgesRef.current > write.edgeAtSettle ||\n sig !== write.sigAtSettle;\n if (hostAgrees || listMoved) {\n dropped.push(rowId);\n stillListed.push(rowId);\n }\n });\n if (dropped.length === 0) return;\n updatePending((m) => dropped.forEach((rowId) => m.delete(rowId)));\n if (dropped.some((rowId) => hiddenRef.current.has(rowId))) {\n updateHidden((s) => dropped.forEach((rowId) => s.delete(rowId)));\n }\n // The host kept the row, and the host is right: stop any fade.\n stillListed.forEach((rowId) => {\n doneExit.cancel(rowId);\n dismissExit.cancel(rowId);\n });\n };\n\n const settle = (rowId: string): void => {\n const write = pendingRef.current.get(rowId);\n if (!write) return;\n updatePending((m) =>\n m.set(rowId, {\n ...write,\n settled: true,\n edgeAtSettle: loadEdgesRef.current,\n sigAtSettle: sigOf(itemsRef.current),\n }),\n );\n // A host that updated `items` before resolving is caught here.\n reconcile();\n };\n\n useEffect(() => {\n if (serverMode) reconcile();\n // `reconcile` reads refs only; the list signature is the trigger.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [serverMode, itemsSig, loading, error]);\n\n /* Server mode: tell the host on the click, hide the row once it has\n faded, and restore it if the host says no. */\n const startServerWrite = (\n item: TasksPanelItem,\n write: PendingWrite,\n call: () => void | Promise<void>,\n exit: typeof doneExit,\n ): WriteAttempt => {\n const rowId = item.id;\n updatePending((m) => m.set(rowId, write));\n let result: void | Promise<void>;\n try {\n result = call();\n } catch (err) {\n rollback(rowId);\n return { started: false, result: handledRejection(err) };\n }\n if (write.leaves) {\n exit.leave(rowId, () => {\n if (pendingRef.current.has(rowId)) updateHidden((s) => s.add(rowId));\n });\n }\n const hostPromise = Promise.resolve(result);\n hostPromise.then(\n () => {\n if (mountedRef.current) settle(rowId);\n },\n () => {\n if (mountedRef.current) rollback(rowId);\n },\n );\n return { started: true, result: hostPromise };\n };\n\n /* A write that did not start. The handle hands this back, so an agent\n learns nothing changed; a click ignores it. */\n const refuse = (reason: string): WriteAttempt => ({\n started: false,\n result: handledRejection(new Error(`TasksPanel: ${reason}`)),\n });\n\n /* Drop a row's guard once the host has answered. */\n const release = (rowId: string): void => {\n if (mountedRef.current && pendingRef.current.has(rowId)) {\n updatePending((m) => m.delete(rowId));\n }\n };\n\n /* Client mode tells the host once the row has faded. The caller gets a\n promise that settles with the host's answer then. */\n const tellAfterExit = (\n rowId: string,\n exit: typeof doneExit,\n call: () => void | Promise<void>,\n ): Promise<void> => {\n let resolve!: () => void;\n let reject!: (reason: unknown) => void;\n const answer = new Promise<void>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n answer.catch(() => undefined);\n unsettledRef.current.add(reject);\n exit.leave(rowId, () => {\n unsettledRef.current.delete(reject);\n let result: void | Promise<void>;\n try {\n result = call();\n } catch (err) {\n release(rowId);\n reject(err);\n return;\n }\n Promise.resolve(result).then(\n () => {\n release(rowId);\n resolve();\n },\n (err: unknown) => {\n release(rowId);\n reject(err);\n },\n );\n });\n return answer;\n };\n\n const runToggleDone = (\n item: TasksPanelItem,\n nextFromBox?: boolean,\n ): WriteAttempt => {\n if (readOnly) return refuse('the panel is read-only.');\n if (!onToggleDone) return refuse('the host gave no onToggleDone.');\n const rowId = item.id;\n if (pendingRef.current.has(rowId)) {\n return refuse('a change to this task is already pending.');\n }\n const next = nextFromBox ?? item.status !== 'done';\n const leaves = leavesOnDone(next);\n if (serverMode) {\n return startServerWrite(\n item,\n {\n kind: 'done',\n next,\n leaves,\n settled: false,\n edgeAtSettle: 0,\n sigAtSettle: '',\n },\n () => onToggleDone(item, next),\n doneExit,\n );\n }\n // Client mode: a row that stays is told at once; a row that leaves\n // fades first, then the host is told.\n if (!leaves) {\n let result: void | Promise<void>;\n try {\n result = onToggleDone(item, next);\n } catch (err) {\n return { started: false, result: handledRejection(err) };\n }\n if (result instanceof Promise) {\n // Hold the box until the host answers. No `next`: the box keeps\n // its own optimistic tick, and drops it if the host refuses.\n updatePending((m) =>\n m.set(rowId, {\n kind: 'done',\n leaves,\n settled: false,\n edgeAtSettle: 0,\n sigAtSettle: '',\n }),\n );\n result.then(\n () => release(rowId),\n () => release(rowId),\n );\n }\n return { started: true, result: handledAnswer(result) };\n }\n updatePending((m) =>\n m.set(rowId, {\n kind: 'done',\n next,\n leaves,\n settled: false,\n edgeAtSettle: 0,\n sigAtSettle: '',\n }),\n );\n return {\n started: true,\n result: tellAfterExit(rowId, doneExit, () => onToggleDone(item, next)),\n };\n };\n\n const runDismiss = (item: TasksPanelItem): WriteAttempt => {\n if (readOnly) return refuse('the panel is read-only.');\n if (!onDismissTask) return refuse('the host gave no onDismissTask.');\n const rowId = item.id;\n if (pendingRef.current.has(rowId)) {\n return refuse('a change to this task is already pending.');\n }\n const write: PendingWrite = {\n kind: 'dismiss',\n leaves: true,\n settled: false,\n edgeAtSettle: 0,\n sigAtSettle: '',\n };\n if (serverMode) {\n return startServerWrite(\n item,\n write,\n () => onDismissTask(item),\n dismissExit,\n );\n }\n // Client mode guards the row while it fades and the host answers.\n updatePending((m) => m.set(rowId, write));\n return {\n started: true,\n result: tellAfterExit(rowId, dismissExit, () => onDismissTask(item)),\n };\n };\n\n const jumpToOverdue = useCallback(() => {\n const region = scrollRef.current;\n const el = overdueHeaderRef.current;\n if (!region || !el) {\n region?.scrollTo({ top: 0 });\n return;\n }\n const delta =\n el.getBoundingClientRect().top - region.getBoundingClientRect().top;\n region.scrollTo({ top: region.scrollTop + delta });\n }, []);\n\n /* ----- Focus rescue ----- */\n /* When the focused row leaves, focus falls to the page body. Put it on\n the same control in the row that took its place, then the row\n above, then the scroll region, then the chosen status. A row that\n only moved (to another bucket) is followed instead. */\n const innerRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => innerRef.current as HTMLElement, []);\n const focusRef = useRef<FocusRecord | null>(null);\n const orderedIdsRef = useRef<string[]>(orderedIds);\n orderedIdsRef.current = orderedIds;\n\n useEffect(() => {\n const root = innerRef.current;\n if (!root) return undefined;\n const onFocusIn = (event: FocusEvent) => {\n const el = event.target;\n if (!(el instanceof HTMLElement)) return;\n const rowId =\n el.closest<HTMLElement>('[data-task-id]')?.dataset.taskId ?? null;\n focusRef.current = {\n el,\n rowId,\n action:\n el.closest<HTMLElement>('[data-action]')?.dataset.action ?? null,\n index: rowId ? orderedIdsRef.current.indexOf(rowId) : -1,\n };\n };\n const onFocusOut = (event: FocusEvent) => {\n const to = event.relatedTarget;\n if (to instanceof Node) {\n if (!root.contains(to)) focusRef.current = null;\n return;\n }\n // No target: a click on empty space, or the row being removed. Decide\n // after the render: a removed row is rescued by then, and one still\n // here but unfocused was left by the user (a window switch keeps it).\n const from = event.target;\n queueMicrotask(() => {\n const record = focusRef.current;\n if (\n record &&\n record.el === from &&\n record.el.isConnected &&\n document.activeElement !== record.el\n ) {\n focusRef.current = null;\n }\n });\n };\n root.addEventListener('focusin', onFocusIn);\n root.addEventListener('focusout', onFocusOut);\n return () => {\n root.removeEventListener('focusin', onFocusIn);\n root.removeEventListener('focusout', onFocusOut);\n };\n }, []);\n\n useIsomorphicLayoutEffect(() => {\n const record = focusRef.current;\n const root = innerRef.current;\n if (!record || !root) return;\n if (record.el.isConnected) {\n // Keep the position current while the row is still here.\n if (record.rowId) {\n record.index = orderedIdsRef.current.indexOf(record.rowId);\n }\n return;\n }\n focusRef.current = null;\n const active = document.activeElement;\n if (active && active !== document.body) return;\n const ids = orderedIdsRef.current;\n const inRow = (rowId: string | undefined): HTMLElement | null =>\n rowId && record.action\n ? root.querySelector<HTMLElement>(\n `[data-task-id=\"${CSS.escape(rowId)}\"] [data-action=\"${CSS.escape(record.action)}\"]`,\n )\n : null;\n const moved = record.rowId ? inRow(record.rowId) : null;\n const target =\n moved ??\n (record.rowId && record.index >= 0\n ? (inRow(ids[record.index]) ?? inRow(ids[record.index - 1]))\n : null) ??\n root.querySelector<HTMLElement>('[data-tasks-panel-region]') ??\n root.querySelector<HTMLElement>(\n '[data-status-filter][aria-pressed=\"true\"]',\n );\n target?.focus();\n });\n\n /* ----- Agent handle ----- */\n /* Stable for the life of the panel: everything is read through refs, so\n a registered handle never goes stale and never re-registers. */\n const actionsRef = useRef<PanelActions | null>(null);\n actionsRef.current = {\n toggleDone: (item) => runToggleDone(item),\n dismiss: (item) => runDismiss(item),\n onOpenTask,\n loadMore: requestMore,\n changeScope,\n commitFilters,\n serverMode,\n };\n const handle = useMemo<TasksPanelHandle>(() => {\n const actions = (): PanelActions => actionsRef.current!;\n const noTask = (targetId: string): Promise<void> =>\n handledRejection(new Error(`TasksPanel: no task \"${targetId}\".`));\n return {\n getItems: () => {\n if (!actions().serverMode) {\n return itemsRef.current.map((i) => ({\n id: i.id,\n status: i.status ?? 'open',\n }));\n }\n return itemsRef.current\n .filter((i) => !hiddenRef.current.has(i.id))\n .map((i) => {\n const write = pendingRef.current.get(i.id);\n const status =\n write?.kind === 'done' && write.next !== undefined\n ? write.next\n ? 'done'\n : 'open'\n : (i.status ?? 'open');\n return { id: i.id, status };\n });\n },\n selectItem: (targetId) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) actions().onOpenTask?.(found);\n },\n toggleDone: (targetId) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (!found) return noTask(targetId);\n return actions().toggleDone(found).result;\n },\n dismiss: (targetId) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (!found) return noTask(targetId);\n return actions().dismiss(found).result;\n },\n jumpToOverdue,\n setFilter: (next) => {\n const patch: Partial<TasksPanelFilters> = {};\n if (next.status !== undefined) patch.status = next.status;\n if (next.type !== undefined) patch.type = next.type;\n if (next.assignee !== undefined) patch.assignee = next.assignee;\n if (next.overdueOnly !== undefined) {\n patch.overdueOnly = next.overdueOnly;\n }\n actions().commitFilters(patch);\n },\n changeScope: (next) => actions().changeScope(next),\n loadMore: () => actions().loadMore(),\n };\n }, [jumpToOverdue]);\n useAgentRegistration(tasksPanelAgent, handle, id);\n\n /* ----- Row rendering ----- */\n const renderTypeBadge = (item: TasksPanelItem): ReactNode => {\n if (!item.type) return null;\n const meta = SYSTEM_TYPE_META[item.type];\n const variant = meta?.variant ?? 'neutral';\n const Icon = meta?.Icon ?? Tag;\n // Never the raw key: a custom type with no label reads \"Other\".\n const label =\n item.typeLabel ||\n systemTypeLabels[item.type] ||\n t('tasksPanel.types.other');\n return (\n <Badge\n variant={variant}\n size=\"sm\"\n leading={<Icon aria-hidden=\"true\" />}\n >\n {label}\n </Badge>\n );\n };\n\n const defaultActions = (item: TasksPanelItem): ReactNode => {\n if (readOnly) return null;\n return (\n <>\n {onEditTask ? (\n <IconButton\n icon={<Pencil />}\n intent=\"ghost\"\n size=\"sm\"\n aria-label={t('tasksPanel.edit')}\n data-action=\"edit-task\"\n onClick={() => onEditTask(item)}\n />\n ) : null}\n {onDismissTask ? (\n <IconButton\n icon={<X />}\n intent=\"ghost\"\n size=\"sm\"\n aria-label={t('tasksPanel.dismiss')}\n data-action=\"dismiss-task\"\n onClick={() => {\n runDismiss(item);\n }}\n />\n ) : null}\n </>\n );\n };\n\n const renderRowActions = (item: TasksPanelItem): ReactNode => {\n const extra = renderItemExtraActions?.(item) ?? null;\n const custom = !readOnly ? renderItemActions?.(item) : null;\n const trailing = custom ?? defaultActions(item);\n const badge = renderTypeBadge(item);\n if (!badge && !extra && !trailing) return undefined;\n return (\n <>\n {badge}\n {extra}\n {trailing}\n </>\n );\n };\n\n const onBoxToggle = (item: TasksPanelItem, next: boolean): WriteAttempt =>\n runToggleDone(item, next);\n\n /* ----- Body branches ----- */\n const skeletonRow = (key: string) => (\n <div\n key={key}\n aria-hidden=\"true\"\n className=\"ds:px-[var(--spacing-sm)] ds:py-[var(--spacing-xs)]\"\n >\n <Skeleton variant=\"rectangular\" height=\"3.5rem\" />\n </div>\n );\n\n const errorBody = (\n <div className=\"ds:flex-1 ds:min-h-0 ds:p-[var(--spacing-md)]\">\n {typeof error === 'boolean' ? (\n <EmptyState\n variant=\"error\"\n size=\"sm\"\n title={t('tasksPanel.error.title')}\n description={t('tasksPanel.error.description')}\n primaryAction={\n onRetry\n ? { label: t('emptyState.error.cta'), onClick: onRetry }\n : undefined\n }\n />\n ) : (\n error\n )}\n </div>\n );\n\n // The skeletons are hidden from assistive tech; the status region below\n // says \"Loading\" for them.\n const skeletonBody = (\n <div className=\"ds:flex-1 ds:min-h-0 ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n {[0, 1, 2, 3].map((i) => skeletonRow(`skeleton-${i}`))}\n </div>\n );\n\n const firstUseBody = (\n <div className=\"ds:flex-1 ds:min-h-0 ds:p-[var(--spacing-md)]\">\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={emptyTitle ?? t('tasksPanel.empty.title')}\n description={emptyDescription ?? t('tasksPanel.empty.description')}\n primaryAction={emptyAction}\n />\n </div>\n );\n\n const anyFilterSeam = Object.values(filterSeams).some(Boolean);\n const filteredEmptyBody = (\n <div className=\"ds:flex-1 ds:min-h-0 ds:p-[var(--spacing-md)]\">\n <EmptyState\n variant=\"no-results\"\n size=\"sm\"\n title={t('tasksPanel.filteredEmpty.title')}\n description={t('tasksPanel.filteredEmpty.description')}\n primaryAction={\n anyFilterSeam\n ? {\n label: t('tasksPanel.filteredEmpty.clear'),\n onClick: clearFilters,\n }\n : undefined\n }\n />\n </div>\n );\n\n // Server mode only: an error while rows are showing sits above them.\n const inlineError =\n serverMode && error ? (\n <div className=\"ds:shrink-0 ds:px-[var(--spacing-md)] ds:pt-[var(--spacing-xs)]\">\n {typeof error === 'boolean' ? (\n <Alert variant=\"error\">\n <Alert.Title as=\"p\">{t('tasksPanel.error.title')}</Alert.Title>\n {onRetry ? (\n <Alert.Action>\n <Button intent=\"outline\" size=\"sm\" onClick={onRetry}>\n {t('emptyState.error.cta')}\n </Button>\n </Alert.Action>\n ) : null}\n </Alert>\n ) : (\n error\n )}\n </div>\n ) : null;\n\n const listBody = (\n <>\n {inlineError}\n <div\n ref={(node) => {\n scrollRef.current = node;\n reflowRef.current = node;\n }}\n // The scroll region must be keyboard-focusable so arrow / Home / End\n // can drive it (axe scrollable-region-focusable).\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={0}\n onScroll={handleScroll}\n data-tasks-panel-region=\"\"\n data-fade-top={fadeTop ? 'true' : undefined}\n data-fade-bottom={fadeBottom ? 'true' : undefined}\n className={scrollRegionClasses}\n >\n <ol\n aria-busy={loading || undefined}\n className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-md)] ds:p-0\"\n >\n {buckets.map((bucket) => (\n <li\n key={bucket.key}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]\"\n >\n <BucketHeader\n bucketKey={bucket.key}\n countLabel={bracketed(bucket.items.length)}\n // A partial page would give a wrong count.\n showCount={!(serverMode && hasMore === true)}\n label={bucketLabels[bucket.key]}\n headerRef={\n bucket.key === 'overdue' ? overdueHeaderRef : undefined\n }\n reflowId={`bucket-${bucket.key}`}\n leaving={bucket.items.every((row) => isLeaving(row.id))}\n />\n <ul className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-0\">\n {bucket.items.map((item) => (\n <TaskCard\n key={item.id}\n item={item}\n size={size}\n onActivate={\n onOpenTask ? () => onOpenTask(item) : undefined\n }\n actions={renderRowActions(item)}\n leading={\n onToggleDone && !readOnly ? (\n <TaskDoneCheckbox\n item={item}\n checked={\n pending.get(item.id)?.next ??\n item.status === 'done'\n }\n pending={pending.has(item.id)}\n label={t('tasksPanel.doneItem', {\n title: item.title,\n })}\n reduceMotion={reduceMotion}\n onToggle={onBoxToggle}\n />\n ) : undefined\n }\n className={`${rowElevationClass} ${REFLOW_ROW_CLASS}${\n isLeaving(item.id) ? ` ${rowLeavingClass}` : ''\n }`}\n data-leaving={isLeaving(item.id) ? '' : undefined}\n data-reflow-id={item.id}\n data-task-id={item.id}\n />\n ))}\n </ul>\n </li>\n ))}\n </ol>\n {loadingMore ? skeletonRow('loading-more') : null}\n {moreAvailable && onLoadMore && !loading ? (\n <div className=\"ds:flex ds:justify-center ds:py-[var(--spacing-sm)]\">\n {/* Stays mounted while the page loads, without `disabled`, so\n focus is not thrown out of the panel. */}\n <Button\n intent=\"ghost\"\n size=\"sm\"\n aria-busy={loadingMore || undefined}\n aria-disabled={loadingMore || undefined}\n onClick={() => {\n if (loadingMore) return;\n requestMore();\n }}\n >\n {t('tasksPanel.loadMore')}\n </Button>\n </div>\n ) : null}\n </div>\n </>\n );\n\n let body: ReactNode;\n if (serverMode) {\n const anyUnsettled = [...pending.values()].some((w) => !w.settled);\n // Filtered empty means \"not the default query\", so an empty default\n // query reads as first use rather than offering Clear filters.\n const anyFilter = !sameQuery(\n {\n status: currentStatus,\n type: currentType,\n assignee: currentAssignee,\n overdueOnly: effectiveOverdue,\n },\n baseline,\n );\n if (error && visible.length === 0) body = errorBody;\n else if (visible.length === 0 && (loading || anyUnsettled)) {\n body = skeletonBody;\n } else if (visible.length === 0) {\n body = anyFilter ? filteredEmptyBody : firstUseBody;\n } else body = listBody;\n } else if (error) body = errorBody;\n else if (loading) body = skeletonBody;\n else if (items.length === 0) body = firstUseBody;\n else if (visible.length === 0) body = filteredEmptyBody;\n else body = listBody;\n\n /* One live region for the panel's whole life, filled a render after it\n mounts: a region inserted already holding its text is often not read. */\n const skeletonShown = body === skeletonBody;\n const [loadingSaid, setLoadingSaid] = useState(false);\n useEffect(() => {\n setLoadingSaid(skeletonShown);\n }, [skeletonShown]);\n\n /* ----- Header ----- */\n // The host's total, shown as given. The bracketed figure is for the\n // eye; a screen reader hears \"42 tasks\" instead.\n const headerTitle: ReactNode =\n totalCount === undefined ? (\n heading\n ) : (\n <>\n {heading}\n <span\n aria-hidden=\"true\"\n data-total-count=\"\"\n className=\"ds:ms-[var(--spacing-2xs)] ds:text-[color:var(--muted-foreground)]\"\n >\n {bracketed(totalCount)}\n </span>\n <VisuallyHidden>\n {` ${t('tasksPanel.totalCount', { count: totalCount })}`}\n </VisuallyHidden>\n </>\n );\n\n /* ----- Filter header ----- */\n const showScopeSegment = (availableScopes?.length ?? 0) > 1;\n const statusValues: TasksPanelStatusFilter[] = ['todo', 'done', 'all'];\n\n // Add-task affordance lives in the PanelHeader action cluster (inline-end of\n // the title row); the rail injects the favourite / close after it.\n const headerActions =\n onAddTask && !readOnly ? (\n <IconButton\n icon={<Plus />}\n intent=\"outline\"\n size=\"sm\"\n aria-label={t('tasksPanel.add')}\n data-action=\"add-task\"\n onClick={onAddTask}\n />\n ) : undefined;\n\n const showStatusFilter = filterSeams.status;\n const showTypeFilter = !!typeOptions?.length && filterSeams.type;\n const showAssigneeFilter =\n !!assigneeOptions?.length && filterSeams.assignee;\n const showOverdueFilter = filterSeams.overdueOnly;\n const filtersShown =\n showFilters &&\n (showStatusFilter ||\n showTypeFilter ||\n showAssigneeFilter ||\n showOverdueFilter);\n\n // Scope segment + filter controls share the PanelHeader filters row, stacked\n // so the scope segment keeps its own line above the filter cluster.\n const headerFilters =\n showScopeSegment || filtersShown ? (\n <div className=\"ds:flex ds:w-full ds:flex-col ds:gap-[var(--spacing-sm)]\">\n {showScopeSegment ? (\n <ButtonGroup label={t('tasksPanel.scope.label')}>\n {availableScopes!.map((value) => {\n const active = currentScope === value;\n return (\n <Button\n key={value}\n intent={active ? 'primary' : 'outline'}\n size=\"sm\"\n aria-pressed={active}\n onClick={() => changeScope(value)}\n >\n {scopeLabels[value]}\n </Button>\n );\n })}\n </ButtonGroup>\n ) : null}\n\n {filtersShown ? (\n <div className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-sm)]\">\n {showStatusFilter ? (\n <ButtonGroup label={t('tasksPanel.status.label')}>\n {statusValues.map((value) => {\n const active = currentStatus === value;\n return (\n <Button\n key={value}\n intent={active ? 'primary' : 'outline'}\n size=\"sm\"\n aria-pressed={active}\n data-status-filter={value}\n onClick={() => commitFilters({ status: value })}\n >\n {statusLabels[value]}\n </Button>\n );\n })}\n </ButtonGroup>\n ) : null}\n\n {showTypeFilter ? (\n <Select\n size=\"sm\"\n clearable\n aria-label={t('tasksPanel.type.label')}\n placeholder={t('tasksPanel.type.placeholder')}\n options={typeOptions}\n value={currentType ?? ''}\n onValueChange={(value) =>\n commitFilters({ type: value || null })\n }\n />\n ) : null}\n\n {showAssigneeFilter ? (\n <Select\n size=\"sm\"\n clearable\n aria-label={t('tasksPanel.assignee.label')}\n placeholder={t('tasksPanel.assignee.placeholder')}\n options={assigneeOptions}\n value={currentAssignee ?? ''}\n onValueChange={(value) =>\n commitFilters({ assignee: value || null })\n }\n />\n ) : null}\n\n {showOverdueFilter ? (\n <Switch\n id={overdueSwitchId}\n size=\"sm\"\n label={t('tasksPanel.overdueOnly')}\n checked={effectiveOverdue}\n disabled={serverMode && currentStatus === 'done'}\n onCheckedChange={(next) =>\n commitFilters({ overdueOnly: next })\n }\n />\n ) : null}\n </div>\n ) : null}\n </div>\n ) : undefined;\n\n return (\n <section\n ref={innerRef}\n data-component=\"tasks-panel\"\n data-component-id={id}\n aria-labelledby={ariaLabel ? undefined : headingId}\n aria-label={ariaLabel}\n className={rootVariants({ size, className })}\n {...rest}\n >\n <PanelHeader\n title={headerTitle}\n titleTooltip={\n totalCount === undefined\n ? undefined\n : t('tasksPanel.titleWithCount', {\n title: heading,\n value: numbers.format(totalCount),\n })\n }\n icon={icon ?? <ClipboardCheck />}\n headingId={headingId}\n actions={headerActions}\n filters={headerFilters}\n />\n\n <p role=\"status\" className=\"ds:sr-only\">\n {loadingSaid ? t('common.loading') : null}\n </p>\n {body}\n </section>\n );\n },\n);\n\nTasksPanel.displayName = 'TasksPanel';\n\n/* -------------------------------------------------------------------- */\n/* Bucket header — sticky label per due bucket */\n/* -------------------------------------------------------------------- */\n\ninterface BucketHeaderProps {\n bucketKey: BucketKey;\n /** The bucket's count, formatted and bracketed for the locale. */\n countLabel: string;\n /** Off while the list is a partial page, when the count would be wrong. */\n showCount?: boolean;\n label: string;\n headerRef?: React.MutableRefObject<HTMLElement | null>;\n /** Tracked by `useListReflow` so the header travels with its rows. */\n reflowId?: string;\n /** The bucket's last row is on its way out, so the header goes too. */\n leaving?: boolean;\n}\n\nfunction BucketHeader({\n bucketKey,\n countLabel,\n showCount = true,\n label,\n headerRef,\n reflowId,\n leaving = false,\n}: BucketHeaderProps): ReactNode {\n // Overdue is tinted destructive, Today brand (+ a decorative leading dot);\n // both clear AA on the --card surface in every theme (verified via axe on the\n // stories). z-[2] sits ABOVE the reused TaskCard's z-[1] action overlay so the\n // sticky header is never painted under a card scrolling beneath it.\n const tone =\n bucketKey === 'overdue'\n ? 'ds:text-[color:var(--destructive)] ds:font-semibold'\n : bucketKey === 'today'\n ? 'ds:text-[color:var(--primary)] ds:font-semibold'\n : 'ds:text-[color:var(--muted-foreground)]';\n return (\n <div\n ref={headerRef as React.Ref<HTMLDivElement>}\n data-bucket={bucketKey}\n data-reflow-id={reflowId}\n data-leaving={leaving ? '' : undefined}\n className={[\n 'ds:sticky ds:top-0 ds:z-[2] ds:bg-[color:var(--card)] ds:py-[var(--spacing-2xs)]',\n 'ds:flex ds:items-center ds:gap-[var(--spacing-2xs)] type-eyebrow',\n // A header travels with its bucket, and leaves with it: a heading\n // left standing over nothing, or snapping while its rows glide,\n // reads as two lists rather than one.\n REFLOW_ROW_CLASS,\n 'ds:transition-opacity ds:duration-[var(--animation-duration)]',\n 'ds:ease-[var(--ease-out)] ds:motion-reduce:transition-none',\n leaving ? rowLeavingClass : '',\n tone,\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {bucketKey === 'today' ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:size-1.5 ds:shrink-0 ds:rounded-[var(--radius-full)] ds:bg-[color:var(--primary)]\"\n />\n ) : null}\n {label}\n {showCount ? (\n <span\n data-bucket-count=\"\"\n className=\"ds:text-[color:var(--muted-foreground)]\"\n >\n {countLabel}\n </span>\n ) : null}\n </div>\n );\n}\n\n/** Re-export of the size variant union for downstream typing. */\nexport type TasksPanelSize = NonNullable<\n VariantProps<typeof rootVariants>['size']\n>;\n"],"names":["__iconNode","Coins","createLucideIcon","Gem","Megaphone","Tag","tasksPanelAgent","handle","args","EDGE_LOAD_THRESHOLD","DEFAULT_FILTERS","EMPTY_PENDING","EMPTY_HIDDEN","sigOf","items","i","sameFilters","a","b","sameQuery","handledRejection","reason","rejected","numberFormatFor","language","handledAnswer","result","answer","rootVariants","cva","scrollRegionClasses","rowElevationClass","rowLeavingClass","TICK_LENGTH","TaskDoneCheckbox","item","checked","pending","label","reduceMotion","onToggle","shown","drawing","toggle","useCheckAnimation","latestRef","useRef","tone","jsx","next","attempt","now","jsxs","SYSTEM_TYPE_META","BUCKET_ORDER","startOfDay","d","dayBoundaries","today","tomorrow","dayAfter","dow","nextWeek","bucketFor","done","startOfToday","startOfTomorrow","startOfDayAfter","startOfNextWeek","due","isOverdue","groupByDueBucket","isDone","map","key","list","buckets","TasksPanel","forwardRef","id","nowIso","title","icon","totalCount","size","filtering","onOpenTask","onToggleDone","onEditTask","onDismissTask","onAddTask","readOnly","renderItemActions","renderItemExtraActions","scope","defaultScope","onScopeChange","availableScopes","onLoadMore","hasMore","loadingMore","loading","error","onRetry","showFilters","defaultFilters","onFiltersChange","statusFilter","defaultStatusFilter","onStatusFilterChange","typeOptions","typeFilter","onTypeFilterChange","assigneeOptions","assigneeFilter","onAssigneeFilterChange","overdueOnly","defaultOverdueOnly","onOverdueOnlyChange","emptyTitle","emptyDescription","emptyAction","className","ariaLabel","rest","ref","t","i18n","useTranslation","headingId","useId","overdueSwitchId","heading","serverMode","filterSeams","statusLabels","scopeLabels","bucketLabels","systemTypeLabels","useMemo","numbers","bracketed","count","scopeState","setScopeState","useState","currentScope","changeScope","useCallback","baseline","statusState","setStatusState","typeState","setTypeState","assigneeState","setAssigneeState","overdueState","setOverdueState","currentStatus","currentType","currentAssignee","currentOverdueOnly","effectiveOverdue","filtersRef","commitFilters","requested","patch","field","prev","touched","clearFilters","setPendingState","pendingRef","hidden","setHiddenState","hiddenRef","mountedRef","unsettledRef","useEffect","unsettled","reject","updatePending","edit","updateHidden","visible","write","orderedIds","bucket","scrollRef","overdueHeaderRef","fadeTop","setFadeTop","fadeBottom","setFadeBottom","updateEdges","region","scrollTop","scrollHeight","clientHeight","useIsomorphicLayoutEffect","observer","moreAvailable","itemsRef","itemsSig","idsSig","idsSigRef","loadEdgesRef","prevLoadingRef","armedRef","idsAtFireRef","edgesAtFireRef","requestMore","handleScroll","resolvedTheme","useTheme","reflowRef","useListReflow","doneExit","useExitTransition","dismissExit","isLeaving","rowId","leavesOnDone","status","overdue","rollback","m","s","reconcile","sig","byId","dropped","stillListed","hostAgrees","listMoved","settle","startServerWrite","call","exit","err","hostPromise","refuse","release","tellAfterExit","resolve","res","rej","runToggleDone","nextFromBox","leaves","runDismiss","jumpToOverdue","el","delta","innerRef","useImperativeHandle","focusRef","orderedIdsRef","root","onFocusIn","event","_a","_b","onFocusOut","to","from","record","active","ids","inRow","target","actionsRef","actions","noTask","targetId","found","useAgentRegistration","renderTypeBadge","meta","variant","Icon","Badge","defaultActions","Fragment","IconButton","Pencil","X","renderRowActions","extra","trailing","badge","onBoxToggle","skeletonRow","Skeleton","errorBody","EmptyState","skeletonBody","firstUseBody","anyFilterSeam","filteredEmptyBody","inlineError","Alert","Button","listBody","node","BucketHeader","row","TaskCard","REFLOW_ROW_CLASS","body","anyUnsettled","w","anyFilter","skeletonShown","loadingSaid","setLoadingSaid","headerTitle","VisuallyHidden","showScopeSegment","statusValues","headerActions","Plus","showStatusFilter","showTypeFilter","showAssigneeFilter","showOverdueFilter","filtersShown","headerFilters","ButtonGroup","value","Select","Switch","PanelHeader","ClipboardCheck","bucketKey","countLabel","showCount","headerRef","reflowId","leaving"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}
1
+ {"version":3,"file":"tasks-panel-DbSjq_mz.js","sources":["../../node_modules/lucide-react/dist/esm/icons/coins.mjs","../../node_modules/lucide-react/dist/esm/icons/gem.mjs","../../node_modules/lucide-react/dist/esm/icons/megaphone.mjs","../../node_modules/lucide-react/dist/esm/icons/tag.mjs","../../src/components/tasks-panel/tasks-panel.agent.ts","../../src/components/tasks-panel/tasks-panel.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M13.744 17.736a6 6 0 1 1-7.48-7.48\", key: \"bq4yh3\" }],\n [\"path\", { d: \"M15 6h1v4\", key: \"11y1tn\" }],\n [\"path\", { d: \"m6.134 14.768.866-.5 2 3.464\", key: \"17snzx\" }],\n [\"circle\", { cx: \"16\", cy: \"8\", r: \"6\", key: \"14bfc9\" }]\n];\nconst Coins = createLucideIcon(\"coins\", __iconNode);\n\nexport { __iconNode, Coins as default };\n//# sourceMappingURL=coins.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M10.5 3 8 9l4 13 4-13-2.5-6\", key: \"b3dvk1\" }],\n [\n \"path\",\n {\n d: \"M17 3a2 2 0 0 1 1.6.8l3 4a2 2 0 0 1 .013 2.382l-7.99 10.986a2 2 0 0 1-3.247 0l-7.99-10.986A2 2 0 0 1 2.4 7.8l2.998-3.997A2 2 0 0 1 7 3z\",\n key: \"7w4byz\"\n }\n ],\n [\"path\", { d: \"M2 9h20\", key: \"16fsjt\" }]\n];\nconst Gem = createLucideIcon(\"gem\", __iconNode);\n\nexport { __iconNode, Gem as default };\n//# sourceMappingURL=gem.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M11 6a13 13 0 0 0 8.4-2.8A1 1 0 0 1 21 4v12a1 1 0 0 1-1.6.8A13 13 0 0 0 11 14H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2z\",\n key: \"q8bfy3\"\n }\n ],\n [\"path\", { d: \"M6 14a12 12 0 0 0 2.4 7.2 2 2 0 0 0 3.2-2.4A8 8 0 0 1 10 14\", key: \"1853fq\" }],\n [\"path\", { d: \"M8 6v8\", key: \"15ugcq\" }]\n];\nconst Megaphone = createLucideIcon(\"megaphone\", __iconNode);\n\nexport { __iconNode, Megaphone as default };\n//# sourceMappingURL=megaphone.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z\",\n key: \"vktsd0\"\n }\n ],\n [\"circle\", { cx: \"7.5\", cy: \"7.5\", r: \".5\", fill: \"currentColor\", key: \"kqv944\" }]\n];\nconst Tag = createLucideIcon(\"tag\", __iconNode);\n\nexport { __iconNode, Tag as default };\n//# sourceMappingURL=tag.mjs.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — TasksPanel. */\n/* */\n/* Rail Tasks surface: read task ids + status (never note / patient), */\n/* activate a row, toggle done / dismiss a task, re-anchor the scroll on */\n/* the overdue bucket, and drive the filter bar — all through the curated */\n/* handle. In-page within the rail panel (no open/close — the rail owns */\n/* panel open state). Mirrors taskTrayAgent's safety mapping (select=read, */\n/* toggle_done=write, dismiss=destructive) plus AppointmentTimeline's */\n/* scroll capability; the stateful filter bar adds the `filter` capability */\n/* backed by `set_filter`. toggle_done and dismiss settle with the host's */\n/* answer (in client mode, after the row's fade), so a refusal reaches */\n/* the agent as a rejection. They also reject, without calling the host, */\n/* when nothing was started, including on a read-only panel. */\n/* In server-filtered panels `items` leaves out rows on their way out and */\n/* reports a ticked row's new status before the host confirms it. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { TasksPanelHandle } from './tasks-panel';\n\nexport const tasksPanelAgent: AgentAdapter<TasksPanelHandle> = {\n id: 'tasks-panel',\n // 'pick' backs select_item (non-persisting activation, matching\n // AppointmentTimeline); 'dismiss' backs dismiss; 'scroll' backs\n // jump_to_overdue (re-anchors the viewport); 'filter' backs set_filter (the\n // status / type / assignee / overdue filter bar is genuinely stateful);\n // 'view_change' backs change_scope (the patient ↔ mine segment); 'paginate'\n // backs load_more (append the next page of tasks).\n capabilities: [\n 'pick',\n 'dismiss',\n 'scroll',\n 'filter',\n 'view_change',\n 'paginate',\n ],\n state: {\n items: {\n type: 'Array<{ id: string; status: string }>',\n descriptionKey: 'ui.agent.tasksPanel.state.items',\n description:\n 'Currently-rendered tasks. Ids + status only — never task note / patient.',\n read: (handle) => handle.getItems(),\n },\n },\n actions: {\n select_item: {\n safety: 'read',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: { id: { type: 'string' } },\n required: ['id'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.selectItem',\n description: 'Activate the task with the given id.',\n invoke: (handle, args: { id: string }) => {\n handle.selectItem(args.id);\n },\n },\n toggle_done: {\n safety: 'write',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: { id: { type: 'string' } },\n required: ['id'],\n },\n // Reaches the host's data source; settles with the host's answer.\n openWorld: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.toggleDone',\n description: 'Request the host to toggle the done state of a task.',\n invoke: (handle, args: { id: string }) => handle.toggleDone(args.id),\n },\n dismiss: {\n safety: 'destructive',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: { id: { type: 'string' } },\n required: ['id'],\n },\n idempotent: true,\n // Reaches the host's data source; settles with the host's answer.\n openWorld: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.dismiss',\n description:\n 'Request the host to dismiss / remove the task with the given id.',\n invoke: (handle, args: { id: string }) => handle.dismiss(args.id),\n },\n jump_to_overdue: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.jumpToOverdue',\n description: 'Re-anchor the panel scroll on the overdue tasks.',\n invoke: (handle) => {\n handle.jumpToOverdue();\n },\n },\n set_filter: {\n safety: 'read',\n argsType:\n \"{ status?: 'todo' | 'done' | 'all'; type?: string | null; assignee?: string | null; overdueOnly?: boolean }\",\n argsSchema: {\n type: 'object',\n properties: {\n status: { type: 'string', enum: ['todo', 'done', 'all'] },\n type: { type: ['string', 'null'] },\n assignee: { type: ['string', 'null'] },\n overdueOnly: { type: 'boolean' },\n },\n },\n idempotent: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.setFilter',\n description:\n \"Set the task filters (status segment, type, assignee, overdue-only). Omitted keys are left unchanged. Unchanged values are not re-sent. In server-filtered panels, choosing status 'done' clears overdueOnly.\",\n invoke: (\n handle,\n args: {\n status?: 'todo' | 'done' | 'all';\n type?: string | null;\n assignee?: string | null;\n overdueOnly?: boolean;\n },\n ) => {\n handle.setFilter(args);\n },\n },\n change_scope: {\n safety: 'read',\n argsType: \"{ scope: 'patient' | 'mine' }\",\n argsSchema: {\n type: 'object',\n properties: { scope: { type: 'string', enum: ['patient', 'mine'] } },\n required: ['scope'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.changeScope',\n description:\n \"Switch the task scope segment between this patient ('patient') and the operator's own tasks ('mine'). The host re-feeds the items.\",\n invoke: (handle, args: { scope: 'patient' | 'mine' }) => {\n handle.changeScope(args.scope);\n },\n },\n load_more: {\n safety: 'read',\n // Requests the host to append the next page — not idempotent (each call\n // advances the page) and reaches the host data source.\n openWorld: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.loadMore',\n description: 'Request the host to append the next page of tasks.',\n invoke: (handle) => {\n handle.loadMore();\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'tasks-panel',\n description: 'Marks the TasksPanel wrapper.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description:\n 'Sourced from the id prop. Required to address a specific panel from the agent.',\n },\n item: {\n attr: 'data-task-id',\n description:\n 'Stable task id emitted on each rendered TaskCard inside the panel.',\n },\n },\n};\n","import {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport {\n Coins,\n Gem,\n ClipboardCheck,\n Megaphone,\n Pencil,\n Plus,\n Tag,\n X,\n} from 'lucide-react';\nimport { Alert } from '../alert';\nimport { Badge, type BadgeProps } from '../badge';\nimport { Button } from '../button';\nimport { IconButton } from '../button/icon-button';\nimport { ButtonGroup } from '../button-group';\nimport { PanelHeader } from '../panel-header';\nimport { Select } from '../select';\nimport { Switch } from '../switch';\nimport { Skeleton } from '../skeleton/skeleton';\nimport { EmptyState } from '../empty-state/empty-state';\nimport { TaskCard, type TaskItem } from '../task-card';\nimport { VisuallyHidden } from '../visually-hidden';\nimport { useCheckAnimation } from '../../hooks/use-check-animation';\nimport { useExitTransition } from '../../hooks/use-exit-transition';\nimport { REFLOW_ROW_CLASS, useListReflow } from '../../hooks/use-list-reflow';\nimport { useTheme } from '../../hooks/use-theme';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { tasksPanelAgent } from './tasks-panel.agent';\n\n/* -------------------------------------------------------------------- */\n/* TasksPanel */\n/* */\n/* The Tasks tool for the Control Room rail — the next surface after */\n/* AppointmentTimeline (Appointments) and NotesPanel (Notes). It is the */\n/* rail equivalent of the in-page TaskTray: a fill-mode panel that owns */\n/* its own scroll, groups a flat task list into DUE-DATE buckets */\n/* (Overdue / Today / Tomorrow / This week / Later, with Done sunk to */\n/* the bottom), pins a filter header + per-bucket headers, and fades at */\n/* each scroll edge. Unlike AppointmentTimeline it does NOT scroll a */\n/* continuous calendar stream — platform tasks are a bounded, date-ASC */\n/* list — so there is no bidirectional infinite scroll or today-anchor, */\n/* only an optional one-way `onLoadMore`. */\n/* */\n/* Each row reuses TaskCard (no reinvention); the panel adds a coloured */\n/* type Badge (the platform's primary per-task signal) + elevation via */\n/* the card's className. All visible text flows through */\n/* useTranslation('ui') against `tasksPanel.*`; only ids + status reach */\n/* the agent adapter (no PHI). */\n/* */\n/* Two filtering modes. 'client' (default) filters `items` itself. */\n/* 'server' shows `items` as the host filtered and paged them, calls the */\n/* host when the done box is clicked, and hides a row it expects to */\n/* leave until the host's list catches up. */\n/* -------------------------------------------------------------------- */\n\n/* How close (px) to the bottom edge before `onLoadMore` fires. */\nconst EDGE_LOAD_THRESHOLD = 96;\n\n/* -------------------------------------------------------------------- */\n/* Types */\n/* -------------------------------------------------------------------- */\n\n/** Which set of tasks the panel shows — the host owns the actual feed. */\nexport type TasksPanelScope = 'patient' | 'mine';\n\n/** Status segment value. Mirrors the platform `done` filter (default `todo`). */\nexport type TasksPanelStatusFilter = 'todo' | 'done' | 'all';\n\n/** Who filters the list: the panel ('client') or the host ('server'). */\nexport type TasksPanelFiltering = 'client' | 'server';\n\n/** The whole filter state, as `onFiltersChange` reports it. */\nexport interface TasksPanelFilters {\n status: TasksPanelStatusFilter;\n type: string | null;\n assignee: string | null;\n overdueOnly: boolean;\n}\n\n/**\n * Panel-local extension of the card's `TaskItem`. The extra fields here drive\n * bucketing + filtering; the row's display fields (the typed link via\n * `linkType` + `linkedLabel`, the `assigneeLabel`, `dueLabel`) live on\n * `TaskItem` and are rendered by `TaskCard` itself. The host maps the platform\n * `DoctorReminder` → this shape — composing `title` (a summary, NOT the bare\n * type), `note`, the linked entity, the assignee, and `dueLabel`.\n */\nexport interface TasksPanelItem extends TaskItem {\n /** ISO-8601 due/scheduled instant (platform `DoctorReminder.date`). Buckets + orders the list. */\n dueIso: string;\n /** System or custom task-type key (`recall` | `payment` | `collection` | `other` | `custom-*`). Drives the type filter + badge. */\n type?: string;\n /**\n * Localised type label, required for CUSTOM types (the panel resolves system\n * keys itself). Falls back to the system label for the four known keys,\n * then to \"Other\". The raw key is never shown.\n */\n typeLabel?: string;\n /**\n * Assignee id (the platform `practiceUser`). Omit ⇒ unassigned; give pool\n * tasks a shared sentinel value (e.g. `'unassigned'`) if you want the pool\n * itself filterable. Drives the assignee FILTER (exact match); the displayed\n * name is `TaskItem.assigneeLabel`.\n */\n assignee?: string;\n /** Provenance — manual vs workflow-created. Filter only. */\n createdBy?: 'user' | 'workflow';\n}\n\n/** Curated imperative handle — identifiers + structural state only, no PHI. */\nexport interface TasksPanelHandle {\n getItems: () => Array<{ id: string; status: string }>;\n selectItem: (id: string) => void;\n /**\n * Same path as a click on the done box. Resolves once the host has\n * answered (in client mode, after the row's fade) and rejects if the\n * host refuses, or if nothing was started: an unknown id, a read-only\n * panel, no `onToggleDone`, or a change to that task already pending.\n */\n toggleDone: (id: string) => Promise<void>;\n /** Same path as the row's dismiss action, and settles in the same way. */\n dismiss: (id: string) => Promise<void>;\n jumpToOverdue: () => void;\n setFilter: (next: {\n status?: TasksPanelStatusFilter;\n type?: string | null;\n assignee?: string | null;\n overdueOnly?: boolean;\n }) => void;\n /** Switch the task scope segment (patient ↔ mine). The host re-feeds items. */\n changeScope: (next: TasksPanelScope) => void;\n /** Request the host to append the next page of tasks (mirrors onLoadMore). */\n loadMore: () => void;\n}\n\ninterface FilterOption {\n /** Stable value passed back through the matching `on…Change`. */\n value: string;\n /** Localised label. */\n label: string;\n}\n\nexport interface TasksPanelProps extends Omit<\n HTMLAttributes<HTMLElement>,\n 'onClick' | 'id' | 'title'\n> {\n /** Stable instance id, surfaced as `data-component-id`. */\n id?: string;\n /** Tasks to render — any order; bucketed + sorted internally (due ASC, Done last). */\n items: TasksPanelItem[];\n /** ISO-8601 \"now\" anchor — buckets + overdue compute against it. Defaults to the current instant; stories pass a fixed value. */\n nowIso?: string;\n /** Panel heading. Defaults to the localised \"Tasks\". */\n title?: string;\n /** PanelHeader glyph. Default <ClipboardCheck />. */\n icon?: ReactNode;\n /**\n * A total the host counted, shown as given after the title (\"Tasks (42)\")\n * and read as \"42 tasks\". Omitted: nothing shown. The panel never\n * computes it.\n */\n totalCount?: number;\n /** Visual density forwarded to each TaskCard. Defaults to `sm`, matching the note and appointment rows. */\n size?: 'xs' | 'sm' | 'md';\n /**\n * 'client' (default): the panel filters `items`. 'server': the host has\n * already filtered and paged `items`; the panel shows them as given. In\n * server mode a filter control shows only when `onFiltersChange` or its\n * own `on…Change` is set, since only the host can re-query.\n */\n filtering?: TasksPanelFiltering;\n /** Fires when a row is activated. */\n onOpenTask?: (item: TasksPanelItem) => void;\n /**\n * Fires when the host should set a task's done state to `nextDone`. In\n * server mode it fires on the click. In client mode it fires on the click\n * for a row that stays in view, and once the row has faded for one that\n * leaves. Either way, the box ignores clicks until a returned promise\n * settles, and a promise that rejects puts the row back, unticked. The\n * panel does not announce a refusal: report it yourself (for example\n * `toastError` with a translated message) and rethrow, so the row still\n * rolls back.\n */\n onToggleDone?: (\n item: TasksPanelItem,\n nextDone: boolean,\n ) => void | Promise<void>;\n /** Fires when the host should open the task editor. Omit to hide the per-row edit action. */\n onEditTask?: (item: TasksPanelItem) => void;\n /**\n * Fires when the host should dismiss / remove a task. Omit to hide the\n * per-row dismiss action. In server mode it fires on the click, in client\n * mode once the row has faded. A returned promise that rejects restores\n * the row. The panel does not announce a refusal: report it yourself and\n * rethrow, as for `onToggleDone`.\n */\n onDismissTask?: (item: TasksPanelItem) => void | Promise<void>;\n /** Fires when the header \"Add\" affordance is activated. Omit to hide it. */\n onAddTask?: () => void;\n /**\n * Read-only mode — hides every write affordance (toggle / edit / dismiss /\n * add), and the handle's `toggleDone` and `dismiss` reject without calling\n * the host. Mirrors the platform gating writes behind `practice_task_edit`.\n */\n readOnly?: boolean;\n /**\n * Per-row trailing action toolbar, forwarded to each TaskCard's `actions`\n * slot. Overrides the default toggle / edit / dismiss buttons (the type Badge\n * is always prepended by the panel). Ignored when `readOnly`.\n */\n renderItemActions?: (item: TasksPanelItem) => ReactNode;\n /**\n * Extra per-row actions, rendered before the toggle / edit / dismiss\n * actions (or before `renderItemActions`, which still replaces those).\n * Not a task write, so `readOnly` does not hide them: withhold them from\n * the host side when they do not apply.\n */\n renderItemExtraActions?: (item: TasksPanelItem) => ReactNode;\n\n /* ----- Scope (host-driven feed switch) ----- */\n /** Controlled scope segment. */\n scope?: TasksPanelScope;\n /** Uncontrolled initial scope. Default `'patient'` when both scopes are available, else the only one. */\n defaultScope?: TasksPanelScope;\n /** Fires when the user switches scope — the host re-feeds `items`. */\n onScopeChange?: (next: TasksPanelScope) => void;\n /** Which scopes the segment offers. Omit ⇒ no scope segment (single-scope panel). */\n availableScopes?: TasksPanelScope[];\n\n /* ----- One-way pagination ----- */\n /** Load the next page — fired once per page when the bottom edge is reached, and via the footer button. */\n onLoadMore?: () => void;\n /** Whether more tasks exist. Defaults to `true` when `onLoadMore` is set (client mode only; server mode needs `true`). */\n hasMore?: boolean;\n /** Show the bottom loading row while the next page is fetched. */\n loadingMore?: boolean;\n /** Loading state. Skeleton rows while there are none to show; in server mode, rows already shown stay. */\n loading?: boolean;\n /** Error surface — `true` for the default error EmptyState, or a custom node. */\n error?: boolean | ReactNode;\n /** Adds a Retry action to the default error state (`error === true`). */\n onRetry?: () => void;\n\n /* ----- Filters (mirror platform TaskFilterType) ----- */\n /**\n * Show the filter header (status segment + type / assignee selects +\n * overdue toggle). Default `true`. In server mode each control also needs\n * `onFiltersChange` or its own `on…Change`.\n */\n showFilters?: boolean;\n /**\n * The host's default query: the uncontrolled start, what Clear filters\n * returns to, and what server mode judges \"filtered empty\" against.\n * Absent: To do, any type, anyone, not overdue-only.\n */\n defaultFilters?: TasksPanelFilters;\n /**\n * Once per user action, with the whole next filter state. Never fires\n * when nothing changed. Fires in both modes.\n */\n onFiltersChange?: (next: TasksPanelFilters) => void;\n /** Controlled status segment. */\n statusFilter?: TasksPanelStatusFilter;\n /** Uncontrolled initial status segment. Default `'todo'` (the platform default). */\n defaultStatusFilter?: TasksPanelStatusFilter;\n onStatusFilterChange?: (next: TasksPanelStatusFilter) => void;\n /** Task types for the type filter. Omit ⇒ no type filter. */\n typeOptions?: FilterOption[];\n /** Controlled type filter (`null`/empty ⇒ all). */\n typeFilter?: string | null;\n onTypeFilterChange?: (next: string | null) => void;\n /** Assignees for the assignee filter. Pass an explicit Unassigned option if wanted. Omit ⇒ no assignee filter. */\n assigneeOptions?: FilterOption[];\n /** Controlled assignee filter (`null`/empty ⇒ anyone). */\n assigneeFilter?: string | null;\n onAssigneeFilterChange?: (next: string | null) => void;\n /** Controlled overdue-only toggle. */\n overdueOnly?: boolean;\n /** Uncontrolled initial overdue-only state. Default `false`. */\n defaultOverdueOnly?: boolean;\n onOverdueOnlyChange?: (next: boolean) => void;\n\n /* ----- Empty ----- */\n emptyTitle?: string;\n emptyDescription?: string;\n /** CTA wired into the first-use empty state (e.g. Create task). */\n emptyAction?: { label: string; onClick: () => void };\n\n /** Accessible name for the panel region (defaults to `title`). */\n 'aria-label'?: string;\n}\n\n/* A write the host has been asked for and the list has not caught up with. */\ninterface PendingWrite {\n kind: 'done' | 'dismiss';\n /** Done only: the value the box flipped to. Absent when it only guards. */\n next?: boolean;\n /** The row leaves the current view once the write lands. */\n leaves: boolean;\n /** The host's promise has resolved. */\n settled: boolean;\n /** Loads finished when it resolved. */\n edgeAtSettle: number;\n /** The id:status list when it resolved. */\n sigAtSettle: string;\n}\n\n/* What a click or a handle call did. `started` false means nothing changed.\n `result` settles with the host's answer, and rejects when nothing started;\n the handle hands it back to its caller. */\ninterface WriteAttempt {\n started: boolean;\n result: Promise<void>;\n}\n\n/* Where focus was, so it can be put back near there when its row leaves. */\ninterface FocusRecord {\n el: HTMLElement;\n rowId: string | null;\n action: string | null;\n index: number;\n}\n\n/* What the stable agent handle reaches through to, refreshed each render. */\ninterface PanelActions {\n toggleDone: (item: TasksPanelItem) => WriteAttempt;\n dismiss: (item: TasksPanelItem) => WriteAttempt;\n onOpenTask?: (item: TasksPanelItem) => void;\n loadMore: () => void;\n changeScope: (next: TasksPanelScope) => void;\n commitFilters: (patch: Partial<TasksPanelFilters>) => void;\n serverMode: boolean;\n}\n\nconst DEFAULT_FILTERS: TasksPanelFilters = {\n status: 'todo',\n type: null,\n assignee: null,\n overdueOnly: false,\n};\n\nconst EMPTY_PENDING: ReadonlyMap<string, PendingWrite> = new Map();\nconst EMPTY_HIDDEN: ReadonlySet<string> = new Set();\n\n/* One string per list state that changes when an id or a status does. */\nfunction sigOf(items: readonly TasksPanelItem[]): string {\n return items.map((i) => `${i.id}:${i.status ?? 'open'}`).join('|');\n}\n\nfunction sameFilters(a: TasksPanelFilters, b: TasksPanelFilters): boolean {\n return (\n a.status === b.status &&\n a.type === b.type &&\n a.assignee === b.assignee &&\n a.overdueOnly === b.overdueOnly\n );\n}\n\n/* The same query, reading an empty select value as \"any\". */\nfunction sameQuery(a: TasksPanelFilters, b: TasksPanelFilters): boolean {\n return (\n a.status === b.status &&\n (a.type || null) === (b.type || null) &&\n (a.assignee || null) === (b.assignee || null) &&\n a.overdueOnly === b.overdueOnly\n );\n}\n\n/* A rejection the caller may await; marked handled so a click that ignores\n it does not raise an unhandled-rejection warning. */\nfunction handledRejection(reason: unknown): Promise<void> {\n const rejected = Promise.reject(reason);\n rejected.catch(() => undefined);\n return rejected;\n}\n\n/* Locale digits and grouping. An unusable language tag falls back to the\n runtime default rather than throwing. */\nfunction numberFormatFor(language: string | undefined): Intl.NumberFormat {\n try {\n return new Intl.NumberFormat(language);\n } catch {\n return new Intl.NumberFormat();\n }\n}\n\n/* The host's answer as a promise, marked handled in the same way. */\nfunction handledAnswer(result: void | Promise<void>): Promise<void> {\n const answer = Promise.resolve(result);\n answer.catch(() => undefined);\n return answer;\n}\n\n/* -------------------------------------------------------------------- */\n/* CVA */\n/* -------------------------------------------------------------------- */\n\nconst rootVariants = cva(\n [\n 'ds:flex ds:flex-col ds:h-full ds:min-h-0',\n 'ds:bg-[color:var(--card)] ds:text-[color:var(--card-foreground)]',\n ].join(' '),\n {\n variants: { size: { xs: '', sm: '', md: '' } },\n defaultVariants: { size: 'sm' },\n },\n);\n\n/* Scroll region with a block-axis fade mask — identical technique to\n AppointmentTimeline, single-direction load. Disabled under reduced-motion,\n the accessible theme, and forced-colors. */\nconst scrollRegionClasses = [\n 'ds:flex-1 ds:min-h-0 ds:overflow-y-auto',\n 'ds:flex ds:flex-col ds:gap-[var(--spacing-md)]',\n 'ds:px-[var(--spacing-md)] ds:py-[var(--spacing-xs)]',\n 'ds:[--tpl-mask-top:black] ds:[--tpl-mask-bottom:black]',\n 'ds:data-[fade-top=true]:[--tpl-mask-top:transparent]',\n 'ds:data-[fade-bottom=true]:[--tpl-mask-bottom:transparent]',\n 'ds:[mask-image:linear-gradient(to_bottom,var(--tpl-mask-top)_0,black_var(--tpl-fade-distance,var(--spacing-lg)),black_calc(100%-var(--tpl-fade-distance,var(--spacing-lg))),var(--tpl-mask-bottom)_100%)]',\n 'ds:motion-reduce:[mask-image:none]',\n 'ds:[.theme-accessible_&]:[mask-image:none]',\n 'ds:forced-colors:[mask-image:none]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[color:var(--ring)] ds:focus-visible:[outline-offset:-2px]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n].join(' ');\n\n/* Elevation for each reused TaskCard row: the same `--shadow-card` as the\n elevated Card that NotesPanel note rows use, so tasks and notes read as one\n family. TaskCard owns its own border + radius. The scroll region clips\n `overflow-x`, so its inline gutter is `--spacing-md` to fit the shadow. */\nconst rowElevationClass = [\n 'ds:shadow-[var(--shadow-card)] ds:bg-[color:var(--card)]',\n // Declared at rest, not only while leaving: a transition added at the\n // same moment as the value it animates has nothing to move from.\n 'ds:transition-opacity ds:duration-[var(--animation-duration)]',\n 'ds:ease-[var(--ease-out)] ds:motion-reduce:transition-none',\n].join(' ');\n\n/* A row on its way out. It keeps its space until the host drops it, so the\n list settles once rather than twice. */\nconst rowLeavingClass = 'ds:opacity-0';\n\n/* Length of the tick path below, so the dash can be drawn from nothing. */\nconst TICK_LENGTH = 12;\n\n/* The leading done control. A checkbox, not a status glyph: the row can be\n completed here, which is where people reach first. Its name never\n changes; the state is carried by `aria-checked` alone. */\nfunction TaskDoneCheckbox({\n item,\n checked,\n pending,\n label,\n reduceMotion,\n onToggle,\n}: {\n item: TasksPanelItem;\n /** The value to show: the pending target while a write is in flight. */\n checked: boolean;\n /** A write is in flight, so a second click does nothing. */\n pending: boolean;\n label: string;\n reduceMotion?: boolean;\n /** Starts the write, and says whether it started and how it ended. */\n onToggle: (item: TasksPanelItem, next: boolean) => WriteAttempt;\n}) {\n const {\n checked: shown,\n drawing,\n toggle,\n } = useCheckAnimation({\n checked,\n reduceMotion,\n });\n // Read when the host answers, which is after later renders.\n const latestRef = useRef({ shown, checked, toggle });\n latestRef.current = { shown, checked, toggle };\n const tone = shown\n ? // `--accent` is magenta-700 in light, the step that clears AA there.\n 'ds:text-[color:var(--accent)]'\n : item.priority === 'high'\n ? 'ds:text-[color:var(--destructive)]'\n : 'ds:text-[color:var(--muted-foreground)]';\n return (\n <button\n type=\"button\"\n role=\"checkbox\"\n aria-checked={shown}\n aria-label={label}\n aria-disabled={pending || undefined}\n data-action=\"toggle-done\"\n data-drawing={drawing ? '' : undefined}\n onClick={() => {\n if (pending) return;\n // The host hears first, so a write it refuses on the spot never\n // ticks the box. The target is what `toggle()` would flip to.\n const next = !shown;\n const attempt = onToggle(item, next);\n if (!attempt.started) return;\n toggle();\n // A later refusal that `checked` does not show (client mode, a row\n // that stays) would leave the tick up, so take it back down.\n attempt.result.catch(() => {\n const now = latestRef.current;\n if (now.shown === next && now.checked !== next) now.toggle();\n });\n }}\n className={[\n 'ds:group/check ds:flex ds:items-center ds:justify-center ds:rounded-[var(--radius-sm)]',\n // 16px glyph + 4px each side = 24px; the accessible theme lifts it\n // to the full target size.\n 'ds:p-[var(--spacing-xs)]',\n 'ds:[.theme-accessible_&]:min-h-[var(--min-target-size)] ds:[.theme-accessible_&]:min-w-[var(--min-target-size)]',\n 'ds:hover:bg-[color:var(--muted)]/40 ds:aria-disabled:cursor-progress',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-[color:var(--ring)] ds:forced-colors:focus-visible:outline-[CanvasText]',\n tone,\n ].join(' ')}\n >\n <svg\n viewBox=\"0 0 18 18\"\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:transition-transform ds:duration-[var(--animation-duration)] ds:ease-[var(--ease-out)] ds:group-data-[drawing]/check:scale-110 ds:motion-reduce:transition-none\"\n >\n <rect\n x=\"1.5\"\n y=\"1.5\"\n width=\"15\"\n height=\"15\"\n rx=\"4\"\n className=\"ds:fill-none ds:stroke-current ds:[stroke-width:1.5]\"\n />\n {/* The tick is drawn by retracting its dash, so it sweeps on rather\n than appearing whole. */}\n <path\n d=\"M5 9.25 L7.75 12 L13 6.25\"\n strokeDashoffset={shown ? 0 : TICK_LENGTH}\n className=\"ds:fill-none ds:stroke-current ds:[stroke-width:2] ds:[stroke-linecap:round] ds:[stroke-linejoin:round] ds:[stroke-dasharray:12] ds:transition-[stroke-dashoffset] ds:duration-[var(--animation-duration)] ds:ease-[var(--ease-out)] ds:motion-reduce:transition-none\"\n />\n </svg>\n </button>\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* Type → Badge variant + icon (system keys only; custom ⇒ neutral) */\n/* -------------------------------------------------------------------- */\n\nconst SYSTEM_TYPE_META: Record<\n string,\n { variant: NonNullable<BadgeProps['variant']>; Icon: typeof Tag }\n> = {\n recall: { variant: 'info', Icon: Megaphone },\n payment: { variant: 'warning', Icon: Gem },\n collection: { variant: 'error', Icon: Coins },\n other: { variant: 'neutral', Icon: Tag },\n};\n\n/* -------------------------------------------------------------------- */\n/* Due-bucket grouping */\n/* -------------------------------------------------------------------- */\n\ntype BucketKey =\n | 'overdue'\n | 'today'\n | 'tomorrow'\n | 'thisWeek'\n | 'later'\n | 'done';\n\nconst BUCKET_ORDER: BucketKey[] = [\n 'overdue',\n 'today',\n 'tomorrow',\n 'thisWeek',\n 'later',\n 'done',\n];\n\ninterface Bucket {\n key: BucketKey;\n items: TasksPanelItem[];\n}\n\nfunction startOfDay(d: Date): Date {\n return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n}\n\n/** Boundary timestamps the buckets + the overdue notion are computed against. */\nfunction dayBoundaries(now: Date) {\n const today = startOfDay(now);\n const tomorrow = new Date(today);\n tomorrow.setDate(today.getDate() + 1);\n const dayAfter = new Date(today);\n dayAfter.setDate(today.getDate() + 2);\n // Monday-based week — start of NEXT week is the upper bound of \"This week\".\n const dow = (today.getDay() + 6) % 7;\n const nextWeek = new Date(today);\n nextWeek.setDate(today.getDate() + (7 - dow));\n return {\n startOfToday: +today,\n startOfTomorrow: +tomorrow,\n startOfDayAfter: +dayAfter,\n startOfNextWeek: +nextWeek,\n };\n}\n\nfunction bucketFor(item: TasksPanelItem, done: boolean, now: Date): BucketKey {\n if (done) return 'done';\n const { startOfToday, startOfTomorrow, startOfDayAfter, startOfNextWeek } =\n dayBoundaries(now);\n const due = +new Date(item.dueIso);\n if (due < startOfToday) return 'overdue';\n if (due < startOfTomorrow) return 'today';\n if (due < startOfDayAfter) return 'tomorrow';\n if (due < startOfNextWeek) return 'thisWeek';\n return 'later';\n}\n\n/** A task is overdue when it is not done and due before tomorrow (platform notion). */\nfunction isOverdue(item: TasksPanelItem, now: Date): boolean {\n if (item.status === 'done') return false;\n return +new Date(item.dueIso) < dayBoundaries(now).startOfTomorrow;\n}\n\nfunction groupByDueBucket(\n items: TasksPanelItem[],\n now: Date,\n isDone: (item: TasksPanelItem) => boolean,\n): Bucket[] {\n const map = new Map<BucketKey, TasksPanelItem[]>();\n for (const item of items) {\n const key = bucketFor(item, isDone(item), now);\n const list = map.get(key);\n if (list) list.push(item);\n else map.set(key, [item]);\n }\n const buckets: Bucket[] = [];\n for (const key of BUCKET_ORDER) {\n const list = map.get(key);\n if (!list || list.length === 0) continue;\n // Due ASC (most-overdue-first), mirroring the platform's ORDER BY date ASC.\n list.sort((a, b) => +new Date(a.dueIso) - +new Date(b.dueIso));\n buckets.push({ key, items: list });\n }\n return buckets;\n}\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\nexport const TasksPanel = forwardRef<HTMLElement, TasksPanelProps>(\n (\n {\n id,\n items,\n nowIso,\n title,\n icon,\n totalCount,\n size = 'sm',\n filtering = 'client',\n onOpenTask,\n onToggleDone,\n onEditTask,\n onDismissTask,\n onAddTask,\n readOnly = false,\n renderItemActions,\n renderItemExtraActions,\n scope,\n defaultScope,\n onScopeChange,\n availableScopes,\n onLoadMore,\n hasMore,\n loadingMore = false,\n loading = false,\n error = false,\n onRetry,\n showFilters = true,\n defaultFilters,\n onFiltersChange,\n statusFilter,\n defaultStatusFilter,\n onStatusFilterChange,\n typeOptions,\n typeFilter,\n onTypeFilterChange,\n assigneeOptions,\n assigneeFilter,\n onAssigneeFilterChange,\n overdueOnly,\n defaultOverdueOnly,\n onOverdueOnlyChange,\n emptyTitle,\n emptyDescription,\n emptyAction,\n className,\n 'aria-label': ariaLabel,\n ...rest\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation();\n const headingId = useId();\n const overdueSwitchId = useId();\n const heading = title ?? t('tasksPanel.title');\n const serverMode = filtering === 'server';\n /* In server mode a filter only works if the host re-queries, so a\n field with no seam (`onFiltersChange` or its own callback) is\n withheld, from the header and from the agent alike. */\n const filterSeams: Record<keyof TasksPanelFilters, boolean> = {\n status: !serverMode || !!onFiltersChange || !!onStatusFilterChange,\n type: !serverMode || !!onFiltersChange || !!onTypeFilterChange,\n assignee: !serverMode || !!onFiltersChange || !!onAssigneeFilterChange,\n overdueOnly: !serverMode || !!onFiltersChange || !!onOverdueOnlyChange,\n };\n\n // Static key lookups — every label is a literal `t()` call so the i18n\n // coverage gate can see each key (template-literal keys are invisible to it).\n const statusLabels: Record<TasksPanelStatusFilter, string> = {\n todo: t('tasksPanel.status.todo'),\n done: t('tasksPanel.status.done'),\n all: t('tasksPanel.status.all'),\n };\n const scopeLabels: Record<TasksPanelScope, string> = {\n patient: t('tasksPanel.scope.patient'),\n mine: t('tasksPanel.scope.mine'),\n };\n const bucketLabels: Record<BucketKey, string> = {\n overdue: t('tasksPanel.buckets.overdue'),\n today: t('tasksPanel.buckets.today'),\n tomorrow: t('tasksPanel.buckets.tomorrow'),\n thisWeek: t('tasksPanel.buckets.thisWeek'),\n later: t('tasksPanel.buckets.later'),\n done: t('tasksPanel.buckets.done'),\n };\n const systemTypeLabels: Record<string, string> = {\n recall: t('tasksPanel.types.recall'),\n payment: t('tasksPanel.types.payment'),\n collection: t('tasksPanel.types.collection'),\n other: t('tasksPanel.types.other'),\n };\n\n const now = useMemo(\n () => (nowIso ? new Date(nowIso) : new Date()),\n [nowIso],\n );\n\n // A count in the locale's digits and its own brackets: \"(1.234)\",\n // \"(42)\".\n const numbers = useMemo(\n () => numberFormatFor(i18n.language),\n [i18n.language],\n );\n const bracketed = (count: number): string =>\n t('tasksPanel.bracketedCount', { value: numbers.format(count) });\n\n /* ----- Controlled / uncontrolled scope state ----- */\n const [scopeState, setScopeState] = useState<TasksPanelScope>(\n defaultScope ?? availableScopes?.[0] ?? 'patient',\n );\n const currentScope = scope ?? scopeState;\n const changeScope = useCallback(\n (next: TasksPanelScope) => {\n if (scope === undefined) setScopeState(next);\n onScopeChange?.(next);\n },\n [scope, onScopeChange],\n );\n\n /* ----- Controlled / uncontrolled filter state ----- */\n const baseline = defaultFilters ?? DEFAULT_FILTERS;\n const [statusState, setStatusState] = useState<TasksPanelStatusFilter>(\n defaultStatusFilter ?? baseline.status,\n );\n const [typeState, setTypeState] = useState<string | null>(baseline.type);\n const [assigneeState, setAssigneeState] = useState<string | null>(\n baseline.assignee,\n );\n const [overdueState, setOverdueState] = useState<boolean>(\n defaultOverdueOnly ?? baseline.overdueOnly,\n );\n const currentStatus = statusFilter ?? statusState;\n const currentType = typeFilter !== undefined ? typeFilter : typeState;\n const currentAssignee =\n assigneeFilter !== undefined ? assigneeFilter : assigneeState;\n const currentOverdueOnly = overdueOnly ?? overdueState;\n // In server mode Done and Overdue never combine: the switch reads off\n // while Done is chosen.\n const effectiveOverdue = serverMode\n ? currentOverdueOnly && currentStatus !== 'done'\n : currentOverdueOnly;\n\n /* Every filter change reads the latest state from here and writes the\n result straight back, so two changes in one tick compose rather than\n the second undoing the first. Refreshed from props and state on\n every render. */\n const filtersRef = useRef<TasksPanelFilters>({\n status: currentStatus,\n type: currentType,\n assignee: currentAssignee,\n overdueOnly: currentOverdueOnly,\n });\n filtersRef.current = {\n status: currentStatus,\n type: currentType,\n assignee: currentAssignee,\n overdueOnly: currentOverdueOnly,\n };\n\n /* One path for every filter change: segments, selects, the switch,\n Clear filters and the agent. Each touched field fires its own\n callback as before; `onFiltersChange` fires once, and only when the\n state actually moved. */\n const commitFilters = (requested: Partial<TasksPanelFilters>): void => {\n const patch = Object.fromEntries(\n Object.entries(requested).filter(\n ([field]) => filterSeams[field as keyof TasksPanelFilters],\n ),\n ) as Partial<TasksPanelFilters>;\n // Every field asked for has no seam: nothing can change.\n if (\n Object.keys(requested).length > 0 &&\n Object.keys(patch).length === 0\n ) {\n return;\n }\n const prev = filtersRef.current;\n // In server mode the switch shows off while Done is chosen, so start\n // from that: changing anything else must not bring Overdue back.\n const shown =\n serverMode && prev.status === 'done' && prev.overdueOnly\n ? { ...prev, overdueOnly: false }\n : prev;\n const next: TasksPanelFilters = { ...shown, ...patch };\n const touched = new Set(Object.keys(patch));\n if (shown !== prev) touched.add('overdueOnly');\n // The server refuses Done with Overdue. Choosing Done clears Overdue;\n // asking for Overdue while Done shows resets the status to the\n // default one (To do if the default is Done).\n if (serverMode && next.status === 'done' && next.overdueOnly) {\n if (patch.status !== undefined) {\n next.overdueOnly = false;\n touched.add('overdueOnly');\n } else {\n next.status = baseline.status === 'done' ? 'todo' : baseline.status;\n touched.add('status');\n }\n }\n filtersRef.current = next;\n if (statusFilter === undefined) setStatusState(next.status);\n if (typeFilter === undefined) setTypeState(next.type);\n if (assigneeFilter === undefined) setAssigneeState(next.assignee);\n if (overdueOnly === undefined) setOverdueState(next.overdueOnly);\n if (touched.has('status')) onStatusFilterChange?.(next.status);\n if (touched.has('type')) onTypeFilterChange?.(next.type);\n if (touched.has('assignee')) onAssigneeFilterChange?.(next.assignee);\n if (touched.has('overdueOnly')) onOverdueOnlyChange?.(next.overdueOnly);\n if (!sameFilters(prev, next)) onFiltersChange?.(next);\n };\n\n // Back to the host's default query, not a hard-coded one.\n const clearFilters = (): void => commitFilters({ ...baseline });\n\n /* ----- Pending writes (server mode; client mode guards the fade) ----- */\n const [pending, setPendingState] =\n useState<ReadonlyMap<string, PendingWrite>>(EMPTY_PENDING);\n const pendingRef = useRef<ReadonlyMap<string, PendingWrite>>(EMPTY_PENDING);\n const [hidden, setHiddenState] =\n useState<ReadonlySet<string>>(EMPTY_HIDDEN);\n const hiddenRef = useRef<ReadonlySet<string>>(EMPTY_HIDDEN);\n const mountedRef = useRef(true);\n /* Client-mode writes still waiting for their fade, so the host has not\n been told yet. Closing the panel stops the fade, so it ends them. */\n const unsettledRef = useRef(new Set<(reason: unknown) => void>());\n useEffect(() => {\n mountedRef.current = true;\n const unsettled = unsettledRef.current;\n return () => {\n mountedRef.current = false;\n unsettled.forEach((reject) =>\n reject(new Error('TasksPanel: closed before the host was told.')),\n );\n unsettled.clear();\n };\n }, []);\n\n // The refs are written first, so a guard read in the same tick sees the\n // change before React re-renders.\n const updatePending = (edit: (m: Map<string, PendingWrite>) => void) => {\n const next = new Map(pendingRef.current);\n edit(next);\n pendingRef.current = next;\n setPendingState(next);\n };\n const updateHidden = (edit: (s: Set<string>) => void) => {\n const next = new Set(hiddenRef.current);\n edit(next);\n hiddenRef.current = next;\n setHiddenState(next);\n };\n\n /* ----- Filter → bucket ----- */\n const visible = useMemo(() => {\n // Server mode shows the host's rows as given, less any it has been\n // asked to drop and has not dropped yet.\n if (serverMode) return items.filter((item) => !hidden.has(item.id));\n return items.filter((item) => {\n const isDone = item.status === 'done';\n if (currentStatus === 'todo' && isDone) return false;\n if (currentStatus === 'done' && !isDone) return false;\n if (currentType && item.type !== currentType) return false;\n if (currentAssignee) {\n const assignee = item.assignee ?? '';\n if (assignee !== currentAssignee) return false;\n }\n if (currentOverdueOnly && !isOverdue(item, now)) return false;\n return true;\n });\n }, [\n serverMode,\n hidden,\n items,\n currentStatus,\n currentType,\n currentAssignee,\n currentOverdueOnly,\n now,\n ]);\n\n const buckets = useMemo(() => {\n // In server mode a ticked row that stays in view (under All) moves to\n // Done at once, before the host confirms. A row on its way out fades\n // where it is instead.\n const isDone = (item: TasksPanelItem): boolean => {\n if (serverMode) {\n const write = pending.get(item.id);\n if (\n write?.kind === 'done' &&\n write.next !== undefined &&\n !write.leaves\n ) {\n return write.next;\n }\n }\n return item.status === 'done';\n };\n return groupByDueBucket(visible, now, isDone);\n }, [visible, now, serverMode, pending]);\n\n // Display order, top to bottom.\n const orderedIds = useMemo(\n () => buckets.flatMap((bucket) => bucket.items.map((item) => item.id)),\n [buckets],\n );\n\n /* ----- Scroll region: edge fades + one-way load-more ----- */\n const scrollRef = useRef<HTMLDivElement>(null);\n const overdueHeaderRef = useRef<HTMLElement | null>(null);\n const [fadeTop, setFadeTop] = useState(false);\n const [fadeBottom, setFadeBottom] = useState(false);\n\n const updateEdges = useCallback(() => {\n const region = scrollRef.current;\n if (!region) return;\n const { scrollTop, scrollHeight, clientHeight } = region;\n setFadeTop(scrollTop > 1);\n setFadeBottom(scrollTop + clientHeight < scrollHeight - 1);\n }, []);\n\n useIsomorphicLayoutEffect(() => {\n updateEdges();\n }, [buckets, updateEdges]);\n\n useIsomorphicLayoutEffect(() => {\n const region = scrollRef.current;\n if (!region || typeof ResizeObserver === 'undefined') return undefined;\n const observer = new ResizeObserver(updateEdges);\n observer.observe(region);\n return () => observer.disconnect();\n }, [updateEdges]);\n\n // Server mode needs the host to say so; a partial page is not proof.\n const moreAvailable = serverMode\n ? hasMore === true\n : (hasMore ?? !!onLoadMore);\n\n /* Loads finished: +1 each time `loading` goes true → false without an\n error. A write that settled before a load finished can then let go. */\n const itemsRef = useRef<TasksPanelItem[]>(items);\n itemsRef.current = items;\n const itemsSig = useMemo(() => sigOf(items), [items]);\n const idsSig = useMemo(\n () => items.map((item) => item.id).join('|'),\n [items],\n );\n const idsSigRef = useRef(idsSig);\n idsSigRef.current = idsSig;\n const loadEdgesRef = useRef(0);\n const prevLoadingRef = useRef(loading);\n useEffect(() => {\n if (prevLoadingRef.current && !loading && !error) {\n loadEdgesRef.current += 1;\n }\n prevLoadingRef.current = loading;\n }, [loading, error]);\n\n /* The load-more latch: the bottom edge asks for one page, then waits\n until that page arrives (the ids change) or a reload finishes. A page\n that fails changes neither, so it does not ask again on its own. */\n const armedRef = useRef(true);\n const idsAtFireRef = useRef('');\n const edgesAtFireRef = useRef(0);\n const requestMore = (): void => {\n armedRef.current = false;\n idsAtFireRef.current = idsSigRef.current;\n edgesAtFireRef.current = loadEdgesRef.current;\n onLoadMore?.();\n };\n useEffect(() => {\n if (armedRef.current) return;\n if (\n idsSig !== idsAtFireRef.current ||\n loadEdgesRef.current > edgesAtFireRef.current\n ) {\n armedRef.current = true;\n }\n }, [idsSig, loading, error]);\n\n const handleScroll = (): void => {\n updateEdges();\n const region = scrollRef.current;\n if (!region) return;\n const { scrollTop, scrollHeight, clientHeight } = region;\n if (\n onLoadMore &&\n moreAvailable &&\n !loading &&\n !loadingMore &&\n armedRef.current &&\n scrollHeight - scrollTop - clientHeight <= EDGE_LOAD_THRESHOLD\n ) {\n requestMore();\n }\n };\n\n /* The accessible theme zeroes `--animation-duration`, so its CSS plays\n nothing — the JS must agree, or a row would sit still for the delay\n and then vanish anyway. `undefined` leaves the media query in charge. */\n const { resolvedTheme } = useTheme();\n const reduceMotion = resolvedTheme.endsWith('-accessible') || undefined;\n\n /* Closing the gap a removed row leaves: the rows below slide up rather\n than jumping, so the eye keeps its place in the list. */\n const { containerRef: reflowRef } = useListReflow<HTMLDivElement>({\n key: orderedIds.join(),\n reduceMotion,\n });\n\n /* A row leaves on two paths, which want different timing: a completed\n row waits for its tick to finish drawing, a dismissed one goes at\n once. */\n const doneExit = useExitTransition({ delayMs: 200, reduceMotion });\n const dismissExit = useExitTransition({ reduceMotion });\n const isLeaving = (rowId: string): boolean =>\n doneExit.isLeaving(rowId) || dismissExit.isLeaving(rowId);\n\n /* Whether a row ticked to `next` leaves the current view. */\n const leavesOnDone = (next: boolean): boolean => {\n const { status, overdueOnly: overdue } = filtersRef.current;\n const overdueShown = serverMode ? overdue && status !== 'done' : overdue;\n return (\n (status === 'todo' && next) ||\n (status === 'done' && !next) ||\n (overdueShown && next)\n );\n };\n\n /* Undo a write the host refused: the row comes back and the box\n reverts, because both read from `pending`. Focus stays where it is. */\n const rollback = (rowId: string): void => {\n if (pendingRef.current.has(rowId)) updatePending((m) => m.delete(rowId));\n if (hiddenRef.current.has(rowId)) updateHidden((s) => s.delete(rowId));\n doneExit.cancel(rowId);\n dismissExit.cancel(rowId);\n };\n\n /* Let go of writes the host's list has caught up with. Never keyed on\n the identity of the `items` array. */\n const reconcile = (): void => {\n const list = itemsRef.current;\n const sig = sigOf(list);\n const byId = new Map(list.map((item) => [item.id, item]));\n const dropped: string[] = [];\n const stillListed: string[] = [];\n pendingRef.current.forEach((write, rowId) => {\n const item = byId.get(rowId);\n if (!item) {\n dropped.push(rowId);\n return;\n }\n if (!write.settled) return;\n const hostAgrees =\n write.kind === 'done' && (item.status === 'done') === write.next;\n const listMoved =\n loadEdgesRef.current > write.edgeAtSettle ||\n sig !== write.sigAtSettle;\n if (hostAgrees || listMoved) {\n dropped.push(rowId);\n stillListed.push(rowId);\n }\n });\n if (dropped.length === 0) return;\n updatePending((m) => dropped.forEach((rowId) => m.delete(rowId)));\n if (dropped.some((rowId) => hiddenRef.current.has(rowId))) {\n updateHidden((s) => dropped.forEach((rowId) => s.delete(rowId)));\n }\n // The host kept the row, and the host is right: stop any fade.\n stillListed.forEach((rowId) => {\n doneExit.cancel(rowId);\n dismissExit.cancel(rowId);\n });\n };\n\n const settle = (rowId: string): void => {\n const write = pendingRef.current.get(rowId);\n if (!write) return;\n updatePending((m) =>\n m.set(rowId, {\n ...write,\n settled: true,\n edgeAtSettle: loadEdgesRef.current,\n sigAtSettle: sigOf(itemsRef.current),\n }),\n );\n // A host that updated `items` before resolving is caught here.\n reconcile();\n };\n\n useEffect(() => {\n if (serverMode) reconcile();\n // `reconcile` reads refs only; the list signature is the trigger.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [serverMode, itemsSig, loading, error]);\n\n /* Server mode: tell the host on the click, hide the row once it has\n faded, and restore it if the host says no. */\n const startServerWrite = (\n item: TasksPanelItem,\n write: PendingWrite,\n call: () => void | Promise<void>,\n exit: typeof doneExit,\n ): WriteAttempt => {\n const rowId = item.id;\n updatePending((m) => m.set(rowId, write));\n let result: void | Promise<void>;\n try {\n result = call();\n } catch (err) {\n rollback(rowId);\n return { started: false, result: handledRejection(err) };\n }\n if (write.leaves) {\n exit.leave(rowId, () => {\n if (pendingRef.current.has(rowId)) updateHidden((s) => s.add(rowId));\n });\n }\n const hostPromise = Promise.resolve(result);\n hostPromise.then(\n () => {\n if (mountedRef.current) settle(rowId);\n },\n () => {\n if (mountedRef.current) rollback(rowId);\n },\n );\n return { started: true, result: hostPromise };\n };\n\n /* A write that did not start. The handle hands this back, so an agent\n learns nothing changed; a click ignores it. */\n const refuse = (reason: string): WriteAttempt => ({\n started: false,\n result: handledRejection(new Error(`TasksPanel: ${reason}`)),\n });\n\n /* Drop a row's guard once the host has answered. */\n const release = (rowId: string): void => {\n if (mountedRef.current && pendingRef.current.has(rowId)) {\n updatePending((m) => m.delete(rowId));\n }\n };\n\n /* Client mode tells the host once the row has faded. The caller gets a\n promise that settles with the host's answer then. */\n const tellAfterExit = (\n rowId: string,\n exit: typeof doneExit,\n call: () => void | Promise<void>,\n ): Promise<void> => {\n let resolve!: () => void;\n let reject!: (reason: unknown) => void;\n const answer = new Promise<void>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n answer.catch(() => undefined);\n unsettledRef.current.add(reject);\n exit.leave(rowId, () => {\n unsettledRef.current.delete(reject);\n let result: void | Promise<void>;\n try {\n result = call();\n } catch (err) {\n release(rowId);\n reject(err);\n return;\n }\n Promise.resolve(result).then(\n () => {\n release(rowId);\n resolve();\n },\n (err: unknown) => {\n release(rowId);\n reject(err);\n },\n );\n });\n return answer;\n };\n\n const runToggleDone = (\n item: TasksPanelItem,\n nextFromBox?: boolean,\n ): WriteAttempt => {\n if (readOnly) return refuse('the panel is read-only.');\n if (!onToggleDone) return refuse('the host gave no onToggleDone.');\n const rowId = item.id;\n if (pendingRef.current.has(rowId)) {\n return refuse('a change to this task is already pending.');\n }\n const next = nextFromBox ?? item.status !== 'done';\n const leaves = leavesOnDone(next);\n if (serverMode) {\n return startServerWrite(\n item,\n {\n kind: 'done',\n next,\n leaves,\n settled: false,\n edgeAtSettle: 0,\n sigAtSettle: '',\n },\n () => onToggleDone(item, next),\n doneExit,\n );\n }\n // Client mode: a row that stays is told at once; a row that leaves\n // fades first, then the host is told.\n if (!leaves) {\n let result: void | Promise<void>;\n try {\n result = onToggleDone(item, next);\n } catch (err) {\n return { started: false, result: handledRejection(err) };\n }\n if (result instanceof Promise) {\n // Hold the box until the host answers. No `next`: the box keeps\n // its own optimistic tick, and drops it if the host refuses.\n updatePending((m) =>\n m.set(rowId, {\n kind: 'done',\n leaves,\n settled: false,\n edgeAtSettle: 0,\n sigAtSettle: '',\n }),\n );\n result.then(\n () => release(rowId),\n () => release(rowId),\n );\n }\n return { started: true, result: handledAnswer(result) };\n }\n updatePending((m) =>\n m.set(rowId, {\n kind: 'done',\n next,\n leaves,\n settled: false,\n edgeAtSettle: 0,\n sigAtSettle: '',\n }),\n );\n return {\n started: true,\n result: tellAfterExit(rowId, doneExit, () => onToggleDone(item, next)),\n };\n };\n\n const runDismiss = (item: TasksPanelItem): WriteAttempt => {\n if (readOnly) return refuse('the panel is read-only.');\n if (!onDismissTask) return refuse('the host gave no onDismissTask.');\n const rowId = item.id;\n if (pendingRef.current.has(rowId)) {\n return refuse('a change to this task is already pending.');\n }\n const write: PendingWrite = {\n kind: 'dismiss',\n leaves: true,\n settled: false,\n edgeAtSettle: 0,\n sigAtSettle: '',\n };\n if (serverMode) {\n return startServerWrite(\n item,\n write,\n () => onDismissTask(item),\n dismissExit,\n );\n }\n // Client mode guards the row while it fades and the host answers.\n updatePending((m) => m.set(rowId, write));\n return {\n started: true,\n result: tellAfterExit(rowId, dismissExit, () => onDismissTask(item)),\n };\n };\n\n const jumpToOverdue = useCallback(() => {\n const region = scrollRef.current;\n const el = overdueHeaderRef.current;\n if (!region || !el) {\n region?.scrollTo({ top: 0 });\n return;\n }\n const delta =\n el.getBoundingClientRect().top - region.getBoundingClientRect().top;\n region.scrollTo({ top: region.scrollTop + delta });\n }, []);\n\n /* ----- Focus rescue ----- */\n /* When the focused row leaves, focus falls to the page body. Put it on\n the same control in the row that took its place, then the row\n above, then the scroll region, then the chosen status. A row that\n only moved (to another bucket) is followed instead. */\n const innerRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => innerRef.current as HTMLElement, []);\n const focusRef = useRef<FocusRecord | null>(null);\n const orderedIdsRef = useRef<string[]>(orderedIds);\n orderedIdsRef.current = orderedIds;\n\n useEffect(() => {\n const root = innerRef.current;\n if (!root) return undefined;\n const onFocusIn = (event: FocusEvent) => {\n const el = event.target;\n if (!(el instanceof HTMLElement)) return;\n const rowId =\n el.closest<HTMLElement>('[data-task-id]')?.dataset.taskId ?? null;\n focusRef.current = {\n el,\n rowId,\n action:\n el.closest<HTMLElement>('[data-action]')?.dataset.action ?? null,\n index: rowId ? orderedIdsRef.current.indexOf(rowId) : -1,\n };\n };\n const onFocusOut = (event: FocusEvent) => {\n const to = event.relatedTarget;\n if (to instanceof Node) {\n if (!root.contains(to)) focusRef.current = null;\n return;\n }\n // No target: a click on empty space, or the row being removed. Decide\n // after the render: a removed row is rescued by then, and one still\n // here but unfocused was left by the user (a window switch keeps it).\n const from = event.target;\n queueMicrotask(() => {\n const record = focusRef.current;\n if (\n record &&\n record.el === from &&\n record.el.isConnected &&\n document.activeElement !== record.el\n ) {\n focusRef.current = null;\n }\n });\n };\n root.addEventListener('focusin', onFocusIn);\n root.addEventListener('focusout', onFocusOut);\n return () => {\n root.removeEventListener('focusin', onFocusIn);\n root.removeEventListener('focusout', onFocusOut);\n };\n }, []);\n\n useIsomorphicLayoutEffect(() => {\n const record = focusRef.current;\n const root = innerRef.current;\n if (!record || !root) return;\n if (record.el.isConnected) {\n // Keep the position current while the row is still here.\n if (record.rowId) {\n record.index = orderedIdsRef.current.indexOf(record.rowId);\n }\n return;\n }\n focusRef.current = null;\n const active = document.activeElement;\n if (active && active !== document.body) return;\n const ids = orderedIdsRef.current;\n const inRow = (rowId: string | undefined): HTMLElement | null =>\n rowId && record.action\n ? root.querySelector<HTMLElement>(\n `[data-task-id=\"${CSS.escape(rowId)}\"] [data-action=\"${CSS.escape(record.action)}\"]`,\n )\n : null;\n const moved = record.rowId ? inRow(record.rowId) : null;\n const target =\n moved ??\n (record.rowId && record.index >= 0\n ? (inRow(ids[record.index]) ?? inRow(ids[record.index - 1]))\n : null) ??\n root.querySelector<HTMLElement>('[data-tasks-panel-region]') ??\n root.querySelector<HTMLElement>(\n '[data-status-filter][aria-pressed=\"true\"]',\n );\n target?.focus();\n });\n\n /* ----- Agent handle ----- */\n /* Stable for the life of the panel: everything is read through refs, so\n a registered handle never goes stale and never re-registers. */\n const actionsRef = useRef<PanelActions | null>(null);\n actionsRef.current = {\n toggleDone: (item) => runToggleDone(item),\n dismiss: (item) => runDismiss(item),\n onOpenTask,\n loadMore: requestMore,\n changeScope,\n commitFilters,\n serverMode,\n };\n const handle = useMemo<TasksPanelHandle>(() => {\n const actions = (): PanelActions => actionsRef.current!;\n const noTask = (targetId: string): Promise<void> =>\n handledRejection(new Error(`TasksPanel: no task \"${targetId}\".`));\n return {\n getItems: () => {\n if (!actions().serverMode) {\n return itemsRef.current.map((i) => ({\n id: i.id,\n status: i.status ?? 'open',\n }));\n }\n return itemsRef.current\n .filter((i) => !hiddenRef.current.has(i.id))\n .map((i) => {\n const write = pendingRef.current.get(i.id);\n const status =\n write?.kind === 'done' && write.next !== undefined\n ? write.next\n ? 'done'\n : 'open'\n : (i.status ?? 'open');\n return { id: i.id, status };\n });\n },\n selectItem: (targetId) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) actions().onOpenTask?.(found);\n },\n toggleDone: (targetId) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (!found) return noTask(targetId);\n return actions().toggleDone(found).result;\n },\n dismiss: (targetId) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (!found) return noTask(targetId);\n return actions().dismiss(found).result;\n },\n jumpToOverdue,\n setFilter: (next) => {\n const patch: Partial<TasksPanelFilters> = {};\n if (next.status !== undefined) patch.status = next.status;\n if (next.type !== undefined) patch.type = next.type;\n if (next.assignee !== undefined) patch.assignee = next.assignee;\n if (next.overdueOnly !== undefined) {\n patch.overdueOnly = next.overdueOnly;\n }\n actions().commitFilters(patch);\n },\n changeScope: (next) => actions().changeScope(next),\n loadMore: () => actions().loadMore(),\n };\n }, [jumpToOverdue]);\n useAgentRegistration(tasksPanelAgent, handle, id);\n\n /* ----- Row rendering ----- */\n const renderTypeBadge = (item: TasksPanelItem): ReactNode => {\n if (!item.type) return null;\n const meta = SYSTEM_TYPE_META[item.type];\n const variant = meta?.variant ?? 'neutral';\n const Icon = meta?.Icon ?? Tag;\n // Never the raw key: a custom type with no label reads \"Other\".\n const label =\n item.typeLabel ||\n systemTypeLabels[item.type] ||\n t('tasksPanel.types.other');\n return (\n <Badge\n variant={variant}\n size=\"sm\"\n leading={<Icon aria-hidden=\"true\" />}\n >\n {label}\n </Badge>\n );\n };\n\n const defaultActions = (item: TasksPanelItem): ReactNode => {\n if (readOnly) return null;\n return (\n <>\n {onEditTask ? (\n <IconButton\n icon={<Pencil />}\n intent=\"ghost\"\n size=\"sm\"\n aria-label={t('tasksPanel.edit')}\n data-action=\"edit-task\"\n onClick={() => onEditTask(item)}\n />\n ) : null}\n {onDismissTask ? (\n <IconButton\n icon={<X />}\n intent=\"ghost\"\n size=\"sm\"\n aria-label={t('tasksPanel.dismiss')}\n data-action=\"dismiss-task\"\n onClick={() => {\n runDismiss(item);\n }}\n />\n ) : null}\n </>\n );\n };\n\n const renderRowActions = (item: TasksPanelItem): ReactNode => {\n const extra = renderItemExtraActions?.(item) ?? null;\n const custom = !readOnly ? renderItemActions?.(item) : null;\n const trailing = custom ?? defaultActions(item);\n const badge = renderTypeBadge(item);\n if (!badge && !extra && !trailing) return undefined;\n return (\n <>\n {badge}\n {extra}\n {trailing}\n </>\n );\n };\n\n const onBoxToggle = (item: TasksPanelItem, next: boolean): WriteAttempt =>\n runToggleDone(item, next);\n\n /* ----- Body branches ----- */\n const skeletonRow = (key: string) => (\n <div\n key={key}\n aria-hidden=\"true\"\n className=\"ds:px-[var(--spacing-sm)] ds:py-[var(--spacing-xs)]\"\n >\n <Skeleton variant=\"rectangular\" height=\"3.5rem\" />\n </div>\n );\n\n const errorBody = (\n <div className=\"ds:flex-1 ds:min-h-0 ds:p-[var(--spacing-md)]\">\n {typeof error === 'boolean' ? (\n <EmptyState\n variant=\"error\"\n size=\"sm\"\n title={t('tasksPanel.error.title')}\n description={t('tasksPanel.error.description')}\n primaryAction={\n onRetry\n ? { label: t('emptyState.error.cta'), onClick: onRetry }\n : undefined\n }\n />\n ) : (\n error\n )}\n </div>\n );\n\n // The skeletons are hidden from assistive tech; the status region below\n // says \"Loading\" for them.\n const skeletonBody = (\n <div className=\"ds:flex-1 ds:min-h-0 ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n {[0, 1, 2, 3].map((i) => skeletonRow(`skeleton-${i}`))}\n </div>\n );\n\n const firstUseBody = (\n <div className=\"ds:flex-1 ds:min-h-0 ds:p-[var(--spacing-md)]\">\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={emptyTitle ?? t('tasksPanel.empty.title')}\n description={emptyDescription ?? t('tasksPanel.empty.description')}\n primaryAction={emptyAction}\n />\n </div>\n );\n\n const anyFilterSeam = Object.values(filterSeams).some(Boolean);\n const filteredEmptyBody = (\n <div className=\"ds:flex-1 ds:min-h-0 ds:p-[var(--spacing-md)]\">\n <EmptyState\n variant=\"no-results\"\n size=\"sm\"\n title={t('tasksPanel.filteredEmpty.title')}\n description={t('tasksPanel.filteredEmpty.description')}\n primaryAction={\n anyFilterSeam\n ? {\n label: t('tasksPanel.filteredEmpty.clear'),\n onClick: clearFilters,\n }\n : undefined\n }\n />\n </div>\n );\n\n // Server mode only: an error while rows are showing sits above them.\n const inlineError =\n serverMode && error ? (\n <div className=\"ds:shrink-0 ds:px-[var(--spacing-md)] ds:pt-[var(--spacing-xs)]\">\n {typeof error === 'boolean' ? (\n <Alert variant=\"error\">\n <Alert.Title as=\"p\">{t('tasksPanel.error.title')}</Alert.Title>\n {onRetry ? (\n <Alert.Action>\n <Button intent=\"outline\" size=\"sm\" onClick={onRetry}>\n {t('emptyState.error.cta')}\n </Button>\n </Alert.Action>\n ) : null}\n </Alert>\n ) : (\n error\n )}\n </div>\n ) : null;\n\n const listBody = (\n <>\n {inlineError}\n <div\n ref={(node) => {\n scrollRef.current = node;\n reflowRef.current = node;\n }}\n // The scroll region must be keyboard-focusable so arrow / Home / End\n // can drive it (axe scrollable-region-focusable).\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={0}\n onScroll={handleScroll}\n data-tasks-panel-region=\"\"\n data-fade-top={fadeTop ? 'true' : undefined}\n data-fade-bottom={fadeBottom ? 'true' : undefined}\n className={scrollRegionClasses}\n >\n <ol\n aria-busy={loading || undefined}\n className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-md)] ds:p-0\"\n >\n {buckets.map((bucket) => (\n <li\n key={bucket.key}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]\"\n >\n <BucketHeader\n bucketKey={bucket.key}\n countLabel={bracketed(bucket.items.length)}\n // A partial page would give a wrong count.\n showCount={!(serverMode && hasMore === true)}\n label={bucketLabels[bucket.key]}\n headerRef={\n bucket.key === 'overdue' ? overdueHeaderRef : undefined\n }\n reflowId={`bucket-${bucket.key}`}\n leaving={bucket.items.every((row) => isLeaving(row.id))}\n />\n <ul className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-0\">\n {bucket.items.map((item) => (\n <TaskCard\n key={item.id}\n item={item}\n size={size}\n onActivate={\n onOpenTask ? () => onOpenTask(item) : undefined\n }\n actions={renderRowActions(item)}\n leading={\n onToggleDone && !readOnly ? (\n <TaskDoneCheckbox\n item={item}\n checked={\n pending.get(item.id)?.next ??\n item.status === 'done'\n }\n pending={pending.has(item.id)}\n label={t('tasksPanel.doneItem', {\n title: item.title,\n })}\n reduceMotion={reduceMotion}\n onToggle={onBoxToggle}\n />\n ) : undefined\n }\n className={`${rowElevationClass} ${REFLOW_ROW_CLASS}${\n isLeaving(item.id) ? ` ${rowLeavingClass}` : ''\n }`}\n data-leaving={isLeaving(item.id) ? '' : undefined}\n data-reflow-id={item.id}\n data-task-id={item.id}\n />\n ))}\n </ul>\n </li>\n ))}\n </ol>\n {loadingMore ? skeletonRow('loading-more') : null}\n {moreAvailable && onLoadMore && !loading ? (\n <div className=\"ds:flex ds:justify-center ds:py-[var(--spacing-sm)]\">\n {/* Stays mounted while the page loads, without `disabled`, so\n focus is not thrown out of the panel. */}\n <Button\n intent=\"ghost\"\n size=\"sm\"\n aria-busy={loadingMore || undefined}\n aria-disabled={loadingMore || undefined}\n onClick={() => {\n if (loadingMore) return;\n requestMore();\n }}\n >\n {t('tasksPanel.loadMore')}\n </Button>\n </div>\n ) : null}\n </div>\n </>\n );\n\n let body: ReactNode;\n if (serverMode) {\n const anyUnsettled = [...pending.values()].some((w) => !w.settled);\n // Filtered empty means \"not the default query\", so an empty default\n // query reads as first use rather than offering Clear filters.\n const anyFilter = !sameQuery(\n {\n status: currentStatus,\n type: currentType,\n assignee: currentAssignee,\n overdueOnly: effectiveOverdue,\n },\n baseline,\n );\n if (error && visible.length === 0) body = errorBody;\n else if (visible.length === 0 && (loading || anyUnsettled)) {\n body = skeletonBody;\n } else if (visible.length === 0) {\n body = anyFilter ? filteredEmptyBody : firstUseBody;\n } else body = listBody;\n } else if (error) body = errorBody;\n else if (loading) body = skeletonBody;\n else if (items.length === 0) body = firstUseBody;\n else if (visible.length === 0) body = filteredEmptyBody;\n else body = listBody;\n\n /* One live region for the panel's whole life, filled a render after it\n mounts: a region inserted already holding its text is often not read. */\n const skeletonShown = body === skeletonBody;\n const [loadingSaid, setLoadingSaid] = useState(false);\n useEffect(() => {\n setLoadingSaid(skeletonShown);\n }, [skeletonShown]);\n\n /* ----- Header ----- */\n // The host's total, shown as given. The bracketed figure is for the\n // eye; a screen reader hears \"42 tasks\" instead.\n const headerTitle: ReactNode =\n totalCount === undefined ? (\n heading\n ) : (\n <>\n {heading}\n <span\n aria-hidden=\"true\"\n data-total-count=\"\"\n className=\"ds:ms-[var(--spacing-2xs)] ds:text-[color:var(--muted-foreground)]\"\n >\n {bracketed(totalCount)}\n </span>\n <VisuallyHidden>\n {` ${t('tasksPanel.totalCount', { count: totalCount })}`}\n </VisuallyHidden>\n </>\n );\n\n /* ----- Filter header ----- */\n const showScopeSegment = (availableScopes?.length ?? 0) > 1;\n const statusValues: TasksPanelStatusFilter[] = ['todo', 'done', 'all'];\n\n // Add-task affordance lives in the PanelHeader action cluster (inline-end of\n // the title row); the rail injects the favourite / close after it.\n const headerActions =\n onAddTask && !readOnly ? (\n <IconButton\n icon={<Plus />}\n intent=\"outline\"\n size=\"sm\"\n aria-label={t('tasksPanel.add')}\n data-action=\"add-task\"\n onClick={onAddTask}\n />\n ) : undefined;\n\n const showStatusFilter = filterSeams.status;\n const showTypeFilter = !!typeOptions?.length && filterSeams.type;\n const showAssigneeFilter =\n !!assigneeOptions?.length && filterSeams.assignee;\n const showOverdueFilter = filterSeams.overdueOnly;\n const filtersShown =\n showFilters &&\n (showStatusFilter ||\n showTypeFilter ||\n showAssigneeFilter ||\n showOverdueFilter);\n\n // Scope segment + filter controls share the PanelHeader filters row, stacked\n // so the scope segment keeps its own line above the filter cluster.\n const headerFilters =\n showScopeSegment || filtersShown ? (\n <div className=\"ds:flex ds:w-full ds:flex-col ds:gap-[var(--spacing-sm)]\">\n {showScopeSegment ? (\n <ButtonGroup label={t('tasksPanel.scope.label')}>\n {availableScopes!.map((value) => {\n const active = currentScope === value;\n return (\n <Button\n key={value}\n intent={active ? 'primary' : 'outline'}\n size=\"sm\"\n aria-pressed={active}\n onClick={() => changeScope(value)}\n >\n {scopeLabels[value]}\n </Button>\n );\n })}\n </ButtonGroup>\n ) : null}\n\n {filtersShown ? (\n <div className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-sm)]\">\n {showStatusFilter ? (\n <ButtonGroup label={t('tasksPanel.status.label')}>\n {statusValues.map((value) => {\n const active = currentStatus === value;\n return (\n <Button\n key={value}\n intent={active ? 'primary' : 'outline'}\n size=\"sm\"\n aria-pressed={active}\n data-status-filter={value}\n onClick={() => commitFilters({ status: value })}\n >\n {statusLabels[value]}\n </Button>\n );\n })}\n </ButtonGroup>\n ) : null}\n\n {showTypeFilter ? (\n <Select\n size=\"sm\"\n clearable\n aria-label={t('tasksPanel.type.label')}\n placeholder={t('tasksPanel.type.placeholder')}\n options={typeOptions}\n value={currentType ?? ''}\n onValueChange={(value) =>\n commitFilters({ type: value || null })\n }\n />\n ) : null}\n\n {showAssigneeFilter ? (\n <Select\n size=\"sm\"\n clearable\n aria-label={t('tasksPanel.assignee.label')}\n placeholder={t('tasksPanel.assignee.placeholder')}\n options={assigneeOptions}\n value={currentAssignee ?? ''}\n onValueChange={(value) =>\n commitFilters({ assignee: value || null })\n }\n />\n ) : null}\n\n {showOverdueFilter ? (\n <Switch\n id={overdueSwitchId}\n size=\"sm\"\n label={t('tasksPanel.overdueOnly')}\n checked={effectiveOverdue}\n disabled={serverMode && currentStatus === 'done'}\n onCheckedChange={(next) =>\n commitFilters({ overdueOnly: next })\n }\n />\n ) : null}\n </div>\n ) : null}\n </div>\n ) : undefined;\n\n return (\n <section\n ref={innerRef}\n data-component=\"tasks-panel\"\n data-component-id={id}\n aria-labelledby={ariaLabel ? undefined : headingId}\n aria-label={ariaLabel}\n className={rootVariants({ size, className })}\n {...rest}\n >\n <PanelHeader\n title={headerTitle}\n titleTooltip={\n totalCount === undefined\n ? undefined\n : t('tasksPanel.titleWithCount', {\n title: heading,\n value: numbers.format(totalCount),\n })\n }\n icon={icon ?? <ClipboardCheck />}\n headingId={headingId}\n actions={headerActions}\n filters={headerFilters}\n />\n\n <p role=\"status\" className=\"ds:sr-only\">\n {loadingSaid ? t('common.loading') : null}\n </p>\n {body}\n </section>\n );\n },\n);\n\nTasksPanel.displayName = 'TasksPanel';\n\n/* -------------------------------------------------------------------- */\n/* Bucket header — sticky label per due bucket */\n/* -------------------------------------------------------------------- */\n\ninterface BucketHeaderProps {\n bucketKey: BucketKey;\n /** The bucket's count, formatted and bracketed for the locale. */\n countLabel: string;\n /** Off while the list is a partial page, when the count would be wrong. */\n showCount?: boolean;\n label: string;\n headerRef?: React.MutableRefObject<HTMLElement | null>;\n /** Tracked by `useListReflow` so the header travels with its rows. */\n reflowId?: string;\n /** The bucket's last row is on its way out, so the header goes too. */\n leaving?: boolean;\n}\n\nfunction BucketHeader({\n bucketKey,\n countLabel,\n showCount = true,\n label,\n headerRef,\n reflowId,\n leaving = false,\n}: BucketHeaderProps): ReactNode {\n // Overdue is tinted destructive, Today brand (+ a decorative leading dot);\n // both clear AA on the --card surface in every theme (verified via axe on the\n // stories). z-[2] sits ABOVE the reused TaskCard's z-[1] action overlay so the\n // sticky header is never painted under a card scrolling beneath it.\n const tone =\n bucketKey === 'overdue'\n ? 'ds:text-[color:var(--destructive)] ds:font-semibold'\n : bucketKey === 'today'\n ? 'ds:text-[color:var(--primary)] ds:font-semibold'\n : 'ds:text-[color:var(--muted-foreground)]';\n return (\n <div\n ref={headerRef as React.Ref<HTMLDivElement>}\n data-bucket={bucketKey}\n data-reflow-id={reflowId}\n data-leaving={leaving ? '' : undefined}\n className={[\n 'ds:sticky ds:top-0 ds:z-[2] ds:bg-[color:var(--card)] ds:py-[var(--spacing-2xs)]',\n 'ds:flex ds:items-center ds:gap-[var(--spacing-2xs)] type-eyebrow',\n // A header travels with its bucket, and leaves with it: a heading\n // left standing over nothing, or snapping while its rows glide,\n // reads as two lists rather than one.\n REFLOW_ROW_CLASS,\n 'ds:transition-opacity ds:duration-[var(--animation-duration)]',\n 'ds:ease-[var(--ease-out)] ds:motion-reduce:transition-none',\n leaving ? rowLeavingClass : '',\n tone,\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {bucketKey === 'today' ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:size-1.5 ds:shrink-0 ds:rounded-[var(--radius-full)] ds:bg-[color:var(--primary)]\"\n />\n ) : null}\n {label}\n {showCount ? (\n <span\n data-bucket-count=\"\"\n className=\"ds:text-[color:var(--muted-foreground)]\"\n >\n {countLabel}\n </span>\n ) : null}\n </div>\n );\n}\n\n/** Re-export of the size variant union for downstream typing. */\nexport type TasksPanelSize = NonNullable<\n VariantProps<typeof rootVariants>['size']\n>;\n"],"names":["__iconNode","Coins","createLucideIcon","Gem","Megaphone","Tag","tasksPanelAgent","handle","args","EDGE_LOAD_THRESHOLD","DEFAULT_FILTERS","EMPTY_PENDING","EMPTY_HIDDEN","sigOf","items","i","sameFilters","a","b","sameQuery","handledRejection","reason","rejected","numberFormatFor","language","handledAnswer","result","answer","rootVariants","cva","scrollRegionClasses","rowElevationClass","rowLeavingClass","TICK_LENGTH","TaskDoneCheckbox","item","checked","pending","label","reduceMotion","onToggle","shown","drawing","toggle","useCheckAnimation","latestRef","useRef","tone","jsx","next","attempt","now","jsxs","SYSTEM_TYPE_META","BUCKET_ORDER","startOfDay","d","dayBoundaries","today","tomorrow","dayAfter","dow","nextWeek","bucketFor","done","startOfToday","startOfTomorrow","startOfDayAfter","startOfNextWeek","due","isOverdue","groupByDueBucket","isDone","map","key","list","buckets","TasksPanel","forwardRef","id","nowIso","title","icon","totalCount","size","filtering","onOpenTask","onToggleDone","onEditTask","onDismissTask","onAddTask","readOnly","renderItemActions","renderItemExtraActions","scope","defaultScope","onScopeChange","availableScopes","onLoadMore","hasMore","loadingMore","loading","error","onRetry","showFilters","defaultFilters","onFiltersChange","statusFilter","defaultStatusFilter","onStatusFilterChange","typeOptions","typeFilter","onTypeFilterChange","assigneeOptions","assigneeFilter","onAssigneeFilterChange","overdueOnly","defaultOverdueOnly","onOverdueOnlyChange","emptyTitle","emptyDescription","emptyAction","className","ariaLabel","rest","ref","t","i18n","useTranslation","headingId","useId","overdueSwitchId","heading","serverMode","filterSeams","statusLabels","scopeLabels","bucketLabels","systemTypeLabels","useMemo","numbers","bracketed","count","scopeState","setScopeState","useState","currentScope","changeScope","useCallback","baseline","statusState","setStatusState","typeState","setTypeState","assigneeState","setAssigneeState","overdueState","setOverdueState","currentStatus","currentType","currentAssignee","currentOverdueOnly","effectiveOverdue","filtersRef","commitFilters","requested","patch","field","prev","touched","clearFilters","setPendingState","pendingRef","hidden","setHiddenState","hiddenRef","mountedRef","unsettledRef","useEffect","unsettled","reject","updatePending","edit","updateHidden","visible","write","orderedIds","bucket","scrollRef","overdueHeaderRef","fadeTop","setFadeTop","fadeBottom","setFadeBottom","updateEdges","region","scrollTop","scrollHeight","clientHeight","useIsomorphicLayoutEffect","observer","moreAvailable","itemsRef","itemsSig","idsSig","idsSigRef","loadEdgesRef","prevLoadingRef","armedRef","idsAtFireRef","edgesAtFireRef","requestMore","handleScroll","resolvedTheme","useTheme","reflowRef","useListReflow","doneExit","useExitTransition","dismissExit","isLeaving","rowId","leavesOnDone","status","overdue","rollback","m","s","reconcile","sig","byId","dropped","stillListed","hostAgrees","listMoved","settle","startServerWrite","call","exit","err","hostPromise","refuse","release","tellAfterExit","resolve","res","rej","runToggleDone","nextFromBox","leaves","runDismiss","jumpToOverdue","el","delta","innerRef","useImperativeHandle","focusRef","orderedIdsRef","root","onFocusIn","event","_a","_b","onFocusOut","to","from","record","active","ids","inRow","target","actionsRef","actions","noTask","targetId","found","useAgentRegistration","renderTypeBadge","meta","variant","Icon","Badge","defaultActions","Fragment","IconButton","Pencil","X","renderRowActions","extra","trailing","badge","onBoxToggle","skeletonRow","Skeleton","errorBody","EmptyState","skeletonBody","firstUseBody","anyFilterSeam","filteredEmptyBody","inlineError","Alert","Button","listBody","node","BucketHeader","row","TaskCard","REFLOW_ROW_CLASS","body","anyUnsettled","w","anyFilter","skeletonShown","loadingSaid","setLoadingSaid","headerTitle","VisuallyHidden","showScopeSegment","statusValues","headerActions","Plus","showStatusFilter","showTypeFilter","showAssigneeFilter","showOverdueFilter","filtersShown","headerFilters","ButtonGroup","value","Select","Switch","PanelHeader","ClipboardCheck","bucketKey","countLabel","showCount","headerRef","reflowId","leaving"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}