@open-mercato/core 0.10.1-develop.7717.1.2befe9c634 → 0.10.1-develop.7721.1.b5c4a00a68

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 (384) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities/staff_support_routing_rule/index.js +21 -0
  3. package/dist/generated/entities/staff_support_routing_rule/index.js.map +7 -0
  4. package/dist/generated/entities/staff_support_ticket/index.js +37 -0
  5. package/dist/generated/entities/staff_support_ticket/index.js.map +7 -0
  6. package/dist/generated/entities/staff_time_project/index.js +2 -0
  7. package/dist/generated/entities/staff_time_project/index.js.map +2 -2
  8. package/dist/generated/entities/staff_time_project_member/index.js +2 -0
  9. package/dist/generated/entities/staff_time_project_member/index.js.map +2 -2
  10. package/dist/generated/entities/staff_time_task/index.js +4 -0
  11. package/dist/generated/entities/staff_time_task/index.js.map +2 -2
  12. package/dist/generated/entities/staff_time_task_comment/index.js +9 -1
  13. package/dist/generated/entities/staff_time_task_comment/index.js.map +2 -2
  14. package/dist/generated/entities.ids.generated.js +2 -0
  15. package/dist/generated/entities.ids.generated.js.map +2 -2
  16. package/dist/generated/entity-fields-registry.js +38 -0
  17. package/dist/generated/entity-fields-registry.js.map +2 -2
  18. package/dist/helpers/integration/auth.js +1 -0
  19. package/dist/helpers/integration/auth.js.map +2 -2
  20. package/dist/helpers/integration/communicationChannelsFixtures.js +20 -0
  21. package/dist/helpers/integration/communicationChannelsFixtures.js.map +2 -2
  22. package/dist/modules/catalog/api/bulk-delete/route.js +12 -2
  23. package/dist/modules/catalog/api/bulk-delete/route.js.map +2 -2
  24. package/dist/modules/communication_channels/api/post/test-seed/route.js +17 -3
  25. package/dist/modules/communication_channels/api/post/test-seed/route.js.map +2 -2
  26. package/dist/modules/communication_channels/lib/test-seed.js +38 -5
  27. package/dist/modules/communication_channels/lib/test-seed.js.map +2 -2
  28. package/dist/modules/messages/commands/messages.js +2 -3
  29. package/dist/modules/messages/commands/messages.js.map +2 -2
  30. package/dist/modules/portal/frontend/[orgSlug]/portal/dashboard/page.js +2 -2
  31. package/dist/modules/portal/frontend/[orgSlug]/portal/dashboard/page.js.map +2 -2
  32. package/dist/modules/staff/api/portal/support-tickets/[id]/attachments/route.js +299 -0
  33. package/dist/modules/staff/api/portal/support-tickets/[id]/attachments/route.js.map +7 -0
  34. package/dist/modules/staff/api/portal/support-tickets/[id]/messages/route.js +91 -0
  35. package/dist/modules/staff/api/portal/support-tickets/[id]/messages/route.js.map +7 -0
  36. package/dist/modules/staff/api/portal/support-tickets/[id]/route.js +146 -0
  37. package/dist/modules/staff/api/portal/support-tickets/[id]/route.js.map +7 -0
  38. package/dist/modules/staff/api/portal/support-tickets/options/route.js +60 -0
  39. package/dist/modules/staff/api/portal/support-tickets/options/route.js.map +7 -0
  40. package/dist/modules/staff/api/portal/support-tickets/route.js +220 -0
  41. package/dist/modules/staff/api/portal/support-tickets/route.js.map +7 -0
  42. package/dist/modules/staff/api/timesheets/settings/route.js +7 -1
  43. package/dist/modules/staff/api/timesheets/settings/route.js.map +2 -2
  44. package/dist/modules/staff/api/timesheets/support-routing-rules/fallback-project/route.js +122 -0
  45. package/dist/modules/staff/api/timesheets/support-routing-rules/fallback-project/route.js.map +7 -0
  46. package/dist/modules/staff/api/timesheets/support-routing-rules/preview/route.js +180 -0
  47. package/dist/modules/staff/api/timesheets/support-routing-rules/preview/route.js.map +7 -0
  48. package/dist/modules/staff/api/timesheets/support-routing-rules/route.js +147 -0
  49. package/dist/modules/staff/api/timesheets/support-routing-rules/route.js.map +7 -0
  50. package/dist/modules/staff/api/timesheets/support-tickets/options/route.js +133 -0
  51. package/dist/modules/staff/api/timesheets/support-tickets/options/route.js.map +7 -0
  52. package/dist/modules/staff/api/timesheets/tasks/[id]/claim/route.js +33 -0
  53. package/dist/modules/staff/api/timesheets/tasks/[id]/claim/route.js.map +7 -0
  54. package/dist/modules/staff/api/timesheets/tasks/[id]/comments/route.js +25 -7
  55. package/dist/modules/staff/api/timesheets/tasks/[id]/comments/route.js.map +2 -2
  56. package/dist/modules/staff/api/timesheets/tasks/[id]/release/route.js +32 -0
  57. package/dist/modules/staff/api/timesheets/tasks/[id]/release/route.js.map +7 -0
  58. package/dist/modules/staff/api/timesheets/tasks/route.js +94 -47
  59. package/dist/modules/staff/api/timesheets/tasks/route.js.map +2 -2
  60. package/dist/modules/staff/api/timesheets/time-projects/[id]/employees/route.js +3 -0
  61. package/dist/modules/staff/api/timesheets/time-projects/[id]/employees/route.js.map +2 -2
  62. package/dist/modules/staff/api/timesheets/time-projects/route.js +3 -0
  63. package/dist/modules/staff/api/timesheets/time-projects/route.js.map +2 -2
  64. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.js +1 -0
  65. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.js.map +2 -2
  66. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js +54 -4
  67. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js.map +2 -2
  68. package/dist/modules/staff/backend/staff/time-tracking/projects/projectFormConfig.js +21 -5
  69. package/dist/modules/staff/backend/staff/time-tracking/projects/projectFormConfig.js.map +2 -2
  70. package/dist/modules/staff/backend/staff/time-tracking/settings/page.js +319 -254
  71. package/dist/modules/staff/backend/staff/time-tracking/settings/page.js.map +2 -2
  72. package/dist/modules/staff/backend/staff/time-tracking/support/page.js +363 -0
  73. package/dist/modules/staff/backend/staff/time-tracking/support/page.js.map +7 -0
  74. package/dist/modules/staff/backend/staff/time-tracking/support/page.meta.js +18 -0
  75. package/dist/modules/staff/backend/staff/time-tracking/support/page.meta.js.map +7 -0
  76. package/dist/modules/staff/cli.js +27 -0
  77. package/dist/modules/staff/cli.js.map +2 -2
  78. package/dist/modules/staff/commands/index.js +3 -0
  79. package/dist/modules/staff/commands/index.js.map +2 -2
  80. package/dist/modules/staff/commands/shared.js +10 -1
  81. package/dist/modules/staff/commands/shared.js.map +2 -2
  82. package/dist/modules/staff/commands/support-routing-rules.js +505 -0
  83. package/dist/modules/staff/commands/support-routing-rules.js.map +7 -0
  84. package/dist/modules/staff/commands/support-tickets.js +513 -0
  85. package/dist/modules/staff/commands/support-tickets.js.map +7 -0
  86. package/dist/modules/staff/commands/timesheets-projects.js +72 -14
  87. package/dist/modules/staff/commands/timesheets-projects.js.map +2 -2
  88. package/dist/modules/staff/commands/timesheets-task-assignment.js +270 -0
  89. package/dist/modules/staff/commands/timesheets-task-assignment.js.map +7 -0
  90. package/dist/modules/staff/commands/timesheets-task-comments.js +58 -12
  91. package/dist/modules/staff/commands/timesheets-task-comments.js.map +2 -2
  92. package/dist/modules/staff/commands/timesheets-tasks.js +91 -9
  93. package/dist/modules/staff/commands/timesheets-tasks.js.map +3 -3
  94. package/dist/modules/staff/data/enrichers.js +141 -0
  95. package/dist/modules/staff/data/enrichers.js.map +2 -2
  96. package/dist/modules/staff/data/entities.js +143 -2
  97. package/dist/modules/staff/data/entities.js.map +2 -2
  98. package/dist/modules/staff/data/extensions.js +8 -0
  99. package/dist/modules/staff/data/extensions.js.map +2 -2
  100. package/dist/modules/staff/data/validators.js +34 -5
  101. package/dist/modules/staff/data/validators.js.map +2 -2
  102. package/dist/modules/staff/encryption.js +6 -0
  103. package/dist/modules/staff/encryption.js.map +2 -2
  104. package/dist/modules/staff/events.js +25 -0
  105. package/dist/modules/staff/events.js.map +2 -2
  106. package/dist/modules/staff/events.payloads.js +54 -0
  107. package/dist/modules/staff/events.payloads.js.map +2 -2
  108. package/dist/modules/staff/extension-points.js +1 -0
  109. package/dist/modules/staff/extension-points.js.map +2 -2
  110. package/dist/modules/staff/frontend/[orgSlug]/portal/support/[id]/page.js +468 -0
  111. package/dist/modules/staff/frontend/[orgSlug]/portal/support/[id]/page.js.map +7 -0
  112. package/dist/modules/staff/frontend/[orgSlug]/portal/support/[id]/page.meta.js +12 -0
  113. package/dist/modules/staff/frontend/[orgSlug]/portal/support/[id]/page.meta.js.map +7 -0
  114. package/dist/modules/staff/frontend/[orgSlug]/portal/support/new/page.js +316 -0
  115. package/dist/modules/staff/frontend/[orgSlug]/portal/support/new/page.js.map +7 -0
  116. package/dist/modules/staff/frontend/[orgSlug]/portal/support/new/page.meta.js +12 -0
  117. package/dist/modules/staff/frontend/[orgSlug]/portal/support/new/page.meta.js.map +7 -0
  118. package/dist/modules/staff/frontend/[orgSlug]/portal/support/page.js +190 -0
  119. package/dist/modules/staff/frontend/[orgSlug]/portal/support/page.js.map +7 -0
  120. package/dist/modules/staff/frontend/[orgSlug]/portal/support/page.meta.js +19 -0
  121. package/dist/modules/staff/frontend/[orgSlug]/portal/support/page.meta.js.map +7 -0
  122. package/dist/modules/staff/index.js +1 -1
  123. package/dist/modules/staff/index.js.map +2 -2
  124. package/dist/modules/staff/lib/crud.js +2 -0
  125. package/dist/modules/staff/lib/crud.js.map +2 -2
  126. package/dist/modules/staff/lib/support/attachments.js +36 -0
  127. package/dist/modules/staff/lib/support/attachments.js.map +7 -0
  128. package/dist/modules/staff/lib/support/dictionaries.js +87 -0
  129. package/dist/modules/staff/lib/support/dictionaries.js.map +7 -0
  130. package/dist/modules/staff/lib/support/notifications.js +111 -0
  131. package/dist/modules/staff/lib/support/notifications.js.map +7 -0
  132. package/dist/modules/staff/lib/support/portalAttachments.js +100 -0
  133. package/dist/modules/staff/lib/support/portalAttachments.js.map +7 -0
  134. package/dist/modules/staff/lib/support/portalBroadcast.js +117 -0
  135. package/dist/modules/staff/lib/support/portalBroadcast.js.map +7 -0
  136. package/dist/modules/staff/lib/support/portalRoute.js +99 -0
  137. package/dist/modules/staff/lib/support/portalRoute.js.map +7 -0
  138. package/dist/modules/staff/lib/support/portalStatus.js +12 -0
  139. package/dist/modules/staff/lib/support/portalStatus.js.map +7 -0
  140. package/dist/modules/staff/lib/support/portalTickets.js +148 -0
  141. package/dist/modules/staff/lib/support/portalTickets.js.map +7 -0
  142. package/dist/modules/staff/lib/support/routing.js +81 -0
  143. package/dist/modules/staff/lib/support/routing.js.map +7 -0
  144. package/dist/modules/staff/lib/support/routingRuleDraft.js +25 -0
  145. package/dist/modules/staff/lib/support/routingRuleDraft.js.map +7 -0
  146. package/dist/modules/staff/lib/support/seedDefaults.js +114 -0
  147. package/dist/modules/staff/lib/support/seedDefaults.js.map +7 -0
  148. package/dist/modules/staff/lib/support/supportActivity.js +26 -0
  149. package/dist/modules/staff/lib/support/supportActivity.js.map +7 -0
  150. package/dist/modules/staff/lib/support-ui/PortalSupportNotLinked.js +23 -0
  151. package/dist/modules/staff/lib/support-ui/PortalSupportNotLinked.js.map +7 -0
  152. package/dist/modules/staff/lib/support-ui/portalAttachmentValidation.js +112 -0
  153. package/dist/modules/staff/lib/support-ui/portalAttachmentValidation.js.map +7 -0
  154. package/dist/modules/staff/lib/support-ui/portalPendingUploads.js +45 -0
  155. package/dist/modules/staff/lib/support-ui/portalPendingUploads.js.map +7 -0
  156. package/dist/modules/staff/lib/support-ui/portalSupport.js +51 -0
  157. package/dist/modules/staff/lib/support-ui/portalSupport.js.map +7 -0
  158. package/dist/modules/staff/lib/time-tracking/access.js +3 -39
  159. package/dist/modules/staff/lib/time-tracking/access.js.map +2 -2
  160. package/dist/modules/staff/lib/time-tracking/listProjectAccess.js +54 -0
  161. package/dist/modules/staff/lib/time-tracking/listProjectAccess.js.map +7 -0
  162. package/dist/modules/staff/lib/time-tracking/portalRecipients.js +92 -2
  163. package/dist/modules/staff/lib/time-tracking/portalRecipients.js.map +2 -2
  164. package/dist/modules/staff/lib/time-tracking/projectAssignment.js +112 -0
  165. package/dist/modules/staff/lib/time-tracking/projectAssignment.js.map +7 -0
  166. package/dist/modules/staff/lib/time-tracking/settingKeys.js +14 -0
  167. package/dist/modules/staff/lib/time-tracking/settingKeys.js.map +2 -2
  168. package/dist/modules/staff/lib/time-tracking/settings.js +28 -1
  169. package/dist/modules/staff/lib/time-tracking/settings.js.map +2 -2
  170. package/dist/modules/staff/lib/time-tracking/taskAssignmentRoute.js +143 -0
  171. package/dist/modules/staff/lib/time-tracking/taskAssignmentRoute.js.map +7 -0
  172. package/dist/modules/staff/lib/time-tracking/workRecipients.js +92 -0
  173. package/dist/modules/staff/lib/time-tracking/workRecipients.js.map +7 -0
  174. package/dist/modules/staff/lib/time-tracking-ui/BoardFilterChips.js +32 -3
  175. package/dist/modules/staff/lib/time-tracking-ui/BoardFilterChips.js.map +2 -2
  176. package/dist/modules/staff/lib/time-tracking-ui/KanbanBoard.js +29 -0
  177. package/dist/modules/staff/lib/time-tracking-ui/KanbanBoard.js.map +2 -2
  178. package/dist/modules/staff/lib/time-tracking-ui/KanbanCard.js +4 -0
  179. package/dist/modules/staff/lib/time-tracking-ui/KanbanCard.js.map +2 -2
  180. package/dist/modules/staff/lib/time-tracking-ui/ProjectFormSections.js +141 -1
  181. package/dist/modules/staff/lib/time-tracking-ui/ProjectFormSections.js.map +2 -2
  182. package/dist/modules/staff/lib/time-tracking-ui/SupportAttachmentsSection.js +153 -0
  183. package/dist/modules/staff/lib/time-tracking-ui/SupportAttachmentsSection.js.map +7 -0
  184. package/dist/modules/staff/lib/time-tracking-ui/SupportRequestPanel.js +67 -0
  185. package/dist/modules/staff/lib/time-tracking-ui/SupportRequestPanel.js.map +7 -0
  186. package/dist/modules/staff/lib/time-tracking-ui/TaskBoardScreen.js +3 -1
  187. package/dist/modules/staff/lib/time-tracking-ui/TaskBoardScreen.js.map +2 -2
  188. package/dist/modules/staff/lib/time-tracking-ui/TaskCommentThread.js +80 -17
  189. package/dist/modules/staff/lib/time-tracking-ui/TaskCommentThread.js.map +2 -2
  190. package/dist/modules/staff/lib/time-tracking-ui/TaskDrawer.js +230 -41
  191. package/dist/modules/staff/lib/time-tracking-ui/TaskDrawer.js.map +2 -2
  192. package/dist/modules/staff/lib/time-tracking-ui/boardDirectory.js +21 -1
  193. package/dist/modules/staff/lib/time-tracking-ui/boardDirectory.js.map +2 -2
  194. package/dist/modules/staff/lib/time-tracking-ui/boardFilters.js +16 -4
  195. package/dist/modules/staff/lib/time-tracking-ui/boardFilters.js.map +2 -2
  196. package/dist/modules/staff/lib/time-tracking-ui/kanbanBoardData.js +3 -1
  197. package/dist/modules/staff/lib/time-tracking-ui/kanbanBoardData.js.map +2 -2
  198. package/dist/modules/staff/lib/time-tracking-ui/projectDefaultAssignee.js +68 -0
  199. package/dist/modules/staff/lib/time-tracking-ui/projectDefaultAssignee.js.map +7 -0
  200. package/dist/modules/staff/lib/time-tracking-ui/settingsTabs.js +7 -0
  201. package/dist/modules/staff/lib/time-tracking-ui/settingsTabs.js.map +7 -0
  202. package/dist/modules/staff/lib/time-tracking-ui/supportTicketData.js +50 -0
  203. package/dist/modules/staff/lib/time-tracking-ui/supportTicketData.js.map +7 -0
  204. package/dist/modules/staff/lib/time-tracking-ui/taskDrawerData.js +13 -1
  205. package/dist/modules/staff/lib/time-tracking-ui/taskDrawerData.js.map +2 -2
  206. package/dist/modules/staff/lib/time-tracking-ui/timeTrackingSettingsForm.js +36 -2
  207. package/dist/modules/staff/lib/time-tracking-ui/timeTrackingSettingsForm.js.map +2 -2
  208. package/dist/modules/staff/migrations/Migration20261009180543_staff.js +42 -0
  209. package/dist/modules/staff/migrations/Migration20261009180543_staff.js.map +7 -0
  210. package/dist/modules/staff/notifications.js +92 -0
  211. package/dist/modules/staff/notifications.js.map +2 -2
  212. package/dist/modules/staff/setup.js +6 -2
  213. package/dist/modules/staff/setup.js.map +2 -2
  214. package/dist/modules/staff/subscribers/support-portal-comment-created.js +26 -0
  215. package/dist/modules/staff/subscribers/support-portal-comment-created.js.map +7 -0
  216. package/dist/modules/staff/subscribers/support-portal-comment-deleted.js +26 -0
  217. package/dist/modules/staff/subscribers/support-portal-comment-deleted.js.map +7 -0
  218. package/dist/modules/staff/subscribers/support-portal-comment-updated.js +26 -0
  219. package/dist/modules/staff/subscribers/support-portal-comment-updated.js.map +7 -0
  220. package/dist/modules/staff/subscribers/support-portal-status-column-updated.js +24 -0
  221. package/dist/modules/staff/subscribers/support-portal-status-column-updated.js.map +7 -0
  222. package/dist/modules/staff/subscribers/support-portal-task-status-changed.js +25 -0
  223. package/dist/modules/staff/subscribers/support-portal-task-status-changed.js.map +7 -0
  224. package/dist/modules/staff/subscribers/support-portal-task-updated.js +25 -0
  225. package/dist/modules/staff/subscribers/support-portal-task-updated.js.map +7 -0
  226. package/dist/modules/staff/subscribers/support-ticket-created-notification.js +25 -0
  227. package/dist/modules/staff/subscribers/support-ticket-created-notification.js.map +7 -0
  228. package/dist/modules/staff/subscribers/support-ticket-customer-replied-notification.js +25 -0
  229. package/dist/modules/staff/subscribers/support-ticket-customer-replied-notification.js.map +7 -0
  230. package/dist/modules/staff/subscribers/support-ticket-unnotified-clear.js +26 -0
  231. package/dist/modules/staff/subscribers/support-ticket-unnotified-clear.js.map +7 -0
  232. package/dist/modules/staff/subscribers/time-task-assignee-notification.js +83 -0
  233. package/dist/modules/staff/subscribers/time-task-assignee-notification.js.map +7 -0
  234. package/dist/modules/staff/widgets/injection/portal-support-tickets/widget.client.js +112 -0
  235. package/dist/modules/staff/widgets/injection/portal-support-tickets/widget.client.js.map +7 -0
  236. package/dist/modules/staff/widgets/injection/portal-support-tickets/widget.js +17 -0
  237. package/dist/modules/staff/widgets/injection/portal-support-tickets/widget.js.map +7 -0
  238. package/dist/modules/staff/widgets/injection/time-tracking-settings-support/widget.client.js +870 -0
  239. package/dist/modules/staff/widgets/injection/time-tracking-settings-support/widget.client.js.map +7 -0
  240. package/dist/modules/staff/widgets/injection/time-tracking-settings-support/widget.js +17 -0
  241. package/dist/modules/staff/widgets/injection/time-tracking-settings-support/widget.js.map +7 -0
  242. package/dist/modules/staff/widgets/injection-table.js +16 -1
  243. package/dist/modules/staff/widgets/injection-table.js.map +2 -2
  244. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js +4 -18
  245. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js.map +2 -2
  246. package/dist/modules/wms/components/backend/WmsLotDetailPage.js +4 -18
  247. package/dist/modules/wms/components/backend/WmsLotDetailPage.js.map +2 -2
  248. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js +4 -18
  249. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js.map +2 -2
  250. package/dist/modules/wms/lib/inventoryCsvExport.js +19 -0
  251. package/dist/modules/wms/lib/inventoryCsvExport.js.map +7 -0
  252. package/generated/entities/staff_support_routing_rule/index.ts +9 -0
  253. package/generated/entities/staff_support_ticket/index.ts +17 -0
  254. package/generated/entities/staff_time_project/index.ts +1 -0
  255. package/generated/entities/staff_time_project_member/index.ts +1 -0
  256. package/generated/entities/staff_time_task/index.ts +2 -0
  257. package/generated/entities/staff_time_task_comment/index.ts +4 -0
  258. package/generated/entities.ids.generated.ts +2 -0
  259. package/generated/entity-fields-registry.ts +38 -0
  260. package/package.json +8 -8
  261. package/src/helpers/integration/auth.ts +1 -1
  262. package/src/helpers/integration/communicationChannelsFixtures.ts +60 -2
  263. package/src/modules/catalog/api/bulk-delete/route.ts +12 -2
  264. package/src/modules/communication_channels/api/post/test-seed/route.ts +29 -12
  265. package/src/modules/communication_channels/lib/test-seed.ts +49 -10
  266. package/src/modules/messages/commands/messages.ts +8 -10
  267. package/src/modules/portal/frontend/[orgSlug]/portal/dashboard/page.tsx +2 -2
  268. package/src/modules/staff/AGENTS.md +22 -6
  269. package/src/modules/staff/api/portal/support-tickets/[id]/attachments/route.ts +327 -0
  270. package/src/modules/staff/api/portal/support-tickets/[id]/messages/route.ts +94 -0
  271. package/src/modules/staff/api/portal/support-tickets/[id]/route.ts +160 -0
  272. package/src/modules/staff/api/portal/support-tickets/options/route.ts +60 -0
  273. package/src/modules/staff/api/portal/support-tickets/route.ts +253 -0
  274. package/src/modules/staff/api/timesheets/settings/route.ts +7 -1
  275. package/src/modules/staff/api/timesheets/support-routing-rules/fallback-project/route.ts +131 -0
  276. package/src/modules/staff/api/timesheets/support-routing-rules/preview/route.ts +248 -0
  277. package/src/modules/staff/api/timesheets/support-routing-rules/route.ts +150 -0
  278. package/src/modules/staff/api/timesheets/support-tickets/options/route.ts +181 -0
  279. package/src/modules/staff/api/timesheets/tasks/[id]/claim/route.ts +31 -0
  280. package/src/modules/staff/api/timesheets/tasks/[id]/comments/route.ts +25 -7
  281. package/src/modules/staff/api/timesheets/tasks/[id]/release/route.ts +30 -0
  282. package/src/modules/staff/api/timesheets/tasks/route.ts +119 -67
  283. package/src/modules/staff/api/timesheets/time-projects/[id]/employees/route.ts +3 -0
  284. package/src/modules/staff/api/timesheets/time-projects/route.ts +3 -0
  285. package/src/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.tsx +1 -0
  286. package/src/modules/staff/backend/staff/time-tracking/projects/[id]/page.tsx +67 -2
  287. package/src/modules/staff/backend/staff/time-tracking/projects/projectFormConfig.ts +22 -3
  288. package/src/modules/staff/backend/staff/time-tracking/settings/page.tsx +405 -308
  289. package/src/modules/staff/backend/staff/time-tracking/support/page.meta.ts +14 -0
  290. package/src/modules/staff/backend/staff/time-tracking/support/page.tsx +428 -0
  291. package/src/modules/staff/cli.ts +28 -0
  292. package/src/modules/staff/commands/index.ts +3 -0
  293. package/src/modules/staff/commands/shared.ts +22 -1
  294. package/src/modules/staff/commands/support-routing-rules.ts +595 -0
  295. package/src/modules/staff/commands/support-tickets.ts +580 -0
  296. package/src/modules/staff/commands/timesheets-projects.ts +84 -13
  297. package/src/modules/staff/commands/timesheets-task-assignment.ts +319 -0
  298. package/src/modules/staff/commands/timesheets-task-comments.ts +70 -15
  299. package/src/modules/staff/commands/timesheets-tasks.ts +106 -15
  300. package/src/modules/staff/data/enrichers.ts +203 -0
  301. package/src/modules/staff/data/entities.ts +133 -2
  302. package/src/modules/staff/data/extensions.ts +9 -1
  303. package/src/modules/staff/data/validators.ts +36 -0
  304. package/src/modules/staff/encryption.ts +6 -0
  305. package/src/modules/staff/events.payloads.ts +87 -1
  306. package/src/modules/staff/events.ts +26 -0
  307. package/src/modules/staff/extension-points.ts +1 -0
  308. package/src/modules/staff/frontend/[orgSlug]/portal/support/[id]/page.meta.ts +10 -0
  309. package/src/modules/staff/frontend/[orgSlug]/portal/support/[id]/page.tsx +553 -0
  310. package/src/modules/staff/frontend/[orgSlug]/portal/support/new/page.meta.ts +10 -0
  311. package/src/modules/staff/frontend/[orgSlug]/portal/support/new/page.tsx +346 -0
  312. package/src/modules/staff/frontend/[orgSlug]/portal/support/page.meta.ts +17 -0
  313. package/src/modules/staff/frontend/[orgSlug]/portal/support/page.tsx +253 -0
  314. package/src/modules/staff/i18n/de.json +291 -0
  315. package/src/modules/staff/i18n/en.json +291 -0
  316. package/src/modules/staff/i18n/es.json +291 -0
  317. package/src/modules/staff/i18n/ko.json +291 -0
  318. package/src/modules/staff/i18n/pl.json +291 -0
  319. package/src/modules/staff/index.ts +1 -1
  320. package/src/modules/staff/lib/crud.ts +2 -1
  321. package/src/modules/staff/lib/support/attachments.ts +43 -0
  322. package/src/modules/staff/lib/support/dictionaries.ts +120 -0
  323. package/src/modules/staff/lib/support/notifications.ts +138 -0
  324. package/src/modules/staff/lib/support/portalAttachments.ts +140 -0
  325. package/src/modules/staff/lib/support/portalBroadcast.ts +161 -0
  326. package/src/modules/staff/lib/support/portalRoute.ts +108 -0
  327. package/src/modules/staff/lib/support/portalStatus.ts +15 -0
  328. package/src/modules/staff/lib/support/portalTickets.ts +233 -0
  329. package/src/modules/staff/lib/support/routing.ts +117 -0
  330. package/src/modules/staff/lib/support/routingRuleDraft.ts +45 -0
  331. package/src/modules/staff/lib/support/seedDefaults.ts +151 -0
  332. package/src/modules/staff/lib/support/supportActivity.ts +39 -0
  333. package/src/modules/staff/lib/support-ui/PortalSupportNotLinked.tsx +20 -0
  334. package/src/modules/staff/lib/support-ui/portalAttachmentValidation.ts +125 -0
  335. package/src/modules/staff/lib/support-ui/portalPendingUploads.ts +49 -0
  336. package/src/modules/staff/lib/support-ui/portalSupport.ts +116 -0
  337. package/src/modules/staff/lib/time-tracking/access.ts +2 -62
  338. package/src/modules/staff/lib/time-tracking/listProjectAccess.ts +78 -0
  339. package/src/modules/staff/lib/time-tracking/portalRecipients.ts +173 -5
  340. package/src/modules/staff/lib/time-tracking/projectAssignment.ts +172 -0
  341. package/src/modules/staff/lib/time-tracking/settingKeys.ts +11 -0
  342. package/src/modules/staff/lib/time-tracking/settings.ts +46 -1
  343. package/src/modules/staff/lib/time-tracking/taskAssignmentRoute.ts +165 -0
  344. package/src/modules/staff/lib/time-tracking/workRecipients.ts +183 -0
  345. package/src/modules/staff/lib/time-tracking-ui/BoardFilterChips.tsx +36 -1
  346. package/src/modules/staff/lib/time-tracking-ui/KanbanBoard.tsx +30 -0
  347. package/src/modules/staff/lib/time-tracking-ui/KanbanCard.tsx +9 -0
  348. package/src/modules/staff/lib/time-tracking-ui/ProjectFormSections.tsx +185 -6
  349. package/src/modules/staff/lib/time-tracking-ui/SupportAttachmentsSection.tsx +188 -0
  350. package/src/modules/staff/lib/time-tracking-ui/SupportRequestPanel.tsx +102 -0
  351. package/src/modules/staff/lib/time-tracking-ui/TaskBoardScreen.tsx +2 -0
  352. package/src/modules/staff/lib/time-tracking-ui/TaskCommentThread.tsx +105 -22
  353. package/src/modules/staff/lib/time-tracking-ui/TaskDrawer.tsx +278 -43
  354. package/src/modules/staff/lib/time-tracking-ui/boardDirectory.ts +21 -0
  355. package/src/modules/staff/lib/time-tracking-ui/boardFilters.ts +16 -2
  356. package/src/modules/staff/lib/time-tracking-ui/kanbanBoardData.ts +4 -0
  357. package/src/modules/staff/lib/time-tracking-ui/projectDefaultAssignee.ts +117 -0
  358. package/src/modules/staff/lib/time-tracking-ui/settingsTabs.ts +17 -0
  359. package/src/modules/staff/lib/time-tracking-ui/supportTicketData.ts +71 -0
  360. package/src/modules/staff/lib/time-tracking-ui/taskDrawerData.ts +15 -0
  361. package/src/modules/staff/lib/time-tracking-ui/timeTrackingSettingsForm.ts +48 -1
  362. package/src/modules/staff/migrations/.snapshot-open-mercato.json +714 -0
  363. package/src/modules/staff/migrations/Migration20261009180543_staff.ts +50 -0
  364. package/src/modules/staff/notifications.ts +92 -0
  365. package/src/modules/staff/setup.ts +6 -2
  366. package/src/modules/staff/subscribers/support-portal-comment-created.ts +35 -0
  367. package/src/modules/staff/subscribers/support-portal-comment-deleted.ts +35 -0
  368. package/src/modules/staff/subscribers/support-portal-comment-updated.ts +35 -0
  369. package/src/modules/staff/subscribers/support-portal-status-column-updated.ts +36 -0
  370. package/src/modules/staff/subscribers/support-portal-task-status-changed.ts +34 -0
  371. package/src/modules/staff/subscribers/support-portal-task-updated.ts +34 -0
  372. package/src/modules/staff/subscribers/support-ticket-created-notification.ts +27 -0
  373. package/src/modules/staff/subscribers/support-ticket-customer-replied-notification.ts +27 -0
  374. package/src/modules/staff/subscribers/support-ticket-unnotified-clear.ts +29 -0
  375. package/src/modules/staff/subscribers/time-task-assignee-notification.ts +102 -0
  376. package/src/modules/staff/widgets/injection/portal-support-tickets/widget.client.tsx +151 -0
  377. package/src/modules/staff/widgets/injection/portal-support-tickets/widget.ts +16 -0
  378. package/src/modules/staff/widgets/injection/time-tracking-settings-support/widget.client.tsx +1058 -0
  379. package/src/modules/staff/widgets/injection/time-tracking-settings-support/widget.ts +17 -0
  380. package/src/modules/staff/widgets/injection-table.ts +15 -0
  381. package/src/modules/wms/components/backend/WmsLocationDetailPage.tsx +4 -20
  382. package/src/modules/wms/components/backend/WmsLotDetailPage.tsx +4 -20
  383. package/src/modules/wms/components/backend/WmsSkuDetailPage.tsx +4 -19
  384. package/src/modules/wms/lib/inventoryCsvExport.ts +18 -0
