@alfadocs/ui-kit-debug 1.12.5 → 1.13.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 (138) hide show
  1. package/dist/_chunks/{actions-cell-renderer-DnSLrgQD.js → actions-cell-renderer-ReurEy5i.js} +2 -2
  2. package/dist/_chunks/{actions-cell-renderer-DnSLrgQD.js.map → actions-cell-renderer-ReurEy5i.js.map} +1 -1
  3. package/dist/_chunks/{address-fields-CZP4Wncx.js → address-fields-CZ0pEdEI.js} +4 -4
  4. package/dist/_chunks/{address-fields-CZP4Wncx.js.map → address-fields-CZ0pEdEI.js.map} +1 -1
  5. package/dist/_chunks/{ai-prompt-input-DnbfEJnr.js → ai-prompt-input-CrHr-5H8.js} +2 -2
  6. package/dist/_chunks/{ai-prompt-input-DnbfEJnr.js.map → ai-prompt-input-CrHr-5H8.js.map} +1 -1
  7. package/dist/_chunks/{anamnesis-summary-rows-BfhxWPO3.js → anamnesis-summary-rows-CRWO8x8g.js} +4 -4
  8. package/dist/_chunks/{anamnesis-summary-rows-BfhxWPO3.js.map → anamnesis-summary-rows-CRWO8x8g.js.map} +1 -1
  9. package/dist/_chunks/{audio-recorder-EWBCNIsd.js → audio-recorder-DXG6LTtO.js} +2 -2
  10. package/dist/_chunks/{audio-recorder-EWBCNIsd.js.map → audio-recorder-DXG6LTtO.js.map} +1 -1
  11. package/dist/_chunks/{autocomplete-BrONKN8l.js → autocomplete-MpBhz-fG.js} +86 -74
  12. package/dist/_chunks/{autocomplete-BrONKN8l.js.map → autocomplete-MpBhz-fG.js.map} +1 -1
  13. package/dist/_chunks/{balance-badge-cell-7L6nzB29.js → balance-badge-cell--iQ_gtmi.js} +4 -4
  14. package/dist/_chunks/{balance-badge-cell-7L6nzB29.js.map → balance-badge-cell--iQ_gtmi.js.map} +1 -1
  15. package/dist/_chunks/{bishop-score-Cnu0xs-z.js → bishop-score-CJUVBfAu.js} +2 -2
  16. package/dist/_chunks/{bishop-score-Cnu0xs-z.js.map → bishop-score-CJUVBfAu.js.map} +1 -1
  17. package/dist/_chunks/{booking-CBHKdsZl.js → booking-DQbo6mQF.js} +609 -591
  18. package/dist/_chunks/booking-DQbo6mQF.js.map +1 -0
  19. package/dist/_chunks/{care-plan-card-aDN4oem9.js → care-plan-card-D-FMfDKH.js} +2 -2
  20. package/dist/_chunks/{care-plan-card-aDN4oem9.js.map → care-plan-card-D-FMfDKH.js.map} +1 -1
  21. package/dist/_chunks/{care-plan-entry-card-BEhANdBE.js → care-plan-entry-card-Bvw_9T-d.js} +2 -2
  22. package/dist/_chunks/{care-plan-entry-card-BEhANdBE.js.map → care-plan-entry-card-Bvw_9T-d.js.map} +1 -1
  23. package/dist/_chunks/{care-plan-header-CkpPyQqG.js → care-plan-header-B5CBE0zu.js} +2 -2
  24. package/dist/_chunks/{care-plan-header-CkpPyQqG.js.map → care-plan-header-B5CBE0zu.js.map} +1 -1
  25. package/dist/_chunks/{city-input-towzBenY.js → city-input-DaQc-Hbj.js} +2 -2
  26. package/dist/_chunks/{city-input-towzBenY.js.map → city-input-DaQc-Hbj.js.map} +1 -1
  27. package/dist/_chunks/{combobox-DiMLItyu.js → combobox-D7_NLE2Z.js} +89 -81
  28. package/dist/_chunks/{combobox-DiMLItyu.js.map → combobox-D7_NLE2Z.js.map} +1 -1
  29. package/dist/_chunks/{contact-profile-card-BMIBr5s9.js → contact-profile-card-BZqi8Hck.js} +38 -36
  30. package/dist/_chunks/{contact-profile-card-BMIBr5s9.js.map → contact-profile-card-BZqi8Hck.js.map} +1 -1
  31. package/dist/_chunks/{country-select-UEF9BEeQ.js → country-select-DzbPFktV.js} +2 -2
  32. package/dist/_chunks/{country-select-UEF9BEeQ.js.map → country-select-DzbPFktV.js.map} +1 -1
  33. package/dist/_chunks/{document-preview-oyx9RhCo.js → document-preview-CDb-n_W7.js} +2 -2
  34. package/dist/_chunks/{document-preview-oyx9RhCo.js.map → document-preview-CDb-n_W7.js.map} +1 -1
  35. package/dist/_chunks/{face-scheme-CZaKm6fG.js → face-scheme-DA2vjqaM.js} +2 -2
  36. package/dist/_chunks/{face-scheme-CZaKm6fG.js.map → face-scheme-DA2vjqaM.js.map} +1 -1
  37. package/dist/_chunks/{file-manager-C0y7HBAN.js → file-manager-UsD8e_AB.js} +2 -2
  38. package/dist/_chunks/{file-manager-C0y7HBAN.js.map → file-manager-UsD8e_AB.js.map} +1 -1
  39. package/dist/_chunks/{gestational-age-calculator-CxZelpu2.js → gestational-age-calculator-CiOQjzgx.js} +2 -2
  40. package/dist/_chunks/{gestational-age-calculator-CxZelpu2.js.map → gestational-age-calculator-CiOQjzgx.js.map} +1 -1
  41. package/dist/_chunks/key-value-pair-BIBdZBLg.js +188 -0
  42. package/dist/_chunks/key-value-pair-BIBdZBLg.js.map +1 -0
  43. package/dist/_chunks/{link-cell-renderer-CenJx-_7.js → link-cell-renderer-CIASXsVM.js} +4 -4
  44. package/dist/_chunks/{link-cell-renderer-CenJx-_7.js.map → link-cell-renderer-CIASXsVM.js.map} +1 -1
  45. package/dist/_chunks/{multi-select-DqL4o0qV.js → multi-select-DYOvx2SJ.js} +56 -48
  46. package/dist/_chunks/{multi-select-DqL4o0qV.js.map → multi-select-DYOvx2SJ.js.map} +1 -1
  47. package/dist/_chunks/{muscle-scheme-yfzP_xoJ.js → muscle-scheme-BSJsI4-I.js} +2 -2
  48. package/dist/_chunks/{muscle-scheme-yfzP_xoJ.js.map → muscle-scheme-BSJsI4-I.js.map} +1 -1
  49. package/dist/_chunks/{optical-prescription-Dj3Eh5Ok.js → optical-prescription-BvwuqTpl.js} +2 -2
  50. package/dist/_chunks/{optical-prescription-Dj3Eh5Ok.js.map → optical-prescription-BvwuqTpl.js.map} +1 -1
  51. package/dist/_chunks/{patient-details-xrqe13az.js → patient-details-BQaUzPqp.js} +5 -5
  52. package/dist/_chunks/{patient-details-xrqe13az.js.map → patient-details-BQaUzPqp.js.map} +1 -1
  53. package/dist/_chunks/{patient-search-D5ufYoRc.js → patient-search-HeEUB-_X.js} +2 -2
  54. package/dist/_chunks/{patient-search-D5ufYoRc.js.map → patient-search-HeEUB-_X.js.map} +1 -1
  55. package/dist/_chunks/{patient-summary-card-CBfuDvJ5.js → patient-summary-card-CvDxhbBR.js} +2 -2
  56. package/dist/_chunks/{patient-summary-card-CBfuDvJ5.js.map → patient-summary-card-CvDxhbBR.js.map} +1 -1
  57. package/dist/_chunks/{payment-request-card-YVCcCZ25.js → payment-request-card-lmKLwsDs.js} +2 -2
  58. package/dist/_chunks/{payment-request-card-YVCcCZ25.js.map → payment-request-card-lmKLwsDs.js.map} +1 -1
  59. package/dist/_chunks/{periodontal-chart-BatZEFar.js → periodontal-chart-B9fphroR.js} +2 -2
  60. package/dist/_chunks/{periodontal-chart-BatZEFar.js.map → periodontal-chart-B9fphroR.js.map} +1 -1
  61. package/dist/_chunks/{periodontal-chart-card-BBpY_rBc.js → periodontal-chart-card-qEZPXj83.js} +2 -2
  62. package/dist/_chunks/{periodontal-chart-card-BBpY_rBc.js.map → periodontal-chart-card-qEZPXj83.js.map} +1 -1
  63. package/dist/_chunks/{pregnancy-dating-DtToyMyc.js → pregnancy-dating-D2wchD11.js} +2 -2
  64. package/dist/_chunks/{pregnancy-dating-DtToyMyc.js.map → pregnancy-dating-D2wchD11.js.map} +1 -1
  65. package/dist/_chunks/{province-select-BDywtmL-.js → province-select-BBc7s7vR.js} +2 -2
  66. package/dist/_chunks/{province-select-BDywtmL-.js.map → province-select-BBc7s7vR.js.map} +1 -1
  67. package/dist/_chunks/{select-BW5ecXlX.js → select-Bi8zril7.js} +165 -136
  68. package/dist/_chunks/select-Bi8zril7.js.map +1 -0
  69. package/dist/_chunks/{signature-request-DVDTKLjM.js → signature-request-CUe903hj.js} +2 -2
  70. package/dist/_chunks/{signature-request-DVDTKLjM.js.map → signature-request-CUe903hj.js.map} +1 -1
  71. package/dist/_chunks/{tabs-CBb2AidH.js → tabs-DqKtTIjZ.js} +2 -2
  72. package/dist/_chunks/{tabs-CBb2AidH.js.map → tabs-DqKtTIjZ.js.map} +1 -1
  73. package/dist/_chunks/{tasks-panel-Do5SFp-j.js → tasks-panel-DPCNaRko.js} +2 -2
  74. package/dist/_chunks/{tasks-panel-Do5SFp-j.js.map → tasks-panel-DPCNaRko.js.map} +1 -1
  75. package/dist/_chunks/{tooth-scheme-WdyVymQ1.js → tooth-scheme-2IsmbE6w.js} +2 -2
  76. package/dist/_chunks/{tooth-scheme-WdyVymQ1.js.map → tooth-scheme-2IsmbE6w.js.map} +1 -1
  77. package/dist/_chunks/{unit-converter-BPumXMA6.js → unit-converter-C6jMjqL9.js} +2 -2
  78. package/dist/_chunks/{unit-converter-BPumXMA6.js.map → unit-converter-C6jMjqL9.js.map} +1 -1
  79. package/dist/_chunks/{workflow-map-DE_ribRM.js → workflow-map-wcw3t6g4.js} +2 -2
  80. package/dist/_chunks/{workflow-map-DE_ribRM.js.map → workflow-map-wcw3t6g4.js.map} +1 -1
  81. package/dist/agent-catalog.json +1 -1
  82. package/dist/components/_shared/option.d.ts +1 -0
  83. package/dist/components/_shared/option.d.ts.map +1 -1
  84. package/dist/components/address-fields/index.js +1 -1
  85. package/dist/components/ai-prompt-input/index.js +1 -1
  86. package/dist/components/audio-recorder/index.js +1 -1
  87. package/dist/components/autocomplete/autocomplete.d.ts.map +1 -1
  88. package/dist/components/autocomplete/index.js +1 -1
  89. package/dist/components/bishop-score/index.js +1 -1
  90. package/dist/components/booking/booking.d.ts.map +1 -1
  91. package/dist/components/booking/index.js +1 -1
  92. package/dist/components/care-plan-card/index.js +1 -1
  93. package/dist/components/care-plan-entry-card/index.js +1 -1
  94. package/dist/components/care-plan-header/index.js +1 -1
  95. package/dist/components/city-input/index.js +1 -1
  96. package/dist/components/combobox/combobox.d.ts.map +1 -1
  97. package/dist/components/combobox/index.js +1 -1
  98. package/dist/components/contact-profile-card/contact-profile-card.d.ts.map +1 -1
  99. package/dist/components/contact-profile-card/index.js +1 -1
  100. package/dist/components/country-select/index.js +1 -1
  101. package/dist/components/data-table/index.js +2 -2
  102. package/dist/components/document-preview/index.js +1 -1
  103. package/dist/components/face-scheme/index.js +1 -1
  104. package/dist/components/file-manager/index.js +1 -1
  105. package/dist/components/gestational-age-calculator/index.js +1 -1
  106. package/dist/components/key-value-pair/index.js +1 -1
  107. package/dist/components/key-value-pair/key-value-pair.d.ts +16 -0
  108. package/dist/components/key-value-pair/key-value-pair.d.ts.map +1 -1
  109. package/dist/components/multi-select/index.js +1 -1
  110. package/dist/components/multi-select/multi-select.d.ts.map +1 -1
  111. package/dist/components/muscle-scheme/index.js +1 -1
  112. package/dist/components/optical-prescription/index.js +1 -1
  113. package/dist/components/patient-details/index.js +1 -1
  114. package/dist/components/patient-search/index.js +1 -1
  115. package/dist/components/patient-summary-card/index.js +1 -1
  116. package/dist/components/patient-table/index.js +1 -1
  117. package/dist/components/payment-card/index.js +1 -1
  118. package/dist/components/periodontal-chart/index.js +1 -1
  119. package/dist/components/periodontal-chart-card/index.js +1 -1
  120. package/dist/components/pregnancy-dating/index.js +1 -1
  121. package/dist/components/province-select/index.js +1 -1
  122. package/dist/components/select/index.js +1 -1
  123. package/dist/components/select/select.d.ts +24 -0
  124. package/dist/components/select/select.d.ts.map +1 -1
  125. package/dist/components/skeleton-scheme/index.js +1 -1
  126. package/dist/components/tabs/index.js +1 -1
  127. package/dist/components/tasks-panel/index.js +1 -1
  128. package/dist/components/tooth-scheme/index.js +1 -1
  129. package/dist/components/unit-converter/index.js +1 -1
  130. package/dist/components/workflow/index.js +1 -1
  131. package/dist/index.js +40 -40
  132. package/dist/patterns/anamnesis/index.js +1 -1
  133. package/dist/patterns/signature-request/index.js +1 -1
  134. package/package.json +1 -1
  135. package/dist/_chunks/booking-CBHKdsZl.js.map +0 -1
  136. package/dist/_chunks/key-value-pair-BubG4fUa.js +0 -144
  137. package/dist/_chunks/key-value-pair-BubG4fUa.js.map +0 -1
  138. package/dist/_chunks/select-BW5ecXlX.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"tasks-panel-Do5SFp-j.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`. */\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 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 }) => {\n handle.toggleDone(args.id);\n },\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 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 }) => {\n handle.dismiss(args.id);\n },\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.',\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 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 SquareCheckBig,\n Coins,\n Gem,\n ClipboardCheck,\n Megaphone,\n Pencil,\n Plus,\n Square,\n Tag,\n X,\n} from 'lucide-react';\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 { 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\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/**\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 */\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 toggleDone: (id: string) => void;\n dismiss: (id: string) => 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 /** Visual density forwarded to each TaskCard. Defaults to `xs` — the compact rail row. */\n size?: 'xs' | 'sm' | 'md';\n /** Fires when a row is activated. */\n onOpenTask?: (item: TasksPanelItem) => void;\n /** Fires when the host should toggle a task's done state. */\n onToggleDone?: (item: TasksPanelItem) => 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 /** Fires when the host should dismiss / remove a task. Omit to hide the per-row dismiss action. */\n onDismissTask?: (item: TasksPanelItem) => 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). 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 /* ----- 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 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. */\n hasMore?: boolean;\n /** Show the bottom loading row while the next page is fetched. */\n loadingMore?: boolean;\n /** Full-panel initial loading state (skeleton rows in the body). */\n loading?: boolean;\n /** Error surface — `true` for the default error EmptyState, or a custom node. */\n error?: boolean | ReactNode;\n\n /* ----- Filters (mirror platform TaskFilterType) ----- */\n /** Show the filter header (status segment + type / assignee selects + overdue toggle). Default `true`. */\n showFilters?: boolean;\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/* -------------------------------------------------------------------- */\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: 'xs' },\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-sm)] 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 — a subtle lift over the panel\n surface so rows read as raised. TaskCard owns its own border + radius.\n Uses `--shadow-sm` (not the heavier `--shadow-card`/`--shadow-lg`): the\n scroll region is `overflow-y:auto` (so `overflow-x` computes to `auto` and\n clips) with only an `--spacing-sm` gutter, and a wide 30px-blur card shadow\n gets sliced with a hard edge at that gutter. A small row shadow fits. */\nconst rowElevationClass =\n 'ds:shadow-[var(--shadow-sm)] ds:bg-[color:var(--card)]';\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, now: Date): BucketKey {\n if (item.status === '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(items: TasksPanelItem[], now: Date): Bucket[] {\n const map = new Map<BucketKey, TasksPanelItem[]>();\n for (const item of items) {\n const key = bucketFor(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 size = 'xs',\n onOpenTask,\n onToggleDone,\n onEditTask,\n onDismissTask,\n onAddTask,\n readOnly = false,\n renderItemActions,\n scope,\n defaultScope,\n onScopeChange,\n availableScopes,\n onLoadMore,\n hasMore,\n loadingMore = false,\n loading = false,\n error = false,\n showFilters = true,\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 } = useTranslation();\n const headingId = useId();\n const overdueSwitchId = useId();\n const heading = title ?? t('tasksPanel.title');\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 /* ----- Controlled / uncontrolled filter + 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 const [statusState, setStatusState] = useState<TasksPanelStatusFilter>(\n defaultStatusFilter ?? 'todo',\n );\n const currentStatus = statusFilter ?? statusState;\n const changeStatus = useCallback(\n (next: TasksPanelStatusFilter) => {\n if (statusFilter === undefined) setStatusState(next);\n onStatusFilterChange?.(next);\n },\n [statusFilter, onStatusFilterChange],\n );\n\n const [typeState, setTypeState] = useState<string | null>(null);\n const currentType = typeFilter !== undefined ? typeFilter : typeState;\n const changeType = useCallback(\n (next: string | null) => {\n if (typeFilter === undefined) setTypeState(next);\n onTypeFilterChange?.(next);\n },\n [typeFilter, onTypeFilterChange],\n );\n\n const [assigneeState, setAssigneeState] = useState<string | null>(null);\n const currentAssignee =\n assigneeFilter !== undefined ? assigneeFilter : assigneeState;\n const changeAssignee = useCallback(\n (next: string | null) => {\n if (assigneeFilter === undefined) setAssigneeState(next);\n onAssigneeFilterChange?.(next);\n },\n [assigneeFilter, onAssigneeFilterChange],\n );\n\n const [overdueState, setOverdueState] = useState<boolean>(\n defaultOverdueOnly ?? false,\n );\n const currentOverdueOnly = overdueOnly ?? overdueState;\n const changeOverdueOnly = useCallback(\n (next: boolean) => {\n if (overdueOnly === undefined) setOverdueState(next);\n onOverdueOnlyChange?.(next);\n },\n [overdueOnly, onOverdueOnlyChange],\n );\n\n const clearFilters = useCallback(() => {\n changeStatus('todo');\n changeType(null);\n changeAssignee(null);\n changeOverdueOnly(false);\n }, [changeStatus, changeType, changeAssignee, changeOverdueOnly]);\n\n /* ----- Filter → bucket ----- */\n const visible = useMemo(() => {\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 items,\n currentStatus,\n currentType,\n currentAssignee,\n currentOverdueOnly,\n now,\n ]);\n\n const buckets = useMemo(\n () => groupByDueBucket(visible, now),\n [visible, now],\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 const moreAvailable = hasMore ?? !!onLoadMore;\n const handleScroll = useCallback(() => {\n updateEdges();\n const region = scrollRef.current;\n if (!region) return;\n const { scrollTop, scrollHeight, clientHeight } = region;\n if (\n onLoadMore &&\n moreAvailable &&\n !loadingMore &&\n scrollHeight - scrollTop - clientHeight <= EDGE_LOAD_THRESHOLD\n ) {\n onLoadMore();\n }\n }, [updateEdges, onLoadMore, moreAvailable, loadingMore]);\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 /* ----- Agent handle ----- */\n const itemsRef = useRef<TasksPanelItem[]>(items);\n itemsRef.current = items;\n const innerRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => innerRef.current as HTMLElement, []);\n\n const handle = useMemo<TasksPanelHandle>(\n () => ({\n getItems: () =>\n itemsRef.current.map((i) => ({\n id: i.id,\n status: i.status ?? 'open',\n })),\n selectItem: (targetId) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onOpenTask?.(found);\n },\n toggleDone: (targetId) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onToggleDone?.(found);\n },\n dismiss: (targetId) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onDismissTask?.(found);\n },\n jumpToOverdue,\n setFilter: (next) => {\n if (next.status !== undefined) changeStatus(next.status);\n if (next.type !== undefined) changeType(next.type);\n if (next.assignee !== undefined) changeAssignee(next.assignee);\n if (next.overdueOnly !== undefined)\n changeOverdueOnly(next.overdueOnly);\n },\n changeScope,\n loadMore: () => onLoadMore?.(),\n }),\n [\n onOpenTask,\n onToggleDone,\n onDismissTask,\n jumpToOverdue,\n changeStatus,\n changeType,\n changeAssignee,\n changeOverdueOnly,\n changeScope,\n onLoadMore,\n ],\n );\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 const label = item.typeLabel ?? systemTypeLabels[item.type] ?? item.type;\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 const done = item.status === 'done';\n return (\n <>\n {onToggleDone ? (\n <IconButton\n icon={done ? <SquareCheckBig /> : <Square />}\n intent=\"ghost\"\n size=\"sm\"\n aria-label={t(\n done ? 'tasksPanel.markNotDone' : 'tasksPanel.markDone',\n )}\n onClick={() => onToggleDone(item)}\n />\n ) : null}\n {onEditTask ? (\n <IconButton\n icon={<Pencil />}\n intent=\"ghost\"\n size=\"sm\"\n aria-label={t('tasksPanel.edit')}\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 onClick={() => onDismissTask(item)}\n />\n ) : null}\n </>\n );\n };\n\n const renderRowActions = (item: TasksPanelItem): ReactNode => {\n const custom = !readOnly ? renderItemActions?.(item) : null;\n const trailing = custom ?? defaultActions(item);\n const badge = renderTypeBadge(item);\n if (!badge && !trailing) return undefined;\n return (\n <>\n {badge}\n {trailing}\n </>\n );\n };\n\n /* ----- Body branches ----- */\n const isFirstUseEmpty = !loading && !error && items.length === 0;\n const isFilteredEmpty =\n !loading && !error && items.length > 0 && visible.length === 0;\n\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 let body: ReactNode;\n if (error) {\n body = (\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 />\n ) : (\n error\n )}\n </div>\n );\n } else if (loading) {\n body = (\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 } else if (isFirstUseEmpty) {\n body = (\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 } else if (isFilteredEmpty) {\n body = (\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 label: t('tasksPanel.filteredEmpty.clear'),\n onClick: clearFilters,\n }}\n />\n </div>\n );\n } else {\n body = (\n <div\n ref={scrollRef}\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-fade-top={fadeTop ? 'true' : undefined}\n data-fade-bottom={fadeBottom ? 'true' : undefined}\n className={scrollRegionClasses}\n >\n <ol className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-md)] ds:p-0\">\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 count={bucket.items.length}\n label={bucketLabels[bucket.key]}\n headerRef={\n bucket.key === 'overdue' ? overdueHeaderRef : undefined\n }\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 className={rowElevationClass}\n data-task-id={item.id}\n />\n ))}\n </ul>\n </li>\n ))}\n </ol>\n {loadingMore ? skeletonRow('loading-more') : null}\n {!loadingMore && moreAvailable && onLoadMore ? (\n <div className=\"ds:flex ds:justify-center ds:py-[var(--spacing-sm)]\">\n <Button intent=\"ghost\" size=\"sm\" onClick={onLoadMore}>\n {t('tasksPanel.loadMore')}\n </Button>\n </div>\n ) : null}\n </div>\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 onClick={onAddTask}\n />\n ) : undefined;\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 || showFilters ? (\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 {showFilters ? (\n <div className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-sm)]\">\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 onClick={() => changeStatus(value)}\n >\n {statusLabels[value]}\n </Button>\n );\n })}\n </ButtonGroup>\n\n {typeOptions && typeOptions.length > 0 ? (\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) => changeType(value || null)}\n />\n ) : null}\n\n {assigneeOptions && assigneeOptions.length > 0 ? (\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) => changeAssignee(value || null)}\n />\n ) : null}\n\n <Switch\n id={overdueSwitchId}\n size=\"sm\"\n label={t('tasksPanel.overdueOnly')}\n checked={currentOverdueOnly}\n onCheckedChange={changeOverdueOnly}\n />\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={heading}\n icon={<ClipboardCheck />}\n headingId={headingId}\n actions={headerActions}\n filters={headerFilters}\n />\n\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 count: number;\n label: string;\n headerRef?: React.MutableRefObject<HTMLElement | null>;\n}\n\nfunction BucketHeader({\n bucketKey,\n count,\n label,\n headerRef,\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 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 tone,\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 <span className=\"ds:text-[color:var(--muted-foreground)]\">\n {`(${count})`}\n </span>\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","rootVariants","cva","scrollRegionClasses","rowElevationClass","SYSTEM_TYPE_META","BUCKET_ORDER","startOfDay","d","dayBoundaries","now","today","tomorrow","dayAfter","dow","nextWeek","bucketFor","item","startOfToday","startOfTomorrow","startOfDayAfter","startOfNextWeek","due","isOverdue","groupByDueBucket","items","map","key","list","buckets","a","b","TasksPanel","forwardRef","id","nowIso","title","size","onOpenTask","onToggleDone","onEditTask","onDismissTask","onAddTask","readOnly","renderItemActions","scope","defaultScope","onScopeChange","availableScopes","onLoadMore","hasMore","loadingMore","loading","error","showFilters","statusFilter","defaultStatusFilter","onStatusFilterChange","typeOptions","typeFilter","onTypeFilterChange","assigneeOptions","assigneeFilter","onAssigneeFilterChange","overdueOnly","defaultOverdueOnly","onOverdueOnlyChange","emptyTitle","emptyDescription","emptyAction","className","ariaLabel","rest","ref","t","useTranslation","headingId","useId","overdueSwitchId","heading","statusLabels","scopeLabels","bucketLabels","systemTypeLabels","useMemo","scopeState","setScopeState","useState","currentScope","changeScope","useCallback","next","statusState","setStatusState","currentStatus","changeStatus","typeState","setTypeState","currentType","changeType","assigneeState","setAssigneeState","currentAssignee","changeAssignee","overdueState","setOverdueState","currentOverdueOnly","changeOverdueOnly","clearFilters","visible","isDone","scrollRef","useRef","overdueHeaderRef","fadeTop","setFadeTop","fadeBottom","setFadeBottom","updateEdges","region","scrollTop","scrollHeight","clientHeight","useIsomorphicLayoutEffect","observer","moreAvailable","handleScroll","jumpToOverdue","el","delta","itemsRef","innerRef","useImperativeHandle","i","targetId","found","useAgentRegistration","renderTypeBadge","meta","variant","Icon","label","jsx","Badge","defaultActions","done","jsxs","Fragment","IconButton","SquareCheckBig","Square","Pencil","X","renderRowActions","trailing","badge","isFirstUseEmpty","isFilteredEmpty","skeletonRow","Skeleton","body","EmptyState","bucket","BucketHeader","TaskCard","Button","showScopeSegment","statusValues","headerActions","Plus","headerFilters","ButtonGroup","value","active","Select","Switch","PanelHeader","ClipboardCheck","bucketKey","count","headerRef"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}
