@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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/auth/components/AclEditor.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport Link from 'next/link'\nimport { hasFeature, matchFeature } from '@open-mercato/shared/security/features'\n\nfunction toTitleCase(value: string): string {\n return value.replace(/[-_.]/g, ' ').replace(/\\b\\w/g, (char) => char.toUpperCase())\n}\n\nfunction normalizeFeatureArray(input: unknown): string[] {\n if (!Array.isArray(input)) return []\n const dedup = new Set<string>()\n for (const value of input) {\n if (typeof value !== 'string') continue\n const trimmed = value.trim()\n if (!trimmed) continue\n dedup.add(trimmed)\n }\n return Array.from(dedup)\n}\n\nfunction isTenantRestrictedFeature(feature: string): boolean {\n if (feature === '*' || feature === 'directory.*') return true\n if (feature.startsWith('directory.tenants')) return true\n return false\n}\n\nfunction formatWildcardLabel(moduleId: string, wildcard: string): string {\n if (!wildcard.endsWith('.*')) return wildcard\n const prefix = `${moduleId}.`\n const suffix = wildcard.startsWith(prefix) ? wildcard.slice(prefix.length, -2) : wildcard.slice(0, -2)\n if (!suffix) return 'All features'\n return `All ${suffix.split('.').map(toTitleCase).join(' / ')}`\n}\n\ntype Feature = { id: string; title: string; module: string }\ntype ModuleInfo = { id: string; title: string }\ntype RoleListItem = { id?: string | null; name?: string | null }\ntype RoleListResponse = { items?: RoleListItem[] }\ntype RoleSummary = { id: string; name: string }\n\nfunction buildRoleSummaries(items: RoleListItem[], allowedNames: string[]): RoleSummary[] {\n const summaries: RoleSummary[] = []\n for (const role of items) {\n const name = typeof role?.name === 'string' ? role.name : ''\n if (!name || !allowedNames.includes(name)) continue\n const hasValidId = typeof role?.id === 'string' && role.id.length > 0\n const id = hasValidId ? (role!.id as string) : name\n summaries.push({ id, name })\n }\n return summaries\n}\n\nexport type AclData = {\n isSuperAdmin: boolean\n features: string[]\n organizations: string[] | null\n}\n\ntype FeatureListResponse = { items?: Feature[]; modules?: ModuleInfo[] }\ntype AclPayload = {\n hasCustomAcl?: boolean\n isSuperAdmin?: boolean\n features?: unknown\n organizations?: unknown\n}\ntype OrganizationListResponse = { items?: Array<{ id?: string; name?: string }> }\n\nfunction normalizeOrganizationOptions(items: OrganizationListResponse['items']): Array<{ id: string; name: string }> {\n if (!Array.isArray(items)) return []\n return items.reduce<Array<{ id: string; name: string }>>((acc, org) => {\n if (!org) return acc\n const id = typeof org.id === 'string' && org.id.trim().length > 0 ? org.id : null\n if (!id) return acc\n const name = typeof org.name === 'string' && org.name.trim().length > 0 ? org.name : id\n acc.push({ id, name })\n return acc\n }, [])\n}\n\nasync function readJsonOr<T>(\n url: string,\n init: RequestInit | undefined,\n fallback: T,\n): Promise<T> {\n const call = await apiCall<T>(url, init, { fallback })\n if (!call.ok) return fallback\n return call.result ?? fallback\n}\n\nexport function AclEditor({\n kind,\n targetId,\n canEditOrganizations,\n value,\n onChange,\n userRoles,\n currentUserIsSuperAdmin,\n tenantId,\n}: {\n kind: 'user' | 'role'\n targetId: string\n canEditOrganizations: boolean\n value?: AclData\n onChange?: (data: AclData) => void\n userRoles?: string[]\n currentUserIsSuperAdmin?: boolean\n tenantId?: string | null\n}) {\n const actorIsSuperAdmin = !!currentUserIsSuperAdmin\n const [loading, setLoading] = React.useState(true)\n const [features, setFeatures] = React.useState<Feature[]>([])\n const [modules, setModules] = React.useState<ModuleInfo[]>([])\n const [granted, setGranted] = React.useState<string[]>(() => {\n const normalized = normalizeFeatureArray(value?.features)\n return actorIsSuperAdmin ? normalized : normalized.filter((feature) => !isTenantRestrictedFeature(feature))\n })\n const [isSuperAdmin, setIsSuperAdmin] = React.useState(value?.isSuperAdmin || false)\n const [organizations, setOrganizations] = React.useState<string[] | null>(value?.organizations ?? null)\n const [orgOptions, setOrgOptions] = React.useState<{ id: string; name: string }[]>([])\n const [hasCustomAcl, setHasCustomAcl] = React.useState(true)\n const [overrideEnabled, setOverrideEnabled] = React.useState(false)\n const [roleDetails, setRoleDetails] = React.useState<RoleSummary[]>([])\n\n const actorSanitizeFeatures = React.useCallback(\n (list: unknown): string[] => {\n const normalized = normalizeFeatureArray(list)\n if (actorIsSuperAdmin) return normalized\n return normalized.filter((feature) => !isTenantRestrictedFeature(feature))\n },\n [actorIsSuperAdmin],\n )\n\n const updateGranted = React.useCallback(\n (updater: (prev: string[]) => string[]) => {\n setGranted((prev) => actorSanitizeFeatures(updater(prev)))\n },\n [actorSanitizeFeatures],\n )\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setLoading(true)\n try {\n const fJson = await readJsonOr<FeatureListResponse>(\n '/api/auth/features',\n undefined,\n { items: [], modules: [] },\n )\n if (!cancelled) {\n setFeatures(fJson.items || [])\n setModules(fJson.modules || [])\n }\n } catch {}\n try {\n const aclQuery = new URLSearchParams()\n aclQuery.set(kind === 'user' ? 'userId' : 'roleId', targetId)\n if (tenantId) aclQuery.set('tenantId', tenantId)\n const aclQueryString = aclQuery.toString()\n const aclJson = await readJsonOr<AclPayload>(\n `/api/auth/${kind === 'user' ? 'users' : 'roles'}/acl${aclQueryString ? `?${aclQueryString}` : ''}`,\n undefined,\n { hasCustomAcl: true, isSuperAdmin: false, features: [], organizations: null },\n )\n if (!cancelled) {\n const customAclExists = aclJson.hasCustomAcl !== false\n setHasCustomAcl(customAclExists)\n setOverrideEnabled(customAclExists)\n setIsSuperAdmin(!!aclJson.isSuperAdmin)\n setGranted(actorSanitizeFeatures(aclJson.features))\n setOrganizations(aclJson.organizations == null ? null : Array.isArray(aclJson.organizations) ? aclJson.organizations : [])\n }\n } catch {}\n if (canEditOrganizations) {\n try {\n const orgQuery = new URLSearchParams()\n if (tenantId) orgQuery.set('tenantId', tenantId)\n const orgQueryString = orgQuery.toString()\n const oJson = await readJsonOr<OrganizationListResponse>(\n `/api/directory/organizations${orgQueryString ? `?${orgQueryString}` : ''}`,\n undefined,\n { items: [] },\n )\n if (!cancelled) setOrgOptions(normalizeOrganizationOptions(oJson.items))\n } catch {}\n }\n if (kind === 'user' && userRoles && userRoles.length > 0) {\n try {\n const roleQuery = new URLSearchParams({ pageSize: '1000' })\n if (tenantId) roleQuery.set('tenantId', tenantId)\n const roleQueryString = roleQuery.toString()\n const rolesJson = await readJsonOr<RoleListResponse>(\n `/api/auth/roles${roleQueryString ? `?${roleQueryString}` : ''}`,\n undefined,\n { items: [] },\n )\n if (!cancelled) {\n const allRoles = Array.isArray(rolesJson.items) ? rolesJson.items : []\n const userRoleDetails: RoleSummary[] = buildRoleSummaries(allRoles, userRoles)\n setRoleDetails(userRoleDetails)\n }\n } catch {}\n }\n if (!cancelled) setLoading(false)\n }\n load()\n return () => { cancelled = true }\n }, [kind, targetId, canEditOrganizations, userRoles, actorSanitizeFeatures, tenantId])\n\n // Notify parent of changes\n React.useEffect(() => {\n onChange?.({ isSuperAdmin, features: granted, organizations })\n }, [isSuperAdmin, granted, organizations, onChange])\n\n const grouped = React.useMemo(() => {\n const moduleMap = new Map<string, string>()\n for (const m of modules) {\n moduleMap.set(m.id, m.title)\n }\n const map = new Map<string, { moduleId: string; moduleTitle: string; features: Feature[] }>()\n for (const f of features) {\n const moduleId = f.module\n const moduleTitle = moduleMap.get(moduleId) || moduleId\n if (!map.has(moduleId)) {\n map.set(moduleId, { moduleId, moduleTitle, features: [] })\n }\n map.get(moduleId)!.features.push(f)\n }\n return Array.from(map.values()).sort((a, b) => a.moduleTitle.localeCompare(b.moduleTitle))\n }, [features, modules])\n\n const hasGlobalWildcard = granted.includes('*')\n const hasOrganizationRestriction = Array.isArray(organizations) && organizations.length > 0\n const showOrganizationWarning =\n (kind === 'role' || overrideEnabled) &&\n canEditOrganizations &&\n !isSuperAdmin &&\n hasOrganizationRestriction &&\n granted.length === 0\n\n \n const toggleWildcard = React.useCallback((wildcard: string, enable: boolean) => {\n if (!actorIsSuperAdmin && enable && isTenantRestrictedFeature(wildcard)) return\n updateGranted((prev) => {\n if (enable) {\n if (prev.includes(wildcard)) return prev\n return [...prev, wildcard]\n }\n return prev.filter((feature) => feature !== wildcard)\n })\n }, [actorIsSuperAdmin, updateGranted])\n\n const toggleModuleWildcard = React.useCallback((moduleId: string, enable: boolean) => {\n toggleWildcard(`${moduleId}.*`, enable)\n }, [toggleWildcard])\n\n const isModuleWildcardEnabled = (moduleId: string) => {\n return granted.includes(`${moduleId}.*`)\n }\n\n const isFeatureCoveredByWildcard = (featureId: string) =>\n granted.some((feature) => (feature === '*' || feature.endsWith('.*')) && matchFeature(featureId, feature))\n\n const isFeatureChecked = (featureId: string) => hasFeature(granted, featureId)\n\n if (loading) return <div className=\"text-sm text-muted-foreground\">Loading ACL\u2026</div>\n\n const showRoleBanner = kind === 'user' && !hasCustomAcl && !overrideEnabled\n\n return (\n <div className=\"space-y-4\">\n {showRoleBanner && (\n <div className=\"rounded-lg border border-blue-200 bg-blue-50 p-4\">\n <div className=\"text-sm font-medium text-blue-900 mb-2\">\n Permissions inherited from roles\n </div>\n <div className=\"text-sm text-blue-700 mb-3\">\n This user currently inherits permissions from their assigned roles.\n {roleDetails.length > 0 && (\n <span>\n {' '}Assigned roles:{' '}\n {roleDetails.map((role, idx) => {\n const roleId = typeof role?.id === 'string' && role.id.length > 0 ? role.id : `role-${idx}`\n const roleName = typeof role?.name === 'string' && role.name.length > 0 ? role.name : roleId\n return (\n <React.Fragment key={roleId}>\n {idx > 0 && ', '}\n <Link \n href={`/backend/roles/${roleId}/edit`}\n className=\"font-semibold text-blue-900 underline hover:text-blue-950 transition-colors\"\n >\n {roleName}\n </Link>\n </React.Fragment>\n )\n })}\n </span>\n )}\n </div>\n <div className=\"flex items-center gap-2\">\n <input \n id=\"overrideAcl\" \n type=\"checkbox\" \n className=\"h-4 w-4\" \n checked={overrideEnabled} \n onChange={(e) => setOverrideEnabled(e.target.checked)} \n />\n <label htmlFor=\"overrideAcl\" className=\"text-sm text-blue-900 font-medium\">\n Override permissions for this user only\n </label>\n </div>\n </div>\n )}\n {(kind === 'role' || overrideEnabled) && (\n <>\n <div className=\"flex items-center gap-2\">\n <input\n id=\"isSuperAdmin\"\n type=\"checkbox\"\n className=\"h-4 w-4\"\n checked={isSuperAdmin}\n disabled={!actorIsSuperAdmin}\n onChange={(e) => setIsSuperAdmin(!!e.target.checked)}\n />\n <label htmlFor=\"isSuperAdmin\" className=\"text-sm\">Super Admin (all features)</label>\n </div>\n {!actorIsSuperAdmin && (\n <p className=\"text-xs text-muted-foreground\">Only super administrators can change this option.</p>\n )}\n {!isSuperAdmin && (\n <>\n {hasGlobalWildcard && (\n <div className=\"rounded border border-blue-200 bg-blue-50 p-3\">\n <div className=\"text-sm font-medium text-blue-900\">Global wildcard (*) enabled</div>\n <div className=\"text-xs text-blue-700 mt-1\">This grants access to all features in the system.</div>\n <Button \n variant=\"outline\" \n size=\"sm\" \n className=\"mt-2\"\n onClick={() => updateGranted((prev) => prev.filter((x) => x !== '*'))}\n >\n Remove global wildcard\n </Button>\n </div>\n )}\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {grouped.map((group) => {\n const moduleWildcard = isModuleWildcardEnabled(group.moduleId)\n const nestedWildcards = Array.from(\n new Set(\n granted.filter(\n (feature) =>\n feature !== '*' &&\n feature.endsWith('.*') &&\n feature.startsWith(`${group.moduleId}.`) &&\n feature !== `${group.moduleId}.*`,\n ),\n ),\n )\n .map((wildcard) => {\n const prefix = wildcard.slice(0, -1)\n const relatedFeatures = group.features.filter((feature) => feature.id.startsWith(prefix))\n return { wildcard, features: relatedFeatures }\n })\n .sort((a, b) => a.wildcard.localeCompare(b.wildcard))\n const nestedCoveredIds = new Set<string>()\n for (const entry of nestedWildcards) {\n for (const feature of entry.features) nestedCoveredIds.add(feature.id)\n }\n const moduleRestricted = !actorIsSuperAdmin && isTenantRestrictedFeature(`${group.moduleId}.*`)\n const moduleCheckboxDisabled = hasGlobalWildcard || moduleRestricted\n return (\n <div key={group.moduleId} className=\"rounded border p-3\">\n <div className=\"flex items-center justify-between mb-3 pb-2 border-b\">\n <div className=\"text-sm font-medium\">{group.moduleTitle}</div>\n <div className=\"flex items-center gap-2\">\n <input \n id={`module-${group.moduleId}`} \n type=\"checkbox\" \n className=\"h-4 w-4\" \n checked={moduleWildcard || hasGlobalWildcard} \n disabled={moduleCheckboxDisabled}\n onChange={(e) => toggleModuleWildcard(group.moduleId, e.target.checked)} \n />\n <label htmlFor={`module-${group.moduleId}`} className=\"text-sm text-muted-foreground\">\n All {moduleWildcard && !hasGlobalWildcard ? <span className=\"font-medium text-blue-600\">({group.moduleId}.*)</span> : ''}\n {moduleRestricted ? <span className=\"ml-2 text-xs font-medium text-muted-foreground\">(manage via super admin)</span> : null}\n </label>\n </div>\n </div>\n {nestedWildcards.length > 0 && (\n <div className=\"space-y-3 mb-3\">\n {nestedWildcards.map(({ wildcard, features: wildcardFeatures }) => {\n const checked = granted.includes(wildcard) || hasGlobalWildcard || moduleWildcard\n const wildcardRestricted = !actorIsSuperAdmin && isTenantRestrictedFeature(wildcard)\n const disabled = hasGlobalWildcard || moduleWildcard || wildcardRestricted\n return (\n <div key={wildcard} className=\"space-y-2\">\n <div className=\"flex items-center gap-2\">\n <input\n id={`wildcard-${wildcard}`}\n type=\"checkbox\"\n className=\"h-4 w-4\"\n checked={checked}\n disabled={disabled}\n onChange={(e) => toggleWildcard(wildcard, !!e.target.checked)}\n />\n <label\n htmlFor={`wildcard-${wildcard}`}\n className={`text-sm ${disabled ? 'text-muted-foreground' : ''}`}\n >\n {formatWildcardLabel(group.moduleId, wildcard)}{' '}\n <span className=\"text-muted-foreground text-xs font-mono\">({wildcard})</span>\n {wildcardRestricted ? <span className=\"ml-2 text-xs font-medium text-muted-foreground\">Restricted</span> : null}\n </label>\n </div>\n {wildcardFeatures.length > 0 && (\n <div className=\"relative ml-6 pl-4 text-sm text-muted-foreground space-y-1\">\n <div className=\"absolute left-0 top-1 bottom-1 w-px bg-border\" aria-hidden />\n {wildcardFeatures.map((wf) => (\n <div key={`${wildcard}-${wf.id}`} className=\"pl-2\">\n <span>\n {wf.title}{' '}\n <span className=\"text-xs font-mono text-muted-foreground\">({wf.id})</span>\n </span>\n </div>\n ))}\n </div>\n )}\n </div>\n )\n })}\n </div>\n )}\n <div className=\"space-y-2\">\n {group.features.map((f) => {\n if (nestedCoveredIds.has(f.id)) return null\n const checked = isFeatureChecked(f.id)\n const isWildcardCovered = isFeatureCoveredByWildcard(f.id)\n const restricted = !actorIsSuperAdmin && isTenantRestrictedFeature(f.id)\n const disabled = isWildcardCovered || restricted\n return (\n <div key={f.id} className=\"flex items-center gap-2\">\n <input\n id={`f-${f.id}`}\n type=\"checkbox\"\n className=\"h-4 w-4\"\n checked={checked}\n disabled={disabled}\n onChange={(e) => {\n const on = !!e.target.checked\n updateGranted((prev) => {\n if (on) return [...prev, f.id]\n return prev.filter((x) => x !== f.id)\n })\n }}\n />\n <label\n htmlFor={`f-${f.id}`}\n className={`text-sm ${disabled ? 'text-muted-foreground' : ''}`}\n >\n {f.title} <span className=\"text-muted-foreground text-xs\">({f.id})</span>\n {restricted ? <span className=\"ml-2 text-xs font-medium text-muted-foreground\">Restricted</span> : null}\n </label>\n </div>\n )\n })}\n </div>\n </div>\n )\n })}\n </div>\n </>\n )}\n {canEditOrganizations && (\n <div className=\"rounded border p-3\">\n <div className=\"text-sm font-medium mb-2\">Organizations scope</div>\n <div className=\"text-xs text-muted-foreground mb-2\">Empty = all organizations. Select one or more to restrict.</div>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-2\">\n {orgOptions.map((o) => {\n const checked = organizations == null ? false : (organizations || []).includes(o.id)\n return (\n <div key={o.id} className=\"flex items-center gap-2\">\n <input id={`org-${o.id}`} type=\"checkbox\" className=\"h-4 w-4\" checked={checked} onChange={(e) => {\n const on = !!e.target.checked\n setOrganizations((prev) => {\n if (prev == null) return on ? [o.id] : []\n return on ? Array.from(new Set([...(prev || []), o.id])) : (prev || []).filter((x) => x !== o.id)\n })\n }} />\n <label htmlFor={`org-${o.id}`} className=\"text-sm\">{o.name}</label>\n </div>\n )\n })}\n </div>\n <div className=\"mt-2\">\n <Button variant=\"outline\" onClick={() => setOrganizations(null)}>Allow all organizations</Button>\n </div>\n {showOrganizationWarning && (\n <div className=\"mt-3 rounded border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900\">\n Organization restrictions are saved only when at least one feature override is selected. Add a feature or enable a module wildcard before saving.\n </div>\n )}\n </div>\n )}\n </>\n )}\n </div>\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport Link from 'next/link'\nimport { hasFeature, matchFeature } from '@open-mercato/shared/security/features'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\nfunction toTitleCase(value: string): string {\n return value.replace(/[-_.]/g, ' ').replace(/\\b\\w/g, (char) => char.toUpperCase())\n}\n\nfunction normalizeFeatureArray(input: unknown): string[] {\n if (!Array.isArray(input)) return []\n const dedup = new Set<string>()\n for (const value of input) {\n if (typeof value !== 'string') continue\n const trimmed = value.trim()\n if (!trimmed) continue\n dedup.add(trimmed)\n }\n return Array.from(dedup)\n}\n\nfunction isTenantRestrictedFeature(feature: string): boolean {\n if (feature === '*' || feature === 'directory.*') return true\n if (feature.startsWith('directory.tenants')) return true\n return false\n}\n\nfunction formatWildcardLabel(moduleId: string, wildcard: string): string {\n if (!wildcard.endsWith('.*')) return wildcard\n const prefix = `${moduleId}.`\n const suffix = wildcard.startsWith(prefix) ? wildcard.slice(prefix.length, -2) : wildcard.slice(0, -2)\n if (!suffix) return 'All features'\n return `All ${suffix.split('.').map(toTitleCase).join(' / ')}`\n}\n\ntype Feature = { id: string; title: string; module: string }\ntype ModuleInfo = { id: string; title: string }\ntype RoleListItem = { id?: string | null; name?: string | null }\ntype RoleListResponse = { items?: RoleListItem[] }\ntype RoleSummary = { id: string; name: string }\n\nfunction buildRoleSummaries(items: RoleListItem[], allowedNames: string[]): RoleSummary[] {\n const summaries: RoleSummary[] = []\n for (const role of items) {\n const name = typeof role?.name === 'string' ? role.name : ''\n if (!name || !allowedNames.includes(name)) continue\n const hasValidId = typeof role?.id === 'string' && role.id.length > 0\n const id = hasValidId ? (role!.id as string) : name\n summaries.push({ id, name })\n }\n return summaries\n}\n\nexport type AclData = {\n isSuperAdmin: boolean\n features: string[]\n organizations: string[] | null\n}\n\ntype FeatureListResponse = { items?: Feature[]; modules?: ModuleInfo[] }\ntype AclPayload = {\n hasCustomAcl?: boolean\n isSuperAdmin?: boolean\n features?: unknown\n organizations?: unknown\n}\ntype OrganizationListResponse = { items?: Array<{ id?: string; name?: string }> }\n\nfunction normalizeOrganizationOptions(items: OrganizationListResponse['items']): Array<{ id: string; name: string }> {\n if (!Array.isArray(items)) return []\n return items.reduce<Array<{ id: string; name: string }>>((acc, org) => {\n if (!org) return acc\n const id = typeof org.id === 'string' && org.id.trim().length > 0 ? org.id : null\n if (!id) return acc\n const name = typeof org.name === 'string' && org.name.trim().length > 0 ? org.name : id\n acc.push({ id, name })\n return acc\n }, [])\n}\n\nasync function readJsonOr<T>(\n url: string,\n init: RequestInit | undefined,\n fallback: T,\n): Promise<T> {\n const call = await apiCall<T>(url, init, { fallback })\n if (!call.ok) return fallback\n return call.result ?? fallback\n}\n\nexport function AclEditor({\n kind,\n targetId,\n canEditOrganizations,\n value,\n onChange,\n userRoles,\n currentUserIsSuperAdmin,\n tenantId,\n}: {\n kind: 'user' | 'role'\n targetId: string\n canEditOrganizations: boolean\n value?: AclData\n onChange?: (data: AclData) => void\n userRoles?: string[]\n currentUserIsSuperAdmin?: boolean\n tenantId?: string | null\n}) {\n const actorIsSuperAdmin = !!currentUserIsSuperAdmin\n const [loading, setLoading] = React.useState(true)\n const [features, setFeatures] = React.useState<Feature[]>([])\n const t = useT()\n const [modules, setModules] = React.useState<ModuleInfo[]>([])\n const [granted, setGranted] = React.useState<string[]>(() => {\n const normalized = normalizeFeatureArray(value?.features)\n return actorIsSuperAdmin ? normalized : normalized.filter((feature) => !isTenantRestrictedFeature(feature))\n })\n const [isSuperAdmin, setIsSuperAdmin] = React.useState(value?.isSuperAdmin || false)\n const [organizations, setOrganizations] = React.useState<string[] | null>(value?.organizations ?? null)\n const [orgOptions, setOrgOptions] = React.useState<{ id: string; name: string }[]>([])\n const [hasCustomAcl, setHasCustomAcl] = React.useState(true)\n const [overrideEnabled, setOverrideEnabled] = React.useState(false)\n const [roleDetails, setRoleDetails] = React.useState<RoleSummary[]>([])\n\n const actorSanitizeFeatures = React.useCallback(\n (list: unknown): string[] => {\n const normalized = normalizeFeatureArray(list)\n if (actorIsSuperAdmin) return normalized\n return normalized.filter((feature) => !isTenantRestrictedFeature(feature))\n },\n [actorIsSuperAdmin],\n )\n\n const updateGranted = React.useCallback(\n (updater: (prev: string[]) => string[]) => {\n setGranted((prev) => actorSanitizeFeatures(updater(prev)))\n },\n [actorSanitizeFeatures],\n )\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setLoading(true)\n try {\n const fJson = await readJsonOr<FeatureListResponse>(\n '/api/auth/features',\n undefined,\n { items: [], modules: [] },\n )\n if (!cancelled) {\n setFeatures(fJson.items || [])\n setModules(fJson.modules || [])\n }\n } catch {}\n try {\n const aclQuery = new URLSearchParams()\n aclQuery.set(kind === 'user' ? 'userId' : 'roleId', targetId)\n if (tenantId) aclQuery.set('tenantId', tenantId)\n const aclQueryString = aclQuery.toString()\n const aclJson = await readJsonOr<AclPayload>(\n `/api/auth/${kind === 'user' ? 'users' : 'roles'}/acl${aclQueryString ? `?${aclQueryString}` : ''}`,\n undefined,\n { hasCustomAcl: true, isSuperAdmin: false, features: [], organizations: null },\n )\n if (!cancelled) {\n const customAclExists = aclJson.hasCustomAcl !== false\n setHasCustomAcl(customAclExists)\n setOverrideEnabled(customAclExists)\n setIsSuperAdmin(!!aclJson.isSuperAdmin)\n setGranted(actorSanitizeFeatures(aclJson.features))\n setOrganizations(aclJson.organizations == null ? null : Array.isArray(aclJson.organizations) ? aclJson.organizations : [])\n }\n } catch {}\n if (canEditOrganizations) {\n try {\n const orgQuery = new URLSearchParams()\n if (tenantId) orgQuery.set('tenantId', tenantId)\n const orgQueryString = orgQuery.toString()\n const oJson = await readJsonOr<OrganizationListResponse>(\n `/api/directory/organizations${orgQueryString ? `?${orgQueryString}` : ''}`,\n undefined,\n { items: [] },\n )\n if (!cancelled) setOrgOptions(normalizeOrganizationOptions(oJson.items))\n } catch {}\n }\n if (kind === 'user' && userRoles && userRoles.length > 0) {\n try {\n const roleQuery = new URLSearchParams({ pageSize: '1000' })\n if (tenantId) roleQuery.set('tenantId', tenantId)\n const roleQueryString = roleQuery.toString()\n const rolesJson = await readJsonOr<RoleListResponse>(\n `/api/auth/roles${roleQueryString ? `?${roleQueryString}` : ''}`,\n undefined,\n { items: [] },\n )\n if (!cancelled) {\n const allRoles = Array.isArray(rolesJson.items) ? rolesJson.items : []\n const userRoleDetails: RoleSummary[] = buildRoleSummaries(allRoles, userRoles)\n setRoleDetails(userRoleDetails)\n }\n } catch {}\n }\n if (!cancelled) setLoading(false)\n }\n load()\n return () => { cancelled = true }\n }, [kind, targetId, canEditOrganizations, userRoles, actorSanitizeFeatures, tenantId])\n\n // Notify parent of changes\n React.useEffect(() => {\n onChange?.({ isSuperAdmin, features: granted, organizations })\n }, [isSuperAdmin, granted, organizations, onChange])\n\n const grouped = React.useMemo(() => {\n const moduleMap = new Map<string, string>()\n for (const m of modules) {\n moduleMap.set(m.id, m.title)\n }\n const map = new Map<string, { moduleId: string; moduleTitle: string; features: Feature[] }>()\n for (const f of features) {\n const moduleId = f.module\n const moduleTitle = moduleMap.get(moduleId) || moduleId\n if (!map.has(moduleId)) {\n map.set(moduleId, { moduleId, moduleTitle, features: [] })\n }\n map.get(moduleId)!.features.push(f)\n }\n return Array.from(map.values()).sort((a, b) => a.moduleTitle.localeCompare(b.moduleTitle))\n }, [features, modules])\n\n const hasGlobalWildcard = granted.includes('*')\n const hasOrganizationRestriction = Array.isArray(organizations) && organizations.length > 0\n const showOrganizationWarning =\n (kind === 'role' || overrideEnabled) &&\n canEditOrganizations &&\n !isSuperAdmin &&\n hasOrganizationRestriction &&\n granted.length === 0\n\n \n const toggleWildcard = React.useCallback((wildcard: string, enable: boolean) => {\n if (!actorIsSuperAdmin && enable && isTenantRestrictedFeature(wildcard)) return\n updateGranted((prev) => {\n if (enable) {\n if (prev.includes(wildcard)) return prev\n return [...prev, wildcard]\n }\n return prev.filter((feature) => feature !== wildcard)\n })\n }, [actorIsSuperAdmin, updateGranted])\n\n const toggleModuleWildcard = React.useCallback((moduleId: string, enable: boolean) => {\n toggleWildcard(`${moduleId}.*`, enable)\n }, [toggleWildcard])\n\n const isModuleWildcardEnabled = (moduleId: string) => {\n return granted.includes(`${moduleId}.*`)\n }\n\n const isFeatureCoveredByWildcard = (featureId: string) =>\n granted.some((feature) => (feature === '*' || feature.endsWith('.*')) && matchFeature(featureId, feature))\n\n const isFeatureChecked = (featureId: string) => hasFeature(granted, featureId)\n\n if (loading) return <div className=\"text-sm text-muted-foreground\">Loading ACL\u2026</div>\n\n const showRoleBanner = kind === 'user' && !hasCustomAcl && !overrideEnabled\n\n return (\n <div className=\"space-y-4\">\n {showRoleBanner && (\n <div className=\"rounded-lg border border-blue-200 bg-blue-50 p-4\">\n <div className=\"text-sm font-medium text-blue-900 mb-2\">\n Permissions inherited from roles\n </div>\n <div className=\"text-sm text-blue-700 mb-3\">\n This user currently inherits permissions from their assigned roles.\n {roleDetails.length > 0 && (\n <span>\n {' '}Assigned roles:{' '}\n {roleDetails.map((role, idx) => {\n const roleId = typeof role?.id === 'string' && role.id.length > 0 ? role.id : `role-${idx}`\n const roleName = typeof role?.name === 'string' && role.name.length > 0 ? role.name : roleId\n return (\n <React.Fragment key={roleId}>\n {idx > 0 && ', '}\n <Link \n href={`/backend/roles/${roleId}/edit`}\n className=\"font-semibold text-blue-900 underline hover:text-blue-950 transition-colors\"\n >\n {roleName}\n </Link>\n </React.Fragment>\n )\n })}\n </span>\n )}\n </div>\n <div className=\"flex items-center gap-2\">\n <input \n id=\"overrideAcl\" \n type=\"checkbox\" \n className=\"h-4 w-4\" \n checked={overrideEnabled} \n onChange={(e) => setOverrideEnabled(e.target.checked)} \n />\n <label htmlFor=\"overrideAcl\" className=\"text-sm text-blue-900 font-medium\">\n Override permissions for this user only\n </label>\n </div>\n </div>\n )}\n {(kind === 'role' || overrideEnabled) && (\n <>\n <div className=\"flex items-center gap-2\">\n <input\n id=\"isSuperAdmin\"\n type=\"checkbox\"\n className=\"h-4 w-4\"\n checked={isSuperAdmin}\n disabled={!actorIsSuperAdmin}\n onChange={(e) => setIsSuperAdmin(!!e.target.checked)}\n />\n <label htmlFor=\"isSuperAdmin\" className=\"text-sm\">Super Admin (all features)</label>\n </div>\n {!actorIsSuperAdmin && (\n <p className=\"text-xs text-muted-foreground\">Only super administrators can change this option.</p>\n )}\n {!isSuperAdmin && (\n <>\n {hasGlobalWildcard && (\n <div className=\"rounded border border-blue-200 bg-blue-50 p-3\">\n <div className=\"text-sm font-medium text-blue-900\">Global wildcard (*) enabled</div>\n <div className=\"text-xs text-blue-700 mt-1\">This grants access to all features in the system.</div>\n <Button \n variant=\"outline\" \n size=\"sm\" \n className=\"mt-2\"\n onClick={() => updateGranted((prev) => prev.filter((x) => x !== '*'))}\n >\n Remove global wildcard\n </Button>\n </div>\n )}\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {grouped.map((group) => {\n const moduleWildcard = isModuleWildcardEnabled(group.moduleId)\n const nestedWildcards = Array.from(\n new Set(\n granted.filter(\n (feature) =>\n feature !== '*' &&\n feature.endsWith('.*') &&\n feature.startsWith(`${group.moduleId}.`) &&\n feature !== `${group.moduleId}.*`,\n ),\n ),\n )\n .map((wildcard) => {\n const prefix = wildcard.slice(0, -1)\n const relatedFeatures = group.features.filter((feature) => feature.id.startsWith(prefix))\n return { wildcard, features: relatedFeatures }\n })\n .sort((a, b) => a.wildcard.localeCompare(b.wildcard))\n const nestedCoveredIds = new Set<string>()\n for (const entry of nestedWildcards) {\n for (const feature of entry.features) nestedCoveredIds.add(feature.id)\n }\n const moduleRestricted = !actorIsSuperAdmin && isTenantRestrictedFeature(`${group.moduleId}.*`)\n const moduleCheckboxDisabled = hasGlobalWildcard || moduleRestricted\n return (\n <div key={group.moduleId} className=\"rounded border p-3\">\n <div className=\"flex items-center justify-between mb-3 pb-2 border-b\">\n <div className=\"text-sm font-medium\">{group.moduleTitle}</div>\n <div className=\"flex items-center gap-2\">\n <input \n id={`module-${group.moduleId}`} \n type=\"checkbox\" \n className=\"h-4 w-4\" \n checked={moduleWildcard || hasGlobalWildcard} \n disabled={moduleCheckboxDisabled}\n onChange={(e) => toggleModuleWildcard(group.moduleId, e.target.checked)} \n />\n <label htmlFor={`module-${group.moduleId}`} className=\"text-sm text-muted-foreground\">\n All {moduleWildcard && !hasGlobalWildcard ? <span className=\"font-medium text-blue-600\">({group.moduleId}.*)</span> : ''}\n {moduleRestricted ? <span className=\"ml-2 text-xs font-medium text-muted-foreground\">(manage via super admin)</span> : null}\n </label>\n </div>\n </div>\n {nestedWildcards.length > 0 && (\n <div className=\"space-y-3 mb-3\">\n {nestedWildcards.map(({ wildcard, features: wildcardFeatures }) => {\n const checked = granted.includes(wildcard) || hasGlobalWildcard || moduleWildcard\n const wildcardRestricted = !actorIsSuperAdmin && isTenantRestrictedFeature(wildcard)\n const disabled = hasGlobalWildcard || moduleWildcard || wildcardRestricted\n return (\n <div key={wildcard} className=\"space-y-2\">\n <div className=\"flex items-center gap-2\">\n <input\n id={`wildcard-${wildcard}`}\n type=\"checkbox\"\n className=\"h-4 w-4\"\n checked={checked}\n disabled={disabled}\n onChange={(e) => toggleWildcard(wildcard, !!e.target.checked)}\n />\n <label\n htmlFor={`wildcard-${wildcard}`}\n className={`text-sm ${disabled ? 'text-muted-foreground' : ''}`}\n >\n {formatWildcardLabel(group.moduleId, wildcard)}{' '}\n <span className=\"text-muted-foreground text-xs font-mono\">({wildcard})</span>\n {wildcardRestricted ? <span className=\"ml-2 text-xs font-medium text-muted-foreground\">Restricted</span> : null}\n </label>\n </div>\n {wildcardFeatures.length > 0 && (\n <div className=\"relative ml-6 pl-4 text-sm text-muted-foreground space-y-1\">\n <div className=\"absolute left-0 top-1 bottom-1 w-px bg-border\" aria-hidden />\n {wildcardFeatures.map((wf) => (\n <div key={`${wildcard}-${wf.id}`} className=\"pl-2\">\n <span>\n {wf.title}{' '}\n <span className=\"text-xs font-mono text-muted-foreground\">({wf.id})</span>\n </span>\n </div>\n ))}\n </div>\n )}\n </div>\n )\n })}\n </div>\n )}\n <div className=\"space-y-2\">\n {group.features.map((f) => {\n if (nestedCoveredIds.has(f.id)) return null\n const checked = isFeatureChecked(f.id)\n const isWildcardCovered = isFeatureCoveredByWildcard(f.id)\n const restricted = !actorIsSuperAdmin && isTenantRestrictedFeature(f.id)\n const disabled = isWildcardCovered || restricted\n return (\n <div key={f.id} className=\"flex items-center gap-2\">\n <input\n id={`f-${f.id}`}\n type=\"checkbox\"\n className=\"h-4 w-4\"\n checked={checked}\n disabled={disabled}\n onChange={(e) => {\n const on = !!e.target.checked\n updateGranted((prev) => {\n if (on) return [...prev, f.id]\n return prev.filter((x) => x !== f.id)\n })\n }}\n />\n <label\n htmlFor={`f-${f.id}`}\n className={`text-sm ${disabled ? 'text-muted-foreground' : ''}`}\n >\n {f.title} <span className=\"text-muted-foreground text-xs\">({f.id})</span>\n {restricted ? <span className=\"ml-2 text-xs font-medium text-muted-foreground\">Restricted</span> : null}\n </label>\n </div>\n )\n })}\n </div>\n </div>\n )\n })}\n </div>\n </>\n )}\n {canEditOrganizations && (\n <div className=\"rounded border p-3\">\n <div className=\"text-sm font-medium mb-2\">Organizations scope</div>\n <div className=\"text-xs text-muted-foreground mb-2\">Empty = all organizations. Select one or more to restrict.</div>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-2\">\n {orgOptions.map((o) => {\n const checked = organizations == null ? false : (organizations || []).includes(o.id)\n return (\n <div key={o.id} className=\"flex items-center gap-2\">\n <input id={`org-${o.id}`} type=\"checkbox\" className=\"h-4 w-4\" checked={checked} onChange={(e) => {\n const on = !!e.target.checked\n setOrganizations((prev) => {\n if (prev == null) return on ? [o.id] : []\n return on ? Array.from(new Set([...(prev || []), o.id])) : (prev || []).filter((x) => x !== o.id)\n })\n }} />\n <label htmlFor={`org-${o.id}`} className=\"text-sm\">{o.name}</label>\n </div>\n )\n })}\n </div>\n <div className=\"mt-2\">\n <Button variant=\"outline\" onClick={() => setOrganizations(null)}>{t('auth.acl.allowAllOrganizations', 'Allow all organizations')}</Button>\n </div>\n {showOrganizationWarning && (\n <div className=\"mt-3 rounded border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900\">\n {t('auth.acl.organizationWarning', 'Organization restrictions are saved only when at least one feature override is selected. Add a feature or enable a module wildcard before saving.')}\n </div>\n )}\n </div>\n )}\n </>\n )}\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -20,7 +20,7 @@ function ResetPage() {
|
|
|
20
20
|
const res = await fetch("/api/auth/reset", { method: "POST", body: form });
|
|
21
21
|
if (!res.ok) {
|
|
22
22
|
const data = await res.json().catch(() => null);
|
|
23
|
-
setError(data?.error || "Something went wrong");
|
|
23
|
+
setError(data?.error || t("auth.reset.error", "Something went wrong"));
|
|
24
24
|
return;
|
|
25
25
|
}
|
|
26
26
|
setSent(true);
|
|
@@ -31,9 +31,9 @@ function ResetPage() {
|
|
|
31
31
|
return /* @__PURE__ */ jsx("div", { className: "min-h-svh flex items-center justify-center p-4", children: /* @__PURE__ */ jsxs(Card, { className: "w-full max-w-sm", children: [
|
|
32
32
|
/* @__PURE__ */ jsxs(CardHeader, { children: [
|
|
33
33
|
/* @__PURE__ */ jsx(CardTitle, { children: t("auth.resetPassword") }),
|
|
34
|
-
/* @__PURE__ */ jsx(CardDescription, { children: "Enter your email to receive reset link" })
|
|
34
|
+
/* @__PURE__ */ jsx(CardDescription, { children: t("auth.reset.description", "Enter your email to receive reset link") })
|
|
35
35
|
] }),
|
|
36
|
-
/* @__PURE__ */ jsx(CardContent, { children: sent ? /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: "If an account with that email exists, we sent a reset link. Please check your inbox." }) : /* @__PURE__ */ jsxs("form", { className: "grid gap-3", onSubmit, noValidate: true, children: [
|
|
36
|
+
/* @__PURE__ */ jsx(CardContent, { children: sent ? /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: t("auth.reset.sent", "If an account with that email exists, we sent a reset link. Please check your inbox.") }) : /* @__PURE__ */ jsxs("form", { className: "grid gap-3", onSubmit, noValidate: true, children: [
|
|
37
37
|
error && /* @__PURE__ */ jsx("div", { className: "text-sm text-red-600", children: error }),
|
|
38
38
|
/* @__PURE__ */ jsxs("div", { className: "grid gap-1", children: [
|
|
39
39
|
/* @__PURE__ */ jsx(Label, { htmlFor: "email", children: t("auth.email") }),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/auth/frontend/reset.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\nimport { useState } from 'react'\nimport { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@open-mercato/ui/primitives/card'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\nexport default function ResetPage() {\n const t = useT()\n const [sent, setSent] = useState(false)\n const [submitting, setSubmitting] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n async function onSubmit(e: React.FormEvent<HTMLFormElement>) {\n e.preventDefault()\n setError(null)\n setSubmitting(true)\n try {\n const form = new FormData(e.currentTarget)\n const res = await fetch('/api/auth/reset', { method: 'POST', body: form })\n if (!res.ok) {\n const data = await res.json().catch(() => null)\n setError(data?.error || 'Something went wrong')\n return\n }\n setSent(true)\n } finally {\n setSubmitting(false)\n }\n }\n\n return (\n <div className=\"min-h-svh flex items-center justify-center p-4\">\n <Card className=\"w-full max-w-sm\">\n <CardHeader>\n <CardTitle>{t('auth.resetPassword')}</CardTitle>\n <CardDescription>Enter your email to receive reset link</CardDescription>\n </CardHeader>\n <CardContent>\n {sent ? (\n <div className=\"text-sm text-muted-foreground\">\n If an account with that email exists, we sent a reset link. Please check your inbox
|
|
5
|
-
"mappings": ";AAmCQ,SACE,KADF;AAlCR,SAAS,gBAAgB;AACzB,SAAS,MAAM,aAAa,YAAY,WAAW,uBAAuB;AAC1E,SAAS,cAAc;AACvB,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,YAAY;AAEN,SAAR,YAA6B;AAClC,QAAM,IAAI,KAAK;AACf,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AAEtD,iBAAe,SAAS,GAAqC;AAC3D,MAAE,eAAe;AACjB,aAAS,IAAI;AACb,kBAAc,IAAI;AAClB,QAAI;AACF,YAAM,OAAO,IAAI,SAAS,EAAE,aAAa;AACzC,YAAM,MAAM,MAAM,MAAM,mBAAmB,EAAE,QAAQ,QAAQ,MAAM,KAAK,CAAC;AACzE,UAAI,CAAC,IAAI,IAAI;AACX,cAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI;AAC9C,iBAAS,MAAM,SAAS,sBAAsB;
|
|
4
|
+
"sourcesContent": ["\"use client\"\nimport { useState } from 'react'\nimport { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@open-mercato/ui/primitives/card'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\nexport default function ResetPage() {\n const t = useT()\n const [sent, setSent] = useState(false)\n const [submitting, setSubmitting] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n async function onSubmit(e: React.FormEvent<HTMLFormElement>) {\n e.preventDefault()\n setError(null)\n setSubmitting(true)\n try {\n const form = new FormData(e.currentTarget)\n const res = await fetch('/api/auth/reset', { method: 'POST', body: form })\n if (!res.ok) {\n const data = await res.json().catch(() => null)\n setError(data?.error || t('auth.reset.error', 'Something went wrong'))\n return\n }\n setSent(true)\n } finally {\n setSubmitting(false)\n }\n }\n\n return (\n <div className=\"min-h-svh flex items-center justify-center p-4\">\n <Card className=\"w-full max-w-sm\">\n <CardHeader>\n <CardTitle>{t('auth.resetPassword')}</CardTitle>\n <CardDescription>{t('auth.reset.description', 'Enter your email to receive reset link')}</CardDescription>\n </CardHeader>\n <CardContent>\n {sent ? (\n <div className=\"text-sm text-muted-foreground\">\n {t('auth.reset.sent', 'If an account with that email exists, we sent a reset link. Please check your inbox.')}\n </div>\n ) : (\n <form className=\"grid gap-3\" onSubmit={onSubmit} noValidate>\n {error && <div className=\"text-sm text-red-600\">{error}</div>}\n <div className=\"grid gap-1\">\n <Label htmlFor=\"email\">{t('auth.email')}</Label>\n <Input id=\"email\" name=\"email\" type=\"email\" required />\n </div>\n <Button type=\"submit\" className=\"mt-2 w-full\" disabled={submitting}>\n {submitting ? '...' : t('auth.sendResetLink')}\n </Button>\n </form>\n )}\n </CardContent>\n </Card>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": ";AAmCQ,SACE,KADF;AAlCR,SAAS,gBAAgB;AACzB,SAAS,MAAM,aAAa,YAAY,WAAW,uBAAuB;AAC1E,SAAS,cAAc;AACvB,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,YAAY;AAEN,SAAR,YAA6B;AAClC,QAAM,IAAI,KAAK;AACf,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AAEtD,iBAAe,SAAS,GAAqC;AAC3D,MAAE,eAAe;AACjB,aAAS,IAAI;AACb,kBAAc,IAAI;AAClB,QAAI;AACF,YAAM,OAAO,IAAI,SAAS,EAAE,aAAa;AACzC,YAAM,MAAM,MAAM,MAAM,mBAAmB,EAAE,QAAQ,QAAQ,MAAM,KAAK,CAAC;AACzE,UAAI,CAAC,IAAI,IAAI;AACX,cAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI;AAC9C,iBAAS,MAAM,SAAS,EAAE,oBAAoB,sBAAsB,CAAC;AACrE;AAAA,MACF;AACA,cAAQ,IAAI;AAAA,IACd,UAAE;AACA,oBAAc,KAAK;AAAA,IACrB;AAAA,EACF;AAEA,SACE,oBAAC,SAAI,WAAU,kDACb,+BAAC,QAAK,WAAU,mBACd;AAAA,yBAAC,cACC;AAAA,0BAAC,aAAW,YAAE,oBAAoB,GAAE;AAAA,MACpC,oBAAC,mBAAiB,YAAE,0BAA0B,wCAAwC,GAAE;AAAA,OAC1F;AAAA,IACA,oBAAC,eACE,iBACC,oBAAC,SAAI,WAAU,iCACZ,YAAE,mBAAmB,sFAAsF,GAC9G,IAEA,qBAAC,UAAK,WAAU,cAAa,UAAoB,YAAU,MACxD;AAAA,eAAS,oBAAC,SAAI,WAAU,wBAAwB,iBAAM;AAAA,MACvD,qBAAC,SAAI,WAAU,cACb;AAAA,4BAAC,SAAM,SAAQ,SAAS,YAAE,YAAY,GAAE;AAAA,QACxC,oBAAC,SAAM,IAAG,SAAQ,MAAK,SAAQ,MAAK,SAAQ,UAAQ,MAAC;AAAA,SACvD;AAAA,MACA,oBAAC,UAAO,MAAK,UAAS,WAAU,eAAc,UAAU,YACrD,uBAAa,QAAQ,EAAE,oBAAoB,GAC9C;AAAA,OACF,GAEJ;AAAA,KACF,GACF;AAEJ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import Link from "next/link";
|
|
5
5
|
import { useRouter } from "next/navigation";
|
|
@@ -8,6 +8,7 @@ import { Page, PageBody } from "@open-mercato/ui/backend/Page";
|
|
|
8
8
|
import { Button } from "@open-mercato/ui/primitives/button";
|
|
9
9
|
import { FormHeader } from "@open-mercato/ui/backend/forms";
|
|
10
10
|
import { VersionHistoryAction } from "@open-mercato/ui/backend/version-history";
|
|
11
|
+
import { SendObjectMessageDialog } from "@open-mercato/ui/backend/messages";
|
|
11
12
|
import { Spinner } from "@open-mercato/ui/primitives/spinner";
|
|
12
13
|
import { flash } from "@open-mercato/ui/backend/FlashMessages";
|
|
13
14
|
import { apiCallOrThrow, readApiResultOrThrow } from "@open-mercato/ui/backend/utils/apiCall";
|
|
@@ -289,13 +290,31 @@ function DealDetailPage({ params }) {
|
|
|
289
290
|
mode: "detail",
|
|
290
291
|
backHref: "/backend/customers/deals",
|
|
291
292
|
backLabel: t("customers.deals.detail.backToList", "Back to deals"),
|
|
292
|
-
utilityActions: /* @__PURE__ */
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
293
|
+
utilityActions: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
294
|
+
/* @__PURE__ */ jsx(
|
|
295
|
+
SendObjectMessageDialog,
|
|
296
|
+
{
|
|
297
|
+
object: {
|
|
298
|
+
entityModule: "customers",
|
|
299
|
+
entityType: "deal",
|
|
300
|
+
entityId: data.deal.id,
|
|
301
|
+
sourceEntityType: "customers.deal",
|
|
302
|
+
sourceEntityId: data.deal.id
|
|
303
|
+
},
|
|
304
|
+
defaultValues: {
|
|
305
|
+
sourceEntityType: "customers.deal",
|
|
306
|
+
sourceEntityId: data.deal.id
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
),
|
|
310
|
+
/* @__PURE__ */ jsx(
|
|
311
|
+
VersionHistoryAction,
|
|
312
|
+
{
|
|
313
|
+
config: { resourceKind: "customers.deal", resourceId: data.deal.id },
|
|
314
|
+
t
|
|
315
|
+
}
|
|
316
|
+
)
|
|
317
|
+
] }),
|
|
299
318
|
title: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
300
319
|
/* @__PURE__ */ jsx("span", { children: data.deal.title || t("customers.deals.detail.untitled", "Untitled deal") }),
|
|
301
320
|
/* @__PURE__ */ jsxs(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../src/modules/customers/backend/customers/deals/%5Bid%5D/page.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { Pencil, MousePointerClick } from 'lucide-react'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { FormHeader } from '@open-mercato/ui/backend/forms'\nimport { VersionHistoryAction } from '@open-mercato/ui/backend/version-history'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { apiCallOrThrow, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { NotesSection, type SectionAction } from '@open-mercato/ui/backend/detail'\nimport { ActivitiesSection } from '../../../../components/detail/ActivitiesSection'\nimport { DealForm, type DealFormSubmitPayload } from '../../../../components/detail/DealForm'\nimport { useCustomerDictionary } from '../../../../components/detail/hooks/useCustomerDictionary'\nimport type { CustomerDictionaryMap } from '../../../../lib/dictionaries'\nimport { createTranslatorWithFallback } from '@open-mercato/shared/lib/i18n/translate'\nimport { renderDictionaryColor, renderDictionaryIcon } from '@open-mercato/core/modules/dictionaries/components/dictionaryAppearance'\nimport { ICON_SUGGESTIONS } from '../../../../lib/dictionaries'\nimport { createCustomerNotesAdapter } from '../../../../components/detail/notesAdapter'\nimport { readMarkdownPreferenceCookie, writeMarkdownPreferenceCookie } from '../../../../lib/markdownPreference'\n\ntype DealAssociation = {\n id: string\n label: string\n subtitle: string | null\n kind: 'person' | 'company'\n}\n\ntype DealDetailPayload = {\n deal: {\n id: string\n title: string\n description: string | null\n status: string | null\n pipelineStage: string | null\n valueAmount: string | null\n valueCurrency: string | null\n probability: number | null\n expectedCloseAt: string | null\n ownerUserId: string | null\n source: string | null\n organizationId: string | null\n tenantId: string | null\n createdAt: string\n updatedAt: string\n }\n people: DealAssociation[]\n companies: DealAssociation[]\n customFields: Record<string, unknown>\n viewer?: {\n userId: string | null\n name?: string | null\n email?: string | null\n } | null\n}\n\nconst CRUD_FOCUSABLE_SELECTOR =\n '[data-crud-focus-target], input:not([type=\"hidden\"]):not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])'\n\nfunction formatCurrency(amount: string | null, currency: string | null): string | null {\n if (!amount) return null\n const value = Number(amount)\n if (!Number.isFinite(value)) return currency ? `${amount} ${currency}` : amount\n if (!currency) return value.toLocaleString()\n try {\n return new Intl.NumberFormat(undefined, { style: 'currency', currency }).format(value)\n } catch {\n return `${value.toLocaleString()} ${currency}`\n }\n}\n\nfunction formatDate(value: string | null, fallback: string): string {\n if (!value) return fallback\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return fallback\n return date.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' })\n}\n\nfunction resolveDictionaryLabel(\n value: string | null | undefined,\n map: CustomerDictionaryMap | null | undefined,\n): string | null {\n if (!value) return null\n const entry = map?.[value]\n if (entry && entry.label && entry.label.length) return entry.label\n return value\n}\n\nexport default function DealDetailPage({ params }: { params?: { id?: string } }) {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const detailTranslator = React.useMemo(() => createTranslatorWithFallback(t), [t])\n const notesAdapter = React.useMemo(() => createCustomerNotesAdapter(detailTranslator), [detailTranslator])\n const router = useRouter()\n const id = params?.id ?? ''\n const scopeVersion = useOrganizationScopeVersion()\n const statusDictionaryQuery = useCustomerDictionary('deal-statuses', scopeVersion)\n const pipelineDictionaryQuery = useCustomerDictionary('pipeline-stages', scopeVersion)\n const statusDictionaryMap = statusDictionaryQuery.data?.map ?? null\n const pipelineDictionaryMap = pipelineDictionaryQuery.data?.map ?? null\n const [data, setData] = React.useState<DealDetailPayload | null>(null)\n const [isLoading, setIsLoading] = React.useState(true)\n const [error, setError] = React.useState<string | null>(null)\n const [isSaving, setIsSaving] = React.useState(false)\n const [isDeleting, setIsDeleting] = React.useState(false)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [activeTab, setActiveTab] = React.useState<'notes' | 'activities'>('notes')\n const [sectionAction, setSectionAction] = React.useState<SectionAction | null>(null)\n const handleNotesLoadingChange = React.useCallback(() => {}, [])\n const handleActivitiesLoadingChange = React.useCallback(() => {}, [])\n const focusDealField = React.useCallback(\n (fieldId: 'title' | 'personIds' | 'companyIds') => {\n if (typeof window === 'undefined' || typeof document === 'undefined') return\n const focusOnce = () => {\n const container = document.querySelector<HTMLElement>(`[data-crud-field-id=\"${fieldId}\"]`)\n if (!container) return false\n const target =\n container.querySelector<HTMLElement>(CRUD_FOCUSABLE_SELECTOR) ?? container\n if (!target || typeof target.focus !== 'function') return false\n if (typeof container.scrollIntoView === 'function') {\n container.scrollIntoView({ behavior: 'smooth', block: 'center' })\n }\n target.focus()\n if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {\n try {\n target.select()\n } catch {}\n }\n return true\n }\n\n const schedule = () => {\n const focused = focusOnce()\n if (focused) return\n window.setTimeout(() => {\n focusOnce()\n }, 60)\n }\n\n if (typeof window.requestAnimationFrame === 'function') {\n window.requestAnimationFrame(schedule)\n } else {\n schedule()\n }\n },\n [],\n )\n const dealSettingsRef = React.useRef<HTMLDivElement | null>(null)\n const scrollToDealSettings = React.useCallback(() => {\n if (typeof window === 'undefined') return\n if (dealSettingsRef.current && typeof dealSettingsRef.current.scrollIntoView === 'function') {\n dealSettingsRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' })\n }\n window.setTimeout(() => {\n focusDealField('title')\n }, 160)\n }, [focusDealField])\n\n React.useEffect(() => {\n if (!id) {\n setError(t('customers.deals.detail.missingId', 'Deal id is required.'))\n setIsLoading(false)\n return\n }\n let cancelled = false\n async function loadDeal() {\n setIsLoading(true)\n setError(null)\n try {\n const payload = await readApiResultOrThrow<DealDetailPayload>(\n `/api/customers/deals/${encodeURIComponent(id)}`,\n undefined,\n { errorMessage: t('customers.deals.detail.loadError', 'Failed to load deal.') },\n )\n if (cancelled) return\n setData(payload as DealDetailPayload)\n } catch (err) {\n if (cancelled) return\n const message =\n err instanceof Error && err.message\n ? err.message\n : t('customers.deals.detail.loadError', 'Failed to load deal.')\n setError(message)\n setData(null)\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n loadDeal().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [id, reloadToken, t])\n\n const handleFormSubmit = React.useCallback(\n async ({ base, custom }: DealFormSubmitPayload) => {\n if (!data || isSaving) return\n setIsSaving(true)\n try {\n const payload: Record<string, unknown> = {\n id: data.deal.id,\n title: base.title,\n status: base.status ?? undefined,\n pipelineStage: base.pipelineStage ?? undefined,\n valueAmount: typeof base.valueAmount === 'number' ? base.valueAmount : undefined,\n valueCurrency: base.valueCurrency ?? undefined,\n probability: typeof base.probability === 'number' ? base.probability : undefined,\n expectedCloseAt: base.expectedCloseAt ?? undefined,\n description: base.description ?? undefined,\n personIds: base.personIds && base.personIds.length ? base.personIds : undefined,\n companyIds: base.companyIds && base.companyIds.length ? base.companyIds : undefined,\n }\n if (Object.keys(custom).length) payload.customFields = custom\n\n await apiCallOrThrow(\n '/api/customers/deals',\n {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n },\n { errorMessage: t('customers.deals.detail.saveError', 'Failed to update deal.') },\n )\n flash(t('customers.deals.detail.saveSuccess', 'Deal updated.'), 'success')\n setReloadToken((token) => token + 1)\n } catch (err) {\n const message =\n err instanceof Error && err.message\n ? err.message\n : t('customers.deals.detail.saveError', 'Failed to update deal.')\n flash(message, 'error')\n throw err instanceof Error ? err : new Error(message)\n } finally {\n setIsSaving(false)\n }\n },\n [data, isSaving, t],\n )\n\n const handleDelete = React.useCallback(async () => {\n if (!data || isDeleting) return\n const confirmed = await confirm({\n title: t(\n 'customers.deals.detail.deleteConfirm',\n 'Delete this deal? This action cannot be undone.',\n ),\n variant: 'destructive',\n })\n if (!confirmed) return\n\n setIsDeleting(true)\n try {\n await apiCallOrThrow(\n '/api/customers/deals',\n {\n method: 'DELETE',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id: data.deal.id }),\n },\n { errorMessage: t('customers.deals.detail.deleteError', 'Failed to delete deal.') },\n )\n flash(t('customers.deals.detail.deleteSuccess', 'Deal deleted.'), 'success')\n router.push('/backend/customers/deals')\n } catch (err) {\n const message =\n err instanceof Error && err.message\n ? err.message\n : t('customers.deals.detail.deleteError', 'Failed to delete deal.')\n flash(message, 'error')\n } finally {\n setIsDeleting(false)\n }\n }, [confirm, data, isDeleting, router, t])\n\n React.useEffect(() => {\n setSectionAction(null)\n }, [activeTab])\n\n const handleSectionAction = React.useCallback(() => {\n if (!sectionAction || sectionAction.disabled) return\n sectionAction.onClick()\n }, [sectionAction])\n\n const dealOptions = React.useMemo(\n () =>\n data\n ? [\n {\n id: data.deal.id,\n label:\n data.deal.title && data.deal.title.length\n ? data.deal.title\n : t('customers.deals.detail.untitled', 'Untitled deal'),\n },\n ]\n : [],\n [data, t],\n )\n\n const entityOptions = React.useMemo(() => {\n if (!data) return []\n const entries: { id: string; label: string }[] = []\n data.people.forEach((person) => {\n if (!person.id) return\n const suffix = person.subtitle ? ` \u00B7 ${person.subtitle}` : ''\n entries.push({ id: person.id, label: `${person.label}${suffix}` })\n })\n data.companies.forEach((company) => {\n if (!company.id) return\n const suffix = company.subtitle ? ` \u00B7 ${company.subtitle}` : ''\n entries.push({ id: company.id, label: `${company.label}${suffix}` })\n })\n return entries\n }, [data])\n\n const defaultEntityId = React.useMemo(() => {\n if (entityOptions.length) return entityOptions[0].id\n return null\n }, [entityOptions])\n\n const tabs = React.useMemo(\n () => [\n { id: 'notes' as const, label: t('customers.deals.detail.tabs.notes', 'Notes') },\n { id: 'activities' as const, label: t('customers.deals.detail.tabs.activities', 'Activities') },\n ],\n [t],\n )\n\n if (isLoading) {\n return (\n <Page>\n <PageBody>\n <div className=\"flex h-[50vh] flex-col items-center justify-center gap-2 text-muted-foreground\">\n <Spinner className=\"h-6 w-6\" />\n <span>{t('customers.deals.detail.loading', 'Loading deal\u2026')}</span>\n </div>\n </PageBody>\n </Page>\n )\n }\n\n if (error || !data) {\n return (\n <Page>\n <PageBody>\n <div className=\"flex h-[50vh] flex-col items-center justify-center gap-3 text-muted-foreground\">\n <p>{error || t('customers.deals.detail.notFound', 'Deal not found.')}</p>\n <Button variant=\"outline\" asChild>\n <Link href=\"/backend/customers/deals\">\n {t('customers.deals.detail.backToList', 'Back to deals')}\n </Link>\n </Button>\n </div>\n </PageBody>\n </Page>\n )\n }\n\n const probabilityLabel = data.deal.probability !== null && data.deal.probability !== undefined\n ? `${data.deal.probability}%`\n : t('customers.deals.detail.noValue', 'Not provided')\n const valueLabel =\n formatCurrency(data.deal.valueAmount, data.deal.valueCurrency) ??\n t('customers.deals.detail.noValue', 'Not provided')\n const expectedCloseLabel = formatDate(data.deal.expectedCloseAt, t('customers.deals.detail.noValue', 'Not provided'))\n const statusLabel =\n resolveDictionaryLabel(data.deal.status, statusDictionaryMap) ??\n t('customers.deals.detail.noStatus', 'No status')\n const pipelineLabel = resolveDictionaryLabel(data.deal.pipelineStage, pipelineDictionaryMap)\n\n const peopleSummaryLabel =\n data.people.length === 1\n ? t('customers.deals.detail.peopleSummaryOne')\n : t('customers.deals.detail.peopleSummaryMany', undefined, { count: data.people.length })\n const companiesSummaryLabel =\n data.companies.length === 1\n ? t('customers.deals.detail.companiesSummaryOne')\n : t('customers.deals.detail.companiesSummaryMany', undefined, { count: data.companies.length })\n\n const viewer = data.viewer ?? null\n\n return (\n <Page>\n <PageBody>\n <div className=\"flex flex-col gap-6\">\n <FormHeader\n mode=\"detail\"\n backHref=\"/backend/customers/deals\"\n backLabel={t('customers.deals.detail.backToList', 'Back to deals')}\n utilityActions={(\n <VersionHistoryAction\n config={{ resourceKind: 'customers.deal', resourceId: data.deal.id }}\n t={t}\n />\n )}\n title={\n <div className=\"flex flex-wrap items-center gap-2\">\n <span>{data.deal.title || t('customers.deals.detail.untitled', 'Untitled deal')}</span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"gap-1 text-muted-foreground hover:text-foreground\"\n onClick={scrollToDealSettings}\n >\n <Pencil className=\"h-4 w-4\" aria-hidden />\n <MousePointerClick className=\"h-4 w-4\" aria-hidden />\n <span>{t('customers.deals.detail.goToSettings', 'Edit deal details')}</span>\n </Button>\n </div>\n }\n subtitle={t('customers.deals.detail.summary', undefined, {\n status: statusLabel,\n pipeline: pipelineLabel ?? t('customers.deals.detail.noPipeline', 'No pipeline'),\n })}\n onDelete={handleDelete}\n isDeleting={isDeleting}\n deleteLabel={t('ui.actions.delete', 'Delete')}\n />\n <div className=\"grid gap-6 lg:grid-cols-[minmax(0,2fr),minmax(0,1.1fr)]\">\n <div className=\"space-y-6\">\n <div className=\"rounded-lg border bg-card p-4\">\n <h2 className=\"mb-4 text-sm font-semibold uppercase text-muted-foreground\">\n {t('customers.deals.detail.highlights', 'Highlights')}\n </h2>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('customers.deals.detail.fields.value', 'Deal value')}\n </p>\n <p className=\"text-base font-semibold text-foreground\">{valueLabel}</p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('customers.deals.detail.fields.probability', 'Probability')}\n </p>\n <p className=\"text-base font-semibold text-foreground\">{probabilityLabel}</p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('customers.deals.detail.fields.pipeline', 'Pipeline stage')}\n </p>\n <p className=\"text-base text-foreground\">\n {pipelineLabel ?? t('customers.deals.detail.noValue', 'Not provided')}\n </p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('customers.deals.detail.fields.expectedClose', 'Expected close')}\n </p>\n <p className=\"text-base text-foreground\">{expectedCloseLabel}</p>\n </div>\n </div>\n </div>\n\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex gap-2\">\n {tabs.map((tab) => (\n <Button\n key={tab.id}\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setActiveTab(tab.id)}\n className={`h-auto rounded-none border-b-2 px-0 py-1 ${\n activeTab === tab.id\n ? 'border-primary text-foreground'\n : 'border-transparent text-muted-foreground hover:text-foreground hover:bg-transparent'\n }`}\n >\n {tab.label}\n </Button>\n ))}\n </div>\n {sectionAction ? (\n <Button\n type=\"button\"\n size=\"sm\"\n disabled={sectionAction.disabled}\n onClick={handleSectionAction}\n >\n {sectionAction.icon ?? null}\n {sectionAction.label}\n </Button>\n ) : null}\n </div>\n {activeTab === 'notes' ? (\n <NotesSection\n entityId={null}\n dealId={data.deal.id}\n dealOptions={dealOptions}\n entityOptions={entityOptions}\n emptyLabel={t('customers.deals.detail.notesEmpty', 'No notes yet.')}\n viewerUserId={viewer?.userId ?? null}\n viewerName={viewer?.name ?? null}\n viewerEmail={viewer?.email ?? null}\n addActionLabel={t('customers.deals.detail.notesAdd', 'Add note')}\n emptyState={{\n title: t('customers.deals.detail.notesEmptyTitle', 'Keep everyone in the loop'),\n actionLabel: t('customers.deals.detail.notesEmptyAction', 'Add a note'),\n }}\n onActionChange={setSectionAction}\n translator={detailTranslator}\n onLoadingChange={handleNotesLoadingChange}\n dataAdapter={notesAdapter}\n renderIcon={renderDictionaryIcon}\n renderColor={renderDictionaryColor}\n iconSuggestions={ICON_SUGGESTIONS}\n readMarkdownPreference={readMarkdownPreferenceCookie}\n writeMarkdownPreference={writeMarkdownPreferenceCookie}\n />\n ) : null}\n {activeTab === 'activities' ? (\n <ActivitiesSection\n entityId={null}\n dealId={data.deal.id}\n dealOptions={dealOptions}\n entityOptions={entityOptions}\n defaultEntityId={defaultEntityId ?? undefined}\n addActionLabel={t('customers.deals.detail.activitiesAdd', 'Log activity')}\n emptyState={{\n title: t('customers.deals.detail.activitiesEmptyTitle', 'No activities yet'),\n actionLabel: t('customers.deals.detail.activitiesEmptyAction', 'Add an activity'),\n }}\n onActionChange={setSectionAction}\n onLoadingChange={handleActivitiesLoadingChange}\n />\n ) : null}\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"mb-3 space-y-1\">\n <h3 className=\"text-sm font-semibold text-foreground\">\n {t('customers.deals.detail.peopleSection', 'People')}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {peopleSummaryLabel}\n </p>\n </div>\n {data.people.length ? (\n <ul className=\"space-y-2 text-sm\">\n {data.people.map((person) => (\n <li key={person.id} className=\"flex flex-col gap-1\">\n <Link href={`/backend/customers/people/${encodeURIComponent(person.id)}`} className=\"font-medium text-foreground hover:underline\">\n {person.label}\n </Link>\n <span className=\"text-xs text-muted-foreground\">\n {person.subtitle ?? t('customers.deals.detail.peopleNoDetails', 'No additional details')}\n </span>\n </li>\n ))}\n </ul>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t('customers.deals.detail.noPeople', 'No people linked to this deal yet.')}\n </p>\n )}\n </div>\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"mb-3 space-y-1\">\n <h3 className=\"text-sm font-semibold text-foreground\">\n {t('customers.deals.detail.companiesSection', 'Companies')}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {companiesSummaryLabel}\n </p>\n </div>\n {data.companies.length ? (\n <ul className=\"space-y-2 text-sm\">\n {data.companies.map((company) => (\n <li key={company.id} className=\"flex flex-col gap-1\">\n <Link href={`/backend/customers/companies/${encodeURIComponent(company.id)}`} className=\"font-medium text-foreground hover:underline\">\n {company.label}\n </Link>\n <span className=\"text-xs text-muted-foreground\">\n {company.subtitle ?? t('customers.deals.detail.companiesNoDetails', 'No additional details')}\n </span>\n </li>\n ))}\n </ul>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t('customers.deals.detail.noCompanies', 'No companies linked to this deal yet.')}\n </p>\n )}\n </div>\n </div>\n </div>\n\n <div className=\"space-y-6\">\n <div\n ref={dealSettingsRef}\n id=\"deal-settings\"\n className=\"rounded-lg border bg-card p-4\"\n >\n <h2 className=\"mb-4 text-sm font-semibold uppercase text-muted-foreground\">\n {t('customers.deals.detail.formTitle', 'Deal settings')}\n </h2>\n <DealForm\n key={data.deal.updatedAt}\n mode=\"edit\"\n initialValues={{\n id: data.deal.id,\n title: data.deal.title ?? '',\n status: data.deal.status ?? '',\n pipelineStage: data.deal.pipelineStage ?? '',\n valueAmount: data.deal.valueAmount ? Number(data.deal.valueAmount) : null,\n valueCurrency: data.deal.valueCurrency ?? undefined,\n probability: data.deal.probability ?? null,\n expectedCloseAt: data.deal.expectedCloseAt ?? null,\n description: data.deal.description ?? '',\n personIds: data.people.map((person) => person.id),\n companyIds: data.companies.map((company) => company.id),\n people: data.people.map((person) => ({ id: person.id, label: person.label })),\n companies: data.companies.map((company) => ({ id: company.id, label: company.label })),\n ...Object.fromEntries(\n Object.entries(data.customFields)\n .filter(([key]) => key.startsWith('cf_'))\n .map(([key, value]) => [key, value]),\n ),\n }}\n onSubmit={handleFormSubmit}\n onCancel={() => setReloadToken((token) => token + 1)}\n onDelete={handleDelete}\n isSubmitting={isSaving || isDeleting}\n />\n </div>\n </div>\n </div>\n </div>\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { Pencil, MousePointerClick } from 'lucide-react'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { FormHeader } from '@open-mercato/ui/backend/forms'\nimport { VersionHistoryAction } from '@open-mercato/ui/backend/version-history'\nimport { SendObjectMessageDialog } from '@open-mercato/ui/backend/messages'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { apiCallOrThrow, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { NotesSection, type SectionAction } from '@open-mercato/ui/backend/detail'\nimport { ActivitiesSection } from '../../../../components/detail/ActivitiesSection'\nimport { DealForm, type DealFormSubmitPayload } from '../../../../components/detail/DealForm'\nimport { useCustomerDictionary } from '../../../../components/detail/hooks/useCustomerDictionary'\nimport type { CustomerDictionaryMap } from '../../../../lib/dictionaries'\nimport { createTranslatorWithFallback } from '@open-mercato/shared/lib/i18n/translate'\nimport { renderDictionaryColor, renderDictionaryIcon } from '@open-mercato/core/modules/dictionaries/components/dictionaryAppearance'\nimport { ICON_SUGGESTIONS } from '../../../../lib/dictionaries'\nimport { createCustomerNotesAdapter } from '../../../../components/detail/notesAdapter'\nimport { readMarkdownPreferenceCookie, writeMarkdownPreferenceCookie } from '../../../../lib/markdownPreference'\n\ntype DealAssociation = {\n id: string\n label: string\n subtitle: string | null\n kind: 'person' | 'company'\n}\n\ntype DealDetailPayload = {\n deal: {\n id: string\n title: string\n description: string | null\n status: string | null\n pipelineStage: string | null\n valueAmount: string | null\n valueCurrency: string | null\n probability: number | null\n expectedCloseAt: string | null\n ownerUserId: string | null\n source: string | null\n organizationId: string | null\n tenantId: string | null\n createdAt: string\n updatedAt: string\n }\n people: DealAssociation[]\n companies: DealAssociation[]\n customFields: Record<string, unknown>\n viewer?: {\n userId: string | null\n name?: string | null\n email?: string | null\n } | null\n}\n\nconst CRUD_FOCUSABLE_SELECTOR =\n '[data-crud-focus-target], input:not([type=\"hidden\"]):not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])'\n\nfunction formatCurrency(amount: string | null, currency: string | null): string | null {\n if (!amount) return null\n const value = Number(amount)\n if (!Number.isFinite(value)) return currency ? `${amount} ${currency}` : amount\n if (!currency) return value.toLocaleString()\n try {\n return new Intl.NumberFormat(undefined, { style: 'currency', currency }).format(value)\n } catch {\n return `${value.toLocaleString()} ${currency}`\n }\n}\n\nfunction formatDate(value: string | null, fallback: string): string {\n if (!value) return fallback\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return fallback\n return date.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' })\n}\n\nfunction resolveDictionaryLabel(\n value: string | null | undefined,\n map: CustomerDictionaryMap | null | undefined,\n): string | null {\n if (!value) return null\n const entry = map?.[value]\n if (entry && entry.label && entry.label.length) return entry.label\n return value\n}\n\nexport default function DealDetailPage({ params }: { params?: { id?: string } }) {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const detailTranslator = React.useMemo(() => createTranslatorWithFallback(t), [t])\n const notesAdapter = React.useMemo(() => createCustomerNotesAdapter(detailTranslator), [detailTranslator])\n const router = useRouter()\n const id = params?.id ?? ''\n const scopeVersion = useOrganizationScopeVersion()\n const statusDictionaryQuery = useCustomerDictionary('deal-statuses', scopeVersion)\n const pipelineDictionaryQuery = useCustomerDictionary('pipeline-stages', scopeVersion)\n const statusDictionaryMap = statusDictionaryQuery.data?.map ?? null\n const pipelineDictionaryMap = pipelineDictionaryQuery.data?.map ?? null\n const [data, setData] = React.useState<DealDetailPayload | null>(null)\n const [isLoading, setIsLoading] = React.useState(true)\n const [error, setError] = React.useState<string | null>(null)\n const [isSaving, setIsSaving] = React.useState(false)\n const [isDeleting, setIsDeleting] = React.useState(false)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [activeTab, setActiveTab] = React.useState<'notes' | 'activities'>('notes')\n const [sectionAction, setSectionAction] = React.useState<SectionAction | null>(null)\n const handleNotesLoadingChange = React.useCallback(() => {}, [])\n const handleActivitiesLoadingChange = React.useCallback(() => {}, [])\n const focusDealField = React.useCallback(\n (fieldId: 'title' | 'personIds' | 'companyIds') => {\n if (typeof window === 'undefined' || typeof document === 'undefined') return\n const focusOnce = () => {\n const container = document.querySelector<HTMLElement>(`[data-crud-field-id=\"${fieldId}\"]`)\n if (!container) return false\n const target =\n container.querySelector<HTMLElement>(CRUD_FOCUSABLE_SELECTOR) ?? container\n if (!target || typeof target.focus !== 'function') return false\n if (typeof container.scrollIntoView === 'function') {\n container.scrollIntoView({ behavior: 'smooth', block: 'center' })\n }\n target.focus()\n if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {\n try {\n target.select()\n } catch {}\n }\n return true\n }\n\n const schedule = () => {\n const focused = focusOnce()\n if (focused) return\n window.setTimeout(() => {\n focusOnce()\n }, 60)\n }\n\n if (typeof window.requestAnimationFrame === 'function') {\n window.requestAnimationFrame(schedule)\n } else {\n schedule()\n }\n },\n [],\n )\n const dealSettingsRef = React.useRef<HTMLDivElement | null>(null)\n const scrollToDealSettings = React.useCallback(() => {\n if (typeof window === 'undefined') return\n if (dealSettingsRef.current && typeof dealSettingsRef.current.scrollIntoView === 'function') {\n dealSettingsRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' })\n }\n window.setTimeout(() => {\n focusDealField('title')\n }, 160)\n }, [focusDealField])\n\n React.useEffect(() => {\n if (!id) {\n setError(t('customers.deals.detail.missingId', 'Deal id is required.'))\n setIsLoading(false)\n return\n }\n let cancelled = false\n async function loadDeal() {\n setIsLoading(true)\n setError(null)\n try {\n const payload = await readApiResultOrThrow<DealDetailPayload>(\n `/api/customers/deals/${encodeURIComponent(id)}`,\n undefined,\n { errorMessage: t('customers.deals.detail.loadError', 'Failed to load deal.') },\n )\n if (cancelled) return\n setData(payload as DealDetailPayload)\n } catch (err) {\n if (cancelled) return\n const message =\n err instanceof Error && err.message\n ? err.message\n : t('customers.deals.detail.loadError', 'Failed to load deal.')\n setError(message)\n setData(null)\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n loadDeal().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [id, reloadToken, t])\n\n const handleFormSubmit = React.useCallback(\n async ({ base, custom }: DealFormSubmitPayload) => {\n if (!data || isSaving) return\n setIsSaving(true)\n try {\n const payload: Record<string, unknown> = {\n id: data.deal.id,\n title: base.title,\n status: base.status ?? undefined,\n pipelineStage: base.pipelineStage ?? undefined,\n valueAmount: typeof base.valueAmount === 'number' ? base.valueAmount : undefined,\n valueCurrency: base.valueCurrency ?? undefined,\n probability: typeof base.probability === 'number' ? base.probability : undefined,\n expectedCloseAt: base.expectedCloseAt ?? undefined,\n description: base.description ?? undefined,\n personIds: base.personIds && base.personIds.length ? base.personIds : undefined,\n companyIds: base.companyIds && base.companyIds.length ? base.companyIds : undefined,\n }\n if (Object.keys(custom).length) payload.customFields = custom\n\n await apiCallOrThrow(\n '/api/customers/deals',\n {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n },\n { errorMessage: t('customers.deals.detail.saveError', 'Failed to update deal.') },\n )\n flash(t('customers.deals.detail.saveSuccess', 'Deal updated.'), 'success')\n setReloadToken((token) => token + 1)\n } catch (err) {\n const message =\n err instanceof Error && err.message\n ? err.message\n : t('customers.deals.detail.saveError', 'Failed to update deal.')\n flash(message, 'error')\n throw err instanceof Error ? err : new Error(message)\n } finally {\n setIsSaving(false)\n }\n },\n [data, isSaving, t],\n )\n\n const handleDelete = React.useCallback(async () => {\n if (!data || isDeleting) return\n const confirmed = await confirm({\n title: t(\n 'customers.deals.detail.deleteConfirm',\n 'Delete this deal? This action cannot be undone.',\n ),\n variant: 'destructive',\n })\n if (!confirmed) return\n\n setIsDeleting(true)\n try {\n await apiCallOrThrow(\n '/api/customers/deals',\n {\n method: 'DELETE',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id: data.deal.id }),\n },\n { errorMessage: t('customers.deals.detail.deleteError', 'Failed to delete deal.') },\n )\n flash(t('customers.deals.detail.deleteSuccess', 'Deal deleted.'), 'success')\n router.push('/backend/customers/deals')\n } catch (err) {\n const message =\n err instanceof Error && err.message\n ? err.message\n : t('customers.deals.detail.deleteError', 'Failed to delete deal.')\n flash(message, 'error')\n } finally {\n setIsDeleting(false)\n }\n }, [confirm, data, isDeleting, router, t])\n\n React.useEffect(() => {\n setSectionAction(null)\n }, [activeTab])\n\n const handleSectionAction = React.useCallback(() => {\n if (!sectionAction || sectionAction.disabled) return\n sectionAction.onClick()\n }, [sectionAction])\n\n const dealOptions = React.useMemo(\n () =>\n data\n ? [\n {\n id: data.deal.id,\n label:\n data.deal.title && data.deal.title.length\n ? data.deal.title\n : t('customers.deals.detail.untitled', 'Untitled deal'),\n },\n ]\n : [],\n [data, t],\n )\n\n const entityOptions = React.useMemo(() => {\n if (!data) return []\n const entries: { id: string; label: string }[] = []\n data.people.forEach((person) => {\n if (!person.id) return\n const suffix = person.subtitle ? ` \u00B7 ${person.subtitle}` : ''\n entries.push({ id: person.id, label: `${person.label}${suffix}` })\n })\n data.companies.forEach((company) => {\n if (!company.id) return\n const suffix = company.subtitle ? ` \u00B7 ${company.subtitle}` : ''\n entries.push({ id: company.id, label: `${company.label}${suffix}` })\n })\n return entries\n }, [data])\n\n const defaultEntityId = React.useMemo(() => {\n if (entityOptions.length) return entityOptions[0].id\n return null\n }, [entityOptions])\n\n const tabs = React.useMemo(\n () => [\n { id: 'notes' as const, label: t('customers.deals.detail.tabs.notes', 'Notes') },\n { id: 'activities' as const, label: t('customers.deals.detail.tabs.activities', 'Activities') },\n ],\n [t],\n )\n\n if (isLoading) {\n return (\n <Page>\n <PageBody>\n <div className=\"flex h-[50vh] flex-col items-center justify-center gap-2 text-muted-foreground\">\n <Spinner className=\"h-6 w-6\" />\n <span>{t('customers.deals.detail.loading', 'Loading deal\u2026')}</span>\n </div>\n </PageBody>\n </Page>\n )\n }\n\n if (error || !data) {\n return (\n <Page>\n <PageBody>\n <div className=\"flex h-[50vh] flex-col items-center justify-center gap-3 text-muted-foreground\">\n <p>{error || t('customers.deals.detail.notFound', 'Deal not found.')}</p>\n <Button variant=\"outline\" asChild>\n <Link href=\"/backend/customers/deals\">\n {t('customers.deals.detail.backToList', 'Back to deals')}\n </Link>\n </Button>\n </div>\n </PageBody>\n </Page>\n )\n }\n\n const probabilityLabel = data.deal.probability !== null && data.deal.probability !== undefined\n ? `${data.deal.probability}%`\n : t('customers.deals.detail.noValue', 'Not provided')\n const valueLabel =\n formatCurrency(data.deal.valueAmount, data.deal.valueCurrency) ??\n t('customers.deals.detail.noValue', 'Not provided')\n const expectedCloseLabel = formatDate(data.deal.expectedCloseAt, t('customers.deals.detail.noValue', 'Not provided'))\n const statusLabel =\n resolveDictionaryLabel(data.deal.status, statusDictionaryMap) ??\n t('customers.deals.detail.noStatus', 'No status')\n const pipelineLabel = resolveDictionaryLabel(data.deal.pipelineStage, pipelineDictionaryMap)\n\n const peopleSummaryLabel =\n data.people.length === 1\n ? t('customers.deals.detail.peopleSummaryOne')\n : t('customers.deals.detail.peopleSummaryMany', undefined, { count: data.people.length })\n const companiesSummaryLabel =\n data.companies.length === 1\n ? t('customers.deals.detail.companiesSummaryOne')\n : t('customers.deals.detail.companiesSummaryMany', undefined, { count: data.companies.length })\n\n const viewer = data.viewer ?? null\n\n return (\n <Page>\n <PageBody>\n <div className=\"flex flex-col gap-6\">\n <FormHeader\n mode=\"detail\"\n backHref=\"/backend/customers/deals\"\n backLabel={t('customers.deals.detail.backToList', 'Back to deals')}\n utilityActions={(\n <>\n <SendObjectMessageDialog\n object={{\n entityModule: 'customers',\n entityType: 'deal',\n entityId: data.deal.id,\n sourceEntityType: 'customers.deal',\n sourceEntityId: data.deal.id,\n }}\n defaultValues={{\n sourceEntityType: 'customers.deal',\n sourceEntityId: data.deal.id,\n }}\n />\n <VersionHistoryAction\n config={{ resourceKind: 'customers.deal', resourceId: data.deal.id }}\n t={t}\n />\n </>\n )}\n title={\n <div className=\"flex flex-wrap items-center gap-2\">\n <span>{data.deal.title || t('customers.deals.detail.untitled', 'Untitled deal')}</span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"gap-1 text-muted-foreground hover:text-foreground\"\n onClick={scrollToDealSettings}\n >\n <Pencil className=\"h-4 w-4\" aria-hidden />\n <MousePointerClick className=\"h-4 w-4\" aria-hidden />\n <span>{t('customers.deals.detail.goToSettings', 'Edit deal details')}</span>\n </Button>\n </div>\n }\n subtitle={t('customers.deals.detail.summary', undefined, {\n status: statusLabel,\n pipeline: pipelineLabel ?? t('customers.deals.detail.noPipeline', 'No pipeline'),\n })}\n onDelete={handleDelete}\n isDeleting={isDeleting}\n deleteLabel={t('ui.actions.delete', 'Delete')}\n />\n <div className=\"grid gap-6 lg:grid-cols-[minmax(0,2fr),minmax(0,1.1fr)]\">\n <div className=\"space-y-6\">\n <div className=\"rounded-lg border bg-card p-4\">\n <h2 className=\"mb-4 text-sm font-semibold uppercase text-muted-foreground\">\n {t('customers.deals.detail.highlights', 'Highlights')}\n </h2>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('customers.deals.detail.fields.value', 'Deal value')}\n </p>\n <p className=\"text-base font-semibold text-foreground\">{valueLabel}</p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('customers.deals.detail.fields.probability', 'Probability')}\n </p>\n <p className=\"text-base font-semibold text-foreground\">{probabilityLabel}</p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('customers.deals.detail.fields.pipeline', 'Pipeline stage')}\n </p>\n <p className=\"text-base text-foreground\">\n {pipelineLabel ?? t('customers.deals.detail.noValue', 'Not provided')}\n </p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('customers.deals.detail.fields.expectedClose', 'Expected close')}\n </p>\n <p className=\"text-base text-foreground\">{expectedCloseLabel}</p>\n </div>\n </div>\n </div>\n\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex gap-2\">\n {tabs.map((tab) => (\n <Button\n key={tab.id}\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setActiveTab(tab.id)}\n className={`h-auto rounded-none border-b-2 px-0 py-1 ${\n activeTab === tab.id\n ? 'border-primary text-foreground'\n : 'border-transparent text-muted-foreground hover:text-foreground hover:bg-transparent'\n }`}\n >\n {tab.label}\n </Button>\n ))}\n </div>\n {sectionAction ? (\n <Button\n type=\"button\"\n size=\"sm\"\n disabled={sectionAction.disabled}\n onClick={handleSectionAction}\n >\n {sectionAction.icon ?? null}\n {sectionAction.label}\n </Button>\n ) : null}\n </div>\n {activeTab === 'notes' ? (\n <NotesSection\n entityId={null}\n dealId={data.deal.id}\n dealOptions={dealOptions}\n entityOptions={entityOptions}\n emptyLabel={t('customers.deals.detail.notesEmpty', 'No notes yet.')}\n viewerUserId={viewer?.userId ?? null}\n viewerName={viewer?.name ?? null}\n viewerEmail={viewer?.email ?? null}\n addActionLabel={t('customers.deals.detail.notesAdd', 'Add note')}\n emptyState={{\n title: t('customers.deals.detail.notesEmptyTitle', 'Keep everyone in the loop'),\n actionLabel: t('customers.deals.detail.notesEmptyAction', 'Add a note'),\n }}\n onActionChange={setSectionAction}\n translator={detailTranslator}\n onLoadingChange={handleNotesLoadingChange}\n dataAdapter={notesAdapter}\n renderIcon={renderDictionaryIcon}\n renderColor={renderDictionaryColor}\n iconSuggestions={ICON_SUGGESTIONS}\n readMarkdownPreference={readMarkdownPreferenceCookie}\n writeMarkdownPreference={writeMarkdownPreferenceCookie}\n />\n ) : null}\n {activeTab === 'activities' ? (\n <ActivitiesSection\n entityId={null}\n dealId={data.deal.id}\n dealOptions={dealOptions}\n entityOptions={entityOptions}\n defaultEntityId={defaultEntityId ?? undefined}\n addActionLabel={t('customers.deals.detail.activitiesAdd', 'Log activity')}\n emptyState={{\n title: t('customers.deals.detail.activitiesEmptyTitle', 'No activities yet'),\n actionLabel: t('customers.deals.detail.activitiesEmptyAction', 'Add an activity'),\n }}\n onActionChange={setSectionAction}\n onLoadingChange={handleActivitiesLoadingChange}\n />\n ) : null}\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"mb-3 space-y-1\">\n <h3 className=\"text-sm font-semibold text-foreground\">\n {t('customers.deals.detail.peopleSection', 'People')}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {peopleSummaryLabel}\n </p>\n </div>\n {data.people.length ? (\n <ul className=\"space-y-2 text-sm\">\n {data.people.map((person) => (\n <li key={person.id} className=\"flex flex-col gap-1\">\n <Link href={`/backend/customers/people/${encodeURIComponent(person.id)}`} className=\"font-medium text-foreground hover:underline\">\n {person.label}\n </Link>\n <span className=\"text-xs text-muted-foreground\">\n {person.subtitle ?? t('customers.deals.detail.peopleNoDetails', 'No additional details')}\n </span>\n </li>\n ))}\n </ul>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t('customers.deals.detail.noPeople', 'No people linked to this deal yet.')}\n </p>\n )}\n </div>\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"mb-3 space-y-1\">\n <h3 className=\"text-sm font-semibold text-foreground\">\n {t('customers.deals.detail.companiesSection', 'Companies')}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {companiesSummaryLabel}\n </p>\n </div>\n {data.companies.length ? (\n <ul className=\"space-y-2 text-sm\">\n {data.companies.map((company) => (\n <li key={company.id} className=\"flex flex-col gap-1\">\n <Link href={`/backend/customers/companies/${encodeURIComponent(company.id)}`} className=\"font-medium text-foreground hover:underline\">\n {company.label}\n </Link>\n <span className=\"text-xs text-muted-foreground\">\n {company.subtitle ?? t('customers.deals.detail.companiesNoDetails', 'No additional details')}\n </span>\n </li>\n ))}\n </ul>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t('customers.deals.detail.noCompanies', 'No companies linked to this deal yet.')}\n </p>\n )}\n </div>\n </div>\n </div>\n\n <div className=\"space-y-6\">\n <div\n ref={dealSettingsRef}\n id=\"deal-settings\"\n className=\"rounded-lg border bg-card p-4\"\n >\n <h2 className=\"mb-4 text-sm font-semibold uppercase text-muted-foreground\">\n {t('customers.deals.detail.formTitle', 'Deal settings')}\n </h2>\n <DealForm\n key={data.deal.updatedAt}\n mode=\"edit\"\n initialValues={{\n id: data.deal.id,\n title: data.deal.title ?? '',\n status: data.deal.status ?? '',\n pipelineStage: data.deal.pipelineStage ?? '',\n valueAmount: data.deal.valueAmount ? Number(data.deal.valueAmount) : null,\n valueCurrency: data.deal.valueCurrency ?? undefined,\n probability: data.deal.probability ?? null,\n expectedCloseAt: data.deal.expectedCloseAt ?? null,\n description: data.deal.description ?? '',\n personIds: data.people.map((person) => person.id),\n companyIds: data.companies.map((company) => company.id),\n people: data.people.map((person) => ({ id: person.id, label: person.label })),\n companies: data.companies.map((company) => ({ id: company.id, label: company.label })),\n ...Object.fromEntries(\n Object.entries(data.customFields)\n .filter(([key]) => key.startsWith('cf_'))\n .map(([key, value]) => [key, value]),\n ),\n }}\n onSubmit={handleFormSubmit}\n onCancel={() => setReloadToken((token) => token + 1)}\n onDelete={handleDelete}\n isSubmitting={isSaving || isDeleting}\n />\n </div>\n </div>\n </div>\n </div>\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|