@open-mercato/core 0.6.4-develop.4371.1.8f3030407e → 0.6.4
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/.turbo/turbo-build.log +2 -2
- package/AGENTS.md +37 -0
- package/dist/generated/entities/channel_ingest_dead_letter/index.js +25 -0
- package/dist/generated/entities/channel_ingest_dead_letter/index.js.map +7 -0
- package/dist/generated/entities/channel_thread_mapping/index.js +25 -0
- package/dist/generated/entities/channel_thread_mapping/index.js.map +7 -0
- package/dist/generated/entities/channel_thread_token/index.js +17 -0
- package/dist/generated/entities/channel_thread_token/index.js.map +7 -0
- package/dist/generated/entities/communication_channel/index.js +43 -0
- package/dist/generated/entities/communication_channel/index.js.map +7 -0
- package/dist/generated/entities/customer_interaction/index.js +4 -0
- package/dist/generated/entities/customer_interaction/index.js.map +2 -2
- package/dist/generated/entities/customer_settings/index.js +2 -0
- package/dist/generated/entities/customer_settings/index.js.map +2 -2
- package/dist/generated/entities/dictionary/index.js +2 -0
- package/dist/generated/entities/dictionary/index.js.map +2 -2
- package/dist/generated/entities/external_conversation/index.js +25 -0
- package/dist/generated/entities/external_conversation/index.js.map +7 -0
- package/dist/generated/entities/external_message/index.js +25 -0
- package/dist/generated/entities/external_message/index.js.map +7 -0
- package/dist/generated/entities/inbox_settings/index.js +2 -0
- package/dist/generated/entities/inbox_settings/index.js.map +2 -2
- package/dist/generated/entities/integration_credentials/index.js +3 -1
- package/dist/generated/entities/integration_credentials/index.js.map +2 -2
- package/dist/generated/entities/message/index.js +2 -0
- package/dist/generated/entities/message/index.js.map +2 -2
- package/dist/generated/entities/message_channel_link/index.js +33 -0
- package/dist/generated/entities/message_channel_link/index.js.map +7 -0
- package/dist/generated/entities/message_reaction/index.js +25 -0
- package/dist/generated/entities/message_reaction/index.js.map +7 -0
- package/dist/generated/entities/role/index.js +3 -1
- package/dist/generated/entities/role/index.js.map +2 -2
- package/dist/generated/entities/step_instance/index.js +2 -0
- package/dist/generated/entities/step_instance/index.js.map +2 -2
- package/dist/generated/entities/user/index.js +3 -1
- package/dist/generated/entities/user/index.js.map +2 -2
- package/dist/generated/entities/user_task/index.js +2 -0
- package/dist/generated/entities/user_task/index.js.map +2 -2
- package/dist/generated/entities/workflow_branch_instance/index.js +39 -0
- package/dist/generated/entities/workflow_branch_instance/index.js.map +7 -0
- package/dist/generated/entities/workflow_event/index.js +2 -0
- package/dist/generated/entities/workflow_event/index.js.map +2 -2
- package/dist/generated/entities/workflow_instance/index.js +2 -0
- package/dist/generated/entities/workflow_instance/index.js.map +2 -2
- package/dist/generated/entities.ids.generated.js +12 -0
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +146 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/helpers/integration/api.js +14 -1
- package/dist/helpers/integration/api.js.map +2 -2
- package/dist/helpers/integration/authFixtures.js +2 -1
- package/dist/helpers/integration/authFixtures.js.map +2 -2
- package/dist/helpers/integration/communicationChannelsFixtures.js +58 -0
- package/dist/helpers/integration/communicationChannelsFixtures.js.map +7 -0
- package/dist/helpers/integration/crudFormFields.js +33 -0
- package/dist/helpers/integration/crudFormFields.js.map +7 -0
- package/dist/helpers/integration/crudFormPersistence.js +107 -0
- package/dist/helpers/integration/crudFormPersistence.js.map +7 -0
- package/dist/helpers/integration/currenciesFixtures.js +52 -1
- package/dist/helpers/integration/currenciesFixtures.js.map +2 -2
- package/dist/helpers/integration/customerAccountsFixtures.js +124 -0
- package/dist/helpers/integration/customerAccountsFixtures.js.map +7 -0
- package/dist/helpers/integration/dbFixtures.js +9 -1
- package/dist/helpers/integration/dbFixtures.js.map +2 -2
- package/dist/helpers/integration/inboxFixtures.js +11 -0
- package/dist/helpers/integration/inboxFixtures.js.map +2 -2
- package/dist/helpers/integration/optimisticLockUi.js +104 -0
- package/dist/helpers/integration/optimisticLockUi.js.map +7 -0
- package/dist/helpers/integration/salesFixtures.js +17 -0
- package/dist/helpers/integration/salesFixtures.js.map +2 -2
- package/dist/helpers/integration/salesUi.js +17 -9
- package/dist/helpers/integration/salesUi.js.map +2 -2
- package/dist/helpers/integration/standaloneEnv.js +58 -0
- package/dist/helpers/integration/standaloneEnv.js.map +7 -0
- package/dist/helpers/integration/undoHarness.js +177 -0
- package/dist/helpers/integration/undoHarness.js.map +7 -0
- package/dist/helpers/integration/workflowsFixtures.js +161 -0
- package/dist/helpers/integration/workflowsFixtures.js.map +2 -2
- package/dist/modules/api_keys/backend/api-keys/page.js +18 -5
- package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
- package/dist/modules/api_keys/data/validators.js +3 -1
- package/dist/modules/api_keys/data/validators.js.map +2 -2
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js +17 -9
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js.map +2 -2
- package/dist/modules/attachments/lib/ocrQueue.js +6 -1
- package/dist/modules/attachments/lib/ocrQueue.js.map +2 -2
- package/dist/modules/attachments/lib/security.js +1 -1
- package/dist/modules/attachments/lib/security.js.map +2 -2
- package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js +4 -2
- package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js.map +2 -2
- package/dist/modules/audit_logs/api/audit-logs/actions/undo/route.js +3 -2
- package/dist/modules/audit_logs/api/audit-logs/actions/undo/route.js.map +2 -2
- package/dist/modules/audit_logs/data/entities.js.map +1 -1
- package/dist/modules/audit_logs/services/actionLogService.js +16 -0
- package/dist/modules/audit_logs/services/actionLogService.js.map +2 -2
- package/dist/modules/auth/api/logout.js +0 -12
- package/dist/modules/auth/api/logout.js.map +2 -2
- package/dist/modules/auth/api/roles/acl/route.js +32 -13
- package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
- package/dist/modules/auth/api/roles/route.js +52 -3
- package/dist/modules/auth/api/roles/route.js.map +2 -2
- package/dist/modules/auth/api/sidebar/preferences/route.js +73 -4
- package/dist/modules/auth/api/sidebar/preferences/route.js.map +2 -2
- package/dist/modules/auth/api/users/acl/route.js +88 -34
- package/dist/modules/auth/api/users/acl/route.js.map +2 -2
- package/dist/modules/auth/api/users/consents/route.js +17 -0
- package/dist/modules/auth/api/users/consents/route.js.map +2 -2
- package/dist/modules/auth/api/users/resend-invite/route.js +18 -0
- package/dist/modules/auth/api/users/resend-invite/route.js.map +2 -2
- package/dist/modules/auth/api/users/route.js +40 -2
- package/dist/modules/auth/api/users/route.js.map +2 -2
- package/dist/modules/auth/backend/roles/[id]/edit/page.js +24 -4
- package/dist/modules/auth/backend/roles/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/backend/roles/page.js +17 -4
- package/dist/modules/auth/backend/roles/page.js.map +2 -2
- package/dist/modules/auth/backend/users/[id]/edit/page.js +72 -7
- package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/backend/users/page.js +15 -2
- package/dist/modules/auth/backend/users/page.js.map +2 -2
- package/dist/modules/auth/cli.js +19 -21
- package/dist/modules/auth/cli.js.map +2 -2
- package/dist/modules/auth/commands/roles.js +78 -1
- package/dist/modules/auth/commands/roles.js.map +2 -2
- package/dist/modules/auth/commands/users.js +106 -6
- package/dist/modules/auth/commands/users.js.map +3 -3
- package/dist/modules/auth/components/AclEditor.js +3 -1
- package/dist/modules/auth/components/AclEditor.js.map +2 -2
- package/dist/modules/auth/data/entities.js +6 -0
- package/dist/modules/auth/data/entities.js.map +2 -2
- package/dist/modules/auth/frontend/reset/[token]/page.js +6 -2
- package/dist/modules/auth/frontend/reset/[token]/page.js.map +2 -2
- package/dist/modules/auth/lib/consentIntegrity.js +15 -2
- package/dist/modules/auth/lib/consentIntegrity.js.map +2 -2
- package/dist/modules/auth/lib/emailHash.js +6 -2
- package/dist/modules/auth/lib/emailHash.js.map +2 -2
- package/dist/modules/auth/lib/grantChecks.js +44 -1
- package/dist/modules/auth/lib/grantChecks.js.map +2 -2
- package/dist/modules/auth/lib/sessionIntegrity.js +11 -1
- package/dist/modules/auth/lib/sessionIntegrity.js.map +2 -2
- package/dist/modules/auth/services/authService.js +10 -19
- package/dist/modules/auth/services/authService.js.map +2 -2
- package/dist/modules/auth/services/sidebarPreferencesService.js +32 -4
- package/dist/modules/auth/services/sidebarPreferencesService.js.map +2 -2
- package/dist/modules/business_rules/api/rules/route.js +28 -0
- package/dist/modules/business_rules/api/rules/route.js.map +2 -2
- package/dist/modules/business_rules/api/sets/route.js +28 -0
- package/dist/modules/business_rules/api/sets/route.js.map +2 -2
- package/dist/modules/business_rules/backend/rules/[id]/page.js +11 -4
- package/dist/modules/business_rules/backend/rules/[id]/page.js.map +3 -3
- package/dist/modules/business_rules/backend/rules/page.js +30 -12
- package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
- package/dist/modules/business_rules/backend/sets/[id]/page.js +11 -4
- package/dist/modules/business_rules/backend/sets/[id]/page.js.map +2 -2
- package/dist/modules/business_rules/backend/sets/page.js +29 -11
- package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
- package/dist/modules/catalog/api/categories/route.js +2 -0
- package/dist/modules/catalog/api/categories/route.js.map +2 -2
- package/dist/modules/catalog/api/products/route.js +2 -1
- package/dist/modules/catalog/api/products/route.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js +2 -0
- package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js +138 -75
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js +87 -24
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/create/page.js +18 -3
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/create/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/create/page.js +4 -17
- package/dist/modules/catalog/backend/catalog/products/create/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/optionSchemaClient.js.map +2 -2
- package/dist/modules/catalog/commands/categories.js +42 -1
- package/dist/modules/catalog/commands/categories.js.map +2 -2
- package/dist/modules/catalog/commands/offers.js +44 -1
- package/dist/modules/catalog/commands/offers.js.map +2 -2
- package/dist/modules/catalog/commands/optionSchemas.js +6 -1
- package/dist/modules/catalog/commands/optionSchemas.js.map +2 -2
- package/dist/modules/catalog/commands/priceKinds.js +6 -1
- package/dist/modules/catalog/commands/priceKinds.js.map +2 -2
- package/dist/modules/catalog/commands/prices.js +50 -1
- package/dist/modules/catalog/commands/prices.js.map +2 -2
- package/dist/modules/catalog/commands/productUnitConversions.js +25 -1
- package/dist/modules/catalog/commands/productUnitConversions.js.map +2 -2
- package/dist/modules/catalog/commands/products.js +84 -0
- package/dist/modules/catalog/commands/products.js.map +2 -2
- package/dist/modules/catalog/commands/variants.js +117 -31
- package/dist/modules/catalog/commands/variants.js.map +2 -2
- package/dist/modules/catalog/components/PriceKindSettings.js +14 -6
- package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js +9 -0
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductMediaManager.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductsDataTable.js +14 -3
- package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
- package/dist/modules/catalog/components/products/VariantBuilder.js +38 -11
- package/dist/modules/catalog/components/products/VariantBuilder.js.map +2 -2
- package/dist/modules/catalog/components/products/productForm.js +21 -0
- package/dist/modules/catalog/components/products/productForm.js.map +2 -2
- package/dist/modules/catalog/components/products/variantForm.js +2 -1
- package/dist/modules/catalog/components/products/variantForm.js.map +2 -2
- package/dist/modules/catalog/lib/pricing.js +3 -0
- package/dist/modules/catalog/lib/pricing.js.map +2 -2
- package/dist/modules/communication_channels/acl.js +47 -0
- package/dist/modules/communication_channels/acl.js.map +7 -0
- package/dist/modules/communication_channels/api/delete/channels/[id]/route.js +133 -0
- package/dist/modules/communication_channels/api/delete/channels/[id]/route.js.map +7 -0
- package/dist/modules/communication_channels/api/delete/messages/[messageId]/reactions/[reactionId]/route.js +113 -0
- package/dist/modules/communication_channels/api/delete/messages/[messageId]/reactions/[reactionId]/route.js.map +7 -0
- package/dist/modules/communication_channels/api/get/channels/[id]/health/route.js +138 -0
- package/dist/modules/communication_channels/api/get/channels/[id]/health/route.js.map +7 -0
- package/dist/modules/communication_channels/api/get/channels/[id]/route.js +93 -0
- package/dist/modules/communication_channels/api/get/channels/[id]/route.js.map +7 -0
- package/dist/modules/communication_channels/api/get/channels/route.js +96 -0
- package/dist/modules/communication_channels/api/get/channels/route.js.map +7 -0
- package/dist/modules/communication_channels/api/get/me/channels/route.js +82 -0
- package/dist/modules/communication_channels/api/get/me/channels/route.js.map +7 -0
- package/dist/modules/communication_channels/api/get/oauth/[provider]/callback/route.js +274 -0
- package/dist/modules/communication_channels/api/get/oauth/[provider]/callback/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/import-history/route.js +168 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/import-history/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/poll-now/route.js +143 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/poll-now/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/push/register/route.js +127 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/push/register/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/set-primary/route.js +99 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/set-primary/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js +197 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/channels/connect/credentials/route.js +124 -0
- package/dist/modules/communication_channels/api/post/channels/connect/credentials/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/messages/[messageId]/reactions/route.js +120 -0
- package/dist/modules/communication_channels/api/post/messages/[messageId]/reactions/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/oauth/[provider]/initiate/route.js +157 -0
- package/dist/modules/communication_channels/api/post/oauth/[provider]/initiate/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/send-as-user/route.js +115 -0
- package/dist/modules/communication_channels/api/post/send-as-user/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/test-seed/route.js +238 -0
- package/dist/modules/communication_channels/api/post/test-seed/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/webhook/[provider]/route.js +175 -0
- package/dist/modules/communication_channels/api/post/webhook/[provider]/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/webhooks/gmail/route.js +123 -0
- package/dist/modules/communication_channels/api/post/webhooks/gmail/route.js.map +7 -0
- package/dist/modules/communication_channels/api/put/threads/[threadId]/assign/route.js +117 -0
- package/dist/modules/communication_channels/api/put/threads/[threadId]/assign/route.js.map +7 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/[id]/page.js +180 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/[id]/page.js.map +7 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/[id]/page.meta.js +36 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/[id]/page.meta.js.map +7 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.js +107 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.js.map +7 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.meta.js +38 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.meta.js.map +7 -0
- package/dist/modules/communication_channels/backend/profile/communication-channels/page.js +732 -0
- package/dist/modules/communication_channels/backend/profile/communication-channels/page.js.map +7 -0
- package/dist/modules/communication_channels/backend/profile/communication-channels/page.meta.js +38 -0
- package/dist/modules/communication_channels/backend/profile/communication-channels/page.meta.js.map +7 -0
- package/dist/modules/communication_channels/commands/connect-credential-channel.js +154 -0
- package/dist/modules/communication_channels/commands/connect-credential-channel.js.map +7 -0
- package/dist/modules/communication_channels/commands/delete-channel.js +137 -0
- package/dist/modules/communication_channels/commands/delete-channel.js.map +7 -0
- package/dist/modules/communication_channels/commands/deliver-outbound-message.js +400 -0
- package/dist/modules/communication_channels/commands/deliver-outbound-message.js.map +7 -0
- package/dist/modules/communication_channels/commands/disconnect-channel.js +163 -0
- package/dist/modules/communication_channels/commands/disconnect-channel.js.map +7 -0
- package/dist/modules/communication_channels/commands/ingest-inbound-message.js +413 -0
- package/dist/modules/communication_channels/commands/ingest-inbound-message.js.map +7 -0
- package/dist/modules/communication_channels/commands/interceptors.js +68 -0
- package/dist/modules/communication_channels/commands/interceptors.js.map +7 -0
- package/dist/modules/communication_channels/commands/process-inbound-reaction.js +198 -0
- package/dist/modules/communication_channels/commands/process-inbound-reaction.js.map +7 -0
- package/dist/modules/communication_channels/commands/push-register.js +146 -0
- package/dist/modules/communication_channels/commands/push-register.js.map +7 -0
- package/dist/modules/communication_channels/commands/push-renew.js +23 -0
- package/dist/modules/communication_channels/commands/push-renew.js.map +7 -0
- package/dist/modules/communication_channels/commands/push-unregister.js +108 -0
- package/dist/modules/communication_channels/commands/push-unregister.js.map +7 -0
- package/dist/modules/communication_channels/commands/queue-import-history.js +113 -0
- package/dist/modules/communication_channels/commands/queue-import-history.js.map +7 -0
- package/dist/modules/communication_channels/commands/reassign-conversation.js +193 -0
- package/dist/modules/communication_channels/commands/reassign-conversation.js.map +7 -0
- package/dist/modules/communication_channels/commands/set-primary-channel.js +115 -0
- package/dist/modules/communication_channels/commands/set-primary-channel.js.map +7 -0
- package/dist/modules/communication_channels/commands/toggle-outbound-reaction.js +260 -0
- package/dist/modules/communication_channels/commands/toggle-outbound-reaction.js.map +7 -0
- package/dist/modules/communication_channels/data/enrichers.js +286 -0
- package/dist/modules/communication_channels/data/enrichers.js.map +7 -0
- package/dist/modules/communication_channels/data/entities.js +447 -0
- package/dist/modules/communication_channels/data/entities.js.map +7 -0
- package/dist/modules/communication_channels/data/extensions.js +67 -0
- package/dist/modules/communication_channels/data/extensions.js.map +7 -0
- package/dist/modules/communication_channels/data/validators.js +123 -0
- package/dist/modules/communication_channels/data/validators.js.map +7 -0
- package/dist/modules/communication_channels/di.js +35 -0
- package/dist/modules/communication_channels/di.js.map +7 -0
- package/dist/modules/communication_channels/encryption.js +12 -0
- package/dist/modules/communication_channels/encryption.js.map +7 -0
- package/dist/modules/communication_channels/events.js +124 -0
- package/dist/modules/communication_channels/events.js.map +7 -0
- package/dist/modules/communication_channels/index.js +20 -0
- package/dist/modules/communication_channels/index.js.map +7 -0
- package/dist/modules/communication_channels/lib/access-control.js +43 -0
- package/dist/modules/communication_channels/lib/access-control.js.map +7 -0
- package/dist/modules/communication_channels/lib/adapter-compat.js +36 -0
- package/dist/modules/communication_channels/lib/adapter-compat.js.map +7 -0
- package/dist/modules/communication_channels/lib/adapter-registry-singleton.js +22 -0
- package/dist/modules/communication_channels/lib/adapter-registry-singleton.js.map +7 -0
- package/dist/modules/communication_channels/lib/adapter.js +1 -0
- package/dist/modules/communication_channels/lib/adapter.js.map +7 -0
- package/dist/modules/communication_channels/lib/connect-channel.js +95 -0
- package/dist/modules/communication_channels/lib/connect-channel.js.map +7 -0
- package/dist/modules/communication_channels/lib/contact-resolver.js +79 -0
- package/dist/modules/communication_channels/lib/contact-resolver.js.map +7 -0
- package/dist/modules/communication_channels/lib/credential-refresh.js +97 -0
- package/dist/modules/communication_channels/lib/credential-refresh.js.map +7 -0
- package/dist/modules/communication_channels/lib/dead-letter.js +62 -0
- package/dist/modules/communication_channels/lib/dead-letter.js.map +7 -0
- package/dist/modules/communication_channels/lib/email-capabilities.js +47 -0
- package/dist/modules/communication_channels/lib/email-capabilities.js.map +7 -0
- package/dist/modules/communication_channels/lib/email-contact.js +14 -0
- package/dist/modules/communication_channels/lib/email-contact.js.map +7 -0
- package/dist/modules/communication_channels/lib/email-mime.js +299 -0
- package/dist/modules/communication_channels/lib/email-mime.js.map +7 -0
- package/dist/modules/communication_channels/lib/error-classification.js +101 -0
- package/dist/modules/communication_channels/lib/error-classification.js.map +7 -0
- package/dist/modules/communication_channels/lib/gmail-pubsub-jwt.js +185 -0
- package/dist/modules/communication_channels/lib/gmail-pubsub-jwt.js.map +7 -0
- package/dist/modules/communication_channels/lib/mutation-guards.js +114 -0
- package/dist/modules/communication_channels/lib/mutation-guards.js.map +7 -0
- package/dist/modules/communication_channels/lib/oauth-client-config.js +32 -0
- package/dist/modules/communication_channels/lib/oauth-client-config.js.map +7 -0
- package/dist/modules/communication_channels/lib/oauth-state.js +128 -0
- package/dist/modules/communication_channels/lib/oauth-state.js.map +7 -0
- package/dist/modules/communication_channels/lib/oauth-token.js +45 -0
- package/dist/modules/communication_channels/lib/oauth-token.js.map +7 -0
- package/dist/modules/communication_channels/lib/pg-errors.js +11 -0
- package/dist/modules/communication_channels/lib/pg-errors.js.map +7 -0
- package/dist/modules/communication_channels/lib/provider-health.js +24 -0
- package/dist/modules/communication_channels/lib/provider-health.js.map +7 -0
- package/dist/modules/communication_channels/lib/push-state.js +19 -0
- package/dist/modules/communication_channels/lib/push-state.js.map +7 -0
- package/dist/modules/communication_channels/lib/queue.js +54 -0
- package/dist/modules/communication_channels/lib/queue.js.map +7 -0
- package/dist/modules/communication_channels/lib/reaction-processor-types.js +5 -0
- package/dist/modules/communication_channels/lib/reaction-processor-types.js.map +7 -0
- package/dist/modules/communication_channels/lib/reaction-semantics.js +11 -0
- package/dist/modules/communication_channels/lib/reaction-semantics.js.map +7 -0
- package/dist/modules/communication_channels/lib/registry.js +67 -0
- package/dist/modules/communication_channels/lib/registry.js.map +7 -0
- package/dist/modules/communication_channels/lib/route-mutation-guard.js +43 -0
- package/dist/modules/communication_channels/lib/route-mutation-guard.js.map +7 -0
- package/dist/modules/communication_channels/lib/sanitize-channel-html.js +96 -0
- package/dist/modules/communication_channels/lib/sanitize-channel-html.js.map +7 -0
- package/dist/modules/communication_channels/lib/send-as-user.js +194 -0
- package/dist/modules/communication_channels/lib/send-as-user.js.map +7 -0
- package/dist/modules/communication_channels/lib/system-user.js +22 -0
- package/dist/modules/communication_channels/lib/system-user.js.map +7 -0
- package/dist/modules/communication_channels/lib/test-seed.js +68 -0
- package/dist/modules/communication_channels/lib/test-seed.js.map +7 -0
- package/dist/modules/communication_channels/lib/thread-matcher.js +263 -0
- package/dist/modules/communication_channels/lib/thread-matcher.js.map +7 -0
- package/dist/modules/communication_channels/lib/thread-token.js +219 -0
- package/dist/modules/communication_channels/lib/thread-token.js.map +7 -0
- package/dist/modules/communication_channels/lib/use-connect-channel.js +61 -0
- package/dist/modules/communication_channels/lib/use-connect-channel.js.map +7 -0
- package/dist/modules/communication_channels/migrations/Migration20260526134719_communication_channels.js +50 -0
- package/dist/modules/communication_channels/migrations/Migration20260526134719_communication_channels.js.map +7 -0
- package/dist/modules/communication_channels/migrations/Migration20260527195446_communication_channels.js +19 -0
- package/dist/modules/communication_channels/migrations/Migration20260527195446_communication_channels.js.map +7 -0
- package/dist/modules/communication_channels/migrations/Migration20260529231848_communication_channels.js +13 -0
- package/dist/modules/communication_channels/migrations/Migration20260529231848_communication_channels.js.map +7 -0
- package/dist/modules/communication_channels/migrations/Migration20260531120000_communication_channels.js +17 -0
- package/dist/modules/communication_channels/migrations/Migration20260531120000_communication_channels.js.map +7 -0
- package/dist/modules/communication_channels/notifications.client.js +51 -0
- package/dist/modules/communication_channels/notifications.client.js.map +7 -0
- package/dist/modules/communication_channels/notifications.handlers.js +53 -0
- package/dist/modules/communication_channels/notifications.handlers.js.map +7 -0
- package/dist/modules/communication_channels/notifications.js +56 -0
- package/dist/modules/communication_channels/notifications.js.map +7 -0
- package/dist/modules/communication_channels/setup.js +105 -0
- package/dist/modules/communication_channels/setup.js.map +7 -0
- package/dist/modules/communication_channels/subscribers/channel-requires-reauth-notification.js +71 -0
- package/dist/modules/communication_channels/subscribers/channel-requires-reauth-notification.js.map +7 -0
- package/dist/modules/communication_channels/subscribers/outbound-bridge.js +103 -0
- package/dist/modules/communication_channels/subscribers/outbound-bridge.js.map +7 -0
- package/dist/modules/communication_channels/subscribers/user-deleted-cascade.js +51 -0
- package/dist/modules/communication_channels/subscribers/user-deleted-cascade.js.map +7 -0
- package/dist/modules/communication_channels/widgets/components.js +7 -0
- package/dist/modules/communication_channels/widgets/components.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/channel-badge/widget.client.js +18 -0
- package/dist/modules/communication_channels/widgets/injection/channel-badge/widget.client.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/channel-badge/widget.js +30 -0
- package/dist/modules/communication_channels/widgets/injection/channel-badge/widget.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/channel-info-panel/widget.client.js +185 -0
- package/dist/modules/communication_channels/widgets/injection/channel-info-panel/widget.client.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/channel-info-panel/widget.js +17 -0
- package/dist/modules/communication_channels/widgets/injection/channel-info-panel/widget.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.js +44 -0
- package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.js +17 -0
- package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/profile-channels-menu/widget.js +23 -0
- package/dist/modules/communication_channels/widgets/injection/profile-channels-menu/widget.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/reaction-bar/widget.client.js +141 -0
- package/dist/modules/communication_channels/widgets/injection/reaction-bar/widget.client.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/reaction-bar/widget.js +17 -0
- package/dist/modules/communication_channels/widgets/injection/reaction-bar/widget.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection-table.js +38 -0
- package/dist/modules/communication_channels/widgets/injection-table.js.map +7 -0
- package/dist/modules/communication_channels/widgets/notifications/ChannelRequiresReauthRenderer.js +25 -0
- package/dist/modules/communication_channels/widgets/notifications/ChannelRequiresReauthRenderer.js.map +7 -0
- package/dist/modules/communication_channels/widgets/notifications/MessageReceivedRenderer.js +19 -0
- package/dist/modules/communication_channels/widgets/notifications/MessageReceivedRenderer.js.map +7 -0
- package/dist/modules/communication_channels/widgets/notifications/index.js +7 -0
- package/dist/modules/communication_channels/widgets/notifications/index.js.map +7 -0
- package/dist/modules/communication_channels/workers/channel-import-history.js +185 -0
- package/dist/modules/communication_channels/workers/channel-import-history.js.map +7 -0
- package/dist/modules/communication_channels/workers/gmail-history-sync.js +154 -0
- package/dist/modules/communication_channels/workers/gmail-history-sync.js.map +7 -0
- package/dist/modules/communication_channels/workers/gmail-renew-watch.js +95 -0
- package/dist/modules/communication_channels/workers/gmail-renew-watch.js.map +7 -0
- package/dist/modules/communication_channels/workers/inbound-processor.js +56 -0
- package/dist/modules/communication_channels/workers/inbound-processor.js.map +7 -0
- package/dist/modules/communication_channels/workers/outbound-delivery.js +85 -0
- package/dist/modules/communication_channels/workers/outbound-delivery.js.map +7 -0
- package/dist/modules/communication_channels/workers/poll-channel.js +240 -0
- package/dist/modules/communication_channels/workers/poll-channel.js.map +7 -0
- package/dist/modules/communication_channels/workers/poll-tick.js +132 -0
- package/dist/modules/communication_channels/workers/poll-tick.js.map +7 -0
- package/dist/modules/communication_channels/workers/reaction-processor.js +192 -0
- package/dist/modules/communication_channels/workers/reaction-processor.js.map +7 -0
- package/dist/modules/configs/api/openapi.js +11 -2
- package/dist/modules/configs/api/openapi.js.map +2 -2
- package/dist/modules/currencies/backend/currencies/[id]/page.js +6 -3
- package/dist/modules/currencies/backend/currencies/[id]/page.js.map +2 -2
- package/dist/modules/currencies/backend/currencies/page.js +27 -11
- package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
- package/dist/modules/currencies/backend/exchange-rates/[id]/page.js +1 -0
- package/dist/modules/currencies/backend/exchange-rates/[id]/page.js.map +2 -2
- package/dist/modules/currencies/backend/exchange-rates/page.js +21 -7
- package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
- package/dist/modules/currencies/commands/currencies.js +37 -16
- package/dist/modules/currencies/commands/currencies.js.map +2 -2
- package/dist/modules/currencies/commands/exchange-rates.js +19 -9
- package/dist/modules/currencies/commands/exchange-rates.js.map +2 -2
- package/dist/modules/currencies/components/CurrencyFetchingConfig.js +26 -19
- package/dist/modules/currencies/components/CurrencyFetchingConfig.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/roles/[id].js +28 -5
- package/dist/modules/customer_accounts/api/admin/roles/[id].js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/roles.js +4 -2
- package/dist/modules/customer_accounts/api/admin/roles.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/users/[id].js +39 -5
- package/dist/modules/customer_accounts/api/admin/users/[id].js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/users-invite.js +17 -1
- package/dist/modules/customer_accounts/api/admin/users-invite.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/users.js +60 -23
- package/dist/modules/customer_accounts/api/admin/users.js.map +2 -2
- package/dist/modules/customer_accounts/api/login.js +11 -4
- package/dist/modules/customer_accounts/api/login.js.map +2 -2
- package/dist/modules/customer_accounts/api/portal/users-invite.js +17 -1
- package/dist/modules/customer_accounts/api/portal/users-invite.js.map +2 -2
- package/dist/modules/customer_accounts/api/signup.js +3 -1
- package/dist/modules/customer_accounts/api/signup.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js +16 -8
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +19 -5
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js +8 -4
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +29 -18
- package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +27 -11
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
- package/dist/modules/customer_accounts/data/validators.js +2 -1
- package/dist/modules/customer_accounts/data/validators.js.map +2 -2
- package/dist/modules/customer_accounts/lib/customerEntityOwnership.js +22 -0
- package/dist/modules/customer_accounts/lib/customerEntityOwnership.js.map +7 -0
- package/dist/modules/customer_accounts/lib/rateLimiter.js +14 -0
- package/dist/modules/customer_accounts/lib/rateLimiter.js.map +2 -2
- package/dist/modules/customer_accounts/lib/resolveTenantContext.js +44 -1
- package/dist/modules/customer_accounts/lib/resolveTenantContext.js.map +3 -3
- package/dist/modules/customer_accounts/services/customerInvitationService.js +28 -1
- package/dist/modules/customer_accounts/services/customerInvitationService.js.map +2 -2
- package/dist/modules/customer_accounts/services/customerUserService.js +13 -7
- package/dist/modules/customer_accounts/services/customerUserService.js.map +2 -2
- package/dist/modules/customer_accounts/subscribers/autoLinkCrmReverse.js +3 -3
- package/dist/modules/customer_accounts/subscribers/autoLinkCrmReverse.js.map +2 -2
- package/dist/modules/customers/acl.js +18 -0
- package/dist/modules/customers/acl.js.map +2 -2
- package/dist/modules/customers/api/activities/route.js +32 -10
- package/dist/modules/customers/api/activities/route.js.map +2 -2
- package/dist/modules/customers/api/addresses/route.js +2 -0
- package/dist/modules/customers/api/addresses/route.js.map +2 -2
- package/dist/modules/customers/api/companies/[id]/route.js +22 -9
- package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/companies/route.js +18 -7
- package/dist/modules/customers/api/companies/route.js.map +2 -2
- package/dist/modules/customers/api/deals/route.js +2 -0
- package/dist/modules/customers/api/deals/route.js.map +2 -2
- package/dist/modules/customers/api/dictionaries/[kind]/route.js +22 -38
- package/dist/modules/customers/api/dictionaries/[kind]/route.js.map +2 -2
- package/dist/modules/customers/api/dictionaries/cache.js +2 -1
- package/dist/modules/customers/api/dictionaries/cache.js.map +2 -2
- package/dist/modules/customers/api/dictionaries/context.js +1 -0
- package/dist/modules/customers/api/dictionaries/context.js.map +2 -2
- package/dist/modules/customers/api/interactions/[id]/visibility/route.js +151 -0
- package/dist/modules/customers/api/interactions/[id]/visibility/route.js.map +7 -0
- package/dist/modules/customers/api/interactions/counts/route.js +6 -0
- package/dist/modules/customers/api/interactions/counts/route.js.map +2 -2
- package/dist/modules/customers/api/interactions/route.js +33 -12
- package/dist/modules/customers/api/interactions/route.js.map +2 -2
- package/dist/modules/customers/api/people/[id]/email-threads/route.js +82 -0
- package/dist/modules/customers/api/people/[id]/email-threads/route.js.map +7 -0
- package/dist/modules/customers/api/people/[id]/emails/route.js +157 -0
- package/dist/modules/customers/api/people/[id]/emails/route.js.map +7 -0
- package/dist/modules/customers/api/people/[id]/route.js +20 -10
- package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/people/route.js +16 -7
- package/dist/modules/customers/api/people/route.js.map +2 -2
- package/dist/modules/customers/api/pipeline-stages/route.js +0 -13
- package/dist/modules/customers/api/pipeline-stages/route.js.map +2 -2
- package/dist/modules/customers/api/settings/dictionary-sort-modes/route.js +223 -0
- package/dist/modules/customers/api/settings/dictionary-sort-modes/route.js.map +7 -0
- package/dist/modules/customers/api/todos/route.js +29 -11
- package/dist/modules/customers/api/todos/route.js.map +2 -2
- package/dist/modules/customers/backend/config/customers/deals/page.js.map +2 -2
- package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js +34 -21
- package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/[id]/page.js +45 -27
- package/dist/modules/customers/backend/customers/companies/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/page.js +10 -1
- package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +22 -5
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js +30 -8
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +1 -0
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/page.js +26 -7
- package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/page.js +62 -39
- package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/[id]/page.js +41 -26
- package/dist/modules/customers/backend/customers/people/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/page.js +10 -1
- package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +60 -23
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/commands/activities.js +19 -0
- package/dist/modules/customers/commands/activities.js.map +2 -2
- package/dist/modules/customers/commands/addresses.js +98 -14
- package/dist/modules/customers/commands/addresses.js.map +2 -2
- package/dist/modules/customers/commands/comments.js +30 -1
- package/dist/modules/customers/commands/comments.js.map +2 -2
- package/dist/modules/customers/commands/companies.js +113 -1
- package/dist/modules/customers/commands/companies.js.map +2 -2
- package/dist/modules/customers/commands/deals.js +196 -77
- package/dist/modules/customers/commands/deals.js.map +2 -2
- package/dist/modules/customers/commands/dictionaries.js +44 -0
- package/dist/modules/customers/commands/dictionaries.js.map +2 -2
- package/dist/modules/customers/commands/entity-roles.js +47 -0
- package/dist/modules/customers/commands/entity-roles.js.map +2 -2
- package/dist/modules/customers/commands/interactions.js +200 -8
- package/dist/modules/customers/commands/interactions.js.map +2 -2
- package/dist/modules/customers/commands/labels.js +83 -1
- package/dist/modules/customers/commands/labels.js.map +2 -2
- package/dist/modules/customers/commands/people.js +167 -13
- package/dist/modules/customers/commands/people.js.map +2 -2
- package/dist/modules/customers/commands/personCompanyLinks.js +141 -69
- package/dist/modules/customers/commands/personCompanyLinks.js.map +2 -2
- package/dist/modules/customers/commands/pipeline-stages.js +13 -11
- package/dist/modules/customers/commands/pipeline-stages.js.map +3 -3
- package/dist/modules/customers/commands/settings.js +31 -0
- package/dist/modules/customers/commands/settings.js.map +2 -2
- package/dist/modules/customers/commands/tags.js +56 -1
- package/dist/modules/customers/commands/tags.js.map +2 -2
- package/dist/modules/customers/commands/todos.js +19 -0
- package/dist/modules/customers/commands/todos.js.map +2 -2
- package/dist/modules/customers/components/AddressFormatSettings.js.map +2 -2
- package/dist/modules/customers/components/CustomersConfigurationSections.js +3 -0
- package/dist/modules/customers/components/CustomersConfigurationSections.js.map +2 -2
- package/dist/modules/customers/components/DictionarySettings.js +20 -13
- package/dist/modules/customers/components/DictionarySettings.js.map +2 -2
- package/dist/modules/customers/components/DictionarySortSettings.js +214 -0
- package/dist/modules/customers/components/DictionarySortSettings.js.map +7 -0
- package/dist/modules/customers/components/PipelineSettings.js +38 -23
- package/dist/modules/customers/components/PipelineSettings.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivityCard.js +32 -0
- package/dist/modules/customers/components/detail/ActivityCard.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivityForm.js +1 -0
- package/dist/modules/customers/components/detail/ActivityForm.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivityTimeline.js +1 -1
- package/dist/modules/customers/components/detail/ActivityTimeline.js.map +2 -2
- package/dist/modules/customers/components/detail/AddressesSection.js +4 -0
- package/dist/modules/customers/components/detail/AddressesSection.js.map +2 -2
- package/dist/modules/customers/components/detail/AnnualRevenueField.js +1 -0
- package/dist/modules/customers/components/detail/AnnualRevenueField.js.map +2 -2
- package/dist/modules/customers/components/detail/CompanyPeopleSection.js +28 -22
- package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
- package/dist/modules/customers/components/detail/ComposeEmailDialog.js +242 -0
- package/dist/modules/customers/components/detail/ComposeEmailDialog.js.map +7 -0
- package/dist/modules/customers/components/detail/DealForm.js +3 -1
- package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
- package/dist/modules/customers/components/detail/DealsSection.js +46 -24
- package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
- package/dist/modules/customers/components/detail/EmailCardActions.js +184 -0
- package/dist/modules/customers/components/detail/EmailCardActions.js.map +7 -0
- package/dist/modules/customers/components/detail/EmailReplyForwardActions.js +52 -0
- package/dist/modules/customers/components/detail/EmailReplyForwardActions.js.map +7 -0
- package/dist/modules/customers/components/detail/EntityTagsDialog.js +7 -0
- package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/ManageTagsDialog.js +34 -22
- package/dist/modules/customers/components/detail/ManageTagsDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/PersonCompaniesSection.js +41 -29
- package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +2 -2
- package/dist/modules/customers/components/detail/PersonDetailTabs.js +7 -1
- package/dist/modules/customers/components/detail/PersonDetailTabs.js.map +2 -2
- package/dist/modules/customers/components/detail/PersonEmailThreadsTab.js +366 -0
- package/dist/modules/customers/components/detail/PersonEmailThreadsTab.js.map +7 -0
- package/dist/modules/customers/components/detail/RoleAssignmentRow.js +14 -8
- package/dist/modules/customers/components/detail/RoleAssignmentRow.js.map +2 -2
- package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +14 -6
- package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/create/DealCurrencyField.js +1 -0
- package/dist/modules/customers/components/detail/create/DealCurrencyField.js.map +2 -2
- package/dist/modules/customers/components/detail/hooks/useCustomerDictionary.js +2 -1
- package/dist/modules/customers/components/detail/hooks/useCustomerDictionary.js.map +2 -2
- package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js +29 -13
- package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js.map +2 -2
- package/dist/modules/customers/components/detail/hooks/useInteractions.js +77 -35
- package/dist/modules/customers/components/detail/hooks/useInteractions.js.map +2 -2
- package/dist/modules/customers/components/detail/hooks/usePersonTasks.js +25 -17
- package/dist/modules/customers/components/detail/hooks/usePersonTasks.js.map +2 -2
- package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +2 -2
- package/dist/modules/customers/components/formConfig.js +62 -12
- package/dist/modules/customers/components/formConfig.js.map +2 -2
- package/dist/modules/customers/data/enrichers.js +133 -2
- package/dist/modules/customers/data/enrichers.js.map +2 -2
- package/dist/modules/customers/data/entities.js +21 -0
- package/dist/modules/customers/data/entities.js.map +2 -2
- package/dist/modules/customers/data/extensions.js +16 -0
- package/dist/modules/customers/data/extensions.js.map +7 -0
- package/dist/modules/customers/data/guards.js +66 -0
- package/dist/modules/customers/data/guards.js.map +7 -0
- package/dist/modules/customers/data/validators.js +33 -8
- package/dist/modules/customers/data/validators.js.map +2 -2
- package/dist/modules/customers/di.js +37 -0
- package/dist/modules/customers/di.js.map +2 -2
- package/dist/modules/customers/encryption.js +11 -0
- package/dist/modules/customers/encryption.js.map +2 -2
- package/dist/modules/customers/events.js +4 -1
- package/dist/modules/customers/events.js.map +2 -2
- package/dist/modules/customers/lib/detailTenantScope.js +15 -0
- package/dist/modules/customers/lib/detailTenantScope.js.map +7 -0
- package/dist/modules/customers/lib/findPeopleByAddresses.js +64 -0
- package/dist/modules/customers/lib/findPeopleByAddresses.js.map +7 -0
- package/dist/modules/customers/lib/kysely.js.map +2 -2
- package/dist/modules/customers/lib/link-channel-message-handler.js +303 -0
- package/dist/modules/customers/lib/link-channel-message-handler.js.map +7 -0
- package/dist/modules/customers/lib/personCompanyLinkTable.js +15 -1
- package/dist/modules/customers/lib/personCompanyLinkTable.js.map +2 -2
- package/dist/modules/customers/lib/personEmailThreads.js +205 -0
- package/dist/modules/customers/lib/personEmailThreads.js.map +7 -0
- package/dist/modules/customers/lib/todoCompatibility.js +11 -0
- package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
- package/dist/modules/customers/lib/visibilityFilter.js +51 -0
- package/dist/modules/customers/lib/visibilityFilter.js.map +7 -0
- package/dist/modules/customers/migrations/Migration20260527012240_customers.js +20 -0
- package/dist/modules/customers/migrations/Migration20260527012240_customers.js.map +7 -0
- package/dist/modules/customers/migrations/Migration20260602202147_customers.js +13 -0
- package/dist/modules/customers/migrations/Migration20260602202147_customers.js.map +7 -0
- package/dist/modules/customers/search.js +12 -6
- package/dist/modules/customers/search.js.map +2 -2
- package/dist/modules/customers/setup.js +2 -1
- package/dist/modules/customers/setup.js.map +2 -2
- package/dist/modules/customers/subscribers/link-channel-message-received.js +12 -0
- package/dist/modules/customers/subscribers/link-channel-message-received.js.map +7 -0
- package/dist/modules/customers/subscribers/link-channel-message-sent.js +12 -0
- package/dist/modules/customers/subscribers/link-channel-message-sent.js.map +7 -0
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +2 -2
- package/dist/modules/data_sync/api/options.js +4 -4
- package/dist/modules/data_sync/api/options.js.map +2 -2
- package/dist/modules/data_sync/api/schedules/route.js +9 -1
- package/dist/modules/data_sync/api/schedules/route.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/page.js +17 -8
- package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
- package/dist/modules/data_sync/components/IntegrationScheduleTab.js +43 -22
- package/dist/modules/data_sync/components/IntegrationScheduleTab.js.map +2 -2
- package/dist/modules/data_sync/lib/sync-schedule-service.js +9 -0
- package/dist/modules/data_sync/lib/sync-schedule-service.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +8 -1
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js +12 -5
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/route.js +25 -1
- package/dist/modules/dictionaries/api/[dictionaryId]/route.js.map +2 -2
- package/dist/modules/dictionaries/api/openapi.js +2 -0
- package/dist/modules/dictionaries/api/openapi.js.map +2 -2
- package/dist/modules/dictionaries/api/route.js +7 -0
- package/dist/modules/dictionaries/api/route.js.map +2 -2
- package/dist/modules/dictionaries/commands/entry-operations.js +8 -0
- package/dist/modules/dictionaries/commands/entry-operations.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionariesManager.js +95 -16
- package/dist/modules/dictionaries/components/DictionariesManager.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js +29 -16
- package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionaryEntrySelect.js +51 -11
- package/dist/modules/dictionaries/components/DictionaryEntrySelect.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionarySelectControl.js +9 -1
- package/dist/modules/dictionaries/components/DictionarySelectControl.js.map +2 -2
- package/dist/modules/dictionaries/components/dictionaryAppearance.js +2 -1
- package/dist/modules/dictionaries/components/dictionaryAppearance.js.map +2 -2
- package/dist/modules/dictionaries/components/hooks/useDictionaryEntries.js +2 -1
- package/dist/modules/dictionaries/components/hooks/useDictionaryEntries.js.map +2 -2
- package/dist/modules/dictionaries/data/entities.js +5 -0
- package/dist/modules/dictionaries/data/entities.js.map +2 -2
- package/dist/modules/dictionaries/data/validators.js +3 -1
- package/dist/modules/dictionaries/data/validators.js.map +2 -2
- package/dist/modules/dictionaries/fields/dictionary.js +2 -2
- package/dist/modules/dictionaries/fields/dictionary.js.map +1 -1
- package/dist/modules/dictionaries/lib/entrySort.js +61 -0
- package/dist/modules/dictionaries/lib/entrySort.js.map +7 -0
- package/dist/modules/dictionaries/migrations/Migration20260602202147_dictionaries.js +13 -0
- package/dist/modules/dictionaries/migrations/Migration20260602202147_dictionaries.js.map +7 -0
- package/dist/modules/directory/api/get/organizations/lookup.js +3 -7
- package/dist/modules/directory/api/get/organizations/lookup.js.map +2 -2
- package/dist/modules/directory/api/organizations/route.js +41 -16
- package/dist/modules/directory/api/organizations/route.js.map +2 -2
- package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js +2 -0
- package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/organizations/page.js +18 -5
- package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js +7 -3
- package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/tenants/page.js +17 -4
- package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
- package/dist/modules/directory/commands/organizations.js +70 -2
- package/dist/modules/directory/commands/organizations.js.map +2 -2
- package/dist/modules/directory/commands/tenants.js +16 -3
- package/dist/modules/directory/commands/tenants.js.map +2 -2
- package/dist/modules/entities/api/records.js +107 -7
- package/dist/modules/entities/api/records.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js +1 -0
- package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +8 -4
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
- package/dist/modules/entities/components/UserEntitiesTable.js +9 -0
- package/dist/modules/entities/components/UserEntitiesTable.js.map +2 -2
- package/dist/modules/entities/lib/entityAcl.js +82 -0
- package/dist/modules/entities/lib/entityAcl.js.map +7 -0
- package/dist/modules/entities/lib/helpers.js +79 -65
- package/dist/modules/entities/lib/helpers.js.map +2 -2
- package/dist/modules/feature_toggles/api/global/[id]/override/route.js +15 -10
- package/dist/modules/feature_toggles/api/global/[id]/override/route.js.map +2 -2
- package/dist/modules/feature_toggles/api/global/[id]/route.js +2 -1
- package/dist/modules/feature_toggles/api/global/[id]/route.js.map +2 -2
- package/dist/modules/feature_toggles/api/overrides/route.js +20 -7
- package/dist/modules/feature_toggles/api/overrides/route.js.map +2 -2
- package/dist/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.js +21 -16
- package/dist/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.js.map +2 -2
- package/dist/modules/feature_toggles/commands/global.js +127 -8
- package/dist/modules/feature_toggles/commands/global.js.map +2 -2
- package/dist/modules/feature_toggles/commands/overrides.js +8 -6
- package/dist/modules/feature_toggles/commands/overrides.js.map +2 -2
- package/dist/modules/feature_toggles/components/FeatureToggleOverrideCard.js +20 -12
- package/dist/modules/feature_toggles/components/FeatureToggleOverrideCard.js.map +2 -2
- package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +15 -2
- package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
- package/dist/modules/feature_toggles/components/formConfig.js +2 -1
- package/dist/modules/feature_toggles/components/formConfig.js.map +2 -2
- package/dist/modules/feature_toggles/components/overrideFormConfig.js +5 -1
- package/dist/modules/feature_toggles/components/overrideFormConfig.js.map +2 -2
- package/dist/modules/feature_toggles/data/validators.js +7 -4
- package/dist/modules/feature_toggles/data/validators.js.map +2 -2
- package/dist/modules/feature_toggles/lib/queries.js +5 -5
- package/dist/modules/feature_toggles/lib/queries.js.map +2 -2
- package/dist/modules/feature_toggles/lib/utils.js.map +2 -2
- package/dist/modules/inbox_ops/api/proposals/[id]/replies/[replyId]/send/route.js +8 -1
- package/dist/modules/inbox_ops/api/proposals/[id]/replies/[replyId]/send/route.js.map +2 -2
- package/dist/modules/inbox_ops/api/settings/route.js +23 -2
- package/dist/modules/inbox_ops/api/settings/route.js.map +2 -2
- package/dist/modules/inbox_ops/api/webhook/inbound.js +53 -14
- package/dist/modules/inbox_ops/api/webhook/inbound.js.map +2 -2
- package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js +13 -8
- package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js.map +2 -2
- package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js +9 -4
- package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js.map +2 -2
- package/dist/modules/inbox_ops/data/entities.js +3 -0
- package/dist/modules/inbox_ops/data/entities.js.map +2 -2
- package/dist/modules/inbox_ops/data/validators.js +5 -1
- package/dist/modules/inbox_ops/data/validators.js.map +2 -2
- package/dist/modules/inbox_ops/encryption.js +9 -0
- package/dist/modules/inbox_ops/encryption.js.map +2 -2
- package/dist/modules/inbox_ops/lib/executionEngine.js +6 -1
- package/dist/modules/inbox_ops/lib/executionEngine.js.map +2 -2
- package/dist/modules/inbox_ops/lib/executionHelpers.js +2 -7
- package/dist/modules/inbox_ops/lib/executionHelpers.js.map +2 -2
- package/dist/modules/inbox_ops/lib/priceValidator.js +35 -7
- package/dist/modules/inbox_ops/lib/priceValidator.js.map +2 -2
- package/dist/modules/inbox_ops/lib/rateLimiter.js +58 -23
- package/dist/modules/inbox_ops/lib/rateLimiter.js.map +2 -2
- package/dist/modules/inbox_ops/lib/translationProvider.js +33 -5
- package/dist/modules/inbox_ops/lib/translationProvider.js.map +2 -2
- package/dist/modules/inbox_ops/migrations/Migration20260607205834.js +13 -0
- package/dist/modules/inbox_ops/migrations/Migration20260607205834.js.map +7 -0
- package/dist/modules/inbox_ops/subscribers/extractionWorker.js +2 -1
- package/dist/modules/inbox_ops/subscribers/extractionWorker.js.map +2 -2
- package/dist/modules/integrations/api/[id]/credentials/route.js +11 -0
- package/dist/modules/integrations/api/[id]/credentials/route.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/[id]/page.js +8 -0
- package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +18 -11
- package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/page.js +12 -8
- package/dist/modules/integrations/backend/integrations/page.js.map +2 -2
- package/dist/modules/integrations/data/entities.js +8 -1
- package/dist/modules/integrations/data/entities.js.map +2 -2
- package/dist/modules/integrations/lib/credentials-field-validation.js +32 -0
- package/dist/modules/integrations/lib/credentials-field-validation.js.map +7 -0
- package/dist/modules/integrations/lib/credentials-service.js +29 -14
- package/dist/modules/integrations/lib/credentials-service.js.map +2 -2
- package/dist/modules/integrations/migrations/Migration20260526154136_integrations.js +15 -0
- package/dist/modules/integrations/migrations/Migration20260526154136_integrations.js.map +7 -0
- package/dist/modules/messages/api/route.js +2 -2
- package/dist/modules/messages/api/route.js.map +2 -2
- package/dist/modules/messages/api/token/[token]/route.js +1 -1
- package/dist/modules/messages/api/token/[token]/route.js.map +2 -2
- package/dist/modules/messages/commands/actions.js +9 -7
- package/dist/modules/messages/commands/actions.js.map +2 -2
- package/dist/modules/messages/commands/messages.js +83 -18
- package/dist/modules/messages/commands/messages.js.map +2 -2
- package/dist/modules/messages/commands/tokens.js +1 -1
- package/dist/modules/messages/commands/tokens.js.map +2 -2
- package/dist/modules/messages/components/ComposeMessagePageClient.js +24 -13
- package/dist/modules/messages/components/ComposeMessagePageClient.js.map +2 -2
- package/dist/modules/messages/components/MessageDetailPageClient.js +39 -2
- package/dist/modules/messages/components/MessageDetailPageClient.js.map +2 -2
- package/dist/modules/messages/components/MessagesInboxPageClient.js +10 -0
- package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsActions.js +2 -2
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsActions.js.map +2 -2
- package/dist/modules/messages/components/message-detail/utils.js +17 -0
- package/dist/modules/messages/components/message-detail/utils.js.map +2 -2
- package/dist/modules/messages/data/entities.js +8 -1
- package/dist/modules/messages/data/entities.js.map +2 -2
- package/dist/modules/messages/data/validators.js +5 -1
- package/dist/modules/messages/data/validators.js.map +2 -2
- package/dist/modules/messages/lib/actions.js +5 -3
- package/dist/modules/messages/lib/actions.js.map +2 -2
- package/dist/modules/messages/migrations/Migration20260531130000.js +15 -0
- package/dist/modules/messages/migrations/Migration20260531130000.js.map +7 -0
- package/dist/modules/messages/widgets/injection-table.js +7 -0
- package/dist/modules/messages/widgets/injection-table.js.map +7 -0
- package/dist/modules/notifications/api/[id]/action/route.js +12 -2
- package/dist/modules/notifications/api/[id]/action/route.js.map +2 -2
- package/dist/modules/notifications/api/route.js +17 -4
- package/dist/modules/notifications/api/route.js.map +2 -2
- package/dist/modules/notifications/lib/notificationService.js +26 -21
- package/dist/modules/notifications/lib/notificationService.js.map +2 -2
- package/dist/modules/notifications/lib/routeHelpers.js +46 -8
- package/dist/modules/notifications/lib/routeHelpers.js.map +2 -2
- package/dist/modules/payment_gateways/api/status/route.js +6 -0
- package/dist/modules/payment_gateways/api/status/route.js.map +2 -2
- package/dist/modules/perspectives/api/[tableId]/route.js +39 -30
- package/dist/modules/perspectives/api/[tableId]/route.js.map +2 -2
- package/dist/modules/perspectives/services/perspectiveService.js +7 -0
- package/dist/modules/perspectives/services/perspectiveService.js.map +2 -2
- package/dist/modules/planner/backend/planner/availability-rulesets/[id]/page.js +6 -14
- package/dist/modules/planner/backend/planner/availability-rulesets/[id]/page.js.map +3 -3
- package/dist/modules/planner/backend/planner/availability-rulesets/page.js +4 -2
- package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
- package/dist/modules/planner/commands/availability-rule-sets.js +20 -1
- package/dist/modules/planner/commands/availability-rule-sets.js.map +2 -2
- package/dist/modules/planner/commands/availability.js +9 -0
- package/dist/modules/planner/commands/availability.js.map +2 -2
- package/dist/modules/planner/components/AvailabilityRuleSetForm.js +3 -1
- package/dist/modules/planner/components/AvailabilityRuleSetForm.js.map +2 -2
- package/dist/modules/planner/components/AvailabilityRulesEditor.js +52 -13
- package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
- package/dist/modules/planner/components/AvailabilitySchedule.js +9 -5
- package/dist/modules/planner/components/AvailabilitySchedule.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js +15 -14
- package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/page.js +14 -21
- package/dist/modules/portal/frontend/[orgSlug]/portal/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js +11 -1
- package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/signup/page.js +15 -5
- package/dist/modules/portal/frontend/[orgSlug]/portal/signup/page.js.map +2 -2
- package/dist/modules/progress/api/jobs/[id]/route.js +7 -1
- package/dist/modules/progress/api/jobs/[id]/route.js.map +2 -2
- package/dist/modules/query_index/api/openapi.js +2 -1
- package/dist/modules/query_index/api/openapi.js.map +2 -2
- package/dist/modules/query_index/api/reindex.js +4 -0
- package/dist/modules/query_index/api/reindex.js.map +2 -2
- package/dist/modules/query_index/data/entities.js +5 -1
- package/dist/modules/query_index/data/entities.js.map +2 -2
- package/dist/modules/query_index/lib/engine.js +48 -15
- package/dist/modules/query_index/lib/engine.js.map +2 -2
- package/dist/modules/query_index/lib/indexer.js +50 -24
- package/dist/modules/query_index/lib/indexer.js.map +2 -2
- package/dist/modules/query_index/lib/jobs.js +28 -0
- package/dist/modules/query_index/lib/jobs.js.map +2 -2
- package/dist/modules/query_index/lib/reindexer.js +24 -15
- package/dist/modules/query_index/lib/reindexer.js.map +2 -2
- package/dist/modules/query_index/lib/search-tokens.js +3 -3
- package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
- package/dist/modules/query_index/migrations/Migration20260606205453_query_index.js +35 -0
- package/dist/modules/query_index/migrations/Migration20260606205453_query_index.js.map +7 -0
- package/dist/modules/query_index/subscribers/delete_one.js +28 -15
- package/dist/modules/query_index/subscribers/delete_one.js.map +2 -2
- package/dist/modules/query_index/subscribers/upsert_one.js +31 -13
- package/dist/modules/query_index/subscribers/upsert_one.js.map +2 -2
- package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js +18 -2
- package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resource-types/page.js +4 -2
- package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/[id]/page.js +31 -4
- package/dist/modules/resources/backend/resources/resources/[id]/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/page.js +17 -4
- package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
- package/dist/modules/resources/commands/activities.js +64 -0
- package/dist/modules/resources/commands/activities.js.map +2 -2
- package/dist/modules/resources/commands/comments.js +21 -1
- package/dist/modules/resources/commands/comments.js.map +2 -2
- package/dist/modules/resources/commands/resource-types.js +22 -1
- package/dist/modules/resources/commands/resource-types.js.map +2 -2
- package/dist/modules/resources/commands/resources.js +87 -0
- package/dist/modules/resources/commands/resources.js.map +2 -2
- package/dist/modules/resources/commands/tag-assignments.js +53 -0
- package/dist/modules/resources/commands/tag-assignments.js.map +2 -2
- package/dist/modules/resources/components/ResourceCrudForm.js +90 -50
- package/dist/modules/resources/components/ResourceCrudForm.js.map +2 -2
- package/dist/modules/resources/components/ResourceTypeCrudForm.js +2 -1
- package/dist/modules/resources/components/ResourceTypeCrudForm.js.map +2 -2
- package/dist/modules/sales/api/documents/factory.js +7 -2
- package/dist/modules/sales/api/documents/factory.js.map +2 -2
- package/dist/modules/sales/api/shipping-methods/route.js +4 -0
- package/dist/modules/sales/api/shipping-methods/route.js.map +2 -2
- package/dist/modules/sales/api/tax-rates/route.js +4 -0
- package/dist/modules/sales/api/tax-rates/route.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js +3 -1
- package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/offers/page.js +13 -4
- package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/page.js +16 -4
- package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +70 -22
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/documents/create/page.js.map +2 -2
- package/dist/modules/sales/commands/configuration.js +112 -7
- package/dist/modules/sales/commands/configuration.js.map +2 -2
- package/dist/modules/sales/commands/documentAddresses.js +181 -2
- package/dist/modules/sales/commands/documentAddresses.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +46 -14
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/commands/notes.js +39 -1
- package/dist/modules/sales/commands/notes.js.map +2 -2
- package/dist/modules/sales/commands/payments.js +121 -14
- package/dist/modules/sales/commands/payments.js.map +2 -2
- package/dist/modules/sales/commands/returns.js +178 -2
- package/dist/modules/sales/commands/returns.js.map +2 -2
- package/dist/modules/sales/commands/shared.js +15 -0
- package/dist/modules/sales/commands/shared.js.map +2 -2
- package/dist/modules/sales/commands/shipments.js +48 -6
- package/dist/modules/sales/commands/shipments.js.map +2 -2
- package/dist/modules/sales/components/AdjustmentKindSettings.js +19 -11
- package/dist/modules/sales/components/AdjustmentKindSettings.js.map +2 -2
- package/dist/modules/sales/components/DocumentNumberSettings.js.map +2 -2
- package/dist/modules/sales/components/OrderEditingSettings.js.map +2 -2
- package/dist/modules/sales/components/PaymentMethodsSettings.js +12 -4
- package/dist/modules/sales/components/PaymentMethodsSettings.js.map +2 -2
- package/dist/modules/sales/components/ShippingMethodsSettings.js +12 -4
- package/dist/modules/sales/components/ShippingMethodsSettings.js.map +2 -2
- package/dist/modules/sales/components/StatusSettings.js +18 -11
- package/dist/modules/sales/components/StatusSettings.js.map +2 -2
- package/dist/modules/sales/components/TaxRatesSettings.js +12 -4
- package/dist/modules/sales/components/TaxRatesSettings.js.map +2 -2
- package/dist/modules/sales/components/channels/ChannelOfferForm.js +65 -18
- package/dist/modules/sales/components/channels/ChannelOfferForm.js.map +2 -2
- package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +11 -4
- package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
- package/dist/modules/sales/components/documents/AddressesSection.js +101 -36
- package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
- package/dist/modules/sales/components/documents/AdjustmentDialog.js +37 -10
- package/dist/modules/sales/components/documents/AdjustmentDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/AdjustmentsSection.js +43 -23
- package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/ItemsSection.js +23 -14
- package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/LineItemDialog.js +70 -28
- package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/PaymentDialog.js +29 -14
- package/dist/modules/sales/components/documents/PaymentDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/PaymentsSection.js +20 -10
- package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/ReturnDialog.js +26 -17
- package/dist/modules/sales/components/documents/ReturnDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/ReturnsSection.js +3 -1
- package/dist/modules/sales/components/documents/ReturnsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentForm.js +1 -0
- package/dist/modules/sales/components/documents/SalesDocumentForm.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js +11 -6
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
- package/dist/modules/sales/components/documents/ShipmentDialog.js +102 -17
- package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/ShipmentsSection.js +19 -10
- package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/optimisticLock.js +27 -0
- package/dist/modules/sales/components/documents/optimisticLock.js.map +7 -0
- package/dist/modules/sales/di.js +18 -0
- package/dist/modules/sales/di.js.map +2 -2
- package/dist/modules/sales/frontend/quote/[token]/page.js +11 -1
- package/dist/modules/sales/frontend/quote/[token]/page.js.map +2 -2
- package/dist/modules/sales/lib/calculations.js +18 -1
- package/dist/modules/sales/lib/calculations.js.map +2 -2
- package/dist/modules/sales/lib/dictionaries.js +2 -2
- package/dist/modules/sales/lib/dictionaries.js.map +2 -2
- package/dist/modules/sales/lib/makeStatusDictionaryRoute.js +2 -0
- package/dist/modules/sales/lib/makeStatusDictionaryRoute.js.map +2 -2
- package/dist/modules/shipping_carriers/api/cancel/route.js +2 -2
- package/dist/modules/shipping_carriers/api/cancel/route.js.map +2 -2
- package/dist/modules/shipping_carriers/lib/status-sync.js +8 -1
- package/dist/modules/shipping_carriers/lib/status-sync.js.map +2 -2
- package/dist/modules/staff/api/job-histories.js +11 -2
- package/dist/modules/staff/api/job-histories.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-entries/route.js +11 -4
- package/dist/modules/staff/api/timesheets/time-entries/route.js.map +2 -2
- package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js +13 -8
- package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/leave-requests/page.js +9 -1
- package/dist/modules/staff/backend/staff/leave-requests/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js +2 -1
- package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/profile/create/page.js +1 -1
- package/dist/modules/staff/backend/staff/profile/create/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js +7 -4
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/page.js +17 -27
- package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js +48 -2
- package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-roles/page.js +17 -35
- package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +5 -2
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/page.js +24 -14
- package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/page.js +4 -1
- package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.js +18 -3
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js +35 -5
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/page.js +12 -3
- package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
- package/dist/modules/staff/commands/activities.js +53 -0
- package/dist/modules/staff/commands/activities.js.map +2 -2
- package/dist/modules/staff/commands/addresses.js +70 -0
- package/dist/modules/staff/commands/addresses.js.map +2 -2
- package/dist/modules/staff/commands/comments.js +21 -1
- package/dist/modules/staff/commands/comments.js.map +2 -2
- package/dist/modules/staff/commands/job-histories.js +88 -3
- package/dist/modules/staff/commands/job-histories.js.map +2 -2
- package/dist/modules/staff/commands/leave-requests.js +39 -1
- package/dist/modules/staff/commands/leave-requests.js.map +2 -2
- package/dist/modules/staff/commands/tag-assignments.js +33 -0
- package/dist/modules/staff/commands/tag-assignments.js.map +2 -2
- package/dist/modules/staff/commands/team-members.js +43 -0
- package/dist/modules/staff/commands/team-members.js.map +2 -2
- package/dist/modules/staff/commands/team-roles.js +23 -0
- package/dist/modules/staff/commands/team-roles.js.map +2 -2
- package/dist/modules/staff/commands/teams.js +23 -0
- package/dist/modules/staff/commands/teams.js.map +2 -2
- package/dist/modules/staff/commands/timesheets-entries.js +31 -1
- package/dist/modules/staff/commands/timesheets-entries.js.map +2 -2
- package/dist/modules/staff/commands/timesheets-projects.js +56 -2
- package/dist/modules/staff/commands/timesheets-projects.js.map +2 -2
- package/dist/modules/staff/components/LeaveRequestForm.js +2 -0
- package/dist/modules/staff/components/LeaveRequestForm.js.map +2 -2
- package/dist/modules/staff/components/TeamForm.js +2 -1
- package/dist/modules/staff/components/TeamForm.js.map +2 -2
- package/dist/modules/staff/components/TeamMemberForm.js +35 -4
- package/dist/modules/staff/components/TeamMemberForm.js.map +3 -3
- package/dist/modules/staff/components/TeamRoleForm.js +4 -3
- package/dist/modules/staff/components/TeamRoleForm.js.map +2 -2
- package/dist/modules/staff/components/detail/JobHistorySection.js +20 -7
- package/dist/modules/staff/components/detail/JobHistorySection.js.map +2 -2
- package/dist/modules/staff/data/validators.js +7 -1
- package/dist/modules/staff/data/validators.js.map +2 -2
- package/dist/modules/staff/lib/leaveRequestHelpers.js +2 -1
- package/dist/modules/staff/lib/leaveRequestHelpers.js.map +2 -2
- package/dist/modules/translations/api/[entityType]/[entityId]/route.js +9 -1
- package/dist/modules/translations/api/[entityType]/[entityId]/route.js.map +2 -2
- package/dist/modules/translations/components/TranslationManager.js +12 -8
- package/dist/modules/translations/components/TranslationManager.js.map +2 -2
- package/dist/modules/workflows/acl.js +102 -17
- package/dist/modules/workflows/acl.js.map +2 -2
- package/dist/modules/workflows/api/definitions/[id]/route.js +106 -0
- package/dist/modules/workflows/api/definitions/[id]/route.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/[id]/page.js +11 -3
- package/dist/modules/workflows/backend/definitions/[id]/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/page.js +33 -13
- package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js +29 -16
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
- package/dist/modules/workflows/components/NodeEditDialog.js +3 -1
- package/dist/modules/workflows/components/NodeEditDialog.js.map +2 -2
- package/dist/modules/workflows/components/WorkflowGraphImpl.js +4 -2
- package/dist/modules/workflows/components/WorkflowGraphImpl.js.map +2 -2
- package/dist/modules/workflows/components/formConfig.js +26 -13
- package/dist/modules/workflows/components/formConfig.js.map +2 -2
- package/dist/modules/workflows/components/nodes/ParallelForkNode.js +49 -0
- package/dist/modules/workflows/components/nodes/ParallelForkNode.js.map +7 -0
- package/dist/modules/workflows/components/nodes/ParallelJoinNode.js +49 -0
- package/dist/modules/workflows/components/nodes/ParallelJoinNode.js.map +7 -0
- package/dist/modules/workflows/components/nodes/index.js +4 -0
- package/dist/modules/workflows/components/nodes/index.js.map +2 -2
- package/dist/modules/workflows/data/entities.js +81 -0
- package/dist/modules/workflows/data/entities.js.map +2 -2
- package/dist/modules/workflows/data/validators.js +146 -1
- package/dist/modules/workflows/data/validators.js.map +2 -2
- package/dist/modules/workflows/di.js +12 -0
- package/dist/modules/workflows/di.js.map +2 -2
- package/dist/modules/workflows/events.js +7 -1
- package/dist/modules/workflows/events.js.map +2 -2
- package/dist/modules/workflows/lib/activity-executor.js +4 -2
- package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
- package/dist/modules/workflows/lib/activity-queue-types.js.map +2 -2
- package/dist/modules/workflows/lib/event-logger.js +2 -0
- package/dist/modules/workflows/lib/event-logger.js.map +2 -2
- package/dist/modules/workflows/lib/execution-token.js +98 -0
- package/dist/modules/workflows/lib/execution-token.js.map +7 -0
- package/dist/modules/workflows/lib/node-type-icons.js +14 -5
- package/dist/modules/workflows/lib/node-type-icons.js.map +2 -2
- package/dist/modules/workflows/lib/parallel-handler.js +364 -0
- package/dist/modules/workflows/lib/parallel-handler.js.map +7 -0
- package/dist/modules/workflows/lib/signal-handler.js +63 -1
- package/dist/modules/workflows/lib/signal-handler.js.map +2 -2
- package/dist/modules/workflows/lib/step-handler.js +74 -30
- package/dist/modules/workflows/lib/step-handler.js.map +2 -2
- package/dist/modules/workflows/lib/task-handler.js +26 -0
- package/dist/modules/workflows/lib/task-handler.js.map +2 -2
- package/dist/modules/workflows/lib/timer-handler.js +26 -1
- package/dist/modules/workflows/lib/timer-handler.js.map +2 -2
- package/dist/modules/workflows/lib/transition-handler.js +33 -21
- package/dist/modules/workflows/lib/transition-handler.js.map +2 -2
- package/dist/modules/workflows/lib/workflow-executor.js +54 -1
- package/dist/modules/workflows/lib/workflow-executor.js.map +2 -2
- package/dist/modules/workflows/migrations/Migration20260602120000.js +24 -0
- package/dist/modules/workflows/migrations/Migration20260602120000.js.map +7 -0
- package/dist/modules/workflows/workers/workflow-activities.worker.js +8 -4
- package/dist/modules/workflows/workers/workflow-activities.worker.js.map +2 -2
- package/generated/entities/channel_ingest_dead_letter/index.ts +11 -0
- package/generated/entities/channel_thread_mapping/index.ts +11 -0
- package/generated/entities/channel_thread_token/index.ts +7 -0
- package/generated/entities/communication_channel/index.ts +20 -0
- package/generated/entities/customer_interaction/index.ts +2 -0
- package/generated/entities/customer_settings/index.ts +1 -0
- package/generated/entities/dictionary/index.ts +1 -0
- package/generated/entities/external_conversation/index.ts +11 -0
- package/generated/entities/external_message/index.ts +11 -0
- package/generated/entities/inbox_settings/index.ts +1 -0
- package/generated/entities/integration_credentials/index.ts +1 -0
- package/generated/entities/message/index.ts +1 -0
- package/generated/entities/message_channel_link/index.ts +15 -0
- package/generated/entities/message_reaction/index.ts +11 -0
- package/generated/entities/role/index.ts +1 -0
- package/generated/entities/step_instance/index.ts +1 -0
- package/generated/entities/user/index.ts +1 -0
- package/generated/entities/user_task/index.ts +1 -0
- package/generated/entities/workflow_branch_instance/index.ts +18 -0
- package/generated/entities/workflow_event/index.ts +1 -0
- package/generated/entities/workflow_instance/index.ts +1 -0
- package/generated/entities.ids.generated.ts +12 -0
- package/generated/entity-fields-registry.ts +146 -0
- package/jest.config.cjs +4 -0
- package/jest.mocks/entities.ids.generated.js +9 -0
- package/jest.setup.ts +17 -0
- package/package.json +17 -15
- package/src/helpers/integration/api.ts +15 -2
- package/src/helpers/integration/authFixtures.ts +4 -1
- package/src/helpers/integration/communicationChannelsFixtures.ts +130 -0
- package/src/helpers/integration/crudFormFields.ts +48 -0
- package/src/helpers/integration/crudFormPersistence.ts +178 -0
- package/src/helpers/integration/currenciesFixtures.ts +60 -0
- package/src/helpers/integration/customerAccountsFixtures.ts +256 -0
- package/src/helpers/integration/dbFixtures.ts +15 -1
- package/src/helpers/integration/inboxFixtures.ts +36 -0
- package/src/helpers/integration/optimisticLockUi.ts +172 -0
- package/src/helpers/integration/salesFixtures.ts +29 -0
- package/src/helpers/integration/salesUi.ts +19 -12
- package/src/helpers/integration/standaloneEnv.ts +62 -0
- package/src/helpers/integration/undoHarness.ts +243 -0
- package/src/helpers/integration/workflowsFixtures.ts +231 -0
- package/src/modules/api_keys/backend/api-keys/page.tsx +18 -5
- package/src/modules/api_keys/data/validators.ts +3 -1
- package/src/modules/attachments/components/AttachmentPartitionSettings.tsx +19 -9
- package/src/modules/attachments/lib/ocrQueue.ts +9 -1
- package/src/modules/attachments/lib/security.ts +1 -1
- package/src/modules/audit_logs/api/audit-logs/actions/redo/route.ts +3 -1
- package/src/modules/audit_logs/api/audit-logs/actions/undo/route.ts +13 -2
- package/src/modules/audit_logs/data/entities.ts +1 -1
- package/src/modules/audit_logs/services/actionLogService.ts +18 -0
- package/src/modules/auth/api/logout.ts +0 -12
- package/src/modules/auth/api/roles/acl/route.ts +37 -11
- package/src/modules/auth/api/roles/route.ts +56 -2
- package/src/modules/auth/api/sidebar/preferences/route.ts +83 -3
- package/src/modules/auth/api/users/acl/route.ts +94 -33
- package/src/modules/auth/api/users/consents/route.ts +20 -0
- package/src/modules/auth/api/users/resend-invite/route.ts +20 -0
- package/src/modules/auth/api/users/route.ts +42 -1
- package/src/modules/auth/backend/roles/[id]/edit/page.tsx +29 -4
- package/src/modules/auth/backend/roles/page.tsx +17 -4
- package/src/modules/auth/backend/users/[id]/edit/page.tsx +92 -6
- package/src/modules/auth/backend/users/page.tsx +15 -2
- package/src/modules/auth/cli.ts +20 -21
- package/src/modules/auth/commands/roles.ts +81 -1
- package/src/modules/auth/commands/users.ts +117 -6
- package/src/modules/auth/components/AclEditor.tsx +10 -1
- package/src/modules/auth/data/entities.ts +7 -1
- package/src/modules/auth/frontend/reset/[token]/page.tsx +7 -2
- package/src/modules/auth/lib/consentIntegrity.ts +18 -2
- package/src/modules/auth/lib/emailHash.ts +5 -1
- package/src/modules/auth/lib/grantChecks.ts +55 -1
- package/src/modules/auth/lib/sessionIntegrity.ts +18 -1
- package/src/modules/auth/services/authService.ts +10 -19
- package/src/modules/auth/services/sidebarPreferencesService.ts +38 -4
- package/src/modules/business_rules/api/rules/route.ts +30 -0
- package/src/modules/business_rules/api/sets/route.ts +30 -0
- package/src/modules/business_rules/backend/rules/[id]/page.tsx +16 -4
- package/src/modules/business_rules/backend/rules/page.tsx +29 -12
- package/src/modules/business_rules/backend/sets/[id]/page.tsx +16 -4
- package/src/modules/business_rules/backend/sets/page.tsx +28 -11
- package/src/modules/catalog/AGENTS.md +10 -0
- package/src/modules/catalog/api/categories/route.ts +3 -0
- package/src/modules/catalog/api/products/route.ts +4 -0
- package/src/modules/catalog/backend/catalog/categories/[id]/edit/page.tsx +5 -0
- package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +174 -91
- package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx +121 -34
- package/src/modules/catalog/backend/catalog/products/[productId]/variants/create/page.tsx +22 -5
- package/src/modules/catalog/backend/catalog/products/create/page.tsx +5 -28
- package/src/modules/catalog/backend/catalog/products/optionSchemaClient.ts +2 -0
- package/src/modules/catalog/commands/categories.ts +42 -0
- package/src/modules/catalog/commands/offers.ts +44 -0
- package/src/modules/catalog/commands/optionSchemas.ts +10 -0
- package/src/modules/catalog/commands/priceKinds.ts +5 -0
- package/src/modules/catalog/commands/prices.ts +50 -0
- package/src/modules/catalog/commands/productUnitConversions.ts +32 -0
- package/src/modules/catalog/commands/products.ts +87 -0
- package/src/modules/catalog/commands/variants.ts +118 -32
- package/src/modules/catalog/components/PriceKindSettings.tsx +21 -7
- package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +9 -0
- package/src/modules/catalog/components/products/ProductMediaManager.tsx +2 -0
- package/src/modules/catalog/components/products/ProductsDataTable.tsx +16 -4
- package/src/modules/catalog/components/products/VariantBuilder.tsx +48 -9
- package/src/modules/catalog/components/products/productForm.ts +41 -0
- package/src/modules/catalog/components/products/variantForm.ts +10 -0
- package/src/modules/catalog/lib/pricing.ts +8 -0
- package/src/modules/communication_channels/acl.ts +43 -0
- package/src/modules/communication_channels/api/delete/channels/[id]/route.ts +163 -0
- package/src/modules/communication_channels/api/delete/messages/[messageId]/reactions/[reactionId]/route.ts +143 -0
- package/src/modules/communication_channels/api/get/channels/[id]/health/route.ts +173 -0
- package/src/modules/communication_channels/api/get/channels/[id]/route.ts +111 -0
- package/src/modules/communication_channels/api/get/channels/route.ts +109 -0
- package/src/modules/communication_channels/api/get/me/channels/route.ts +100 -0
- package/src/modules/communication_channels/api/get/oauth/[provider]/callback/route.ts +355 -0
- package/src/modules/communication_channels/api/post/channels/[id]/import-history/route.ts +206 -0
- package/src/modules/communication_channels/api/post/channels/[id]/poll-now/route.ts +174 -0
- package/src/modules/communication_channels/api/post/channels/[id]/push/register/route.ts +158 -0
- package/src/modules/communication_channels/api/post/channels/[id]/set-primary/route.ts +114 -0
- package/src/modules/communication_channels/api/post/channels/[id]/test-send/route.ts +241 -0
- package/src/modules/communication_channels/api/post/channels/connect/credentials/route.ts +134 -0
- package/src/modules/communication_channels/api/post/messages/[messageId]/reactions/route.ts +143 -0
- package/src/modules/communication_channels/api/post/oauth/[provider]/initiate/route.ts +192 -0
- package/src/modules/communication_channels/api/post/send-as-user/route.ts +125 -0
- package/src/modules/communication_channels/api/post/test-seed/route.ts +294 -0
- package/src/modules/communication_channels/api/post/webhook/[provider]/route.ts +227 -0
- package/src/modules/communication_channels/api/post/webhooks/gmail/route.ts +161 -0
- package/src/modules/communication_channels/api/put/threads/[threadId]/assign/route.ts +132 -0
- package/src/modules/communication_channels/backend/communication_channels/channels/[id]/page.meta.ts +34 -0
- package/src/modules/communication_channels/backend/communication_channels/channels/[id]/page.tsx +250 -0
- package/src/modules/communication_channels/backend/communication_channels/channels/page.meta.ts +36 -0
- package/src/modules/communication_channels/backend/communication_channels/channels/page.tsx +137 -0
- package/src/modules/communication_channels/backend/profile/communication-channels/page.meta.ts +36 -0
- package/src/modules/communication_channels/backend/profile/communication-channels/page.tsx +912 -0
- package/src/modules/communication_channels/commands/connect-credential-channel.ts +243 -0
- package/src/modules/communication_channels/commands/delete-channel.ts +193 -0
- package/src/modules/communication_channels/commands/deliver-outbound-message.ts +579 -0
- package/src/modules/communication_channels/commands/disconnect-channel.ts +241 -0
- package/src/modules/communication_channels/commands/ingest-inbound-message.ts +602 -0
- package/src/modules/communication_channels/commands/interceptors.ts +104 -0
- package/src/modules/communication_channels/commands/process-inbound-reaction.ts +265 -0
- package/src/modules/communication_channels/commands/push-register.ts +203 -0
- package/src/modules/communication_channels/commands/push-renew.ts +49 -0
- package/src/modules/communication_channels/commands/push-unregister.ts +168 -0
- package/src/modules/communication_channels/commands/queue-import-history.ts +180 -0
- package/src/modules/communication_channels/commands/reassign-conversation.ts +273 -0
- package/src/modules/communication_channels/commands/set-primary-channel.ts +157 -0
- package/src/modules/communication_channels/commands/toggle-outbound-reaction.ts +347 -0
- package/src/modules/communication_channels/data/enrichers.ts +413 -0
- package/src/modules/communication_channels/data/entities.ts +546 -0
- package/src/modules/communication_channels/data/extensions.ts +76 -0
- package/src/modules/communication_channels/data/validators.ts +138 -0
- package/src/modules/communication_channels/di.ts +40 -0
- package/src/modules/communication_channels/encryption.ts +44 -0
- package/src/modules/communication_channels/events.ts +122 -0
- package/src/modules/communication_channels/i18n/de.json +138 -0
- package/src/modules/communication_channels/i18n/en.json +138 -0
- package/src/modules/communication_channels/i18n/es.json +138 -0
- package/src/modules/communication_channels/i18n/pl.json +138 -0
- package/src/modules/communication_channels/index.ts +19 -0
- package/src/modules/communication_channels/lib/access-control.ts +110 -0
- package/src/modules/communication_channels/lib/adapter-compat.ts +57 -0
- package/src/modules/communication_channels/lib/adapter-registry-singleton.ts +35 -0
- package/src/modules/communication_channels/lib/adapter.ts +605 -0
- package/src/modules/communication_channels/lib/connect-channel.ts +163 -0
- package/src/modules/communication_channels/lib/contact-resolver.ts +162 -0
- package/src/modules/communication_channels/lib/credential-refresh.ts +197 -0
- package/src/modules/communication_channels/lib/dead-letter.ts +87 -0
- package/src/modules/communication_channels/lib/email-capabilities.ts +60 -0
- package/src/modules/communication_channels/lib/email-contact.ts +17 -0
- package/src/modules/communication_channels/lib/email-mime.ts +501 -0
- package/src/modules/communication_channels/lib/error-classification.ts +144 -0
- package/src/modules/communication_channels/lib/gmail-pubsub-jwt.ts +278 -0
- package/src/modules/communication_channels/lib/mutation-guards.ts +215 -0
- package/src/modules/communication_channels/lib/oauth-client-config.ts +79 -0
- package/src/modules/communication_channels/lib/oauth-state.ts +228 -0
- package/src/modules/communication_channels/lib/oauth-token.ts +81 -0
- package/src/modules/communication_channels/lib/pg-errors.ts +12 -0
- package/src/modules/communication_channels/lib/provider-health.ts +47 -0
- package/src/modules/communication_channels/lib/push-state.ts +38 -0
- package/src/modules/communication_channels/lib/queue.ts +66 -0
- package/src/modules/communication_channels/lib/reaction-processor-types.ts +51 -0
- package/src/modules/communication_channels/lib/reaction-semantics.ts +48 -0
- package/src/modules/communication_channels/lib/registry.ts +99 -0
- package/src/modules/communication_channels/lib/route-mutation-guard.ts +68 -0
- package/src/modules/communication_channels/lib/sanitize-channel-html.ts +129 -0
- package/src/modules/communication_channels/lib/send-as-user.ts +284 -0
- package/src/modules/communication_channels/lib/system-user.ts +74 -0
- package/src/modules/communication_channels/lib/test-seed.ts +140 -0
- package/src/modules/communication_channels/lib/thread-matcher.ts +430 -0
- package/src/modules/communication_channels/lib/thread-token.ts +355 -0
- package/src/modules/communication_channels/lib/use-connect-channel.ts +73 -0
- package/src/modules/communication_channels/migrations/.snapshot-open-mercato.json +2142 -0
- package/src/modules/communication_channels/migrations/Migration20260526134719_communication_channels.ts +55 -0
- package/src/modules/communication_channels/migrations/Migration20260527195446_communication_channels.ts +20 -0
- package/src/modules/communication_channels/migrations/Migration20260529231848_communication_channels.ts +13 -0
- package/src/modules/communication_channels/migrations/Migration20260531120000_communication_channels.ts +24 -0
- package/src/modules/communication_channels/notifications.client.ts +50 -0
- package/src/modules/communication_channels/notifications.handlers.ts +86 -0
- package/src/modules/communication_channels/notifications.ts +52 -0
- package/src/modules/communication_channels/setup.ts +158 -0
- package/src/modules/communication_channels/subscribers/channel-requires-reauth-notification.ts +118 -0
- package/src/modules/communication_channels/subscribers/outbound-bridge.ts +175 -0
- package/src/modules/communication_channels/subscribers/user-deleted-cascade.ts +100 -0
- package/src/modules/communication_channels/widgets/components.ts +36 -0
- package/src/modules/communication_channels/widgets/injection/channel-badge/widget.client.tsx +38 -0
- package/src/modules/communication_channels/widgets/injection/channel-badge/widget.ts +51 -0
- package/src/modules/communication_channels/widgets/injection/channel-info-panel/widget.client.tsx +278 -0
- package/src/modules/communication_channels/widgets/injection/channel-info-panel/widget.ts +24 -0
- package/src/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.tsx +63 -0
- package/src/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.ts +29 -0
- package/src/modules/communication_channels/widgets/injection/profile-channels-menu/widget.ts +34 -0
- package/src/modules/communication_channels/widgets/injection/reaction-bar/widget.client.tsx +177 -0
- package/src/modules/communication_channels/widgets/injection/reaction-bar/widget.ts +26 -0
- package/src/modules/communication_channels/widgets/injection-table.ts +47 -0
- package/src/modules/communication_channels/widgets/notifications/ChannelRequiresReauthRenderer.tsx +48 -0
- package/src/modules/communication_channels/widgets/notifications/MessageReceivedRenderer.tsx +45 -0
- package/src/modules/communication_channels/widgets/notifications/index.ts +2 -0
- package/src/modules/communication_channels/workers/channel-import-history.ts +252 -0
- package/src/modules/communication_channels/workers/gmail-history-sync.ts +223 -0
- package/src/modules/communication_channels/workers/gmail-renew-watch.ts +141 -0
- package/src/modules/communication_channels/workers/inbound-processor.ts +114 -0
- package/src/modules/communication_channels/workers/outbound-delivery.ts +155 -0
- package/src/modules/communication_channels/workers/poll-channel.ts +391 -0
- package/src/modules/communication_channels/workers/poll-tick.ts +210 -0
- package/src/modules/communication_channels/workers/reaction-processor.ts +264 -0
- package/src/modules/configs/api/openapi.ts +12 -2
- package/src/modules/currencies/backend/currencies/[id]/page.tsx +13 -6
- package/src/modules/currencies/backend/currencies/page.tsx +26 -11
- package/src/modules/currencies/backend/exchange-rates/[id]/page.tsx +3 -0
- package/src/modules/currencies/backend/exchange-rates/page.tsx +21 -12
- package/src/modules/currencies/commands/currencies.ts +42 -18
- package/src/modules/currencies/commands/exchange-rates.ts +18 -8
- package/src/modules/currencies/components/CurrencyFetchingConfig.tsx +31 -21
- package/src/modules/currencies/i18n/de.json +1 -0
- package/src/modules/currencies/i18n/en.json +1 -0
- package/src/modules/currencies/i18n/es.json +1 -0
- package/src/modules/currencies/i18n/pl.json +1 -0
- package/src/modules/customer_accounts/api/admin/roles/[id].ts +35 -5
- package/src/modules/customer_accounts/api/admin/roles.ts +2 -0
- package/src/modules/customer_accounts/api/admin/users/[id].ts +57 -5
- package/src/modules/customer_accounts/api/admin/users-invite.ts +17 -0
- package/src/modules/customer_accounts/api/admin/users.ts +74 -23
- package/src/modules/customer_accounts/api/login.ts +21 -4
- package/src/modules/customer_accounts/api/portal/users-invite.ts +17 -0
- package/src/modules/customer_accounts/api/signup.ts +3 -1
- package/src/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.tsx +34 -20
- package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +20 -6
- package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/page.tsx +11 -4
- package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +28 -17
- package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +27 -11
- package/src/modules/customer_accounts/data/validators.ts +1 -0
- package/src/modules/customer_accounts/lib/customerEntityOwnership.ts +39 -0
- package/src/modules/customer_accounts/lib/rateLimiter.ts +14 -0
- package/src/modules/customer_accounts/lib/resolveTenantContext.ts +61 -4
- package/src/modules/customer_accounts/services/customerInvitationService.ts +35 -2
- package/src/modules/customer_accounts/services/customerUserService.ts +13 -7
- package/src/modules/customer_accounts/subscribers/autoLinkCrmReverse.ts +3 -3
- package/src/modules/customers/AGENTS.md +8 -2
- package/src/modules/customers/acl.ts +18 -0
- package/src/modules/customers/agentic/standalone-guide.md +1 -1
- package/src/modules/customers/api/activities/route.ts +42 -21
- package/src/modules/customers/api/addresses/route.ts +2 -0
- package/src/modules/customers/api/companies/[id]/route.ts +26 -3
- package/src/modules/customers/api/companies/route.ts +18 -5
- package/src/modules/customers/api/deals/route.ts +3 -0
- package/src/modules/customers/api/dictionaries/[kind]/route.ts +21 -46
- package/src/modules/customers/api/dictionaries/cache.ts +3 -1
- package/src/modules/customers/api/dictionaries/context.ts +1 -1
- package/src/modules/customers/api/interactions/[id]/visibility/route.ts +179 -0
- package/src/modules/customers/api/interactions/counts/route.ts +10 -0
- package/src/modules/customers/api/interactions/route.ts +58 -11
- package/src/modules/customers/api/people/[id]/email-threads/route.ts +92 -0
- package/src/modules/customers/api/people/[id]/emails/route.ts +184 -0
- package/src/modules/customers/api/people/[id]/route.ts +26 -8
- package/src/modules/customers/api/people/route.ts +16 -5
- package/src/modules/customers/api/pipeline-stages/route.ts +0 -14
- package/src/modules/customers/api/settings/dictionary-sort-modes/route.ts +258 -0
- package/src/modules/customers/api/todos/route.ts +29 -11
- package/src/modules/customers/backend/config/customers/deals/page.tsx +1 -0
- package/src/modules/customers/backend/config/customers/pipeline-stages/page.tsx +36 -21
- package/src/modules/customers/backend/customers/companies/[id]/page.tsx +52 -27
- package/src/modules/customers/backend/customers/companies/page.tsx +11 -1
- package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +27 -5
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.ts +39 -7
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +1 -0
- package/src/modules/customers/backend/customers/deals/page.tsx +27 -7
- package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +64 -39
- package/src/modules/customers/backend/customers/people/[id]/page.tsx +46 -26
- package/src/modules/customers/backend/customers/people/page.tsx +11 -1
- package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +95 -25
- package/src/modules/customers/commands/activities.ts +28 -0
- package/src/modules/customers/commands/addresses.ts +100 -14
- package/src/modules/customers/commands/comments.ts +30 -0
- package/src/modules/customers/commands/companies.ts +121 -1
- package/src/modules/customers/commands/deals.ts +241 -101
- package/src/modules/customers/commands/dictionaries.ts +45 -0
- package/src/modules/customers/commands/entity-roles.ts +49 -0
- package/src/modules/customers/commands/interactions.ts +264 -8
- package/src/modules/customers/commands/labels.ts +85 -0
- package/src/modules/customers/commands/people.ts +208 -13
- package/src/modules/customers/commands/personCompanyLinks.ts +148 -70
- package/src/modules/customers/commands/pipeline-stages.ts +16 -16
- package/src/modules/customers/commands/settings.ts +41 -0
- package/src/modules/customers/commands/tags.ts +59 -0
- package/src/modules/customers/commands/todos.ts +28 -0
- package/src/modules/customers/components/AddressFormatSettings.tsx +1 -0
- package/src/modules/customers/components/CustomersConfigurationSections.tsx +3 -0
- package/src/modules/customers/components/DictionarySettings.tsx +18 -13
- package/src/modules/customers/components/DictionarySortSettings.tsx +268 -0
- package/src/modules/customers/components/PipelineSettings.tsx +42 -21
- package/src/modules/customers/components/detail/ActivityCard.tsx +48 -0
- package/src/modules/customers/components/detail/ActivityForm.tsx +1 -0
- package/src/modules/customers/components/detail/ActivityTimeline.tsx +3 -3
- package/src/modules/customers/components/detail/AddressesSection.tsx +4 -0
- package/src/modules/customers/components/detail/AnnualRevenueField.tsx +1 -0
- package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +2 -0
- package/src/modules/customers/components/detail/ComposeEmailDialog.tsx +329 -0
- package/src/modules/customers/components/detail/DealForm.tsx +3 -1
- package/src/modules/customers/components/detail/DealsSection.tsx +30 -0
- package/src/modules/customers/components/detail/EmailCardActions.tsx +263 -0
- package/src/modules/customers/components/detail/EmailReplyForwardActions.tsx +53 -0
- package/src/modules/customers/components/detail/EntityTagsDialog.tsx +7 -0
- package/src/modules/customers/components/detail/ManageTagsDialog.tsx +4 -0
- package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +4 -0
- package/src/modules/customers/components/detail/PersonDetailTabs.tsx +8 -1
- package/src/modules/customers/components/detail/PersonEmailThreadsTab.tsx +448 -0
- package/src/modules/customers/components/detail/RoleAssignmentRow.tsx +2 -0
- package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +23 -7
- package/src/modules/customers/components/detail/create/DealCurrencyField.tsx +1 -0
- package/src/modules/customers/components/detail/hooks/useCustomerDictionary.ts +1 -0
- package/src/modules/customers/components/detail/hooks/useInteractionMutations.ts +25 -15
- package/src/modules/customers/components/detail/hooks/useInteractions.ts +76 -35
- package/src/modules/customers/components/detail/hooks/usePersonTasks.ts +30 -17
- package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +2 -0
- package/src/modules/customers/components/detail/types.ts +1 -0
- package/src/modules/customers/components/formConfig.tsx +134 -30
- package/src/modules/customers/data/enrichers.ts +252 -1
- package/src/modules/customers/data/entities.ts +51 -2
- package/src/modules/customers/data/extensions.ts +26 -0
- package/src/modules/customers/data/guards.ts +67 -0
- package/src/modules/customers/data/validators.ts +46 -13
- package/src/modules/customers/di.ts +66 -0
- package/src/modules/customers/encryption.ts +11 -0
- package/src/modules/customers/events.ts +4 -0
- package/src/modules/customers/i18n/de.json +50 -0
- package/src/modules/customers/i18n/en.json +50 -0
- package/src/modules/customers/i18n/es.json +50 -0
- package/src/modules/customers/i18n/pl.json +50 -0
- package/src/modules/customers/lib/detailTenantScope.ts +36 -0
- package/src/modules/customers/lib/findPeopleByAddresses.ts +107 -0
- package/src/modules/customers/lib/kysely.ts +16 -0
- package/src/modules/customers/lib/link-channel-message-handler.ts +571 -0
- package/src/modules/customers/lib/personCompanyLinkTable.ts +39 -0
- package/src/modules/customers/lib/personEmailThreads.ts +325 -0
- package/src/modules/customers/lib/todoCompatibility.ts +14 -0
- package/src/modules/customers/lib/visibilityFilter.ts +152 -0
- package/src/modules/customers/migrations/.snapshot-open-mercato.json +392 -0
- package/src/modules/customers/migrations/Migration20260527012240_customers.ts +23 -0
- package/src/modules/customers/migrations/Migration20260602202147_customers.ts +13 -0
- package/src/modules/customers/search.ts +6 -0
- package/src/modules/customers/setup.ts +1 -0
- package/src/modules/customers/subscribers/link-channel-message-received.ts +21 -0
- package/src/modules/customers/subscribers/link-channel-message-sent.ts +21 -0
- package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +2 -0
- package/src/modules/data_sync/api/options.ts +7 -4
- package/src/modules/data_sync/api/schedules/route.ts +9 -1
- package/src/modules/data_sync/backend/data-sync/page.tsx +18 -5
- package/src/modules/data_sync/components/IntegrationScheduleTab.tsx +46 -19
- package/src/modules/data_sync/i18n/de.json +1 -0
- package/src/modules/data_sync/i18n/en.json +1 -0
- package/src/modules/data_sync/i18n/es.json +1 -0
- package/src/modules/data_sync/i18n/pl.json +1 -0
- package/src/modules/data_sync/lib/sync-schedule-service.ts +11 -0
- package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +8 -1
- package/src/modules/dictionaries/api/[dictionaryId]/entries/route.ts +12 -5
- package/src/modules/dictionaries/api/[dictionaryId]/route.ts +31 -0
- package/src/modules/dictionaries/api/openapi.ts +2 -1
- package/src/modules/dictionaries/api/route.ts +7 -0
- package/src/modules/dictionaries/commands/entry-operations.ts +19 -0
- package/src/modules/dictionaries/components/DictionariesManager.tsx +125 -14
- package/src/modules/dictionaries/components/DictionaryEntriesEditor.tsx +31 -18
- package/src/modules/dictionaries/components/DictionaryEntrySelect.tsx +56 -9
- package/src/modules/dictionaries/components/DictionarySelectControl.tsx +9 -0
- package/src/modules/dictionaries/components/dictionaryAppearance.tsx +5 -1
- package/src/modules/dictionaries/components/hooks/useDictionaryEntries.ts +1 -0
- package/src/modules/dictionaries/data/entities.ts +6 -0
- package/src/modules/dictionaries/data/validators.ts +2 -0
- package/src/modules/dictionaries/fields/dictionary.tsx +2 -2
- package/src/modules/dictionaries/i18n/de.json +9 -0
- package/src/modules/dictionaries/i18n/en.json +9 -0
- package/src/modules/dictionaries/i18n/es.json +9 -0
- package/src/modules/dictionaries/i18n/pl.json +9 -0
- package/src/modules/dictionaries/lib/entrySort.ts +73 -0
- package/src/modules/dictionaries/migrations/.snapshot-open-mercato.json +44 -0
- package/src/modules/dictionaries/migrations/Migration20260602202147_dictionaries.ts +13 -0
- package/src/modules/directory/api/get/organizations/lookup.ts +0 -8
- package/src/modules/directory/api/organizations/route.ts +40 -16
- package/src/modules/directory/backend/directory/organizations/[id]/edit/page.tsx +8 -0
- package/src/modules/directory/backend/directory/organizations/page.tsx +18 -5
- package/src/modules/directory/backend/directory/tenants/[id]/edit/page.tsx +16 -5
- package/src/modules/directory/backend/directory/tenants/page.tsx +16 -4
- package/src/modules/directory/commands/organizations.ts +74 -4
- package/src/modules/directory/commands/tenants.ts +14 -1
- package/src/modules/entities/api/records.ts +141 -6
- package/src/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.tsx +7 -0
- package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +8 -4
- package/src/modules/entities/components/UserEntitiesTable.tsx +8 -0
- package/src/modules/entities/lib/entityAcl.ts +108 -0
- package/src/modules/entities/lib/helpers.ts +40 -5
- package/src/modules/feature_toggles/api/global/[id]/override/route.ts +18 -13
- package/src/modules/feature_toggles/api/global/[id]/route.ts +1 -0
- package/src/modules/feature_toggles/api/overrides/route.ts +26 -9
- package/src/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.tsx +42 -15
- package/src/modules/feature_toggles/commands/global.ts +135 -10
- package/src/modules/feature_toggles/commands/overrides.ts +8 -6
- package/src/modules/feature_toggles/components/FeatureToggleOverrideCard.tsx +22 -12
- package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +15 -2
- package/src/modules/feature_toggles/components/formConfig.tsx +2 -1
- package/src/modules/feature_toggles/components/overrideFormConfig.tsx +10 -1
- package/src/modules/feature_toggles/data/validators.ts +11 -3
- package/src/modules/feature_toggles/lib/queries.ts +5 -5
- package/src/modules/feature_toggles/lib/utils.ts +3 -3
- package/src/modules/inbox_ops/api/proposals/[id]/replies/[replyId]/send/route.ts +10 -1
- package/src/modules/inbox_ops/api/settings/route.ts +25 -0
- package/src/modules/inbox_ops/api/webhook/inbound.ts +99 -18
- package/src/modules/inbox_ops/backend/inbox-ops/settings/page.tsx +15 -10
- package/src/modules/inbox_ops/components/proposals/EditActionDialog.tsx +9 -4
- package/src/modules/inbox_ops/data/entities.ts +7 -0
- package/src/modules/inbox_ops/data/validators.ts +4 -0
- package/src/modules/inbox_ops/encryption.ts +9 -0
- package/src/modules/inbox_ops/i18n/de.json +2 -0
- package/src/modules/inbox_ops/i18n/en.json +2 -0
- package/src/modules/inbox_ops/i18n/es.json +2 -0
- package/src/modules/inbox_ops/i18n/pl.json +2 -0
- package/src/modules/inbox_ops/lib/executionEngine.ts +6 -1
- package/src/modules/inbox_ops/lib/executionHelpers.ts +8 -7
- package/src/modules/inbox_ops/lib/priceValidator.ts +82 -7
- package/src/modules/inbox_ops/lib/rateLimiter.ts +84 -28
- package/src/modules/inbox_ops/lib/translationProvider.ts +37 -5
- package/src/modules/inbox_ops/migrations/.snapshot-open-mercato.json +16 -0
- package/src/modules/inbox_ops/migrations/.snapshot-openmercato.json +16 -0
- package/src/modules/inbox_ops/migrations/Migration20260607205834.ts +13 -0
- package/src/modules/inbox_ops/subscribers/extractionWorker.ts +5 -2
- package/src/modules/integrations/AGENTS.md +9 -0
- package/src/modules/integrations/api/[id]/credentials/route.ts +12 -0
- package/src/modules/integrations/backend/integrations/[id]/page.tsx +13 -0
- package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +20 -11
- package/src/modules/integrations/backend/integrations/page.tsx +13 -8
- package/src/modules/integrations/data/entities.ts +21 -1
- package/src/modules/integrations/i18n/de.json +3 -0
- package/src/modules/integrations/i18n/en.json +3 -0
- package/src/modules/integrations/i18n/es.json +3 -0
- package/src/modules/integrations/i18n/pl.json +3 -0
- package/src/modules/integrations/lib/credentials-field-validation.ts +53 -0
- package/src/modules/integrations/lib/credentials-service.ts +49 -13
- package/src/modules/integrations/migrations/.snapshot-open-mercato.json +26 -1
- package/src/modules/integrations/migrations/Migration20260526154136_integrations.ts +15 -0
- package/src/modules/messages/api/route.ts +2 -2
- package/src/modules/messages/api/token/[token]/route.ts +1 -3
- package/src/modules/messages/commands/actions.ts +8 -6
- package/src/modules/messages/commands/messages.ts +128 -23
- package/src/modules/messages/commands/tokens.ts +1 -3
- package/src/modules/messages/components/ComposeMessagePageClient.tsx +17 -0
- package/src/modules/messages/components/MessageDetailPageClient.tsx +43 -0
- package/src/modules/messages/components/MessagesInboxPageClient.tsx +12 -0
- package/src/modules/messages/components/message-detail/hooks/useMessageDetailsActions.ts +6 -2
- package/src/modules/messages/components/message-detail/utils.ts +18 -0
- package/src/modules/messages/data/entities.ts +11 -0
- package/src/modules/messages/data/validators.ts +8 -1
- package/src/modules/messages/lib/actions.ts +9 -3
- package/src/modules/messages/migrations/.snapshot-open-mercato.json +18 -0
- package/src/modules/messages/migrations/Migration20260531130000.ts +15 -0
- package/src/modules/messages/widgets/injection-table.ts +29 -0
- package/src/modules/notifications/api/[id]/action/route.ts +13 -2
- package/src/modules/notifications/api/route.ts +17 -4
- package/src/modules/notifications/lib/notificationService.ts +31 -21
- package/src/modules/notifications/lib/routeHelpers.ts +49 -8
- package/src/modules/payment_gateways/api/status/route.ts +6 -0
- package/src/modules/perspectives/api/[tableId]/route.ts +11 -2
- package/src/modules/perspectives/services/perspectiveService.ts +13 -1
- package/src/modules/planner/backend/planner/availability-rulesets/[id]/page.tsx +16 -14
- package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +6 -3
- package/src/modules/planner/commands/availability-rule-sets.ts +19 -0
- package/src/modules/planner/commands/availability.ts +9 -0
- package/src/modules/planner/components/AvailabilityRuleSetForm.tsx +4 -1
- package/src/modules/planner/components/AvailabilityRulesEditor.tsx +74 -17
- package/src/modules/planner/components/AvailabilitySchedule.tsx +22 -7
- package/src/modules/portal/frontend/[orgSlug]/portal/login/page.tsx +15 -16
- package/src/modules/portal/frontend/[orgSlug]/portal/page.tsx +11 -31
- package/src/modules/portal/frontend/[orgSlug]/portal/reset-password/page.tsx +8 -3
- package/src/modules/portal/frontend/[orgSlug]/portal/signup/page.tsx +12 -9
- package/src/modules/progress/api/jobs/[id]/route.ts +7 -0
- package/src/modules/query_index/api/openapi.ts +2 -1
- package/src/modules/query_index/api/reindex.ts +4 -0
- package/src/modules/query_index/data/entities.ts +10 -0
- package/src/modules/query_index/lib/engine.ts +66 -6
- package/src/modules/query_index/lib/indexer.ts +71 -24
- package/src/modules/query_index/lib/jobs.ts +57 -0
- package/src/modules/query_index/lib/reindexer.ts +41 -15
- package/src/modules/query_index/lib/search-tokens.ts +4 -4
- package/src/modules/query_index/migrations/.snapshot-open-mercato.json +9 -0
- package/src/modules/query_index/migrations/Migration20260606205453_query_index.ts +39 -0
- package/src/modules/query_index/subscribers/delete_one.ts +36 -16
- package/src/modules/query_index/subscribers/upsert_one.ts +44 -15
- package/src/modules/resources/backend/resources/resource-types/[id]/edit/page.tsx +28 -3
- package/src/modules/resources/backend/resources/resource-types/page.tsx +6 -3
- package/src/modules/resources/backend/resources/resources/[id]/page.tsx +62 -4
- package/src/modules/resources/backend/resources/resources/page.tsx +23 -4
- package/src/modules/resources/commands/activities.ts +67 -0
- package/src/modules/resources/commands/comments.ts +20 -0
- package/src/modules/resources/commands/resource-types.ts +21 -0
- package/src/modules/resources/commands/resources.ts +89 -0
- package/src/modules/resources/commands/tag-assignments.ts +55 -0
- package/src/modules/resources/components/ResourceCrudForm.tsx +103 -56
- package/src/modules/resources/components/ResourceTypeCrudForm.tsx +3 -1
- package/src/modules/resources/i18n/de.json +1 -0
- package/src/modules/resources/i18n/en.json +1 -0
- package/src/modules/resources/i18n/es.json +1 -0
- package/src/modules/resources/i18n/pl.json +1 -0
- package/src/modules/sales/api/documents/factory.ts +13 -1
- package/src/modules/sales/api/shipping-methods/route.ts +4 -0
- package/src/modules/sales/api/tax-rates/route.ts +4 -0
- package/src/modules/sales/backend/sales/channels/[channelId]/edit/page.tsx +6 -0
- package/src/modules/sales/backend/sales/channels/offers/page.tsx +10 -4
- package/src/modules/sales/backend/sales/channels/page.tsx +19 -4
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +75 -20
- package/src/modules/sales/backend/sales/documents/create/page.tsx +2 -0
- package/src/modules/sales/commands/configuration.ts +108 -2
- package/src/modules/sales/commands/documentAddresses.ts +226 -4
- package/src/modules/sales/commands/documents.ts +41 -9
- package/src/modules/sales/commands/notes.ts +39 -0
- package/src/modules/sales/commands/payments.ts +160 -14
- package/src/modules/sales/commands/returns.ts +194 -3
- package/src/modules/sales/commands/shared.ts +36 -0
- package/src/modules/sales/commands/shipments.ts +63 -6
- package/src/modules/sales/components/AdjustmentKindSettings.tsx +20 -11
- package/src/modules/sales/components/DocumentNumberSettings.tsx +1 -0
- package/src/modules/sales/components/OrderEditingSettings.tsx +1 -0
- package/src/modules/sales/components/PaymentMethodsSettings.tsx +12 -4
- package/src/modules/sales/components/ShippingMethodsSettings.tsx +12 -4
- package/src/modules/sales/components/StatusSettings.tsx +20 -11
- package/src/modules/sales/components/TaxRatesSettings.tsx +12 -5
- package/src/modules/sales/components/channels/ChannelOfferForm.tsx +85 -20
- package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +10 -4
- package/src/modules/sales/components/documents/AddressesSection.tsx +116 -48
- package/src/modules/sales/components/documents/AdjustmentDialog.tsx +61 -18
- package/src/modules/sales/components/documents/AdjustmentsSection.tsx +50 -25
- package/src/modules/sales/components/documents/ItemsSection.tsx +25 -14
- package/src/modules/sales/components/documents/LineItemDialog.tsx +107 -36
- package/src/modules/sales/components/documents/PaymentDialog.tsx +33 -14
- package/src/modules/sales/components/documents/PaymentsSection.tsx +22 -10
- package/src/modules/sales/components/documents/ReturnDialog.tsx +28 -17
- package/src/modules/sales/components/documents/ReturnsSection.tsx +4 -1
- package/src/modules/sales/components/documents/SalesDocumentForm.tsx +1 -0
- package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +12 -5
- package/src/modules/sales/components/documents/ShipmentDialog.tsx +132 -22
- package/src/modules/sales/components/documents/ShipmentsSection.tsx +20 -10
- package/src/modules/sales/components/documents/optimisticLock.ts +34 -0
- package/src/modules/sales/components/documents/shipmentTypes.ts +1 -0
- package/src/modules/sales/di.ts +35 -0
- package/src/modules/sales/frontend/quote/[token]/page.tsx +8 -1
- package/src/modules/sales/i18n/de.json +4 -0
- package/src/modules/sales/i18n/en.json +4 -0
- package/src/modules/sales/i18n/es.json +4 -0
- package/src/modules/sales/i18n/pl.json +4 -0
- package/src/modules/sales/lib/calculations.ts +32 -4
- package/src/modules/sales/lib/dictionaries.ts +3 -2
- package/src/modules/sales/lib/makeStatusDictionaryRoute.ts +2 -0
- package/src/modules/shipping_carriers/api/cancel/route.ts +2 -2
- package/src/modules/shipping_carriers/lib/status-sync.ts +19 -0
- package/src/modules/staff/api/job-histories.ts +12 -2
- package/src/modules/staff/api/timesheets/time-entries/route.ts +16 -4
- package/src/modules/staff/backend/staff/leave-requests/[id]/page.tsx +12 -7
- package/src/modules/staff/backend/staff/leave-requests/page.tsx +8 -1
- package/src/modules/staff/backend/staff/my-leave-requests/[id]/page.tsx +2 -0
- package/src/modules/staff/backend/staff/profile/create/page.tsx +1 -1
- package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +16 -5
- package/src/modules/staff/backend/staff/team-members/page.tsx +18 -25
- package/src/modules/staff/backend/staff/team-roles/[id]/edit/page.tsx +61 -6
- package/src/modules/staff/backend/staff/team-roles/page.tsx +22 -34
- package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +13 -3
- package/src/modules/staff/backend/staff/teams/page.tsx +24 -15
- package/src/modules/staff/backend/staff/timesheets/page.tsx +10 -1
- package/src/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.tsx +22 -3
- package/src/modules/staff/backend/staff/timesheets/projects/[id]/page.tsx +37 -7
- package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +9 -3
- package/src/modules/staff/commands/activities.ts +56 -0
- package/src/modules/staff/commands/addresses.ts +72 -0
- package/src/modules/staff/commands/comments.ts +25 -0
- package/src/modules/staff/commands/job-histories.ts +92 -3
- package/src/modules/staff/commands/leave-requests.ts +40 -0
- package/src/modules/staff/commands/tag-assignments.ts +35 -0
- package/src/modules/staff/commands/team-members.ts +45 -0
- package/src/modules/staff/commands/team-roles.ts +24 -0
- package/src/modules/staff/commands/teams.ts +24 -0
- package/src/modules/staff/commands/timesheets-entries.ts +31 -0
- package/src/modules/staff/commands/timesheets-projects.ts +56 -0
- package/src/modules/staff/components/LeaveRequestForm.tsx +3 -0
- package/src/modules/staff/components/TeamForm.tsx +3 -1
- package/src/modules/staff/components/TeamMemberForm.tsx +36 -3
- package/src/modules/staff/components/TeamRoleForm.tsx +5 -3
- package/src/modules/staff/components/detail/JobHistorySection.tsx +28 -6
- package/src/modules/staff/data/validators.ts +6 -0
- package/src/modules/staff/i18n/de.json +2 -0
- package/src/modules/staff/i18n/en.json +2 -0
- package/src/modules/staff/i18n/es.json +2 -0
- package/src/modules/staff/i18n/pl.json +2 -0
- package/src/modules/staff/lib/leaveRequestHelpers.ts +4 -0
- package/src/modules/translations/api/[entityType]/[entityId]/route.ts +9 -1
- package/src/modules/translations/components/TranslationManager.tsx +13 -8
- package/src/modules/workflows/acl.ts +102 -17
- package/src/modules/workflows/api/definitions/[id]/route.ts +112 -0
- package/src/modules/workflows/backend/definitions/[id]/page.tsx +20 -4
- package/src/modules/workflows/backend/definitions/page.tsx +34 -15
- package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +29 -16
- package/src/modules/workflows/components/NodeEditDialog.tsx +2 -0
- package/src/modules/workflows/components/WorkflowGraphImpl.tsx +3 -1
- package/src/modules/workflows/components/formConfig.tsx +37 -17
- package/src/modules/workflows/components/nodes/ParallelForkNode.tsx +66 -0
- package/src/modules/workflows/components/nodes/ParallelJoinNode.tsx +66 -0
- package/src/modules/workflows/components/nodes/index.ts +6 -0
- package/src/modules/workflows/data/entities.ts +109 -0
- package/src/modules/workflows/data/validators.ts +223 -0
- package/src/modules/workflows/di.ts +20 -0
- package/src/modules/workflows/events.ts +7 -0
- package/src/modules/workflows/i18n/de.json +13 -0
- package/src/modules/workflows/i18n/en.json +13 -0
- package/src/modules/workflows/i18n/es.json +13 -0
- package/src/modules/workflows/i18n/pl.json +13 -0
- package/src/modules/workflows/lib/activity-executor.ts +8 -2
- package/src/modules/workflows/lib/activity-queue-types.ts +3 -0
- package/src/modules/workflows/lib/event-logger.ts +3 -0
- package/src/modules/workflows/lib/execution-token.ts +166 -0
- package/src/modules/workflows/lib/node-type-icons.ts +11 -2
- package/src/modules/workflows/lib/parallel-handler.ts +575 -0
- package/src/modules/workflows/lib/signal-handler.ts +72 -1
- package/src/modules/workflows/lib/step-handler.ts +94 -34
- package/src/modules/workflows/lib/task-handler.ts +32 -0
- package/src/modules/workflows/lib/timer-handler.ts +30 -1
- package/src/modules/workflows/lib/transition-handler.ts +56 -24
- package/src/modules/workflows/lib/workflow-executor.ts +70 -1
- package/src/modules/workflows/migrations/.snapshot-open-mercato.json +263 -0
- package/src/modules/workflows/migrations/Migration20260602120000.ts +25 -0
- package/src/modules/workflows/workers/workflow-activities.worker.ts +9 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/sales/components/channels/ChannelOfferForm.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { CrudForm, type CrudField, type CrudFormGroup, type CrudFormGroupComponentProps } from '@open-mercato/ui/backend/CrudForm'\nimport { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'\nimport { createCrud, updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { createCrudFormError, type CrudServerFieldErrors } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { readApiResultOrThrow, apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { Loader2, Search, Image as ImageIcon, Trash2 } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { extractCustomFieldEntries } from '@open-mercato/shared/lib/crud/custom-fields-client'\nimport { E } from '#generated/entities.ids.generated'\nimport { buildAttachmentImageUrl, slugifyAttachmentFileName } from '@open-mercato/core/modules/attachments/lib/imageUrls'\nimport { cn } from '@open-mercato/shared/lib/utils'\n\ntype PriceKindSummary = {\n id: string\n code: string | null\n title: string | null\n displayMode: 'including-tax' | 'excluding-tax'\n currencyCode: string | null\n}\n\ntype PriceOverrideDraft = {\n tempId: string\n priceId?: string | null\n priceKindId?: string | null\n priceKindCode?: string | null\n currencyCode?: string | null\n displayMode?: 'including-tax' | 'excluding-tax' | null\n amount?: string\n}\n\nexport type OfferFormValues = {\n channelId: string | null\n productId: string | null\n title: string\n description: string\n defaultMediaId?: string | null\n isActive: boolean\n priceOverrides: PriceOverrideDraft[]\n} & Record<string, unknown>\n\ntype ChannelOfferFormProps = {\n channelId?: string\n offerId?: string\n mode: 'create' | 'edit'\n}\n\ntype OfferResponse = {\n items?: Array<Record<string, unknown>>\n}\n\ntype PriceResponse = {\n items?: Array<Record<string, unknown>>\n}\n\ntype AttachmentsResponse = {\n items?: Array<{ id?: string; fileName?: string; url?: string; thumbnailUrl?: string | null }>\n}\n\ntype ProductSummaryCacheEntry = {\n title: string\n description: string | null\n defaultMediaId: string | null\n defaultMediaUrl: string | null\n sku: string | null\n pricing: PricingSummary | null\n}\n\ntype MediaOption = { id: string; label: string; fileName: string; thumbnailUrl?: string | null }\n\ntype PricingSummary = {\n currencyCode: string | null\n unitPriceNet: string | null\n unitPriceGross: string | null\n displayMode: 'including-tax' | 'excluding-tax' | null\n}\n\ntype ProductVariantPreview = {\n id: string\n name: string\n sku: string | null\n thumbnailUrl: string | null\n thumbnailId: string | null\n thumbnailFileName: string | null\n}\n\ntype ProductSummary = ProductSummaryCacheEntry | null\n\ntype ProductSearchResult = {\n id: string\n title: string\n sku: string | null\n defaultMediaUrl: string | null\n pricing: PricingSummary | null\n existingOfferId: string | null\n existingOfferTitle: string | null\n isCurrentOfferProduct: boolean\n}\n\nconst UUID_REGEX = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/\nconst MAX_LIST_PAGE_SIZE = 100\ntype VariantThumbnailInfo = { attachmentId: string | null; thumbnailUrl: string | null; fileName: string | null }\n\nexport function ChannelOfferForm({ channelId: lockedChannelId, offerId, mode }: ChannelOfferFormProps) {\n const t = useT()\n const router = useRouter()\n const [initialValues, setInitialValues] = React.useState<OfferFormValues | null>(mode === 'create'\n ? {\n channelId: lockedChannelId ?? null,\n productId: null,\n title: '',\n description: '',\n defaultMediaId: null,\n isActive: true,\n priceOverrides: [],\n }\n : null)\n const [loading, setLoading] = React.useState(mode === 'edit')\n const [error, setError] = React.useState<string | null>(null)\n const [priceKinds, setPriceKinds] = React.useState<PriceKindSummary[]>([])\n const [mediaOptions, setMediaOptions] = React.useState<MediaOption[]>([])\n const attachmentCache = React.useRef<Map<string, MediaOption[]>>(new Map())\n const productCache = React.useRef<Map<string, ProductSummaryCacheEntry>>(new Map())\n const [productSummary, setProductSummary] = React.useState<ProductSummary>(null)\n const [variantPreviews, setVariantPreviews] = React.useState<ProductVariantPreview[]>([])\n const variantCache = React.useRef<Map<string, ProductVariantPreview[]>>(new Map())\n const variantMediaCache = React.useRef<Map<string, VariantThumbnailInfo>>(new Map())\n const [selectedChannelId, setSelectedChannelId] = React.useState<string | null>(lockedChannelId ?? null)\n const manualMediaSelections = React.useRef<Set<string>>(new Set())\n const initialPriceIdsRef = React.useRef<Set<string>>(new Set())\n const [currentProductId, setCurrentProductId] = React.useState<string | null>(null)\n React.useEffect(() => {\n if (initialValues) {\n initialPriceIdsRef.current = collectPriceIds(initialValues.priceOverrides)\n } else {\n initialPriceIdsRef.current = new Set()\n }\n }, [initialValues])\n const channelOffersHref = React.useMemo(\n () => buildChannelOffersHref(lockedChannelId),\n [lockedChannelId],\n )\n\n React.useEffect(() => {\n if (lockedChannelId) {\n setSelectedChannelId(lockedChannelId)\n } else if (initialValues?.channelId) {\n setSelectedChannelId(initialValues.channelId)\n }\n }, [initialValues?.channelId, lockedChannelId])\n\n React.useEffect(() => {\n if (typeof initialValues?.productId === 'string') {\n setCurrentProductId(initialValues.productId)\n }\n }, [initialValues?.productId])\n\n React.useEffect(() => {\n if (typeof initialValues?.productId === 'string' && initialValues?.defaultMediaId === null) {\n manualMediaSelections.current.add(initialValues.productId)\n }\n }, [initialValues?.defaultMediaId, initialValues?.productId])\n\n React.useEffect(() => {\n if (mode !== 'edit') return\n const productId = typeof initialValues?.productId === 'string' ? initialValues.productId : null\n if (!productId) return\n const resolvedProductId = productId\n const hydrationChannelId = selectedChannelId\n ?? lockedChannelId\n ?? (typeof initialValues?.channelId === 'string' ? initialValues.channelId : null)\n let cancelled = false\n async function hydrateExistingProduct() {\n try {\n const [summary, attachments, variants] = await Promise.all([\n resolveProductSummaryWithCache({\n productId: resolvedProductId,\n channelId: hydrationChannelId ?? null,\n productCache,\n }),\n resolveProductMediaOptionsWithCache({ productId: resolvedProductId, attachmentCache }),\n resolveVariantPreviewsWithCache({ productId: resolvedProductId, variantCache, variantMediaCache }),\n ])\n if (!cancelled) {\n setProductSummary(summary ?? null)\n const mergedMedia = buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n })\n attachmentCache.current.set(resolvedProductId, mergedMedia)\n setMediaOptions(mergedMedia)\n setVariantPreviews(variants)\n }\n } catch (err) {\n console.error('sales.channels.offer.initialHydrate', err)\n }\n }\n void hydrateExistingProduct()\n return () => {\n cancelled = true\n }\n }, [\n attachmentCache,\n initialValues?.channelId,\n initialValues?.productId,\n lockedChannelId,\n mode,\n productCache,\n selectedChannelId,\n setMediaOptions,\n setProductSummary,\n setVariantPreviews,\n variantCache,\n variantMediaCache,\n ])\n\n React.useEffect(() => {\n async function loadKinds() {\n const mapItems = (items: Array<Record<string, unknown>>): PriceKindSummary[] =>\n items.map((item): PriceKindSummary => {\n const displayMode =\n item.displayMode === 'including-tax' || item.display_mode === 'including-tax'\n ? 'including-tax'\n : 'excluding-tax'\n return {\n id: typeof item.id === 'string' ? item.id : '',\n code: typeof item.code === 'string' ? item.code : null,\n title: typeof item.title === 'string' ? item.title : null,\n currencyCode:\n typeof item.currencyCode === 'string'\n ? item.currencyCode\n : typeof item.currency_code === 'string'\n ? item.currency_code\n : null,\n displayMode,\n }\n })\n const endpoints = [\n `/api/sales/price-kinds?pageSize=${MAX_LIST_PAGE_SIZE}`,\n `/api/catalog/price-kinds?pageSize=${MAX_LIST_PAGE_SIZE}`,\n ]\n try {\n for (const endpoint of endpoints) {\n try {\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n endpoint,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n setPriceKinds(mapItems(items))\n return\n } catch (err) {\n console.error('sales.channels.price-kinds.fetch', { endpoint, err })\n }\n }\n setPriceKinds([])\n } catch (err) {\n console.error('catalog.price-kinds.list', err)\n }\n }\n void loadKinds()\n }, [])\n\n React.useEffect(() => {\n if (mode !== 'edit' || !offerId) return\n const offerKey = offerId\n let cancelled = false\n async function loadOffer() {\n setLoading(true)\n setError(null)\n try {\n const payload = await readApiResultOrThrow<OfferResponse>(\n `/api/catalog/offers?id=${encodeURIComponent(offerKey)}&pageSize=1`,\n undefined,\n { errorMessage: t('sales.channels.offers.errors.loadOffer', 'Failed to load offer.') },\n )\n const offer = Array.isArray(payload.items) ? payload.items[0] : null\n if (!offer) throw new Error(t('sales.channels.offers.errors.notFound', 'Offer not found.'))\n const values = mapOfferToFormValues(offer, lockedChannelId)\n const pricePayload = await readApiResultOrThrow<PriceResponse>(\n `/api/catalog/prices?offerId=${encodeURIComponent(offer.id as string)}&pageSize=${MAX_LIST_PAGE_SIZE}`,\n undefined,\n { fallback: { items: [] } },\n )\n const priceItems = Array.isArray(pricePayload.items) ? pricePayload.items : []\n values.priceOverrides = priceItems.map(mapPriceRow)\n let preloadedMedia: MediaOption[] = []\n let preloadedVariants: ProductVariantPreview[] = []\n let preloadedSummary: ProductSummary | null = null\n const productId = typeof values.productId === 'string' ? values.productId : null\n if (productId) {\n try {\n const hydrationChannelId = selectedChannelId\n ?? lockedChannelId\n ?? (typeof values.channelId === 'string' ? values.channelId : null)\n const [summary, attachments, variants] = await Promise.all([\n resolveProductSummaryWithCache({\n productId,\n channelId: hydrationChannelId ?? null,\n productCache,\n }),\n loadProductMedia(productId),\n resolveVariantPreviewsWithCache({ productId, variantCache, variantMediaCache }),\n ])\n preloadedSummary = summary ?? null\n preloadedVariants = variants\n preloadedMedia = buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n })\n attachmentCache.current.set(productId, preloadedMedia)\n } catch (err) {\n console.error('sales.channels.offer.media.preload', err)\n }\n }\n if (!cancelled) {\n setInitialValues(values)\n setProductSummary(preloadedSummary)\n setVariantPreviews(preloadedVariants)\n setMediaOptions(preloadedMedia)\n }\n } catch (err) {\n console.error('sales.channels.offer.load', err)\n if (!cancelled) setError(t('sales.channels.offers.errors.loadOffer', 'Failed to load offer.'))\n } finally {\n if (!cancelled) setLoading(false)\n }\n }\n void loadOffer()\n return () => { cancelled = true }\n }, [\n attachmentCache,\n lockedChannelId,\n mode,\n offerId,\n productCache,\n selectedChannelId,\n setMediaOptions,\n setProductSummary,\n setVariantPreviews,\n t,\n variantCache,\n variantMediaCache,\n ])\n\n const fields = React.useMemo<CrudField[]>(() => [\n {\n id: 'channelId',\n label: t('sales.channels.offers.form.channel', 'Channel'),\n type: 'custom',\n required: true,\n component: ({ value, setValue }) => (\n <ChannelSelectInput\n value={(value as string | null) ?? lockedChannelId ?? null}\n onChange={(next) => {\n setValue(next ?? null)\n setSelectedChannelId(next ?? null)\n }}\n disabled={!!lockedChannelId}\n showDetailsLink\n />\n ),\n },\n {\n id: 'productId',\n label: t('sales.channels.offers.form.product', 'Product'),\n type: 'custom',\n required: true,\n component: ({ value, setValue }) => (\n <ProductSelectInput\n value={(value as string | null) ?? null}\n onChange={(next) => setValue(next)}\n channelId={selectedChannelId}\n currentOfferId={offerId ?? null}\n />\n ),\n },\n {\n id: 'defaultMediaId',\n label: t('sales.channels.offers.form.defaultMedia', 'Default media'),\n type: 'custom',\n component: ({ value, setValue }) => (\n <DefaultMediaSelect\n value={(value as string | null | undefined) ?? null}\n onChange={(next) => {\n setValue(next)\n if (!currentProductId) return\n if (next === null || next === undefined) {\n manualMediaSelections.current.add(currentProductId)\n } else {\n manualMediaSelections.current.delete(currentProductId)\n }\n }}\n options={mediaOptions}\n productThumbnail={productSummary?.defaultMediaUrl ?? null}\n hasProduct={Boolean(productSummary)}\n productDefaultMediaId={productSummary?.defaultMediaId ?? null}\n />\n ),\n },\n {\n id: 'title',\n label: t('sales.channels.offers.form.title', 'Title'),\n type: 'text',\n required: true,\n },\n {\n id: 'description',\n label: t('sales.channels.offers.form.description', 'Description'),\n type: 'textarea',\n },\n {\n id: 'isActive',\n label: t('sales.channels.offers.form.active', 'Active'),\n type: 'checkbox',\n },\n ], [lockedChannelId, mediaOptions, productSummary, selectedChannelId, t, currentProductId])\n\n const handleOverrideRemove = React.useCallback(async (draft: PriceOverrideDraft) => {\n const priceId = typeof draft?.priceId === 'string' ? draft.priceId : null\n if (!priceId) return true\n if (mode !== 'edit') return true\n try {\n await deleteCrud('catalog/prices', priceId, {\n errorMessage: t('sales.channels.offers.errors.removePrice', 'Failed to remove price override.'),\n })\n initialPriceIdsRef.current.delete(priceId)\n return true\n } catch (err) {\n console.error('sales.channels.pricing.remove', err)\n flash(t('sales.channels.offers.errors.removePrice', 'Failed to remove price override.'), 'error')\n return false\n }\n }, [mode, t])\n\n const groups = React.useMemo<CrudFormGroup[]>(() => [\n { id: 'associations', column: 1, title: t('sales.channels.offers.form.groups.associations', 'Associations'), fields: ['channelId'] },\n {\n id: 'product',\n column: 1,\n title: t('sales.channels.offers.form.productGroup', 'Product'),\n description: t('sales.channels.offers.form.productGroupHelp', 'Search the catalog and pick the product you want to customize for this channel.'),\n fields: ['productId'],\n },\n {\n id: 'productSummary',\n column: 2,\n title: t('sales.channels.offers.form.productSummaryTitle', 'Product summary'),\n component: () => (\n <ProductOverviewCard summary={productSummary} variants={variantPreviews} />\n ),\n },\n {\n id: 'media',\n column: 1,\n title: t('sales.channels.offers.form.mediaGroupTitle', 'Default media override'),\n fields: ['defaultMediaId'],\n },\n { id: 'content', column: 1, title: t('sales.channels.offers.form.groups.content', 'Content'), fields: ['title', 'description', 'isActive'] },\n {\n id: 'pricing',\n column: 1,\n title: t('sales.channels.offers.form.groups.pricing', 'Price overrides'),\n component: ({ values, setValue }) => (\n <PriceOverridesEditor\n values={Array.isArray(values.priceOverrides) ? values.priceOverrides as PriceOverrideDraft[] : []}\n onChange={(next) => setValue('priceOverrides', next)}\n priceKinds={priceKinds}\n basePrice={productSummary?.pricing ?? null}\n onRemoveDraft={handleOverrideRemove}\n />\n ),\n },\n {\n id: 'customFields',\n column: 2,\n title: t('entities.customFields.title', 'Custom attributes'),\n kind: 'customFields',\n },\n {\n id: 'watchers',\n column: 1,\n bare: true,\n component: ({ values, setValue, errors }) => (\n <OfferFormWatchers\n values={values}\n setValue={setValue}\n errors={errors}\n productCache={productCache}\n attachmentCache={attachmentCache}\n setMediaOptions={setMediaOptions}\n setProductSummary={setProductSummary}\n setVariantPreviews={setVariantPreviews}\n variantCache={variantCache}\n variantMediaCache={variantMediaCache}\n channelId={selectedChannelId}\n manualMediaSelections={manualMediaSelections}\n setCurrentProductId={setCurrentProductId}\n />\n ),\n },\n ], [\n attachmentCache,\n handleOverrideRemove,\n manualMediaSelections,\n priceKinds,\n productCache,\n productSummary,\n selectedChannelId,\n setMediaOptions,\n setCurrentProductId,\n t,\n variantPreviews,\n ])\n\n const handleSubmit = React.useCallback(async (values: OfferFormValues) => {\n const channelId = typeof values.channelId === 'string' && values.channelId.length\n ? values.channelId\n : selectedChannelId ?? lockedChannelId\n const productId = typeof values.productId === 'string' ? values.productId : null\n if (!channelId || !productId) {\n throw new Error(t('sales.channels.offers.errors.requiredFields', 'Choose a channel and product.'))\n }\n const resolvedDefaultMediaId = typeof values.defaultMediaId === 'string' && values.defaultMediaId.trim().length\n ? values.defaultMediaId\n : values.defaultMediaId === null\n ? null\n : undefined\n const basePayload: Record<string, unknown> = {\n channelId,\n productId,\n title: values.title?.trim() || undefined,\n description: values.description?.trim() || undefined,\n isActive: values.isActive !== false,\n }\n if (resolvedDefaultMediaId !== undefined) {\n basePayload.defaultMediaId = resolvedDefaultMediaId\n }\n const attachmentLookup = attachmentCache.current.get(productId) ?? []\n const mediaMap = new Map(attachmentLookup.map((entry) => [entry.id, entry.fileName]))\n if (typeof resolvedDefaultMediaId === 'string' && mediaMap.has(resolvedDefaultMediaId)) {\n const fileName = mediaMap.get(resolvedDefaultMediaId) ?? null\n basePayload.defaultMediaUrl = buildAttachmentImageUrl(resolvedDefaultMediaId, {\n slug: slugifyAttachmentFileName(fileName),\n })\n } else if (resolvedDefaultMediaId === null) {\n basePayload.defaultMediaUrl = null\n }\n const customFields = collectCustomFieldValues(values)\n if (Object.keys(customFields).length) basePayload.customFields = customFields\n const overrides = Array.isArray(values.priceOverrides) ? values.priceOverrides as PriceOverrideDraft[] : []\n const priceWithoutKind = overrides.find((entry) => {\n const amount = typeof entry.amount === 'string' ? entry.amount.trim() : entry.amount\n const hasAmount = typeof amount === 'string' ? amount.length > 0 : amount !== undefined && amount !== null\n const hasExistingPrice = typeof entry.priceId === 'string' && entry.priceId.length > 0\n const hasCurrency = typeof entry.currencyCode === 'string' && entry.currencyCode.length > 0\n return !entry.priceKindId && (hasAmount || hasExistingPrice || hasCurrency)\n })\n if (priceWithoutKind) {\n throw createCrudFormError(t('sales.channels.offers.errors.priceKindRequired', 'Select a price kind for each override.'), {})\n }\n const duplicateKind = (() => {\n const seen = new Set<string>()\n for (const entry of overrides) {\n const kindId = typeof entry.priceKindId === 'string' ? entry.priceKindId : null\n if (!kindId) continue\n if (seen.has(kindId)) return kindId\n seen.add(kindId)\n }\n return null\n })()\n if (duplicateKind) {\n throw createCrudFormError(\n t('sales.channels.offers.errors.priceKindDuplicate', 'Each price kind can only be overridden once.'),\n {},\n )\n }\n const submittedPriceIds = collectPriceIds(overrides)\n const deletedIdSet = new Set<string>()\n initialPriceIdsRef.current.forEach((id) => {\n if (!submittedPriceIds.has(id)) deletedIdSet.add(id)\n })\n const deletedIds = Array.from(deletedIdSet)\n let savedId = offerId ?? null\n try {\n if (mode === 'create') {\n const res = await createCrud<{ id?: string; offerId?: string }>('catalog/offers', basePayload, {\n errorMessage: t('sales.channels.offers.errors.save', 'Failed to save offer.'),\n })\n savedId = res?.result?.offerId ?? res?.result?.id ?? null\n } else if (offerId) {\n await updateCrud('catalog/offers', { id: offerId, ...basePayload }, {\n errorMessage: t('sales.channels.offers.errors.save', 'Failed to save offer.'),\n })\n savedId = offerId\n }\n } catch (err) {\n const details = (err as { details?: unknown })?.details\n const rawFieldErrors = (err as { fieldErrors?: unknown })?.fieldErrors\n const fieldErrors = rawFieldErrors && typeof rawFieldErrors === 'object'\n ? (rawFieldErrors as CrudServerFieldErrors)\n : undefined\n const status = (err as { status?: number })?.status\n const message = typeof (err as { message?: unknown }).message === 'string' && (err as { message: string }).message.trim().length\n ? (err as { message: string }).message\n : t(\n 'sales.channels.offers.errors.duplicateProduct',\n 'This product already has an offer in this channel.',\n )\n throw createCrudFormError(\n message,\n fieldErrors,\n { status, details },\n )\n }\n if (savedId) {\n await syncPriceOverrides({\n overrides,\n deletedIds,\n offerId: savedId,\n channelId,\n productId,\n })\n initialPriceIdsRef.current = submittedPriceIds\n }\n flash(t('sales.channels.offers.messages.saved', 'Offer saved.'), 'success')\n router.push(buildChannelOffersHref(channelId))\n }, [attachmentCache, initialPriceIdsRef, lockedChannelId, mode, offerId, router, selectedChannelId, t])\n\n const handleDelete = React.useCallback(async () => {\n if (!offerId) return\n await deleteCrud('catalog/offers', offerId, {\n errorMessage: t('sales.channels.offers.errors.delete', 'Failed to delete offer.'),\n })\n flash(t('sales.channels.offers.messages.deleted', 'Offer deleted.'), 'success')\n const targetChannel = initialValues?.channelId ?? lockedChannelId ?? ''\n router.push(buildChannelOffersHref(targetChannel))\n }, [initialValues?.channelId, lockedChannelId, offerId, router, t])\n\n return (\n <div>\n {error ? (\n <div className=\"mb-4 rounded border border-destructive/40 bg-destructive/10 px-4 py-3 text-sm text-destructive\">\n {error}\n </div>\n ) : null}\n <CrudForm<OfferFormValues>\n title={mode === 'create'\n ? t('sales.channels.offers.form.createTitle', 'Create offer')\n : t('sales.channels.offers.form.editTitle', 'Edit offer')}\n entityId={E.catalog.catalog_offer}\n fields={fields}\n groups={groups}\n initialValues={initialValues ?? undefined}\n isLoading={loading}\n loadingMessage={t('sales.channels.offers.form.loading', 'Loading offer\u2026')}\n submitLabel={mode === 'create'\n ? t('sales.channels.offers.form.createSubmit', 'Create offer')\n : t('sales.channels.offers.form.updateSubmit', 'Save changes')}\n cancelHref={channelOffersHref}\n backHref={channelOffersHref}\n onSubmit={handleSubmit}\n onDelete={mode === 'edit' ? handleDelete : undefined}\n deleteVisible={mode === 'edit'}\n deleteRedirect={channelOffersHref}\n />\n </div>\n )\n}\n\nfunction mapOfferToFormValues(item: Record<string, unknown>, lockedChannelId?: string | null): OfferFormValues {\n const values: OfferFormValues = {\n channelId: typeof item.channelId === 'string'\n ? item.channelId\n : typeof item.channel_id === 'string'\n ? item.channel_id\n : lockedChannelId ?? null,\n productId: typeof item.productId === 'string'\n ? item.productId\n : typeof item.product_id === 'string'\n ? item.product_id\n : null,\n title: typeof item.title === 'string' ? item.title : '',\n description: typeof item.description === 'string' ? item.description : '',\n defaultMediaId: typeof item.defaultMediaId === 'string'\n ? item.defaultMediaId\n : typeof item.default_media_id === 'string'\n ? item.default_media_id\n : null,\n isActive: item.isActive === true || item.is_active === true,\n priceOverrides: [],\n }\n mergeCustomFieldValues(values, item)\n return values\n}\n\nfunction mapPriceRow(row: Record<string, unknown>): PriceOverrideDraft {\n return {\n tempId: String(row.id ?? crypto.randomUUID?.() ?? Math.random()),\n priceId: typeof row.id === 'string' ? row.id : undefined,\n priceKindId: typeof row.priceKindId === 'string'\n ? row.priceKindId\n : typeof row.price_kind_id === 'string'\n ? row.price_kind_id\n : undefined,\n priceKindCode: typeof row.priceKindCode === 'string'\n ? row.priceKindCode\n : typeof row.price_kind_code === 'string'\n ? row.price_kind_code\n : null,\n currencyCode: typeof row.currencyCode === 'string'\n ? row.currencyCode\n : typeof row.currency_code === 'string'\n ? row.currency_code\n : null,\n displayMode: row.displayMode === 'including-tax' || row.display_mode === 'including-tax'\n ? 'including-tax'\n : 'excluding-tax',\n amount: typeof row.unitPriceNet === 'string'\n ? row.unitPriceNet\n : typeof row.unit_price_net === 'string'\n ? row.unit_price_net\n : typeof row.unitPriceGross === 'string'\n ? row.unitPriceGross\n : typeof row.unit_price_gross === 'string'\n ? row.unit_price_gross\n : '',\n }\n}\n\nfunction collectPriceIds(source: PriceOverrideDraft[] | null | undefined): Set<string> {\n if (!Array.isArray(source)) return new Set()\n const ids = source\n .map((entry) => (typeof entry?.priceId === 'string' ? entry.priceId : null))\n .filter((id): id is string => Boolean(id))\n return new Set(ids)\n}\n\nfunction mergeCustomFieldValues(target: Record<string, unknown>, source: Record<string, unknown> | null | undefined) {\n Object.assign(target, extractCustomFieldEntries(source ?? {}))\n}\n\nfunction buildChannelOffersHref(channelId?: string | null): string {\n return channelId && channelId.length\n ? `/backend/sales/channels/${channelId}/edit?tab=offers`\n : '/backend/sales/channels/offers'\n}\n\nasync function syncPriceOverrides(params: {\n overrides: PriceOverrideDraft[]\n deletedIds: string[]\n offerId: string\n channelId: string\n productId: string\n}) {\n const { overrides, deletedIds, offerId, channelId, productId } = params\n for (const draft of overrides) {\n if (!draft.priceKindId || !draft.amount) continue\n const amount = Number(draft.amount)\n if (Number.isNaN(amount)) continue\n const payload: Record<string, unknown> = {\n offerId,\n productId,\n channelId,\n priceKindId: draft.priceKindId,\n currencyCode: draft.currencyCode ?? undefined,\n }\n if (draft.displayMode === 'including-tax') {\n payload.unitPriceGross = amount\n } else {\n payload.unitPriceNet = amount\n }\n if (draft.priceId) {\n await updateCrud('catalog/prices', { id: draft.priceId, ...payload })\n } else {\n await createCrud('catalog/prices', payload)\n }\n }\n const uniqueDeletedIds = Array.from(new Set(\n deletedIds.filter((id): id is string => typeof id === 'string' && id.length > 0),\n ))\n for (const id of uniqueDeletedIds) {\n if (!id) continue\n try {\n await deleteCrud('catalog/prices', id)\n } catch (err) {\n console.error('catalog.prices.delete', err)\n }\n }\n}\n\nfunction ChannelSelectInput({\n value,\n onChange,\n disabled,\n showDetailsLink,\n}: {\n value: string | null\n onChange: (next: string | null) => void\n disabled?: boolean\n showDetailsLink?: boolean\n}) {\n const t = useT()\n const [options, setOptions] = React.useState<Array<{ id: string; name: string; code: string | null }>>([])\n const selectedOption = React.useMemo(\n () => (value ? options.find((opt) => opt.id === value) ?? null : null),\n [options, value],\n )\n React.useEffect(() => {\n async function load() {\n try {\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/channels?pageSize=${MAX_LIST_PAGE_SIZE}`,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n setOptions(items.map((item) => ({\n id: typeof item.id === 'string' ? item.id : '',\n name: typeof item.name === 'string' ? item.name : '',\n code: typeof item.code === 'string' ? item.code : null,\n })))\n } catch (err) {\n console.error('sales.channels.options', err)\n }\n }\n void load()\n }, [])\n React.useEffect(() => {\n const channelIdToLoad = typeof value === 'string' ? value : null\n if (!channelIdToLoad || selectedOption) return\n const resolvedChannelId = channelIdToLoad\n let cancelled = false\n async function loadSingle() {\n try {\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/channels?id=${encodeURIComponent(resolvedChannelId)}&pageSize=1`,\n undefined,\n { fallback: { items: [] } },\n )\n const item = Array.isArray(payload.items) ? payload.items[0] : null\n if (!item || cancelled) return\n const entry = {\n id: typeof item.id === 'string' ? item.id : resolvedChannelId,\n name: typeof item.name === 'string' ? item.name : resolvedChannelId,\n code: typeof item.code === 'string' ? item.code : null,\n }\n setOptions((prev) => {\n if (prev.some((opt) => opt.id === entry.id)) return prev\n return [...prev, entry]\n })\n } catch (err) {\n console.error('sales.channels.lookup', err)\n }\n }\n void loadSingle()\n return () => { cancelled = true }\n }, [selectedOption, value])\n\n if (disabled && value) {\n const label = selectedOption?.name ?? value\n const detail = selectedOption?.code ?? null\n return (\n <div className=\"flex items-center justify-between gap-3 rounded border bg-muted px-3 py-2 text-sm\">\n <div className=\"min-w-0\">\n <div className=\"font-medium truncate\">{label}</div>\n {detail ? (\n <div className=\"text-xs text-muted-foreground truncate\">{detail}</div>\n ) : null}\n </div>\n {showDetailsLink ? (\n <Link href={`/backend/sales/channels/${value}/edit`} className=\"text-xs font-medium text-primary hover:underline\">\n {t('sales.channels.offers.form.channelDetails', 'Details')}\n </Link>\n ) : null}\n </div>\n )\n }\n return (\n <Select value={value || undefined} onValueChange={(next) => onChange(next || null)}>\n <SelectTrigger>\n <SelectValue placeholder={t('sales.channels.offers.form.channelPlaceholder', 'Select channel')} />\n </SelectTrigger>\n <SelectContent>\n {options.map((opt) => (\n <SelectItem key={opt.id} value={opt.id}>\n {opt.code ? `${opt.name} (${opt.code})` : opt.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )\n}\n\nfunction ProductSelectInput({\n value,\n onChange,\n channelId,\n currentOfferId,\n}: {\n value: string | null\n onChange: (next: string | null) => void\n channelId: string | null\n currentOfferId?: string | null\n}) {\n const t = useT()\n const [query, setQuery] = React.useState('')\n const [results, setResults] = React.useState<ProductSearchResult[]>([])\n const [isLoading, setLoading] = React.useState(false)\n const [hasTyped, setHasTyped] = React.useState(false)\n\n const trimmed = query.trim()\n const shouldSearch = trimmed.length >= 2 || UUID_REGEX.test(trimmed)\n\n React.useEffect(() => {\n if (!shouldSearch) {\n setResults([])\n return\n }\n let cancelled = false\n const controller = new AbortController()\n const timeout = setTimeout(async () => {\n setLoading(true)\n try {\n const params = new URLSearchParams({ pageSize: '10' })\n if (UUID_REGEX.test(trimmed)) {\n params.set('id', trimmed)\n } else if (trimmed.length) {\n params.set('search', trimmed)\n }\n if (channelId) params.set('channelId', channelId)\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/catalog/products?${params.toString()}`,\n { signal: controller.signal },\n { fallback: { items: [] } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n if (!cancelled) {\n const mapped = items.map((item) => mapProductSearchResult(item, channelId, currentOfferId))\n mapped.sort((a, b) => {\n const aBlocked = Boolean(a.existingOfferId && !a.isCurrentOfferProduct)\n const bBlocked = Boolean(b.existingOfferId && !b.isCurrentOfferProduct)\n return Number(aBlocked) - Number(bBlocked)\n })\n setResults(mapped)\n }\n } catch (err) {\n if ((err as Error).name === 'AbortError') return\n console.error('catalog.products.lookup', err)\n } finally {\n if (!cancelled) setLoading(false)\n }\n }, 250)\n return () => {\n cancelled = true\n clearTimeout(timeout)\n controller.abort()\n }\n }, [channelId, currentOfferId, shouldSearch, trimmed])\n\n const handleKeyDown = React.useCallback((event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key === 'Enter' && UUID_REGEX.test(trimmed)) {\n event.preventDefault()\n onChange(trimmed)\n }\n }, [onChange, trimmed])\n\n const selectedHint = value\n ? t('sales.channels.offers.form.productSelectedHint', 'Selected product ID: {{id}}', { id: value })\n : null\n\n return (\n <div className=\"space-y-3\">\n <Input\n leftIcon={<Search />}\n value={query}\n onChange={(event) => {\n setQuery(event.target.value)\n setHasTyped(true)\n }}\n onKeyDown={handleKeyDown}\n placeholder={t('sales.channels.offers.form.productSearchPlaceholder', 'Search by title, SKU, or ID\u2026')}\n />\n {selectedHint ? (\n <div className=\"rounded border bg-muted px-3 py-2 text-xs text-muted-foreground\">\n {selectedHint}\n </div>\n ) : null}\n {value ? (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => onChange(null)}>\n {t('sales.channels.offers.form.productClear', 'Clear selection')}\n </Button>\n ) : null}\n {shouldSearch ? (\n <div className=\"space-y-2\">\n {isLoading ? (\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n {t('sales.channels.offers.form.productSearchLoading', 'Searching products\u2026')}\n </div>\n ) : null}\n {!isLoading && !results.length ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSearchEmpty', 'No products match your search.')}\n </p>\n ) : null}\n <div className=\"space-y-2 max-h-80 overflow-y-auto\">\n {results.map((product) => {\n const isSelected = value === product.id\n const hasConflict = Boolean(product.existingOfferId && !product.isCurrentOfferProduct)\n return (\n <div\n key={product.id}\n className={cn(\n 'flex gap-3 rounded border bg-card p-3 transition-colors',\n isSelected ? 'border-primary/70 bg-primary/5' : 'hover:border-primary/50',\n )}\n >\n <div className=\"h-12 w-12 overflow-hidden rounded border bg-muted\">\n {product.defaultMediaUrl ? (\n <img src={product.defaultMediaUrl} alt={product.title} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-5 w-5\" />\n </div>\n )}\n </div>\n <div className=\"flex flex-1 flex-col gap-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-medium\">{product.title || t('sales.channels.offers.form.productUntitled', 'Untitled product')}</div>\n {product.sku ? (\n <div className=\"text-xs text-muted-foreground\">SKU \u00B7 {product.sku}</div>\n ) : null}\n </div>\n <div className=\"text-xs font-medium text-muted-foreground\">\n {product.pricing ? formatPriceDisplay(product.pricing) : t('sales.channels.offers.form.productPriceMissing', 'No price')}\n </div>\n </div>\n {hasConflict ? (\n <div className=\"flex items-center justify-between gap-2 text-xs text-status-warning-text\">\n <span className=\"truncate\">\n {t('sales.channels.offers.form.productHasOffer', 'Already has an offer for this channel.')}\n </span>\n {channelId && product.existingOfferId ? (\n <Link\n href={`/backend/sales/channels/${encodeURIComponent(\n String(channelId)\n )}/offers/${encodeURIComponent(String(product.existingOfferId))}/edit`}\n className=\"shrink-0 font-medium text-primary hover:underline\"\n >\n {t('sales.channels.offers.form.productHasOfferLink', 'View offer')}\n </Link>\n ) : null}\n </div>\n ) : null}\n <div className=\"flex justify-end\">\n <Button\n type=\"button\"\n variant={isSelected ? 'secondary' : 'outline'}\n size=\"sm\"\n onClick={() => onChange(product.id)}\n disabled={hasConflict && !isSelected}\n >\n {hasConflict && !isSelected\n ? t('sales.channels.offers.form.productUnavailable', 'Unavailable')\n : isSelected\n ? t('sales.channels.offers.form.productSelected', 'Selected')\n : t('sales.channels.offers.form.productSelect', 'Select')}\n </Button>\n </div>\n </div>\n </div>\n )\n })}\n </div>\n </div>\n ) : hasTyped ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSearchHint', 'Type at least 2 characters or paste a product ID.')}\n </p>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSearchIntro', 'Search by name or paste the product id to find catalog items.')}\n </p>\n )}\n </div>\n )\n}\n\nfunction DefaultMediaSelect({\n value,\n options,\n onChange,\n productThumbnail,\n hasProduct,\n productDefaultMediaId,\n}: {\n value: string | null\n options: MediaOption[]\n onChange: (next: string | null) => void\n productThumbnail: string | null\n hasProduct: boolean\n productDefaultMediaId?: string | null\n}) {\n const t = useT()\n const filteredOptions = React.useMemo(() => {\n if (!productDefaultMediaId) return options\n return options.filter((opt) => opt.id !== productDefaultMediaId)\n }, [options, productDefaultMediaId])\n const hasAttachmentOptions = filteredOptions.length > 0\n const showPlaceholder = !hasAttachmentOptions && !productThumbnail && !hasProduct\n if (showPlaceholder) {\n return (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.mediaSelectProduct', 'Select a product to load its media.')}\n </p>\n )\n }\n const tiles = [\n {\n id: 'inherit',\n label: t('sales.channels.offers.form.mediaInherit', 'Use product default'),\n thumbnail: productThumbnail,\n selected: value == null,\n onClick: () => onChange(null),\n },\n ...filteredOptions.map((opt) => ({\n id: opt.id,\n label: opt.label,\n thumbnail: opt.thumbnailUrl ?? null,\n selected: value === opt.id,\n onClick: () => onChange(opt.id),\n })),\n ]\n return (\n <div className=\"space-y-3\">\n <div className=\"text-xs text-muted-foreground\">\n <p>\n {t('sales.channels.offers.form.mediaHelp', 'Choose the thumbnail that should represent this offer in the channel.')}\n </p>\n {!hasAttachmentOptions && hasProduct ? (\n <p className=\"mt-1\">\n {t('sales.channels.offers.form.mediaEmpty', 'This product has no uploaded media yet; the product default will be used.')}\n </p>\n ) : null}\n </div>\n <div className=\"grid gap-3 sm:grid-cols-3\">\n {tiles.map((tile) => (\n <button\n key={tile.id}\n type=\"button\"\n className={cn(\n 'flex flex-col rounded border text-left transition-colors',\n tile.selected ? 'border-primary shadow-sm' : 'hover:border-primary/60',\n )}\n onClick={tile.onClick}\n >\n <div className=\"relative aspect-square overflow-hidden rounded-t bg-muted\">\n {tile.thumbnail ? (\n <img src={tile.thumbnail} alt={tile.label} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-6 w-6\" />\n </div>\n )}\n {tile.selected ? (\n <div className=\"absolute right-2 top-2 rounded-full bg-primary/90 px-2 py-0.5 text-xs font-semibold text-primary-foreground\">\n {t('sales.channels.offers.form.mediaSelected', 'Active')}\n </div>\n ) : null}\n </div>\n <div className=\"p-2\">\n <div className=\"line-clamp-2 text-xs font-medium\">{tile.label}</div>\n </div>\n </button>\n ))}\n </div>\n </div>\n )\n}\n\nfunction OfferFormWatchers({\n values,\n setValue,\n productCache,\n attachmentCache,\n setMediaOptions,\n setProductSummary,\n setVariantPreviews,\n variantCache,\n variantMediaCache,\n channelId,\n manualMediaSelections,\n setCurrentProductId,\n errors,\n}: CrudFormGroupComponentProps & {\n productCache: React.MutableRefObject<Map<string, ProductSummaryCacheEntry>>\n attachmentCache: React.MutableRefObject<Map<string, MediaOption[]>>\n setMediaOptions: React.Dispatch<React.SetStateAction<MediaOption[]>>\n setProductSummary: React.Dispatch<React.SetStateAction<ProductSummary>>\n setVariantPreviews: React.Dispatch<React.SetStateAction<ProductVariantPreview[]>>\n variantCache: React.MutableRefObject<Map<string, ProductVariantPreview[]>>\n variantMediaCache: React.MutableRefObject<Map<string, VariantThumbnailInfo>>\n channelId: string | null\n manualMediaSelections: React.MutableRefObject<Set<string>>\n setCurrentProductId: React.Dispatch<React.SetStateAction<string | null>>\n}) {\n const previousProductIdRef = React.useRef<string | null>(null)\n const initializedProductRef = React.useRef(false)\n React.useEffect(() => {\n const productId = typeof values.productId === 'string' ? values.productId : null\n setCurrentProductId(productId)\n if (!productId) {\n setMediaOptions([])\n setProductSummary(null)\n setVariantPreviews([])\n previousProductIdRef.current = null\n return\n }\n const resolvedProductId = productId as string\n const resolvedChannelId = channelId ?? null\n if (!initializedProductRef.current) {\n previousProductIdRef.current = resolvedProductId\n initializedProductRef.current = true\n } else if (previousProductIdRef.current !== resolvedProductId) {\n previousProductIdRef.current = resolvedProductId\n setValue('defaultMediaId', undefined)\n }\n let cancelled = false\n async function load() {\n try {\n const summary = await resolveProductSummaryWithCache({\n productId: resolvedProductId,\n channelId: resolvedChannelId,\n productCache,\n })\n if (!cancelled) {\n setProductSummary(summary ?? null)\n if (summary) {\n const hasTitle = typeof values.title === 'string' && values.title.trim().length > 0\n if (!hasTitle && summary.title) {\n setValue('title', summary.title)\n }\n const hasDescription =\n typeof values.description === 'string' && values.description.trim().length > 0\n if (!hasDescription && summary.description) {\n setValue('description', summary.description)\n }\n if (\n !values.defaultMediaId &&\n summary.defaultMediaId &&\n !manualMediaSelections.current.has(resolvedProductId)\n ) {\n setValue('defaultMediaId', summary.defaultMediaId)\n }\n }\n }\n const attachments = await resolveProductMediaOptionsWithCache({\n productId: resolvedProductId,\n attachmentCache,\n })\n if (!cancelled) {\n const variants = await resolveVariantPreviewsWithCache({\n productId: resolvedProductId,\n variantCache,\n variantMediaCache,\n })\n const mergedMedia = buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n })\n attachmentCache.current.set(resolvedProductId, mergedMedia)\n setMediaOptions(mergedMedia)\n setVariantPreviews(variants)\n }\n } catch (err) {\n console.error('sales.channels.offer.watchers', err)\n }\n }\n void load()\n return () => { cancelled = true }\n }, [\n attachmentCache,\n channelId,\n manualMediaSelections,\n productCache,\n setMediaOptions,\n setProductSummary,\n setValue,\n setVariantPreviews,\n values.defaultMediaId,\n values.description,\n values.productId,\n values.title,\n variantCache,\n variantMediaCache,\n setCurrentProductId,\n ])\n return null\n}\n\nasync function resolveProductSummaryWithCache({\n productId,\n channelId,\n productCache,\n}: {\n productId: string\n channelId: string | null\n productCache: React.MutableRefObject<Map<string, ProductSummaryCacheEntry>>\n}): Promise<ProductSummaryCacheEntry | null> {\n if (!productId) return null\n const cacheKey = channelId ? `${productId}:${channelId}` : productId\n let summary: ProductSummaryCacheEntry | null | undefined = productCache.current.get(cacheKey)\n if (summary) return summary\n const params = new URLSearchParams({ id: productId, pageSize: '1' })\n if (channelId) params.set('channelId', channelId)\n const payload = await readApiResultOrThrow<OfferResponse>(\n `/api/catalog/products?${params.toString()}`,\n undefined,\n { fallback: { items: [] } },\n )\n const product = Array.isArray(payload.items) ? payload.items[0] : null\n summary = product ? mapProductSummary(product) : null\n if (summary) {\n productCache.current.set(cacheKey, summary)\n }\n return summary ?? null\n}\n\nasync function resolveProductMediaOptionsWithCache({\n productId,\n attachmentCache,\n}: {\n productId: string\n attachmentCache: React.MutableRefObject<Map<string, MediaOption[]>>\n}): Promise<MediaOption[]> {\n if (!productId) return []\n const cached = attachmentCache.current.get(productId) ?? []\n if (cached.length) {\n const deduped = dedupeMediaOptions(cached)\n attachmentCache.current.set(productId, deduped)\n return deduped\n }\n const attachments = dedupeMediaOptions(await loadProductMedia(productId))\n attachmentCache.current.set(productId, attachments)\n return attachments\n}\n\nasync function resolveVariantPreviewsWithCache({\n productId,\n variantCache,\n variantMediaCache,\n}: {\n productId: string\n variantCache: React.MutableRefObject<Map<string, ProductVariantPreview[]>>\n variantMediaCache: React.MutableRefObject<Map<string, VariantThumbnailInfo>>\n}): Promise<ProductVariantPreview[]> {\n if (!productId) return []\n const cached = variantCache.current.get(productId)\n if (cached) return cached\n const variantPayload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/catalog/variants?productId=${encodeURIComponent(productId)}&pageSize=${MAX_LIST_PAGE_SIZE}`,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(variantPayload.items) ? variantPayload.items : []\n const variants = await Promise.all(\n items.map(async (item) => {\n const preview = mapVariantPreview(item)\n const media = await resolveVariantThumbnail(preview.id, variantMediaCache)\n return {\n ...preview,\n thumbnailId: media?.attachmentId ?? preview.thumbnailId,\n thumbnailUrl: media?.thumbnailUrl ?? preview.thumbnailUrl,\n thumbnailFileName: media?.fileName ?? preview.thumbnailFileName,\n }\n }),\n )\n variantCache.current.set(productId, variants)\n return variants\n}\n\nfunction mapProductSummary(item: Record<string, unknown>): ProductSummaryCacheEntry {\n const pricingSource = item.pricing && typeof item.pricing === 'object' ? item.pricing as Record<string, unknown> : null\n return {\n title: typeof item.title === 'string' ? item.title : '',\n description: typeof item.description === 'string' ? item.description : null,\n defaultMediaId: typeof item.defaultMediaId === 'string'\n ? item.defaultMediaId\n : typeof item.default_media_id === 'string'\n ? item.default_media_id\n : null,\n defaultMediaUrl: typeof item.defaultMediaUrl === 'string'\n ? item.defaultMediaUrl\n : typeof item.default_media_url === 'string'\n ? item.default_media_url\n : null,\n sku: typeof item.sku === 'string' ? item.sku : null,\n pricing: normalizePricing(pricingSource),\n }\n}\n\nfunction normalizePricing(source: Record<string, unknown> | null): PricingSummary | null {\n if (!source) return null\n const currencyCode = typeof source.currencyCode === 'string'\n ? source.currencyCode\n : typeof source.currency_code === 'string'\n ? source.currency_code\n : null\n const unitPriceNet = typeof source.unitPriceNet === 'string'\n ? source.unitPriceNet\n : typeof source.unit_price_net === 'string'\n ? source.unit_price_net\n : null\n const unitPriceGross = typeof source.unitPriceGross === 'string'\n ? source.unitPriceGross\n : typeof source.unit_price_gross === 'string'\n ? source.unit_price_gross\n : null\n const displayMode = source.displayMode === 'including-tax' || source.display_mode === 'including-tax'\n ? 'including-tax'\n : source.displayMode === 'excluding-tax' || source.display_mode === 'excluding-tax'\n ? 'excluding-tax'\n : null\n return { currencyCode, unitPriceNet, unitPriceGross, displayMode }\n}\n\nasync function loadProductMedia(productId: string): Promise<MediaOption[]> {\n if (!productId) return []\n const normalize = (items: Array<{ id?: string; fileName?: string; thumbnailUrl?: string | null }>) => (\n items\n .filter((item): item is { id: string; fileName: string; thumbnailUrl?: string | null } => (\n typeof item.id === 'string' && typeof item.fileName === 'string'\n ))\n .map((item) => ({\n id: item.id,\n label: item.fileName,\n fileName: item.fileName,\n thumbnailUrl: typeof item.thumbnailUrl === 'string'\n ? item.thumbnailUrl\n : buildAttachmentImageUrl(item.id, {\n width: 360,\n height: 360,\n slug: slugifyAttachmentFileName(item.fileName),\n }),\n }))\n )\n try {\n const primary = await apiCall<AttachmentsResponse>(\n `/api/catalog/product-media?productId=${encodeURIComponent(productId)}`,\n undefined,\n { fallback: { items: [] } },\n )\n if (primary.ok && primary.result?.items) {\n return normalize(primary.result.items)\n }\n } catch (err) {\n console.error('catalog.product-media.lookup', err)\n }\n try {\n const fallback = await apiCall<AttachmentsResponse>(\n `/api/attachments?entityId=${encodeURIComponent(E.catalog.catalog_product)}&recordId=${encodeURIComponent(productId)}`,\n undefined,\n { fallback: { items: [] } },\n )\n if (fallback.ok && fallback.result?.items) {\n return normalize(fallback.result.items)\n }\n } catch (err) {\n console.error('attachments.lookup', err)\n }\n return []\n}\n\nfunction buildVariantMediaOptions(variants: ProductVariantPreview[]): MediaOption[] {\n return variants\n .map((variant): MediaOption | null => {\n if (!variant.thumbnailId || !variant.thumbnailUrl) return null\n const label = variant.name || variant.sku || 'Variant'\n const fileName = variant.thumbnailFileName ?? `${variant.thumbnailId}.jpg`\n return {\n id: variant.thumbnailId,\n label,\n fileName,\n thumbnailUrl: variant.thumbnailUrl,\n }\n })\n .filter((entry): entry is MediaOption => Boolean(entry))\n}\n\nfunction buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n}: {\n attachments?: MediaOption[] | null\n variants?: ProductVariantPreview[] | null\n summary?: ProductSummary | null\n}): MediaOption[] {\n const merged = dedupeMediaOptions([\n ...(attachments ?? []),\n ...buildVariantMediaOptions(variants ?? []),\n ])\n const defaultId = summary?.defaultMediaId ?? null\n const defaultUrl = summary?.defaultMediaUrl ?? null\n if (defaultId && defaultUrl && !merged.some((entry) => entry.id === defaultId)) {\n const fileName = inferFileNameFromUrl(defaultUrl, defaultId)\n merged.unshift({\n id: defaultId,\n label: fileName,\n fileName,\n thumbnailUrl: defaultUrl,\n })\n }\n return merged\n}\n\nfunction dedupeMediaOptions(entries: MediaOption[] | null | undefined): MediaOption[] {\n if (!Array.isArray(entries)) return []\n const seen = new Set<string>()\n const result: MediaOption[] = []\n for (const entry of entries) {\n if (!entry || typeof entry.id !== 'string') continue\n if (seen.has(entry.id)) continue\n seen.add(entry.id)\n result.push(entry)\n }\n return result\n}\n\nfunction inferFileNameFromUrl(url: string | null, fallbackId: string): string {\n if (typeof url === 'string' && url.length) {\n const cleaned = url.split(/[?#]/)[0]\n const last = cleaned.split('/').pop()\n if (last && last.trim().length) return last\n }\n return `${fallbackId}.jpg`\n}\n\nfunction mapVariantPreview(item: Record<string, unknown>): ProductVariantPreview {\n return {\n id: typeof item.id === 'string' ? item.id : '',\n name: typeof item.name === 'string'\n ? item.name\n : typeof item.sku === 'string'\n ? item.sku\n : 'Variant',\n sku: typeof item.sku === 'string' ? item.sku : null,\n thumbnailUrl: typeof item.defaultMediaUrl === 'string'\n ? item.defaultMediaUrl\n : typeof item.default_media_url === 'string'\n ? item.default_media_url\n : null,\n thumbnailId: null,\n thumbnailFileName: null,\n }\n}\n\nasync function resolveVariantThumbnail(\n variantId: string,\n cache: React.MutableRefObject<Map<string, VariantThumbnailInfo>>,\n): Promise<VariantThumbnailInfo | null> {\n if (!variantId) return null\n if (cache.current.has(variantId)) {\n return cache.current.get(variantId) ?? null\n }\n try {\n const payload = await apiCall<AttachmentsResponse>(\n `/api/attachments?entityId=${encodeURIComponent(E.catalog.catalog_product_variant)}&recordId=${encodeURIComponent(variantId)}`,\n )\n const items = payload.ok && payload.result?.items ? payload.result.items : []\n const first = items.find((item) => typeof item.id === 'string')\n if (first?.id) {\n const thumbnailUrl = typeof first.thumbnailUrl === 'string'\n ? first.thumbnailUrl\n : buildAttachmentImageUrl(first.id, {\n width: 360,\n height: 360,\n slug: slugifyAttachmentFileName(first.fileName ?? first.id),\n })\n const info: VariantThumbnailInfo = {\n attachmentId: first.id,\n thumbnailUrl: thumbnailUrl ?? null,\n fileName: typeof first.fileName === 'string' ? first.fileName : null,\n }\n cache.current.set(variantId, info)\n return info\n }\n } catch (err) {\n console.error('sales.channels.offer.variantMedia', err)\n }\n const empty: VariantThumbnailInfo = { attachmentId: null, thumbnailUrl: null, fileName: null }\n cache.current.set(variantId, empty)\n return empty\n}\n\nfunction mapProductSearchResult(\n item: Record<string, unknown>,\n channelId?: string | null,\n currentOfferId?: string | null,\n): ProductSearchResult {\n const offers = Array.isArray((item as { offers?: unknown }).offers)\n ? (item as { offers: Array<Record<string, unknown>> }).offers\n : []\n const channelOffer = offers.find((entry) => {\n if (!entry || typeof entry !== 'object') return false\n const offerChannelId = typeof entry.channelId === 'string'\n ? entry.channelId\n : typeof (entry as Record<string, unknown>).channel_id === 'string'\n ? (entry as Record<string, unknown>).channel_id\n : null\n return channelId ? offerChannelId === channelId : false\n }) ?? null\n const existingOfferId = channelOffer && typeof channelOffer.id === 'string' ? channelOffer.id : null\n return {\n id: typeof item.id === 'string' ? item.id : '',\n title: typeof item.title === 'string' ? item.title : '',\n sku: typeof item.sku === 'string' ? item.sku : null,\n defaultMediaUrl: typeof item.defaultMediaUrl === 'string'\n ? item.defaultMediaUrl\n : typeof item.default_media_url === 'string'\n ? item.default_media_url\n : null,\n pricing: item.pricing && typeof item.pricing === 'object'\n ? normalizePricing(item.pricing as Record<string, unknown>)\n : null,\n existingOfferId,\n existingOfferTitle:\n channelOffer && typeof channelOffer.title === 'string' ? channelOffer.title : null,\n isCurrentOfferProduct: Boolean(existingOfferId && currentOfferId && existingOfferId === currentOfferId),\n }\n}\n\nfunction formatPriceDisplay(pricing: PricingSummary | null): string {\n if (!pricing) return '\u2014'\n const amount = pricing.displayMode === 'including-tax'\n ? pricing.unitPriceGross ?? pricing.unitPriceNet\n : pricing.unitPriceNet ?? pricing.unitPriceGross\n if (!amount) return pricing.currencyCode ?? '\u2014'\n return `${pricing.currencyCode ?? ''} ${amount}`\n}\n\nfunction PriceOverridesEditor({\n values,\n onChange,\n priceKinds,\n basePrice,\n onRemoveDraft,\n}: {\n values: PriceOverrideDraft[]\n onChange: (next: PriceOverrideDraft[]) => void\n priceKinds: PriceKindSummary[]\n basePrice: PricingSummary | null\n onRemoveDraft?: (draft: PriceOverrideDraft) => Promise<boolean> | boolean\n}) {\n const t = useT()\n const baseAmount = React.useMemo(() => {\n if (!basePrice) return ''\n const net = basePrice.unitPriceNet ?? null\n const gross = basePrice.unitPriceGross ?? null\n if (basePrice.displayMode === 'including-tax') {\n return gross ?? net ?? ''\n }\n if (basePrice.displayMode === 'excluding-tax') {\n return net ?? gross ?? ''\n }\n return net ?? gross ?? ''\n }, [basePrice])\n const baseDefaults = React.useMemo(() => ({\n amount: baseAmount,\n currencyCode: basePrice?.currencyCode ?? null,\n displayMode: basePrice?.displayMode ?? null,\n }), [baseAmount, basePrice?.currencyCode, basePrice?.displayMode])\n const usedKindIdSet = React.useMemo(() => {\n const next = new Set<string>()\n values.forEach((row) => {\n if (typeof row.priceKindId === 'string' && row.priceKindId.length) {\n next.add(row.priceKindId)\n }\n })\n return next\n }, [values])\n const availableKindCount = priceKinds.reduce(\n (count, kind) => (usedKindIdSet.has(kind.id) ? count : count + 1),\n 0,\n )\n const canAddRow = availableKindCount > 0\n const addRow = React.useCallback(() => {\n const usedIds = new Set<string>()\n values.forEach((row) => {\n if (typeof row.priceKindId === 'string' && row.priceKindId.length) {\n usedIds.add(row.priceKindId)\n }\n })\n const nextKind = priceKinds.find((kind) => !usedIds.has(kind.id))\n if (!nextKind && priceKinds.length) {\n return\n }\n onChange([\n ...values,\n {\n tempId: crypto.randomUUID?.() ?? Math.random().toString(36).slice(2),\n amount: baseDefaults.amount,\n currencyCode: nextKind?.currencyCode ?? baseDefaults.currencyCode,\n displayMode: nextKind?.displayMode ?? baseDefaults.displayMode,\n priceKindId: nextKind?.id ?? null,\n priceKindCode: nextKind?.code ?? nextKind?.title ?? null,\n },\n ])\n }, [baseDefaults, onChange, priceKinds, values])\n\n const updateRow = React.useCallback((tempId: string, patch: Partial<PriceOverrideDraft>) => {\n onChange(values.map((row) => (row.tempId === tempId ? { ...row, ...patch } : row)))\n }, [onChange, values])\n\n const removeRow = React.useCallback(async (row: PriceOverrideDraft) => {\n const allowRemoval = await onRemoveDraft?.(row)\n if (allowRemoval === false) return\n onChange(values.filter((entry) => entry.tempId !== row.tempId))\n }, [onChange, onRemoveDraft, values])\n\n return (\n <div className=\"space-y-4\">\n <div className=\"rounded border bg-muted/50 px-3 py-2\">\n <div className=\"text-xs uppercase text-muted-foreground\">\n {t('sales.channels.offers.pricing.basePriceLabel', 'Original product price')}\n </div>\n <div className=\"text-base font-semibold\">\n {basePrice ? formatPriceDisplay(basePrice) : t('sales.channels.offers.pricing.basePriceMissing', 'No price found')}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.pricing.basePriceHelp', 'Shown to shoppers when no override is configured.')}\n </div>\n </div>\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-muted-foreground\">\n {t('sales.channels.offers.pricing.help', 'Provide overrides for price kinds when this offer is active.')}\n </p>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={addRow} disabled={!canAddRow}>\n {t('sales.channels.offers.pricing.add', 'Add price')}\n </Button>\n </div>\n {!canAddRow ? (\n <p className=\"text-xs text-muted-foreground\">\n {priceKinds.length\n ? t('sales.channels.offers.pricing.allKindsUsed', 'Each price kind already has an override.')\n : t('sales.channels.offers.pricing.noKindsAvailable', 'Define a price kind before adding overrides.')}\n </p>\n ) : null}\n </div>\n <div className=\"flex items-center justify-between\">\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.pricing.overrideHint', 'Overrides take precedence over the original product price.')}\n </p>\n </div>\n {values.length ? (\n <div className=\"space-y-2\">\n {values.map((row) => (\n <div key={row.tempId} className=\"grid gap-2 rounded border p-3 md:grid-cols-3\">\n <Select\n value={row.priceKindId || undefined}\n onValueChange={(value) => {\n const next = priceKinds.find((kind) => kind.id === value)\n updateRow(row.tempId, {\n priceKindId: next?.id ?? null,\n priceKindCode: next?.code ?? next?.title ?? null,\n currencyCode: next?.currencyCode ?? null,\n displayMode: next?.displayMode ?? null,\n })\n }}\n >\n <SelectTrigger>\n <SelectValue placeholder={t('sales.channels.offers.pricing.selectKind', 'Select price kind')} />\n </SelectTrigger>\n <SelectContent>\n {priceKinds.map((kind) => (\n <SelectItem\n key={kind.id}\n value={kind.id}\n disabled={usedKindIdSet.has(kind.id) && row.priceKindId !== kind.id}\n >\n {kind.title ?? kind.code ?? kind.id}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <div className=\"relative\">\n {(row.currencyCode ?? basePrice?.currencyCode) ? (\n <span className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-xs font-semibold text-muted-foreground\">\n {row.currencyCode ?? basePrice?.currencyCode}\n </span>\n ) : null}\n <Input\n inputClassName={cn(row.currencyCode || basePrice?.currencyCode ? 'pl-13' : '')}\n type=\"number\"\n placeholder={t('sales.channels.offers.pricing.amount', 'Amount')}\n value={row.amount ?? ''}\n onChange={(event) => updateRow(row.tempId, { amount: event.target.value })}\n />\n </div>\n <div className=\"flex flex-col justify-between gap-2 text-xs text-muted-foreground sm:flex-row sm:items-center\">\n <span>\n {row.displayMode === 'including-tax'\n ? t('sales.channels.offers.pricing.includingTax', 'Including tax')\n : t('sales.channels.offers.pricing.excludingTax', 'Excluding tax')}\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"gap-1 px-2 font-normal text-destructive hover:text-destructive focus-visible:text-destructive\"\n onClick={() => { void removeRow(row) }}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n {t('sales.channels.offers.pricing.remove', 'Remove')}\n </Button>\n </div>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.pricing.empty', 'No overrides yet.')}\n {basePrice ? (\n <>\n {' '}\n {t(\n 'sales.channels.offers.pricing.emptyFallback',\n 'Using {price} from the product until you add overrides.',\n { price: formatPriceDisplay(basePrice) },\n )}\n </>\n ) : null}\n </p>\n )}\n </div>\n )\n}\n\nfunction ProductOverviewCard({ summary, variants }: { summary: ProductSummary; variants: ProductVariantPreview[] }) {\n const t = useT()\n if (!summary) {\n return (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSummaryPlaceholder', 'Select a product to preview its media, price, and variants.')}\n </p>\n )\n }\n return (\n <div className=\"space-y-4\">\n <div className=\"flex gap-3\">\n <div className=\"h-16 w-16 overflow-hidden rounded border bg-muted\">\n {summary.defaultMediaUrl ? (\n <img src={summary.defaultMediaUrl} alt={summary.title} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-5 w-5\" />\n </div>\n )}\n </div>\n <div className=\"flex-1\">\n <div className=\"text-sm font-semibold\">{summary.title || t('sales.channels.offers.form.productUntitled', 'Untitled product')}</div>\n {summary.sku ? (\n <div className=\"text-xs text-muted-foreground\">SKU \u00B7 {summary.sku}</div>\n ) : null}\n <div className=\"text-sm\">\n <span className=\"text-muted-foreground\">{t('sales.channels.offers.form.productPriceLabel', 'Base price')}:</span>{' '}\n <span className=\"font-semibold\">{formatPriceDisplay(summary.pricing)}</span>\n </div>\n </div>\n </div>\n {summary.description ? (\n <p className=\"text-sm text-muted-foreground\">{summary.description}</p>\n ) : null}\n <ProductVariantsList variants={variants} />\n </div>\n )\n}\n\nfunction ProductVariantsList({ variants }: { variants: ProductVariantPreview[] }) {\n const t = useT()\n if (!variants.length) {\n return (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.variantsEmpty', 'No variants available for this product.')}\n </p>\n )\n }\n return (\n <div className=\"space-y-2\">\n <div className=\"text-sm font-medium\">{t('sales.channels.offers.form.variantsTitle', 'Variants')}</div>\n <div className=\"space-y-2 max-h-64 overflow-y-auto pr-1\">\n {variants.map((variant) => (\n <div key={variant.id} className=\"flex gap-3 rounded border bg-card p-2\">\n <div className=\"h-10 w-10 overflow-hidden rounded border bg-muted\">\n {variant.thumbnailUrl ? (\n <img src={variant.thumbnailUrl} alt={variant.name} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-4 w-4\" />\n </div>\n )}\n </div>\n <div className=\"min-w-0\">\n <div className=\"text-xs font-medium\">{variant.name}</div>\n {variant.sku ? (\n <div className=\"text-overline text-muted-foreground\">SKU \u00B7 {variant.sku}</div>\n ) : null}\n </div>\n </div>\n ))}\n </div>\n </div>\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 { CrudForm, type CrudField, type CrudFormGroup, type CrudFormGroupComponentProps } from '@open-mercato/ui/backend/CrudForm'\nimport { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'\nimport { createCrud, updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { createCrudFormError, type CrudServerFieldErrors } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { readApiResultOrThrow, apiCall, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader, extractOptimisticLockConflict } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { ErrorMessage, RecordNotFoundState } from '@open-mercato/ui/backend/detail'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { Loader2, Search, Image as ImageIcon, Trash2 } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { extractCustomFieldEntries } from '@open-mercato/shared/lib/crud/custom-fields-client'\nimport { E } from '#generated/entities.ids.generated'\nimport { buildAttachmentImageUrl, slugifyAttachmentFileName } from '@open-mercato/core/modules/attachments/lib/imageUrls'\nimport { cn } from '@open-mercato/shared/lib/utils'\n\ntype PriceKindSummary = {\n id: string\n code: string | null\n title: string | null\n displayMode: 'including-tax' | 'excluding-tax'\n currencyCode: string | null\n}\n\ntype PriceOverrideDraft = {\n tempId: string\n priceId?: string | null\n priceKindId?: string | null\n priceKindCode?: string | null\n currencyCode?: string | null\n displayMode?: 'including-tax' | 'excluding-tax' | null\n amount?: string\n /** The price row's version, for the per-price optimistic-lock header (#2332). */\n updatedAt?: string | null\n}\n\nexport type OfferFormValues = {\n channelId: string | null\n productId: string | null\n title: string\n description: string\n defaultMediaId?: string | null\n isActive: boolean\n priceOverrides: PriceOverrideDraft[]\n updatedAt?: string | null\n} & Record<string, unknown>\n\ntype ChannelOfferFormProps = {\n channelId?: string\n offerId?: string\n mode: 'create' | 'edit'\n}\n\ntype OfferResponse = {\n items?: Array<Record<string, unknown>>\n}\n\ntype PriceResponse = {\n items?: Array<Record<string, unknown>>\n}\n\ntype AttachmentsResponse = {\n items?: Array<{ id?: string; fileName?: string; url?: string; thumbnailUrl?: string | null }>\n}\n\ntype ProductSummaryCacheEntry = {\n title: string\n description: string | null\n defaultMediaId: string | null\n defaultMediaUrl: string | null\n sku: string | null\n pricing: PricingSummary | null\n}\n\ntype MediaOption = { id: string; label: string; fileName: string; thumbnailUrl?: string | null }\n\ntype PricingSummary = {\n currencyCode: string | null\n unitPriceNet: string | null\n unitPriceGross: string | null\n displayMode: 'including-tax' | 'excluding-tax' | null\n}\n\ntype ProductVariantPreview = {\n id: string\n name: string\n sku: string | null\n thumbnailUrl: string | null\n thumbnailId: string | null\n thumbnailFileName: string | null\n}\n\ntype ProductSummary = ProductSummaryCacheEntry | null\n\ntype ProductSearchResult = {\n id: string\n title: string\n sku: string | null\n defaultMediaUrl: string | null\n pricing: PricingSummary | null\n existingOfferId: string | null\n existingOfferTitle: string | null\n isCurrentOfferProduct: boolean\n}\n\nconst UUID_REGEX = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/\nconst MAX_LIST_PAGE_SIZE = 100\ntype VariantThumbnailInfo = { attachmentId: string | null; thumbnailUrl: string | null; fileName: string | null }\n\nexport function ChannelOfferForm({ channelId: lockedChannelId, offerId, mode }: ChannelOfferFormProps) {\n const t = useT()\n const router = useRouter()\n const [initialValues, setInitialValues] = React.useState<OfferFormValues | null>(mode === 'create'\n ? {\n channelId: lockedChannelId ?? null,\n productId: null,\n title: '',\n description: '',\n defaultMediaId: null,\n isActive: true,\n priceOverrides: [],\n }\n : null)\n const [loading, setLoading] = React.useState(mode === 'edit')\n const [error, setError] = React.useState<string | null>(null)\n const [isNotFound, setIsNotFound] = React.useState(false)\n const [priceKinds, setPriceKinds] = React.useState<PriceKindSummary[]>([])\n const [mediaOptions, setMediaOptions] = React.useState<MediaOption[]>([])\n const attachmentCache = React.useRef<Map<string, MediaOption[]>>(new Map())\n const productCache = React.useRef<Map<string, ProductSummaryCacheEntry>>(new Map())\n const [productSummary, setProductSummary] = React.useState<ProductSummary>(null)\n const [variantPreviews, setVariantPreviews] = React.useState<ProductVariantPreview[]>([])\n const variantCache = React.useRef<Map<string, ProductVariantPreview[]>>(new Map())\n const variantMediaCache = React.useRef<Map<string, VariantThumbnailInfo>>(new Map())\n const [selectedChannelId, setSelectedChannelId] = React.useState<string | null>(lockedChannelId ?? null)\n const manualMediaSelections = React.useRef<Set<string>>(new Set())\n // Map of the loaded price-override id \u2192 its `updatedAt`, so deletes during the\n // offer save can send the price's own optimistic-lock version (#2332).\n const initialPriceVersionsRef = React.useRef<Map<string, string | null>>(new Map())\n const [currentProductId, setCurrentProductId] = React.useState<string | null>(null)\n React.useEffect(() => {\n if (initialValues) {\n initialPriceVersionsRef.current = collectPriceVersions(initialValues.priceOverrides)\n } else {\n initialPriceVersionsRef.current = new Map()\n }\n }, [initialValues])\n const channelOffersHref = React.useMemo(\n () => buildChannelOffersHref(lockedChannelId),\n [lockedChannelId],\n )\n\n React.useEffect(() => {\n if (lockedChannelId) {\n setSelectedChannelId(lockedChannelId)\n } else if (initialValues?.channelId) {\n setSelectedChannelId(initialValues.channelId)\n }\n }, [initialValues?.channelId, lockedChannelId])\n\n React.useEffect(() => {\n if (typeof initialValues?.productId === 'string') {\n setCurrentProductId(initialValues.productId)\n }\n }, [initialValues?.productId])\n\n React.useEffect(() => {\n if (typeof initialValues?.productId === 'string' && initialValues?.defaultMediaId === null) {\n manualMediaSelections.current.add(initialValues.productId)\n }\n }, [initialValues?.defaultMediaId, initialValues?.productId])\n\n React.useEffect(() => {\n if (mode !== 'edit') return\n const productId = typeof initialValues?.productId === 'string' ? initialValues.productId : null\n if (!productId) return\n const resolvedProductId = productId\n const hydrationChannelId = selectedChannelId\n ?? lockedChannelId\n ?? (typeof initialValues?.channelId === 'string' ? initialValues.channelId : null)\n let cancelled = false\n async function hydrateExistingProduct() {\n try {\n const [summary, attachments, variants] = await Promise.all([\n resolveProductSummaryWithCache({\n productId: resolvedProductId,\n channelId: hydrationChannelId ?? null,\n productCache,\n }),\n resolveProductMediaOptionsWithCache({ productId: resolvedProductId, attachmentCache }),\n resolveVariantPreviewsWithCache({ productId: resolvedProductId, variantCache, variantMediaCache }),\n ])\n if (!cancelled) {\n setProductSummary(summary ?? null)\n const mergedMedia = buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n })\n attachmentCache.current.set(resolvedProductId, mergedMedia)\n setMediaOptions(mergedMedia)\n setVariantPreviews(variants)\n }\n } catch (err) {\n console.error('sales.channels.offer.initialHydrate', err)\n }\n }\n void hydrateExistingProduct()\n return () => {\n cancelled = true\n }\n }, [\n attachmentCache,\n initialValues?.channelId,\n initialValues?.productId,\n lockedChannelId,\n mode,\n productCache,\n selectedChannelId,\n setMediaOptions,\n setProductSummary,\n setVariantPreviews,\n variantCache,\n variantMediaCache,\n ])\n\n React.useEffect(() => {\n async function loadKinds() {\n const mapItems = (items: Array<Record<string, unknown>>): PriceKindSummary[] =>\n items.map((item): PriceKindSummary => {\n const displayMode =\n item.displayMode === 'including-tax' || item.display_mode === 'including-tax'\n ? 'including-tax'\n : 'excluding-tax'\n return {\n id: typeof item.id === 'string' ? item.id : '',\n code: typeof item.code === 'string' ? item.code : null,\n title: typeof item.title === 'string' ? item.title : null,\n currencyCode:\n typeof item.currencyCode === 'string'\n ? item.currencyCode\n : typeof item.currency_code === 'string'\n ? item.currency_code\n : null,\n displayMode,\n }\n })\n const endpoints = [\n `/api/sales/price-kinds?pageSize=${MAX_LIST_PAGE_SIZE}`,\n `/api/catalog/price-kinds?pageSize=${MAX_LIST_PAGE_SIZE}`,\n ]\n try {\n for (const endpoint of endpoints) {\n try {\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n endpoint,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n setPriceKinds(mapItems(items))\n return\n } catch (err) {\n console.error('sales.channels.price-kinds.fetch', { endpoint, err })\n }\n }\n setPriceKinds([])\n } catch (err) {\n console.error('catalog.price-kinds.list', err)\n }\n }\n void loadKinds()\n }, [])\n\n React.useEffect(() => {\n if (mode !== 'edit' || !offerId) return\n const offerKey = offerId\n let cancelled = false\n async function loadOffer() {\n setLoading(true)\n setError(null)\n setIsNotFound(false)\n try {\n const payload = await readApiResultOrThrow<OfferResponse>(\n `/api/catalog/offers?id=${encodeURIComponent(offerKey)}&pageSize=1`,\n undefined,\n { errorMessage: t('sales.channels.offers.errors.loadOffer', 'Failed to load offer.') },\n )\n const offer = Array.isArray(payload.items) ? payload.items[0] : null\n if (!offer) {\n if (!cancelled) setIsNotFound(true)\n return\n }\n const values = mapOfferToFormValues(offer, lockedChannelId)\n const pricePayload = await readApiResultOrThrow<PriceResponse>(\n `/api/catalog/prices?offerId=${encodeURIComponent(offer.id as string)}&pageSize=${MAX_LIST_PAGE_SIZE}`,\n undefined,\n { fallback: { items: [] } },\n )\n const priceItems = Array.isArray(pricePayload.items) ? pricePayload.items : []\n values.priceOverrides = priceItems.map(mapPriceRow)\n let preloadedMedia: MediaOption[] = []\n let preloadedVariants: ProductVariantPreview[] = []\n let preloadedSummary: ProductSummary | null = null\n const productId = typeof values.productId === 'string' ? values.productId : null\n if (productId) {\n try {\n const hydrationChannelId = selectedChannelId\n ?? lockedChannelId\n ?? (typeof values.channelId === 'string' ? values.channelId : null)\n const [summary, attachments, variants] = await Promise.all([\n resolveProductSummaryWithCache({\n productId,\n channelId: hydrationChannelId ?? null,\n productCache,\n }),\n loadProductMedia(productId),\n resolveVariantPreviewsWithCache({ productId, variantCache, variantMediaCache }),\n ])\n preloadedSummary = summary ?? null\n preloadedVariants = variants\n preloadedMedia = buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n })\n attachmentCache.current.set(productId, preloadedMedia)\n } catch (err) {\n console.error('sales.channels.offer.media.preload', err)\n }\n }\n if (!cancelled) {\n setInitialValues(values)\n setProductSummary(preloadedSummary)\n setVariantPreviews(preloadedVariants)\n setMediaOptions(preloadedMedia)\n }\n } catch (err) {\n console.error('sales.channels.offer.load', err)\n if (!cancelled) setError(t('sales.channels.offers.errors.loadOffer', 'Failed to load offer.'))\n } finally {\n if (!cancelled) setLoading(false)\n }\n }\n void loadOffer()\n return () => { cancelled = true }\n }, [\n attachmentCache,\n lockedChannelId,\n mode,\n offerId,\n productCache,\n selectedChannelId,\n setMediaOptions,\n setProductSummary,\n setVariantPreviews,\n t,\n variantCache,\n variantMediaCache,\n ])\n\n const fields = React.useMemo<CrudField[]>(() => [\n {\n id: 'channelId',\n label: t('sales.channels.offers.form.channel', 'Channel'),\n type: 'custom',\n required: true,\n component: ({ value, setValue }) => (\n <ChannelSelectInput\n value={(value as string | null) ?? lockedChannelId ?? null}\n onChange={(next) => {\n setValue(next ?? null)\n setSelectedChannelId(next ?? null)\n }}\n disabled={!!lockedChannelId}\n showDetailsLink\n />\n ),\n },\n {\n id: 'productId',\n label: t('sales.channels.offers.form.product', 'Product'),\n type: 'custom',\n required: true,\n component: ({ value, setValue }) => (\n <ProductSelectInput\n value={(value as string | null) ?? null}\n onChange={(next) => setValue(next)}\n channelId={selectedChannelId}\n currentOfferId={offerId ?? null}\n />\n ),\n },\n {\n id: 'defaultMediaId',\n label: t('sales.channels.offers.form.defaultMedia', 'Default media'),\n type: 'custom',\n component: ({ value, setValue }) => (\n <DefaultMediaSelect\n value={(value as string | null | undefined) ?? null}\n onChange={(next) => {\n setValue(next)\n if (!currentProductId) return\n if (next === null || next === undefined) {\n manualMediaSelections.current.add(currentProductId)\n } else {\n manualMediaSelections.current.delete(currentProductId)\n }\n }}\n options={mediaOptions}\n productThumbnail={productSummary?.defaultMediaUrl ?? null}\n hasProduct={Boolean(productSummary)}\n productDefaultMediaId={productSummary?.defaultMediaId ?? null}\n />\n ),\n },\n {\n id: 'title',\n label: t('sales.channels.offers.form.title', 'Title'),\n type: 'text',\n required: true,\n },\n {\n id: 'description',\n label: t('sales.channels.offers.form.description', 'Description'),\n type: 'textarea',\n },\n {\n id: 'isActive',\n label: t('sales.channels.offers.form.active', 'Active'),\n type: 'checkbox',\n },\n ], [lockedChannelId, mediaOptions, productSummary, selectedChannelId, t, currentProductId])\n\n const handleOverrideRemove = React.useCallback(async (draft: PriceOverrideDraft) => {\n const priceId = typeof draft?.priceId === 'string' ? draft.priceId : null\n if (!priceId) return true\n if (mode !== 'edit') return true\n try {\n await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(draft.updatedAt),\n () => deleteCrud('catalog/prices', priceId, {\n errorMessage: t('sales.channels.offers.errors.removePrice', 'Failed to remove price override.'),\n }),\n )\n initialPriceVersionsRef.current.delete(priceId)\n return true\n } catch (err) {\n if (surfaceRecordConflict(err, t)) return false\n console.error('sales.channels.pricing.remove', err)\n flash(t('sales.channels.offers.errors.removePrice', 'Failed to remove price override.'), 'error')\n return false\n }\n }, [mode, t])\n\n const groups = React.useMemo<CrudFormGroup[]>(() => [\n { id: 'associations', column: 1, title: t('sales.channels.offers.form.groups.associations', 'Associations'), fields: ['channelId'] },\n {\n id: 'product',\n column: 1,\n title: t('sales.channels.offers.form.productGroup', 'Product'),\n description: t('sales.channels.offers.form.productGroupHelp', 'Search the catalog and pick the product you want to customize for this channel.'),\n fields: ['productId'],\n },\n {\n id: 'productSummary',\n column: 2,\n title: t('sales.channels.offers.form.productSummaryTitle', 'Product summary'),\n component: () => (\n <ProductOverviewCard summary={productSummary} variants={variantPreviews} />\n ),\n },\n {\n id: 'media',\n column: 1,\n title: t('sales.channels.offers.form.mediaGroupTitle', 'Default media override'),\n fields: ['defaultMediaId'],\n },\n { id: 'content', column: 1, title: t('sales.channels.offers.form.groups.content', 'Content'), fields: ['title', 'description', 'isActive'] },\n {\n id: 'pricing',\n column: 1,\n title: t('sales.channels.offers.form.groups.pricing', 'Price overrides'),\n component: ({ values, setValue }) => (\n <PriceOverridesEditor\n values={Array.isArray(values.priceOverrides) ? values.priceOverrides as PriceOverrideDraft[] : []}\n onChange={(next) => setValue('priceOverrides', next)}\n priceKinds={priceKinds}\n basePrice={productSummary?.pricing ?? null}\n onRemoveDraft={handleOverrideRemove}\n />\n ),\n },\n {\n id: 'customFields',\n column: 2,\n title: t('entities.customFields.title', 'Custom attributes'),\n kind: 'customFields',\n },\n {\n id: 'watchers',\n column: 1,\n bare: true,\n component: ({ values, setValue, errors }) => (\n <OfferFormWatchers\n values={values}\n setValue={setValue}\n errors={errors}\n productCache={productCache}\n attachmentCache={attachmentCache}\n setMediaOptions={setMediaOptions}\n setProductSummary={setProductSummary}\n setVariantPreviews={setVariantPreviews}\n variantCache={variantCache}\n variantMediaCache={variantMediaCache}\n channelId={selectedChannelId}\n manualMediaSelections={manualMediaSelections}\n setCurrentProductId={setCurrentProductId}\n />\n ),\n },\n ], [\n attachmentCache,\n handleOverrideRemove,\n manualMediaSelections,\n priceKinds,\n productCache,\n productSummary,\n selectedChannelId,\n setMediaOptions,\n setCurrentProductId,\n t,\n variantPreviews,\n ])\n\n const handleSubmit = React.useCallback(async (values: OfferFormValues) => {\n const channelId = typeof values.channelId === 'string' && values.channelId.length\n ? values.channelId\n : selectedChannelId ?? lockedChannelId\n const productId = typeof values.productId === 'string' ? values.productId : null\n if (!channelId || !productId) {\n throw new Error(t('sales.channels.offers.errors.requiredFields', 'Choose a channel and product.'))\n }\n const resolvedDefaultMediaId = typeof values.defaultMediaId === 'string' && values.defaultMediaId.trim().length\n ? values.defaultMediaId\n : values.defaultMediaId === null\n ? null\n : undefined\n const basePayload: Record<string, unknown> = {\n channelId,\n productId,\n title: values.title?.trim() || undefined,\n description: values.description?.trim() || undefined,\n isActive: values.isActive !== false,\n }\n if (resolvedDefaultMediaId !== undefined) {\n basePayload.defaultMediaId = resolvedDefaultMediaId\n }\n const attachmentLookup = attachmentCache.current.get(productId) ?? []\n const mediaMap = new Map(attachmentLookup.map((entry) => [entry.id, entry.fileName]))\n if (typeof resolvedDefaultMediaId === 'string' && mediaMap.has(resolvedDefaultMediaId)) {\n const fileName = mediaMap.get(resolvedDefaultMediaId) ?? null\n basePayload.defaultMediaUrl = buildAttachmentImageUrl(resolvedDefaultMediaId, {\n slug: slugifyAttachmentFileName(fileName),\n })\n } else if (resolvedDefaultMediaId === null) {\n basePayload.defaultMediaUrl = null\n }\n const customFields = collectCustomFieldValues(values)\n if (Object.keys(customFields).length) basePayload.customFields = customFields\n const overrides = Array.isArray(values.priceOverrides) ? values.priceOverrides as PriceOverrideDraft[] : []\n const priceWithoutKind = overrides.find((entry) => {\n const amount = typeof entry.amount === 'string' ? entry.amount.trim() : entry.amount\n const hasAmount = typeof amount === 'string' ? amount.length > 0 : amount !== undefined && amount !== null\n const hasExistingPrice = typeof entry.priceId === 'string' && entry.priceId.length > 0\n const hasCurrency = typeof entry.currencyCode === 'string' && entry.currencyCode.length > 0\n return !entry.priceKindId && (hasAmount || hasExistingPrice || hasCurrency)\n })\n if (priceWithoutKind) {\n throw createCrudFormError(t('sales.channels.offers.errors.priceKindRequired', 'Select a price kind for each override.'), {})\n }\n const duplicateKind = (() => {\n const seen = new Set<string>()\n for (const entry of overrides) {\n const kindId = typeof entry.priceKindId === 'string' ? entry.priceKindId : null\n if (!kindId) continue\n if (seen.has(kindId)) return kindId\n seen.add(kindId)\n }\n return null\n })()\n if (duplicateKind) {\n throw createCrudFormError(\n t('sales.channels.offers.errors.priceKindDuplicate', 'Each price kind can only be overridden once.'),\n {},\n )\n }\n const submittedPriceIds = collectPriceIds(overrides)\n const deletedIdSet = new Set<string>()\n initialPriceVersionsRef.current.forEach((_version, id) => {\n if (!submittedPriceIds.has(id)) deletedIdSet.add(id)\n })\n const deletedIds = Array.from(deletedIdSet)\n const deletedVersions = new Map(deletedIds.map((id) => [id, initialPriceVersionsRef.current.get(id) ?? null]))\n let savedId = offerId ?? null\n try {\n if (mode === 'create') {\n const res = await createCrud<{ id?: string; offerId?: string }>('catalog/offers', basePayload, {\n errorMessage: t('sales.channels.offers.errors.save', 'Failed to save offer.'),\n })\n savedId = res?.result?.offerId ?? res?.result?.id ?? null\n } else if (offerId) {\n await updateCrud('catalog/offers', { id: offerId, ...basePayload }, {\n errorMessage: t('sales.channels.offers.errors.save', 'Failed to save offer.'),\n })\n savedId = offerId\n }\n } catch (err) {\n // Let an optimistic-lock 409 propagate untouched so CrudForm's\n // extractOptimisticLockConflict still sees the top-level `code` /\n // `currentUpdatedAt` / `expectedUpdatedAt` and surfaces the unified\n // conflict bar. Re-wrapping via createCrudFormError below would drop them.\n if (extractOptimisticLockConflict(err)) {\n throw err\n }\n const details = (err as { details?: unknown })?.details\n const rawFieldErrors = (err as { fieldErrors?: unknown })?.fieldErrors\n const fieldErrors = rawFieldErrors && typeof rawFieldErrors === 'object'\n ? (rawFieldErrors as CrudServerFieldErrors)\n : undefined\n const status = (err as { status?: number })?.status\n const message = typeof (err as { message?: unknown }).message === 'string' && (err as { message: string }).message.trim().length\n ? (err as { message: string }).message\n : t(\n 'sales.channels.offers.errors.duplicateProduct',\n 'This product already has an offer in this channel.',\n )\n throw createCrudFormError(\n message,\n fieldErrors,\n { status, details },\n )\n }\n if (savedId) {\n await syncPriceOverrides({\n overrides,\n deletedIds,\n deletedVersions,\n offerId: savedId,\n channelId,\n productId,\n })\n initialPriceVersionsRef.current = collectPriceVersions(overrides)\n }\n flash(t('sales.channels.offers.messages.saved', 'Offer saved.'), 'success')\n router.push(buildChannelOffersHref(channelId))\n }, [attachmentCache, lockedChannelId, mode, offerId, router, selectedChannelId, t])\n\n const handleDelete = React.useCallback(async () => {\n if (!offerId) return\n await deleteCrud('catalog/offers', offerId, {\n errorMessage: t('sales.channels.offers.errors.delete', 'Failed to delete offer.'),\n })\n flash(t('sales.channels.offers.messages.deleted', 'Offer deleted.'), 'success')\n const targetChannel = initialValues?.channelId ?? lockedChannelId ?? ''\n router.push(buildChannelOffersHref(targetChannel))\n }, [initialValues?.channelId, lockedChannelId, offerId, router, t])\n\n if (isNotFound) {\n return (\n <RecordNotFoundState\n label={t('sales.channels.offers.errors.notFound', 'Offer not found.')}\n backHref={channelOffersHref}\n backLabel={t('sales.channels.offers.actions.backToList', 'Back to offers')}\n />\n )\n }\n\n return (\n <div>\n {error ? <ErrorMessage label={error} className=\"mb-4\" /> : null}\n <CrudForm<OfferFormValues>\n title={mode === 'create'\n ? t('sales.channels.offers.form.createTitle', 'Create offer')\n : t('sales.channels.offers.form.editTitle', 'Edit offer')}\n entityId={E.catalog.catalog_offer}\n fields={fields}\n groups={groups}\n initialValues={initialValues ?? undefined}\n optimisticLockUpdatedAt={initialValues?.updatedAt}\n isLoading={loading}\n loadingMessage={t('sales.channels.offers.form.loading', 'Loading offer\u2026')}\n submitLabel={mode === 'create'\n ? t('sales.channels.offers.form.createSubmit', 'Create offer')\n : t('sales.channels.offers.form.updateSubmit', 'Save changes')}\n cancelHref={channelOffersHref}\n backHref={channelOffersHref}\n onSubmit={handleSubmit}\n onDelete={mode === 'edit' ? handleDelete : undefined}\n deleteVisible={mode === 'edit'}\n deleteRedirect={channelOffersHref}\n />\n </div>\n )\n}\n\nfunction mapOfferToFormValues(item: Record<string, unknown>, lockedChannelId?: string | null): OfferFormValues {\n const values: OfferFormValues = {\n channelId: typeof item.channelId === 'string'\n ? item.channelId\n : typeof item.channel_id === 'string'\n ? item.channel_id\n : lockedChannelId ?? null,\n productId: typeof item.productId === 'string'\n ? item.productId\n : typeof item.product_id === 'string'\n ? item.product_id\n : null,\n title: typeof item.title === 'string' ? item.title : '',\n description: typeof item.description === 'string' ? item.description : '',\n defaultMediaId: typeof item.defaultMediaId === 'string'\n ? item.defaultMediaId\n : typeof item.default_media_id === 'string'\n ? item.default_media_id\n : null,\n isActive: item.isActive === true || item.is_active === true,\n priceOverrides: [],\n updatedAt: typeof item.updatedAt === 'string'\n ? item.updatedAt\n : typeof item.updated_at === 'string'\n ? item.updated_at\n : null,\n }\n mergeCustomFieldValues(values, item)\n return values\n}\n\nfunction mapPriceRow(row: Record<string, unknown>): PriceOverrideDraft {\n return {\n tempId: String(row.id ?? crypto.randomUUID?.() ?? Math.random()),\n priceId: typeof row.id === 'string' ? row.id : undefined,\n priceKindId: typeof row.priceKindId === 'string'\n ? row.priceKindId\n : typeof row.price_kind_id === 'string'\n ? row.price_kind_id\n : undefined,\n priceKindCode: typeof row.priceKindCode === 'string'\n ? row.priceKindCode\n : typeof row.price_kind_code === 'string'\n ? row.price_kind_code\n : null,\n currencyCode: typeof row.currencyCode === 'string'\n ? row.currencyCode\n : typeof row.currency_code === 'string'\n ? row.currency_code\n : null,\n displayMode: row.displayMode === 'including-tax' || row.display_mode === 'including-tax'\n ? 'including-tax'\n : 'excluding-tax',\n amount: typeof row.unitPriceNet === 'string'\n ? row.unitPriceNet\n : typeof row.unit_price_net === 'string'\n ? row.unit_price_net\n : typeof row.unitPriceGross === 'string'\n ? row.unitPriceGross\n : typeof row.unit_price_gross === 'string'\n ? row.unit_price_gross\n : '',\n updatedAt: typeof row.updatedAt === 'string'\n ? row.updatedAt\n : typeof row.updated_at === 'string'\n ? row.updated_at\n : null,\n }\n}\n\nfunction collectPriceIds(source: PriceOverrideDraft[] | null | undefined): Set<string> {\n if (!Array.isArray(source)) return new Set()\n const ids = source\n .map((entry) => (typeof entry?.priceId === 'string' ? entry.priceId : null))\n .filter((id): id is string => Boolean(id))\n return new Set(ids)\n}\n\nfunction collectPriceVersions(source: PriceOverrideDraft[] | null | undefined): Map<string, string | null> {\n const versions = new Map<string, string | null>()\n if (!Array.isArray(source)) return versions\n for (const entry of source) {\n if (typeof entry?.priceId === 'string' && entry.priceId) {\n versions.set(entry.priceId, typeof entry.updatedAt === 'string' ? entry.updatedAt : null)\n }\n }\n return versions\n}\n\nfunction mergeCustomFieldValues(target: Record<string, unknown>, source: Record<string, unknown> | null | undefined) {\n Object.assign(target, extractCustomFieldEntries(source ?? {}))\n}\n\nfunction buildChannelOffersHref(channelId?: string | null): string {\n return channelId && channelId.length\n ? `/backend/sales/channels/${channelId}/edit?tab=offers`\n : '/backend/sales/channels/offers'\n}\n\nasync function syncPriceOverrides(params: {\n overrides: PriceOverrideDraft[]\n deletedIds: string[]\n deletedVersions: Map<string, string | null>\n offerId: string\n channelId: string\n productId: string\n}) {\n const { overrides, deletedIds, deletedVersions, offerId, channelId, productId } = params\n for (const draft of overrides) {\n if (!draft.priceKindId || !draft.amount) continue\n const amount = Number(draft.amount)\n if (Number.isNaN(amount)) continue\n const payload: Record<string, unknown> = {\n offerId,\n productId,\n channelId,\n priceKindId: draft.priceKindId,\n currencyCode: draft.currencyCode ?? undefined,\n }\n if (draft.displayMode === 'including-tax') {\n payload.unitPriceGross = amount\n } else {\n payload.unitPriceNet = amount\n }\n if (draft.priceId) {\n // Send the PRICE's own version, overriding the offer header the parent\n // CrudForm submit scope put on the stack (otherwise the price guard would\n // compare the offer's `updated_at` and 409 falsely). #2332.\n const priceId = draft.priceId\n await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(draft.updatedAt),\n () => updateCrud('catalog/prices', { id: priceId, ...payload }),\n )\n } else {\n await createCrud('catalog/prices', payload)\n }\n }\n const uniqueDeletedIds = Array.from(new Set(\n deletedIds.filter((id): id is string => typeof id === 'string' && id.length > 0),\n ))\n for (const id of uniqueDeletedIds) {\n if (!id) continue\n try {\n await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(deletedVersions.get(id) ?? null),\n () => deleteCrud('catalog/prices', id),\n )\n } catch (err) {\n console.error('catalog.prices.delete', err)\n }\n }\n}\n\nfunction ChannelSelectInput({\n value,\n onChange,\n disabled,\n showDetailsLink,\n}: {\n value: string | null\n onChange: (next: string | null) => void\n disabled?: boolean\n showDetailsLink?: boolean\n}) {\n const t = useT()\n const [options, setOptions] = React.useState<Array<{ id: string; name: string; code: string | null }>>([])\n const selectedOption = React.useMemo(\n () => (value ? options.find((opt) => opt.id === value) ?? null : null),\n [options, value],\n )\n React.useEffect(() => {\n async function load() {\n try {\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/channels?pageSize=${MAX_LIST_PAGE_SIZE}`,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n setOptions(items.map((item) => ({\n id: typeof item.id === 'string' ? item.id : '',\n name: typeof item.name === 'string' ? item.name : '',\n code: typeof item.code === 'string' ? item.code : null,\n })))\n } catch (err) {\n console.error('sales.channels.options', err)\n }\n }\n void load()\n }, [])\n React.useEffect(() => {\n const channelIdToLoad = typeof value === 'string' ? value : null\n if (!channelIdToLoad || selectedOption) return\n const resolvedChannelId = channelIdToLoad\n let cancelled = false\n async function loadSingle() {\n try {\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/channels?id=${encodeURIComponent(resolvedChannelId)}&pageSize=1`,\n undefined,\n { fallback: { items: [] } },\n )\n const item = Array.isArray(payload.items) ? payload.items[0] : null\n if (!item || cancelled) return\n const entry = {\n id: typeof item.id === 'string' ? item.id : resolvedChannelId,\n name: typeof item.name === 'string' ? item.name : resolvedChannelId,\n code: typeof item.code === 'string' ? item.code : null,\n }\n setOptions((prev) => {\n if (prev.some((opt) => opt.id === entry.id)) return prev\n return [...prev, entry]\n })\n } catch (err) {\n console.error('sales.channels.lookup', err)\n }\n }\n void loadSingle()\n return () => { cancelled = true }\n }, [selectedOption, value])\n\n if (disabled && value) {\n const label = selectedOption?.name ?? value\n const detail = selectedOption?.code ?? null\n return (\n <div className=\"flex items-center justify-between gap-3 rounded border bg-muted px-3 py-2 text-sm\">\n <div className=\"min-w-0\">\n <div className=\"font-medium truncate\">{label}</div>\n {detail ? (\n <div className=\"text-xs text-muted-foreground truncate\">{detail}</div>\n ) : null}\n </div>\n {showDetailsLink ? (\n <Link href={`/backend/sales/channels/${value}/edit`} className=\"text-xs font-medium text-primary hover:underline\">\n {t('sales.channels.offers.form.channelDetails', 'Details')}\n </Link>\n ) : null}\n </div>\n )\n }\n return (\n <Select value={value || undefined} onValueChange={(next) => onChange(next || null)}>\n <SelectTrigger>\n <SelectValue placeholder={t('sales.channels.offers.form.channelPlaceholder', 'Select channel')} />\n </SelectTrigger>\n <SelectContent>\n {options.map((opt) => (\n <SelectItem key={opt.id} value={opt.id}>\n {opt.code ? `${opt.name} (${opt.code})` : opt.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )\n}\n\nfunction ProductSelectInput({\n value,\n onChange,\n channelId,\n currentOfferId,\n}: {\n value: string | null\n onChange: (next: string | null) => void\n channelId: string | null\n currentOfferId?: string | null\n}) {\n const t = useT()\n const [query, setQuery] = React.useState('')\n const [results, setResults] = React.useState<ProductSearchResult[]>([])\n const [isLoading, setLoading] = React.useState(false)\n const [hasTyped, setHasTyped] = React.useState(false)\n\n const trimmed = query.trim()\n const shouldSearch = trimmed.length >= 2 || UUID_REGEX.test(trimmed)\n\n React.useEffect(() => {\n if (!shouldSearch) {\n setResults([])\n return\n }\n let cancelled = false\n const controller = new AbortController()\n const timeout = setTimeout(async () => {\n setLoading(true)\n try {\n const params = new URLSearchParams({ pageSize: '10' })\n if (UUID_REGEX.test(trimmed)) {\n params.set('id', trimmed)\n } else if (trimmed.length) {\n params.set('search', trimmed)\n }\n if (channelId) params.set('channelId', channelId)\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/catalog/products?${params.toString()}`,\n { signal: controller.signal },\n { fallback: { items: [] } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n if (!cancelled) {\n const mapped = items.map((item) => mapProductSearchResult(item, channelId, currentOfferId))\n mapped.sort((a, b) => {\n const aBlocked = Boolean(a.existingOfferId && !a.isCurrentOfferProduct)\n const bBlocked = Boolean(b.existingOfferId && !b.isCurrentOfferProduct)\n return Number(aBlocked) - Number(bBlocked)\n })\n setResults(mapped)\n }\n } catch (err) {\n if ((err as Error).name === 'AbortError') return\n console.error('catalog.products.lookup', err)\n } finally {\n if (!cancelled) setLoading(false)\n }\n }, 250)\n return () => {\n cancelled = true\n clearTimeout(timeout)\n controller.abort()\n }\n }, [channelId, currentOfferId, shouldSearch, trimmed])\n\n const handleKeyDown = React.useCallback((event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key === 'Enter' && UUID_REGEX.test(trimmed)) {\n event.preventDefault()\n onChange(trimmed)\n }\n }, [onChange, trimmed])\n\n const selectedHint = value\n ? t('sales.channels.offers.form.productSelectedHint', 'Selected product ID: {{id}}', { id: value })\n : null\n\n return (\n <div className=\"space-y-3\">\n <Input\n leftIcon={<Search />}\n value={query}\n onChange={(event) => {\n setQuery(event.target.value)\n setHasTyped(true)\n }}\n onKeyDown={handleKeyDown}\n placeholder={t('sales.channels.offers.form.productSearchPlaceholder', 'Search by title, SKU, or ID\u2026')}\n />\n {selectedHint ? (\n <div className=\"rounded border bg-muted px-3 py-2 text-xs text-muted-foreground\">\n {selectedHint}\n </div>\n ) : null}\n {value ? (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => onChange(null)}>\n {t('sales.channels.offers.form.productClear', 'Clear selection')}\n </Button>\n ) : null}\n {shouldSearch ? (\n <div className=\"space-y-2\">\n {isLoading ? (\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n {t('sales.channels.offers.form.productSearchLoading', 'Searching products\u2026')}\n </div>\n ) : null}\n {!isLoading && !results.length ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSearchEmpty', 'No products match your search.')}\n </p>\n ) : null}\n <div className=\"space-y-2 max-h-80 overflow-y-auto\">\n {results.map((product) => {\n const isSelected = value === product.id\n const hasConflict = Boolean(product.existingOfferId && !product.isCurrentOfferProduct)\n return (\n <div\n key={product.id}\n className={cn(\n 'flex gap-3 rounded border bg-card p-3 transition-colors',\n isSelected ? 'border-primary/70 bg-primary/5' : 'hover:border-primary/50',\n )}\n >\n <div className=\"h-12 w-12 overflow-hidden rounded border bg-muted\">\n {product.defaultMediaUrl ? (\n <img src={product.defaultMediaUrl} alt={product.title} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-5 w-5\" />\n </div>\n )}\n </div>\n <div className=\"flex flex-1 flex-col gap-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-medium\">{product.title || t('sales.channels.offers.form.productUntitled', 'Untitled product')}</div>\n {product.sku ? (\n <div className=\"text-xs text-muted-foreground\">SKU \u00B7 {product.sku}</div>\n ) : null}\n </div>\n <div className=\"text-xs font-medium text-muted-foreground\">\n {product.pricing ? formatPriceDisplay(product.pricing) : t('sales.channels.offers.form.productPriceMissing', 'No price')}\n </div>\n </div>\n {hasConflict ? (\n <div className=\"flex items-center justify-between gap-2 text-xs text-status-warning-text\">\n <span className=\"truncate\">\n {t('sales.channels.offers.form.productHasOffer', 'Already has an offer for this channel.')}\n </span>\n {channelId && product.existingOfferId ? (\n <Link\n href={`/backend/sales/channels/${encodeURIComponent(\n String(channelId)\n )}/offers/${encodeURIComponent(String(product.existingOfferId))}/edit`}\n className=\"shrink-0 font-medium text-primary hover:underline\"\n >\n {t('sales.channels.offers.form.productHasOfferLink', 'View offer')}\n </Link>\n ) : null}\n </div>\n ) : null}\n <div className=\"flex justify-end\">\n <Button\n type=\"button\"\n variant={isSelected ? 'secondary' : 'outline'}\n size=\"sm\"\n onClick={() => onChange(product.id)}\n disabled={hasConflict && !isSelected}\n >\n {hasConflict && !isSelected\n ? t('sales.channels.offers.form.productUnavailable', 'Unavailable')\n : isSelected\n ? t('sales.channels.offers.form.productSelected', 'Selected')\n : t('sales.channels.offers.form.productSelect', 'Select')}\n </Button>\n </div>\n </div>\n </div>\n )\n })}\n </div>\n </div>\n ) : hasTyped ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSearchHint', 'Type at least 2 characters or paste a product ID.')}\n </p>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSearchIntro', 'Search by name or paste the product id to find catalog items.')}\n </p>\n )}\n </div>\n )\n}\n\nfunction DefaultMediaSelect({\n value,\n options,\n onChange,\n productThumbnail,\n hasProduct,\n productDefaultMediaId,\n}: {\n value: string | null\n options: MediaOption[]\n onChange: (next: string | null) => void\n productThumbnail: string | null\n hasProduct: boolean\n productDefaultMediaId?: string | null\n}) {\n const t = useT()\n const filteredOptions = React.useMemo(() => {\n if (!productDefaultMediaId) return options\n return options.filter((opt) => opt.id !== productDefaultMediaId)\n }, [options, productDefaultMediaId])\n const hasAttachmentOptions = filteredOptions.length > 0\n const showPlaceholder = !hasAttachmentOptions && !productThumbnail && !hasProduct\n if (showPlaceholder) {\n return (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.mediaSelectProduct', 'Select a product to load its media.')}\n </p>\n )\n }\n const tiles = [\n {\n id: 'inherit',\n label: t('sales.channels.offers.form.mediaInherit', 'Use product default'),\n thumbnail: productThumbnail,\n selected: value == null,\n onClick: () => onChange(null),\n },\n ...filteredOptions.map((opt) => ({\n id: opt.id,\n label: opt.label,\n thumbnail: opt.thumbnailUrl ?? null,\n selected: value === opt.id,\n onClick: () => onChange(opt.id),\n })),\n ]\n return (\n <div className=\"space-y-3\">\n <div className=\"text-xs text-muted-foreground\">\n <p>\n {t('sales.channels.offers.form.mediaHelp', 'Choose the thumbnail that should represent this offer in the channel.')}\n </p>\n {!hasAttachmentOptions && hasProduct ? (\n <p className=\"mt-1\">\n {t('sales.channels.offers.form.mediaEmpty', 'This product has no uploaded media yet; the product default will be used.')}\n </p>\n ) : null}\n </div>\n <div className=\"grid gap-3 sm:grid-cols-3\">\n {tiles.map((tile) => (\n <button\n key={tile.id}\n type=\"button\"\n className={cn(\n 'flex flex-col rounded border text-left transition-colors',\n tile.selected ? 'border-primary shadow-sm' : 'hover:border-primary/60',\n )}\n onClick={tile.onClick}\n >\n <div className=\"relative aspect-square overflow-hidden rounded-t bg-muted\">\n {tile.thumbnail ? (\n <img src={tile.thumbnail} alt={tile.label} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-6 w-6\" />\n </div>\n )}\n {tile.selected ? (\n <div className=\"absolute right-2 top-2 rounded-full bg-primary/90 px-2 py-0.5 text-xs font-semibold text-primary-foreground\">\n {t('sales.channels.offers.form.mediaSelected', 'Active')}\n </div>\n ) : null}\n </div>\n <div className=\"p-2\">\n <div className=\"line-clamp-2 text-xs font-medium\">{tile.label}</div>\n </div>\n </button>\n ))}\n </div>\n </div>\n )\n}\n\nfunction OfferFormWatchers({\n values,\n setValue,\n productCache,\n attachmentCache,\n setMediaOptions,\n setProductSummary,\n setVariantPreviews,\n variantCache,\n variantMediaCache,\n channelId,\n manualMediaSelections,\n setCurrentProductId,\n errors,\n}: CrudFormGroupComponentProps & {\n productCache: React.MutableRefObject<Map<string, ProductSummaryCacheEntry>>\n attachmentCache: React.MutableRefObject<Map<string, MediaOption[]>>\n setMediaOptions: React.Dispatch<React.SetStateAction<MediaOption[]>>\n setProductSummary: React.Dispatch<React.SetStateAction<ProductSummary>>\n setVariantPreviews: React.Dispatch<React.SetStateAction<ProductVariantPreview[]>>\n variantCache: React.MutableRefObject<Map<string, ProductVariantPreview[]>>\n variantMediaCache: React.MutableRefObject<Map<string, VariantThumbnailInfo>>\n channelId: string | null\n manualMediaSelections: React.MutableRefObject<Set<string>>\n setCurrentProductId: React.Dispatch<React.SetStateAction<string | null>>\n}) {\n const previousProductIdRef = React.useRef<string | null>(null)\n const initializedProductRef = React.useRef(false)\n React.useEffect(() => {\n const productId = typeof values.productId === 'string' ? values.productId : null\n setCurrentProductId(productId)\n if (!productId) {\n setMediaOptions([])\n setProductSummary(null)\n setVariantPreviews([])\n previousProductIdRef.current = null\n return\n }\n const resolvedProductId = productId as string\n const resolvedChannelId = channelId ?? null\n if (!initializedProductRef.current) {\n previousProductIdRef.current = resolvedProductId\n initializedProductRef.current = true\n } else if (previousProductIdRef.current !== resolvedProductId) {\n previousProductIdRef.current = resolvedProductId\n setValue('defaultMediaId', undefined)\n }\n let cancelled = false\n async function load() {\n try {\n const summary = await resolveProductSummaryWithCache({\n productId: resolvedProductId,\n channelId: resolvedChannelId,\n productCache,\n })\n if (!cancelled) {\n setProductSummary(summary ?? null)\n if (summary) {\n const hasTitle = typeof values.title === 'string' && values.title.trim().length > 0\n if (!hasTitle && summary.title) {\n setValue('title', summary.title)\n }\n const hasDescription =\n typeof values.description === 'string' && values.description.trim().length > 0\n if (!hasDescription && summary.description) {\n setValue('description', summary.description)\n }\n if (\n !values.defaultMediaId &&\n summary.defaultMediaId &&\n !manualMediaSelections.current.has(resolvedProductId)\n ) {\n setValue('defaultMediaId', summary.defaultMediaId)\n }\n }\n }\n const attachments = await resolveProductMediaOptionsWithCache({\n productId: resolvedProductId,\n attachmentCache,\n })\n if (!cancelled) {\n const variants = await resolveVariantPreviewsWithCache({\n productId: resolvedProductId,\n variantCache,\n variantMediaCache,\n })\n const mergedMedia = buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n })\n attachmentCache.current.set(resolvedProductId, mergedMedia)\n setMediaOptions(mergedMedia)\n setVariantPreviews(variants)\n }\n } catch (err) {\n console.error('sales.channels.offer.watchers', err)\n }\n }\n void load()\n return () => { cancelled = true }\n }, [\n attachmentCache,\n channelId,\n manualMediaSelections,\n productCache,\n setMediaOptions,\n setProductSummary,\n setValue,\n setVariantPreviews,\n values.defaultMediaId,\n values.description,\n values.productId,\n values.title,\n variantCache,\n variantMediaCache,\n setCurrentProductId,\n ])\n return null\n}\n\nasync function resolveProductSummaryWithCache({\n productId,\n channelId,\n productCache,\n}: {\n productId: string\n channelId: string | null\n productCache: React.MutableRefObject<Map<string, ProductSummaryCacheEntry>>\n}): Promise<ProductSummaryCacheEntry | null> {\n if (!productId) return null\n const cacheKey = channelId ? `${productId}:${channelId}` : productId\n let summary: ProductSummaryCacheEntry | null | undefined = productCache.current.get(cacheKey)\n if (summary) return summary\n const params = new URLSearchParams({ id: productId, pageSize: '1' })\n if (channelId) params.set('channelId', channelId)\n const payload = await readApiResultOrThrow<OfferResponse>(\n `/api/catalog/products?${params.toString()}`,\n undefined,\n { fallback: { items: [] } },\n )\n const product = Array.isArray(payload.items) ? payload.items[0] : null\n summary = product ? mapProductSummary(product) : null\n if (summary) {\n productCache.current.set(cacheKey, summary)\n }\n return summary ?? null\n}\n\nasync function resolveProductMediaOptionsWithCache({\n productId,\n attachmentCache,\n}: {\n productId: string\n attachmentCache: React.MutableRefObject<Map<string, MediaOption[]>>\n}): Promise<MediaOption[]> {\n if (!productId) return []\n const cached = attachmentCache.current.get(productId) ?? []\n if (cached.length) {\n const deduped = dedupeMediaOptions(cached)\n attachmentCache.current.set(productId, deduped)\n return deduped\n }\n const attachments = dedupeMediaOptions(await loadProductMedia(productId))\n attachmentCache.current.set(productId, attachments)\n return attachments\n}\n\nasync function resolveVariantPreviewsWithCache({\n productId,\n variantCache,\n variantMediaCache,\n}: {\n productId: string\n variantCache: React.MutableRefObject<Map<string, ProductVariantPreview[]>>\n variantMediaCache: React.MutableRefObject<Map<string, VariantThumbnailInfo>>\n}): Promise<ProductVariantPreview[]> {\n if (!productId) return []\n const cached = variantCache.current.get(productId)\n if (cached) return cached\n const variantPayload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/catalog/variants?productId=${encodeURIComponent(productId)}&pageSize=${MAX_LIST_PAGE_SIZE}`,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(variantPayload.items) ? variantPayload.items : []\n const variants = await Promise.all(\n items.map(async (item) => {\n const preview = mapVariantPreview(item)\n const media = await resolveVariantThumbnail(preview.id, variantMediaCache)\n return {\n ...preview,\n thumbnailId: media?.attachmentId ?? preview.thumbnailId,\n thumbnailUrl: media?.thumbnailUrl ?? preview.thumbnailUrl,\n thumbnailFileName: media?.fileName ?? preview.thumbnailFileName,\n }\n }),\n )\n variantCache.current.set(productId, variants)\n return variants\n}\n\nfunction mapProductSummary(item: Record<string, unknown>): ProductSummaryCacheEntry {\n const pricingSource = item.pricing && typeof item.pricing === 'object' ? item.pricing as Record<string, unknown> : null\n return {\n title: typeof item.title === 'string' ? item.title : '',\n description: typeof item.description === 'string' ? item.description : null,\n defaultMediaId: typeof item.defaultMediaId === 'string'\n ? item.defaultMediaId\n : typeof item.default_media_id === 'string'\n ? item.default_media_id\n : null,\n defaultMediaUrl: typeof item.defaultMediaUrl === 'string'\n ? item.defaultMediaUrl\n : typeof item.default_media_url === 'string'\n ? item.default_media_url\n : null,\n sku: typeof item.sku === 'string' ? item.sku : null,\n pricing: normalizePricing(pricingSource),\n }\n}\n\nfunction normalizePricing(source: Record<string, unknown> | null): PricingSummary | null {\n if (!source) return null\n const currencyCode = typeof source.currencyCode === 'string'\n ? source.currencyCode\n : typeof source.currency_code === 'string'\n ? source.currency_code\n : null\n const unitPriceNet = typeof source.unitPriceNet === 'string'\n ? source.unitPriceNet\n : typeof source.unit_price_net === 'string'\n ? source.unit_price_net\n : null\n const unitPriceGross = typeof source.unitPriceGross === 'string'\n ? source.unitPriceGross\n : typeof source.unit_price_gross === 'string'\n ? source.unit_price_gross\n : null\n const displayMode = source.displayMode === 'including-tax' || source.display_mode === 'including-tax'\n ? 'including-tax'\n : source.displayMode === 'excluding-tax' || source.display_mode === 'excluding-tax'\n ? 'excluding-tax'\n : null\n return { currencyCode, unitPriceNet, unitPriceGross, displayMode }\n}\n\nasync function loadProductMedia(productId: string): Promise<MediaOption[]> {\n if (!productId) return []\n const normalize = (items: Array<{ id?: string; fileName?: string; thumbnailUrl?: string | null }>) => (\n items\n .filter((item): item is { id: string; fileName: string; thumbnailUrl?: string | null } => (\n typeof item.id === 'string' && typeof item.fileName === 'string'\n ))\n .map((item) => ({\n id: item.id,\n label: item.fileName,\n fileName: item.fileName,\n thumbnailUrl: typeof item.thumbnailUrl === 'string'\n ? item.thumbnailUrl\n : buildAttachmentImageUrl(item.id, {\n width: 360,\n height: 360,\n slug: slugifyAttachmentFileName(item.fileName),\n }),\n }))\n )\n try {\n const primary = await apiCall<AttachmentsResponse>(\n `/api/catalog/product-media?productId=${encodeURIComponent(productId)}`,\n undefined,\n { fallback: { items: [] } },\n )\n if (primary.ok && primary.result?.items) {\n return normalize(primary.result.items)\n }\n } catch (err) {\n console.error('catalog.product-media.lookup', err)\n }\n try {\n const fallback = await apiCall<AttachmentsResponse>(\n `/api/attachments?entityId=${encodeURIComponent(E.catalog.catalog_product)}&recordId=${encodeURIComponent(productId)}`,\n undefined,\n { fallback: { items: [] } },\n )\n if (fallback.ok && fallback.result?.items) {\n return normalize(fallback.result.items)\n }\n } catch (err) {\n console.error('attachments.lookup', err)\n }\n return []\n}\n\nfunction buildVariantMediaOptions(variants: ProductVariantPreview[]): MediaOption[] {\n return variants\n .map((variant): MediaOption | null => {\n if (!variant.thumbnailId || !variant.thumbnailUrl) return null\n const label = variant.name || variant.sku || 'Variant'\n const fileName = variant.thumbnailFileName ?? `${variant.thumbnailId}.jpg`\n return {\n id: variant.thumbnailId,\n label,\n fileName,\n thumbnailUrl: variant.thumbnailUrl,\n }\n })\n .filter((entry): entry is MediaOption => Boolean(entry))\n}\n\nfunction buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n}: {\n attachments?: MediaOption[] | null\n variants?: ProductVariantPreview[] | null\n summary?: ProductSummary | null\n}): MediaOption[] {\n const merged = dedupeMediaOptions([\n ...(attachments ?? []),\n ...buildVariantMediaOptions(variants ?? []),\n ])\n const defaultId = summary?.defaultMediaId ?? null\n const defaultUrl = summary?.defaultMediaUrl ?? null\n if (defaultId && defaultUrl && !merged.some((entry) => entry.id === defaultId)) {\n const fileName = inferFileNameFromUrl(defaultUrl, defaultId)\n merged.unshift({\n id: defaultId,\n label: fileName,\n fileName,\n thumbnailUrl: defaultUrl,\n })\n }\n return merged\n}\n\nfunction dedupeMediaOptions(entries: MediaOption[] | null | undefined): MediaOption[] {\n if (!Array.isArray(entries)) return []\n const seen = new Set<string>()\n const result: MediaOption[] = []\n for (const entry of entries) {\n if (!entry || typeof entry.id !== 'string') continue\n if (seen.has(entry.id)) continue\n seen.add(entry.id)\n result.push(entry)\n }\n return result\n}\n\nfunction inferFileNameFromUrl(url: string | null, fallbackId: string): string {\n if (typeof url === 'string' && url.length) {\n const cleaned = url.split(/[?#]/)[0]\n const last = cleaned.split('/').pop()\n if (last && last.trim().length) return last\n }\n return `${fallbackId}.jpg`\n}\n\nfunction mapVariantPreview(item: Record<string, unknown>): ProductVariantPreview {\n return {\n id: typeof item.id === 'string' ? item.id : '',\n name: typeof item.name === 'string'\n ? item.name\n : typeof item.sku === 'string'\n ? item.sku\n : 'Variant',\n sku: typeof item.sku === 'string' ? item.sku : null,\n thumbnailUrl: typeof item.defaultMediaUrl === 'string'\n ? item.defaultMediaUrl\n : typeof item.default_media_url === 'string'\n ? item.default_media_url\n : null,\n thumbnailId: null,\n thumbnailFileName: null,\n }\n}\n\nasync function resolveVariantThumbnail(\n variantId: string,\n cache: React.MutableRefObject<Map<string, VariantThumbnailInfo>>,\n): Promise<VariantThumbnailInfo | null> {\n if (!variantId) return null\n if (cache.current.has(variantId)) {\n return cache.current.get(variantId) ?? null\n }\n try {\n const payload = await apiCall<AttachmentsResponse>(\n `/api/attachments?entityId=${encodeURIComponent(E.catalog.catalog_product_variant)}&recordId=${encodeURIComponent(variantId)}`,\n )\n const items = payload.ok && payload.result?.items ? payload.result.items : []\n const first = items.find((item) => typeof item.id === 'string')\n if (first?.id) {\n const thumbnailUrl = typeof first.thumbnailUrl === 'string'\n ? first.thumbnailUrl\n : buildAttachmentImageUrl(first.id, {\n width: 360,\n height: 360,\n slug: slugifyAttachmentFileName(first.fileName ?? first.id),\n })\n const info: VariantThumbnailInfo = {\n attachmentId: first.id,\n thumbnailUrl: thumbnailUrl ?? null,\n fileName: typeof first.fileName === 'string' ? first.fileName : null,\n }\n cache.current.set(variantId, info)\n return info\n }\n } catch (err) {\n console.error('sales.channels.offer.variantMedia', err)\n }\n const empty: VariantThumbnailInfo = { attachmentId: null, thumbnailUrl: null, fileName: null }\n cache.current.set(variantId, empty)\n return empty\n}\n\nfunction mapProductSearchResult(\n item: Record<string, unknown>,\n channelId?: string | null,\n currentOfferId?: string | null,\n): ProductSearchResult {\n const offers = Array.isArray((item as { offers?: unknown }).offers)\n ? (item as { offers: Array<Record<string, unknown>> }).offers\n : []\n const channelOffer = offers.find((entry) => {\n if (!entry || typeof entry !== 'object') return false\n const offerChannelId = typeof entry.channelId === 'string'\n ? entry.channelId\n : typeof (entry as Record<string, unknown>).channel_id === 'string'\n ? (entry as Record<string, unknown>).channel_id\n : null\n return channelId ? offerChannelId === channelId : false\n }) ?? null\n const existingOfferId = channelOffer && typeof channelOffer.id === 'string' ? channelOffer.id : null\n return {\n id: typeof item.id === 'string' ? item.id : '',\n title: typeof item.title === 'string' ? item.title : '',\n sku: typeof item.sku === 'string' ? item.sku : null,\n defaultMediaUrl: typeof item.defaultMediaUrl === 'string'\n ? item.defaultMediaUrl\n : typeof item.default_media_url === 'string'\n ? item.default_media_url\n : null,\n pricing: item.pricing && typeof item.pricing === 'object'\n ? normalizePricing(item.pricing as Record<string, unknown>)\n : null,\n existingOfferId,\n existingOfferTitle:\n channelOffer && typeof channelOffer.title === 'string' ? channelOffer.title : null,\n isCurrentOfferProduct: Boolean(existingOfferId && currentOfferId && existingOfferId === currentOfferId),\n }\n}\n\nfunction formatPriceDisplay(pricing: PricingSummary | null): string {\n if (!pricing) return '\u2014'\n const amount = pricing.displayMode === 'including-tax'\n ? pricing.unitPriceGross ?? pricing.unitPriceNet\n : pricing.unitPriceNet ?? pricing.unitPriceGross\n if (!amount) return pricing.currencyCode ?? '\u2014'\n return `${pricing.currencyCode ?? ''} ${amount}`\n}\n\nfunction PriceOverridesEditor({\n values,\n onChange,\n priceKinds,\n basePrice,\n onRemoveDraft,\n}: {\n values: PriceOverrideDraft[]\n onChange: (next: PriceOverrideDraft[]) => void\n priceKinds: PriceKindSummary[]\n basePrice: PricingSummary | null\n onRemoveDraft?: (draft: PriceOverrideDraft) => Promise<boolean> | boolean\n}) {\n const t = useT()\n const baseAmount = React.useMemo(() => {\n if (!basePrice) return ''\n const net = basePrice.unitPriceNet ?? null\n const gross = basePrice.unitPriceGross ?? null\n if (basePrice.displayMode === 'including-tax') {\n return gross ?? net ?? ''\n }\n if (basePrice.displayMode === 'excluding-tax') {\n return net ?? gross ?? ''\n }\n return net ?? gross ?? ''\n }, [basePrice])\n const baseDefaults = React.useMemo(() => ({\n amount: baseAmount,\n currencyCode: basePrice?.currencyCode ?? null,\n displayMode: basePrice?.displayMode ?? null,\n }), [baseAmount, basePrice?.currencyCode, basePrice?.displayMode])\n const usedKindIdSet = React.useMemo(() => {\n const next = new Set<string>()\n values.forEach((row) => {\n if (typeof row.priceKindId === 'string' && row.priceKindId.length) {\n next.add(row.priceKindId)\n }\n })\n return next\n }, [values])\n const availableKindCount = priceKinds.reduce(\n (count, kind) => (usedKindIdSet.has(kind.id) ? count : count + 1),\n 0,\n )\n const canAddRow = availableKindCount > 0\n const addRow = React.useCallback(() => {\n const usedIds = new Set<string>()\n values.forEach((row) => {\n if (typeof row.priceKindId === 'string' && row.priceKindId.length) {\n usedIds.add(row.priceKindId)\n }\n })\n const nextKind = priceKinds.find((kind) => !usedIds.has(kind.id))\n if (!nextKind && priceKinds.length) {\n return\n }\n onChange([\n ...values,\n {\n tempId: crypto.randomUUID?.() ?? Math.random().toString(36).slice(2),\n amount: baseDefaults.amount,\n currencyCode: nextKind?.currencyCode ?? baseDefaults.currencyCode,\n displayMode: nextKind?.displayMode ?? baseDefaults.displayMode,\n priceKindId: nextKind?.id ?? null,\n priceKindCode: nextKind?.code ?? nextKind?.title ?? null,\n },\n ])\n }, [baseDefaults, onChange, priceKinds, values])\n\n const updateRow = React.useCallback((tempId: string, patch: Partial<PriceOverrideDraft>) => {\n onChange(values.map((row) => (row.tempId === tempId ? { ...row, ...patch } : row)))\n }, [onChange, values])\n\n const removeRow = React.useCallback(async (row: PriceOverrideDraft) => {\n const allowRemoval = await onRemoveDraft?.(row)\n if (allowRemoval === false) return\n onChange(values.filter((entry) => entry.tempId !== row.tempId))\n }, [onChange, onRemoveDraft, values])\n\n return (\n <div className=\"space-y-4\">\n <div className=\"rounded border bg-muted/50 px-3 py-2\">\n <div className=\"text-xs uppercase text-muted-foreground\">\n {t('sales.channels.offers.pricing.basePriceLabel', 'Original product price')}\n </div>\n <div className=\"text-base font-semibold\">\n {basePrice ? formatPriceDisplay(basePrice) : t('sales.channels.offers.pricing.basePriceMissing', 'No price found')}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.pricing.basePriceHelp', 'Shown to shoppers when no override is configured.')}\n </div>\n </div>\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-muted-foreground\">\n {t('sales.channels.offers.pricing.help', 'Provide overrides for price kinds when this offer is active.')}\n </p>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={addRow} disabled={!canAddRow}>\n {t('sales.channels.offers.pricing.add', 'Add price')}\n </Button>\n </div>\n {!canAddRow ? (\n <p className=\"text-xs text-muted-foreground\">\n {priceKinds.length\n ? t('sales.channels.offers.pricing.allKindsUsed', 'Each price kind already has an override.')\n : t('sales.channels.offers.pricing.noKindsAvailable', 'Define a price kind before adding overrides.')}\n </p>\n ) : null}\n </div>\n <div className=\"flex items-center justify-between\">\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.pricing.overrideHint', 'Overrides take precedence over the original product price.')}\n </p>\n </div>\n {values.length ? (\n <div className=\"space-y-2\">\n {values.map((row) => (\n <div key={row.tempId} className=\"grid gap-2 rounded border p-3 md:grid-cols-3\">\n <Select\n value={row.priceKindId || undefined}\n onValueChange={(value) => {\n const next = priceKinds.find((kind) => kind.id === value)\n updateRow(row.tempId, {\n priceKindId: next?.id ?? null,\n priceKindCode: next?.code ?? next?.title ?? null,\n currencyCode: next?.currencyCode ?? null,\n displayMode: next?.displayMode ?? null,\n })\n }}\n >\n <SelectTrigger>\n <SelectValue placeholder={t('sales.channels.offers.pricing.selectKind', 'Select price kind')} />\n </SelectTrigger>\n <SelectContent>\n {priceKinds.map((kind) => (\n <SelectItem\n key={kind.id}\n value={kind.id}\n disabled={usedKindIdSet.has(kind.id) && row.priceKindId !== kind.id}\n >\n {kind.title ?? kind.code ?? kind.id}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <div className=\"relative\">\n {(row.currencyCode ?? basePrice?.currencyCode) ? (\n <span className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-xs font-semibold text-muted-foreground\">\n {row.currencyCode ?? basePrice?.currencyCode}\n </span>\n ) : null}\n <Input\n inputClassName={cn(row.currencyCode || basePrice?.currencyCode ? 'pl-13' : '')}\n type=\"number\"\n placeholder={t('sales.channels.offers.pricing.amount', 'Amount')}\n value={row.amount ?? ''}\n onChange={(event) => updateRow(row.tempId, { amount: event.target.value })}\n />\n </div>\n <div className=\"flex flex-col justify-between gap-2 text-xs text-muted-foreground sm:flex-row sm:items-center\">\n <span>\n {row.displayMode === 'including-tax'\n ? t('sales.channels.offers.pricing.includingTax', 'Including tax')\n : t('sales.channels.offers.pricing.excludingTax', 'Excluding tax')}\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"gap-1 px-2 font-normal text-destructive hover:text-destructive focus-visible:text-destructive\"\n onClick={() => { void removeRow(row) }}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n {t('sales.channels.offers.pricing.remove', 'Remove')}\n </Button>\n </div>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.pricing.empty', 'No overrides yet.')}\n {basePrice ? (\n <>\n {' '}\n {t(\n 'sales.channels.offers.pricing.emptyFallback',\n 'Using {price} from the product until you add overrides.',\n { price: formatPriceDisplay(basePrice) },\n )}\n </>\n ) : null}\n </p>\n )}\n </div>\n )\n}\n\nfunction ProductOverviewCard({ summary, variants }: { summary: ProductSummary; variants: ProductVariantPreview[] }) {\n const t = useT()\n if (!summary) {\n return (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSummaryPlaceholder', 'Select a product to preview its media, price, and variants.')}\n </p>\n )\n }\n return (\n <div className=\"space-y-4\">\n <div className=\"flex gap-3\">\n <div className=\"h-16 w-16 overflow-hidden rounded border bg-muted\">\n {summary.defaultMediaUrl ? (\n <img src={summary.defaultMediaUrl} alt={summary.title} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-5 w-5\" />\n </div>\n )}\n </div>\n <div className=\"flex-1\">\n <div className=\"text-sm font-semibold\">{summary.title || t('sales.channels.offers.form.productUntitled', 'Untitled product')}</div>\n {summary.sku ? (\n <div className=\"text-xs text-muted-foreground\">SKU \u00B7 {summary.sku}</div>\n ) : null}\n <div className=\"text-sm\">\n <span className=\"text-muted-foreground\">{t('sales.channels.offers.form.productPriceLabel', 'Base price')}:</span>{' '}\n <span className=\"font-semibold\">{formatPriceDisplay(summary.pricing)}</span>\n </div>\n </div>\n </div>\n {summary.description ? (\n <p className=\"text-sm text-muted-foreground\">{summary.description}</p>\n ) : null}\n <ProductVariantsList variants={variants} />\n </div>\n )\n}\n\nfunction ProductVariantsList({ variants }: { variants: ProductVariantPreview[] }) {\n const t = useT()\n if (!variants.length) {\n return (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.variantsEmpty', 'No variants available for this product.')}\n </p>\n )\n }\n return (\n <div className=\"space-y-2\">\n <div className=\"text-sm font-medium\">{t('sales.channels.offers.form.variantsTitle', 'Variants')}</div>\n <div className=\"space-y-2 max-h-64 overflow-y-auto pr-1\">\n {variants.map((variant) => (\n <div key={variant.id} className=\"flex gap-3 rounded border bg-card p-2\">\n <div className=\"h-10 w-10 overflow-hidden rounded border bg-muted\">\n {variant.thumbnailUrl ? (\n <img src={variant.thumbnailUrl} alt={variant.name} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-4 w-4\" />\n </div>\n )}\n </div>\n <div className=\"min-w-0\">\n <div className=\"text-xs font-medium\">{variant.name}</div>\n {variant.sku ? (\n <div className=\"text-overline text-muted-foreground\">SKU \u00B7 {variant.sku}</div>\n ) : null}\n </div>\n </div>\n ))}\n </div>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|