@open-mercato/core 0.7.1-develop.7178.1.ab93fbaf4e → 0.7.1-develop.7180.1.9717fbbb43

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 (808) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities/staff_time_entry/index.js +14 -0
  3. package/dist/generated/entities/staff_time_entry/index.js.map +2 -2
  4. package/dist/generated/entities/staff_time_entry_tag/index.js +15 -0
  5. package/dist/generated/entities/staff_time_entry_tag/index.js.map +7 -0
  6. package/dist/generated/entities/staff_time_project/index.js +16 -0
  7. package/dist/generated/entities/staff_time_project/index.js.map +2 -2
  8. package/dist/generated/entities/staff_time_report/index.js +57 -0
  9. package/dist/generated/entities/staff_time_report/index.js.map +7 -0
  10. package/dist/generated/entities/staff_time_report_entry/index.js +27 -0
  11. package/dist/generated/entities/staff_time_report_entry/index.js.map +7 -0
  12. package/dist/generated/entities/staff_time_report_event/index.js +21 -0
  13. package/dist/generated/entities/staff_time_report_event/index.js.map +7 -0
  14. package/dist/generated/entities/staff_time_report_project/index.js +15 -0
  15. package/dist/generated/entities/staff_time_report_project/index.js.map +7 -0
  16. package/dist/generated/entities/staff_time_tag/index.js +21 -0
  17. package/dist/generated/entities/staff_time_tag/index.js.map +7 -0
  18. package/dist/generated/entities/staff_time_task/index.js +37 -0
  19. package/dist/generated/entities/staff_time_task/index.js.map +7 -0
  20. package/dist/generated/entities/staff_time_task_comment/index.js +21 -0
  21. package/dist/generated/entities/staff_time_task_comment/index.js.map +7 -0
  22. package/dist/generated/entities/staff_time_task_status/index.js +29 -0
  23. package/dist/generated/entities/staff_time_task_status/index.js.map +7 -0
  24. package/dist/generated/entities/staff_time_task_tag/index.js +15 -0
  25. package/dist/generated/entities/staff_time_task_tag/index.js.map +7 -0
  26. package/dist/generated/entities.ids.generated.js +11 -1
  27. package/dist/generated/entities.ids.generated.js.map +2 -2
  28. package/dist/generated/entity-fields-registry.js +149 -0
  29. package/dist/generated/entity-fields-registry.js.map +2 -2
  30. package/dist/helpers/integration/timesheetFixtures.js +7 -0
  31. package/dist/helpers/integration/timesheetFixtures.js.map +2 -2
  32. package/dist/modules/auth/cli.js +16 -0
  33. package/dist/modules/auth/cli.js.map +2 -2
  34. package/dist/modules/auth/lib/backendChrome.js +1 -0
  35. package/dist/modules/auth/lib/backendChrome.js.map +2 -2
  36. package/dist/modules/customer_accounts/lib/customerRoleAcls.js +44 -0
  37. package/dist/modules/customer_accounts/lib/customerRoleAcls.js.map +7 -0
  38. package/dist/modules/customer_accounts/setup.js +1 -28
  39. package/dist/modules/customer_accounts/setup.js.map +2 -2
  40. package/dist/modules/data_sync/api/options.js +2 -0
  41. package/dist/modules/data_sync/api/options.js.map +2 -2
  42. package/dist/modules/data_sync/backend/data-sync/page.js +39 -17
  43. package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
  44. package/dist/modules/data_sync/lib/start-controls.js +42 -0
  45. package/dist/modules/data_sync/lib/start-controls.js.map +7 -0
  46. package/dist/modules/staff/acl.js +9 -1
  47. package/dist/modules/staff/acl.js.map +2 -2
  48. package/dist/modules/staff/ai-agents.js +142 -0
  49. package/dist/modules/staff/ai-agents.js.map +7 -0
  50. package/dist/modules/staff/ai-tools/time-tracking-pack.js +348 -0
  51. package/dist/modules/staff/ai-tools/time-tracking-pack.js.map +7 -0
  52. package/dist/modules/staff/ai-tools/types.js +54 -0
  53. package/dist/modules/staff/ai-tools/types.js.map +7 -0
  54. package/dist/modules/staff/ai-tools.js +8 -0
  55. package/dist/modules/staff/ai-tools.js.map +7 -0
  56. package/dist/modules/staff/analytics.js +84 -1
  57. package/dist/modules/staff/analytics.js.map +2 -2
  58. package/dist/modules/staff/api/guards.js +37 -3
  59. package/dist/modules/staff/api/guards.js.map +2 -2
  60. package/dist/modules/staff/api/leave-requests/accept/route.js +1 -3
  61. package/dist/modules/staff/api/leave-requests/accept/route.js.map +2 -2
  62. package/dist/modules/staff/api/leave-requests/reject/route.js +1 -3
  63. package/dist/modules/staff/api/leave-requests/reject/route.js.map +2 -2
  64. package/dist/modules/staff/api/portal/time-reports/[id]/route.js +131 -0
  65. package/dist/modules/staff/api/portal/time-reports/[id]/route.js.map +7 -0
  66. package/dist/modules/staff/api/portal/time-reports/route.js +179 -0
  67. package/dist/modules/staff/api/portal/time-reports/route.js.map +7 -0
  68. package/dist/modules/staff/api/team-members/self/route.js +1 -3
  69. package/dist/modules/staff/api/team-members/self/route.js.map +2 -2
  70. package/dist/modules/staff/api/team-members/tags/assign/route.js +1 -3
  71. package/dist/modules/staff/api/team-members/tags/assign/route.js.map +2 -2
  72. package/dist/modules/staff/api/team-members/tags/unassign/route.js +1 -3
  73. package/dist/modules/staff/api/team-members/tags/unassign/route.js.map +2 -2
  74. package/dist/modules/staff/api/timesheets/_shared/withTimesheetInterceptors.js +174 -0
  75. package/dist/modules/staff/api/timesheets/_shared/withTimesheetInterceptors.js.map +7 -0
  76. package/dist/modules/staff/api/timesheets/access-requests/route.js +226 -0
  77. package/dist/modules/staff/api/timesheets/access-requests/route.js.map +7 -0
  78. package/dist/modules/staff/api/timesheets/my-projects/[projectId]/route.js +15 -8
  79. package/dist/modules/staff/api/timesheets/my-projects/[projectId]/route.js.map +2 -2
  80. package/dist/modules/staff/api/timesheets/my-projects/route.js +13 -1
  81. package/dist/modules/staff/api/timesheets/my-projects/route.js.map +2 -2
  82. package/dist/modules/staff/api/timesheets/my-work/myWorkAggregate.js +42 -0
  83. package/dist/modules/staff/api/timesheets/my-work/myWorkAggregate.js.map +7 -0
  84. package/dist/modules/staff/api/timesheets/my-work/route.js +383 -0
  85. package/dist/modules/staff/api/timesheets/my-work/route.js.map +7 -0
  86. package/dist/modules/staff/api/timesheets/projects/kpis/route.js +14 -2
  87. package/dist/modules/staff/api/timesheets/projects/kpis/route.js.map +2 -2
  88. package/dist/modules/staff/api/timesheets/reports/[id]/close/route.js +168 -0
  89. package/dist/modules/staff/api/timesheets/reports/[id]/close/route.js.map +7 -0
  90. package/dist/modules/staff/api/timesheets/reports/[id]/export/route.js +246 -0
  91. package/dist/modules/staff/api/timesheets/reports/[id]/export/route.js.map +7 -0
  92. package/dist/modules/staff/api/timesheets/reports/[id]/sheet/route.js +183 -0
  93. package/dist/modules/staff/api/timesheets/reports/[id]/sheet/route.js.map +7 -0
  94. package/dist/modules/staff/api/timesheets/reports/[id]/unlock/route.js +164 -0
  95. package/dist/modules/staff/api/timesheets/reports/[id]/unlock/route.js.map +7 -0
  96. package/dist/modules/staff/api/timesheets/reports/preview/route.js +360 -0
  97. package/dist/modules/staff/api/timesheets/reports/preview/route.js.map +7 -0
  98. package/dist/modules/staff/api/timesheets/reports/route.js +316 -0
  99. package/dist/modules/staff/api/timesheets/reports/route.js.map +7 -0
  100. package/dist/modules/staff/api/timesheets/reports/shared.js +63 -0
  101. package/dist/modules/staff/api/timesheets/reports/shared.js.map +7 -0
  102. package/dist/modules/staff/api/timesheets/settings/reapply-rounding/route.js +164 -0
  103. package/dist/modules/staff/api/timesheets/settings/reapply-rounding/route.js.map +7 -0
  104. package/dist/modules/staff/api/timesheets/settings/rounding-impact/route.js +168 -0
  105. package/dist/modules/staff/api/timesheets/settings/rounding-impact/route.js.map +7 -0
  106. package/dist/modules/staff/api/timesheets/settings/route.js +199 -0
  107. package/dist/modules/staff/api/timesheets/settings/route.js.map +7 -0
  108. package/dist/modules/staff/api/timesheets/tags/access.js +76 -0
  109. package/dist/modules/staff/api/timesheets/tags/access.js.map +7 -0
  110. package/dist/modules/staff/api/timesheets/tags/entry-assignments/route.js +235 -0
  111. package/dist/modules/staff/api/timesheets/tags/entry-assignments/route.js.map +7 -0
  112. package/dist/modules/staff/api/timesheets/tags/route.js +160 -0
  113. package/dist/modules/staff/api/timesheets/tags/route.js.map +7 -0
  114. package/dist/modules/staff/api/timesheets/tags/task-assignments/route.js +233 -0
  115. package/dist/modules/staff/api/timesheets/tags/task-assignments/route.js.map +7 -0
  116. package/dist/modules/staff/api/timesheets/task-statuses/route.js +188 -0
  117. package/dist/modules/staff/api/timesheets/task-statuses/route.js.map +7 -0
  118. package/dist/modules/staff/api/timesheets/tasks/[id]/comments/route.js +399 -0
  119. package/dist/modules/staff/api/timesheets/tasks/[id]/comments/route.js.map +7 -0
  120. package/dist/modules/staff/api/timesheets/tasks/[id]/status/route.js +210 -0
  121. package/dist/modules/staff/api/timesheets/tasks/[id]/status/route.js.map +7 -0
  122. package/dist/modules/staff/api/timesheets/tasks/route.js +333 -0
  123. package/dist/modules/staff/api/timesheets/tasks/route.js.map +7 -0
  124. package/dist/modules/staff/api/timesheets/time-entries/[id]/duplicate/route.js +228 -0
  125. package/dist/modules/staff/api/timesheets/time-entries/[id]/duplicate/route.js.map +7 -0
  126. package/dist/modules/staff/api/timesheets/time-entries/[id]/segments/[segmentId]/route.js +29 -10
  127. package/dist/modules/staff/api/timesheets/time-entries/[id]/segments/[segmentId]/route.js.map +2 -2
  128. package/dist/modules/staff/api/timesheets/time-entries/[id]/segments/route.js +31 -18
  129. package/dist/modules/staff/api/timesheets/time-entries/[id]/segments/route.js.map +2 -2
  130. package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js +21 -7
  131. package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js.map +2 -2
  132. package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-stop/route.js +27 -7
  133. package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-stop/route.js.map +2 -2
  134. package/dist/modules/staff/api/timesheets/time-entries/bulk/route.js +215 -32
  135. package/dist/modules/staff/api/timesheets/time-entries/bulk/route.js.map +2 -2
  136. package/dist/modules/staff/api/timesheets/time-entries/copy-day/route.js +378 -0
  137. package/dist/modules/staff/api/timesheets/time-entries/copy-day/route.js.map +7 -0
  138. package/dist/modules/staff/api/timesheets/time-entries/overlaps/route.js +340 -0
  139. package/dist/modules/staff/api/timesheets/time-entries/overlaps/route.js.map +7 -0
  140. package/dist/modules/staff/api/timesheets/time-entries/route.js +238 -26
  141. package/dist/modules/staff/api/timesheets/time-entries/route.js.map +2 -2
  142. package/dist/modules/staff/api/timesheets/time-entries/start-timer/route.js +23 -8
  143. package/dist/modules/staff/api/timesheets/time-entries/start-timer/route.js.map +2 -2
  144. package/dist/modules/staff/api/timesheets/time-projects/[id]/change-currency/route.js +209 -0
  145. package/dist/modules/staff/api/timesheets/time-projects/[id]/change-currency/route.js.map +7 -0
  146. package/dist/modules/staff/api/timesheets/time-projects/[id]/employees/route.js +59 -2
  147. package/dist/modules/staff/api/timesheets/time-projects/[id]/employees/route.js.map +2 -2
  148. package/dist/modules/staff/api/timesheets/time-projects/route.js +264 -22
  149. package/dist/modules/staff/api/timesheets/time-projects/route.js.map +2 -2
  150. package/dist/modules/staff/backend/staff/time-tracking/board/page.js +110 -0
  151. package/dist/modules/staff/backend/staff/time-tracking/board/page.js.map +7 -0
  152. package/dist/modules/staff/backend/staff/time-tracking/board/page.meta.js +18 -0
  153. package/dist/modules/staff/backend/staff/time-tracking/board/page.meta.js.map +7 -0
  154. package/dist/modules/staff/backend/staff/time-tracking/entries/page.js +981 -0
  155. package/dist/modules/staff/backend/staff/time-tracking/entries/page.js.map +7 -0
  156. package/dist/modules/staff/backend/staff/time-tracking/entries/page.meta.js +18 -0
  157. package/dist/modules/staff/backend/staff/time-tracking/entries/page.meta.js.map +7 -0
  158. package/dist/modules/staff/backend/staff/time-tracking/page.js +583 -0
  159. package/dist/modules/staff/backend/staff/time-tracking/page.js.map +7 -0
  160. package/dist/modules/staff/backend/staff/time-tracking/page.meta.js +15 -0
  161. package/dist/modules/staff/backend/staff/time-tracking/page.meta.js.map +7 -0
  162. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/board/page.js +65 -0
  163. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/board/page.js.map +7 -0
  164. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/board/page.meta.js +16 -0
  165. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/board/page.meta.js.map +7 -0
  166. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.js +229 -0
  167. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.js.map +7 -0
  168. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.meta.js +16 -0
  169. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.meta.js.map +7 -0
  170. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js +1014 -0
  171. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js.map +7 -0
  172. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.meta.js +16 -0
  173. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.meta.js.map +7 -0
  174. package/dist/modules/staff/backend/staff/time-tracking/projects/create/page.js +97 -0
  175. package/dist/modules/staff/backend/staff/time-tracking/projects/create/page.js.map +7 -0
  176. package/dist/modules/staff/backend/staff/time-tracking/projects/create/page.meta.js +16 -0
  177. package/dist/modules/staff/backend/staff/time-tracking/projects/create/page.meta.js.map +7 -0
  178. package/dist/modules/staff/backend/staff/time-tracking/projects/page.js +1040 -0
  179. package/dist/modules/staff/backend/staff/time-tracking/projects/page.js.map +7 -0
  180. package/dist/modules/staff/backend/staff/time-tracking/projects/page.meta.js +19 -0
  181. package/dist/modules/staff/backend/staff/time-tracking/projects/page.meta.js.map +7 -0
  182. package/dist/modules/staff/backend/staff/time-tracking/projects/projectFormConfig.js +353 -0
  183. package/dist/modules/staff/backend/staff/time-tracking/projects/projectFormConfig.js.map +7 -0
  184. package/dist/modules/staff/backend/staff/time-tracking/reports/[id]/page.js +457 -0
  185. package/dist/modules/staff/backend/staff/time-tracking/reports/[id]/page.js.map +7 -0
  186. package/dist/modules/staff/backend/staff/time-tracking/reports/[id]/page.meta.js +16 -0
  187. package/dist/modules/staff/backend/staff/time-tracking/reports/[id]/page.meta.js.map +7 -0
  188. package/dist/modules/staff/backend/staff/time-tracking/reports/create/page.js +697 -0
  189. package/dist/modules/staff/backend/staff/time-tracking/reports/create/page.js.map +7 -0
  190. package/dist/modules/staff/backend/staff/time-tracking/reports/create/page.meta.js +16 -0
  191. package/dist/modules/staff/backend/staff/time-tracking/reports/create/page.meta.js.map +7 -0
  192. package/dist/modules/staff/backend/staff/time-tracking/reports/page.js +174 -0
  193. package/dist/modules/staff/backend/staff/time-tracking/reports/page.js.map +7 -0
  194. package/dist/modules/staff/backend/staff/time-tracking/reports/page.meta.js +18 -0
  195. package/dist/modules/staff/backend/staff/time-tracking/reports/page.meta.js.map +7 -0
  196. package/dist/modules/staff/backend/staff/time-tracking/settings/page.js +546 -0
  197. package/dist/modules/staff/backend/staff/time-tracking/settings/page.js.map +7 -0
  198. package/dist/modules/staff/backend/staff/time-tracking/settings/page.meta.js +18 -0
  199. package/dist/modules/staff/backend/staff/time-tracking/settings/page.meta.js.map +7 -0
  200. package/dist/modules/staff/backend/staff/time-tracking/timesheet/GridView.js +710 -0
  201. package/dist/modules/staff/backend/staff/time-tracking/timesheet/GridView.js.map +7 -0
  202. package/dist/modules/staff/backend/staff/time-tracking/timesheet/page.js +646 -0
  203. package/dist/modules/staff/backend/staff/time-tracking/timesheet/page.js.map +7 -0
  204. package/dist/modules/staff/backend/staff/time-tracking/timesheet/page.meta.js +18 -0
  205. package/dist/modules/staff/backend/staff/time-tracking/timesheet/page.meta.js.map +7 -0
  206. package/dist/modules/staff/backend/staff/timesheets/page.js +4 -793
  207. package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
  208. package/dist/modules/staff/backend/staff/timesheets/page.meta.js +2 -7
  209. package/dist/modules/staff/backend/staff/timesheets/page.meta.js.map +2 -2
  210. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.js +5 -136
  211. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.js.map +2 -2
  212. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.meta.js +1 -7
  213. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.meta.js.map +2 -2
  214. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js +5 -445
  215. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js.map +3 -3
  216. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.meta.js +1 -7
  217. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.meta.js.map +2 -2
  218. package/dist/modules/staff/backend/staff/timesheets/projects/create/page.js +4 -76
  219. package/dist/modules/staff/backend/staff/timesheets/projects/create/page.js.map +2 -2
  220. package/dist/modules/staff/backend/staff/timesheets/projects/create/page.meta.js +1 -7
  221. package/dist/modules/staff/backend/staff/timesheets/projects/create/page.meta.js.map +2 -2
  222. package/dist/modules/staff/backend/staff/timesheets/projects/page.js +4 -613
  223. package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
  224. package/dist/modules/staff/backend/staff/timesheets/projects/page.meta.js +2 -17
  225. package/dist/modules/staff/backend/staff/timesheets/projects/page.meta.js.map +2 -2
  226. package/dist/modules/staff/ce.js +40 -0
  227. package/dist/modules/staff/ce.js.map +2 -2
  228. package/dist/modules/staff/cli.js +166 -1
  229. package/dist/modules/staff/cli.js.map +2 -2
  230. package/dist/modules/staff/commands/index.js +5 -0
  231. package/dist/modules/staff/commands/index.js.map +2 -2
  232. package/dist/modules/staff/commands/timesheets-entries.js +569 -21
  233. package/dist/modules/staff/commands/timesheets-entries.js.map +3 -3
  234. package/dist/modules/staff/commands/timesheets-projects.js +450 -7
  235. package/dist/modules/staff/commands/timesheets-projects.js.map +2 -2
  236. package/dist/modules/staff/commands/timesheets-reports.js +1036 -0
  237. package/dist/modules/staff/commands/timesheets-reports.js.map +7 -0
  238. package/dist/modules/staff/commands/timesheets-tags.js +1015 -0
  239. package/dist/modules/staff/commands/timesheets-tags.js.map +7 -0
  240. package/dist/modules/staff/commands/timesheets-task-comments.js +438 -0
  241. package/dist/modules/staff/commands/timesheets-task-comments.js.map +7 -0
  242. package/dist/modules/staff/commands/timesheets-task-statuses.js +723 -0
  243. package/dist/modules/staff/commands/timesheets-task-statuses.js.map +7 -0
  244. package/dist/modules/staff/commands/timesheets-tasks.js +834 -0
  245. package/dist/modules/staff/commands/timesheets-tasks.js.map +7 -0
  246. package/dist/modules/staff/data/enrichers.js +426 -12
  247. package/dist/modules/staff/data/enrichers.js.map +2 -2
  248. package/dist/modules/staff/data/entities.js +552 -3
  249. package/dist/modules/staff/data/entities.js.map +2 -2
  250. package/dist/modules/staff/data/extensions.js +41 -0
  251. package/dist/modules/staff/data/extensions.js.map +7 -0
  252. package/dist/modules/staff/data/validators.js +254 -9
  253. package/dist/modules/staff/data/validators.js.map +2 -2
  254. package/dist/modules/staff/di.js +42 -1
  255. package/dist/modules/staff/di.js.map +2 -2
  256. package/dist/modules/staff/events.js +84 -6
  257. package/dist/modules/staff/events.js.map +2 -2
  258. package/dist/modules/staff/events.payloads.js +158 -0
  259. package/dist/modules/staff/events.payloads.js.map +7 -0
  260. package/dist/modules/staff/extension-points.js +261 -0
  261. package/dist/modules/staff/extension-points.js.map +7 -0
  262. package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.js +138 -0
  263. package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.js.map +7 -0
  264. package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.meta.js +12 -0
  265. package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.meta.js.map +7 -0
  266. package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/page.js +133 -0
  267. package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/page.js.map +7 -0
  268. package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/page.meta.js +19 -0
  269. package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/page.meta.js.map +7 -0
  270. package/dist/modules/staff/lib/crud.js +11 -1
  271. package/dist/modules/staff/lib/crud.js.map +2 -2
  272. package/dist/modules/staff/lib/time-tracking/access.js +92 -0
  273. package/dist/modules/staff/lib/time-tracking/access.js.map +7 -0
  274. package/dist/modules/staff/lib/time-tracking/billability.js +39 -0
  275. package/dist/modules/staff/lib/time-tracking/billability.js.map +7 -0
  276. package/dist/modules/staff/lib/time-tracking/capacity.js +68 -0
  277. package/dist/modules/staff/lib/time-tracking/capacity.js.map +7 -0
  278. package/dist/modules/staff/lib/time-tracking/componentContracts.js +15 -0
  279. package/dist/modules/staff/lib/time-tracking/componentContracts.js.map +7 -0
  280. package/dist/modules/staff/lib/time-tracking/cost.js +82 -0
  281. package/dist/modules/staff/lib/time-tracking/cost.js.map +7 -0
  282. package/dist/modules/staff/lib/time-tracking/duration.js +55 -0
  283. package/dist/modules/staff/lib/time-tracking/duration.js.map +7 -0
  284. package/dist/modules/staff/lib/time-tracking/featureAccess.js +41 -0
  285. package/dist/modules/staff/lib/time-tracking/featureAccess.js.map +7 -0
  286. package/dist/modules/staff/lib/time-tracking/interval.js +72 -0
  287. package/dist/modules/staff/lib/time-tracking/interval.js.map +7 -0
  288. package/dist/modules/staff/lib/time-tracking/migrateProjectCodes.js +88 -0
  289. package/dist/modules/staff/lib/time-tracking/migrateProjectCodes.js.map +7 -0
  290. package/dist/modules/staff/lib/time-tracking/moneyVisibility.js +10 -0
  291. package/dist/modules/staff/lib/time-tracking/moneyVisibility.js.map +7 -0
  292. package/dist/modules/staff/lib/time-tracking/overlap.js +87 -0
  293. package/dist/modules/staff/lib/time-tracking/overlap.js.map +7 -0
  294. package/dist/modules/staff/lib/time-tracking/portalRecipients.js +27 -0
  295. package/dist/modules/staff/lib/time-tracking/portalRecipients.js.map +7 -0
  296. package/dist/modules/staff/lib/time-tracking/portalReports.js +16 -0
  297. package/dist/modules/staff/lib/time-tracking/portalReports.js.map +7 -0
  298. package/dist/modules/staff/lib/time-tracking/projectCode.js +135 -0
  299. package/dist/modules/staff/lib/time-tracking/projectCode.js.map +7 -0
  300. package/dist/modules/staff/lib/time-tracking/reapplyRounding.js +187 -0
  301. package/dist/modules/staff/lib/time-tracking/reapplyRounding.js.map +7 -0
  302. package/dist/modules/staff/lib/time-tracking/recalculationRunner.js +80 -0
  303. package/dist/modules/staff/lib/time-tracking/recalculationRunner.js.map +7 -0
  304. package/dist/modules/staff/lib/time-tracking/recalculations.js +56 -0
  305. package/dist/modules/staff/lib/time-tracking/recalculations.js.map +7 -0
  306. package/dist/modules/staff/lib/time-tracking/registries/invoke.js +63 -0
  307. package/dist/modules/staff/lib/time-tracking/registries/invoke.js.map +7 -0
  308. package/dist/modules/staff/lib/time-tracking/registries/registry.js +62 -0
  309. package/dist/modules/staff/lib/time-tracking/registries/registry.js.map +7 -0
  310. package/dist/modules/staff/lib/time-tracking/registries/scope.js +21 -0
  311. package/dist/modules/staff/lib/time-tracking/registries/scope.js.map +7 -0
  312. package/dist/modules/staff/lib/time-tracking/rollup.js +34 -0
  313. package/dist/modules/staff/lib/time-tracking/rollup.js.map +7 -0
  314. package/dist/modules/staff/lib/time-tracking/rounding.js +66 -0
  315. package/dist/modules/staff/lib/time-tracking/rounding.js.map +7 -0
  316. package/dist/modules/staff/lib/time-tracking/roundingImpact.js +39 -0
  317. package/dist/modules/staff/lib/time-tracking/roundingImpact.js.map +7 -0
  318. package/dist/modules/staff/lib/time-tracking/settingKeys.js +214 -0
  319. package/dist/modules/staff/lib/time-tracking/settingKeys.js.map +7 -0
  320. package/dist/modules/staff/lib/time-tracking/settings.js +87 -0
  321. package/dist/modules/staff/lib/time-tracking/settings.js.map +7 -0
  322. package/dist/modules/staff/lib/time-tracking/sqlInClause.js +9 -0
  323. package/dist/modules/staff/lib/time-tracking/sqlInClause.js.map +7 -0
  324. package/dist/modules/staff/lib/time-tracking/timeEntrySources.js +48 -0
  325. package/dist/modules/staff/lib/time-tracking/timeEntrySources.js.map +7 -0
  326. package/dist/modules/staff/lib/time-tracking-ui/BoardFilterChips.js +283 -0
  327. package/dist/modules/staff/lib/time-tracking-ui/BoardFilterChips.js.map +7 -0
  328. package/dist/modules/staff/lib/time-tracking-ui/CustomerPicker.js +324 -0
  329. package/dist/modules/staff/lib/time-tracking-ui/CustomerPicker.js.map +7 -0
  330. package/dist/modules/staff/lib/time-tracking-ui/DurationInput.js +121 -0
  331. package/dist/modules/staff/lib/time-tracking-ui/DurationInput.js.map +7 -0
  332. package/dist/modules/staff/lib/time-tracking-ui/EntryDetailsFields.js +188 -0
  333. package/dist/modules/staff/lib/time-tracking-ui/EntryDetailsFields.js.map +7 -0
  334. package/dist/modules/staff/lib/time-tracking-ui/EntryFilterBar.js +89 -0
  335. package/dist/modules/staff/lib/time-tracking-ui/EntryFilterBar.js.map +7 -0
  336. package/dist/modules/staff/lib/time-tracking-ui/KanbanBoard.js +855 -0
  337. package/dist/modules/staff/lib/time-tracking-ui/KanbanBoard.js.map +7 -0
  338. package/dist/modules/staff/lib/time-tracking-ui/KanbanCard.js +360 -0
  339. package/dist/modules/staff/lib/time-tracking-ui/KanbanCard.js.map +7 -0
  340. package/dist/modules/staff/lib/time-tracking-ui/KanbanColumn.js +259 -0
  341. package/dist/modules/staff/lib/time-tracking-ui/KanbanColumn.js.map +7 -0
  342. package/dist/modules/staff/lib/time-tracking-ui/NewTaskDialog.js +238 -0
  343. package/dist/modules/staff/lib/time-tracking-ui/NewTaskDialog.js.map +7 -0
  344. package/dist/modules/staff/lib/time-tracking-ui/NoProjectAccess.js +130 -0
  345. package/dist/modules/staff/lib/time-tracking-ui/NoProjectAccess.js.map +7 -0
  346. package/dist/modules/staff/lib/time-tracking-ui/PeriodSelector.js +98 -0
  347. package/dist/modules/staff/lib/time-tracking-ui/PeriodSelector.js.map +7 -0
  348. package/dist/modules/staff/lib/time-tracking-ui/PhasePlaceholder.js +27 -0
  349. package/dist/modules/staff/lib/time-tracking-ui/PhasePlaceholder.js.map +7 -0
  350. package/dist/modules/staff/lib/time-tracking-ui/ProjectCodeField.js +166 -0
  351. package/dist/modules/staff/lib/time-tracking-ui/ProjectCodeField.js.map +7 -0
  352. package/dist/modules/staff/lib/time-tracking-ui/ProjectCurrencyField.js +295 -0
  353. package/dist/modules/staff/lib/time-tracking-ui/ProjectCurrencyField.js.map +7 -0
  354. package/dist/modules/staff/lib/time-tracking-ui/ProjectFormSections.js +212 -0
  355. package/dist/modules/staff/lib/time-tracking-ui/ProjectFormSections.js.map +7 -0
  356. package/dist/modules/staff/lib/time-tracking-ui/ProjectTeamDrawer.js +729 -0
  357. package/dist/modules/staff/lib/time-tracking-ui/ProjectTeamDrawer.js.map +7 -0
  358. package/dist/modules/staff/lib/time-tracking-ui/ReportSheet.js +217 -0
  359. package/dist/modules/staff/lib/time-tracking-ui/ReportSheet.js.map +7 -0
  360. package/dist/modules/staff/lib/time-tracking-ui/TagPicker.js +158 -0
  361. package/dist/modules/staff/lib/time-tracking-ui/TagPicker.js.map +7 -0
  362. package/dist/modules/staff/lib/time-tracking-ui/TaskBoardScreen.js +224 -0
  363. package/dist/modules/staff/lib/time-tracking-ui/TaskBoardScreen.js.map +7 -0
  364. package/dist/modules/staff/lib/time-tracking-ui/TaskCommentThread.js +93 -0
  365. package/dist/modules/staff/lib/time-tracking-ui/TaskCommentThread.js.map +7 -0
  366. package/dist/modules/staff/lib/time-tracking-ui/TaskDrawer.js +1196 -0
  367. package/dist/modules/staff/lib/time-tracking-ui/TaskDrawer.js.map +7 -0
  368. package/dist/modules/staff/lib/time-tracking-ui/TaskListView.js +176 -0
  369. package/dist/modules/staff/lib/time-tracking-ui/TaskListView.js.map +7 -0
  370. package/dist/modules/staff/lib/time-tracking-ui/TaskPicker.js +307 -0
  371. package/dist/modules/staff/lib/time-tracking-ui/TaskPicker.js.map +7 -0
  372. package/dist/modules/staff/lib/time-tracking-ui/TaskQuickLog.js +284 -0
  373. package/dist/modules/staff/lib/time-tracking-ui/TaskQuickLog.js.map +7 -0
  374. package/dist/modules/staff/lib/time-tracking-ui/TimeEntriesSummaryFooter.js +73 -0
  375. package/dist/modules/staff/lib/time-tracking-ui/TimeEntriesSummaryFooter.js.map +7 -0
  376. package/dist/modules/staff/lib/time-tracking-ui/TimeEntryDialog.js +1499 -0
  377. package/dist/modules/staff/lib/time-tracking-ui/TimeEntryDialog.js.map +7 -0
  378. package/dist/modules/staff/lib/time-tracking-ui/TimeEntryDurationCell.js +95 -0
  379. package/dist/modules/staff/lib/time-tracking-ui/TimeEntryDurationCell.js.map +7 -0
  380. package/dist/modules/staff/lib/time-tracking-ui/TimesheetCalendar.js +188 -0
  381. package/dist/modules/staff/lib/time-tracking-ui/TimesheetCalendar.js.map +7 -0
  382. package/dist/modules/staff/lib/time-tracking-ui/TimesheetPeriodFooter.js +61 -0
  383. package/dist/modules/staff/lib/time-tracking-ui/TimesheetPeriodFooter.js.map +7 -0
  384. package/dist/modules/staff/lib/time-tracking-ui/TimesheetViewSwitch.js +45 -0
  385. package/dist/modules/staff/lib/time-tracking-ui/TimesheetViewSwitch.js.map +7 -0
  386. package/dist/modules/staff/lib/time-tracking-ui/boardDirectory.js +176 -0
  387. package/dist/modules/staff/lib/time-tracking-ui/boardDirectory.js.map +7 -0
  388. package/dist/modules/staff/lib/time-tracking-ui/boardFilters.js +82 -0
  389. package/dist/modules/staff/lib/time-tracking-ui/boardFilters.js.map +7 -0
  390. package/dist/modules/staff/lib/time-tracking-ui/boardSummary.js +5 -0
  391. package/dist/modules/staff/lib/time-tracking-ui/boardSummary.js.map +7 -0
  392. package/dist/modules/staff/lib/time-tracking-ui/kanbanBoardData.js +152 -0
  393. package/dist/modules/staff/lib/time-tracking-ui/kanbanBoardData.js.map +7 -0
  394. package/dist/modules/staff/lib/time-tracking-ui/projectTeamAssignment.js +92 -0
  395. package/dist/modules/staff/lib/time-tracking-ui/projectTeamAssignment.js.map +7 -0
  396. package/dist/modules/staff/lib/time-tracking-ui/taskDrawerData.js +111 -0
  397. package/dist/modules/staff/lib/time-tracking-ui/taskDrawerData.js.map +7 -0
  398. package/dist/modules/staff/lib/time-tracking-ui/timeEntryDialogState.js +243 -0
  399. package/dist/modules/staff/lib/time-tracking-ui/timeEntryDialogState.js.map +7 -0
  400. package/dist/modules/staff/lib/time-tracking-ui/timeEntryListData.js +151 -0
  401. package/dist/modules/staff/lib/time-tracking-ui/timeEntryListData.js.map +7 -0
  402. package/dist/modules/staff/lib/time-tracking-ui/timeTrackingSettingsForm.js +105 -0
  403. package/dist/modules/staff/lib/time-tracking-ui/timeTrackingSettingsForm.js.map +7 -0
  404. package/dist/modules/staff/lib/time-tracking-ui/timesheetData.js +132 -0
  405. package/dist/modules/staff/lib/time-tracking-ui/timesheetData.js.map +7 -0
  406. package/dist/modules/staff/lib/time-tracking-ui/timesheetPeriod.js +205 -0
  407. package/dist/modules/staff/lib/time-tracking-ui/timesheetPeriod.js.map +7 -0
  408. package/dist/modules/staff/lib/time-tracking-ui/timesheetTargets.js +53 -0
  409. package/dist/modules/staff/lib/time-tracking-ui/timesheetTargets.js.map +7 -0
  410. package/dist/modules/staff/lib/time-tracking-ui/useBoardFilters.js +77 -0
  411. package/dist/modules/staff/lib/time-tracking-ui/useBoardFilters.js.map +7 -0
  412. package/dist/modules/staff/lib/time-tracking-ui/useTimesheetPreferences.js +151 -0
  413. package/dist/modules/staff/lib/time-tracking-ui/useTimesheetPreferences.js.map +7 -0
  414. package/dist/modules/staff/lib/timeTrackingSeeds.js +809 -0
  415. package/dist/modules/staff/lib/timeTrackingSeeds.js.map +7 -0
  416. package/dist/modules/staff/lib/timesheets/timeEntryCacheInvalidation.js +2 -3
  417. package/dist/modules/staff/lib/timesheets/timeEntryCacheInvalidation.js.map +2 -2
  418. package/dist/modules/staff/lib/timesheets/timeEntryDecoration.js +152 -0
  419. package/dist/modules/staff/lib/timesheets/timeEntryDecoration.js.map +7 -0
  420. package/dist/modules/staff/lib/timesheets-projects/budgetBurn.js +36 -0
  421. package/dist/modules/staff/lib/timesheets-projects/budgetBurn.js.map +7 -0
  422. package/dist/modules/staff/lib/timesheets-projects/budgetThreshold.js +66 -0
  423. package/dist/modules/staff/lib/timesheets-projects/budgetThreshold.js.map +7 -0
  424. package/dist/modules/staff/lib/timesheets-projects/budgetThresholdState.js +78 -0
  425. package/dist/modules/staff/lib/timesheets-projects/budgetThresholdState.js.map +7 -0
  426. package/dist/modules/staff/lib/timesheets-projects/computeProjectFinancials.js +81 -0
  427. package/dist/modules/staff/lib/timesheets-projects/computeProjectFinancials.js.map +7 -0
  428. package/dist/modules/staff/lib/timesheets-projects/reportSelection.js +44 -0
  429. package/dist/modules/staff/lib/timesheets-projects/reportSelection.js.map +7 -0
  430. package/dist/modules/staff/lib/timesheets-projects-ui/AssignMembersDialog.js +169 -0
  431. package/dist/modules/staff/lib/timesheets-projects-ui/AssignMembersDialog.js.map +7 -0
  432. package/dist/modules/staff/lib/timesheets-projects-ui/ProjectBudgetCell.js +22 -0
  433. package/dist/modules/staff/lib/timesheets-projects-ui/ProjectBudgetCell.js.map +7 -0
  434. package/dist/modules/staff/lib/timesheets-projects-ui/ProjectCard.js +51 -1
  435. package/dist/modules/staff/lib/timesheets-projects-ui/ProjectCard.js.map +2 -2
  436. package/dist/modules/staff/lib/timesheets-projects-ui/ProjectsBulkActionsBar.js +70 -0
  437. package/dist/modules/staff/lib/timesheets-projects-ui/ProjectsBulkActionsBar.js.map +7 -0
  438. package/dist/modules/staff/lib/timesheets-reports/buildReportSheet.js +63 -0
  439. package/dist/modules/staff/lib/timesheets-reports/buildReportSheet.js.map +7 -0
  440. package/dist/modules/staff/lib/timesheets-reports/loadReportData.js +170 -0
  441. package/dist/modules/staff/lib/timesheets-reports/loadReportData.js.map +7 -0
  442. package/dist/modules/staff/lib/timesheets-reports/pdf.js +205 -0
  443. package/dist/modules/staff/lib/timesheets-reports/pdf.js.map +7 -0
  444. package/dist/modules/staff/lib/timesheets-reports/reportApprovalPolicies.js +68 -0
  445. package/dist/modules/staff/lib/timesheets-reports/reportApprovalPolicies.js.map +7 -0
  446. package/dist/modules/staff/lib/timesheets-reports/reportConfigData.js +135 -0
  447. package/dist/modules/staff/lib/timesheets-reports/reportConfigData.js.map +7 -0
  448. package/dist/modules/staff/lib/timesheets-reports/reportConfigState.js +48 -0
  449. package/dist/modules/staff/lib/timesheets-reports/reportConfigState.js.map +7 -0
  450. package/dist/modules/staff/lib/timesheets-reports/reportExport.js +262 -0
  451. package/dist/modules/staff/lib/timesheets-reports/reportExport.js.map +7 -0
  452. package/dist/modules/staff/lib/timesheets-reports/reportExportFormats.js +34 -0
  453. package/dist/modules/staff/lib/timesheets-reports/reportExportFormats.js.map +7 -0
  454. package/dist/modules/staff/lib/timesheets-reports/reportGroupings.js +79 -0
  455. package/dist/modules/staff/lib/timesheets-reports/reportGroupings.js.map +7 -0
  456. package/dist/modules/staff/lib/timesheets-reports/reportLabels.js +11 -0
  457. package/dist/modules/staff/lib/timesheets-reports/reportLabels.js.map +7 -0
  458. package/dist/modules/staff/lib/timesheets-reports/reportReference.js +83 -0
  459. package/dist/modules/staff/lib/timesheets-reports/reportReference.js.map +7 -0
  460. package/dist/modules/staff/lib/timesheets-reports/reportRows.js +42 -0
  461. package/dist/modules/staff/lib/timesheets-reports/reportRows.js.map +7 -0
  462. package/dist/modules/staff/lib/timesheets-reports/reportSheetData.js +107 -0
  463. package/dist/modules/staff/lib/timesheets-reports/reportSheetData.js.map +7 -0
  464. package/dist/modules/staff/lib/timesheets-reports/reportTotals.js +289 -0
  465. package/dist/modules/staff/lib/timesheets-reports/reportTotals.js.map +7 -0
  466. package/dist/modules/staff/lib/timesheets-reports/xlsx.js +145 -0
  467. package/dist/modules/staff/lib/timesheets-reports/xlsx.js.map +7 -0
  468. package/dist/modules/staff/lib/timesheets-tasks/computeTaskRollups.js +116 -0
  469. package/dist/modules/staff/lib/timesheets-tasks/computeTaskRollups.js.map +7 -0
  470. package/dist/modules/staff/lib/timesheets-tasks/defaultStatusTemplate.js +50 -0
  471. package/dist/modules/staff/lib/timesheets-tasks/defaultStatusTemplate.js.map +7 -0
  472. package/dist/modules/staff/lib/timesheets-tasks/seedProjectStatuses.js +27 -0
  473. package/dist/modules/staff/lib/timesheets-tasks/seedProjectStatuses.js.map +7 -0
  474. package/dist/modules/staff/lib/timesheets-tasks/statusPositions.js +65 -0
  475. package/dist/modules/staff/lib/timesheets-tasks/statusPositions.js.map +7 -0
  476. package/dist/modules/staff/lib/timesheets-tasks/statusSlug.js +31 -0
  477. package/dist/modules/staff/lib/timesheets-tasks/statusSlug.js.map +7 -0
  478. package/dist/modules/staff/lib/timesheets-tasks/taskHierarchy.js +31 -0
  479. package/dist/modules/staff/lib/timesheets-tasks/taskHierarchy.js.map +7 -0
  480. package/dist/modules/staff/lib/timesheets-tasks/taskHoursTotals.js +17 -0
  481. package/dist/modules/staff/lib/timesheets-tasks/taskHoursTotals.js.map +7 -0
  482. package/dist/modules/staff/lib/timesheets-tasks/taskReference.js +51 -0
  483. package/dist/modules/staff/lib/timesheets-tasks/taskReference.js.map +7 -0
  484. package/dist/modules/staff/lib/timesheets-ui/CreateProjectDialog.js +11 -4
  485. package/dist/modules/staff/lib/timesheets-ui/CreateProjectDialog.js.map +2 -2
  486. package/dist/modules/staff/lib/timesheets-ui/ListView.js +369 -111
  487. package/dist/modules/staff/lib/timesheets-ui/ListView.js.map +2 -2
  488. package/dist/modules/staff/lib/timesheets-ui/TimerBar.js +47 -2
  489. package/dist/modules/staff/lib/timesheets-ui/TimerBar.js.map +2 -2
  490. package/dist/modules/staff/migrations/Migration20260813073131_staff.js +79 -0
  491. package/dist/modules/staff/migrations/Migration20260813073131_staff.js.map +7 -0
  492. package/dist/modules/staff/migrations/Migration20260824143357_staff.js +15 -0
  493. package/dist/modules/staff/migrations/Migration20260824143357_staff.js.map +7 -0
  494. package/dist/modules/staff/notifications.client.js +16 -0
  495. package/dist/modules/staff/notifications.client.js.map +7 -0
  496. package/dist/modules/staff/notifications.handlers.js +80 -0
  497. package/dist/modules/staff/notifications.handlers.js.map +7 -0
  498. package/dist/modules/staff/notifications.js +168 -0
  499. package/dist/modules/staff/notifications.js.map +2 -2
  500. package/dist/modules/staff/search.js +159 -1
  501. package/dist/modules/staff/search.js.map +2 -2
  502. package/dist/modules/staff/setup.js +20 -1
  503. package/dist/modules/staff/setup.js.map +2 -2
  504. package/dist/modules/staff/subscribers/time-project-access-requested-notification.js +68 -0
  505. package/dist/modules/staff/subscribers/time-project-access-requested-notification.js.map +7 -0
  506. package/dist/modules/staff/subscribers/time-project-budget-threshold-notification.js +149 -0
  507. package/dist/modules/staff/subscribers/time-project-budget-threshold-notification.js.map +7 -0
  508. package/dist/modules/staff/subscribers/time-report-approved-notification.js +78 -0
  509. package/dist/modules/staff/subscribers/time-report-approved-notification.js.map +7 -0
  510. package/dist/modules/staff/subscribers/time-report-portal-broadcast.js +78 -0
  511. package/dist/modules/staff/subscribers/time-report-portal-broadcast.js.map +7 -0
  512. package/dist/modules/staff/translations.js +4 -1
  513. package/dist/modules/staff/translations.js.map +2 -2
  514. package/dist/modules/staff/widgets/components.js +7 -0
  515. package/dist/modules/staff/widgets/components.js.map +7 -0
  516. package/dist/modules/staff/widgets/injection/timer-sidebar-indicator/widget.js +5 -4
  517. package/dist/modules/staff/widgets/injection/timer-sidebar-indicator/widget.js.map +2 -2
  518. package/dist/modules/staff/widgets/notifications/TimeProjectAccessRequestedRenderer.js +135 -0
  519. package/dist/modules/staff/widgets/notifications/TimeProjectAccessRequestedRenderer.js.map +7 -0
  520. package/dist/modules/staff/widgets/notifications/index.js +5 -0
  521. package/dist/modules/staff/widgets/notifications/index.js.map +7 -0
  522. package/dist/modules/staff/workers/timesheets-reapply-rounding.js +43 -0
  523. package/dist/modules/staff/workers/timesheets-reapply-rounding.js.map +7 -0
  524. package/generated/entities/staff_time_entry/index.ts +7 -0
  525. package/generated/entities/staff_time_entry_tag/index.ts +6 -0
  526. package/generated/entities/staff_time_project/index.ts +8 -0
  527. package/generated/entities/staff_time_report/index.ts +27 -0
  528. package/generated/entities/staff_time_report_entry/index.ts +12 -0
  529. package/generated/entities/staff_time_report_event/index.ts +9 -0
  530. package/generated/entities/staff_time_report_project/index.ts +6 -0
  531. package/generated/entities/staff_time_tag/index.ts +9 -0
  532. package/generated/entities/staff_time_task/index.ts +17 -0
  533. package/generated/entities/staff_time_task_comment/index.ts +9 -0
  534. package/generated/entities/staff_time_task_status/index.ts +13 -0
  535. package/generated/entities/staff_time_task_tag/index.ts +6 -0
  536. package/generated/entities.ids.generated.ts +11 -1
  537. package/generated/entity-fields-registry.ts +149 -0
  538. package/package.json +7 -7
  539. package/src/helpers/integration/timesheetFixtures.ts +31 -1
  540. package/src/modules/auth/README.md +1 -1
  541. package/src/modules/auth/cli.ts +35 -1
  542. package/src/modules/auth/i18n/de.json +7 -0
  543. package/src/modules/auth/i18n/en.json +7 -0
  544. package/src/modules/auth/i18n/es.json +7 -0
  545. package/src/modules/auth/i18n/ko.json +7 -0
  546. package/src/modules/auth/i18n/pl.json +7 -0
  547. package/src/modules/auth/lib/backendChrome.tsx +1 -0
  548. package/src/modules/customer_accounts/lib/customerRoleAcls.ts +79 -0
  549. package/src/modules/customer_accounts/setup.ts +1 -45
  550. package/src/modules/data_sync/AGENTS.md +34 -0
  551. package/src/modules/data_sync/api/options.ts +2 -0
  552. package/src/modules/data_sync/backend/data-sync/page.tsx +82 -33
  553. package/src/modules/data_sync/i18n/de.json +1 -0
  554. package/src/modules/data_sync/i18n/en.json +1 -0
  555. package/src/modules/data_sync/i18n/es.json +1 -0
  556. package/src/modules/data_sync/i18n/ko.json +1 -0
  557. package/src/modules/data_sync/i18n/pl.json +1 -0
  558. package/src/modules/data_sync/lib/adapter.ts +45 -0
  559. package/src/modules/data_sync/lib/start-controls.ts +89 -0
  560. package/src/modules/staff/AGENTS.md +769 -1
  561. package/src/modules/staff/acl.ts +9 -0
  562. package/src/modules/staff/ai-agents.ts +189 -0
  563. package/src/modules/staff/ai-tools/time-tracking-pack.ts +494 -0
  564. package/src/modules/staff/ai-tools/types.ts +82 -0
  565. package/src/modules/staff/ai-tools.ts +13 -0
  566. package/src/modules/staff/analytics.ts +113 -0
  567. package/src/modules/staff/api/guards.ts +85 -3
  568. package/src/modules/staff/api/leave-requests/accept/route.ts +0 -2
  569. package/src/modules/staff/api/leave-requests/reject/route.ts +0 -2
  570. package/src/modules/staff/api/portal/time-reports/[id]/route.ts +182 -0
  571. package/src/modules/staff/api/portal/time-reports/route.ts +270 -0
  572. package/src/modules/staff/api/team-members/self/route.ts +0 -2
  573. package/src/modules/staff/api/team-members/tags/assign/route.ts +0 -2
  574. package/src/modules/staff/api/team-members/tags/unassign/route.ts +0 -2
  575. package/src/modules/staff/api/timesheets/_shared/withTimesheetInterceptors.ts +292 -0
  576. package/src/modules/staff/api/timesheets/access-requests/route.ts +299 -0
  577. package/src/modules/staff/api/timesheets/my-projects/[projectId]/route.ts +15 -7
  578. package/src/modules/staff/api/timesheets/my-projects/route.ts +14 -1
  579. package/src/modules/staff/api/timesheets/my-work/myWorkAggregate.ts +90 -0
  580. package/src/modules/staff/api/timesheets/my-work/route.ts +475 -0
  581. package/src/modules/staff/api/timesheets/projects/kpis/route.ts +15 -2
  582. package/src/modules/staff/api/timesheets/reports/[id]/close/route.ts +203 -0
  583. package/src/modules/staff/api/timesheets/reports/[id]/export/route.ts +315 -0
  584. package/src/modules/staff/api/timesheets/reports/[id]/sheet/route.ts +220 -0
  585. package/src/modules/staff/api/timesheets/reports/[id]/unlock/route.ts +208 -0
  586. package/src/modules/staff/api/timesheets/reports/preview/route.ts +449 -0
  587. package/src/modules/staff/api/timesheets/reports/route.ts +386 -0
  588. package/src/modules/staff/api/timesheets/reports/shared.ts +121 -0
  589. package/src/modules/staff/api/timesheets/settings/reapply-rounding/route.ts +205 -0
  590. package/src/modules/staff/api/timesheets/settings/rounding-impact/route.ts +226 -0
  591. package/src/modules/staff/api/timesheets/settings/route.ts +242 -0
  592. package/src/modules/staff/api/timesheets/tags/access.ts +134 -0
  593. package/src/modules/staff/api/timesheets/tags/entry-assignments/route.ts +290 -0
  594. package/src/modules/staff/api/timesheets/tags/route.ts +177 -0
  595. package/src/modules/staff/api/timesheets/tags/task-assignments/route.ts +294 -0
  596. package/src/modules/staff/api/timesheets/task-statuses/route.ts +232 -0
  597. package/src/modules/staff/api/timesheets/tasks/[id]/comments/route.ts +532 -0
  598. package/src/modules/staff/api/timesheets/tasks/[id]/status/route.ts +271 -0
  599. package/src/modules/staff/api/timesheets/tasks/route.ts +443 -0
  600. package/src/modules/staff/api/timesheets/time-entries/[id]/duplicate/route.ts +306 -0
  601. package/src/modules/staff/api/timesheets/time-entries/[id]/segments/[segmentId]/route.ts +32 -10
  602. package/src/modules/staff/api/timesheets/time-entries/[id]/segments/route.ts +32 -17
  603. package/src/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.ts +27 -6
  604. package/src/modules/staff/api/timesheets/time-entries/[id]/timer-stop/route.ts +36 -6
  605. package/src/modules/staff/api/timesheets/time-entries/bulk/route.ts +331 -34
  606. package/src/modules/staff/api/timesheets/time-entries/copy-day/route.ts +533 -0
  607. package/src/modules/staff/api/timesheets/time-entries/overlaps/route.ts +457 -0
  608. package/src/modules/staff/api/timesheets/time-entries/route.ts +378 -24
  609. package/src/modules/staff/api/timesheets/time-entries/start-timer/route.ts +31 -9
  610. package/src/modules/staff/api/timesheets/time-projects/[id]/change-currency/route.ts +246 -0
  611. package/src/modules/staff/api/timesheets/time-projects/[id]/employees/route.ts +62 -2
  612. package/src/modules/staff/api/timesheets/time-projects/route.ts +397 -22
  613. package/src/modules/staff/backend/staff/time-tracking/board/page.meta.ts +14 -0
  614. package/src/modules/staff/backend/staff/time-tracking/board/page.tsx +151 -0
  615. package/src/modules/staff/backend/staff/time-tracking/entries/page.meta.ts +14 -0
  616. package/src/modules/staff/backend/staff/time-tracking/entries/page.tsx +1229 -0
  617. package/src/modules/staff/backend/staff/time-tracking/page.meta.ts +11 -0
  618. package/src/modules/staff/backend/staff/time-tracking/page.tsx +823 -0
  619. package/src/modules/staff/backend/staff/time-tracking/projects/[id]/board/page.meta.ts +12 -0
  620. package/src/modules/staff/backend/staff/time-tracking/projects/[id]/board/page.tsx +81 -0
  621. package/src/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.meta.ts +12 -0
  622. package/src/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.tsx +275 -0
  623. package/src/modules/staff/backend/staff/time-tracking/projects/[id]/page.meta.ts +12 -0
  624. package/src/modules/staff/backend/staff/time-tracking/projects/[id]/page.tsx +1420 -0
  625. package/src/modules/staff/backend/staff/time-tracking/projects/create/page.meta.ts +12 -0
  626. package/src/modules/staff/backend/staff/time-tracking/projects/create/page.tsx +109 -0
  627. package/src/modules/staff/backend/staff/time-tracking/projects/page.meta.ts +15 -0
  628. package/src/modules/staff/backend/staff/time-tracking/projects/page.tsx +1254 -0
  629. package/src/modules/staff/backend/staff/time-tracking/projects/projectFormConfig.ts +466 -0
  630. package/src/modules/staff/backend/staff/time-tracking/reports/[id]/page.meta.ts +12 -0
  631. package/src/modules/staff/backend/staff/time-tracking/reports/[id]/page.tsx +632 -0
  632. package/src/modules/staff/backend/staff/time-tracking/reports/create/page.meta.ts +12 -0
  633. package/src/modules/staff/backend/staff/time-tracking/reports/create/page.tsx +867 -0
  634. package/src/modules/staff/backend/staff/time-tracking/reports/page.meta.ts +14 -0
  635. package/src/modules/staff/backend/staff/time-tracking/reports/page.tsx +246 -0
  636. package/src/modules/staff/backend/staff/time-tracking/settings/page.meta.ts +14 -0
  637. package/src/modules/staff/backend/staff/time-tracking/settings/page.tsx +701 -0
  638. package/src/modules/staff/backend/staff/time-tracking/timesheet/GridView.tsx +953 -0
  639. package/src/modules/staff/backend/staff/time-tracking/timesheet/page.meta.ts +14 -0
  640. package/src/modules/staff/backend/staff/time-tracking/timesheet/page.tsx +800 -0
  641. package/src/modules/staff/backend/staff/timesheets/page.meta.ts +6 -6
  642. package/src/modules/staff/backend/staff/timesheets/page.tsx +12 -1010
  643. package/src/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.meta.ts +0 -6
  644. package/src/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.tsx +4 -158
  645. package/src/modules/staff/backend/staff/timesheets/projects/[id]/page.meta.ts +0 -6
  646. package/src/modules/staff/backend/staff/timesheets/projects/[id]/page.tsx +4 -609
  647. package/src/modules/staff/backend/staff/timesheets/projects/create/page.meta.ts +0 -6
  648. package/src/modules/staff/backend/staff/timesheets/projects/create/page.tsx +3 -89
  649. package/src/modules/staff/backend/staff/timesheets/projects/page.meta.ts +2 -19
  650. package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +3 -778
  651. package/src/modules/staff/ce.ts +63 -0
  652. package/src/modules/staff/cli.ts +207 -1
  653. package/src/modules/staff/commands/index.ts +5 -0
  654. package/src/modules/staff/commands/timesheets-entries.ts +1006 -28
  655. package/src/modules/staff/commands/timesheets-projects.ts +593 -7
  656. package/src/modules/staff/commands/timesheets-reports.ts +1329 -0
  657. package/src/modules/staff/commands/timesheets-tags.ts +1315 -0
  658. package/src/modules/staff/commands/timesheets-task-comments.ts +583 -0
  659. package/src/modules/staff/commands/timesheets-task-statuses.ts +889 -0
  660. package/src/modules/staff/commands/timesheets-tasks.ts +1121 -0
  661. package/src/modules/staff/data/enrichers.ts +675 -10
  662. package/src/modules/staff/data/entities.ts +494 -2
  663. package/src/modules/staff/data/extensions.ts +68 -0
  664. package/src/modules/staff/data/validators.ts +348 -3
  665. package/src/modules/staff/di.ts +96 -0
  666. package/src/modules/staff/events.payloads.ts +268 -0
  667. package/src/modules/staff/events.ts +87 -5
  668. package/src/modules/staff/extension-points.ts +308 -0
  669. package/src/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.meta.ts +10 -0
  670. package/src/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.tsx +225 -0
  671. package/src/modules/staff/frontend/[orgSlug]/portal/time-reports/page.meta.ts +17 -0
  672. package/src/modules/staff/frontend/[orgSlug]/portal/time-reports/page.tsx +182 -0
  673. package/src/modules/staff/i18n/de.json +899 -0
  674. package/src/modules/staff/i18n/en.json +899 -0
  675. package/src/modules/staff/i18n/es.json +899 -0
  676. package/src/modules/staff/i18n/ko.json +899 -0
  677. package/src/modules/staff/i18n/pl.json +899 -0
  678. package/src/modules/staff/lib/crud.ts +14 -3
  679. package/src/modules/staff/lib/time-tracking/access.ts +155 -0
  680. package/src/modules/staff/lib/time-tracking/billability.ts +68 -0
  681. package/src/modules/staff/lib/time-tracking/capacity.ts +124 -0
  682. package/src/modules/staff/lib/time-tracking/componentContracts.ts +26 -0
  683. package/src/modules/staff/lib/time-tracking/cost.ts +144 -0
  684. package/src/modules/staff/lib/time-tracking/duration.ts +68 -0
  685. package/src/modules/staff/lib/time-tracking/featureAccess.ts +115 -0
  686. package/src/modules/staff/lib/time-tracking/interval.ts +90 -0
  687. package/src/modules/staff/lib/time-tracking/migrateProjectCodes.ts +161 -0
  688. package/src/modules/staff/lib/time-tracking/moneyVisibility.ts +37 -0
  689. package/src/modules/staff/lib/time-tracking/overlap.ts +159 -0
  690. package/src/modules/staff/lib/time-tracking/portalRecipients.ts +76 -0
  691. package/src/modules/staff/lib/time-tracking/portalReports.ts +31 -0
  692. package/src/modules/staff/lib/time-tracking/projectCode.ts +221 -0
  693. package/src/modules/staff/lib/time-tracking/reapplyRounding.ts +313 -0
  694. package/src/modules/staff/lib/time-tracking/recalculationRunner.ts +118 -0
  695. package/src/modules/staff/lib/time-tracking/recalculations.ts +135 -0
  696. package/src/modules/staff/lib/time-tracking/registries/invoke.ts +122 -0
  697. package/src/modules/staff/lib/time-tracking/registries/registry.ts +124 -0
  698. package/src/modules/staff/lib/time-tracking/registries/scope.ts +56 -0
  699. package/src/modules/staff/lib/time-tracking/rollup.ts +59 -0
  700. package/src/modules/staff/lib/time-tracking/rounding.ts +126 -0
  701. package/src/modules/staff/lib/time-tracking/roundingImpact.ts +75 -0
  702. package/src/modules/staff/lib/time-tracking/settingKeys.ts +274 -0
  703. package/src/modules/staff/lib/time-tracking/settings.ts +168 -0
  704. package/src/modules/staff/lib/time-tracking/sqlInClause.ts +22 -0
  705. package/src/modules/staff/lib/time-tracking/timeEntrySources.ts +85 -0
  706. package/src/modules/staff/lib/time-tracking-ui/BoardFilterChips.tsx +360 -0
  707. package/src/modules/staff/lib/time-tracking-ui/CustomerPicker.tsx +427 -0
  708. package/src/modules/staff/lib/time-tracking-ui/DurationInput.tsx +192 -0
  709. package/src/modules/staff/lib/time-tracking-ui/EntryDetailsFields.tsx +224 -0
  710. package/src/modules/staff/lib/time-tracking-ui/EntryFilterBar.tsx +144 -0
  711. package/src/modules/staff/lib/time-tracking-ui/KanbanBoard.tsx +1065 -0
  712. package/src/modules/staff/lib/time-tracking-ui/KanbanCard.tsx +435 -0
  713. package/src/modules/staff/lib/time-tracking-ui/KanbanColumn.tsx +316 -0
  714. package/src/modules/staff/lib/time-tracking-ui/NewTaskDialog.tsx +291 -0
  715. package/src/modules/staff/lib/time-tracking-ui/NoProjectAccess.tsx +162 -0
  716. package/src/modules/staff/lib/time-tracking-ui/PeriodSelector.tsx +149 -0
  717. package/src/modules/staff/lib/time-tracking-ui/PhasePlaceholder.tsx +31 -0
  718. package/src/modules/staff/lib/time-tracking-ui/ProjectCodeField.tsx +230 -0
  719. package/src/modules/staff/lib/time-tracking-ui/ProjectCurrencyField.tsx +432 -0
  720. package/src/modules/staff/lib/time-tracking-ui/ProjectFormSections.tsx +323 -0
  721. package/src/modules/staff/lib/time-tracking-ui/ProjectTeamDrawer.tsx +930 -0
  722. package/src/modules/staff/lib/time-tracking-ui/ReportSheet.tsx +357 -0
  723. package/src/modules/staff/lib/time-tracking-ui/TagPicker.tsx +195 -0
  724. package/src/modules/staff/lib/time-tracking-ui/TaskBoardScreen.tsx +243 -0
  725. package/src/modules/staff/lib/time-tracking-ui/TaskCommentThread.tsx +137 -0
  726. package/src/modules/staff/lib/time-tracking-ui/TaskDrawer.tsx +1405 -0
  727. package/src/modules/staff/lib/time-tracking-ui/TaskListView.tsx +260 -0
  728. package/src/modules/staff/lib/time-tracking-ui/TaskPicker.tsx +435 -0
  729. package/src/modules/staff/lib/time-tracking-ui/TaskQuickLog.tsx +296 -0
  730. package/src/modules/staff/lib/time-tracking-ui/TimeEntriesSummaryFooter.tsx +97 -0
  731. package/src/modules/staff/lib/time-tracking-ui/TimeEntryDialog.tsx +1929 -0
  732. package/src/modules/staff/lib/time-tracking-ui/TimeEntryDurationCell.tsx +126 -0
  733. package/src/modules/staff/lib/time-tracking-ui/TimesheetCalendar.tsx +265 -0
  734. package/src/modules/staff/lib/time-tracking-ui/TimesheetPeriodFooter.tsx +78 -0
  735. package/src/modules/staff/lib/time-tracking-ui/TimesheetViewSwitch.tsx +70 -0
  736. package/src/modules/staff/lib/time-tracking-ui/boardDirectory.ts +231 -0
  737. package/src/modules/staff/lib/time-tracking-ui/boardFilters.ts +128 -0
  738. package/src/modules/staff/lib/time-tracking-ui/boardSummary.ts +20 -0
  739. package/src/modules/staff/lib/time-tracking-ui/kanbanBoardData.ts +228 -0
  740. package/src/modules/staff/lib/time-tracking-ui/projectTeamAssignment.ts +143 -0
  741. package/src/modules/staff/lib/time-tracking-ui/taskDrawerData.ts +194 -0
  742. package/src/modules/staff/lib/time-tracking-ui/timeEntryDialogState.ts +400 -0
  743. package/src/modules/staff/lib/time-tracking-ui/timeEntryListData.ts +271 -0
  744. package/src/modules/staff/lib/time-tracking-ui/timeTrackingSettingsForm.ts +168 -0
  745. package/src/modules/staff/lib/time-tracking-ui/timesheetData.ts +225 -0
  746. package/src/modules/staff/lib/time-tracking-ui/timesheetPeriod.ts +278 -0
  747. package/src/modules/staff/lib/time-tracking-ui/timesheetTargets.ts +93 -0
  748. package/src/modules/staff/lib/time-tracking-ui/useBoardFilters.ts +107 -0
  749. package/src/modules/staff/lib/time-tracking-ui/useTimesheetPreferences.ts +245 -0
  750. package/src/modules/staff/lib/timeTrackingSeeds.ts +1037 -0
  751. package/src/modules/staff/lib/timesheets/timeEntryCacheInvalidation.ts +11 -10
  752. package/src/modules/staff/lib/timesheets/timeEntryDecoration.ts +256 -0
  753. package/src/modules/staff/lib/timesheets-projects/budgetBurn.ts +60 -0
  754. package/src/modules/staff/lib/timesheets-projects/budgetThreshold.ts +135 -0
  755. package/src/modules/staff/lib/timesheets-projects/budgetThresholdState.ts +137 -0
  756. package/src/modules/staff/lib/timesheets-projects/computeProjectFinancials.ts +142 -0
  757. package/src/modules/staff/lib/timesheets-projects/reportSelection.ts +82 -0
  758. package/src/modules/staff/lib/timesheets-projects-ui/AssignMembersDialog.tsx +237 -0
  759. package/src/modules/staff/lib/timesheets-projects-ui/ProjectBudgetCell.tsx +33 -0
  760. package/src/modules/staff/lib/timesheets-projects-ui/ProjectCard.tsx +56 -1
  761. package/src/modules/staff/lib/timesheets-projects-ui/ProjectsBulkActionsBar.tsx +90 -0
  762. package/src/modules/staff/lib/timesheets-reports/buildReportSheet.ts +125 -0
  763. package/src/modules/staff/lib/timesheets-reports/loadReportData.ts +251 -0
  764. package/src/modules/staff/lib/timesheets-reports/pdf.ts +263 -0
  765. package/src/modules/staff/lib/timesheets-reports/reportApprovalPolicies.ts +137 -0
  766. package/src/modules/staff/lib/timesheets-reports/reportConfigData.ts +247 -0
  767. package/src/modules/staff/lib/timesheets-reports/reportConfigState.ts +89 -0
  768. package/src/modules/staff/lib/timesheets-reports/reportExport.ts +373 -0
  769. package/src/modules/staff/lib/timesheets-reports/reportExportFormats.ts +71 -0
  770. package/src/modules/staff/lib/timesheets-reports/reportGroupings.ts +153 -0
  771. package/src/modules/staff/lib/timesheets-reports/reportLabels.ts +23 -0
  772. package/src/modules/staff/lib/timesheets-reports/reportReference.ts +146 -0
  773. package/src/modules/staff/lib/timesheets-reports/reportRows.ts +89 -0
  774. package/src/modules/staff/lib/timesheets-reports/reportSheetData.ts +196 -0
  775. package/src/modules/staff/lib/timesheets-reports/reportTotals.ts +544 -0
  776. package/src/modules/staff/lib/timesheets-reports/xlsx.ts +207 -0
  777. package/src/modules/staff/lib/timesheets-tasks/computeTaskRollups.ts +238 -0
  778. package/src/modules/staff/lib/timesheets-tasks/defaultStatusTemplate.ts +90 -0
  779. package/src/modules/staff/lib/timesheets-tasks/seedProjectStatuses.ts +43 -0
  780. package/src/modules/staff/lib/timesheets-tasks/statusPositions.ts +132 -0
  781. package/src/modules/staff/lib/timesheets-tasks/statusSlug.ts +43 -0
  782. package/src/modules/staff/lib/timesheets-tasks/taskHierarchy.ts +99 -0
  783. package/src/modules/staff/lib/timesheets-tasks/taskHoursTotals.ts +42 -0
  784. package/src/modules/staff/lib/timesheets-tasks/taskReference.ts +108 -0
  785. package/src/modules/staff/lib/timesheets-ui/CreateProjectDialog.tsx +18 -4
  786. package/src/modules/staff/lib/timesheets-ui/ListView.tsx +504 -149
  787. package/src/modules/staff/lib/timesheets-ui/TimerBar.tsx +50 -2
  788. package/src/modules/staff/migrations/.snapshot-open-mercato.json +3244 -228
  789. package/src/modules/staff/migrations/Migration20260813073131_staff.ts +94 -0
  790. package/src/modules/staff/migrations/Migration20260824143357_staff.ts +17 -0
  791. package/src/modules/staff/notifications.client.ts +16 -0
  792. package/src/modules/staff/notifications.handlers.ts +88 -0
  793. package/src/modules/staff/notifications.ts +163 -0
  794. package/src/modules/staff/search.ts +191 -1
  795. package/src/modules/staff/setup.ts +22 -0
  796. package/src/modules/staff/subscribers/time-project-access-requested-notification.ts +95 -0
  797. package/src/modules/staff/subscribers/time-project-budget-threshold-notification.ts +226 -0
  798. package/src/modules/staff/subscribers/time-report-approved-notification.ts +116 -0
  799. package/src/modules/staff/subscribers/time-report-portal-broadcast.ts +120 -0
  800. package/src/modules/staff/translations.ts +17 -0
  801. package/src/modules/staff/widgets/components.ts +34 -0
  802. package/src/modules/staff/widgets/injection/timer-sidebar-indicator/widget.tsx +6 -5
  803. package/src/modules/staff/widgets/notifications/TimeProjectAccessRequestedRenderer.tsx +138 -0
  804. package/src/modules/staff/widgets/notifications/index.ts +1 -0
  805. package/src/modules/staff/workers/timesheets-reapply-rounding.ts +59 -0
  806. package/dist/modules/staff/backend/staff/timesheets/projects/projectFormConfig.js +0 -123
  807. package/dist/modules/staff/backend/staff/timesheets/projects/projectFormConfig.js.map +0 -7
  808. package/src/modules/staff/backend/staff/timesheets/projects/projectFormConfig.ts +0 -138