1
+ {"version":3,"file":"tasks-panel-DPCNaRko.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`. */\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 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 }) => {\n handle.toggleDone(args.id);\n },\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 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 }) => {\n handle.dismiss(args.id);\n },\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.',\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 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 SquareCheckBig,\n Coins,\n Gem,\n ClipboardCheck,\n Megaphone,\n Pencil,\n Plus,\n Square,\n Tag,\n X,\n} from 'lucide-react';\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 { 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\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/**\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 */\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 toggleDone: (id: string) => void;\n dismiss: (id: string) => 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 /** Visual density forwarded to each TaskCard. Defaults to `xs` — the compact rail row. */\n size?: 'xs' | 'sm' | 'md';\n /** Fires when a row is activated. */\n onOpenTask?: (item: TasksPanelItem) => void;\n /** Fires when the host should toggle a task's done state. */\n onToggleDone?: (item: TasksPanelItem) => 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 /** Fires when the host should dismiss / remove a task. Omit to hide the per-row dismiss action. */\n onDismissTask?: (item: TasksPanelItem) => 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). 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 /* ----- 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 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. */\n hasMore?: boolean;\n /** Show the bottom loading row while the next page is fetched. */\n loadingMore?: boolean;\n /** Full-panel initial loading state (skeleton rows in the body). */\n loading?: boolean;\n /** Error surface — `true` for the default error EmptyState, or a custom node. */\n error?: boolean | ReactNode;\n\n /* ----- Filters (mirror platform TaskFilterType) ----- */\n /** Show the filter header (status segment + type / assignee selects + overdue toggle). Default `true`. */\n showFilters?: boolean;\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/* -------------------------------------------------------------------- */\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: 'xs' },\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-sm)] 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 — a subtle lift over the panel\n surface so rows read as raised. TaskCard owns its own border + radius.\n Uses `--shadow-sm` (not the heavier `--shadow-card`/`--shadow-lg`): the\n scroll region is `overflow-y:auto` (so `overflow-x` computes to `auto` and\n clips) with only an `--spacing-sm` gutter, and a wide 30px-blur card shadow\n gets sliced with a hard edge at that gutter. A small row shadow fits. */\nconst rowElevationClass =\n 'ds:shadow-[var(--shadow-sm)] ds:bg-[color:var(--card)]';\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, now: Date): BucketKey {\n if (item.status === '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(items: TasksPanelItem[], now: Date): Bucket[] {\n const map = new Map<BucketKey, TasksPanelItem[]>();\n for (const item of items) {\n const key = bucketFor(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 size = 'xs',\n onOpenTask,\n onToggleDone,\n onEditTask,\n onDismissTask,\n onAddTask,\n readOnly = false,\n renderItemActions,\n scope,\n defaultScope,\n onScopeChange,\n availableScopes,\n onLoadMore,\n hasMore,\n loadingMore = false,\n loading = false,\n error = false,\n showFilters = true,\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 } = useTranslation();\n const headingId = useId();\n const overdueSwitchId = useId();\n const heading = title ?? t('tasksPanel.title');\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 /* ----- Controlled / uncontrolled filter + 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 const [statusState, setStatusState] = useState<TasksPanelStatusFilter>(\n defaultStatusFilter ?? 'todo',\n );\n const currentStatus = statusFilter ?? statusState;\n const changeStatus = useCallback(\n (next: TasksPanelStatusFilter) => {\n if (statusFilter === undefined) setStatusState(next);\n onStatusFilterChange?.(next);\n },\n [statusFilter, onStatusFilterChange],\n );\n\n const [typeState, setTypeState] = useState<string | null>(null);\n const currentType = typeFilter !== undefined ? typeFilter : typeState;\n const changeType = useCallback(\n (next: string | null) => {\n if (typeFilter === undefined) setTypeState(next);\n onTypeFilterChange?.(next);\n },\n [typeFilter, onTypeFilterChange],\n );\n\n const [assigneeState, setAssigneeState] = useState<string | null>(null);\n const currentAssignee =\n assigneeFilter !== undefined ? assigneeFilter : assigneeState;\n const changeAssignee = useCallback(\n (next: string | null) => {\n if (assigneeFilter === undefined) setAssigneeState(next);\n onAssigneeFilterChange?.(next);\n },\n [assigneeFilter, onAssigneeFilterChange],\n );\n\n const [overdueState, setOverdueState] = useState<boolean>(\n defaultOverdueOnly ?? false,\n );\n const currentOverdueOnly = overdueOnly ?? overdueState;\n const changeOverdueOnly = useCallback(\n (next: boolean) => {\n if (overdueOnly === undefined) setOverdueState(next);\n onOverdueOnlyChange?.(next);\n },\n [overdueOnly, onOverdueOnlyChange],\n );\n\n const clearFilters = useCallback(() => {\n changeStatus('todo');\n changeType(null);\n changeAssignee(null);\n changeOverdueOnly(false);\n }, [changeStatus, changeType, changeAssignee, changeOverdueOnly]);\n\n /* ----- Filter → bucket ----- */\n const visible = useMemo(() => {\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 items,\n currentStatus,\n currentType,\n currentAssignee,\n currentOverdueOnly,\n now,\n ]);\n\n const buckets = useMemo(\n () => groupByDueBucket(visible, now),\n [visible, now],\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 const moreAvailable = hasMore ?? !!onLoadMore;\n const handleScroll = useCallback(() => {\n updateEdges();\n const region = scrollRef.current;\n if (!region) return;\n const { scrollTop, scrollHeight, clientHeight } = region;\n if (\n onLoadMore &&\n moreAvailable &&\n !loadingMore &&\n scrollHeight - scrollTop - clientHeight <= EDGE_LOAD_THRESHOLD\n ) {\n onLoadMore();\n }\n }, [updateEdges, onLoadMore, moreAvailable, loadingMore]);\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 /* ----- Agent handle ----- */\n const itemsRef = useRef<TasksPanelItem[]>(items);\n itemsRef.current = items;\n const innerRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => innerRef.current as HTMLElement, []);\n\n const handle = useMemo<TasksPanelHandle>(\n () => ({\n getItems: () =>\n itemsRef.current.map((i) => ({\n id: i.id,\n status: i.status ?? 'open',\n })),\n selectItem: (targetId) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onOpenTask?.(found);\n },\n toggleDone: (targetId) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onToggleDone?.(found);\n },\n dismiss: (targetId) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onDismissTask?.(found);\n },\n jumpToOverdue,\n setFilter: (next) => {\n if (next.status !== undefined) changeStatus(next.status);\n if (next.type !== undefined) changeType(next.type);\n if (next.assignee !== undefined) changeAssignee(next.assignee);\n if (next.overdueOnly !== undefined)\n changeOverdueOnly(next.overdueOnly);\n },\n changeScope,\n loadMore: () => onLoadMore?.(),\n }),\n [\n onOpenTask,\n onToggleDone,\n onDismissTask,\n jumpToOverdue,\n changeStatus,\n changeType,\n changeAssignee,\n changeOverdueOnly,\n changeScope,\n onLoadMore,\n ],\n );\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 const label = item.typeLabel ?? systemTypeLabels[item.type] ?? item.type;\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 const done = item.status === 'done';\n return (\n <>\n {onToggleDone ? (\n <IconButton\n icon={done ? <SquareCheckBig /> : <Square />}\n intent=\"ghost\"\n size=\"sm\"\n aria-label={t(\n done ? 'tasksPanel.markNotDone' : 'tasksPanel.markDone',\n )}\n onClick={() => onToggleDone(item)}\n />\n ) : null}\n {onEditTask ? (\n <IconButton\n icon={<Pencil />}\n intent=\"ghost\"\n size=\"sm\"\n aria-label={t('tasksPanel.edit')}\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 onClick={() => onDismissTask(item)}\n />\n ) : null}\n </>\n );\n };\n\n const renderRowActions = (item: TasksPanelItem): ReactNode => {\n const custom = !readOnly ? renderItemActions?.(item) : null;\n const trailing = custom ?? defaultActions(item);\n const badge = renderTypeBadge(item);\n if (!badge && !trailing) return undefined;\n return (\n <>\n {badge}\n {trailing}\n </>\n );\n };\n\n /* ----- Body branches ----- */\n const isFirstUseEmpty = !loading && !error && items.length === 0;\n const isFilteredEmpty =\n !loading && !error && items.length > 0 && visible.length === 0;\n\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 let body: ReactNode;\n if (error) {\n body = (\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 />\n ) : (\n error\n )}\n </div>\n );\n } else if (loading) {\n body = (\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 } else if (isFirstUseEmpty) {\n body = (\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 } else if (isFilteredEmpty) {\n body = (\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 label: t('tasksPanel.filteredEmpty.clear'),\n onClick: clearFilters,\n }}\n />\n </div>\n );\n } else {\n body = (\n <div\n ref={scrollRef}\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-fade-top={fadeTop ? 'true' : undefined}\n data-fade-bottom={fadeBottom ? 'true' : undefined}\n className={scrollRegionClasses}\n >\n <ol className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-md)] ds:p-0\">\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 count={bucket.items.length}\n label={bucketLabels[bucket.key]}\n headerRef={\n bucket.key === 'overdue' ? overdueHeaderRef : undefined\n }\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 className={rowElevationClass}\n data-task-id={item.id}\n />\n ))}\n </ul>\n </li>\n ))}\n </ol>\n {loadingMore ? skeletonRow('loading-more') : null}\n {!loadingMore && moreAvailable && onLoadMore ? (\n <div className=\"ds:flex ds:justify-center ds:py-[var(--spacing-sm)]\">\n <Button intent=\"ghost\" size=\"sm\" onClick={onLoadMore}>\n {t('tasksPanel.loadMore')}\n </Button>\n </div>\n ) : null}\n </div>\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 onClick={onAddTask}\n />\n ) : undefined;\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 || showFilters ? (\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 {showFilters ? (\n <div className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-sm)]\">\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 onClick={() => changeStatus(value)}\n >\n {statusLabels[value]}\n </Button>\n );\n })}\n </ButtonGroup>\n\n {typeOptions && typeOptions.length > 0 ? (\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) => changeType(value || null)}\n />\n ) : null}\n\n {assigneeOptions && assigneeOptions.length > 0 ? (\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) => changeAssignee(value || null)}\n />\n ) : null}\n\n <Switch\n id={overdueSwitchId}\n size=\"sm\"\n label={t('tasksPanel.overdueOnly')}\n checked={currentOverdueOnly}\n onCheckedChange={changeOverdueOnly}\n />\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={heading}\n icon={<ClipboardCheck />}\n headingId={headingId}\n actions={headerActions}\n filters={headerFilters}\n />\n\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 count: number;\n label: string;\n headerRef?: React.MutableRefObject<HTMLElement | null>;\n}\n\nfunction BucketHeader({\n bucketKey,\n count,\n label,\n headerRef,\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 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 tone,\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 <span className=\"ds:text-[color:var(--muted-foreground)]\">\n {`(${count})`}\n </span>\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","rootVariants","cva","scrollRegionClasses","rowElevationClass","SYSTEM_TYPE_META","BUCKET_ORDER","startOfDay","d","dayBoundaries","now","today","tomorrow","dayAfter","dow","nextWeek","bucketFor","item","startOfToday","startOfTomorrow","startOfDayAfter","startOfNextWeek","due","isOverdue","groupByDueBucket","items","map","key","list","buckets","a","b","TasksPanel","forwardRef","id","nowIso","title","size","onOpenTask","onToggleDone","onEditTask","onDismissTask","onAddTask","readOnly","renderItemActions","scope","defaultScope","onScopeChange","availableScopes","onLoadMore","hasMore","loadingMore","loading","error","showFilters","statusFilter","defaultStatusFilter","onStatusFilterChange","typeOptions","typeFilter","onTypeFilterChange","assigneeOptions","assigneeFilter","onAssigneeFilterChange","overdueOnly","defaultOverdueOnly","onOverdueOnlyChange","emptyTitle","emptyDescription","emptyAction","className","ariaLabel","rest","ref","t","useTranslation","headingId","useId","overdueSwitchId","heading","statusLabels","scopeLabels","bucketLabels","systemTypeLabels","useMemo","scopeState","setScopeState","useState","currentScope","changeScope","useCallback","next","statusState","setStatusState","currentStatus","changeStatus","typeState","setTypeState","currentType","changeType","assigneeState","setAssigneeState","currentAssignee","changeAssignee","overdueState","setOverdueState","currentOverdueOnly","changeOverdueOnly","clearFilters","visible","isDone","scrollRef","useRef","overdueHeaderRef","fadeTop","setFadeTop","fadeBottom","setFadeBottom","updateEdges","region","scrollTop","scrollHeight","clientHeight","useIsomorphicLayoutEffect","observer","moreAvailable","handleScroll","jumpToOverdue","el","delta","itemsRef","innerRef","useImperativeHandle","i","targetId","found","useAgentRegistration","renderTypeBadge","meta","variant","Icon","label","jsx","Badge","defaultActions","done","jsxs","Fragment","IconButton","SquareCheckBig","Square","Pencil","X","renderRowActions","trailing","badge","isFirstUseEmpty","isFilteredEmpty","skeletonRow","Skeleton","body","EmptyState","bucket","BucketHeader","TaskCard","Button","showScopeSegment","statusValues","headerActions","Plus","headerFilters","ButtonGroup","value","active","Select","Switch","PanelHeader","ClipboardCheck","bucketKey","count","headerRef"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}
@@ -7,7 +7,7 @@ import { useTranslation as io } from "react-i18next";
7
7
  import { u as Xo } from "./registry-DvAUVLHh.js";