@@ -13,6 +13,7 @@ import {
13
13
  DrawerHeader,
14
14
  DrawerTitle
15
15
  } from "@open-mercato/ui/primitives/drawer";
16
+ import { Alert, AlertDescription } from "@open-mercato/ui/primitives/alert";
16
17
  import { Avatar } from "@open-mercato/ui/primitives/avatar";
17
18
  import { Badge } from "@open-mercato/ui/primitives/badge";
18
19
  import { Button } from "@open-mercato/ui/primitives/button";
@@ -28,7 +29,11 @@ import {
28
29
  } from "@open-mercato/ui/primitives/select";
29
30
  import { ErrorMessage, LoadingMessage } from "@open-mercato/ui/backend/detail";
30
31
  import { apiCall, apiCallOrThrow, withScopedApiRequestHeaders } from "@open-mercato/ui/backend/utils/apiCall";
31
- import { buildOptimisticLockHeader } from "@open-mercato/ui/backend/utils/optimisticLock";
32
+ import {
33
+ buildOptimisticLockHeader,
34
+ extractOptimisticLockConflict,
35
+ extractRecordLockConflict
36
+ } from "@open-mercato/ui/backend/utils/optimisticLock";
32
37
  import { surfaceRecordConflict } from "@open-mercato/ui/backend/conflicts";