@@ -0,0 +1,697 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { useRouter, useSearchParams } from "next/navigation";
5
+ import { AlertTriangle, FileText, Info } from "lucide-react";
6
+ import { Page, PageBody } from "@open-mercato/ui/backend/Page";
7
+ import { Alert, AlertDescription, AlertTitle } from "@open-mercato/ui/primitives/alert";
8
+ import { Button } from "@open-mercato/ui/primitives/button";
9
+ import { Card, CardContent, CardHeader, CardTitle } from "@open-mercato/ui/primitives/card";
10
+ import { Checkbox } from "@open-mercato/ui/primitives/checkbox";
11
+ import { Input } from "@open-mercato/ui/primitives/input";
12
+ import { Label } from "@open-mercato/ui/primitives/label";
13
+ import { Separator } from "@open-mercato/ui/primitives/separator";
14
+ import { SegmentedControl, SegmentedControlItem } from "@open-mercato/ui/primitives/segmented-control";
15
+ import {
16
+ Select,
17
+ SelectContent,
18
+ SelectItem,
19
+ SelectTrigger,
20
+ SelectValue
21
+ } from "@open-mercato/ui/primitives/select";
22
+ import { Switch } from "@open-mercato/ui/primitives/switch";
23
+ import { Spinner } from "@open-mercato/ui/primitives/spinner";
24
+ import { FormHeader } from "@open-mercato/ui/backend/forms";
25
+ import { InjectionSpot } from "@open-mercato/ui/backend/injection/InjectionSpot";
26
+ import { extensionPoints } from "@open-mercato/core/modules/staff/extension-points";
27
+ import { extensionSpotChildId } from "@open-mercato/shared/modules/widgets/extension-points";
28
+ import { ErrorMessage } from "@open-mercato/ui/backend/detail";
29
+ import { apiCall, readApiResultOrThrow } from "@open-mercato/ui/backend/utils/apiCall";
30
+ import { useGuardedMutation } from "@open-mercato/ui/backend/injection/useGuardedMutation";
31
+ import { useBackendChrome } from "@open-mercato/ui/backend/BackendChromeProvider";
32
+ import { flash } from "@open-mercato/ui/backend/FlashMessages";
33
+ import { formatCurrency } from "@open-mercato/ui/utils/format";
34
+ import { hasFeature } from "@open-mercato/shared/security/features";
35
+ import { useT } from "@open-mercato/shared/lib/i18n/context";
36
+ import { useOrganizationScopeVersion } from "@open-mercato/shared/lib/frontend/useOrganizationScope";
37
+ import { createLogger } from "@open-mercato/shared/lib/logger";
38
+ import { CustomerPicker } from "../../../../../lib/time-tracking-ui/CustomerPicker.js";
39
+ import {
40
+ applyBound,
41
+ applyPreset,
42
+ defaultReportTitle,
43
+ initialReportPeriod,
44
+ isValidReportPeriod,
45
+ REPORT_PERIOD_PRESETS,
46
+ spansMultipleMonths
47
+ } from "../../../../../lib/timesheets-reports/reportConfigState.js";
48
+ import {
49
+ parseReportPreview,
50
+ readCurrencyConflict,
51
+ toCandidateProject
52
+ } from "../../../../../lib/timesheets-reports/reportConfigData.js";
53
+ import { formatReportMinutes } from "../../../../../lib/timesheets-reports/reportTotals.js";
54
+ const logger = createLogger("staff").child({ component: "time-tracking/reports/create" });
55
+ const REPORTS_HREF = "/backend/staff/time-tracking/reports";
56
+ const PROJECTS_API = "/api/staff/timesheets/time-projects";
57
+ const PREVIEW_API = "/api/staff/timesheets/reports/preview";
58
+ const REPORTS_API_PATH = "staff/timesheets/reports";
59
+ const RATES_FEATURE = "staff.timesheets.rates.view";
60
+ const MUTATION_CONTEXT_ID = "staff.time_tracking.reportCreate";
61
+ const REPORT_ENTITY_ID = "staff:staff_time_report";
62
+ const RESOURCE_KIND = "staff.timesheets.time_report";
63
+ const CANDIDATE_PAGE_SIZE = 100;
64
+ function readPreselectedProjectIds(params) {
65
+ const raw = params.get("projectIds");
66
+ return raw ? raw.split(",").map((id) => id.trim()).filter(Boolean) : [];
67
+ }
68
+ function readRows(payload) {
69
+ if (!payload || typeof payload !== "object") return [];
70
+ const items = payload.items;
71
+ return Array.isArray(items) ? items.filter((row) => row && typeof row === "object") : [];
72
+ }
73
+ function TimeTrackingReportCreatePage() {
74
+ const t = useT();
75
+ const router = useRouter();
76
+ const searchParams = useSearchParams();
77
+ const scopeVersion = useOrganizationScopeVersion();
78
+ const { payload } = useBackendChrome();
79
+ const canSeeMoney = hasFeature(payload?.grantedFeatures, RATES_FEATURE);
80
+ const [customer, setCustomer] = React.useState(null);
81
+ const [customerId, setCustomerId] = React.useState(() => searchParams.get("customerId"));
82
+ const [period, setPeriod] = React.useState(() => initialReportPeriod());
83
+ const [candidates, setCandidates] = React.useState([]);
84
+ const [candidatesLoading, setCandidatesLoading] = React.useState(false);
85
+ const preselectedIds = React.useMemo(() => readPreselectedProjectIds(searchParams), [searchParams]);
86
+ const [selectedIds, setSelectedIds] = React.useState(preselectedIds);
87
+ const [defaultSelectionPending, setDefaultSelectionPending] = React.useState(preselectedIds.length === 0);
88
+ const [grouping, setGrouping] = React.useState("project_task");
89
+ const [nonbillableMode, setNonbillableMode] = React.useState("separate");
90
+ const [showRates, setShowRates] = React.useState(true);
91
+ const [includeAlreadyReported, setIncludeAlreadyReported] = React.useState(false);
92
+ const [title, setTitle] = React.useState("");
93
+ const [titleTouched, setTitleTouched] = React.useState(false);
94
+ const [candidatePreview, setCandidatePreview] = React.useState(null);
95
+ const [preview, setPreview] = React.useState(null);
96
+ const [previewLoading, setPreviewLoading] = React.useState(false);
97
+ const [previewError, setPreviewError] = React.useState(null);
98
+ const [conflict, setConflict] = React.useState(null);
99
+ const [submitting, setSubmitting] = React.useState(false);
100
+ const labels = React.useMemo(
101
+ () => ({
102
+ customer: t("staff.time_tracking.reports.create.customer", "Customer"),
103
+ customerHint: t(
104
+ "staff.time_tracking.reports.create.customerHint",
105
+ "Report currency: {currency} \u2014 it comes from this customer projects."
106
+ ),
107
+ unknownCustomer: t("staff.time_tracking.reports.create.unknownCustomer", "Customer"),
108
+ previewError: t("staff.time_tracking.reports.errors.previewFailed", "Could not compute the report totals."),
109
+ createError: t("staff.time_tracking.reports.errors.createFailed", "Could not create the report.")
110
+ }),
111
+ [t]
112
+ );
113
+ const { runMutation, retryLastMutation } = useGuardedMutation({
114
+ contextId: MUTATION_CONTEXT_ID,
115
+ blockedMessage: labels.createError
116
+ });
117
+ const selectedIdsRef = React.useRef(selectedIds);
118
+ React.useEffect(() => {
119
+ selectedIdsRef.current = selectedIds;
120
+ }, [selectedIds]);
121
+ React.useEffect(() => {
122
+ if (!customer) return;
123
+ setCustomerId(customer.id);
124
+ }, [customer]);
125
+ React.useEffect(() => {
126
+ if (titleTouched) return;
127
+ setTitle(defaultReportTitle(customer?.name ?? null, period, labels.unknownCustomer));
128
+ }, [customer?.name, labels.unknownCustomer, period, titleTouched]);
129
+ React.useEffect(() => {
130
+ if (!customerId) {
131
+ setCandidates([]);
132
+ return;
133
+ }
134
+ let cancelled = false;
135
+ setCandidatesLoading(true);
136
+ const params = new URLSearchParams({
137
+ page: "1",
138
+ pageSize: String(CANDIDATE_PAGE_SIZE),
139
+ customerId
140
+ });
141
+ void readApiResultOrThrow(`${PROJECTS_API}?${params.toString()}`, void 0, {
142
+ allowNullResult: true,
143
+ errorMessage: labels.previewError
144
+ }).then((result) => {
145
+ if (cancelled) return;
146
+ const rows = readRows(result).map(toCandidateProject).filter((project) => project !== null);
147
+ setCandidates(rows);
148
+ const allowed = new Set(rows.map((project) => project.id));
149
+ const kept = selectedIdsRef.current.filter((id) => allowed.has(id));
150
+ setSelectedIds(kept);
151
+ setDefaultSelectionPending(kept.length === 0);
152
+ }).catch((err) => {
153
+ if (cancelled) return;
154
+ logger.error("staff.time_tracking.reports candidate projects failed", { err });
155
+ setCandidates([]);
156
+ }).finally(() => {
157
+ if (!cancelled) setCandidatesLoading(false);
158
+ });
159
+ return () => {
160
+ cancelled = true;
161
+ };
162
+ }, [customerId, labels.previewError, scopeVersion]);
163
+ const runPreview = React.useCallback(
164
+ async (projectIds, signal) => {
165
+ if (projectIds.length === 0 || !isValidReportPeriod(period)) return null;
166
+ const call = await apiCall(
167
+ PREVIEW_API,
168
+ {
169
+ method: "POST",
170
+ headers: { "content-type": "application/json" },
171
+ body: JSON.stringify({
172
+ customerId,
173
+ periodKind: period.kind,
174
+ periodFrom: period.from,
175
+ periodTo: period.to,
176
+ grouping,
177
+ nonbillableMode,
178
+ includeAlreadyReported,
179
+ showRates,
180
+ timeProjectIds: projectIds
181
+ }),
182
+ signal
183
+ }
184
+ );
185
+ if (!call.ok) {
186
+ const currencyConflict = readCurrencyConflict(call.result);
187
+ if (currencyConflict) {
188
+ setConflict(currencyConflict);
189
+ return null;
190
+ }
191
+ const message = (call.result && typeof call.result === "object" && typeof call.result.error === "string" ? call.result.error : null) ?? labels.previewError;
192
+ throw new Error(message);
193
+ }
194
+ setConflict(null);
195
+ return parseReportPreview(call.result);
196
+ },
197
+ [customerId, grouping, includeAlreadyReported, labels.previewError, nonbillableMode, period, showRates]
198
+ );
199
+ React.useEffect(() => {
200
+ if (candidates.length === 0) {
201
+ setCandidatePreview(null);
202
+ return;
203
+ }
204
+ const controller = new AbortController();
205
+ void runPreview(candidates.map((project) => project.id), controller.signal).then((result) => {
206
+ if (!controller.signal.aborted) setCandidatePreview(result);
207
+ }).catch((err) => {
208
+ if (controller.signal.aborted) return;
209
+ logger.error("staff.time_tracking.reports candidate preview failed", { err });
210
+ });
211
+ return () => controller.abort();
212
+ }, [candidates, runPreview]);
213
+ React.useEffect(() => {
214
+ if (selectedIds.length === 0) {
215
+ setPreview(null);
216
+ setPreviewError(null);
217
+ return;
218
+ }
219
+ const controller = new AbortController();
220
+ setPreviewLoading(true);
221
+ setPreviewError(null);
222
+ void runPreview(selectedIds, controller.signal).then((result) => {
223
+ if (!controller.signal.aborted) setPreview(result);
224
+ }).catch((err) => {
225
+ if (controller.signal.aborted) return;
226
+ setPreview(null);
227
+ setPreviewError(err instanceof Error ? err.message : labels.previewError);
228
+ }).finally(() => {
229
+ if (!controller.signal.aborted) setPreviewLoading(false);
230
+ });
231
+ return () => controller.abort();
232
+ }, [labels.previewError, runPreview, selectedIds]);
233
+ const projectFigures = React.useMemo(() => {
234
+ const map = /* @__PURE__ */ new Map();
235
+ for (const row of candidatePreview?.projects ?? []) {
236
+ map.set(row.id, {
237
+ entryCount: row.entryCount,
238
+ minutes: row.billableMinutes + row.nonbillableMinutes,
239
+ amount: row.amount
240
+ });
241
+ }
242
+ return map;
243
+ }, [candidatePreview]);
244
+ React.useEffect(() => {
245
+ if (!defaultSelectionPending || !candidatePreview || candidates.length === 0) return;
246
+ const withEntries = candidates.filter((project) => (projectFigures.get(project.id)?.entryCount ?? 0) > 0).map((project) => project.id);
247
+ setSelectedIds((current) => Array.from(/* @__PURE__ */ new Set([...current, ...withEntries])));
248
+ setDefaultSelectionPending(false);
249
+ }, [candidatePreview, candidates, defaultSelectionPending, projectFigures]);
250
+ const currencyCode = preview?.currencyCode ?? candidatePreview?.currencyCode ?? null;
251
+ const money = React.useCallback(
252
+ (amount) => {
253
+ if (amount === null || amount === void 0) return "\u2014";
254
+ return formatCurrency(amount, currencyCode ?? void 0) ?? "\u2014";
255
+ },
256
+ [currencyCode]
257
+ );
258
+ const toggleProject = React.useCallback((projectId, checked) => {
259
+ setSelectedIds(
260
+ (current) => checked ? Array.from(/* @__PURE__ */ new Set([...current, projectId])) : current.filter((id) => id !== projectId)
261
+ );
262
+ }, []);
263
+ const reportFormValues = React.useMemo(
264
+ () => ({
265
+ customerId,
266
+ timeProjectIds: selectedIds,
267
+ periodFrom: period.from,
268
+ periodTo: period.to,
269
+ grouping,
270
+ nonbillableMode,
271
+ showRates,
272
+ includeAlreadyReported,
273
+ title
274
+ }),
275
+ [customerId, grouping, includeAlreadyReported, nonbillableMode, period.from, period.to, selectedIds, showRates, title]
276
+ );
277
+ const reportFormInjectionContext = React.useMemo(
278
+ () => ({
279
+ formId: MUTATION_CONTEXT_ID,
280
+ entityId: REPORT_ENTITY_ID,
281
+ recordId: null,
282
+ resourceKind: "staff.timesheets.time_report",
283
+ resourceId: "new",
284
+ operation: "create",
285
+ retryLastMutation
286
+ }),
287
+ [retryLastMutation]
288
+ );
289
+ const canSubmit = Boolean(customerId) && selectedIds.length > 0 && isValidReportPeriod(period) && title.trim().length > 0 && !conflict && !submitting;
290
+ const handleSubmit = React.useCallback(async () => {
291
+ if (!customerId || selectedIds.length === 0) return;
292
+ setSubmitting(true);
293
+ try {
294
+ const call = await runMutation({
295
+ operation: () => apiCall(
296
+ `/api/${REPORTS_API_PATH}`,
297
+ {
298
+ method: "POST",
299
+ headers: { "content-type": "application/json" },
300
+ body: JSON.stringify({
301
+ customerId,
302
+ title: title.trim(),
303
+ periodKind: period.kind,
304
+ periodFrom: period.from,
305
+ periodTo: period.to,
306
+ grouping,
307
+ nonbillableMode,
308
+ includeAlreadyReported,
309
+ showRates,
310
+ timeProjectIds: selectedIds
311
+ })
312
+ }
313
+ ),
314
+ context: {
315
+ formId: MUTATION_CONTEXT_ID,
316
+ resourceKind: RESOURCE_KIND,
317
+ resourceId: "new",
318
+ retryLastMutation
319
+ },
320
+ mutationPayload: { customerId, timeProjectIds: selectedIds }
321
+ });
322
+ if (!call.ok) {
323
+ const currencyConflict = readCurrencyConflict(call.result);
324
+ if (currencyConflict) {
325
+ setConflict(currencyConflict);
326
+ return;
327
+ }
328
+ const message = call.result && typeof call.result === "object" && typeof call.result.error === "string" ? call.result.error : labels.createError;
329
+ flash(message, "error");
330
+ return;
331
+ }
332
+ const reportId = call.result?.id ?? null;
333
+ flash(t("staff.time_tracking.reports.create.created", "Report generated."), "success");
334
+ router.push(reportId ? `${REPORTS_HREF}/${reportId}` : REPORTS_HREF);
335
+ } catch (err) {
336
+ logger.error("staff.time_tracking.reports create failed", { err });
337
+ flash(err instanceof Error ? err.message : labels.createError, "error");
338
+ } finally {
339
+ setSubmitting(false);
340
+ }
341
+ }, [
342
+ customerId,
343
+ grouping,
344
+ includeAlreadyReported,
345
+ labels.createError,
346
+ nonbillableMode,
347
+ period,
348
+ retryLastMutation,
349
+ router,
350
+ runMutation,
351
+ selectedIds,
352
+ showRates,
353
+ t,
354
+ title
355
+ ]);
356
+ return /* @__PURE__ */ jsx(Page, { children: /* @__PURE__ */ jsxs(PageBody, { children: [
357
+ /* @__PURE__ */ jsx(
358
+ FormHeader,
359
+ {
360
+ mode: "detail",
361
+ title: t("staff.time_tracking.reports.create.title", "New report"),
362
+ subtitle: t("staff.time_tracking.reports.create.subtitle", "A report always covers one customer."),
363
+ backHref: REPORTS_HREF
364
+ }
365
+ ),
366
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-6 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]", children: [
367
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
368
+ /* @__PURE__ */ jsx(
369
+ InjectionSpot,
370
+ {
371
+ spotId: extensionSpotChildId(extensionPoints.hosts.reportForm.spotId, "before-fields"),
372
+ context: reportFormInjectionContext,
373
+ data: reportFormValues
374
+ }
375
+ ),
376
+ /* @__PURE__ */ jsxs("section", { className: "flex flex-col gap-2", children: [
377
+ /* @__PURE__ */ jsx(Label, { htmlFor: "report-customer", children: labels.customer }),
378
+ /* @__PURE__ */ jsx(
379
+ CustomerPicker,
380
+ {
381
+ value: customerId,
382
+ snapshot: customer,
383
+ onChange: (selection) => {
384
+ setCustomer(selection);
385
+ setCustomerId(selection?.id ?? null);
386
+ setSelectedIds([]);
387
+ setDefaultSelectionPending(true);
388
+ setConflict(null);
389
+ }
390
+ }
391
+ ),
392
+ currencyCode ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: labels.customerHint.replace("{currency}", currencyCode) }) : null
393
+ ] }),
394
+ /* @__PURE__ */ jsxs("section", { className: "flex flex-col gap-2", children: [
395
+ /* @__PURE__ */ jsx(Label, { htmlFor: "report-title", children: t("staff.time_tracking.reports.create.reportTitle", "Report title") }),
396
+ /* @__PURE__ */ jsx(
397
+ Input,
398
+ {
399
+ id: "report-title",
400
+ value: title,
401
+ onChange: (event) => {
402
+ setTitleTouched(true);
403
+ setTitle(event.target.value);
404
+ }
405
+ }
406
+ )
407
+ ] }),
408
+ /* @__PURE__ */ jsxs("section", { className: "flex flex-col gap-3", children: [
409
+ /* @__PURE__ */ jsx(Label, { children: t("staff.time_tracking.reports.create.period", "Period") }),
410
+ /* @__PURE__ */ jsx(
411
+ SegmentedControl,
412
+ {
413
+ value: period.kind === "custom" ? "" : period.kind,
414
+ onValueChange: (value) => {
415
+ if (value === "week" || value === "month" || value === "year") {
416
+ setPeriod((current) => applyPreset(current, value));
417
+ }
418
+ },
419
+ children: REPORT_PERIOD_PRESETS.map((preset) => /* @__PURE__ */ jsx(SegmentedControlItem, { value: preset, children: t(`staff.time_tracking.reports.create.preset.${preset}`, preset) }, preset))
420
+ }
421
+ ),
422
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-3 sm:grid-cols-2", children: [
423
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
424
+ /* @__PURE__ */ jsx(Label, { htmlFor: "report-from", children: t("staff.time_tracking.reports.create.from", "From") }),
425
+ /* @__PURE__ */ jsx(
426
+ Input,
427
+ {
428
+ id: "report-from",
429
+ type: "date",
430
+ value: period.from,
431
+ onChange: (event) => setPeriod((current) => applyBound(current, "from", event.target.value))
432
+ }
433
+ )
434
+ ] }),
435
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
436
+ /* @__PURE__ */ jsx(Label, { htmlFor: "report-to", children: t("staff.time_tracking.reports.create.to", "To") }),
437
+ /* @__PURE__ */ jsx(
438
+ Input,
439
+ {
440
+ id: "report-to",
441
+ type: "date",
442
+ value: period.to,
443
+ onChange: (event) => setPeriod((current) => applyBound(current, "to", event.target.value))
444
+ }
445
+ )
446
+ ] })
447
+ ] }),
448
+ !isValidReportPeriod(period) ? /* @__PURE__ */ jsx("p", { className: "text-xs text-status-error-text", children: t("staff.time_tracking.reports.create.invalidPeriod", "The end date must not precede the start date.") }) : spansMultipleMonths(period) ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t(
449
+ "staff.time_tracking.reports.create.spansMonths",
450
+ "This range covers more than one month \u2014 adjust the dates if you only want one of them."
451
+ ) }) : null
452
+ ] }),
453
+ /* @__PURE__ */ jsxs("section", { className: "flex flex-col gap-2", children: [
454
+ /* @__PURE__ */ jsxs("div", { children: [
455
+ /* @__PURE__ */ jsx(Label, { children: t("staff.time_tracking.reports.create.projects", "Customer projects") }),
456
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("staff.time_tracking.reports.create.projectsHint", "Tick the projects this report should cover.") })
457
+ ] }),
458
+ candidatesLoading ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
459
+ /* @__PURE__ */ jsx(Spinner, { className: "size-4" }),
460
+ t("staff.time_tracking.reports.create.loadingProjects", "Loading projects\u2026")
461
+ ] }) : candidates.length === 0 ? /* @__PURE__ */ jsx("p", { className: "rounded-md border border-border p-4 text-sm text-muted-foreground", children: customerId ? t("staff.time_tracking.reports.create.noProjects", "This customer has no time projects yet.") : t("staff.time_tracking.reports.create.pickCustomer", "Pick a customer to see their projects.") }) : /* @__PURE__ */ jsx("ul", { className: "divide-y divide-border rounded-md border border-border", children: candidates.map((project) => {
462
+ const figures = projectFigures.get(project.id);
463
+ const empty = (figures?.entryCount ?? 0) === 0;
464
+ const checked = selectedIds.includes(project.id);
465
+ const isOffender = conflict?.offenders.some((offender) => offender.id === project.id) ?? false;
466
+ return /* @__PURE__ */ jsxs(
467
+ "li",
468
+ {
469
+ className: `flex items-center gap-3 p-3 ${empty && !checked ? "opacity-60" : ""}`,
470
+ children: [
471
+ /* @__PURE__ */ jsx(
472
+ Checkbox,
473
+ {
474
+ checked,
475
+ onCheckedChange: (value) => toggleProject(project.id, value === true),
476
+ "aria-label": project.name
477
+ }
478
+ ),
479
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
480
+ /* @__PURE__ */ jsx("span", { className: "truncate text-sm font-medium", children: project.name }),
481
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: [
482
+ canSeeMoney && project.hourlyRate !== null ? `${money(project.hourlyRate)}/h` : null,
483
+ t("staff.time_tracking.reports.create.entriesInPeriod", "{count} entries in period").replace(
484
+ "{count}",
485
+ String(figures?.entryCount ?? 0)
486
+ ),
487
+ isOffender && project.currencyCode ? project.currencyCode : null
488
+ ].filter(Boolean).join(" \xB7 ") })
489
+ ] }),
490
+ /* @__PURE__ */ jsx("span", { className: "font-mono text-sm tabular-nums", children: formatReportMinutes(figures?.minutes ?? 0) }),
491
+ /* @__PURE__ */ jsx("span", { className: "w-28 text-right font-mono text-sm tabular-nums text-muted-foreground", children: canSeeMoney ? money(figures?.amount ?? null) : "\u2014" })
492
+ ]
493
+ },
494
+ project.id
495
+ );
496
+ }) })
497
+ ] }),
498
+ /* @__PURE__ */ jsxs("section", { className: "flex flex-col gap-3", children: [
499
+ /* @__PURE__ */ jsx(Label, { children: t("staff.time_tracking.reports.create.presentation", "Presentation") }),
500
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-3 sm:grid-cols-2", children: [
501
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
502
+ /* @__PURE__ */ jsx(Label, { htmlFor: "report-grouping", children: t("staff.time_tracking.reports.create.grouping", "Grouping") }),
503
+ /* @__PURE__ */ jsxs(Select, { value: grouping, onValueChange: (value) => setGrouping(value), children: [
504
+ /* @__PURE__ */ jsx(SelectTrigger, { id: "report-grouping", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
505
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
506
+ /* @__PURE__ */ jsx(SelectItem, { value: "project_task", children: t("staff.time_tracking.reports.grouping.project_task", "Project \u2192 task") }),
507
+ /* @__PURE__ */ jsx(SelectItem, { value: "project_person", children: t("staff.time_tracking.reports.grouping.project_person", "Project \u2192 person") }),
508
+ /* @__PURE__ */ jsx(SelectItem, { value: "project_day", children: t("staff.time_tracking.reports.grouping.project_day", "Project \u2192 day") })
509
+ ] })
510
+ ] })
511
+ ] }),
512
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
513
+ /* @__PURE__ */ jsx(Label, { htmlFor: "report-nonbillable", children: t("staff.time_tracking.reports.create.nonbillable", "Non-billable time") }),
514
+ /* @__PURE__ */ jsxs(
515
+ Select,
516
+ {
517
+ value: nonbillableMode,
518
+ onValueChange: (value) => setNonbillableMode(value),
519
+ children: [
520
+ /* @__PURE__ */ jsx(SelectTrigger, { id: "report-nonbillable", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
521
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
522
+ /* @__PURE__ */ jsx(SelectItem, { value: "separate", children: t("staff.time_tracking.reports.nonbillable.separate", "Show separately, at no cost") }),
523
+ /* @__PURE__ */ jsx(SelectItem, { value: "exclude", children: t("staff.time_tracking.reports.nonbillable.exclude", "Leave it out entirely") })
524
+ ] })
525
+ ]
526
+ }
527
+ )
528
+ ] })
529
+ ] }),
530
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
531
+ /* @__PURE__ */ jsx(
532
+ Switch,
533
+ {
534
+ checked: showRates,
535
+ onCheckedChange: (value) => setShowRates(value === true),
536
+ "aria-label": t("staff.time_tracking.reports.create.showRates", "Show hourly rates"),
537
+ disabled: !canSeeMoney
538
+ }
539
+ ),
540
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
541
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: t("staff.time_tracking.reports.create.showRates", "Show hourly rates") }),
542
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: t(
543
+ "staff.time_tracking.reports.create.showRatesHint",
544
+ "Turn off if the client should see amounts only."
545
+ ) })
546
+ ] })
547
+ ] })
548
+ ] }),
549
+ /* @__PURE__ */ jsx(
550
+ InjectionSpot,
551
+ {
552
+ spotId: extensionSpotChildId(extensionPoints.hosts.reportForm.spotId, "fields"),
553
+ context: reportFormInjectionContext,
554
+ data: reportFormValues
555
+ }
556
+ )
557
+ ] }),
558
+ /* @__PURE__ */ jsxs("aside", { className: "flex flex-col gap-4", children: [
559
+ /* @__PURE__ */ jsxs(Card, { children: [
560
+ /* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsx(CardTitle, { children: t("staff.time_tracking.reports.create.summary", "Range summary") }) }),
561
+ /* @__PURE__ */ jsxs(CardContent, { className: "flex flex-col gap-3", children: [
562
+ /* @__PURE__ */ jsx(
563
+ SummaryRow,
564
+ {
565
+ label: t("staff.time_tracking.reports.create.summaryProjects", "Projects"),
566
+ value: `${selectedIds.length} / ${candidates.length}`
567
+ }
568
+ ),
569
+ /* @__PURE__ */ jsx(
570
+ SummaryRow,
571
+ {
572
+ label: t("staff.time_tracking.reports.create.summaryEntries", "Entries"),
573
+ value: String(preview?.totals.entryCount ?? 0),
574
+ mono: true
575
+ }
576
+ ),
577
+ /* @__PURE__ */ jsx(
578
+ SummaryRow,
579
+ {
580
+ label: t("staff.time_tracking.reports.create.summaryBillable", "Billable time"),
581
+ value: formatReportMinutes(preview?.totals.billableMinutes ?? 0),
582
+ mono: true
583
+ }
584
+ ),
585
+ /* @__PURE__ */ jsx(
586
+ SummaryRow,
587
+ {
588
+ label: t("staff.time_tracking.reports.create.summaryNonbillable", "Non-billable"),
589
+ value: formatReportMinutes(preview?.totals.nonbillableMinutes ?? 0),
590
+ mono: true
591
+ }
592
+ ),
593
+ /* @__PURE__ */ jsx(Separator, {}),
594
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
595
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: t("staff.time_tracking.reports.create.summaryTotal", "To invoice") }),
596
+ /* @__PURE__ */ jsx("span", { className: "font-mono text-sm font-semibold tabular-nums", children: previewLoading ? /* @__PURE__ */ jsx(Spinner, { className: "size-4" }) : money(preview?.totals.totalAmount ?? null) })
597
+ ] })
598
+ ] })
599
+ ] }),
600
+ conflict ? /* @__PURE__ */ jsxs(Alert, { status: "error", children: [
601
+ /* @__PURE__ */ jsx(AlertTitle, { children: t("staff.time_tracking.reports.errors.currencyConflictTitle", "Mixed currencies in this selection") }),
602
+ /* @__PURE__ */ jsxs(AlertDescription, { children: [
603
+ /* @__PURE__ */ jsx("p", { children: t(
604
+ "staff.time_tracking.reports.errors.currencyConflict",
605
+ "A report always covers one currency. Selected projects use {currencies}."
606
+ ).replace("{currencies}", conflict.currencies.join(", ")) }),
607
+ /* @__PURE__ */ jsx("ul", { className: "mt-2 list-disc pl-4", children: conflict.offenders.map((offender) => /* @__PURE__ */ jsxs("li", { children: [
608
+ offender.name,
609
+ " \u2014 ",
610
+ offender.currencyCode ?? "\u2014"
611
+ ] }, offender.id)) })
612
+ ] })
613
+ ] }) : null,
614
+ previewError ? /* @__PURE__ */ jsx(ErrorMessage, { label: previewError }) : null,
615
+ (preview?.alreadyReportedCount ?? 0) > 0 || includeAlreadyReported ? /* @__PURE__ */ jsxs(Alert, { status: "warning", icon: /* @__PURE__ */ jsx(AlertTriangle, { "aria-hidden": "true" }), children: [
616
+ /* @__PURE__ */ jsx(AlertTitle, { children: t(
617
+ "staff.time_tracking.reports.alreadyReported.title",
618
+ "{count} entries are already in another report"
619
+ ).replace("{count}", String(preview?.alreadyReportedCount ?? 0)) }),
620
+ /* @__PURE__ */ jsxs(AlertDescription, { children: [
621
+ /* @__PURE__ */ jsx("p", { children: t(
622
+ "staff.time_tracking.reports.alreadyReported.body",
623
+ "They are excluded from this report so the same hour is not billed twice. Including them adds {hours} at the values frozen when those reports were closed."
624
+ ).replace("{hours}", formatReportMinutes(preview?.alreadyReportedMinutes ?? 0)) }),
625
+ (preview?.alreadyReportedIn.length ?? 0) > 0 ? /* @__PURE__ */ jsx("ul", { className: "mt-2 list-disc pl-4", children: preview?.alreadyReportedIn.map((source) => /* @__PURE__ */ jsxs("li", { children: [
626
+ /* @__PURE__ */ jsx("a", { className: "underline", href: `${REPORTS_HREF}/${source.reportId}`, children: source.reference ?? source.title ?? source.reportId }),
627
+ " ",
628
+ "\u2014 ",
629
+ source.entryCount,
630
+ " \xB7 ",
631
+ formatReportMinutes(source.minutes)
632
+ ] }, source.reportId)) }) : null,
633
+ /* @__PURE__ */ jsxs("label", { className: "mt-3 flex items-start gap-2", children: [
634
+ /* @__PURE__ */ jsx(
635
+ Checkbox,
636
+ {
637
+ checked: includeAlreadyReported,
638
+ onCheckedChange: (value) => setIncludeAlreadyReported(value === true)
639
+ }
640
+ ),
641
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: t(
642
+ "staff.time_tracking.reports.alreadyReported.optIn",
643
+ "Include them anyway, at their frozen values"
644
+ ) })
645
+ ] })
646
+ ] })
647
+ ] }) : null,
648
+ /* @__PURE__ */ jsx(Alert, { status: "information", icon: /* @__PURE__ */ jsx(Info, { "aria-hidden": "true" }), children: /* @__PURE__ */ jsx(AlertDescription, { children: t(
649
+ "staff.time_tracking.reports.create.roundingNotice",
650
+ "Rounding: {rule} (global). Every amount above is rounded at the entry and then summed, so the printed lines add up to the total."
651
+ ).replace(
652
+ "{rule}",
653
+ preview?.rounding.unitMinutes || candidatePreview?.rounding.unitMinutes ? t("staff.time_tracking.reports.create.roundingRule", "{minutes} min, {direction}").replace(
654
+ "{minutes}",
655
+ String(preview?.rounding.unitMinutes ?? candidatePreview?.rounding.unitMinutes ?? 0)
656
+ ).replace(
657
+ "{direction}",
658
+ (preview?.rounding.direction ?? candidatePreview?.rounding.direction) === "nearest" ? t("staff.time_tracking.reports.create.roundingNearest", "to the nearest") : t("staff.time_tracking.reports.create.roundingUp", "always up")
659
+ ) : t("staff.time_tracking.reports.create.roundingOff", "off")
660
+ ) }) })
661
+ ] })
662
+ ] }),
663
+ /* @__PURE__ */ jsx(
664
+ InjectionSpot,
665
+ {
666
+ spotId: extensionSpotChildId(extensionPoints.hosts.reportForm.spotId, "after-fields"),
667
+ context: reportFormInjectionContext,
668
+ data: reportFormValues
669
+ }
670
+ ),
671
+ /* @__PURE__ */ jsxs("div", { className: "mt-6 flex items-center justify-end gap-2", children: [
672
+ /* @__PURE__ */ jsx(
673
+ InjectionSpot,
674
+ {
675
+ spotId: extensionSpotChildId(extensionPoints.hosts.reportForm.spotId, "footer"),
676
+ context: reportFormInjectionContext,
677
+ data: reportFormValues
678
+ }
679
+ ),
680
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: () => router.push(REPORTS_HREF), children: t("staff.time_tracking.reports.create.cancel", "Cancel") }),
681
+ /* @__PURE__ */ jsxs(Button, { onClick: () => void handleSubmit(), disabled: !canSubmit, children: [
682
+ /* @__PURE__ */ jsx(FileText, { "aria-hidden": "true" }),
683
+ t("staff.time_tracking.reports.create.submit", "Generate preview")
684
+ ] })
685
+ ] })
686
+ ] }) });
687
+ }
688
+ function SummaryRow({ label, value, mono }) {
689
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
690
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: label }),
691
+ /* @__PURE__ */ jsx("span", { className: mono ? "font-mono text-sm tabular-nums" : "text-sm font-medium", children: value })
692
+ ] });
693
+ }
694
+ export {
695
+ TimeTrackingReportCreatePage as default
696
+ };
697
+ //# sourceMappingURL=page.js.map