@open-mercato/core 0.4.5-develop-754ef4d2f0 → 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.
- package/dist/generated/entities/message/index.js +65 -0
- package/dist/generated/entities/message/index.js.map +7 -0
- package/dist/generated/entities/message_access_token/index.js +19 -0
- package/dist/generated/entities/message_access_token/index.js.map +7 -0
- package/dist/generated/entities/message_confirmation/index.js +21 -0
- package/dist/generated/entities/message_confirmation/index.js.map +7 -0
- package/dist/generated/entities/message_object/index.js +23 -0
- package/dist/generated/entities/message_object/index.js.map +7 -0
- package/dist/generated/entities/message_recipient/index.js +31 -0
- package/dist/generated/entities/message_recipient/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +8 -0
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +10 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/auth/components/AclEditor.js +4 -2
- package/dist/modules/auth/components/AclEditor.js.map +2 -2
- package/dist/modules/auth/frontend/reset.js +3 -3
- package/dist/modules/auth/frontend/reset.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +27 -8
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/lib/messageObjectPreviews.js +131 -0
- package/dist/modules/customers/lib/messageObjectPreviews.js.map +7 -0
- package/dist/modules/customers/message-objects.js +71 -0
- package/dist/modules/customers/message-objects.js.map +7 -0
- package/dist/modules/customers/widgets/messages/CustomerMessageObjectDetail.js +51 -0
- package/dist/modules/customers/widgets/messages/CustomerMessageObjectDetail.js.map +7 -0
- package/dist/modules/customers/widgets/messages/CustomerMessageObjectPreview.js +35 -0
- package/dist/modules/customers/widgets/messages/CustomerMessageObjectPreview.js.map +7 -0
- package/dist/modules/customers/widgets/messages/index.js +7 -0
- package/dist/modules/customers/widgets/messages/index.js.map +7 -0
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js +35 -6
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +2 -2
- package/dist/modules/messages/acl.js +15 -0
- package/dist/modules/messages/acl.js.map +7 -0
- package/dist/modules/messages/api/[id]/actions/[actionId]/route.js +92 -0
- package/dist/modules/messages/api/[id]/actions/[actionId]/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/archive/route.js +120 -0
- package/dist/modules/messages/api/[id]/archive/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/attachments/route.js +195 -0
- package/dist/modules/messages/api/[id]/attachments/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/confirmation/route.js +67 -0
- package/dist/modules/messages/api/[id]/confirmation/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/conversation/archive/route.js +68 -0
- package/dist/modules/messages/api/[id]/conversation/archive/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/conversation/read/route.js +68 -0
- package/dist/modules/messages/api/[id]/conversation/read/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/conversation/route.js +68 -0
- package/dist/modules/messages/api/[id]/conversation/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/forward/route.js +85 -0
- package/dist/modules/messages/api/[id]/forward/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/forward-preview/route.js +70 -0
- package/dist/modules/messages/api/[id]/forward-preview/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/read/route.js +120 -0
- package/dist/modules/messages/api/[id]/read/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/reply/route.js +87 -0
- package/dist/modules/messages/api/[id]/reply/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/route.js +350 -0
- package/dist/modules/messages/api/[id]/route.js.map +7 -0
- package/dist/modules/messages/api/object-types/route.js +54 -0
- package/dist/modules/messages/api/object-types/route.js.map +7 -0
- package/dist/modules/messages/api/openapi.js +261 -0
- package/dist/modules/messages/api/openapi.js.map +7 -0
- package/dist/modules/messages/api/route.js +262 -0
- package/dist/modules/messages/api/route.js.map +7 -0
- package/dist/modules/messages/api/token/[token]/route.js +99 -0
- package/dist/modules/messages/api/token/[token]/route.js.map +7 -0
- package/dist/modules/messages/api/types/route.js +40 -0
- package/dist/modules/messages/api/types/route.js.map +7 -0
- package/dist/modules/messages/api/unread-count/route.js +43 -0
- package/dist/modules/messages/api/unread-count/route.js.map +7 -0
- package/dist/modules/messages/backend/messages/[id]/page.js +10 -0
- package/dist/modules/messages/backend/messages/[id]/page.js.map +7 -0
- package/dist/modules/messages/backend/messages/[id]/page.meta.js +16 -0
- package/dist/modules/messages/backend/messages/[id]/page.meta.js.map +7 -0
- package/dist/modules/messages/backend/messages/compose/page.js +10 -0
- package/dist/modules/messages/backend/messages/compose/page.js.map +7 -0
- package/dist/modules/messages/backend/messages/compose/page.meta.js +17 -0
- package/dist/modules/messages/backend/messages/compose/page.meta.js.map +7 -0
- package/dist/modules/messages/backend/page.js +10 -0
- package/dist/modules/messages/backend/page.js.map +7 -0
- package/dist/modules/messages/backend/page.meta.js +33 -0
- package/dist/modules/messages/backend/page.meta.js.map +7 -0
- package/dist/modules/messages/commands/actions.js +265 -0
- package/dist/modules/messages/commands/actions.js.map +7 -0
- package/dist/modules/messages/commands/attachments.js +217 -0
- package/dist/modules/messages/commands/attachments.js.map +7 -0
- package/dist/modules/messages/commands/confirmations.js +151 -0
- package/dist/modules/messages/commands/confirmations.js.map +7 -0
- package/dist/modules/messages/commands/conversation.js +240 -0
- package/dist/modules/messages/commands/conversation.js.map +7 -0
- package/dist/modules/messages/commands/messages.js +748 -0
- package/dist/modules/messages/commands/messages.js.map +7 -0
- package/dist/modules/messages/commands/recipients.js +259 -0
- package/dist/modules/messages/commands/recipients.js.map +7 -0
- package/dist/modules/messages/commands/shared.js +258 -0
- package/dist/modules/messages/commands/shared.js.map +7 -0
- package/dist/modules/messages/commands/tokens.js +69 -0
- package/dist/modules/messages/commands/tokens.js.map +7 -0
- package/dist/modules/messages/components/ComposeMessagePageClient.js +24 -0
- package/dist/modules/messages/components/ComposeMessagePageClient.js.map +7 -0
- package/dist/modules/messages/components/MessageDetailPageClient.js +261 -0
- package/dist/modules/messages/components/MessageDetailPageClient.js.map +7 -0
- package/dist/modules/messages/components/MessagesInboxPageClient.js +390 -0
- package/dist/modules/messages/components/MessagesInboxPageClient.js.map +7 -0
- package/dist/modules/messages/components/confirmation/MessageConfirmationActions.js +31 -0
- package/dist/modules/messages/components/confirmation/MessageConfirmationActions.js.map +7 -0
- package/dist/modules/messages/components/confirmation/MessageConfirmationContent.js +69 -0
- package/dist/modules/messages/components/confirmation/MessageConfirmationContent.js.map +7 -0
- package/dist/modules/messages/components/defaults/DefaultMessageActions.js +31 -0
- package/dist/modules/messages/components/defaults/DefaultMessageActions.js.map +7 -0
- package/dist/modules/messages/components/defaults/DefaultMessageContent.js +19 -0
- package/dist/modules/messages/components/defaults/DefaultMessageContent.js.map +7 -0
- package/dist/modules/messages/components/defaults/DefaultMessageListItem.js +90 -0
- package/dist/modules/messages/components/defaults/DefaultMessageListItem.js.map +7 -0
- package/dist/modules/messages/components/defaults/MessageRecordObjectDetail.js +86 -0
- package/dist/modules/messages/components/defaults/MessageRecordObjectDetail.js.map +7 -0
- package/dist/modules/messages/components/defaults/MessageRecordObjectPreview.js +61 -0
- package/dist/modules/messages/components/defaults/MessageRecordObjectPreview.js.map +7 -0
- package/dist/modules/messages/components/message-detail/detail-panels.js +27 -0
- package/dist/modules/messages/components/message-detail/detail-panels.js.map +7 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetails.js +52 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetails.js.map +7 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsActions.js +289 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsActions.js.map +7 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js +103 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js.map +7 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.js +78 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/MainMessageHeader.js +94 -0
- package/dist/modules/messages/components/message-detail/panels/MainMessageHeader.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/MessageHeader.js +110 -0
- package/dist/modules/messages/components/message-detail/panels/MessageHeader.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/MessageListComponent.js +58 -0
- package/dist/modules/messages/components/message-detail/panels/MessageListComponent.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/actions-panel.js +51 -0
- package/dist/modules/messages/components/message-detail/panels/actions-panel.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/attachments-panel.js +66 -0
- package/dist/modules/messages/components/message-detail/panels/attachments-panel.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/body-panel.js +20 -0
- package/dist/modules/messages/components/message-detail/panels/body-panel.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/composer-dialogs.js +36 -0
- package/dist/modules/messages/components/message-detail/panels/composer-dialogs.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/dialogs.js +96 -0
- package/dist/modules/messages/components/message-detail/panels/dialogs.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/index.js +25 -0
- package/dist/modules/messages/components/message-detail/panels/index.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/meta-panel.js +14 -0
- package/dist/modules/messages/components/message-detail/panels/meta-panel.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/objects-panel.js +51 -0
- package/dist/modules/messages/components/message-detail/panels/objects-panel.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/thread-panel.js +54 -0
- package/dist/modules/messages/components/message-detail/panels/thread-panel.js.map +7 -0
- package/dist/modules/messages/components/message-detail/types.js +1 -0
- package/dist/modules/messages/components/message-detail/types.js.map +7 -0
- package/dist/modules/messages/components/message-detail/utils.js +54 -0
- package/dist/modules/messages/components/message-detail/utils.js.map +7 -0
- package/dist/modules/messages/components/utils/PriorityBadge.js +52 -0
- package/dist/modules/messages/components/utils/PriorityBadge.js.map +7 -0
- package/dist/modules/messages/components/utils/typeUiRegistry.js +77 -0
- package/dist/modules/messages/components/utils/typeUiRegistry.js.map +7 -0
- package/dist/modules/messages/data/entities.js +309 -0
- package/dist/modules/messages/data/entities.js.map +7 -0
- package/dist/modules/messages/data/validators.js +272 -0
- package/dist/modules/messages/data/validators.js.map +7 -0
- package/dist/modules/messages/emails/MessageEmail.js +108 -0
- package/dist/modules/messages/emails/MessageEmail.js.map +7 -0
- package/dist/modules/messages/events.js +24 -0
- package/dist/modules/messages/events.js.map +7 -0
- package/dist/modules/messages/frontend/messages/view/[token]/page.js +247 -0
- package/dist/modules/messages/frontend/messages/view/[token]/page.js.map +7 -0
- package/dist/modules/messages/frontend/messages/view/[token]/page.meta.js +9 -0
- package/dist/modules/messages/frontend/messages/view/[token]/page.meta.js.map +7 -0
- package/dist/modules/messages/index.js +21 -0
- package/dist/modules/messages/index.js.map +7 -0
- package/dist/modules/messages/lib/actions.js +141 -0
- package/dist/modules/messages/lib/actions.js.map +7 -0
- package/dist/modules/messages/lib/attachments.js +131 -0
- package/dist/modules/messages/lib/attachments.js.map +7 -0
- package/dist/modules/messages/lib/constants.js +7 -0
- package/dist/modules/messages/lib/constants.js.map +7 -0
- package/dist/modules/messages/lib/email-sender.js +201 -0
- package/dist/modules/messages/lib/email-sender.js.map +7 -0
- package/dist/modules/messages/lib/forwarding.js +179 -0
- package/dist/modules/messages/lib/forwarding.js.map +7 -0
- package/dist/modules/messages/lib/message-objects-registry.js +49 -0
- package/dist/modules/messages/lib/message-objects-registry.js.map +7 -0
- package/dist/modules/messages/lib/message-types-registry.js +41 -0
- package/dist/modules/messages/lib/message-types-registry.js.map +7 -0
- package/dist/modules/messages/lib/object-validation.js +20 -0
- package/dist/modules/messages/lib/object-validation.js.map +7 -0
- package/dist/modules/messages/lib/operationMetadata.js +21 -0
- package/dist/modules/messages/lib/operationMetadata.js.map +7 -0
- package/dist/modules/messages/lib/priorityUtils.js +61 -0
- package/dist/modules/messages/lib/priorityUtils.js.map +7 -0
- package/dist/modules/messages/lib/routeHelpers.js +44 -0
- package/dist/modules/messages/lib/routeHelpers.js.map +7 -0
- package/dist/modules/messages/message-objects.js +7 -0
- package/dist/modules/messages/message-objects.js.map +7 -0
- package/dist/modules/messages/message-types.js +67 -0
- package/dist/modules/messages/message-types.js.map +7 -0
- package/dist/modules/messages/migrations/Migration20260213181243.js +31 -0
- package/dist/modules/messages/migrations/Migration20260213181243.js.map +7 -0
- package/dist/modules/messages/migrations/Migration20260215165126.js +16 -0
- package/dist/modules/messages/migrations/Migration20260215165126.js.map +7 -0
- package/dist/modules/messages/notifications.js +27 -0
- package/dist/modules/messages/notifications.js.map +7 -0
- package/dist/modules/messages/setup.js +21 -0
- package/dist/modules/messages/setup.js.map +7 -0
- package/dist/modules/messages/subscribers/message-notification.js +108 -0
- package/dist/modules/messages/subscribers/message-notification.js.map +7 -0
- package/dist/modules/messages/workers/send-email.worker.js +253 -0
- package/dist/modules/messages/workers/send-email.worker.js.map +7 -0
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +30 -11
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/commands/payments.js +12 -6
- package/dist/modules/sales/commands/payments.js.map +2 -2
- package/dist/modules/sales/lib/messageObjectPreviews.js +114 -0
- package/dist/modules/sales/lib/messageObjectPreviews.js.map +7 -0
- package/dist/modules/sales/message-objects.js +57 -0
- package/dist/modules/sales/message-objects.js.map +7 -0
- package/dist/modules/sales/widgets/messages/SalesDocumentMessageDetail.js +51 -0
- package/dist/modules/sales/widgets/messages/SalesDocumentMessageDetail.js.map +7 -0
- package/dist/modules/sales/widgets/messages/SalesDocumentMessagePreview.js +36 -0
- package/dist/modules/sales/widgets/messages/SalesDocumentMessagePreview.js.map +7 -0
- package/dist/modules/sales/widgets/messages/index.js +7 -0
- package/dist/modules/sales/widgets/messages/index.js.map +7 -0
- package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js +55 -1
- package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js +60 -1
- package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js +2 -19
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
- package/dist/modules/staff/components/LeaveRequestDetail.js +112 -0
- package/dist/modules/staff/components/LeaveRequestDetail.js.map +7 -0
- package/dist/modules/staff/components/LeaveRequestForm.js +3 -1
- package/dist/modules/staff/components/LeaveRequestForm.js.map +2 -2
- package/dist/modules/staff/components/LeaveRequestPreview.js +43 -0
- package/dist/modules/staff/components/LeaveRequestPreview.js.map +7 -0
- package/dist/modules/staff/lib/messageObjectPreviews.js +148 -0
- package/dist/modules/staff/lib/messageObjectPreviews.js.map +7 -0
- package/dist/modules/staff/message-objects.js +104 -0
- package/dist/modules/staff/message-objects.js.map +7 -0
- package/dist/modules/staff/message-types.js +23 -0
- package/dist/modules/staff/message-types.js.map +7 -0
- package/dist/modules/staff/widgets/messages/StaffMessageObjectDetail.js +51 -0
- package/dist/modules/staff/widgets/messages/StaffMessageObjectDetail.js.map +7 -0
- package/dist/modules/staff/widgets/messages/StaffMessageObjectPreview.js +34 -0
- package/dist/modules/staff/widgets/messages/StaffMessageObjectPreview.js.map +7 -0
- package/dist/modules/staff/widgets/messages/index.js +7 -0
- package/dist/modules/staff/widgets/messages/index.js.map +7 -0
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js +6 -6
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
- package/generated/entities/message/index.ts +31 -0
- package/generated/entities/message_access_token/index.ts +8 -0
- package/generated/entities/message_confirmation/index.ts +9 -0
- package/generated/entities/message_object/index.ts +10 -0
- package/generated/entities/message_recipient/index.ts +14 -0
- package/generated/entities.ids.generated.ts +8 -0
- package/generated/entity-fields-registry.ts +10 -0
- package/jest.setup.ts +5 -0
- package/package.json +2 -2
- package/src/modules/attachments/i18n/de.json +4 -0
- package/src/modules/attachments/i18n/en.json +4 -0
- package/src/modules/attachments/i18n/es.json +4 -0
- package/src/modules/attachments/i18n/pl.json +4 -0
- package/src/modules/auth/components/AclEditor.tsx +4 -2
- package/src/modules/auth/frontend/reset.tsx +3 -3
- package/src/modules/auth/i18n/de.json +5 -0
- package/src/modules/auth/i18n/en.json +5 -0
- package/src/modules/auth/i18n/es.json +5 -0
- package/src/modules/auth/i18n/pl.json +5 -0
- package/src/modules/catalog/i18n/de.json +21 -0
- package/src/modules/catalog/i18n/en.json +21 -0
- package/src/modules/catalog/i18n/es.json +21 -0
- package/src/modules/catalog/i18n/pl.json +21 -0
- package/src/modules/currencies/i18n/de.json +6 -0
- package/src/modules/currencies/i18n/en.json +6 -0
- package/src/modules/currencies/i18n/es.json +6 -0
- package/src/modules/currencies/i18n/pl.json +6 -0
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +20 -4
- package/src/modules/customers/i18n/de.json +26 -1
- package/src/modules/customers/i18n/en.json +25 -0
- package/src/modules/customers/i18n/es.json +25 -0
- package/src/modules/customers/i18n/pl.json +25 -0
- package/src/modules/customers/lib/messageObjectPreviews.ts +154 -0
- package/src/modules/customers/message-objects.ts +70 -0
- package/src/modules/customers/widgets/messages/CustomerMessageObjectDetail.tsx +57 -0
- package/src/modules/customers/widgets/messages/CustomerMessageObjectPreview.tsx +49 -0
- package/src/modules/customers/widgets/messages/index.ts +2 -0
- package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +41 -5
- package/src/modules/dashboards/i18n/de.json +5 -1
- package/src/modules/dashboards/i18n/en.json +5 -1
- package/src/modules/dashboards/i18n/es.json +5 -1
- package/src/modules/dashboards/i18n/pl.json +5 -1
- package/src/modules/dictionaries/i18n/de.json +14 -1
- package/src/modules/dictionaries/i18n/en.json +14 -1
- package/src/modules/dictionaries/i18n/es.json +14 -1
- package/src/modules/dictionaries/i18n/pl.json +14 -1
- package/src/modules/feature_toggles/i18n/de.json +3 -0
- package/src/modules/feature_toggles/i18n/en.json +3 -0
- package/src/modules/feature_toggles/i18n/es.json +3 -0
- package/src/modules/feature_toggles/i18n/pl.json +3 -0
- package/src/modules/messages/acl.ts +11 -0
- package/src/modules/messages/api/[id]/actions/[actionId]/route.ts +103 -0
- package/src/modules/messages/api/[id]/archive/route.ts +138 -0
- package/src/modules/messages/api/[id]/attachments/route.ts +217 -0
- package/src/modules/messages/api/[id]/confirmation/route.ts +73 -0
- package/src/modules/messages/api/[id]/conversation/archive/route.ts +69 -0
- package/src/modules/messages/api/[id]/conversation/read/route.ts +69 -0
- package/src/modules/messages/api/[id]/conversation/route.ts +69 -0
- package/src/modules/messages/api/[id]/forward/route.ts +87 -0
- package/src/modules/messages/api/[id]/forward-preview/route.ts +75 -0
- package/src/modules/messages/api/[id]/read/route.ts +138 -0
- package/src/modules/messages/api/[id]/reply/route.ts +89 -0
- package/src/modules/messages/api/[id]/route.ts +401 -0
- package/src/modules/messages/api/object-types/route.ts +54 -0
- package/src/modules/messages/api/openapi.ts +261 -0
- package/src/modules/messages/api/route.ts +374 -0
- package/src/modules/messages/api/token/[token]/route.ts +103 -0
- package/src/modules/messages/api/types/route.ts +39 -0
- package/src/modules/messages/api/unread-count/route.ts +55 -0
- package/src/modules/messages/backend/messages/[id]/page.meta.ts +12 -0
- package/src/modules/messages/backend/messages/[id]/page.tsx +12 -0
- package/src/modules/messages/backend/messages/compose/page.meta.ts +13 -0
- package/src/modules/messages/backend/messages/compose/page.tsx +12 -0
- package/src/modules/messages/backend/page.meta.ts +31 -0
- package/src/modules/messages/backend/page.tsx +12 -0
- package/src/modules/messages/commands/actions.ts +307 -0
- package/src/modules/messages/commands/attachments.ts +227 -0
- package/src/modules/messages/commands/confirmations.ts +183 -0
- package/src/modules/messages/commands/conversation.ts +292 -0
- package/src/modules/messages/commands/messages.ts +845 -0
- package/src/modules/messages/commands/recipients.ts +281 -0
- package/src/modules/messages/commands/shared.ts +350 -0
- package/src/modules/messages/commands/tokens.ts +80 -0
- package/src/modules/messages/components/ComposeMessagePageClient.tsx +23 -0
- package/src/modules/messages/components/MessageDetailPageClient.tsx +287 -0
- package/src/modules/messages/components/MessagesInboxPageClient.tsx +469 -0
- package/src/modules/messages/components/confirmation/MessageConfirmationActions.tsx +35 -0
- package/src/modules/messages/components/confirmation/MessageConfirmationContent.tsx +88 -0
- package/src/modules/messages/components/defaults/DefaultMessageActions.tsx +37 -0
- package/src/modules/messages/components/defaults/DefaultMessageContent.tsx +21 -0
- package/src/modules/messages/components/defaults/DefaultMessageListItem.tsx +102 -0
- package/src/modules/messages/components/defaults/MessageRecordObjectDetail.tsx +114 -0
- package/src/modules/messages/components/defaults/MessageRecordObjectPreview.tsx +74 -0
- package/src/modules/messages/components/message-detail/detail-panels.ts +13 -0
- package/src/modules/messages/components/message-detail/hooks/useMessageDetails.ts +56 -0
- package/src/modules/messages/components/message-detail/hooks/useMessageDetailsActions.ts +367 -0
- package/src/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.ts +134 -0
- package/src/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.ts +102 -0
- package/src/modules/messages/components/message-detail/panels/MainMessageHeader.tsx +108 -0
- package/src/modules/messages/components/message-detail/panels/MessageHeader.tsx +144 -0
- package/src/modules/messages/components/message-detail/panels/MessageListComponent.tsx +63 -0
- package/src/modules/messages/components/message-detail/panels/actions-panel.tsx +66 -0
- package/src/modules/messages/components/message-detail/panels/attachments-panel.tsx +86 -0
- package/src/modules/messages/components/message-detail/panels/body-panel.tsx +32 -0
- package/src/modules/messages/components/message-detail/panels/composer-dialogs.tsx +42 -0
- package/src/modules/messages/components/message-detail/panels/dialogs.tsx +107 -0
- package/src/modules/messages/components/message-detail/panels/index.ts +11 -0
- package/src/modules/messages/components/message-detail/panels/meta-panel.tsx +19 -0
- package/src/modules/messages/components/message-detail/panels/objects-panel.tsx +65 -0
- package/src/modules/messages/components/message-detail/panels/thread-panel.tsx +65 -0
- package/src/modules/messages/components/message-detail/types.ts +114 -0
- package/src/modules/messages/components/message-detail/utils.ts +62 -0
- package/src/modules/messages/components/utils/PriorityBadge.tsx +63 -0
- package/src/modules/messages/components/utils/typeUiRegistry.ts +106 -0
- package/src/modules/messages/data/entities.ts +284 -0
- package/src/modules/messages/data/validators.ts +297 -0
- package/src/modules/messages/emails/MessageEmail.tsx +143 -0
- package/src/modules/messages/events.ts +24 -0
- package/src/modules/messages/frontend/messages/view/[token]/page.meta.ts +5 -0
- package/src/modules/messages/frontend/messages/view/[token]/page.tsx +389 -0
- package/src/modules/messages/i18n/de.json +240 -0
- package/src/modules/messages/i18n/en.json +240 -0
- package/src/modules/messages/i18n/es.json +240 -0
- package/src/modules/messages/i18n/pl.json +240 -0
- package/src/modules/messages/index.ts +19 -0
- package/src/modules/messages/lib/actions.ts +204 -0
- package/src/modules/messages/lib/attachments.ts +197 -0
- package/src/modules/messages/lib/constants.ts +2 -0
- package/src/modules/messages/lib/email-sender.ts +255 -0
- package/src/modules/messages/lib/forwarding.ts +240 -0
- package/src/modules/messages/lib/message-objects-registry.ts +60 -0
- package/src/modules/messages/lib/message-types-registry.ts +48 -0
- package/src/modules/messages/lib/object-validation.ts +26 -0
- package/src/modules/messages/lib/operationMetadata.ts +43 -0
- package/src/modules/messages/lib/priorityUtils.ts +76 -0
- package/src/modules/messages/lib/routeHelpers.ts +65 -0
- package/src/modules/messages/message-objects.ts +5 -0
- package/src/modules/messages/message-types.ts +65 -0
- package/src/modules/messages/migrations/.snapshot-open-mercato.json +957 -0
- package/src/modules/messages/migrations/Migration20260213181243.ts +34 -0
- package/src/modules/messages/migrations/Migration20260215165126.ts +16 -0
- package/src/modules/messages/notifications.ts +25 -0
- package/src/modules/messages/setup.ts +19 -0
- package/src/modules/messages/subscribers/message-notification.ts +138 -0
- package/src/modules/messages/workers/send-email.worker.ts +321 -0
- package/src/modules/query_index/i18n/es.json +2 -2
- package/src/modules/resources/i18n/de.json +57 -0
- package/src/modules/resources/i18n/en.json +57 -0
- package/src/modules/resources/i18n/es.json +57 -0
- package/src/modules/resources/i18n/pl.json +57 -0
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +23 -7
- package/src/modules/sales/commands/payments.ts +12 -6
- package/src/modules/sales/i18n/de.json +26 -0
- package/src/modules/sales/i18n/en.json +26 -0
- package/src/modules/sales/i18n/es.json +26 -0
- package/src/modules/sales/i18n/pl.json +26 -0
- package/src/modules/sales/lib/messageObjectPreviews.ts +150 -0
- package/src/modules/sales/message-objects.ts +56 -0
- package/src/modules/sales/widgets/messages/SalesDocumentMessageDetail.tsx +57 -0
- package/src/modules/sales/widgets/messages/SalesDocumentMessagePreview.tsx +46 -0
- package/src/modules/sales/widgets/messages/index.ts +2 -0
- package/src/modules/staff/backend/staff/leave-requests/[id]/page.tsx +54 -0
- package/src/modules/staff/backend/staff/my-leave-requests/[id]/page.tsx +58 -0
- package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +2 -32
- package/src/modules/staff/components/LeaveRequestDetail.tsx +135 -0
- package/src/modules/staff/components/LeaveRequestForm.tsx +3 -0
- package/src/modules/staff/components/LeaveRequestPreview.tsx +74 -0
- package/src/modules/staff/i18n/de.json +22 -0
- package/src/modules/staff/i18n/en.json +22 -0
- package/src/modules/staff/i18n/es.json +22 -0
- package/src/modules/staff/i18n/pl.json +22 -0
- package/src/modules/staff/lib/messageObjectPreviews.ts +182 -0
- package/src/modules/staff/message-objects.ts +102 -0
- package/src/modules/staff/message-types.ts +21 -0
- package/src/modules/staff/widgets/messages/StaffMessageObjectDetail.tsx +57 -0
- package/src/modules/staff/widgets/messages/StaffMessageObjectPreview.tsx +44 -0
- package/src/modules/staff/widgets/messages/index.ts +2 -0
- package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +6 -6
- package/src/modules/workflows/i18n/de.json +41 -0
- package/src/modules/workflows/i18n/en.json +41 -0
- package/src/modules/workflows/i18n/es.json +41 -0
- package/src/modules/workflows/i18n/pl.json +41 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Migration } from '@mikro-orm/migrations';
|
|
2
|
+
|
|
3
|
+
export class Migration20260213181243 extends Migration {
|
|
4
|
+
|
|
5
|
+
override async up(): Promise<void> {
|
|
6
|
+
this.addSql(`create table "messages" ("id" uuid not null default gen_random_uuid(), "type" text not null default 'default', "thread_id" uuid null, "parent_message_id" uuid null, "sender_user_id" uuid not null, "subject" text not null, "body" text not null, "body_format" text not null default 'text', "priority" text not null default 'normal', "status" text not null default 'draft', "is_draft" boolean not null default true, "sent_at" timestamptz null, "action_data" jsonb null, "action_result" jsonb null, "action_taken" text null, "action_taken_by_user_id" uuid null, "action_taken_at" timestamptz null, "send_via_email" boolean not null default false, "tenant_id" uuid not null, "organization_id" uuid null, "created_at" timestamptz not null, "updated_at" timestamptz not null, "deleted_at" timestamptz null, "visibility" text null, "source_entity_type" text null, "source_entity_id" uuid null, "external_email" text null, "external_name" text null, "external_email_sent_at" timestamptz null, "external_email_failed_at" timestamptz null, "external_email_error" text null, constraint "messages_pkey" primary key ("id"));`);
|
|
7
|
+
this.addSql(`create index "messages_tenant_idx" on "messages" ("tenant_id", "organization_id");`);
|
|
8
|
+
this.addSql(`create index "messages_type_idx" on "messages" ("type", "tenant_id");`);
|
|
9
|
+
this.addSql(`create index "messages_thread_idx" on "messages" ("thread_id");`);
|
|
10
|
+
this.addSql(`create index "messages_sender_idx" on "messages" ("sender_user_id", "sent_at");`);
|
|
11
|
+
|
|
12
|
+
this.addSql(`create table "message_access_tokens" ("id" uuid not null default gen_random_uuid(), "message_id" uuid not null, "recipient_user_id" uuid not null, "token" text not null, "expires_at" timestamptz not null, "used_at" timestamptz null, "use_count" int not null default 0, "created_at" timestamptz not null, constraint "message_access_tokens_pkey" primary key ("id"));`);
|
|
13
|
+
this.addSql(`alter table "message_access_tokens" add constraint "message_access_tokens_token_unique" unique ("token");`);
|
|
14
|
+
this.addSql(`create index "message_access_tokens_message_idx" on "message_access_tokens" ("message_id");`);
|
|
15
|
+
this.addSql(`create index "message_access_tokens_token_idx" on "message_access_tokens" ("token");`);
|
|
16
|
+
|
|
17
|
+
this.addSql(`create table "message_objects" ("id" uuid not null default gen_random_uuid(), "message_id" uuid not null, "entity_module" text not null, "entity_type" text not null, "entity_id" uuid not null, "action_required" boolean not null default false, "action_type" text null, "action_label" text null, "entity_snapshot" jsonb null, "created_at" timestamptz not null, constraint "message_objects_pkey" primary key ("id"));`);
|
|
18
|
+
this.addSql(`create index "message_objects_entity_idx" on "message_objects" ("entity_type", "entity_id");`);
|
|
19
|
+
this.addSql(`create index "message_objects_message_idx" on "message_objects" ("message_id");`);
|
|
20
|
+
|
|
21
|
+
this.addSql(`create table "message_recipients" ("id" uuid not null default gen_random_uuid(), "message_id" uuid not null, "recipient_user_id" uuid not null, "recipient_type" text not null default 'to', "status" text not null default 'unread', "read_at" timestamptz null, "archived_at" timestamptz null, "deleted_at" timestamptz null, "email_sent_at" timestamptz null, "email_delivered_at" timestamptz null, "email_opened_at" timestamptz null, "email_failed_at" timestamptz null, "email_error" text null, "created_at" timestamptz not null, constraint "message_recipients_pkey" primary key ("id"));`);
|
|
22
|
+
this.addSql(`alter table "message_recipients" add constraint "message_recipients_message_user_unique" unique ("message_id", "recipient_user_id");`);
|
|
23
|
+
this.addSql(`create index "message_recipients_message_idx" on "message_recipients" ("message_id");`);
|
|
24
|
+
this.addSql(`create index "message_recipients_user_idx" on "message_recipients" ("recipient_user_id", "status");`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
override async down(): Promise<void> {
|
|
28
|
+
this.addSql(`drop table if exists "message_recipients" cascade;`);
|
|
29
|
+
this.addSql(`drop table if exists "message_objects" cascade;`);
|
|
30
|
+
this.addSql(`drop table if exists "message_access_tokens" cascade;`);
|
|
31
|
+
this.addSql(`drop table if exists "messages" cascade;`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Migration } from '@mikro-orm/migrations';
|
|
2
|
+
|
|
3
|
+
export class Migration20260215165126 extends Migration {
|
|
4
|
+
|
|
5
|
+
override async up(): Promise<void> {
|
|
6
|
+
this.addSql(`create table "message_confirmations" ("id" uuid not null default gen_random_uuid(), "message_id" uuid not null, "tenant_id" uuid not null, "organization_id" uuid null, "confirmed" boolean not null default true, "confirmed_by_user_id" uuid null, "confirmed_at" timestamptz null, "created_at" timestamptz not null, "updated_at" timestamptz not null, constraint "message_confirmations_pkey" primary key ("id"));`);
|
|
7
|
+
this.addSql(`create index "message_confirmations_scope_idx" on "message_confirmations" ("tenant_id", "organization_id");`);
|
|
8
|
+
this.addSql(`create index "message_confirmations_message_idx" on "message_confirmations" ("message_id");`);
|
|
9
|
+
this.addSql(`alter table "message_confirmations" add constraint "message_confirmations_message_unique" unique ("message_id");`);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
override async down(): Promise<void> {
|
|
13
|
+
this.addSql(`drop table if exists "message_confirmations" cascade;`);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { NotificationTypeDefinition } from '@open-mercato/shared/modules/notifications/types'
|
|
2
|
+
|
|
3
|
+
export const notificationTypes: NotificationTypeDefinition[] = [
|
|
4
|
+
{
|
|
5
|
+
type: 'messages.new',
|
|
6
|
+
module: 'messages',
|
|
7
|
+
titleKey: 'messages.notifications.new.title',
|
|
8
|
+
bodyKey: 'messages.notifications.new.body',
|
|
9
|
+
icon: 'mail',
|
|
10
|
+
severity: 'info',
|
|
11
|
+
actions: [
|
|
12
|
+
{
|
|
13
|
+
id: 'view',
|
|
14
|
+
labelKey: 'common.view',
|
|
15
|
+
variant: 'outline',
|
|
16
|
+
href: '/backend/messages/{sourceEntityId}',
|
|
17
|
+
icon: 'external-link',
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
linkHref: '/backend/messages/{sourceEntityId}',
|
|
21
|
+
expiresAfterHours: 168,
|
|
22
|
+
},
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
export default notificationTypes
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ModuleSetupConfig } from '@open-mercato/shared/modules/setup'
|
|
2
|
+
|
|
3
|
+
export const setup: ModuleSetupConfig = {
|
|
4
|
+
defaultRoleFeatures: {
|
|
5
|
+
superadmin: ['messages.*'],
|
|
6
|
+
admin: [
|
|
7
|
+
'messages.*',
|
|
8
|
+
],
|
|
9
|
+
employee: [
|
|
10
|
+
'messages.view',
|
|
11
|
+
'messages.compose',
|
|
12
|
+
'messages.attach',
|
|
13
|
+
'messages.attach_files',
|
|
14
|
+
'messages.actions',
|
|
15
|
+
],
|
|
16
|
+
},
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default setup
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import type { EntityManager } from '@mikro-orm/postgresql'
|
|
2
|
+
import { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'
|
|
3
|
+
import { createQueue } from '@open-mercato/queue'
|
|
4
|
+
import { buildBatchNotificationFromType } from '../../notifications/lib/notificationBuilder'
|
|
5
|
+
import { resolveNotificationService } from '../../notifications/lib/notificationService'
|
|
6
|
+
import {
|
|
7
|
+
MESSAGES_EMAIL_QUEUE_NAME,
|
|
8
|
+
type SendMessageEmailJob,
|
|
9
|
+
} from '../workers/send-email.worker'
|
|
10
|
+
import { User } from '../../auth/data/entities'
|
|
11
|
+
import { Message } from '../data/entities'
|
|
12
|
+
import { notificationTypes } from '../notifications'
|
|
13
|
+
|
|
14
|
+
export const metadata = {
|
|
15
|
+
event: 'messages.message.sent',
|
|
16
|
+
persistent: true,
|
|
17
|
+
id: 'messages:queue-email-delivery',
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type MessageSentPayload = {
|
|
21
|
+
messageId: string
|
|
22
|
+
senderUserId: string
|
|
23
|
+
recipientUserIds: string[]
|
|
24
|
+
sendViaEmail: boolean
|
|
25
|
+
externalEmail?: string | null
|
|
26
|
+
forwardedFrom?: string
|
|
27
|
+
replyTo?: string
|
|
28
|
+
tenantId: string
|
|
29
|
+
organizationId?: string | null
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
type ResolverContext = {
|
|
33
|
+
resolve: <T = unknown>(name: string) => T
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function resolveNotificationVariables(payload: MessageSentPayload, ctx: ResolverContext): Promise<{ title: string; from: string }> {
|
|
37
|
+
try {
|
|
38
|
+
const em = ctx.resolve<EntityManager>('em')?.fork()
|
|
39
|
+
if (!em) return { title: '', from: '' }
|
|
40
|
+
|
|
41
|
+
const scope = {
|
|
42
|
+
tenantId: payload.tenantId,
|
|
43
|
+
organizationId: payload.organizationId ?? null,
|
|
44
|
+
}
|
|
45
|
+
const whereUser: { id: string; tenantId: string; deletedAt: null; organizationId?: string | null } = {
|
|
46
|
+
id: payload.senderUserId,
|
|
47
|
+
tenantId: payload.tenantId,
|
|
48
|
+
deletedAt: null,
|
|
49
|
+
}
|
|
50
|
+
if (payload.organizationId !== undefined) {
|
|
51
|
+
whereUser.organizationId = payload.organizationId
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const [message, sender] = await Promise.all([
|
|
55
|
+
findOneWithDecryption(
|
|
56
|
+
em,
|
|
57
|
+
Message,
|
|
58
|
+
{
|
|
59
|
+
id: payload.messageId,
|
|
60
|
+
tenantId: payload.tenantId,
|
|
61
|
+
deletedAt: null,
|
|
62
|
+
},
|
|
63
|
+
undefined,
|
|
64
|
+
scope,
|
|
65
|
+
),
|
|
66
|
+
findOneWithDecryption(
|
|
67
|
+
em,
|
|
68
|
+
User,
|
|
69
|
+
whereUser,
|
|
70
|
+
undefined,
|
|
71
|
+
scope,
|
|
72
|
+
),
|
|
73
|
+
])
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
title: typeof message?.subject === 'string' ? message.subject : '',
|
|
77
|
+
from: typeof sender?.name === 'string' && sender.name.trim().length > 0
|
|
78
|
+
? sender.name
|
|
79
|
+
: typeof sender?.email === 'string'
|
|
80
|
+
? sender.email
|
|
81
|
+
: '',
|
|
82
|
+
}
|
|
83
|
+
} catch {
|
|
84
|
+
return { title: '', from: '' }
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
export default async function handle(payload: MessageSentPayload, ctx: ResolverContext): Promise<void> {
|
|
90
|
+
const uniqueRecipientUserIds = Array.from(new Set(payload.recipientUserIds))
|
|
91
|
+
|
|
92
|
+
const typeDef = notificationTypes.find((type) => type.type === 'messages.new')
|
|
93
|
+
if (typeDef && uniqueRecipientUserIds.length > 0) {
|
|
94
|
+
const variables = await resolveNotificationVariables(payload, ctx)
|
|
95
|
+
const notificationService = resolveNotificationService(ctx)
|
|
96
|
+
const notificationInput = buildBatchNotificationFromType(typeDef, {
|
|
97
|
+
recipientUserIds: uniqueRecipientUserIds,
|
|
98
|
+
titleVariables: variables,
|
|
99
|
+
bodyVariables: variables,
|
|
100
|
+
sourceEntityType: 'message',
|
|
101
|
+
sourceEntityId: payload.messageId,
|
|
102
|
+
linkHref: `/backend/messages/${payload.messageId}`,
|
|
103
|
+
})
|
|
104
|
+
await notificationService.createBatch(notificationInput, {
|
|
105
|
+
tenantId: payload.tenantId,
|
|
106
|
+
organizationId: payload.organizationId ?? null,
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (!payload.sendViaEmail) {
|
|
111
|
+
return
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const strategy = process.env.QUEUE_STRATEGY === 'async' ? 'async' : 'local'
|
|
115
|
+
|
|
116
|
+
const emailQueue = createQueue<SendMessageEmailJob>(MESSAGES_EMAIL_QUEUE_NAME, strategy)
|
|
117
|
+
|
|
118
|
+
for (const recipientUserId of uniqueRecipientUserIds) {
|
|
119
|
+
await emailQueue.enqueue({
|
|
120
|
+
type: 'recipient',
|
|
121
|
+
messageId: payload.messageId,
|
|
122
|
+
recipientUserId,
|
|
123
|
+
tenantId: payload.tenantId,
|
|
124
|
+
organizationId: payload.organizationId ?? null,
|
|
125
|
+
})
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const externalEmail = payload.externalEmail?.trim()
|
|
129
|
+
if (externalEmail) {
|
|
130
|
+
await emailQueue.enqueue({
|
|
131
|
+
type: 'external',
|
|
132
|
+
messageId: payload.messageId,
|
|
133
|
+
email: externalEmail,
|
|
134
|
+
tenantId: payload.tenantId,
|
|
135
|
+
organizationId: payload.organizationId ?? null,
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
import type { EntityManager } from '@mikro-orm/postgresql'
|
|
2
|
+
import type { JobContext, QueuedJob, WorkerMeta } from '@open-mercato/queue'
|
|
3
|
+
import { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'
|
|
4
|
+
import { User } from '../../auth/data/entities'
|
|
5
|
+
import { Message, MessageObject, MessageRecipient } from '../data/entities'
|
|
6
|
+
import { emitMessagesEvent } from '../events'
|
|
7
|
+
import { getMessageEmailAttachments } from '../lib/attachments'
|
|
8
|
+
import {
|
|
9
|
+
sendMessageEmailToExternal,
|
|
10
|
+
sendMessageEmailToRecipient,
|
|
11
|
+
} from '../lib/email-sender'
|
|
12
|
+
|
|
13
|
+
export const MESSAGES_EMAIL_QUEUE_NAME = 'messages-email'
|
|
14
|
+
|
|
15
|
+
export type SendMessageEmailToRecipientJob = {
|
|
16
|
+
type: 'recipient'
|
|
17
|
+
messageId: string
|
|
18
|
+
recipientUserId: string
|
|
19
|
+
tenantId: string
|
|
20
|
+
organizationId?: string | null
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type SendMessageEmailToExternalJob = {
|
|
24
|
+
type: 'external'
|
|
25
|
+
messageId: string
|
|
26
|
+
email: string
|
|
27
|
+
tenantId: string
|
|
28
|
+
organizationId?: string | null
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type SendMessageEmailJob = SendMessageEmailToRecipientJob | SendMessageEmailToExternalJob
|
|
32
|
+
|
|
33
|
+
export const metadata: WorkerMeta = {
|
|
34
|
+
queue: MESSAGES_EMAIL_QUEUE_NAME,
|
|
35
|
+
id: 'messages:send-email',
|
|
36
|
+
concurrency: 10,
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
type HandlerContext = {
|
|
40
|
+
resolve: <T = unknown>(name: string) => T
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function emitEmailDeliveryEvent(
|
|
44
|
+
ctx: HandlerContext,
|
|
45
|
+
eventId: 'messages.message.email_sent' | 'messages.message.email_failed',
|
|
46
|
+
payload: {
|
|
47
|
+
messageId: string
|
|
48
|
+
target: 'recipient' | 'external'
|
|
49
|
+
recipientUserId?: string
|
|
50
|
+
email?: string
|
|
51
|
+
error?: string
|
|
52
|
+
tenantId: string
|
|
53
|
+
organizationId?: string | null
|
|
54
|
+
}
|
|
55
|
+
) {
|
|
56
|
+
const eventBus = ctx.resolve<{ emit?: unknown } | null>('eventBus')
|
|
57
|
+
if (!eventBus || typeof eventBus !== 'object' || typeof (eventBus as { emit?: unknown }).emit !== 'function') {
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
await emitMessagesEvent(eventId, payload, { persistent: true })
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function resolveSender(em: EntityManager, message: Message) {
|
|
64
|
+
const sender = await findOneWithDecryption(
|
|
65
|
+
em,
|
|
66
|
+
User,
|
|
67
|
+
{
|
|
68
|
+
id: message.senderUserId,
|
|
69
|
+
tenantId: message.tenantId,
|
|
70
|
+
deletedAt: null,
|
|
71
|
+
},
|
|
72
|
+
undefined,
|
|
73
|
+
{ tenantId: message.tenantId, organizationId: message.organizationId ?? null }
|
|
74
|
+
)
|
|
75
|
+
return {
|
|
76
|
+
name: sender?.name ?? null,
|
|
77
|
+
email: sender?.email ?? null,
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function resolveMessageScope(
|
|
82
|
+
em: EntityManager,
|
|
83
|
+
payload: SendMessageEmailJob
|
|
84
|
+
) {
|
|
85
|
+
return await em.findOne(Message, {
|
|
86
|
+
id: payload.messageId,
|
|
87
|
+
tenantId: payload.tenantId,
|
|
88
|
+
organizationId: payload.organizationId ?? null,
|
|
89
|
+
deletedAt: null,
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export async function claimRecipientDelivery(
|
|
94
|
+
em: EntityManager,
|
|
95
|
+
payload: SendMessageEmailToRecipientJob,
|
|
96
|
+
): Promise<Date | null> {
|
|
97
|
+
const claimTimestamp = new Date()
|
|
98
|
+
const updatedRows = await em.nativeUpdate(
|
|
99
|
+
MessageRecipient,
|
|
100
|
+
{
|
|
101
|
+
messageId: payload.messageId,
|
|
102
|
+
recipientUserId: payload.recipientUserId,
|
|
103
|
+
emailSentAt: null,
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
emailSentAt: claimTimestamp,
|
|
107
|
+
emailFailedAt: null,
|
|
108
|
+
emailError: null,
|
|
109
|
+
},
|
|
110
|
+
)
|
|
111
|
+
return updatedRows > 0 ? claimTimestamp : null
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export async function releaseRecipientClaim(
|
|
115
|
+
em: EntityManager,
|
|
116
|
+
payload: SendMessageEmailToRecipientJob,
|
|
117
|
+
claimTimestamp: Date,
|
|
118
|
+
errorMessage: string,
|
|
119
|
+
): Promise<void> {
|
|
120
|
+
await em.nativeUpdate(
|
|
121
|
+
MessageRecipient,
|
|
122
|
+
{
|
|
123
|
+
messageId: payload.messageId,
|
|
124
|
+
recipientUserId: payload.recipientUserId,
|
|
125
|
+
emailSentAt: claimTimestamp,
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
emailSentAt: null,
|
|
129
|
+
emailFailedAt: new Date(),
|
|
130
|
+
emailError: errorMessage,
|
|
131
|
+
},
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export async function claimExternalDelivery(
|
|
136
|
+
em: EntityManager,
|
|
137
|
+
payload: SendMessageEmailToExternalJob,
|
|
138
|
+
): Promise<Date | null> {
|
|
139
|
+
const claimTimestamp = new Date()
|
|
140
|
+
const updatedRows = await em.nativeUpdate(
|
|
141
|
+
Message,
|
|
142
|
+
{
|
|
143
|
+
id: payload.messageId,
|
|
144
|
+
tenantId: payload.tenantId,
|
|
145
|
+
organizationId: payload.organizationId ?? null,
|
|
146
|
+
externalEmailSentAt: null,
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
externalEmailSentAt: claimTimestamp,
|
|
150
|
+
externalEmailFailedAt: null,
|
|
151
|
+
externalEmailError: null,
|
|
152
|
+
},
|
|
153
|
+
)
|
|
154
|
+
return updatedRows > 0 ? claimTimestamp : null
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export async function releaseExternalClaim(
|
|
158
|
+
em: EntityManager,
|
|
159
|
+
payload: SendMessageEmailToExternalJob,
|
|
160
|
+
claimTimestamp: Date,
|
|
161
|
+
errorMessage: string,
|
|
162
|
+
): Promise<void> {
|
|
163
|
+
await em.nativeUpdate(
|
|
164
|
+
Message,
|
|
165
|
+
{
|
|
166
|
+
id: payload.messageId,
|
|
167
|
+
tenantId: payload.tenantId,
|
|
168
|
+
organizationId: payload.organizationId ?? null,
|
|
169
|
+
externalEmailSentAt: claimTimestamp,
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
externalEmailSentAt: null,
|
|
173
|
+
externalEmailFailedAt: new Date(),
|
|
174
|
+
externalEmailError: errorMessage,
|
|
175
|
+
},
|
|
176
|
+
)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export default async function handle(
|
|
180
|
+
job: QueuedJob<SendMessageEmailJob>,
|
|
181
|
+
ctx: JobContext & HandlerContext
|
|
182
|
+
): Promise<void> {
|
|
183
|
+
const { payload } = job
|
|
184
|
+
const em = (ctx.resolve('em') as EntityManager).fork()
|
|
185
|
+
|
|
186
|
+
const message = await resolveMessageScope(em, payload)
|
|
187
|
+
if (!message) {
|
|
188
|
+
console.error('[messages:send-email] Message not found', payload.messageId)
|
|
189
|
+
return
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const objects = await em.find(MessageObject, { messageId: message.id })
|
|
193
|
+
const attachments = await getMessageEmailAttachments(
|
|
194
|
+
em,
|
|
195
|
+
message.id,
|
|
196
|
+
message.organizationId ?? null,
|
|
197
|
+
message.tenantId
|
|
198
|
+
)
|
|
199
|
+
const sender = await resolveSender(em, message)
|
|
200
|
+
|
|
201
|
+
if (payload.type === 'external') {
|
|
202
|
+
const externalClaimTimestamp = await claimExternalDelivery(em, payload)
|
|
203
|
+
if (!externalClaimTimestamp) {
|
|
204
|
+
return
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
try {
|
|
208
|
+
await sendMessageEmailToExternal({
|
|
209
|
+
message,
|
|
210
|
+
email: payload.email,
|
|
211
|
+
sender,
|
|
212
|
+
objects,
|
|
213
|
+
attachments,
|
|
214
|
+
})
|
|
215
|
+
await emitEmailDeliveryEvent(ctx, 'messages.message.email_sent', {
|
|
216
|
+
messageId: message.id,
|
|
217
|
+
target: 'external',
|
|
218
|
+
email: payload.email,
|
|
219
|
+
tenantId: message.tenantId,
|
|
220
|
+
organizationId: message.organizationId ?? null,
|
|
221
|
+
})
|
|
222
|
+
} catch (error) {
|
|
223
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error'
|
|
224
|
+
await releaseExternalClaim(
|
|
225
|
+
em,
|
|
226
|
+
payload,
|
|
227
|
+
externalClaimTimestamp,
|
|
228
|
+
errorMessage,
|
|
229
|
+
)
|
|
230
|
+
await emitEmailDeliveryEvent(ctx, 'messages.message.email_failed', {
|
|
231
|
+
messageId: message.id,
|
|
232
|
+
target: 'external',
|
|
233
|
+
email: payload.email,
|
|
234
|
+
error: errorMessage,
|
|
235
|
+
tenantId: message.tenantId,
|
|
236
|
+
organizationId: message.organizationId ?? null,
|
|
237
|
+
})
|
|
238
|
+
console.error('[messages:send-email] External email send failed', error)
|
|
239
|
+
}
|
|
240
|
+
return
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const recipientRecord = await em.findOne(MessageRecipient, {
|
|
244
|
+
messageId: payload.messageId,
|
|
245
|
+
recipientUserId: payload.recipientUserId,
|
|
246
|
+
})
|
|
247
|
+
if (!recipientRecord) {
|
|
248
|
+
console.error('[messages:send-email] Recipient row not found', payload)
|
|
249
|
+
return
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (recipientRecord.emailSentAt) {
|
|
253
|
+
return
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const recipientClaimTimestamp = await claimRecipientDelivery(em, payload)
|
|
257
|
+
if (!recipientClaimTimestamp) {
|
|
258
|
+
return
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const recipientUser = await findOneWithDecryption(
|
|
262
|
+
em,
|
|
263
|
+
User,
|
|
264
|
+
{
|
|
265
|
+
id: payload.recipientUserId,
|
|
266
|
+
tenantId: message.tenantId,
|
|
267
|
+
deletedAt: null,
|
|
268
|
+
},
|
|
269
|
+
undefined,
|
|
270
|
+
{ tenantId: message.tenantId, organizationId: message.organizationId ?? null }
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
const recipientEmail = recipientUser?.email?.trim()
|
|
274
|
+
if (!recipientEmail) {
|
|
275
|
+
await releaseRecipientClaim(
|
|
276
|
+
em,
|
|
277
|
+
payload,
|
|
278
|
+
recipientClaimTimestamp,
|
|
279
|
+
'Recipient has no email address',
|
|
280
|
+
)
|
|
281
|
+
return
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
try {
|
|
285
|
+
await sendMessageEmailToRecipient({
|
|
286
|
+
em,
|
|
287
|
+
message,
|
|
288
|
+
recipientUserId: payload.recipientUserId,
|
|
289
|
+
recipientEmail,
|
|
290
|
+
sender,
|
|
291
|
+
objects,
|
|
292
|
+
attachments,
|
|
293
|
+
})
|
|
294
|
+
await emitEmailDeliveryEvent(ctx, 'messages.message.email_sent', {
|
|
295
|
+
messageId: message.id,
|
|
296
|
+
target: 'recipient',
|
|
297
|
+
recipientUserId: payload.recipientUserId,
|
|
298
|
+
email: recipientEmail,
|
|
299
|
+
tenantId: message.tenantId,
|
|
300
|
+
organizationId: message.organizationId ?? null,
|
|
301
|
+
})
|
|
302
|
+
} catch (error) {
|
|
303
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error'
|
|
304
|
+
await releaseRecipientClaim(
|
|
305
|
+
em,
|
|
306
|
+
payload,
|
|
307
|
+
recipientClaimTimestamp,
|
|
308
|
+
errorMessage,
|
|
309
|
+
)
|
|
310
|
+
await emitEmailDeliveryEvent(ctx, 'messages.message.email_failed', {
|
|
311
|
+
messageId: message.id,
|
|
312
|
+
target: 'recipient',
|
|
313
|
+
recipientUserId: payload.recipientUserId,
|
|
314
|
+
email: recipientEmail,
|
|
315
|
+
error: errorMessage,
|
|
316
|
+
tenantId: message.tenantId,
|
|
317
|
+
organizationId: message.organizationId ?? null,
|
|
318
|
+
})
|
|
319
|
+
console.error('[messages:send-email] Recipient email send failed', error)
|
|
320
|
+
}
|
|
321
|
+
}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"query_index.table.columns.label": "Etiqueta",
|
|
21
21
|
"query_index.table.columns.records": "Registros",
|
|
22
22
|
"query_index.table.columns.status": "Estado",
|
|
23
|
-
"query_index.table.columns.vector": "
|
|
23
|
+
"query_index.table.columns.vector": "Vectorial",
|
|
24
24
|
"query_index.table.confirm.fulltextPurge": "¿Eliminar el índice de texto completo de esta entidad? Esta acción no se puede deshacer.",
|
|
25
25
|
"query_index.table.confirm.vectorPurge": "¿Eliminar los embeddings vectoriales de esta entidad? Esta acción no se puede deshacer.",
|
|
26
26
|
"query_index.table.errors.actionFailed": "No se pudo ejecutar {{action}}.",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"query_index.table.status.scope.stalled": "Detenido",
|
|
59
59
|
"query_index.table.status.scopeLabel": "Ámbito",
|
|
60
60
|
"query_index.table.status.stalled": "Detenido",
|
|
61
|
-
"query_index.table.status.vectorLabel": "
|
|
61
|
+
"query_index.table.status.vectorLabel": "Vectorial",
|
|
62
62
|
"query_index.table.status.vectorValue": "{{count}} / {{total}}",
|
|
63
63
|
"query_index.table.status.withProgress": "{{status}} ({{progress}})"
|
|
64
64
|
}
|
|
@@ -76,6 +76,12 @@
|
|
|
76
76
|
"resources.audit.availabilityRuleSets.create": "Verfügbarkeitszeitplan erstellen",
|
|
77
77
|
"resources.audit.availabilityRuleSets.delete": "Verfügbarkeitszeitplan löschen",
|
|
78
78
|
"resources.audit.availabilityRuleSets.update": "Verfügbarkeitszeitplan aktualisieren",
|
|
79
|
+
"resources.audit.resourceActivities.create": "Ressourcenaktivität erstellen",
|
|
80
|
+
"resources.audit.resourceActivities.delete": "Ressourcenaktivität löschen",
|
|
81
|
+
"resources.audit.resourceActivities.update": "Ressourcenaktivität aktualisieren",
|
|
82
|
+
"resources.audit.resourceComments.create": "Ressourcenkommentar erstellen",
|
|
83
|
+
"resources.audit.resourceComments.delete": "Ressourcenkommentar löschen",
|
|
84
|
+
"resources.audit.resourceComments.update": "Ressourcenkommentar aktualisieren",
|
|
79
85
|
"resources.audit.resourceTags.assign": "Ressourcen-Tag zuweisen",
|
|
80
86
|
"resources.audit.resourceTags.create": "Ressourcen-Tag erstellen",
|
|
81
87
|
"resources.audit.resourceTags.delete": "Ressourcen-Tag löschen",
|
|
@@ -349,6 +355,7 @@
|
|
|
349
355
|
"resources.resources.detail.activities.update": "Aktivität aktualisieren (Cmd/Ctrl + Enter)",
|
|
350
356
|
"resources.resources.detail.activities.updateSuccess": "Aktivität aktualisiert.",
|
|
351
357
|
"resources.resources.detail.back": "Zurück zu Ressourcen",
|
|
358
|
+
"resources.resources.detail.formTitle": "Ressourceneinstellungen",
|
|
352
359
|
"resources.resources.detail.inline.cancel": "Stornieren",
|
|
353
360
|
"resources.resources.detail.inline.clear": "Klar",
|
|
354
361
|
"resources.resources.detail.inline.emailChecking": "Suche nach übereinstimmenden Datensätzen...",
|
|
@@ -435,13 +442,63 @@
|
|
|
435
442
|
"resources.resources.detail.tabs.notes": "Notizen",
|
|
436
443
|
"resources.resources.detail.untitled": "Unbenannte Ressource",
|
|
437
444
|
"resources.resources.flash.createdAvailability": "Gespeichert. Du kannst jetzt die Verfügbarkeit festlegen.",
|
|
445
|
+
"resources.resources.form.actions.create": "Erstellen",
|
|
446
|
+
"resources.resources.form.appearance.colorClear": "Farbe entfernen",
|
|
447
|
+
"resources.resources.form.appearance.colorHelp": "Wählen Sie eine Farbe für diese Ressource.",
|
|
448
|
+
"resources.resources.form.appearance.colorLabel": "Farbe",
|
|
449
|
+
"resources.resources.form.appearance.iconClear": "Symbol entfernen",
|
|
450
|
+
"resources.resources.form.appearance.iconLabel": "Symbol",
|
|
451
|
+
"resources.resources.form.appearance.iconPicker": "Symbole durchsuchen",
|
|
452
|
+
"resources.resources.form.appearance.iconPlaceholder": "Emoji oder Symbolname eingeben",
|
|
453
|
+
"resources.resources.form.appearance.iconSearch": "Symbole oder Emojis suchen…",
|
|
454
|
+
"resources.resources.form.appearance.iconSearchEmpty": "Keine Symbole entsprechen Ihrer Suche",
|
|
455
|
+
"resources.resources.form.appearance.iconSuggestions": "Vorschläge",
|
|
456
|
+
"resources.resources.form.appearance.label": "Darstellung",
|
|
457
|
+
"resources.resources.form.appearance.previewEmpty": "Keine Darstellung ausgewählt",
|
|
458
|
+
"resources.resources.form.createTitle": "Ressource erstellen",
|
|
459
|
+
"resources.resources.form.editTitle": "Ressource bearbeiten",
|
|
460
|
+
"resources.resources.form.errors.create": "Ressource konnte nicht erstellt werden.",
|
|
461
|
+
"resources.resources.form.errors.delete": "Ressource konnte nicht gelöscht werden.",
|
|
462
|
+
"resources.resources.form.errors.load": "Ressource konnte nicht geladen werden.",
|
|
463
|
+
"resources.resources.form.errors.nameRequired": "Ressourcenname ist erforderlich.",
|
|
464
|
+
"resources.resources.form.errors.notFound": "Ressource nicht gefunden.",
|
|
465
|
+
"resources.resources.form.errors.update": "Ressource konnte nicht aktualisiert werden.",
|
|
466
|
+
"resources.resources.form.fields.active": "Aktiv",
|
|
467
|
+
"resources.resources.form.fields.capacity": "Kapazität",
|
|
438
468
|
"resources.resources.form.fields.capacity.help": "Hängt von der Ressource ab und kann Plätze, Einheiten, Menge oder eine andere Kapazitätsart bedeuten.",
|
|
439
469
|
"resources.resources.form.fields.capacityUnit": "Kapazitätseinheit",
|
|
440
470
|
"resources.resources.form.fields.capacityUnit.missing": "Das Kapazitätseinheiten-Wörterbuch ist nicht konfiguriert.",
|
|
471
|
+
"resources.resources.form.fields.description": "Beschreibung",
|
|
472
|
+
"resources.resources.form.fields.name": "Name",
|
|
473
|
+
"resources.resources.form.fields.type": "Ressourcentyp",
|
|
441
474
|
"resources.resources.form.fields.type.add": "Ressourcentyp hinzufügen",
|
|
442
475
|
"resources.resources.form.fields.type.manage": "Ressourcentypen verwalten",
|
|
476
|
+
"resources.resources.form.flash.deleted": "Ressource gelöscht.",
|
|
477
|
+
"resources.resources.form.flash.updated": "Ressource aktualisiert.",
|
|
478
|
+
"resources.resources.form.loading": "Ressource wird geladen…",
|
|
479
|
+
"resources.resources.list.actions.create": "Erstellen",
|
|
480
|
+
"resources.resources.list.columns.active": "Aktiv",
|
|
481
|
+
"resources.resources.list.columns.appearance": "Darstellung",
|
|
482
|
+
"resources.resources.list.columns.capacity": "Kapazität",
|
|
483
|
+
"resources.resources.list.columns.capacity.empty": "Nicht festgelegt",
|
|
484
|
+
"resources.resources.list.columns.name": "Name",
|
|
485
|
+
"resources.resources.list.columns.tags": "Tags",
|
|
486
|
+
"resources.resources.list.columns.tags.empty": "Keine Tags",
|
|
487
|
+
"resources.resources.list.columns.type": "Type",
|
|
488
|
+
"resources.resources.list.columns.type.empty": "Kein Typ",
|
|
489
|
+
"resources.resources.list.confirmDelete": "Diese Ressource löschen? Kann nicht rückgängig gemacht werden.",
|
|
490
|
+
"resources.resources.list.error.delete": "Ressource konnte nicht gelöscht werden.",
|
|
491
|
+
"resources.resources.list.error.load": "Ressourcen konnten nicht geladen werden.",
|
|
443
492
|
"resources.resources.list.filters.resourceType": "Ressourcentyp",
|
|
444
493
|
"resources.resources.list.filters.tags": "Schlagworte",
|
|
494
|
+
"resources.resources.list.flash.deleted": "Ressource gelöscht.",
|
|
495
|
+
"resources.resources.list.group.unassigned": "Nicht zugewiesen",
|
|
496
|
+
"resources.resources.list.group.unknown": "Unbekannt",
|
|
497
|
+
"resources.resources.page.title": "Ressourcen",
|
|
498
|
+
"resources.resources.schedule.actions.details": "Details anzeigen",
|
|
499
|
+
"resources.resources.tabs.availability": "Verfügbarkeit",
|
|
500
|
+
"resources.resources.tabs.details": "Details",
|
|
501
|
+
"resources.resources.tabs.label": "Ressourcenbereiche",
|
|
445
502
|
"resources.resources.tags.cancelShortcut": "Abbrechen (Esc)",
|
|
446
503
|
"resources.resources.tags.createError": "Tag konnte nicht erstellt werden.",
|
|
447
504
|
"resources.resources.tags.errors.invalid": "Ungültige Tag-Daten",
|