8
8
  import { I as Jo } from "./icon-button-DA2CAGHZ.js";
9
9
  import { P as rt } from "./popover-Cqcjx-Ny.js";
10
- import { S as en } from "./select-BW5ecXlX.js";
10
+ import { S as en } from "./select-Bi8zril7.js";
11
11
  import { S as at } from "./switch-OILsBLWo.js";
12
12
  import { o as zt, K as tn, a0 as on, J as Ke, R as Ue, u as ro, U as ao, G as nn, S as rn, w as Ve, X as F, f as de, $ as st, _ as Vt, E as ft, a1 as ce, H as Bt, z as ut, y as an, l as ct, A as so, L as sn, t as pt, W as dt, s as co, Y as lo, x as cn, V as dn, a2 as ln, a3 as $, a4 as U, a5 as hn, Z as un, C as ho, Q as pn, a6 as fn, k as Gt, T as mn, O as gn, q as vn, N as bn } from "./tooth-data-DR8Kdnup.js";
13
13
  import { S as yn } from "./settings-d25ju_6L.js";
@@ -2048,4 +2048,4 @@ export {
2048
2048
  Nn as r,
2049
2049
  $n as t
2050
2050
  };
2051
- //# sourceMappingURL=tooth-scheme-WdyVymQ1.js.map
2051
+ //# sourceMappingURL=tooth-scheme-2IsmbE6w.js.map