33
38
  import { useBackendChrome } from "@open-mercato/ui/backend/BackendChromeProvider";
34
39
  import { useConfirmDialog } from "@open-mercato/ui/backend/confirm-dialog";
@@ -42,6 +47,10 @@ import { useT } from "@open-mercato/shared/lib/i18n/context";
42
47
  import { useOrganizationScopeVersion } from "@open-mercato/shared/lib/frontend/useOrganizationScope";
43
48
  import { createLogger } from "@open-mercato/shared/lib/logger";
44
49
  import { TaskCommentThread } from "./TaskCommentThread.js";
50
+ import { useAppEvent } from "@open-mercato/ui/backend/injection/useAppEvent";
51
+ import { SupportRequestPanel } from "./SupportRequestPanel.js";
52
+ import { SupportAttachmentsSection } from "./SupportAttachmentsSection.js";
53
+ import { readSupportTicket, SUPPORT_ACTIVITY_EVENT } from "./supportTicketData.js";
45
54
  import { TaskQuickLog } from "./TaskQuickLog.js";
46
55
  import { TagPicker, tagChipStyle } from "./TagPicker.js";
47
56
  import { slugifyProjectName } from "../time-tracking/projectCode.js";
@@ -65,15 +74,28 @@ import {
65
74
  toDrawerComment,
66
75
  toDrawerEntry,
67
76
  todayIsoDate,
68
- buildEntryClocks
77
+ buildEntryClocks,
78
+ isAssignmentEventForTask,
79
+ TASK_ASSIGNMENT_CHANGED_EVENT,
80
+ TASK_DRAWER_QUERY_ROOT
69
81
  } from "./taskDrawerData.js";
