@open-mercato/core 0.4.5-develop-5191db4ef3 → 0.4.5-develop-9f9549ebc8

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 (385) hide show
  1. package/dist/generated/entities/message/index.js +65 -0
  2. package/dist/generated/entities/message/index.js.map +7 -0
  3. package/dist/generated/entities/message_access_token/index.js +19 -0
  4. package/dist/generated/entities/message_access_token/index.js.map +7 -0
  5. package/dist/generated/entities/message_confirmation/index.js +21 -0
  6. package/dist/generated/entities/message_confirmation/index.js.map +7 -0
  7. package/dist/generated/entities/message_object/index.js +23 -0
  8. package/dist/generated/entities/message_object/index.js.map +7 -0
  9. package/dist/generated/entities/message_recipient/index.js +31 -0
  10. package/dist/generated/entities/message_recipient/index.js.map +7 -0
  11. package/dist/generated/entities.ids.generated.js +8 -0
  12. package/dist/generated/entities.ids.generated.js.map +2 -2
  13. package/dist/generated/entity-fields-registry.js +10 -0
  14. package/dist/generated/entity-fields-registry.js.map +2 -2
  15. package/dist/modules/customers/backend/customers/deals/[id]/page.js +27 -8
  16. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
  17. package/dist/modules/customers/lib/messageObjectPreviews.js +131 -0
  18. package/dist/modules/customers/lib/messageObjectPreviews.js.map +7 -0
  19. package/dist/modules/customers/message-objects.js +71 -0
  20. package/dist/modules/customers/message-objects.js.map +7 -0
  21. package/dist/modules/customers/widgets/messages/CustomerMessageObjectDetail.js +51 -0
  22. package/dist/modules/customers/widgets/messages/CustomerMessageObjectDetail.js.map +7 -0
  23. package/dist/modules/customers/widgets/messages/CustomerMessageObjectPreview.js +35 -0
  24. package/dist/modules/customers/widgets/messages/CustomerMessageObjectPreview.js.map +7 -0
  25. package/dist/modules/customers/widgets/messages/index.js +7 -0
  26. package/dist/modules/customers/widgets/messages/index.js.map +7 -0
  27. package/dist/modules/messages/acl.js +15 -0
  28. package/dist/modules/messages/acl.js.map +7 -0
  29. package/dist/modules/messages/api/[id]/actions/[actionId]/route.js +92 -0
  30. package/dist/modules/messages/api/[id]/actions/[actionId]/route.js.map +7 -0
  31. package/dist/modules/messages/api/[id]/archive/route.js +120 -0
  32. package/dist/modules/messages/api/[id]/archive/route.js.map +7 -0
  33. package/dist/modules/messages/api/[id]/attachments/route.js +195 -0
  34. package/dist/modules/messages/api/[id]/attachments/route.js.map +7 -0
  35. package/dist/modules/messages/api/[id]/confirmation/route.js +67 -0
  36. package/dist/modules/messages/api/[id]/confirmation/route.js.map +7 -0
  37. package/dist/modules/messages/api/[id]/conversation/archive/route.js +68 -0
  38. package/dist/modules/messages/api/[id]/conversation/archive/route.js.map +7 -0
  39. package/dist/modules/messages/api/[id]/conversation/read/route.js +68 -0
  40. package/dist/modules/messages/api/[id]/conversation/read/route.js.map +7 -0
  41. package/dist/modules/messages/api/[id]/conversation/route.js +68 -0
  42. package/dist/modules/messages/api/[id]/conversation/route.js.map +7 -0
  43. package/dist/modules/messages/api/[id]/forward/route.js +85 -0
  44. package/dist/modules/messages/api/[id]/forward/route.js.map +7 -0
  45. package/dist/modules/messages/api/[id]/forward-preview/route.js +70 -0
  46. package/dist/modules/messages/api/[id]/forward-preview/route.js.map +7 -0
  47. package/dist/modules/messages/api/[id]/read/route.js +120 -0
  48. package/dist/modules/messages/api/[id]/read/route.js.map +7 -0
  49. package/dist/modules/messages/api/[id]/reply/route.js +87 -0
  50. package/dist/modules/messages/api/[id]/reply/route.js.map +7 -0
  51. package/dist/modules/messages/api/[id]/route.js +350 -0
  52. package/dist/modules/messages/api/[id]/route.js.map +7 -0
  53. package/dist/modules/messages/api/object-types/route.js +54 -0
  54. package/dist/modules/messages/api/object-types/route.js.map +7 -0
  55. package/dist/modules/messages/api/openapi.js +261 -0
  56. package/dist/modules/messages/api/openapi.js.map +7 -0
  57. package/dist/modules/messages/api/route.js +262 -0
  58. package/dist/modules/messages/api/route.js.map +7 -0
  59. package/dist/modules/messages/api/token/[token]/route.js +99 -0
  60. package/dist/modules/messages/api/token/[token]/route.js.map +7 -0
  61. package/dist/modules/messages/api/types/route.js +40 -0
  62. package/dist/modules/messages/api/types/route.js.map +7 -0
  63. package/dist/modules/messages/api/unread-count/route.js +43 -0
  64. package/dist/modules/messages/api/unread-count/route.js.map +7 -0
  65. package/dist/modules/messages/backend/messages/[id]/page.js +10 -0
  66. package/dist/modules/messages/backend/messages/[id]/page.js.map +7 -0
  67. package/dist/modules/messages/backend/messages/[id]/page.meta.js +16 -0
  68. package/dist/modules/messages/backend/messages/[id]/page.meta.js.map +7 -0
  69. package/dist/modules/messages/backend/messages/compose/page.js +10 -0
  70. package/dist/modules/messages/backend/messages/compose/page.js.map +7 -0
  71. package/dist/modules/messages/backend/messages/compose/page.meta.js +17 -0
  72. package/dist/modules/messages/backend/messages/compose/page.meta.js.map +7 -0
  73. package/dist/modules/messages/backend/page.js +10 -0
  74. package/dist/modules/messages/backend/page.js.map +7 -0
  75. package/dist/modules/messages/backend/page.meta.js +33 -0
  76. package/dist/modules/messages/backend/page.meta.js.map +7 -0
  77. package/dist/modules/messages/commands/actions.js +265 -0
  78. package/dist/modules/messages/commands/actions.js.map +7 -0
  79. package/dist/modules/messages/commands/attachments.js +217 -0
  80. package/dist/modules/messages/commands/attachments.js.map +7 -0
  81. package/dist/modules/messages/commands/confirmations.js +151 -0
  82. package/dist/modules/messages/commands/confirmations.js.map +7 -0
  83. package/dist/modules/messages/commands/conversation.js +240 -0
  84. package/dist/modules/messages/commands/conversation.js.map +7 -0
  85. package/dist/modules/messages/commands/messages.js +748 -0
  86. package/dist/modules/messages/commands/messages.js.map +7 -0
  87. package/dist/modules/messages/commands/recipients.js +259 -0
  88. package/dist/modules/messages/commands/recipients.js.map +7 -0
  89. package/dist/modules/messages/commands/shared.js +258 -0
  90. package/dist/modules/messages/commands/shared.js.map +7 -0
  91. package/dist/modules/messages/commands/tokens.js +69 -0
  92. package/dist/modules/messages/commands/tokens.js.map +7 -0
  93. package/dist/modules/messages/components/ComposeMessagePageClient.js +24 -0
  94. package/dist/modules/messages/components/ComposeMessagePageClient.js.map +7 -0
  95. package/dist/modules/messages/components/MessageDetailPageClient.js +261 -0
  96. package/dist/modules/messages/components/MessageDetailPageClient.js.map +7 -0
  97. package/dist/modules/messages/components/MessagesInboxPageClient.js +390 -0
  98. package/dist/modules/messages/components/MessagesInboxPageClient.js.map +7 -0
  99. package/dist/modules/messages/components/confirmation/MessageConfirmationActions.js +31 -0
  100. package/dist/modules/messages/components/confirmation/MessageConfirmationActions.js.map +7 -0
  101. package/dist/modules/messages/components/confirmation/MessageConfirmationContent.js +69 -0
  102. package/dist/modules/messages/components/confirmation/MessageConfirmationContent.js.map +7 -0
  103. package/dist/modules/messages/components/defaults/DefaultMessageActions.js +31 -0
  104. package/dist/modules/messages/components/defaults/DefaultMessageActions.js.map +7 -0
  105. package/dist/modules/messages/components/defaults/DefaultMessageContent.js +19 -0
  106. package/dist/modules/messages/components/defaults/DefaultMessageContent.js.map +7 -0
  107. package/dist/modules/messages/components/defaults/DefaultMessageListItem.js +90 -0
  108. package/dist/modules/messages/components/defaults/DefaultMessageListItem.js.map +7 -0
  109. package/dist/modules/messages/components/defaults/MessageRecordObjectDetail.js +86 -0
  110. package/dist/modules/messages/components/defaults/MessageRecordObjectDetail.js.map +7 -0
  111. package/dist/modules/messages/components/defaults/MessageRecordObjectPreview.js +61 -0
  112. package/dist/modules/messages/components/defaults/MessageRecordObjectPreview.js.map +7 -0
  113. package/dist/modules/messages/components/message-detail/detail-panels.js +27 -0
  114. package/dist/modules/messages/components/message-detail/detail-panels.js.map +7 -0
  115. package/dist/modules/messages/components/message-detail/hooks/useMessageDetails.js +52 -0
  116. package/dist/modules/messages/components/message-detail/hooks/useMessageDetails.js.map +7 -0
  117. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsActions.js +289 -0
  118. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsActions.js.map +7 -0
  119. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js +103 -0
  120. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js.map +7 -0
  121. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.js +78 -0
  122. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.js.map +7 -0
  123. package/dist/modules/messages/components/message-detail/panels/MainMessageHeader.js +94 -0
  124. package/dist/modules/messages/components/message-detail/panels/MainMessageHeader.js.map +7 -0
  125. package/dist/modules/messages/components/message-detail/panels/MessageHeader.js +110 -0
  126. package/dist/modules/messages/components/message-detail/panels/MessageHeader.js.map +7 -0
  127. package/dist/modules/messages/components/message-detail/panels/MessageListComponent.js +58 -0
  128. package/dist/modules/messages/components/message-detail/panels/MessageListComponent.js.map +7 -0
  129. package/dist/modules/messages/components/message-detail/panels/actions-panel.js +51 -0
  130. package/dist/modules/messages/components/message-detail/panels/actions-panel.js.map +7 -0
  131. package/dist/modules/messages/components/message-detail/panels/attachments-panel.js +66 -0
  132. package/dist/modules/messages/components/message-detail/panels/attachments-panel.js.map +7 -0
  133. package/dist/modules/messages/components/message-detail/panels/body-panel.js +20 -0
  134. package/dist/modules/messages/components/message-detail/panels/body-panel.js.map +7 -0
  135. package/dist/modules/messages/components/message-detail/panels/composer-dialogs.js +36 -0
  136. package/dist/modules/messages/components/message-detail/panels/composer-dialogs.js.map +7 -0
  137. package/dist/modules/messages/components/message-detail/panels/dialogs.js +96 -0
  138. package/dist/modules/messages/components/message-detail/panels/dialogs.js.map +7 -0
  139. package/dist/modules/messages/components/message-detail/panels/index.js +25 -0
  140. package/dist/modules/messages/components/message-detail/panels/index.js.map +7 -0
  141. package/dist/modules/messages/components/message-detail/panels/meta-panel.js +14 -0
  142. package/dist/modules/messages/components/message-detail/panels/meta-panel.js.map +7 -0
  143. package/dist/modules/messages/components/message-detail/panels/objects-panel.js +51 -0
  144. package/dist/modules/messages/components/message-detail/panels/objects-panel.js.map +7 -0
  145. package/dist/modules/messages/components/message-detail/panels/thread-panel.js +54 -0
  146. package/dist/modules/messages/components/message-detail/panels/thread-panel.js.map +7 -0
  147. package/dist/modules/messages/components/message-detail/types.js +1 -0
  148. package/dist/modules/messages/components/message-detail/types.js.map +7 -0
  149. package/dist/modules/messages/components/message-detail/utils.js +54 -0
  150. package/dist/modules/messages/components/message-detail/utils.js.map +7 -0
  151. package/dist/modules/messages/components/utils/PriorityBadge.js +52 -0
  152. package/dist/modules/messages/components/utils/PriorityBadge.js.map +7 -0
  153. package/dist/modules/messages/components/utils/typeUiRegistry.js +77 -0
  154. package/dist/modules/messages/components/utils/typeUiRegistry.js.map +7 -0
  155. package/dist/modules/messages/data/entities.js +309 -0
  156. package/dist/modules/messages/data/entities.js.map +7 -0
  157. package/dist/modules/messages/data/validators.js +272 -0
  158. package/dist/modules/messages/data/validators.js.map +7 -0
  159. package/dist/modules/messages/emails/MessageEmail.js +108 -0
  160. package/dist/modules/messages/emails/MessageEmail.js.map +7 -0
  161. package/dist/modules/messages/events.js +24 -0
  162. package/dist/modules/messages/events.js.map +7 -0
  163. package/dist/modules/messages/frontend/messages/view/[token]/page.js +247 -0
  164. package/dist/modules/messages/frontend/messages/view/[token]/page.js.map +7 -0
  165. package/dist/modules/messages/frontend/messages/view/[token]/page.meta.js +9 -0
  166. package/dist/modules/messages/frontend/messages/view/[token]/page.meta.js.map +7 -0
  167. package/dist/modules/messages/index.js +21 -0
  168. package/dist/modules/messages/index.js.map +7 -0
  169. package/dist/modules/messages/lib/actions.js +141 -0
  170. package/dist/modules/messages/lib/actions.js.map +7 -0
  171. package/dist/modules/messages/lib/attachments.js +131 -0
  172. package/dist/modules/messages/lib/attachments.js.map +7 -0
  173. package/dist/modules/messages/lib/constants.js +7 -0
  174. package/dist/modules/messages/lib/constants.js.map +7 -0
  175. package/dist/modules/messages/lib/email-sender.js +201 -0
  176. package/dist/modules/messages/lib/email-sender.js.map +7 -0
  177. package/dist/modules/messages/lib/forwarding.js +179 -0
  178. package/dist/modules/messages/lib/forwarding.js.map +7 -0
  179. package/dist/modules/messages/lib/message-objects-registry.js +49 -0
  180. package/dist/modules/messages/lib/message-objects-registry.js.map +7 -0
  181. package/dist/modules/messages/lib/message-types-registry.js +41 -0
  182. package/dist/modules/messages/lib/message-types-registry.js.map +7 -0
  183. package/dist/modules/messages/lib/object-validation.js +20 -0
  184. package/dist/modules/messages/lib/object-validation.js.map +7 -0
  185. package/dist/modules/messages/lib/operationMetadata.js +21 -0
  186. package/dist/modules/messages/lib/operationMetadata.js.map +7 -0
  187. package/dist/modules/messages/lib/priorityUtils.js +61 -0
  188. package/dist/modules/messages/lib/priorityUtils.js.map +7 -0
  189. package/dist/modules/messages/lib/routeHelpers.js +44 -0
  190. package/dist/modules/messages/lib/routeHelpers.js.map +7 -0
  191. package/dist/modules/messages/message-objects.js +7 -0
  192. package/dist/modules/messages/message-objects.js.map +7 -0
  193. package/dist/modules/messages/message-types.js +67 -0
  194. package/dist/modules/messages/message-types.js.map +7 -0
  195. package/dist/modules/messages/migrations/Migration20260213181243.js +31 -0
  196. package/dist/modules/messages/migrations/Migration20260213181243.js.map +7 -0
  197. package/dist/modules/messages/migrations/Migration20260215165126.js +16 -0
  198. package/dist/modules/messages/migrations/Migration20260215165126.js.map +7 -0
  199. package/dist/modules/messages/notifications.js +27 -0
  200. package/dist/modules/messages/notifications.js.map +7 -0
  201. package/dist/modules/messages/setup.js +21 -0
  202. package/dist/modules/messages/setup.js.map +7 -0
  203. package/dist/modules/messages/subscribers/message-notification.js +108 -0
  204. package/dist/modules/messages/subscribers/message-notification.js.map +7 -0
  205. package/dist/modules/messages/workers/send-email.worker.js +253 -0
  206. package/dist/modules/messages/workers/send-email.worker.js.map +7 -0
  207. package/dist/modules/sales/backend/sales/documents/[id]/page.js +30 -11
  208. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  209. package/dist/modules/sales/commands/payments.js +12 -6
  210. package/dist/modules/sales/commands/payments.js.map +2 -2
  211. package/dist/modules/sales/lib/messageObjectPreviews.js +114 -0
  212. package/dist/modules/sales/lib/messageObjectPreviews.js.map +7 -0
  213. package/dist/modules/sales/message-objects.js +57 -0
  214. package/dist/modules/sales/message-objects.js.map +7 -0
  215. package/dist/modules/sales/widgets/messages/SalesDocumentMessageDetail.js +51 -0
  216. package/dist/modules/sales/widgets/messages/SalesDocumentMessageDetail.js.map +7 -0
  217. package/dist/modules/sales/widgets/messages/SalesDocumentMessagePreview.js +36 -0
  218. package/dist/modules/sales/widgets/messages/SalesDocumentMessagePreview.js.map +7 -0
  219. package/dist/modules/sales/widgets/messages/index.js +7 -0
  220. package/dist/modules/sales/widgets/messages/index.js.map +7 -0
  221. package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js +55 -1
  222. package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js.map +2 -2
  223. package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js +60 -1
  224. package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js.map +2 -2
  225. package/dist/modules/staff/backend/staff/team-members/[id]/page.js +2 -19
  226. package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
  227. package/dist/modules/staff/components/LeaveRequestDetail.js +112 -0
  228. package/dist/modules/staff/components/LeaveRequestDetail.js.map +7 -0
  229. package/dist/modules/staff/components/LeaveRequestForm.js +3 -1
  230. package/dist/modules/staff/components/LeaveRequestForm.js.map +2 -2
  231. package/dist/modules/staff/components/LeaveRequestPreview.js +43 -0
  232. package/dist/modules/staff/components/LeaveRequestPreview.js.map +7 -0
  233. package/dist/modules/staff/lib/messageObjectPreviews.js +148 -0
  234. package/dist/modules/staff/lib/messageObjectPreviews.js.map +7 -0
  235. package/dist/modules/staff/message-objects.js +104 -0
  236. package/dist/modules/staff/message-objects.js.map +7 -0
  237. package/dist/modules/staff/message-types.js +23 -0
  238. package/dist/modules/staff/message-types.js.map +7 -0
  239. package/dist/modules/staff/widgets/messages/StaffMessageObjectDetail.js +51 -0
  240. package/dist/modules/staff/widgets/messages/StaffMessageObjectDetail.js.map +7 -0
  241. package/dist/modules/staff/widgets/messages/StaffMessageObjectPreview.js +34 -0
  242. package/dist/modules/staff/widgets/messages/StaffMessageObjectPreview.js.map +7 -0
  243. package/dist/modules/staff/widgets/messages/index.js +7 -0
  244. package/dist/modules/staff/widgets/messages/index.js.map +7 -0
  245. package/generated/entities/message/index.ts +31 -0
  246. package/generated/entities/message_access_token/index.ts +8 -0
  247. package/generated/entities/message_confirmation/index.ts +9 -0
  248. package/generated/entities/message_object/index.ts +10 -0
  249. package/generated/entities/message_recipient/index.ts +14 -0
  250. package/generated/entities.ids.generated.ts +8 -0
  251. package/generated/entity-fields-registry.ts +10 -0
  252. package/jest.setup.ts +5 -0
  253. package/package.json +2 -2
  254. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +20 -4
  255. package/src/modules/customers/i18n/de.json +4 -0
  256. package/src/modules/customers/i18n/en.json +4 -0
  257. package/src/modules/customers/i18n/es.json +4 -0
  258. package/src/modules/customers/i18n/pl.json +4 -0
  259. package/src/modules/customers/lib/messageObjectPreviews.ts +154 -0
  260. package/src/modules/customers/message-objects.ts +70 -0
  261. package/src/modules/customers/widgets/messages/CustomerMessageObjectDetail.tsx +57 -0
  262. package/src/modules/customers/widgets/messages/CustomerMessageObjectPreview.tsx +49 -0
  263. package/src/modules/customers/widgets/messages/index.ts +2 -0
  264. package/src/modules/messages/acl.ts +11 -0
  265. package/src/modules/messages/api/[id]/actions/[actionId]/route.ts +103 -0
  266. package/src/modules/messages/api/[id]/archive/route.ts +138 -0
  267. package/src/modules/messages/api/[id]/attachments/route.ts +217 -0
  268. package/src/modules/messages/api/[id]/confirmation/route.ts +73 -0
  269. package/src/modules/messages/api/[id]/conversation/archive/route.ts +69 -0
  270. package/src/modules/messages/api/[id]/conversation/read/route.ts +69 -0
  271. package/src/modules/messages/api/[id]/conversation/route.ts +69 -0
  272. package/src/modules/messages/api/[id]/forward/route.ts +87 -0
  273. package/src/modules/messages/api/[id]/forward-preview/route.ts +75 -0
  274. package/src/modules/messages/api/[id]/read/route.ts +138 -0
  275. package/src/modules/messages/api/[id]/reply/route.ts +89 -0
  276. package/src/modules/messages/api/[id]/route.ts +401 -0
  277. package/src/modules/messages/api/object-types/route.ts +54 -0
  278. package/src/modules/messages/api/openapi.ts +261 -0
  279. package/src/modules/messages/api/route.ts +374 -0
  280. package/src/modules/messages/api/token/[token]/route.ts +103 -0
  281. package/src/modules/messages/api/types/route.ts +39 -0
  282. package/src/modules/messages/api/unread-count/route.ts +55 -0
  283. package/src/modules/messages/backend/messages/[id]/page.meta.ts +12 -0
  284. package/src/modules/messages/backend/messages/[id]/page.tsx +12 -0
  285. package/src/modules/messages/backend/messages/compose/page.meta.ts +13 -0
  286. package/src/modules/messages/backend/messages/compose/page.tsx +12 -0
  287. package/src/modules/messages/backend/page.meta.ts +31 -0
  288. package/src/modules/messages/backend/page.tsx +12 -0
  289. package/src/modules/messages/commands/actions.ts +307 -0
  290. package/src/modules/messages/commands/attachments.ts +227 -0
  291. package/src/modules/messages/commands/confirmations.ts +183 -0
  292. package/src/modules/messages/commands/conversation.ts +292 -0
  293. package/src/modules/messages/commands/messages.ts +845 -0
  294. package/src/modules/messages/commands/recipients.ts +281 -0
  295. package/src/modules/messages/commands/shared.ts +350 -0
  296. package/src/modules/messages/commands/tokens.ts +80 -0
  297. package/src/modules/messages/components/ComposeMessagePageClient.tsx +23 -0
  298. package/src/modules/messages/components/MessageDetailPageClient.tsx +287 -0
  299. package/src/modules/messages/components/MessagesInboxPageClient.tsx +469 -0
  300. package/src/modules/messages/components/confirmation/MessageConfirmationActions.tsx +35 -0
  301. package/src/modules/messages/components/confirmation/MessageConfirmationContent.tsx +88 -0
  302. package/src/modules/messages/components/defaults/DefaultMessageActions.tsx +37 -0
  303. package/src/modules/messages/components/defaults/DefaultMessageContent.tsx +21 -0
  304. package/src/modules/messages/components/defaults/DefaultMessageListItem.tsx +102 -0
  305. package/src/modules/messages/components/defaults/MessageRecordObjectDetail.tsx +114 -0
  306. package/src/modules/messages/components/defaults/MessageRecordObjectPreview.tsx +74 -0
  307. package/src/modules/messages/components/message-detail/detail-panels.ts +13 -0
  308. package/src/modules/messages/components/message-detail/hooks/useMessageDetails.ts +56 -0
  309. package/src/modules/messages/components/message-detail/hooks/useMessageDetailsActions.ts +367 -0
  310. package/src/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.ts +134 -0
  311. package/src/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.ts +102 -0
  312. package/src/modules/messages/components/message-detail/panels/MainMessageHeader.tsx +108 -0
  313. package/src/modules/messages/components/message-detail/panels/MessageHeader.tsx +144 -0
  314. package/src/modules/messages/components/message-detail/panels/MessageListComponent.tsx +63 -0
  315. package/src/modules/messages/components/message-detail/panels/actions-panel.tsx +66 -0
  316. package/src/modules/messages/components/message-detail/panels/attachments-panel.tsx +86 -0
  317. package/src/modules/messages/components/message-detail/panels/body-panel.tsx +32 -0
  318. package/src/modules/messages/components/message-detail/panels/composer-dialogs.tsx +42 -0
  319. package/src/modules/messages/components/message-detail/panels/dialogs.tsx +107 -0
  320. package/src/modules/messages/components/message-detail/panels/index.ts +11 -0
  321. package/src/modules/messages/components/message-detail/panels/meta-panel.tsx +19 -0
  322. package/src/modules/messages/components/message-detail/panels/objects-panel.tsx +65 -0
  323. package/src/modules/messages/components/message-detail/panels/thread-panel.tsx +65 -0
  324. package/src/modules/messages/components/message-detail/types.ts +114 -0
  325. package/src/modules/messages/components/message-detail/utils.ts +62 -0
  326. package/src/modules/messages/components/utils/PriorityBadge.tsx +63 -0
  327. package/src/modules/messages/components/utils/typeUiRegistry.ts +106 -0
  328. package/src/modules/messages/data/entities.ts +284 -0
  329. package/src/modules/messages/data/validators.ts +297 -0
  330. package/src/modules/messages/emails/MessageEmail.tsx +143 -0
  331. package/src/modules/messages/events.ts +24 -0
  332. package/src/modules/messages/frontend/messages/view/[token]/page.meta.ts +5 -0
  333. package/src/modules/messages/frontend/messages/view/[token]/page.tsx +389 -0
  334. package/src/modules/messages/i18n/de.json +240 -0
  335. package/src/modules/messages/i18n/en.json +240 -0
  336. package/src/modules/messages/i18n/es.json +240 -0
  337. package/src/modules/messages/i18n/pl.json +240 -0
  338. package/src/modules/messages/index.ts +19 -0
  339. package/src/modules/messages/lib/actions.ts +204 -0
  340. package/src/modules/messages/lib/attachments.ts +197 -0
  341. package/src/modules/messages/lib/constants.ts +2 -0
  342. package/src/modules/messages/lib/email-sender.ts +255 -0
  343. package/src/modules/messages/lib/forwarding.ts +240 -0
  344. package/src/modules/messages/lib/message-objects-registry.ts +60 -0
  345. package/src/modules/messages/lib/message-types-registry.ts +48 -0
  346. package/src/modules/messages/lib/object-validation.ts +26 -0
  347. package/src/modules/messages/lib/operationMetadata.ts +43 -0
  348. package/src/modules/messages/lib/priorityUtils.ts +76 -0
  349. package/src/modules/messages/lib/routeHelpers.ts +65 -0
  350. package/src/modules/messages/message-objects.ts +5 -0
  351. package/src/modules/messages/message-types.ts +65 -0
  352. package/src/modules/messages/migrations/.snapshot-open-mercato.json +957 -0
  353. package/src/modules/messages/migrations/Migration20260213181243.ts +34 -0
  354. package/src/modules/messages/migrations/Migration20260215165126.ts +16 -0
  355. package/src/modules/messages/notifications.ts +25 -0
  356. package/src/modules/messages/setup.ts +19 -0
  357. package/src/modules/messages/subscribers/message-notification.ts +138 -0
  358. package/src/modules/messages/workers/send-email.worker.ts +321 -0
  359. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +23 -7
  360. package/src/modules/sales/commands/payments.ts +12 -6
  361. package/src/modules/sales/i18n/de.json +3 -0
  362. package/src/modules/sales/i18n/en.json +3 -0
  363. package/src/modules/sales/i18n/es.json +3 -0
  364. package/src/modules/sales/i18n/pl.json +3 -0
  365. package/src/modules/sales/lib/messageObjectPreviews.ts +150 -0
  366. package/src/modules/sales/message-objects.ts +56 -0
  367. package/src/modules/sales/widgets/messages/SalesDocumentMessageDetail.tsx +57 -0
  368. package/src/modules/sales/widgets/messages/SalesDocumentMessagePreview.tsx +46 -0
  369. package/src/modules/sales/widgets/messages/index.ts +2 -0
  370. package/src/modules/staff/backend/staff/leave-requests/[id]/page.tsx +54 -0
  371. package/src/modules/staff/backend/staff/my-leave-requests/[id]/page.tsx +58 -0
  372. package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +2 -32
  373. package/src/modules/staff/components/LeaveRequestDetail.tsx +135 -0
  374. package/src/modules/staff/components/LeaveRequestForm.tsx +3 -0
  375. package/src/modules/staff/components/LeaveRequestPreview.tsx +74 -0
  376. package/src/modules/staff/i18n/de.json +8 -0
  377. package/src/modules/staff/i18n/en.json +8 -0
  378. package/src/modules/staff/i18n/es.json +8 -0
  379. package/src/modules/staff/i18n/pl.json +8 -0
  380. package/src/modules/staff/lib/messageObjectPreviews.ts +182 -0
  381. package/src/modules/staff/message-objects.ts +102 -0
  382. package/src/modules/staff/message-types.ts +21 -0
  383. package/src/modules/staff/widgets/messages/StaffMessageObjectDetail.tsx +57 -0
  384. package/src/modules/staff/widgets/messages/StaffMessageObjectPreview.tsx +44 -0
  385. package/src/modules/staff/widgets/messages/index.ts +2 -0
@@ -0,0 +1,143 @@
1
+ import React from 'react'
2
+ import {
3
+ Html,
4
+ Head,
5
+ Preview,
6
+ Body,
7
+ Container,
8
+ Text,
9
+ Section,
10
+ Link,
11
+ Hr,
12
+ } from '@react-email/components'
13
+
14
+ export type MessageEmailCopy = {
15
+ preview: string
16
+ heading: string
17
+ from: string
18
+ sentAt: string
19
+ viewCta: string
20
+ attachmentsLabel: string
21
+ objectsLabel: string
22
+ footer: string
23
+ }
24
+
25
+ export type MessageEmailProps = {
26
+ subject: string
27
+ body: string
28
+ bodyHtml?: string | null
29
+ senderName: string
30
+ sentAtLabel: string
31
+ viewUrl?: string | null
32
+ copy: MessageEmailCopy
33
+ attachmentNames?: string[]
34
+ objectLabels?: string[]
35
+ }
36
+
37
+ export function MessageEmail({
38
+ subject,
39
+ body,
40
+ bodyHtml,
41
+ senderName,
42
+ sentAtLabel,
43
+ viewUrl,
44
+ copy,
45
+ attachmentNames,
46
+ objectLabels,
47
+ }: MessageEmailProps) {
48
+ return (
49
+ <Html>
50
+ <Head>
51
+ <title>{subject}</title>
52
+ </Head>
53
+ <Preview>{copy.preview}</Preview>
54
+ <Body
55
+ style={{
56
+ backgroundColor: '#ffffff',
57
+ fontFamily: 'Arial, Helvetica, sans-serif',
58
+ padding: '12px 0',
59
+ margin: 0,
60
+ textAlign: 'left',
61
+ }}
62
+ >
63
+ <Container
64
+ style={{
65
+ padding: '0 16px',
66
+ margin: 0,
67
+ maxWidth: '640px',
68
+ textAlign: 'left',
69
+ }}
70
+ >
71
+ <Text style={{ margin: '0 0 8px', fontSize: '14px', color: '#202124' }}>{copy.heading}</Text>
72
+ <Text style={{ margin: '0 0 4px', color: '#5f6368', fontSize: '14px' }}>
73
+ {copy.from}: {senderName}
74
+ </Text>
75
+ <Text style={{ margin: '0 0 16px', color: '#5f6368', fontSize: '14px' }}>
76
+ {copy.sentAt}: {sentAtLabel}
77
+ </Text>
78
+ <Text style={{ margin: '0 0 12px', fontSize: '20px', lineHeight: 1.3, color: '#202124' }}>{subject}</Text>
79
+ <Section
80
+ style={{
81
+ whiteSpace: bodyHtml ? 'normal' : 'pre-wrap',
82
+ color: '#202124',
83
+ fontSize: '14px',
84
+ lineHeight: 1.5,
85
+ }}
86
+ >
87
+ {bodyHtml ? (
88
+ <div
89
+ style={{ margin: 0 }}
90
+ dangerouslySetInnerHTML={{ __html: bodyHtml }}
91
+ />
92
+ ) : (
93
+ <Text style={{ margin: 0 }}>{body}</Text>
94
+ )}
95
+ </Section>
96
+
97
+ {viewUrl ? (
98
+ <Section style={{ marginTop: '16px' }}>
99
+ <Text style={{ margin: 0, fontSize: '14px', color: '#202124' }}>
100
+ <Link href={viewUrl} style={{ color: '#1a73e8', textDecoration: 'none' }}>
101
+ {copy.viewCta}
102
+ </Link>
103
+ </Text>
104
+ </Section>
105
+ ) : null}
106
+
107
+ {attachmentNames?.length ? (
108
+ <>
109
+ <Hr style={{ borderColor: '#dadce0', margin: '20px 0 12px' }} />
110
+ <Text style={{ margin: '0 0 8px', fontSize: '13px', color: '#202124', fontWeight: 600 }}>
111
+ {copy.attachmentsLabel}
112
+ </Text>
113
+ {attachmentNames.slice(0, 5).map((name) => (
114
+ <Text key={name} style={{ margin: '0 0 4px', fontSize: '13px', color: '#202124' }}>
115
+ • {name}
116
+ </Text>
117
+ ))}
118
+ </>
119
+ ) : null}
120
+
121
+ {objectLabels?.length ? (
122
+ <>
123
+ <Hr style={{ borderColor: '#dadce0', margin: '20px 0 12px' }} />
124
+ <Text style={{ margin: '0 0 8px', fontSize: '13px', color: '#202124', fontWeight: 600 }}>
125
+ {copy.objectsLabel}
126
+ </Text>
127
+ {objectLabels.slice(0, 5).map((label) => (
128
+ <Text key={label} style={{ margin: '0 0 4px', fontSize: '13px', color: '#202124' }}>
129
+ • {label}
130
+ </Text>
131
+ ))}
132
+ </>
133
+ ) : null}
134
+
135
+ <Hr style={{ borderColor: '#dadce0', margin: '24px 0 12px' }} />
136
+ <Text style={{ margin: 0, fontSize: '12px', color: '#5f6368' }}>{copy.footer}</Text>
137
+ </Container>
138
+ </Body>
139
+ </Html>
140
+ )
141
+ }
142
+
143
+ export default MessageEmail
@@ -0,0 +1,24 @@
1
+ import { createModuleEvents } from '@open-mercato/shared/modules/events'
2
+
3
+ const events = [
4
+ { id: 'messages.message.sent', label: 'Message Sent', entity: 'message', category: 'custom' },
5
+ { id: 'messages.message.read', label: 'Message Read', entity: 'message', category: 'custom' },
6
+ { id: 'messages.message.marked_unread', label: 'Message Marked Unread', entity: 'message', category: 'custom' },
7
+ { id: 'messages.message.archived', label: 'Message Archived', entity: 'message', category: 'custom' },
8
+ { id: 'messages.message.unarchived', label: 'Message Unarchived', entity: 'message', category: 'custom' },
9
+ { id: 'messages.message.deleted', label: 'Message Deleted', entity: 'message', category: 'custom' },
10
+ { id: 'messages.message.action_taken', label: 'Message Action Taken', entity: 'message', category: 'custom' },
11
+ { id: 'messages.message.email_sent', label: 'Message Email Sent', entity: 'message', category: 'custom' },
12
+ { id: 'messages.message.email_failed', label: 'Message Email Failed', entity: 'message', category: 'custom' },
13
+ ] as const
14
+
15
+ export const eventsConfig = createModuleEvents({
16
+ moduleId: 'messages',
17
+ events,
18
+ })
19
+
20
+ export const emitMessagesEvent = eventsConfig.emit
21
+
22
+ export type MessagesEventId = typeof events[number]['id']
23
+
24
+ export default eventsConfig
@@ -0,0 +1,5 @@
1
+ export const metadata = {
2
+ requireAuth: false,
3
+ pageTitle: 'Message',
4
+ pageTitleKey: 'messages.token.pageTitle',
5
+ } as const
@@ -0,0 +1,389 @@
1
+ "use client"
2
+
3
+ import * as React from 'react'
4
+ import Link from 'next/link'
5
+ import type {
6
+ MessageContentProps,
7
+ MessageObjectAction,
8
+ } from '@open-mercato/shared/modules/messages/types'
9
+ import { useT } from '@open-mercato/shared/lib/i18n/context'
10
+ import { MarkdownContent } from '@open-mercato/ui/backend/markdown/MarkdownContent'
11
+ import { apiCall } from '@open-mercato/ui/backend/utils/apiCall'
12
+ import { Button } from '@open-mercato/ui/primitives/button'
13
+ import { Spinner } from '@open-mercato/ui/primitives/spinner'
14
+ import {
15
+ getMessageUiComponentRegistry,
16
+ } from '../../../../components/utils/typeUiRegistry'
17
+ import { getMessageObjectType } from '../../../../lib/message-objects-registry'
18
+ import { getMessageTypeOrDefault } from '../../../../lib/message-types-registry'
19
+
20
+ type TokenMessageObject = {
21
+ id: string
22
+ entityModule: string
23
+ entityType: string
24
+ entityId: string
25
+ actionRequired: boolean
26
+ actionType?: string | null
27
+ actionLabel?: string | null
28
+ snapshot?: Record<string, unknown> | null
29
+ }
30
+
31
+ type MessageTokenResponse = {
32
+ id: string
33
+ type: string
34
+ subject: string
35
+ body: string
36
+ bodyFormat: 'text' | 'markdown'
37
+ priority: 'low' | 'normal' | 'high' | 'urgent'
38
+ senderUserId: string
39
+ sentAt?: string | null
40
+ actionData?: {
41
+ actions: Array<{
42
+ id: string
43
+ label: string
44
+ labelKey?: string
45
+ variant?: 'default' | 'secondary' | 'destructive' | 'outline' | 'ghost'
46
+ icon?: string
47
+ commandId?: string
48
+ href?: string
49
+ isTerminal?: boolean
50
+ confirmRequired?: boolean
51
+ confirmMessage?: string
52
+ }>
53
+ primaryActionId?: string
54
+ expiresAt?: string
55
+ } | null
56
+ actionTaken?: string | null
57
+ actionTakenAt?: string | null
58
+ actionTakenByUserId?: string | null
59
+ objects: TokenMessageObject[]
60
+ requiresAuth: boolean
61
+ recipientUserId: string
62
+ }
63
+
64
+ function toErrorMessage(payload: unknown): string | null {
65
+ if (!payload) return null
66
+ if (typeof payload === 'string') return payload
67
+ if (Array.isArray(payload)) {
68
+ for (const entry of payload) {
69
+ const nested = toErrorMessage(entry)
70
+ if (nested) return nested
71
+ }
72
+ return null
73
+ }
74
+ if (typeof payload === 'object') {
75
+ const record = payload as Record<string, unknown>
76
+ return (
77
+ toErrorMessage(record.error)
78
+ ?? toErrorMessage(record.message)
79
+ ?? toErrorMessage(record.detail)
80
+ ?? toErrorMessage(record.details)
81
+ ?? null
82
+ )
83
+ }
84
+ return null
85
+ }
86
+
87
+ function formatDateTime(value: string | null | undefined): string {
88
+ if (!value) return '—'
89
+ const date = new Date(value)
90
+ if (Number.isNaN(date.getTime())) return '—'
91
+ return date.toLocaleString()
92
+ }
93
+
94
+ function toObjectActions(
95
+ objectActions: Array<{
96
+ id: string
97
+ labelKey: string
98
+ variant?: 'default' | 'secondary' | 'destructive' | 'outline'
99
+ icon?: string
100
+ commandId?: string
101
+ href?: string
102
+ isTerminal?: boolean
103
+ confirmRequired?: boolean
104
+ confirmMessage?: string
105
+ }>,
106
+ ): MessageObjectAction[] {
107
+ return objectActions.map((action) => ({
108
+ id: action.id,
109
+ labelKey: action.labelKey,
110
+ variant: action.variant,
111
+ icon: action.icon,
112
+ commandId: action.commandId,
113
+ href: action.href,
114
+ isTerminal: action.isTerminal,
115
+ confirmRequired: action.confirmRequired,
116
+ confirmMessage: action.confirmMessage,
117
+ }))
118
+ }
119
+
120
+ function mergeTokenActions(
121
+ messageActions: MessageTokenResponse['actionData'],
122
+ defaultActions: Array<{
123
+ id: string
124
+ label: string
125
+ labelKey?: string
126
+ variant?: 'default' | 'secondary' | 'destructive' | 'outline' | 'ghost'
127
+ icon?: string
128
+ commandId?: string
129
+ href?: string
130
+ isTerminal?: boolean
131
+ confirmRequired?: boolean
132
+ confirmMessage?: string
133
+ }> | undefined,
134
+ ): MessageTokenResponse['actionData'] {
135
+ const deduped = new Map<string, NonNullable<MessageTokenResponse['actionData']>['actions'][number]>()
136
+
137
+ for (const action of messageActions?.actions ?? []) {
138
+ const normalizedId = action.id.trim()
139
+ if (!normalizedId) continue
140
+ deduped.set(normalizedId, { ...action, id: normalizedId })
141
+ }
142
+
143
+ for (const action of defaultActions ?? []) {
144
+ const normalizedId = action.id.trim()
145
+ if (!normalizedId || deduped.has(normalizedId)) continue
146
+ deduped.set(normalizedId, { ...action, id: normalizedId })
147
+ }
148
+
149
+ const actions = Array.from(deduped.values())
150
+ if (actions.length === 0 && !messageActions?.expiresAt) return null
151
+
152
+ return {
153
+ actions,
154
+ primaryActionId: messageActions?.primaryActionId,
155
+ expiresAt: messageActions?.expiresAt,
156
+ }
157
+ }
158
+
159
+ export default function MessageTokenPage({ params }: { params: { token: string } }) {
160
+ const t = useT()
161
+ const messageUiRegistry = React.useMemo(() => getMessageUiComponentRegistry(), [])
162
+ const token = params?.token
163
+
164
+ const [loading, setLoading] = React.useState(true)
165
+ const [data, setData] = React.useState<MessageTokenResponse | null>(null)
166
+ const [errorMessage, setErrorMessage] = React.useState<string | null>(null)
167
+ const [errorStatus, setErrorStatus] = React.useState<number | null>(null)
168
+
169
+ React.useEffect(() => {
170
+ let mounted = true
171
+
172
+ async function run() {
173
+ if (!token) return
174
+
175
+ setLoading(true)
176
+ setData(null)
177
+ setErrorMessage(null)
178
+ setErrorStatus(null)
179
+
180
+ try {
181
+ const call = await apiCall<MessageTokenResponse>(`/api/messages/token/${encodeURIComponent(token)}`)
182
+
183
+ if (!mounted) return
184
+
185
+ if (!call.ok || !call.result) {
186
+ const status = call.status
187
+ setErrorStatus(status)
188
+
189
+ const fallback = status === 404
190
+ ? t('messages.token.errors.notFound', 'This message link is invalid or has already been used.')
191
+ : status === 409
192
+ ? t('messages.token.errors.limitExceeded', 'This message link reached its usage limit.')
193
+ : status === 410
194
+ ? t('messages.token.errors.expired', 'This message link has expired.')
195
+ : t('messages.token.errors.generic', 'Unable to load this message.')
196
+
197
+ setErrorMessage(toErrorMessage(call.result) ?? fallback)
198
+ return
199
+ }
200
+
201
+ setData(call.result)
202
+ } catch (error) {
203
+ if (!mounted) return
204
+ setErrorMessage(
205
+ error instanceof Error
206
+ ? error.message
207
+ : t('messages.token.errors.generic', 'Unable to load this message.'),
208
+ )
209
+ } finally {
210
+ if (mounted) {
211
+ setLoading(false)
212
+ }
213
+ }
214
+ }
215
+
216
+ void run()
217
+
218
+ return () => {
219
+ mounted = false
220
+ }
221
+ }, [t, token])
222
+
223
+ if (loading) {
224
+ return (
225
+ <main className="mx-auto max-w-3xl p-6">
226
+ <p className="flex items-center gap-2 text-sm text-muted-foreground">
227
+ <Spinner className="h-4 w-4 animate-spin" />
228
+ {t('messages.token.loading', 'Loading message...')}
229
+ </p>
230
+ </main>
231
+ )
232
+ }
233
+
234
+ if (errorMessage || !data) {
235
+ return (
236
+ <main className="mx-auto max-w-3xl space-y-3 p-6">
237
+ <h1 className="text-2xl font-semibold">{t('messages.token.pageTitle', 'Message')}</h1>
238
+ <p className="text-sm text-destructive">{errorMessage ?? t('messages.token.errors.generic', 'Unable to load this message.')}</p>
239
+ {errorStatus ? <p className="text-xs text-muted-foreground">HTTP {errorStatus}</p> : null}
240
+ </main>
241
+ )
242
+ }
243
+
244
+ if (data.requiresAuth) {
245
+ return (
246
+ <main className="mx-auto max-w-3xl space-y-4 p-6">
247
+ <h1 className="text-2xl font-semibold">{t('messages.token.authRequired.title', 'Sign in required')}</h1>
248
+ <p className="text-sm text-muted-foreground">
249
+ {t('messages.token.authRequired.description', 'This message includes protected objects. Sign in to continue.')}
250
+ </p>
251
+ <Button asChild>
252
+ <Link href="/login">{t('auth.signIn', 'Sign in')}</Link>
253
+ </Button>
254
+ </main>
255
+ )
256
+ }
257
+
258
+ const messageType = getMessageTypeOrDefault(data.type)
259
+ const contentComponentKey = messageType.ui?.contentComponent
260
+ const actionsComponentKey = messageType.ui?.actionsComponent
261
+ const ContentComponent = contentComponentKey
262
+ ? messageUiRegistry.contentComponents[contentComponentKey] ?? null
263
+ : null
264
+ const ActionsComponent = actionsComponentKey
265
+ ? messageUiRegistry.actionsComponents[actionsComponentKey] ?? null
266
+ : null
267
+ const resolvedActionData = mergeTokenActions(data.actionData ?? null, messageType.defaultActions)
268
+
269
+ const contentProps: MessageContentProps = {
270
+ message: {
271
+ id: data.id,
272
+ type: data.type,
273
+ subject: data.subject,
274
+ body: data.body,
275
+ bodyFormat: data.bodyFormat,
276
+ priority: data.priority,
277
+ sentAt: data.sentAt ? new Date(data.sentAt) : null,
278
+ senderUserId: data.senderUserId,
279
+ actionData: resolvedActionData,
280
+ actionTaken: data.actionTaken ?? null,
281
+ actionTakenAt: data.actionTakenAt ? new Date(data.actionTakenAt) : null,
282
+ },
283
+ objects: data.objects.map((objectItem) => ({
284
+ id: objectItem.id,
285
+ entityModule: objectItem.entityModule,
286
+ entityType: objectItem.entityType,
287
+ entityId: objectItem.entityId,
288
+ actionRequired: objectItem.actionRequired,
289
+ snapshot: objectItem.snapshot ?? undefined,
290
+ })),
291
+ attachments: [],
292
+ }
293
+
294
+ const tokenActions = resolvedActionData?.actions ?? []
295
+
296
+ return (
297
+ <main className="mx-auto max-w-3xl space-y-6 p-6">
298
+ <header className="space-y-1">
299
+ <h1 className="text-2xl font-semibold">{data.subject}</h1>
300
+ <p className="text-sm text-muted-foreground">
301
+ {t('messages.token.sentAt', 'Sent')}: {formatDateTime(data.sentAt)}
302
+ </p>
303
+ </header>
304
+
305
+ <section className="rounded-xl border bg-card p-4">
306
+ {ContentComponent ? (
307
+ <ContentComponent {...contentProps} />
308
+ ) : (
309
+ <MarkdownContent
310
+ body={data.body}
311
+ format={data.bodyFormat}
312
+ className="text-sm whitespace-pre-wrap [&>*]:mb-2 [&>*:last-child]:mb-0 [&_ul]:ml-4 [&_ul]:list-disc [&_ol]:ml-4 [&_ol]:list-decimal [&_code]:rounded [&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_pre]:rounded-md [&_pre]:bg-muted [&_pre]:p-3 [&_pre]:text-xs"
313
+ />
314
+ )}
315
+ </section>
316
+
317
+ {tokenActions.length > 0 ? (
318
+ <section className="space-y-3 rounded-xl border bg-card p-4">
319
+ <h2 className="text-base font-semibold">{t('messages.actions.title', 'Actions')}</h2>
320
+ {ActionsComponent ? (
321
+ <ActionsComponent
322
+ message={{
323
+ id: data.id,
324
+ type: data.type,
325
+ actionData: resolvedActionData,
326
+ actionTaken: data.actionTaken ?? null,
327
+ }}
328
+ onExecuteAction={async (_actionId) => {
329
+ return
330
+ }}
331
+ isExecuting={false}
332
+ executingActionId={null}
333
+ />
334
+ ) : (
335
+ <div className="flex flex-wrap gap-2">
336
+ {tokenActions.map((action) => (
337
+ <Button
338
+ key={action.id}
339
+ type="button"
340
+ variant={action.variant ?? 'default'}
341
+ disabled
342
+ >
343
+ {t(action.labelKey ?? action.label, action.label)}
344
+ </Button>
345
+ ))}
346
+ </div>
347
+ )}
348
+ </section>
349
+ ) : null}
350
+
351
+ <section className="space-y-2 rounded-xl border bg-card p-4">
352
+ <h2 className="text-base font-semibold">{t('messages.attachedObjects', 'Attached objects')}</h2>
353
+ {data.objects.length === 0 ? (
354
+ null
355
+ ) : (
356
+ <div className="space-y-2">
357
+ {data.objects.map((objectItem) => {
358
+ const objectType = getMessageObjectType(objectItem.entityModule, objectItem.entityType)
359
+ const objectActions = toObjectActions(objectType?.actions ?? [])
360
+ const detailComponentKey = `${objectItem.entityModule}:${objectItem.entityType}`
361
+ const DetailComponent = messageUiRegistry.objectDetailComponents[detailComponentKey] ?? null
362
+
363
+ return DetailComponent ? (
364
+ <DetailComponent
365
+ key={objectItem.id}
366
+ entityId={objectItem.entityId}
367
+ entityModule={objectItem.entityModule}
368
+ entityType={objectItem.entityType}
369
+ snapshot={objectItem.snapshot ?? undefined}
370
+ previewData={undefined}
371
+ actionRequired={objectItem.actionRequired}
372
+ actionType={objectItem.actionType ?? undefined}
373
+ actionLabel={objectItem.actionLabel ?? undefined}
374
+ actions={objectActions}
375
+ actionTaken={data.actionTaken ?? null}
376
+ actionTakenAt={data.actionTakenAt ? new Date(data.actionTakenAt) : null}
377
+ actionTakenByUserId={data.actionTakenByUserId ?? null}
378
+ onAction={async () => {
379
+ return
380
+ }}
381
+ />
382
+ ) : null
383
+ })}
384
+ </div>
385
+ )}
386
+ </section>
387
+ </main>
388
+ )
389
+ }