70
82
  const logger = createLogger("staff").child({ component: "TaskDrawer" });
71
83
  const TASK_ENTITY_ID = "staff:staff_time_task";
72
84
  const TASK_DRAWER_MUTATION_CONTEXT_ID = "staff.time_tracking.task_drawer";
85
+ function taskDrawerFormId(taskId) {
86
+ return `${TASK_DRAWER_MUTATION_CONTEXT_ID}:${taskId}`;
87
+ }
88
+ const ASSIGNMENT_RACE_CODES = /* @__PURE__ */ new Set(["task_already_claimed", "task_assignment_changed"]);
89
+ function isAssignmentRace(error) {
90
+ if (extractOptimisticLockConflict(error) || extractRecordLockConflict(error)) return true;
91
+ if (!error || typeof error !== "object") return false;
92
+ const code = error.code;
93
+ return typeof code === "string" && ASSIGNMENT_RACE_CODES.has(code);
94
+ }
73
95
  const RATES_FEATURE = "staff.timesheets.rates.view";
74
96
  const TASKS_MANAGE_FEATURE = "staff.timesheets.tasks.manage";
75
97
  const ENTRIES_LIST_PATH = "/backend/staff/time-tracking/entries";
76
- const DRAWER_QUERY_ROOT = ["staff", "time-tracking", "task-drawer"];
98
+ const DRAWER_QUERY_ROOT = TASK_DRAWER_QUERY_ROOT;
77
99
  const DIRECTORY_PAGE_SIZE = 100;
78
100
  const CHILD_PAGE_SIZE = 100;
79
101
  const COMMENT_PAGE_SIZE = 50;
@@ -81,6 +103,12 @@ const ENTRY_PAGE_SIZE = 100;
81
103
  const MAX_ENTRY_PAGES = 3;
82
104
  const RECENT_ENTRY_COUNT = 5;
83
105
  const ELAPSED_TICK_MS = 1e3;
106
+ function readTaskAssignmentAbility(row) {
107
+ const block = row._staffAssignment;
108
+ if (!block || typeof block !== "object") return { canClaim: false, canRelease: false };
109
+ const ability = block;
110
+ return { canClaim: ability.canClaim === true, canRelease: ability.canRelease === true };
111
+ }
84
112
  async function fetchProjectEntries(projectId) {
85
113
  const rows = [];
86
114
  for (let page = 1; page <= MAX_ENTRY_PAGES; page += 1) {
@@ -119,10 +147,18 @@ function TaskDrawer({
119
147
  const [now, setNow] = React.useState(() => Date.now());
120
148
  const saveChainRef = React.useRef(Promise.resolve());
121
149
  const versionRef = React.useRef(null);
122
- const { runMutation, retryLastMutation } = useGuardedMutation({
150
+ const [notice, setNotice] = React.useState(null);
151
+ const { runMutation: runGuardedMutation, retryLastMutation } = useGuardedMutation({
123
152
  contextId: TASK_DRAWER_MUTATION_CONTEXT_ID,
124
153
  blockedMessage: t("staff.time_tracking.taskDrawer.properties.saveError", "Could not save the change.")
125
154
  });
155
+ const runMutation = React.useCallback(
156
+ (input) => {
157
+ setNotice(null);
158
+ return runGuardedMutation(input);
159
+ },
160
+ [runGuardedMutation]
161
+ );
126
162
  const taskQuery = useQuery({
127
163
  queryKey: [...DRAWER_QUERY_ROOT, "task", `scope:${scopeVersion}`, taskId],
128
164
  enabled: open && taskId.length > 0,
@@ -135,11 +171,17 @@ function TaskDrawer({
135
171
  const row = readItems(call.result)[0];
136
172
  if (!row) return null;
137
173
  const parsed = toBoardTask(row);
138
- return parsed ? { task: parsed, createdAt: readString(row, "created_at", "createdAt") } : null;
174
+ return parsed ? {
175
+ task: parsed,
176
+ createdAt: readString(row, "created_at", "createdAt"),
177
+ support: readSupportTicket(row),
178
+ assignment: readTaskAssignmentAbility(row)
179
+ } : null;
139
180
  }
140
181
  });
141
182
  const task = taskQuery.data?.task ?? null;
142
183
  const createdAt = taskQuery.data?.createdAt ?? null;
184
+ const support = taskQuery.data?.support ?? null;
143
185
  const projectId = task?.timeProjectId ?? null;
144
186
  const taskInjectionContext = React.useMemo(
145
187
  () => ({
@@ -157,6 +199,9 @@ function TaskDrawer({
157
199
  versionRef.current = task.updatedAt;
158
200
  setTagIds(task.tagIds);
159
201
  }, [task]);
202
+ React.useEffect(() => {
203
+ setNotice(null);
204
+ }, [taskId]);
160
205
  const statusesQuery = useQuery({
161
206
  queryKey: [...DRAWER_QUERY_ROOT, "statuses", `scope:${scopeVersion}`, projectId ?? "none"],
162
207
  enabled: open && !!projectId,
@@ -320,15 +365,28 @@ function TaskDrawer({
320
365
  }, [taskQuery]);
321
366
  const reportError = React.useCallback(
322
367
  (error, fallback) => {
368
+ const conflictNotice = {
369
+ status: "warning",
370
+ message: t(
371
+ "staff.time_tracking.taskDrawer.conflict",
372
+ "Someone else changed this task. It now shows the latest version. Check it and try again."
373
+ )
374
+ };
375
+ const seenVersion = versionRef.current;
376
+ invalidate("children");
323
377
  if (surfaceRecordConflict(error, t)) {
378
+ setNotice(conflictNotice);
324
379
  invalidate("task");
325
- invalidate("children");
326
380
  return;
327
381
  }
328
382
  logger.error("staff.time_tracking task drawer mutation failed", { err: error });
329
- flash(error instanceof Error && error.message ? error.message : fallback, "error");
383
+ setNotice({ status: "error", message: error instanceof Error && error.message ? error.message : fallback });
384
+ void taskQuery.refetch().then((refreshed) => {
385
+ const currentVersion = refreshed.data?.task.updatedAt ?? null;
386
+ if (seenVersion && currentVersion && currentVersion !== seenVersion) setNotice(conflictNotice);
387
+ });
330
388
  },
331
- [invalidate, t]
389
+ [invalidate, t, taskQuery]
332
390
  );
333
391
  const handleQuickLog = React.useCallback(
334
392
  async ({ minutes, description, date, isBillable, startClock, endClock }) => {
@@ -372,9 +430,7 @@ function TaskDrawer({
372
430
  { errorMessage: t("staff.time_tracking.taskDrawer.quickLog.error", "Could not save the time entry.") }
373
431
  ),
374
432
  context: {
375
- formId: TASK_DRAWER_MUTATION_CONTEXT_ID,
376
- resourceKind: "staff.timesheets.time_entry",
377
- resourceId: taskId,
433
+ formId: taskDrawerFormId(taskId),
378
434
  retryLastMutation
379
435
  }
380
436
  });
@@ -401,14 +457,12 @@ function TaskDrawer({
401
457
  { errorMessage: t("staff.time_tracking.board.timer.stopError", "Could not stop the timer.") }
402
458
  ),
403
459
  context: {
404
- formId: TASK_DRAWER_MUTATION_CONTEXT_ID,
405
- resourceKind: "staff.timesheets.time_entry",
406
- resourceId: entryId,
460
+ formId: taskDrawerFormId(taskId),
407
461
  retryLastMutation
408
462
  }
409
463
  });
410
464
  },
411
- [retryLastMutation, runMutation, t]
465
+ [retryLastMutation, runMutation, t, taskId]
412
466
  );
413
467
  const handleStopTimer = React.useCallback(async () => {
414
468
  if (!runningTimer.entryId) return;
@@ -458,9 +512,7 @@ function TaskDrawer({
458
512
  { errorMessage: t("staff.time_tracking.board.timer.startError", "Could not start the timer.") }
459
513
  ),
460
514
  context: {
461
- formId: TASK_DRAWER_MUTATION_CONTEXT_ID,
462
- resourceKind: "staff.timesheets.time_entry",
463
- resourceId: taskId,
515
+ formId: taskDrawerFormId(taskId),
464
516
  retryLastMutation
465
517
  }
466
518
  });
@@ -535,9 +587,7 @@ function TaskDrawer({
535
587
  )
536
588
  ),
537
589
  context: {
538
- formId: TASK_DRAWER_MUTATION_CONTEXT_ID,
539
- resourceKind: "staff.timesheets.task",
540
- resourceId: taskId,
590
+ formId: taskDrawerFormId(taskId),
541
591
  retryLastMutation
542
592
  }
543
593
  });
@@ -572,9 +622,7 @@ function TaskDrawer({
572
622
  )
573
623
  ),
574
624
  context: {
575
- formId: TASK_DRAWER_MUTATION_CONTEXT_ID,
576
- resourceKind: "staff.timesheets.task",
577
- resourceId: taskId,
625
+ formId: taskDrawerFormId(taskId),
578
626
  retryLastMutation
579
627
  }
580
628
  });
@@ -609,6 +657,72 @@ function TaskDrawer({
609
657
  },
610
658
  [saveTaskField]
611
659
  );
660
+ const canClaim = taskQuery.data?.assignment.canClaim === true;
661
+ const canRelease = taskQuery.data?.assignment.canRelease === true;
662
+ const runAssignmentAction = React.useCallback(
663
+ (action) => {
664
+ if (!task) return;
665
+ const errorMessage = action === "claim" ? t("staff.time_tracking.taskDrawer.assignment.claimError", "Could not claim the task.") : t("staff.time_tracking.taskDrawer.assignment.releaseError", "Could not release the task.");
666
+ setBusy(true);
667
+ void runSerialized(async () => {
668
+ try {
669
+ const done = await runMutation({
670
+ operation: () => apiCallOrThrow(
671
+ `/api/staff/timesheets/tasks/${encodeURIComponent(taskId)}/${action}`,
672
+ { method: "POST" },
673
+ { errorMessage }
674
+ ),
675
+ context: {
676
+ formId: taskDrawerFormId(taskId),
677
+ retryLastMutation
678
+ }
679
+ });
680
+ const updatedAt = typeof done?.result?.updatedAt === "string" ? done.result.updatedAt : null;
681
+ if (updatedAt) versionRef.current = updatedAt;
682
+ else await refreshVersion();
683
+ invalidate("task");
684
+ flash(
685
+ action === "claim" ? t("staff.time_tracking.taskDrawer.assignment.claimed", "Task claimed.") : t("staff.time_tracking.taskDrawer.assignment.released", "Task released."),
686
+ "success"
687
+ );
688
+ onChanged?.();
689
+ } catch (error) {
690
+ if (!isAssignmentRace(error)) {
691
+ reportError(error, errorMessage);
692
+ return;
693
+ }
694
+ const refreshed = await taskQuery.refetch();
695
+ const assigneeId = refreshed.data?.task.assigneeStaffMemberId ?? null;
696
+ const takenByOther = action === "claim" && assigneeId !== null && assigneeId !== selfStaffMemberId;
697
+ setNotice({
698
+ status: "warning",
699
+ message: takenByOther ? t("staff.timesheets.errors.taskAlreadyClaimed", "Someone else already took this task.") : t(
700
+ "staff.time_tracking.taskDrawer.conflict",
701
+ "Someone else changed this task. It now shows the latest version. Check it and try again."
702
+ )
703
+ });
704
+ invalidate("task");
705
+ onChanged?.();
706
+ } finally {
707
+ setBusy(false);
708
+ }
709
+ });
710
+ },
711
+ [
712
+ invalidate,
713
+ onChanged,
714
+ refreshVersion,
715
+ reportError,
716
+ retryLastMutation,
717
+ runMutation,
718
+ runSerialized,
719
+ selfStaffMemberId,
720
+ t,
721
+ task,
722
+ taskId,
723
+ taskQuery
724
+ ]
725
+ );
612
726
  const handleToggleSubtask = React.useCallback(
613
727
  async (child, done) => {
614
728
  const targetStatusId = done ? resolveDoneStatusId(statuses) : resolveDefaultStatusId(statuses);
@@ -638,9 +752,7 @@ function TaskDrawer({
638
752
  )
639
753
  ),
640
754
  context: {
641
- formId: TASK_DRAWER_MUTATION_CONTEXT_ID,
642
- resourceKind: "staff.timesheets.task",
643
- resourceId: child.id,
755
+ formId: taskDrawerFormId(taskId),
644
756
  retryLastMutation
645
757
  }
646
758
  });
@@ -656,7 +768,7 @@ function TaskDrawer({
656
768
  setBusy(false);
657
769
  }
658
770
  },
659
- [invalidate, onChanged, reportError, retryLastMutation, runMutation, statuses, t]
771
+ [invalidate, onChanged, reportError, retryLastMutation, runMutation, statuses, t, taskId]
660
772
  );
661
773
  const handleAddSubtask = React.useCallback(async () => {
662
774
  const title = subtaskDraft.trim();
@@ -685,9 +797,7 @@ function TaskDrawer({
685
797
  }
686
798
  ),
687
799
  context: {
688
- formId: TASK_DRAWER_MUTATION_CONTEXT_ID,
689
- resourceKind: "staff.timesheets.task",
690
- resourceId: taskId,
800
+ formId: taskDrawerFormId(taskId),
691
801
  retryLastMutation
692
802
  }
693
803
  });
@@ -713,8 +823,62 @@ function TaskDrawer({
713
823
  t,
714
824
  taskId
715
825
  ]);
826
+ useAppEvent(
827
+ SUPPORT_ACTIVITY_EVENT,
828
+ (event) => {
829
+ const eventTaskId = event.payload?.taskId;
830
+ if (!open || eventTaskId !== taskId) return;
831
+ invalidate("task");
832
+ invalidate("comments");
833
+ invalidate("attachments");
834
+ },
835
+ [invalidate, open, taskId]
836
+ );
837
+ useAppEvent(
838
+ TASK_ASSIGNMENT_CHANGED_EVENT,
839
+ (event) => {
840
+ if (!open || !isAssignmentEventForTask(event.payload, taskId)) return;
841
+ invalidate("task");
842
+ },
843
+ [invalidate, open, taskId]
844
+ );
845
+ const handleMakeInternal = React.useCallback(
846
+ async (comment) => {
847
+ setBusy(true);
848
+ try {
849
+ await runMutation({
850
+ operation: () => withScopedApiRequestHeaders(
851
+ buildOptimisticLockHeader(comment.updatedAt),
852
+ () => apiCallOrThrow(
853
+ `/api/staff/timesheets/tasks/${encodeURIComponent(taskId)}/comments`,
854
+ {
855
+ method: "PUT",
856
+ headers: { "content-type": "application/json" },
857
+ body: JSON.stringify({ id: comment.id, visibility: "internal" })
858
+ },
859
+ { errorMessage: t("staff.time_tracking.taskComments.makeInternalError", "Could not change the reply.") }
860
+ )
861
+ ),
862
+ context: {
863
+ formId: taskDrawerFormId(taskId),
864
+ retryLastMutation
865
+ }
866
+ });
867
+ invalidate("comments");
868
+ } catch (error) {
869
+ if (surfaceRecordConflict(error, t)) {
870
+ invalidate("comments");
871
+ return;
872
+ }
873
+ reportError(error, t("staff.time_tracking.taskComments.makeInternalError", "Could not change the reply."));
874
+ } finally {
875
+ setBusy(false);
876
+ }
877
+ },
878
+ [invalidate, reportError, retryLastMutation, runMutation, t, taskId]
879
+ );
716
880
  const handlePostComment = React.useCallback(
717
- async (body2) => {
881
+ async (body2, visibility = "internal") => {
718
882
  setBusy(true);
719
883
  try {
720
884
  await runMutation({
@@ -723,14 +887,12 @@ function TaskDrawer({
723
887
  {
724
888
  method: "POST",
725
889
  headers: { "content-type": "application/json" },
726
- body: JSON.stringify({ body: body2 })
890
+ body: JSON.stringify({ body: body2, visibility })
727
891
  },
728
892
  { errorMessage: t("staff.time_tracking.taskDrawer.comments.error", "Could not post the comment.") }
729
893
  ),
730
894
  context: {
731
- formId: TASK_DRAWER_MUTATION_CONTEXT_ID,
732
- resourceKind: "staff.timesheets.task_comment",
733
- resourceId: taskId,
895
+ formId: taskDrawerFormId(taskId),
734
896
  retryLastMutation
735
897
  }
736
898
  });
@@ -764,9 +926,7 @@ function TaskDrawer({
764
926
  { errorMessage: t("staff.time_tracking.taskDrawer.properties.tagError", "Could not save the tags.") }
765
927
  ),
766
928
  context: {
767
- formId: TASK_DRAWER_MUTATION_CONTEXT_ID,
768
- resourceKind: "staff.timesheets.task_tag",
769
- resourceId: taskId,
929
+ formId: taskDrawerFormId(taskId),
770
930
  retryLastMutation
771
931
  }
772
932
  });
@@ -840,6 +1000,9 @@ function TaskDrawer({
840
1000
  );
841
1001
  }
842
1002
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
1003
+ notice ? /* @__PURE__ */ jsx(Alert, { status: notice.status, "data-testid": "task-drawer-notice", children: /* @__PURE__ */ jsx(AlertDescription, { children: notice.message }) }) : null,
1004
+ support ? /* @__PURE__ */ jsx(SupportRequestPanel, { ticket: support }) : null,
1005
+ support ? /* @__PURE__ */ jsx(SupportAttachmentsSection, { taskId }) : null,
843
1006
  /* @__PURE__ */ jsx(
844
1007
  TaskQuickLog,
845
1008
  {
@@ -1008,7 +1171,9 @@ function TaskDrawer({
1008
1171
  loadError: commentsQuery.isError,
1009
1172
  posting: busy,
1010
1173
  canComment: canManage,
1011
- onPost: handlePostComment
1174
+ onPost: handlePostComment,
1175
+ mode: support ? "support" : "internal",
1176
+ onMakeInternal: support ? handleMakeInternal : void 0
1012
1177
  }
1013
1178
  ),
1014
1179
  /* @__PURE__ */ jsxs("section", { className: "flex flex-col gap-3", "data-testid": "task-drawer-properties", children: [
@@ -1061,7 +1226,31 @@ function TaskDrawer({
1061
1226
  /* @__PURE__ */ jsx(SelectContent, { children: members.map((member) => /* @__PURE__ */ jsx(SelectItem, { value: member.id, children: member.name }, member.id)) })
1062
1227
  ]
1063
1228
  }
1064
- )
1229
+ ),
1230
+ canClaim ? /* @__PURE__ */ jsx(
1231
+ Button,
1232
+ {
1233
+ type: "button",
1234
+ size: "sm",
1235
+ variant: "outline",
1236
+ disabled: busy,
1237
+ onClick: () => runAssignmentAction("claim"),
1238
+ "data-testid": "task-drawer-claim",
1239
+ children: t("staff.time_tracking.taskDrawer.assignment.claim", "Claim")
1240
+ }
1241
+ ) : null,
1242
+ canRelease ? /* @__PURE__ */ jsx(
1243
+ Button,
1244
+ {
1245
+ type: "button",
1246
+ size: "sm",
1247
+ variant: "ghost",
1248
+ disabled: busy,
1249
+ onClick: () => runAssignmentAction("release"),
1250
+ "data-testid": "task-drawer-release",
1251
+ children: t("staff.time_tracking.taskDrawer.assignment.release", "Release")
1252
+ }
1253
+ ) : null
1065
1254
  ] })
1066
1255
  ] }),
1067
1256
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [