@open-mercato/core 0.6.6-develop.6460.1.f94c74174c → 0.6.6-develop.6471.1.9ab5bdd79a
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 +1 -1
- package/dist/bootstrap.js +13 -11
- package/dist/bootstrap.js.map +2 -2
- package/dist/helpers/integration/auth.js +148 -82
- package/dist/helpers/integration/auth.js.map +2 -2
- package/dist/helpers/integration/queue-runner.js +4 -2
- package/dist/helpers/integration/queue-runner.js.map +2 -2
- package/dist/modules/api_keys/services/apiKeyService.js +5 -3
- package/dist/modules/api_keys/services/apiKeyService.js.map +2 -2
- package/dist/modules/attachments/api/image/[id]/[[...slug]]/route.js +4 -2
- package/dist/modules/attachments/api/image/[id]/[[...slug]]/route.js.map +2 -2
- package/dist/modules/attachments/api/library/[id]/route.js +3 -1
- package/dist/modules/attachments/api/library/[id]/route.js.map +2 -2
- package/dist/modules/attachments/api/route.js +8 -6
- package/dist/modules/attachments/api/route.js.map +2 -2
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js +5 -3
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js.map +2 -2
- package/dist/modules/attachments/lib/assignmentDetails.js +3 -1
- package/dist/modules/attachments/lib/assignmentDetails.js.map +2 -2
- package/dist/modules/attachments/lib/drivers/driverFactory.js +3 -1
- package/dist/modules/attachments/lib/drivers/driverFactory.js.map +2 -2
- package/dist/modules/attachments/lib/ocrQueue.js +10 -11
- package/dist/modules/attachments/lib/ocrQueue.js.map +2 -2
- package/dist/modules/attachments/lib/ocrService.js +6 -4
- package/dist/modules/attachments/lib/ocrService.js.map +2 -2
- package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js +3 -1
- 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 -1
- package/dist/modules/audit_logs/api/audit-logs/actions/undo/route.js.map +2 -2
- package/dist/modules/audit_logs/backend/audit-logs/page.js +3 -1
- package/dist/modules/audit_logs/backend/audit-logs/page.js.map +2 -2
- package/dist/modules/audit_logs/components/AuditLogsActions.js +4 -2
- package/dist/modules/audit_logs/components/AuditLogsActions.js.map +2 -2
- package/dist/modules/audit_logs/services/accessLogService.js +4 -2
- package/dist/modules/audit_logs/services/accessLogService.js.map +2 -2
- package/dist/modules/audit_logs/services/actionLogService.js +7 -5
- package/dist/modules/audit_logs/services/actionLogService.js.map +3 -3
- package/dist/modules/auth/api/profile/route.js +4 -2
- package/dist/modules/auth/api/profile/route.js.map +2 -2
- package/dist/modules/auth/api/reset/confirm.js +3 -1
- package/dist/modules/auth/api/reset/confirm.js.map +2 -2
- package/dist/modules/auth/api/reset.js +4 -2
- package/dist/modules/auth/api/reset.js.map +2 -2
- package/dist/modules/auth/api/roles/route.js +3 -1
- package/dist/modules/auth/api/roles/route.js.map +2 -2
- package/dist/modules/auth/api/sidebar/variants/route.js +3 -1
- package/dist/modules/auth/api/sidebar/variants/route.js.map +2 -2
- package/dist/modules/auth/api/users/resend-invite/route.js +4 -2
- package/dist/modules/auth/api/users/resend-invite/route.js.map +2 -2
- package/dist/modules/auth/api/users/route.js +3 -1
- package/dist/modules/auth/api/users/route.js.map +2 -2
- package/dist/modules/auth/backend/auth/profile/page.js +3 -1
- package/dist/modules/auth/backend/auth/profile/page.js.map +2 -2
- package/dist/modules/auth/backend/profile/change-password/page.js +3 -1
- package/dist/modules/auth/backend/profile/change-password/page.js.map +2 -2
- package/dist/modules/auth/backend/users/[id]/edit/page.js +5 -3
- package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/backend/users/create/page.js +4 -2
- package/dist/modules/auth/backend/users/create/page.js.map +2 -2
- package/dist/modules/auth/cli.js +10 -0
- package/dist/modules/auth/cli.js.map +2 -2
- package/dist/modules/auth/commands/users.js +4 -2
- package/dist/modules/auth/commands/users.js.map +2 -2
- package/dist/modules/auth/lib/consentIntegrity.js +3 -3
- package/dist/modules/auth/lib/consentIntegrity.js.map +2 -2
- package/dist/modules/auth/lib/setup-app.js +9 -10
- package/dist/modules/auth/lib/setup-app.js.map +2 -2
- package/dist/modules/auth/lib/tenantAccess.js +3 -1
- package/dist/modules/auth/lib/tenantAccess.js.map +2 -2
- package/dist/modules/auth/lib/tokenHash.js +3 -3
- package/dist/modules/auth/lib/tokenHash.js.map +2 -2
- package/dist/modules/business_rules/api/rules/route.js +4 -2
- package/dist/modules/business_rules/api/rules/route.js.map +2 -2
- package/dist/modules/business_rules/lib/expression-evaluator.js +7 -5
- package/dist/modules/business_rules/lib/expression-evaluator.js.map +2 -2
- package/dist/modules/business_rules/lib/rule-engine.js +5 -3
- package/dist/modules/business_rules/lib/rule-engine.js.map +2 -2
- package/dist/modules/business_rules/lib/rule-evaluator.js +11 -12
- package/dist/modules/business_rules/lib/rule-evaluator.js.map +2 -2
- package/dist/modules/business_rules/subscribers/crud-rule-trigger.js +3 -1
- package/dist/modules/business_rules/subscribers/crud-rule-trigger.js.map +2 -2
- package/dist/modules/business_rules/subscribers/rule-execution-failed-notification.js +3 -1
- package/dist/modules/business_rules/subscribers/rule-execution-failed-notification.js.map +2 -2
- package/dist/modules/catalog/ai-agents-context.js +4 -5
- package/dist/modules/catalog/ai-agents-context.js.map +2 -2
- package/dist/modules/catalog/ai-tools/_shared.js +3 -1
- package/dist/modules/catalog/ai-tools/_shared.js.map +2 -2
- package/dist/modules/catalog/ai-tools/authoring-pack.js +3 -1
- package/dist/modules/catalog/ai-tools/authoring-pack.js.map +2 -2
- package/dist/modules/catalog/ai-tools/merchandising-pack.js +3 -1
- package/dist/modules/catalog/ai-tools/merchandising-pack.js.map +2 -2
- package/dist/modules/catalog/api/dictionaries/[key]/route.js +3 -1
- package/dist/modules/catalog/api/dictionaries/[key]/route.js.map +2 -2
- package/dist/modules/catalog/api/prices/route.js +3 -1
- package/dist/modules/catalog/api/prices/route.js.map +2 -2
- package/dist/modules/catalog/api/products/route.js +5 -3
- package/dist/modules/catalog/api/products/route.js.map +2 -2
- package/dist/modules/catalog/api/settings/route.js +4 -2
- package/dist/modules/catalog/api/settings/route.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js +14 -12
- 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 +8 -6
- 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 +5 -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 +5 -6
- package/dist/modules/catalog/backend/catalog/products/create/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/optionSchemaClient.js +3 -1
- package/dist/modules/catalog/backend/catalog/products/optionSchemaClient.js.map +2 -2
- package/dist/modules/catalog/components/PriceKindSettings.js +5 -3
- package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
- package/dist/modules/catalog/components/UnitPriceDisplaySettings.js +4 -2
- package/dist/modules/catalog/components/UnitPriceDisplaySettings.js.map +2 -2
- package/dist/modules/catalog/inbox-actions.js +4 -2
- package/dist/modules/catalog/inbox-actions.js.map +2 -2
- package/dist/modules/catalog/seed/examples.js +4 -5
- package/dist/modules/catalog/seed/examples.js.map +2 -2
- package/dist/modules/catalog/subscribers/low-stock-notification.js +3 -1
- package/dist/modules/catalog/subscribers/low-stock-notification.js.map +2 -2
- package/dist/modules/catalog/widgets/injection/product-seo/state.js +3 -1
- package/dist/modules/catalog/widgets/injection/product-seo/state.js.map +2 -2
- package/dist/modules/communication_channels/api/get/oauth/[provider]/callback/route.js +12 -11
- package/dist/modules/communication_channels/api/get/oauth/[provider]/callback/route.js.map +2 -2
- package/dist/modules/communication_channels/api/post/channels/[id]/import-history/route.js +3 -1
- package/dist/modules/communication_channels/api/post/channels/[id]/import-history/route.js.map +2 -2
- package/dist/modules/communication_channels/api/post/channels/[id]/push/register/route.js +3 -1
- package/dist/modules/communication_channels/api/post/channels/[id]/push/register/route.js.map +2 -2
- package/dist/modules/communication_channels/api/post/webhook/[provider]/route.js +5 -3
- package/dist/modules/communication_channels/api/post/webhook/[provider]/route.js.map +2 -2
- package/dist/modules/communication_channels/api/post/webhooks/gmail/route.js +6 -6
- package/dist/modules/communication_channels/api/post/webhooks/gmail/route.js.map +2 -2
- package/dist/modules/communication_channels/commands/connect-credential-channel.js +4 -6
- package/dist/modules/communication_channels/commands/connect-credential-channel.js.map +2 -2
- package/dist/modules/communication_channels/commands/delete-channel.js +3 -3
- package/dist/modules/communication_channels/commands/delete-channel.js.map +2 -2
- package/dist/modules/communication_channels/commands/deliver-outbound-message.js +4 -5
- package/dist/modules/communication_channels/commands/deliver-outbound-message.js.map +2 -2
- package/dist/modules/communication_channels/commands/disconnect-channel.js +3 -3
- package/dist/modules/communication_channels/commands/disconnect-channel.js.map +2 -2
- package/dist/modules/communication_channels/commands/ingest-inbound-message.js +5 -12
- package/dist/modules/communication_channels/commands/ingest-inbound-message.js.map +2 -2
- package/dist/modules/communication_channels/commands/push-unregister.js +3 -3
- package/dist/modules/communication_channels/commands/push-unregister.js.map +2 -2
- package/dist/modules/communication_channels/commands/reassign-conversation.js +5 -3
- package/dist/modules/communication_channels/commands/reassign-conversation.js.map +2 -2
- package/dist/modules/communication_channels/lib/dead-letter.js +3 -3
- package/dist/modules/communication_channels/lib/dead-letter.js.map +2 -2
- package/dist/modules/communication_channels/lib/email-mime.js +4 -6
- package/dist/modules/communication_channels/lib/email-mime.js.map +2 -2
- package/dist/modules/communication_channels/lib/oauth-client-config.js +5 -3
- package/dist/modules/communication_channels/lib/oauth-client-config.js.map +2 -2
- package/dist/modules/communication_channels/lib/send-as-user.js +3 -1
- package/dist/modules/communication_channels/lib/send-as-user.js.map +2 -2
- package/dist/modules/communication_channels/lib/thread-token.js +4 -2
- package/dist/modules/communication_channels/lib/thread-token.js.map +2 -2
- package/dist/modules/communication_channels/setup.js +3 -4
- package/dist/modules/communication_channels/setup.js.map +2 -2
- package/dist/modules/communication_channels/workers/channel-import-history.js +4 -6
- package/dist/modules/communication_channels/workers/channel-import-history.js.map +2 -2
- package/dist/modules/communication_channels/workers/gmail-history-sync.js +8 -16
- package/dist/modules/communication_channels/workers/gmail-history-sync.js.map +2 -2
- package/dist/modules/communication_channels/workers/gmail-renew-watch.js +5 -7
- package/dist/modules/communication_channels/workers/gmail-renew-watch.js.map +2 -2
- package/dist/modules/communication_channels/workers/outbound-delivery.js +6 -12
- package/dist/modules/communication_channels/workers/outbound-delivery.js.map +2 -2
- package/dist/modules/communication_channels/workers/poll-channel.js +7 -15
- package/dist/modules/communication_channels/workers/poll-channel.js.map +2 -2
- package/dist/modules/communication_channels/workers/poll-tick.js +5 -6
- package/dist/modules/communication_channels/workers/poll-tick.js.map +2 -2
- package/dist/modules/communication_channels/workers/reaction-processor.js +5 -9
- package/dist/modules/communication_channels/workers/reaction-processor.js.map +2 -2
- package/dist/modules/configs/api/cache/route.js +4 -2
- package/dist/modules/configs/api/cache/route.js.map +2 -2
- package/dist/modules/configs/api/system-status/route.js +4 -2
- package/dist/modules/configs/api/system-status/route.js.map +2 -2
- package/dist/modules/configs/api/upgrade-actions/route.js +4 -2
- package/dist/modules/configs/api/upgrade-actions/route.js.map +2 -2
- package/dist/modules/configs/components/ModuleTelemetryPanel.js +3 -1
- package/dist/modules/configs/components/ModuleTelemetryPanel.js.map +2 -2
- package/dist/modules/configs/lib/touchGeneratedBarrels.js +2 -1
- package/dist/modules/configs/lib/touchGeneratedBarrels.js.map +2 -2
- package/dist/modules/configs/services/upgradeActionsService.js +6 -3
- package/dist/modules/configs/services/upgradeActionsService.js.map +2 -2
- package/dist/modules/currencies/components/CurrencyFetchingConfig.js +3 -1
- package/dist/modules/currencies/components/CurrencyFetchingConfig.js.map +2 -2
- package/dist/modules/currencies/lib/exchangeRateFormConfig.js +3 -1
- package/dist/modules/currencies/lib/exchangeRateFormConfig.js.map +2 -2
- package/dist/modules/currencies/services/providers/nbp.js +6 -4
- package/dist/modules/currencies/services/providers/nbp.js.map +2 -2
- package/dist/modules/currencies/services/providers/raiffeisen.js +7 -7
- package/dist/modules/currencies/services/providers/raiffeisen.js.map +2 -2
- package/dist/modules/customer_accounts/api/domain-resolve/all.js +6 -5
- package/dist/modules/customer_accounts/api/domain-resolve/all.js.map +2 -2
- package/dist/modules/customer_accounts/api/signup.js +4 -2
- package/dist/modules/customer_accounts/api/signup.js.map +2 -2
- package/dist/modules/customer_accounts/lib/customerAuthServer.js +3 -1
- package/dist/modules/customer_accounts/lib/customerAuthServer.js.map +2 -2
- package/dist/modules/customer_accounts/subscribers/autoLinkCrm.js +3 -1
- package/dist/modules/customer_accounts/subscribers/autoLinkCrm.js.map +2 -2
- package/dist/modules/customer_accounts/subscribers/autoLinkCrmReverse.js +3 -1
- package/dist/modules/customer_accounts/subscribers/autoLinkCrmReverse.js.map +2 -2
- package/dist/modules/customer_accounts/subscribers/unlinkOnCompanyDelete.js +3 -1
- package/dist/modules/customer_accounts/subscribers/unlinkOnCompanyDelete.js.map +2 -2
- package/dist/modules/customer_accounts/subscribers/unlinkOnPersonDelete.js +3 -1
- package/dist/modules/customer_accounts/subscribers/unlinkOnPersonDelete.js.map +2 -2
- package/dist/modules/customers/ai-agents-context.js +4 -5
- package/dist/modules/customers/ai-agents-context.js.map +2 -2
- package/dist/modules/customers/api/activities/route.js +6 -4
- package/dist/modules/customers/api/activities/route.js.map +2 -2
- package/dist/modules/customers/api/comments/route.js +3 -1
- package/dist/modules/customers/api/comments/route.js.map +2 -2
- package/dist/modules/customers/api/companies/[id]/people/route.js +3 -1
- package/dist/modules/customers/api/companies/[id]/people/route.js.map +2 -2
- package/dist/modules/customers/api/companies/[id]/route.js +5 -3
- package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/companies/route.js +5 -3
- package/dist/modules/customers/api/companies/route.js.map +2 -2
- package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js +3 -1
- package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js.map +2 -2
- package/dist/modules/customers/api/dashboard/widgets/new-customers/route.js +3 -1
- package/dist/modules/customers/api/dashboard/widgets/new-customers/route.js.map +2 -2
- package/dist/modules/customers/api/dashboard/widgets/new-deals/route.js +3 -1
- package/dist/modules/customers/api/dashboard/widgets/new-deals/route.js.map +2 -2
- package/dist/modules/customers/api/dashboard/widgets/next-interactions/route.js +3 -1
- package/dist/modules/customers/api/dashboard/widgets/next-interactions/route.js.map +2 -2
- package/dist/modules/customers/api/deals/[id]/companies/route.js +3 -1
- package/dist/modules/customers/api/deals/[id]/companies/route.js.map +2 -2
- package/dist/modules/customers/api/deals/[id]/people/route.js +3 -1
- package/dist/modules/customers/api/deals/[id]/people/route.js.map +2 -2
- package/dist/modules/customers/api/deals/aggregate/route.js +3 -1
- package/dist/modules/customers/api/deals/aggregate/route.js.map +2 -2
- package/dist/modules/customers/api/deals/bulk-update-owner/route.js +7 -5
- package/dist/modules/customers/api/deals/bulk-update-owner/route.js.map +2 -2
- package/dist/modules/customers/api/deals/bulk-update-stage/route.js +7 -5
- package/dist/modules/customers/api/deals/bulk-update-stage/route.js.map +2 -2
- package/dist/modules/customers/api/deals/route.js +3 -1
- package/dist/modules/customers/api/deals/route.js.map +2 -2
- package/dist/modules/customers/api/deals/summary/route.js +3 -1
- package/dist/modules/customers/api/deals/summary/route.js.map +2 -2
- package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js +4 -2
- package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/dictionaries/[kind]/route.js +5 -3
- package/dist/modules/customers/api/dictionaries/[kind]/route.js.map +2 -2
- package/dist/modules/customers/api/dictionaries/cache.js +3 -1
- package/dist/modules/customers/api/dictionaries/cache.js.map +2 -2
- package/dist/modules/customers/api/dictionaries/context.js +3 -1
- package/dist/modules/customers/api/dictionaries/context.js.map +2 -2
- package/dist/modules/customers/api/dictionaries/currency/route.js +3 -1
- package/dist/modules/customers/api/dictionaries/currency/route.js.map +2 -2
- package/dist/modules/customers/api/dictionaries/kind-settings/route.js +4 -2
- package/dist/modules/customers/api/dictionaries/kind-settings/route.js.map +2 -2
- package/dist/modules/customers/api/entity-roles-factory.js +7 -5
- package/dist/modules/customers/api/entity-roles-factory.js.map +2 -2
- package/dist/modules/customers/api/interactions/cancel/route.js +3 -1
- package/dist/modules/customers/api/interactions/cancel/route.js.map +2 -2
- package/dist/modules/customers/api/interactions/complete/route.js +3 -1
- package/dist/modules/customers/api/interactions/complete/route.js.map +2 -2
- package/dist/modules/customers/api/interactions/conflicts/route.js +3 -1
- package/dist/modules/customers/api/interactions/conflicts/route.js.map +2 -2
- package/dist/modules/customers/api/interactions/counts/route.js +3 -1
- package/dist/modules/customers/api/interactions/counts/route.js.map +2 -2
- package/dist/modules/customers/api/interactions/route.js +7 -4
- package/dist/modules/customers/api/interactions/route.js.map +2 -2
- package/dist/modules/customers/api/interactions/tasks/route.js +3 -1
- package/dist/modules/customers/api/interactions/tasks/route.js.map +2 -2
- package/dist/modules/customers/api/labels/assign/route.js +3 -1
- package/dist/modules/customers/api/labels/assign/route.js.map +2 -2
- package/dist/modules/customers/api/labels/route.js +6 -3
- package/dist/modules/customers/api/labels/route.js.map +2 -2
- package/dist/modules/customers/api/labels/unassign/route.js +3 -1
- package/dist/modules/customers/api/labels/unassign/route.js.map +2 -2
- package/dist/modules/customers/api/people/[id]/companies/enriched/route.js +3 -1
- package/dist/modules/customers/api/people/[id]/companies/enriched/route.js.map +2 -2
- package/dist/modules/customers/api/people/[id]/route.js +5 -3
- package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/people/route.js +5 -3
- package/dist/modules/customers/api/people/route.js.map +2 -2
- package/dist/modules/customers/api/pipeline-stages/reorder/route.js +3 -1
- package/dist/modules/customers/api/pipeline-stages/reorder/route.js.map +2 -2
- package/dist/modules/customers/api/pipeline-stages/route.js +6 -4
- package/dist/modules/customers/api/pipeline-stages/route.js.map +2 -2
- package/dist/modules/customers/api/pipelines/route.js +6 -4
- package/dist/modules/customers/api/pipelines/route.js.map +2 -2
- package/dist/modules/customers/api/settings/address-format/route.js +4 -2
- package/dist/modules/customers/api/settings/address-format/route.js.map +2 -2
- package/dist/modules/customers/api/settings/dictionary-sort-modes/route.js +4 -2
- package/dist/modules/customers/api/settings/dictionary-sort-modes/route.js.map +2 -2
- package/dist/modules/customers/api/settings/stuck-threshold/route.js +4 -2
- package/dist/modules/customers/api/settings/stuck-threshold/route.js.map +2 -2
- package/dist/modules/customers/api/tags/assign/route.js +3 -1
- package/dist/modules/customers/api/tags/assign/route.js.map +2 -2
- package/dist/modules/customers/api/tags/unassign/route.js +3 -1
- package/dist/modules/customers/api/tags/unassign/route.js.map +2 -2
- package/dist/modules/customers/api/todos/route.js +6 -4
- package/dist/modules/customers/api/todos/route.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +5 -3
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js +3 -1
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.js +3 -1
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/map/components/DealsMapCanvasImpl.js +4 -2
- package/dist/modules/customers/backend/customers/deals/map/components/DealsMapCanvasImpl.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/page.js +4 -2
- package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +5 -3
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/commands/deals.js +3 -1
- package/dist/modules/customers/commands/deals.js.map +2 -2
- package/dist/modules/customers/commands/dictionaries.js +3 -1
- package/dist/modules/customers/commands/dictionaries.js.map +2 -2
- package/dist/modules/customers/commands/interactions.js +4 -2
- package/dist/modules/customers/commands/interactions.js.map +2 -2
- package/dist/modules/customers/commands/shared.js +4 -2
- package/dist/modules/customers/commands/shared.js.map +2 -2
- package/dist/modules/customers/commands/todos.js +3 -1
- package/dist/modules/customers/commands/todos.js.map +2 -2
- package/dist/modules/customers/components/DictionarySettings.js +5 -3
- package/dist/modules/customers/components/DictionarySettings.js.map +2 -2
- package/dist/modules/customers/components/DictionarySortSettings.js +3 -1
- package/dist/modules/customers/components/DictionarySortSettings.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivitiesCard.js +3 -1
- package/dist/modules/customers/components/detail/ActivitiesCard.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivitiesDayStrip.js +3 -1
- package/dist/modules/customers/components/detail/ActivitiesDayStrip.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivitiesSection.js +6 -4
- package/dist/modules/customers/components/detail/ActivitiesSection.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivityCard.js +3 -1
- package/dist/modules/customers/components/detail/ActivityCard.js.map +2 -2
- package/dist/modules/customers/components/detail/ChangelogTab.js +3 -1
- package/dist/modules/customers/components/detail/ChangelogTab.js.map +2 -2
- package/dist/modules/customers/components/detail/CompanyCard.js +3 -1
- package/dist/modules/customers/components/detail/CompanyCard.js.map +2 -2
- package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js +3 -1
- package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/EntityTagsDialog.js +3 -1
- package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/InlineActivityComposer.js +3 -1
- package/dist/modules/customers/components/detail/InlineActivityComposer.js.map +2 -2
- package/dist/modules/customers/components/detail/ManageTagsDialog.js +3 -1
- package/dist/modules/customers/components/detail/ManageTagsDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/RoleAssignmentRow.js +5 -3
- package/dist/modules/customers/components/detail/RoleAssignmentRow.js.map +2 -2
- package/dist/modules/customers/components/detail/RolesSection.js +4 -2
- package/dist/modules/customers/components/detail/RolesSection.js.map +2 -2
- package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js +5 -3
- package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js.map +2 -2
- package/dist/modules/customers/components/linking/LinkEntityDialog.js +4 -2
- package/dist/modules/customers/components/linking/LinkEntityDialog.js.map +2 -2
- package/dist/modules/customers/inbox-actions.js +3 -1
- package/dist/modules/customers/inbox-actions.js.map +2 -2
- package/dist/modules/customers/lib/bulkDeals.js +3 -1
- package/dist/modules/customers/lib/bulkDeals.js.map +2 -2
- package/dist/modules/customers/lib/dealClosureNotification.js +4 -2
- package/dist/modules/customers/lib/dealClosureNotification.js.map +2 -2
- package/dist/modules/customers/lib/dealStageTransitionTable.js +3 -1
- package/dist/modules/customers/lib/dealStageTransitionTable.js.map +2 -2
- package/dist/modules/customers/lib/interactionFeatureFlags.js +3 -1
- package/dist/modules/customers/lib/interactionFeatureFlags.js.map +2 -2
- package/dist/modules/customers/lib/todoCompatibility.js +3 -1
- package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
- package/dist/modules/customers/search.js +14 -7
- package/dist/modules/customers/search.js.map +2 -2
- package/dist/modules/customers/widgets/dashboard/customer-todos/widget.client.js +3 -1
- package/dist/modules/customers/widgets/dashboard/customer-todos/widget.client.js.map +2 -2
- package/dist/modules/customers/widgets/dashboard/new-customers/widget.client.js +3 -1
- package/dist/modules/customers/widgets/dashboard/new-customers/widget.client.js.map +2 -2
- package/dist/modules/customers/widgets/dashboard/new-deals/widget.client.js +3 -1
- package/dist/modules/customers/widgets/dashboard/new-deals/widget.client.js.map +2 -2
- package/dist/modules/customers/widgets/dashboard/next-interactions/widget.client.js +3 -1
- package/dist/modules/customers/widgets/dashboard/next-interactions/widget.client.js.map +2 -2
- package/dist/modules/dashboards/api/widgets/data/batch/route.js +3 -1
- package/dist/modules/dashboards/api/widgets/data/batch/route.js.map +2 -2
- package/dist/modules/dashboards/api/widgets/data/route.js +3 -1
- package/dist/modules/dashboards/api/widgets/data/route.js.map +2 -2
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js +5 -3
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/aov-kpi/widget.client.js +3 -1
- package/dist/modules/dashboards/widgets/dashboard/aov-kpi/widget.client.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.client.js +3 -1
- package/dist/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.client.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.js +3 -1
- package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/orders-kpi/widget.client.js +3 -1
- package/dist/modules/dashboards/widgets/dashboard/orders-kpi/widget.client.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/widget.client.js +3 -1
- package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/widget.client.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/revenue-kpi/widget.client.js +3 -1
- package/dist/modules/dashboards/widgets/dashboard/revenue-kpi/widget.client.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.js +3 -1
- package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.js +3 -1
- package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.client.js +3 -1
- package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.client.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/top-products/widget.client.js +3 -1
- package/dist/modules/dashboards/widgets/dashboard/top-products/widget.client.js.map +2 -2
- package/dist/modules/data_sync/api/run.js +3 -1
- package/dist/modules/data_sync/api/run.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/runs/[id]/page.js +1 -1
- package/dist/modules/data_sync/backend/data-sync/runs/[id]/page.js.map +2 -2
- package/dist/modules/data_sync/lib/adapter-registry.js +11 -4
- package/dist/modules/data_sync/lib/adapter-registry.js.map +2 -2
- package/dist/modules/data_sync/lib/sync-engine.js +23 -2
- package/dist/modules/data_sync/lib/sync-engine.js.map +2 -2
- package/dist/modules/data_sync/workers/sync-export.js +3 -1
- package/dist/modules/data_sync/workers/sync-export.js.map +2 -2
- package/dist/modules/data_sync/workers/sync-import.js +3 -1
- package/dist/modules/data_sync/workers/sync-import.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +4 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.js +3 -1
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js +4 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.js +3 -1
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/route.js +5 -3
- package/dist/modules/dictionaries/api/[dictionaryId]/route.js.map +2 -2
- package/dist/modules/dictionaries/api/context.js +3 -1
- package/dist/modules/dictionaries/api/context.js.map +2 -2
- package/dist/modules/dictionaries/api/route.js +4 -2
- package/dist/modules/dictionaries/api/route.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionariesManager.js +5 -3
- package/dist/modules/dictionaries/components/DictionariesManager.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js +4 -2
- package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionaryEntrySelect.js +4 -2
- package/dist/modules/dictionaries/components/DictionaryEntrySelect.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionarySelectControl.js +3 -1
- package/dist/modules/dictionaries/components/DictionarySelectControl.js.map +2 -2
- package/dist/modules/dictionaries/fields/dictionary.js +3 -1
- package/dist/modules/dictionaries/fields/dictionary.js.map +2 -2
- package/dist/modules/directory/api/organization-branding/route.js +3 -1
- package/dist/modules/directory/api/organization-branding/route.js.map +2 -2
- package/dist/modules/directory/api/organization-switcher/route.js +3 -1
- package/dist/modules/directory/api/organization-switcher/route.js.map +2 -2
- package/dist/modules/directory/commands/tenants.js +5 -3
- package/dist/modules/directory/commands/tenants.js.map +2 -2
- package/dist/modules/directory/utils/organizationScope.js +6 -4
- package/dist/modules/directory/utils/organizationScope.js.map +2 -2
- package/dist/modules/entities/api/definitions.cache.js +3 -1
- package/dist/modules/entities/api/definitions.cache.js.map +2 -2
- package/dist/modules/entities/api/definitions.js +7 -5
- package/dist/modules/entities/api/definitions.js.map +2 -2
- package/dist/modules/entities/api/records.js +4 -8
- package/dist/modules/entities/api/records.js.map +2 -2
- package/dist/modules/entities/components/EncryptionManager.js +3 -1
- package/dist/modules/entities/components/EncryptionManager.js.map +2 -2
- package/dist/modules/entities/lib/makeActivityRoute.js +3 -1
- package/dist/modules/entities/lib/makeActivityRoute.js.map +2 -2
- package/dist/modules/feature_toggles/api/overrides/route.js +3 -1
- package/dist/modules/feature_toggles/api/overrides/route.js.map +2 -2
- package/dist/modules/feature_toggles/lib/feature-flag-check.js +5 -9
- package/dist/modules/feature_toggles/lib/feature-flag-check.js.map +2 -2
- package/dist/modules/inbox_ops/api/emails/[id]/reprocess/route.js +4 -2
- package/dist/modules/inbox_ops/api/emails/[id]/reprocess/route.js.map +2 -2
- package/dist/modules/inbox_ops/api/emails/[id]/route.js +4 -2
- package/dist/modules/inbox_ops/api/emails/[id]/route.js.map +2 -2
- package/dist/modules/inbox_ops/api/emails/route.js +3 -1
- package/dist/modules/inbox_ops/api/emails/route.js.map +2 -2
- package/dist/modules/inbox_ops/api/extract/route.js +3 -1
- package/dist/modules/inbox_ops/api/extract/route.js.map +2 -2
- package/dist/modules/inbox_ops/api/proposals/[id]/actions/[actionId]/route.js +3 -1
- package/dist/modules/inbox_ops/api/proposals/[id]/actions/[actionId]/route.js.map +2 -2
- package/dist/modules/inbox_ops/api/proposals/[id]/replies/[replyId]/send/route.js +4 -2
- package/dist/modules/inbox_ops/api/proposals/[id]/replies/[replyId]/send/route.js.map +2 -2
- package/dist/modules/inbox_ops/api/proposals/counts/route.js +4 -2
- package/dist/modules/inbox_ops/api/proposals/counts/route.js.map +2 -2
- package/dist/modules/inbox_ops/api/proposals/route.js +3 -1
- package/dist/modules/inbox_ops/api/proposals/route.js.map +2 -2
- package/dist/modules/inbox_ops/api/routeHelpers.js +3 -1
- package/dist/modules/inbox_ops/api/routeHelpers.js.map +2 -2
- package/dist/modules/inbox_ops/api/settings/route.js +3 -1
- package/dist/modules/inbox_ops/api/settings/route.js.map +2 -2
- package/dist/modules/inbox_ops/api/webhook/inbound.js +7 -5
- package/dist/modules/inbox_ops/api/webhook/inbound.js.map +2 -2
- package/dist/modules/inbox_ops/lib/cache.js +4 -2
- package/dist/modules/inbox_ops/lib/cache.js.map +2 -2
- package/dist/modules/inbox_ops/lib/catalogLookup.js +3 -1
- package/dist/modules/inbox_ops/lib/catalogLookup.js.map +2 -2
- package/dist/modules/inbox_ops/lib/eventBus.js +3 -4
- package/dist/modules/inbox_ops/lib/eventBus.js.map +2 -2
- package/dist/modules/inbox_ops/lib/messagesIntegration.js +4 -8
- package/dist/modules/inbox_ops/lib/messagesIntegration.js.map +2 -2
- package/dist/modules/inbox_ops/subscribers/executionAuditor.js +3 -1
- package/dist/modules/inbox_ops/subscribers/executionAuditor.js.map +2 -2
- package/dist/modules/inbox_ops/subscribers/extractionWorker.js +10 -8
- package/dist/modules/inbox_ops/subscribers/extractionWorker.js.map +2 -2
- package/dist/modules/inbox_ops/subscribers/proposalNotifier.js +3 -1
- package/dist/modules/inbox_ops/subscribers/proposalNotifier.js.map +2 -2
- package/dist/modules/messages/api/[id]/route.js +3 -4
- package/dist/modules/messages/api/[id]/route.js.map +2 -2
- package/dist/modules/messages/commands/actions.js +3 -1
- package/dist/modules/messages/commands/actions.js.map +2 -2
- package/dist/modules/messages/components/MessagesInboxPageClient.js +3 -1
- package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
- package/dist/modules/messages/lib/email-sender.js +3 -7
- package/dist/modules/messages/lib/email-sender.js.map +2 -2
- package/dist/modules/messages/lib/message-objects-registry.js +3 -1
- package/dist/modules/messages/lib/message-objects-registry.js.map +2 -2
- package/dist/modules/messages/lib/message-types-registry.js +3 -1
- package/dist/modules/messages/lib/message-types-registry.js.map +2 -2
- package/dist/modules/messages/workers/send-email.worker.js +6 -4
- package/dist/modules/messages/workers/send-email.worker.js.map +2 -2
- package/dist/modules/notifications/lib/notificationMapper.js +3 -4
- package/dist/modules/notifications/lib/notificationMapper.js.map +2 -2
- package/dist/modules/notifications/lib/notificationService.js +4 -5
- package/dist/modules/notifications/lib/notificationService.js.map +2 -2
- package/dist/modules/notifications/subscribers/deliver-notification.js +8 -13
- package/dist/modules/notifications/subscribers/deliver-notification.js.map +2 -2
- package/dist/modules/payment_gateways/api/webhook/[provider]/route.js +3 -1
- package/dist/modules/payment_gateways/api/webhook/[provider]/route.js.map +2 -2
- package/dist/modules/perspectives/services/perspectiveService.js +3 -3
- package/dist/modules/perspectives/services/perspectiveService.js.map +2 -2
- package/dist/modules/planner/api/access.js +3 -3
- package/dist/modules/planner/api/access.js.map +2 -2
- package/dist/modules/planner/api/availability-date-specific.js +3 -1
- package/dist/modules/planner/api/availability-date-specific.js.map +2 -2
- package/dist/modules/planner/api/availability-weekly.js +3 -1
- package/dist/modules/planner/api/availability-weekly.js.map +2 -2
- 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/components/AvailabilityRulesEditor.js +3 -1
- package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
- package/dist/modules/progress/api/jobs/route.js +3 -1
- package/dist/modules/progress/api/jobs/route.js.map +2 -2
- package/dist/modules/query_index/components/QueryIndexesTable.js +5 -3
- package/dist/modules/query_index/components/QueryIndexesTable.js.map +2 -2
- package/dist/modules/query_index/lib/batch.js +4 -2
- package/dist/modules/query_index/lib/batch.js.map +2 -2
- package/dist/modules/query_index/lib/coverage.js +3 -1
- package/dist/modules/query_index/lib/coverage.js.map +2 -2
- package/dist/modules/query_index/lib/engine.js +13 -18
- package/dist/modules/query_index/lib/engine.js.map +2 -2
- package/dist/modules/query_index/lib/reindexer.js +8 -6
- package/dist/modules/query_index/lib/reindexer.js.map +2 -2
- package/dist/modules/query_index/lib/search-tokens.js +3 -1
- package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
- package/dist/modules/query_index/subscribers/coverage_refresh.js +3 -1
- package/dist/modules/query_index/subscribers/coverage_refresh.js.map +2 -2
- package/dist/modules/resources/api/comments.js +3 -1
- package/dist/modules/resources/api/comments.js.map +2 -2
- package/dist/modules/resources/api/resources/tags/assign/route.js +3 -1
- package/dist/modules/resources/api/resources/tags/assign/route.js.map +2 -2
- package/dist/modules/resources/api/resources/tags/unassign/route.js +3 -1
- package/dist/modules/resources/api/resources/tags/unassign/route.js.map +2 -2
- package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js +3 -1
- 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/commands/activities.js +6 -5
- package/dist/modules/resources/commands/activities.js.map +2 -2
- package/dist/modules/resources/commands/comments.js +6 -4
- package/dist/modules/resources/commands/comments.js.map +2 -2
- package/dist/modules/resources/commands/shared.js +24 -1
- package/dist/modules/resources/commands/shared.js.map +2 -2
- package/dist/modules/sales/api/channels/route.js +3 -1
- package/dist/modules/sales/api/channels/route.js.map +2 -2
- package/dist/modules/sales/api/document-addresses/route.js +96 -6
- package/dist/modules/sales/api/document-addresses/route.js.map +2 -2
- package/dist/modules/sales/api/document-history/route.js +3 -1
- package/dist/modules/sales/api/document-history/route.js.map +2 -2
- package/dist/modules/sales/api/document-numbers/route.js +3 -1
- package/dist/modules/sales/api/document-numbers/route.js.map +2 -2
- package/dist/modules/sales/api/quotes/accept/route.js +4 -2
- package/dist/modules/sales/api/quotes/accept/route.js.map +2 -2
- package/dist/modules/sales/api/quotes/convert/route.js +3 -1
- package/dist/modules/sales/api/quotes/convert/route.js.map +2 -2
- package/dist/modules/sales/api/quotes/public/[token]/route.js +3 -1
- package/dist/modules/sales/api/quotes/public/[token]/route.js.map +2 -2
- package/dist/modules/sales/api/quotes/send/route.js +3 -1
- package/dist/modules/sales/api/quotes/send/route.js.map +2 -2
- package/dist/modules/sales/api/returns/[id]/route.js +3 -1
- package/dist/modules/sales/api/returns/[id]/route.js.map +2 -2
- package/dist/modules/sales/api/settings/document-numbers/route.js +4 -2
- package/dist/modules/sales/api/settings/document-numbers/route.js.map +2 -2
- package/dist/modules/sales/api/settings/order-editing/route.js +4 -2
- package/dist/modules/sales/api/settings/order-editing/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 +6 -4
- package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/page.js +4 -2
- package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +20 -18
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/commands/documentAddresses.js +7 -0
- package/dist/modules/sales/commands/documentAddresses.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +4 -8
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/commands/payments.js +3 -1
- package/dist/modules/sales/commands/payments.js.map +2 -2
- package/dist/modules/sales/commands/shipments.js +3 -1
- package/dist/modules/sales/commands/shipments.js.map +2 -2
- package/dist/modules/sales/components/AdjustmentKindSettings.js +5 -3
- package/dist/modules/sales/components/AdjustmentKindSettings.js.map +2 -2
- package/dist/modules/sales/components/DocumentNumberSettings.js +4 -2
- package/dist/modules/sales/components/DocumentNumberSettings.js.map +2 -2
- package/dist/modules/sales/components/OrderEditingSettings.js +4 -2
- package/dist/modules/sales/components/OrderEditingSettings.js.map +2 -2
- package/dist/modules/sales/components/PaymentMethodsSettings.js +5 -3
- package/dist/modules/sales/components/PaymentMethodsSettings.js.map +2 -2
- package/dist/modules/sales/components/ShippingMethodsSettings.js +5 -3
- package/dist/modules/sales/components/ShippingMethodsSettings.js.map +2 -2
- package/dist/modules/sales/components/StatusSettings.js +5 -3
- package/dist/modules/sales/components/StatusSettings.js.map +2 -2
- package/dist/modules/sales/components/TaxRatesSettings.js +5 -3
- package/dist/modules/sales/components/TaxRatesSettings.js.map +2 -2
- package/dist/modules/sales/components/channels/ChannelOfferForm.js +16 -14
- package/dist/modules/sales/components/channels/ChannelOfferForm.js.map +2 -2
- package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +4 -2
- package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
- package/dist/modules/sales/components/documents/AddressesSection.js +5 -3
- package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
- package/dist/modules/sales/components/documents/AdjustmentDialog.js +3 -1
- package/dist/modules/sales/components/documents/AdjustmentDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/AdjustmentsSection.js +5 -3
- package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/ItemsSection.js +6 -4
- package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/LineItemDialog.js +8 -6
- package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/PaymentDialog.js +5 -3
- package/dist/modules/sales/components/documents/PaymentDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/PaymentsSection.js +4 -2
- package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentForm.js +14 -12
- package/dist/modules/sales/components/documents/SalesDocumentForm.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js +5 -3
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
- package/dist/modules/sales/components/documents/ShipmentDialog.js +9 -7
- package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/ShipmentsSection.js +4 -2
- package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
- package/dist/modules/sales/frontend/quote/[token]/page.js +4 -2
- package/dist/modules/sales/frontend/quote/[token]/page.js.map +2 -2
- package/dist/modules/sales/seed/examples.js +7 -9
- package/dist/modules/sales/seed/examples.js.map +2 -2
- package/dist/modules/sales/subscribers/quote-expiring-notification.js +3 -1
- package/dist/modules/sales/subscribers/quote-expiring-notification.js.map +2 -2
- package/dist/modules/sales/subscribers/reconcileOnAddressDelete.js +3 -1
- package/dist/modules/sales/subscribers/reconcileOnAddressDelete.js.map +2 -2
- package/dist/modules/sales/subscribers/reconcileOnCompanyDelete.js +3 -1
- package/dist/modules/sales/subscribers/reconcileOnCompanyDelete.js.map +2 -2
- package/dist/modules/sales/subscribers/reconcileOnCustomerDelete.js +3 -1
- package/dist/modules/sales/subscribers/reconcileOnCustomerDelete.js.map +2 -2
- package/dist/modules/sales/widgets/dashboard/makeDashboardWidgetRoute.js +5 -3
- package/dist/modules/sales/widgets/dashboard/makeDashboardWidgetRoute.js.map +2 -2
- package/dist/modules/sales/widgets/dashboard/new-orders/widget.client.js +3 -1
- package/dist/modules/sales/widgets/dashboard/new-orders/widget.client.js.map +2 -2
- package/dist/modules/sales/widgets/dashboard/new-quotes/widget.client.js +3 -1
- package/dist/modules/sales/widgets/dashboard/new-quotes/widget.client.js.map +2 -2
- package/dist/modules/shipping_carriers/api/tracking/route.js +5 -0
- package/dist/modules/shipping_carriers/api/tracking/route.js.map +2 -2
- package/dist/modules/shipping_carriers/api/webhook/[provider]/route.js +3 -1
- package/dist/modules/shipping_carriers/api/webhook/[provider]/route.js.map +2 -2
- package/dist/modules/shipping_carriers/lib/shipping-service.js +41 -19
- package/dist/modules/shipping_carriers/lib/shipping-service.js.map +2 -2
- package/dist/modules/shipping_carriers/lib/upstream-error-response.js +3 -1
- package/dist/modules/shipping_carriers/lib/upstream-error-response.js.map +2 -2
- package/dist/modules/shipping_carriers/workers/webhook-processor.js +3 -5
- package/dist/modules/shipping_carriers/workers/webhook-processor.js.map +2 -2
- package/dist/modules/staff/api/comments.js +3 -1
- package/dist/modules/staff/api/comments.js.map +2 -2
- package/dist/modules/staff/api/leave-requests/accept/route.js +3 -1
- package/dist/modules/staff/api/leave-requests/accept/route.js.map +2 -2
- package/dist/modules/staff/api/leave-requests/reject/route.js +3 -1
- package/dist/modules/staff/api/leave-requests/reject/route.js.map +2 -2
- package/dist/modules/staff/api/team-members/assignable/route.js +3 -1
- package/dist/modules/staff/api/team-members/assignable/route.js.map +2 -2
- package/dist/modules/staff/api/team-members/self/route.js +4 -2
- package/dist/modules/staff/api/team-members/self/route.js.map +2 -2
- package/dist/modules/staff/api/team-members/tags/assign/route.js +3 -1
- package/dist/modules/staff/api/team-members/tags/assign/route.js.map +2 -2
- package/dist/modules/staff/api/team-members/tags/unassign/route.js +3 -1
- package/dist/modules/staff/api/team-members/tags/unassign/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/my-projects/[projectId]/route.js +3 -1
- package/dist/modules/staff/api/timesheets/my-projects/[projectId]/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/my-projects/route.js +3 -1
- package/dist/modules/staff/api/timesheets/my-projects/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/projects/kpis/route.js +3 -1
- package/dist/modules/staff/api/timesheets/projects/kpis/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-entries/[id]/segments/route.js +3 -1
- package/dist/modules/staff/api/timesheets/time-entries/[id]/segments/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js +4 -2
- package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-stop/route.js +4 -2
- package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-stop/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-entries/bulk/route.js +3 -1
- package/dist/modules/staff/api/timesheets/time-entries/bulk/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-entries/start-timer/route.js +3 -1
- package/dist/modules/staff/api/timesheets/time-entries/start-timer/route.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/page.js +4 -2
- package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-roles/page.js +4 -2
- package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +4 -2
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/page.js +4 -2
- package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/page.js +7 -5
- package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js +3 -1
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/page.js +4 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
- package/dist/modules/staff/commands/activities.js +23 -12
- package/dist/modules/staff/commands/activities.js.map +2 -2
- package/dist/modules/staff/commands/addresses.js +20 -12
- package/dist/modules/staff/commands/addresses.js.map +2 -2
- package/dist/modules/staff/commands/comments.js +18 -11
- package/dist/modules/staff/commands/comments.js.map +2 -2
- package/dist/modules/staff/commands/job-histories.js +23 -12
- package/dist/modules/staff/commands/job-histories.js.map +2 -2
- package/dist/modules/staff/commands/leave-requests.js +37 -19
- package/dist/modules/staff/commands/leave-requests.js.map +2 -2
- package/dist/modules/staff/commands/shared.js +28 -1
- package/dist/modules/staff/commands/shared.js.map +2 -2
- package/dist/modules/staff/commands/tag-assignments.js +20 -3
- package/dist/modules/staff/commands/tag-assignments.js.map +2 -2
- package/dist/modules/staff/commands/team-members.js +21 -11
- package/dist/modules/staff/commands/team-members.js.map +2 -2
- package/dist/modules/staff/commands/team-roles.js +21 -11
- package/dist/modules/staff/commands/team-roles.js.map +2 -2
- package/dist/modules/staff/commands/teams.js +21 -11
- package/dist/modules/staff/commands/teams.js.map +2 -2
- package/dist/modules/staff/commands/timesheets-entries.js +27 -15
- package/dist/modules/staff/commands/timesheets-entries.js.map +2 -2
- package/dist/modules/staff/commands/timesheets-projects.js +34 -18
- package/dist/modules/staff/commands/timesheets-projects.js.map +2 -2
- package/dist/modules/staff/widgets/dashboard/timesheets-hours-by-project/widget.client.js +3 -1
- package/dist/modules/staff/widgets/dashboard/timesheets-hours-by-project/widget.client.js.map +2 -2
- package/dist/modules/staff/widgets/dashboard/timesheets-time-reporting/widget.client.js +5 -3
- package/dist/modules/staff/widgets/dashboard/timesheets-time-reporting/widget.client.js.map +2 -2
- package/dist/modules/sync_excel/api/import/route.js +3 -1
- package/dist/modules/sync_excel/api/import/route.js.map +2 -2
- package/dist/modules/translations/api/[entityType]/[entityId]/route.js +5 -3
- package/dist/modules/translations/api/[entityType]/[entityId]/route.js.map +2 -2
- package/dist/modules/translations/api/get/locales.js +3 -1
- package/dist/modules/translations/api/get/locales.js.map +2 -2
- package/dist/modules/translations/api/put/locales.js +3 -1
- package/dist/modules/translations/api/put/locales.js.map +2 -2
- package/dist/modules/translations/components/TranslationManager.js +3 -1
- package/dist/modules/translations/components/TranslationManager.js.map +2 -2
- package/dist/modules/translations/subscribers/cleanup.js +3 -1
- package/dist/modules/translations/subscribers/cleanup.js.map +2 -2
- package/dist/modules/workflows/api/definitions/[id]/customize/route.js +4 -2
- package/dist/modules/workflows/api/definitions/[id]/customize/route.js.map +2 -2
- package/dist/modules/workflows/api/definitions/[id]/reset-to-code/route.js +4 -2
- package/dist/modules/workflows/api/definitions/[id]/reset-to-code/route.js.map +2 -2
- package/dist/modules/workflows/api/definitions/[id]/route.js +6 -4
- package/dist/modules/workflows/api/definitions/[id]/route.js.map +2 -2
- package/dist/modules/workflows/api/definitions/route.js +4 -2
- package/dist/modules/workflows/api/definitions/route.js.map +2 -2
- package/dist/modules/workflows/api/events/[id]/route.js +3 -1
- package/dist/modules/workflows/api/events/[id]/route.js.map +2 -2
- package/dist/modules/workflows/api/events/route.js +3 -1
- package/dist/modules/workflows/api/events/route.js.map +2 -2
- package/dist/modules/workflows/api/instances/[id]/advance/route.js +3 -1
- package/dist/modules/workflows/api/instances/[id]/advance/route.js.map +2 -2
- package/dist/modules/workflows/api/instances/[id]/cancel/route.js +3 -1
- package/dist/modules/workflows/api/instances/[id]/cancel/route.js.map +2 -2
- package/dist/modules/workflows/api/instances/[id]/events/route.js +3 -1
- package/dist/modules/workflows/api/instances/[id]/events/route.js.map +2 -2
- package/dist/modules/workflows/api/instances/[id]/retry/route.js +3 -1
- package/dist/modules/workflows/api/instances/[id]/retry/route.js.map +2 -2
- package/dist/modules/workflows/api/instances/[id]/route.js +3 -1
- package/dist/modules/workflows/api/instances/[id]/route.js.map +2 -2
- package/dist/modules/workflows/api/instances/[id]/signal/route.js +5 -7
- package/dist/modules/workflows/api/instances/[id]/signal/route.js.map +2 -2
- package/dist/modules/workflows/api/instances/route.js +6 -4
- package/dist/modules/workflows/api/instances/route.js.map +2 -2
- package/dist/modules/workflows/api/instances/validate-start/route.js +3 -1
- package/dist/modules/workflows/api/instances/validate-start/route.js.map +2 -2
- package/dist/modules/workflows/api/signals/route.js +3 -1
- package/dist/modules/workflows/api/signals/route.js.map +2 -2
- package/dist/modules/workflows/api/tasks/[id]/claim/route.js +3 -1
- package/dist/modules/workflows/api/tasks/[id]/claim/route.js.map +2 -2
- package/dist/modules/workflows/api/tasks/[id]/complete/route.js +3 -1
- package/dist/modules/workflows/api/tasks/[id]/complete/route.js.map +2 -2
- package/dist/modules/workflows/api/tasks/[id]/route.js +3 -1
- package/dist/modules/workflows/api/tasks/[id]/route.js.map +2 -2
- package/dist/modules/workflows/api/tasks/route.js +3 -1
- package/dist/modules/workflows/api/tasks/route.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js +4 -2
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
- package/dist/modules/workflows/backend/instances/[id]/page.js +5 -3
- package/dist/modules/workflows/backend/instances/[id]/page.js.map +2 -2
- package/dist/modules/workflows/backend/tasks/[id]/page.js +3 -1
- package/dist/modules/workflows/backend/tasks/[id]/page.js.map +2 -2
- package/dist/modules/workflows/components/BusinessRulesSelector.js +5 -3
- package/dist/modules/workflows/components/BusinessRulesSelector.js.map +2 -2
- package/dist/modules/workflows/components/WorkflowSelector.js +5 -3
- package/dist/modules/workflows/components/WorkflowSelector.js.map +2 -2
- package/dist/modules/workflows/components/fields/BusinessRuleConditionsEditor.js +3 -1
- package/dist/modules/workflows/components/fields/BusinessRuleConditionsEditor.js.map +2 -2
- package/dist/modules/workflows/components/fields/StartPreConditionsEditor.js +3 -1
- package/dist/modules/workflows/components/fields/StartPreConditionsEditor.js.map +2 -2
- package/dist/modules/workflows/components/fields/WorkflowSelectorField.js +3 -1
- package/dist/modules/workflows/components/fields/WorkflowSelectorField.js.map +2 -2
- package/dist/modules/workflows/frontend/checkout-demo/page.js +8 -7
- package/dist/modules/workflows/frontend/checkout-demo/page.js.map +2 -2
- package/dist/modules/workflows/lib/activity-executor.js +25 -21
- package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
- package/dist/modules/workflows/lib/activity-worker-handler.js +8 -15
- package/dist/modules/workflows/lib/activity-worker-handler.js.map +2 -2
- package/dist/modules/workflows/lib/code-registry.js +7 -7
- package/dist/modules/workflows/lib/code-registry.js.map +2 -2
- package/dist/modules/workflows/lib/compensation-handler.js +4 -2
- package/dist/modules/workflows/lib/compensation-handler.js.map +2 -2
- package/dist/modules/workflows/lib/edgeFormTransforms.js +3 -1
- package/dist/modules/workflows/lib/edgeFormTransforms.js.map +2 -2
- package/dist/modules/workflows/lib/event-trigger-service.js +5 -3
- package/dist/modules/workflows/lib/event-trigger-service.js.map +2 -2
- package/dist/modules/workflows/lib/nodeFormTransforms.js +3 -1
- package/dist/modules/workflows/lib/nodeFormTransforms.js.map +2 -2
- package/dist/modules/workflows/lib/seeds.js +16 -2
- package/dist/modules/workflows/lib/seeds.js.map +2 -2
- package/dist/modules/workflows/lib/signal-handler.js +3 -1
- package/dist/modules/workflows/lib/signal-handler.js.map +2 -2
- package/dist/modules/workflows/lib/start-validator.js +9 -3
- package/dist/modules/workflows/lib/start-validator.js.map +2 -2
- package/dist/modules/workflows/lib/step-handler.js +3 -1
- package/dist/modules/workflows/lib/step-handler.js.map +2 -2
- package/dist/modules/workflows/lib/task-handler.js +3 -1
- package/dist/modules/workflows/lib/task-handler.js.map +2 -2
- package/dist/modules/workflows/lib/transition-handler.js +5 -3
- package/dist/modules/workflows/lib/transition-handler.js.map +2 -2
- package/dist/modules/workflows/lib/workflow-executor.js +27 -15
- package/dist/modules/workflows/lib/workflow-executor.js.map +2 -2
- package/dist/modules/workflows/subscribers/event-trigger.js +21 -18
- package/dist/modules/workflows/subscribers/event-trigger.js.map +2 -2
- package/dist/modules/workflows/subscribers/task-assigned-notification.js +3 -1
- package/dist/modules/workflows/subscribers/task-assigned-notification.js.map +2 -2
- package/dist/modules/workflows/workers/workflow-activities.worker.js +30 -20
- package/dist/modules/workflows/workers/workflow-activities.worker.js.map +2 -2
- package/package.json +7 -7
- package/src/bootstrap.ts +14 -11
- package/src/helpers/integration/auth.ts +178 -86
- package/src/helpers/integration/queue-runner.ts +2 -2
- package/src/modules/api_keys/services/apiKeyService.ts +6 -3
- package/src/modules/attachments/api/image/[id]/[[...slug]]/route.ts +5 -2
- package/src/modules/attachments/api/library/[id]/route.ts +4 -1
- package/src/modules/attachments/api/route.ts +9 -6
- package/src/modules/attachments/components/AttachmentPartitionSettings.tsx +6 -3
- package/src/modules/attachments/lib/assignmentDetails.ts +4 -1
- package/src/modules/attachments/lib/drivers/driverFactory.ts +4 -1
- package/src/modules/attachments/lib/ocrQueue.ts +11 -11
- package/src/modules/attachments/lib/ocrService.ts +7 -4
- package/src/modules/audit_logs/api/audit-logs/actions/redo/route.ts +4 -1
- package/src/modules/audit_logs/api/audit-logs/actions/undo/route.ts +4 -1
- package/src/modules/audit_logs/backend/audit-logs/page.tsx +4 -1
- package/src/modules/audit_logs/components/AuditLogsActions.tsx +5 -2
- package/src/modules/audit_logs/services/accessLogService.ts +5 -4
- package/src/modules/audit_logs/services/actionLogService.ts +5 -2
- package/src/modules/auth/api/profile/route.ts +5 -2
- package/src/modules/auth/api/reset/confirm.ts +4 -1
- package/src/modules/auth/api/reset.ts +5 -2
- package/src/modules/auth/api/roles/route.ts +4 -1
- package/src/modules/auth/api/sidebar/variants/route.ts +4 -2
- package/src/modules/auth/api/users/resend-invite/route.ts +5 -2
- package/src/modules/auth/api/users/route.ts +4 -1
- package/src/modules/auth/backend/auth/profile/page.tsx +4 -1
- package/src/modules/auth/backend/profile/change-password/page.tsx +4 -1
- package/src/modules/auth/backend/users/[id]/edit/page.tsx +6 -3
- package/src/modules/auth/backend/users/create/page.tsx +5 -2
- package/src/modules/auth/cli.ts +10 -0
- package/src/modules/auth/commands/users.ts +5 -2
- package/src/modules/auth/lib/consentIntegrity.ts +4 -4
- package/src/modules/auth/lib/setup-app.ts +10 -10
- package/src/modules/auth/lib/tenantAccess.ts +4 -1
- package/src/modules/auth/lib/tokenHash.ts +4 -4
- package/src/modules/business_rules/api/rules/route.ts +5 -2
- package/src/modules/business_rules/lib/expression-evaluator.ts +8 -6
- package/src/modules/business_rules/lib/rule-engine.ts +6 -3
- package/src/modules/business_rules/lib/rule-evaluator.ts +11 -11
- package/src/modules/business_rules/subscribers/crud-rule-trigger.ts +4 -1
- package/src/modules/business_rules/subscribers/rule-execution-failed-notification.ts +4 -1
- package/src/modules/catalog/ai-agents-context.ts +5 -5
- package/src/modules/catalog/ai-tools/_shared.ts +4 -1
- package/src/modules/catalog/ai-tools/authoring-pack.ts +4 -1
- package/src/modules/catalog/ai-tools/merchandising-pack.ts +4 -1
- package/src/modules/catalog/api/dictionaries/[key]/route.ts +4 -1
- package/src/modules/catalog/api/prices/route.ts +4 -1
- package/src/modules/catalog/api/products/route.ts +6 -3
- package/src/modules/catalog/api/settings/route.ts +5 -2
- package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +15 -12
- package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx +9 -6
- package/src/modules/catalog/backend/catalog/products/[productId]/variants/create/page.tsx +6 -3
- package/src/modules/catalog/backend/catalog/products/create/page.tsx +6 -6
- package/src/modules/catalog/backend/catalog/products/optionSchemaClient.ts +4 -1
- package/src/modules/catalog/components/PriceKindSettings.tsx +6 -3
- package/src/modules/catalog/components/UnitPriceDisplaySettings.tsx +5 -2
- package/src/modules/catalog/inbox-actions.ts +5 -2
- package/src/modules/catalog/seed/examples.ts +5 -5
- package/src/modules/catalog/subscribers/low-stock-notification.ts +4 -1
- package/src/modules/catalog/widgets/injection/product-seo/state.ts +4 -1
- package/src/modules/communication_channels/api/get/oauth/[provider]/callback/route.ts +13 -13
- package/src/modules/communication_channels/api/post/channels/[id]/import-history/route.ts +4 -1
- package/src/modules/communication_channels/api/post/channels/[id]/push/register/route.ts +4 -1
- package/src/modules/communication_channels/api/post/webhook/[provider]/route.ts +6 -3
- package/src/modules/communication_channels/api/post/webhooks/gmail/route.ts +7 -6
- package/src/modules/communication_channels/commands/connect-credential-channel.ts +5 -10
- package/src/modules/communication_channels/commands/delete-channel.ts +4 -5
- package/src/modules/communication_channels/commands/deliver-outbound-message.ts +5 -5
- package/src/modules/communication_channels/commands/disconnect-channel.ts +4 -5
- package/src/modules/communication_channels/commands/ingest-inbound-message.ts +6 -12
- package/src/modules/communication_channels/commands/push-unregister.ts +4 -3
- package/src/modules/communication_channels/commands/reassign-conversation.ts +6 -3
- package/src/modules/communication_channels/lib/dead-letter.ts +4 -5
- package/src/modules/communication_channels/lib/email-mime.ts +5 -6
- package/src/modules/communication_channels/lib/oauth-client-config.ts +7 -3
- package/src/modules/communication_channels/lib/send-as-user.ts +4 -1
- package/src/modules/communication_channels/lib/thread-token.ts +5 -2
- package/src/modules/communication_channels/setup.ts +4 -4
- package/src/modules/communication_channels/workers/channel-import-history.ts +5 -8
- package/src/modules/communication_channels/workers/gmail-history-sync.ts +9 -18
- package/src/modules/communication_channels/workers/gmail-renew-watch.ts +6 -9
- package/src/modules/communication_channels/workers/outbound-delivery.ts +7 -12
- package/src/modules/communication_channels/workers/poll-channel.ts +8 -15
- package/src/modules/communication_channels/workers/poll-tick.ts +6 -6
- package/src/modules/communication_channels/workers/reaction-processor.ts +6 -9
- package/src/modules/configs/api/cache/route.ts +5 -2
- package/src/modules/configs/api/system-status/route.ts +5 -2
- package/src/modules/configs/api/upgrade-actions/route.ts +5 -2
- package/src/modules/configs/components/ModuleTelemetryPanel.tsx +4 -1
- package/src/modules/configs/lib/touchGeneratedBarrels.ts +1 -1
- package/src/modules/configs/services/upgradeActionsService.ts +7 -3
- package/src/modules/currencies/components/CurrencyFetchingConfig.tsx +4 -1
- package/src/modules/currencies/lib/exchangeRateFormConfig.ts +4 -1
- package/src/modules/currencies/services/providers/nbp.ts +7 -4
- package/src/modules/currencies/services/providers/raiffeisen.ts +8 -7
- package/src/modules/customer_accounts/api/domain-resolve/all.ts +7 -5
- package/src/modules/customer_accounts/api/signup.ts +5 -2
- package/src/modules/customer_accounts/lib/customerAuthServer.ts +4 -1
- package/src/modules/customer_accounts/subscribers/autoLinkCrm.ts +4 -1
- package/src/modules/customer_accounts/subscribers/autoLinkCrmReverse.ts +4 -1
- package/src/modules/customer_accounts/subscribers/unlinkOnCompanyDelete.ts +4 -1
- package/src/modules/customer_accounts/subscribers/unlinkOnPersonDelete.ts +4 -1
- package/src/modules/customers/ai-agents-context.ts +5 -5
- package/src/modules/customers/api/activities/route.ts +7 -4
- package/src/modules/customers/api/comments/route.ts +4 -1
- package/src/modules/customers/api/companies/[id]/people/route.ts +4 -1
- package/src/modules/customers/api/companies/[id]/route.ts +6 -3
- package/src/modules/customers/api/companies/route.ts +6 -3
- package/src/modules/customers/api/dashboard/widgets/customer-todos/route.ts +4 -1
- package/src/modules/customers/api/dashboard/widgets/new-customers/route.ts +4 -1
- package/src/modules/customers/api/dashboard/widgets/new-deals/route.ts +4 -1
- package/src/modules/customers/api/dashboard/widgets/next-interactions/route.ts +4 -1
- package/src/modules/customers/api/deals/[id]/companies/route.ts +4 -1
- package/src/modules/customers/api/deals/[id]/people/route.ts +4 -1
- package/src/modules/customers/api/deals/aggregate/route.ts +4 -1
- package/src/modules/customers/api/deals/bulk-update-owner/route.ts +8 -5
- package/src/modules/customers/api/deals/bulk-update-stage/route.ts +8 -5
- package/src/modules/customers/api/deals/route.ts +4 -1
- package/src/modules/customers/api/deals/summary/route.ts +4 -1
- package/src/modules/customers/api/dictionaries/[kind]/[id]/route.ts +5 -2
- package/src/modules/customers/api/dictionaries/[kind]/route.ts +6 -3
- package/src/modules/customers/api/dictionaries/cache.ts +4 -1
- package/src/modules/customers/api/dictionaries/context.ts +4 -1
- package/src/modules/customers/api/dictionaries/currency/route.ts +4 -1
- package/src/modules/customers/api/dictionaries/kind-settings/route.ts +5 -2
- package/src/modules/customers/api/entity-roles-factory.ts +8 -5
- package/src/modules/customers/api/interactions/cancel/route.ts +4 -1
- package/src/modules/customers/api/interactions/complete/route.ts +4 -1
- package/src/modules/customers/api/interactions/conflicts/route.ts +4 -1
- package/src/modules/customers/api/interactions/counts/route.ts +4 -1
- package/src/modules/customers/api/interactions/route.ts +8 -4
- package/src/modules/customers/api/interactions/tasks/route.ts +4 -1
- package/src/modules/customers/api/labels/assign/route.ts +4 -1
- package/src/modules/customers/api/labels/route.ts +7 -3
- package/src/modules/customers/api/labels/unassign/route.ts +4 -1
- package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +4 -1
- package/src/modules/customers/api/people/[id]/route.ts +6 -3
- package/src/modules/customers/api/people/route.ts +6 -3
- package/src/modules/customers/api/pipeline-stages/reorder/route.ts +4 -1
- package/src/modules/customers/api/pipeline-stages/route.ts +7 -4
- package/src/modules/customers/api/pipelines/route.ts +7 -4
- package/src/modules/customers/api/settings/address-format/route.ts +5 -2
- package/src/modules/customers/api/settings/dictionary-sort-modes/route.ts +5 -2
- package/src/modules/customers/api/settings/stuck-threshold/route.ts +5 -2
- package/src/modules/customers/api/tags/assign/route.ts +4 -1
- package/src/modules/customers/api/tags/unassign/route.ts +4 -1
- package/src/modules/customers/api/todos/route.ts +7 -4
- package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +6 -3
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.ts +4 -1
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.ts +4 -1
- package/src/modules/customers/backend/customers/deals/map/components/DealsMapCanvasImpl.tsx +5 -3
- package/src/modules/customers/backend/customers/deals/page.tsx +5 -2
- package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +6 -3
- package/src/modules/customers/commands/deals.ts +4 -1
- package/src/modules/customers/commands/dictionaries.ts +4 -1
- package/src/modules/customers/commands/interactions.ts +5 -2
- package/src/modules/customers/commands/shared.ts +5 -2
- package/src/modules/customers/commands/todos.ts +4 -1
- package/src/modules/customers/components/DictionarySettings.tsx +6 -3
- package/src/modules/customers/components/DictionarySortSettings.tsx +4 -1
- package/src/modules/customers/components/detail/ActivitiesCard.tsx +4 -1
- package/src/modules/customers/components/detail/ActivitiesDayStrip.tsx +4 -1
- package/src/modules/customers/components/detail/ActivitiesSection.tsx +7 -4
- package/src/modules/customers/components/detail/ActivityCard.tsx +4 -1
- package/src/modules/customers/components/detail/ChangelogTab.tsx +4 -1
- package/src/modules/customers/components/detail/CompanyCard.tsx +4 -1
- package/src/modules/customers/components/detail/ConfirmDealLostDialog.tsx +4 -1
- package/src/modules/customers/components/detail/EntityTagsDialog.tsx +4 -1
- package/src/modules/customers/components/detail/InlineActivityComposer.tsx +4 -1
- package/src/modules/customers/components/detail/ManageTagsDialog.tsx +4 -1
- package/src/modules/customers/components/detail/RoleAssignmentRow.tsx +6 -3
- package/src/modules/customers/components/detail/RolesSection.tsx +5 -2
- package/src/modules/customers/components/detail/hooks/useInteractionMutations.ts +6 -3
- package/src/modules/customers/components/linking/LinkEntityDialog.tsx +5 -2
- package/src/modules/customers/inbox-actions.ts +4 -1
- package/src/modules/customers/lib/bulkDeals.ts +4 -1
- package/src/modules/customers/lib/dealClosureNotification.ts +5 -2
- package/src/modules/customers/lib/dealStageTransitionTable.ts +4 -1
- package/src/modules/customers/lib/interactionFeatureFlags.ts +5 -1
- package/src/modules/customers/lib/todoCompatibility.ts +4 -1
- package/src/modules/customers/search.ts +15 -7
- package/src/modules/customers/widgets/dashboard/customer-todos/widget.client.tsx +4 -1
- package/src/modules/customers/widgets/dashboard/new-customers/widget.client.tsx +4 -1
- package/src/modules/customers/widgets/dashboard/new-deals/widget.client.tsx +4 -1
- package/src/modules/customers/widgets/dashboard/next-interactions/widget.client.tsx +4 -1
- package/src/modules/dashboards/api/widgets/data/batch/route.ts +4 -1
- package/src/modules/dashboards/api/widgets/data/route.ts +4 -1
- package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +6 -3
- package/src/modules/dashboards/widgets/dashboard/aov-kpi/widget.client.tsx +4 -1
- package/src/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.client.tsx +4 -1
- package/src/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.tsx +4 -1
- package/src/modules/dashboards/widgets/dashboard/orders-kpi/widget.client.tsx +4 -1
- package/src/modules/dashboards/widgets/dashboard/pipeline-summary/widget.client.tsx +4 -1
- package/src/modules/dashboards/widgets/dashboard/revenue-kpi/widget.client.tsx +4 -1
- package/src/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.tsx +4 -1
- package/src/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.tsx +4 -1
- package/src/modules/dashboards/widgets/dashboard/top-customers/widget.client.tsx +4 -1
- package/src/modules/dashboards/widgets/dashboard/top-products/widget.client.tsx +4 -1
- package/src/modules/data_sync/api/run.ts +4 -1
- package/src/modules/data_sync/backend/data-sync/runs/[id]/page.tsx +3 -1
- package/src/modules/data_sync/lib/adapter-registry.ts +16 -4
- package/src/modules/data_sync/lib/sync-engine.ts +31 -2
- package/src/modules/data_sync/workers/sync-export.ts +4 -1
- package/src/modules/data_sync/workers/sync-import.ts +4 -1
- package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +5 -2
- package/src/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.ts +4 -1
- package/src/modules/dictionaries/api/[dictionaryId]/entries/route.ts +5 -2
- package/src/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.ts +4 -1
- package/src/modules/dictionaries/api/[dictionaryId]/route.ts +6 -3
- package/src/modules/dictionaries/api/context.ts +4 -1
- package/src/modules/dictionaries/api/route.ts +5 -2
- package/src/modules/dictionaries/components/DictionariesManager.tsx +6 -3
- package/src/modules/dictionaries/components/DictionaryEntriesEditor.tsx +5 -2
- package/src/modules/dictionaries/components/DictionaryEntrySelect.tsx +5 -2
- package/src/modules/dictionaries/components/DictionarySelectControl.tsx +4 -1
- package/src/modules/dictionaries/fields/dictionary.tsx +4 -1
- package/src/modules/directory/api/organization-branding/route.ts +4 -1
- package/src/modules/directory/api/organization-switcher/route.ts +4 -1
- package/src/modules/directory/commands/tenants.ts +6 -3
- package/src/modules/directory/utils/organizationScope.ts +7 -4
- package/src/modules/entities/api/definitions.cache.ts +4 -1
- package/src/modules/entities/api/definitions.ts +8 -5
- package/src/modules/entities/api/records.ts +5 -2
- package/src/modules/entities/components/EncryptionManager.tsx +4 -1
- package/src/modules/entities/lib/makeActivityRoute.ts +4 -1
- package/src/modules/feature_toggles/api/overrides/route.ts +4 -1
- package/src/modules/feature_toggles/lib/feature-flag-check.ts +6 -9
- package/src/modules/inbox_ops/api/emails/[id]/reprocess/route.ts +5 -2
- package/src/modules/inbox_ops/api/emails/[id]/route.ts +5 -2
- package/src/modules/inbox_ops/api/emails/route.ts +4 -1
- package/src/modules/inbox_ops/api/extract/route.ts +4 -1
- package/src/modules/inbox_ops/api/proposals/[id]/actions/[actionId]/route.ts +4 -1
- package/src/modules/inbox_ops/api/proposals/[id]/replies/[replyId]/send/route.ts +5 -2
- package/src/modules/inbox_ops/api/proposals/counts/route.ts +5 -2
- package/src/modules/inbox_ops/api/proposals/route.ts +4 -1
- package/src/modules/inbox_ops/api/routeHelpers.ts +4 -1
- package/src/modules/inbox_ops/api/settings/route.ts +4 -1
- package/src/modules/inbox_ops/api/webhook/inbound.ts +8 -5
- package/src/modules/inbox_ops/lib/cache.ts +5 -2
- package/src/modules/inbox_ops/lib/catalogLookup.ts +4 -1
- package/src/modules/inbox_ops/lib/eventBus.ts +4 -4
- package/src/modules/inbox_ops/lib/messagesIntegration.ts +5 -8
- package/src/modules/inbox_ops/subscribers/executionAuditor.ts +5 -1
- package/src/modules/inbox_ops/subscribers/extractionWorker.ts +11 -8
- package/src/modules/inbox_ops/subscribers/proposalNotifier.ts +4 -1
- package/src/modules/messages/api/[id]/route.ts +4 -4
- package/src/modules/messages/commands/actions.ts +4 -1
- package/src/modules/messages/components/MessagesInboxPageClient.tsx +4 -1
- package/src/modules/messages/lib/email-sender.ts +4 -7
- package/src/modules/messages/lib/message-objects-registry.ts +4 -1
- package/src/modules/messages/lib/message-types-registry.ts +4 -1
- package/src/modules/messages/workers/send-email.worker.ts +7 -4
- package/src/modules/notifications/lib/notificationMapper.ts +4 -4
- package/src/modules/notifications/lib/notificationService.ts +4 -5
- package/src/modules/notifications/subscribers/deliver-notification.ts +9 -14
- package/src/modules/payment_gateways/api/webhook/[provider]/route.ts +4 -1
- package/src/modules/perspectives/services/perspectiveService.ts +4 -3
- package/src/modules/planner/api/access.ts +4 -3
- package/src/modules/planner/api/availability-date-specific.ts +4 -1
- package/src/modules/planner/api/availability-weekly.ts +4 -1
- package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +5 -2
- package/src/modules/planner/components/AvailabilityRulesEditor.tsx +4 -1
- package/src/modules/progress/api/jobs/route.ts +4 -1
- package/src/modules/query_index/components/QueryIndexesTable.tsx +6 -3
- package/src/modules/query_index/lib/batch.ts +5 -2
- package/src/modules/query_index/lib/coverage.ts +4 -1
- package/src/modules/query_index/lib/engine.ts +14 -17
- package/src/modules/query_index/lib/reindexer.ts +9 -6
- package/src/modules/query_index/lib/search-tokens.ts +4 -2
- package/src/modules/query_index/subscribers/coverage_refresh.ts +4 -1
- package/src/modules/resources/api/comments.ts +4 -1
- package/src/modules/resources/api/resources/tags/assign/route.ts +4 -1
- package/src/modules/resources/api/resources/tags/unassign/route.ts +4 -1
- package/src/modules/resources/backend/resources/resource-types/[id]/edit/page.tsx +4 -1
- package/src/modules/resources/backend/resources/resource-types/page.tsx +5 -2
- package/src/modules/resources/commands/activities.ts +5 -4
- package/src/modules/resources/commands/comments.ts +6 -4
- package/src/modules/resources/commands/shared.ts +36 -0
- package/src/modules/sales/api/channels/route.ts +4 -1
- package/src/modules/sales/api/document-addresses/route.ts +140 -7
- package/src/modules/sales/api/document-history/route.ts +4 -1
- package/src/modules/sales/api/document-numbers/route.ts +4 -1
- package/src/modules/sales/api/quotes/accept/route.ts +5 -2
- package/src/modules/sales/api/quotes/convert/route.ts +4 -1
- package/src/modules/sales/api/quotes/public/[token]/route.ts +4 -1
- package/src/modules/sales/api/quotes/send/route.ts +4 -1
- package/src/modules/sales/api/returns/[id]/route.ts +4 -1
- package/src/modules/sales/api/settings/document-numbers/route.ts +5 -2
- package/src/modules/sales/api/settings/order-editing/route.ts +5 -2
- package/src/modules/sales/backend/sales/channels/[channelId]/edit/page.tsx +4 -1
- package/src/modules/sales/backend/sales/channels/offers/page.tsx +7 -4
- package/src/modules/sales/backend/sales/channels/page.tsx +5 -2
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +21 -18
- package/src/modules/sales/commands/documentAddresses.ts +8 -0
- package/src/modules/sales/commands/documents.ts +5 -8
- package/src/modules/sales/commands/payments.ts +4 -1
- package/src/modules/sales/commands/shipments.ts +4 -2
- package/src/modules/sales/components/AdjustmentKindSettings.tsx +6 -3
- package/src/modules/sales/components/DocumentNumberSettings.tsx +5 -2
- package/src/modules/sales/components/OrderEditingSettings.tsx +5 -2
- package/src/modules/sales/components/PaymentMethodsSettings.tsx +6 -3
- package/src/modules/sales/components/ShippingMethodsSettings.tsx +6 -3
- package/src/modules/sales/components/StatusSettings.tsx +6 -3
- package/src/modules/sales/components/TaxRatesSettings.tsx +6 -3
- package/src/modules/sales/components/channels/ChannelOfferForm.tsx +17 -14
- package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +5 -2
- package/src/modules/sales/components/documents/AddressesSection.tsx +6 -3
- package/src/modules/sales/components/documents/AdjustmentDialog.tsx +4 -1
- package/src/modules/sales/components/documents/AdjustmentsSection.tsx +6 -3
- package/src/modules/sales/components/documents/ItemsSection.tsx +7 -4
- package/src/modules/sales/components/documents/LineItemDialog.tsx +9 -6
- package/src/modules/sales/components/documents/PaymentDialog.tsx +6 -3
- package/src/modules/sales/components/documents/PaymentsSection.tsx +5 -2
- package/src/modules/sales/components/documents/SalesDocumentForm.tsx +15 -12
- package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +6 -3
- package/src/modules/sales/components/documents/ShipmentDialog.tsx +10 -7
- package/src/modules/sales/components/documents/ShipmentsSection.tsx +5 -2
- package/src/modules/sales/frontend/quote/[token]/page.tsx +5 -2
- package/src/modules/sales/seed/examples.ts +8 -9
- package/src/modules/sales/subscribers/quote-expiring-notification.ts +4 -1
- package/src/modules/sales/subscribers/reconcileOnAddressDelete.ts +4 -1
- package/src/modules/sales/subscribers/reconcileOnCompanyDelete.ts +4 -1
- package/src/modules/sales/subscribers/reconcileOnCustomerDelete.ts +4 -1
- package/src/modules/sales/widgets/dashboard/makeDashboardWidgetRoute.ts +6 -3
- package/src/modules/sales/widgets/dashboard/new-orders/widget.client.tsx +274 -271
- package/src/modules/sales/widgets/dashboard/new-quotes/widget.client.tsx +280 -277
- package/src/modules/shipping_carriers/api/tracking/route.ts +5 -1
- package/src/modules/shipping_carriers/api/webhook/[provider]/route.ts +4 -1
- package/src/modules/shipping_carriers/lib/shipping-service.ts +47 -22
- package/src/modules/shipping_carriers/lib/upstream-error-response.ts +4 -1
- package/src/modules/shipping_carriers/workers/webhook-processor.ts +4 -5
- package/src/modules/staff/api/comments.ts +4 -1
- package/src/modules/staff/api/leave-requests/accept/route.ts +4 -1
- package/src/modules/staff/api/leave-requests/reject/route.ts +4 -1
- package/src/modules/staff/api/team-members/assignable/route.ts +4 -1
- package/src/modules/staff/api/team-members/self/route.ts +5 -2
- package/src/modules/staff/api/team-members/tags/assign/route.ts +4 -1
- package/src/modules/staff/api/team-members/tags/unassign/route.ts +4 -1
- package/src/modules/staff/api/timesheets/my-projects/[projectId]/route.ts +4 -1
- package/src/modules/staff/api/timesheets/my-projects/route.ts +4 -1
- package/src/modules/staff/api/timesheets/projects/kpis/route.ts +4 -1
- package/src/modules/staff/api/timesheets/time-entries/[id]/segments/route.ts +4 -1
- package/src/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.ts +5 -2
- package/src/modules/staff/api/timesheets/time-entries/[id]/timer-stop/route.ts +5 -2
- package/src/modules/staff/api/timesheets/time-entries/bulk/route.ts +4 -1
- package/src/modules/staff/api/timesheets/time-entries/start-timer/route.ts +4 -1
- package/src/modules/staff/backend/staff/team-members/page.tsx +5 -2
- package/src/modules/staff/backend/staff/team-roles/page.tsx +5 -2
- package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +5 -2
- package/src/modules/staff/backend/staff/teams/page.tsx +5 -2
- package/src/modules/staff/backend/staff/timesheets/page.tsx +8 -5
- package/src/modules/staff/backend/staff/timesheets/projects/[id]/page.tsx +4 -1
- package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +5 -2
- package/src/modules/staff/commands/activities.ts +23 -11
- package/src/modules/staff/commands/addresses.ts +20 -11
- package/src/modules/staff/commands/comments.ts +18 -10
- package/src/modules/staff/commands/job-histories.ts +27 -11
- package/src/modules/staff/commands/leave-requests.ts +38 -19
- package/src/modules/staff/commands/shared.ts +38 -0
- package/src/modules/staff/commands/tag-assignments.ts +19 -2
- package/src/modules/staff/commands/team-members.ts +21 -10
- package/src/modules/staff/commands/team-roles.ts +21 -10
- package/src/modules/staff/commands/teams.ts +21 -10
- package/src/modules/staff/commands/timesheets-entries.ts +28 -14
- package/src/modules/staff/commands/timesheets-projects.ts +34 -17
- package/src/modules/staff/widgets/dashboard/timesheets-hours-by-project/widget.client.tsx +4 -1
- package/src/modules/staff/widgets/dashboard/timesheets-time-reporting/widget.client.tsx +6 -3
- package/src/modules/sync_excel/api/import/route.ts +4 -1
- package/src/modules/translations/api/[entityType]/[entityId]/route.ts +6 -3
- package/src/modules/translations/api/get/locales.ts +4 -1
- package/src/modules/translations/api/put/locales.ts +4 -1
- package/src/modules/translations/components/TranslationManager.tsx +4 -1
- package/src/modules/translations/subscribers/cleanup.ts +4 -1
- package/src/modules/workflows/api/definitions/[id]/customize/route.ts +5 -2
- package/src/modules/workflows/api/definitions/[id]/reset-to-code/route.ts +5 -2
- package/src/modules/workflows/api/definitions/[id]/route.ts +7 -4
- package/src/modules/workflows/api/definitions/route.ts +5 -2
- package/src/modules/workflows/api/events/[id]/route.ts +4 -1
- package/src/modules/workflows/api/events/route.ts +4 -1
- package/src/modules/workflows/api/instances/[id]/advance/route.ts +4 -1
- package/src/modules/workflows/api/instances/[id]/cancel/route.ts +4 -1
- package/src/modules/workflows/api/instances/[id]/events/route.ts +4 -1
- package/src/modules/workflows/api/instances/[id]/retry/route.ts +4 -1
- package/src/modules/workflows/api/instances/[id]/route.ts +4 -1
- package/src/modules/workflows/api/instances/[id]/signal/route.ts +6 -7
- package/src/modules/workflows/api/instances/route.ts +8 -5
- package/src/modules/workflows/api/instances/validate-start/route.ts +4 -1
- package/src/modules/workflows/api/signals/route.ts +4 -1
- package/src/modules/workflows/api/tasks/[id]/claim/route.ts +4 -1
- package/src/modules/workflows/api/tasks/[id]/complete/route.ts +4 -1
- package/src/modules/workflows/api/tasks/[id]/route.ts +4 -1
- package/src/modules/workflows/api/tasks/route.ts +4 -1
- package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +5 -2
- package/src/modules/workflows/backend/instances/[id]/page.tsx +6 -3
- package/src/modules/workflows/backend/tasks/[id]/page.tsx +4 -1
- package/src/modules/workflows/components/BusinessRulesSelector.tsx +6 -3
- package/src/modules/workflows/components/WorkflowSelector.tsx +6 -3
- package/src/modules/workflows/components/fields/BusinessRuleConditionsEditor.tsx +4 -1
- package/src/modules/workflows/components/fields/StartPreConditionsEditor.tsx +4 -1
- package/src/modules/workflows/components/fields/WorkflowSelectorField.tsx +4 -1
- package/src/modules/workflows/frontend/checkout-demo/page.tsx +9 -7
- package/src/modules/workflows/lib/activity-executor.ts +26 -21
- package/src/modules/workflows/lib/activity-worker-handler.ts +9 -15
- package/src/modules/workflows/lib/code-registry.ts +8 -7
- package/src/modules/workflows/lib/compensation-handler.ts +5 -2
- package/src/modules/workflows/lib/edgeFormTransforms.ts +4 -1
- package/src/modules/workflows/lib/event-trigger-service.ts +6 -3
- package/src/modules/workflows/lib/nodeFormTransforms.ts +4 -1
- package/src/modules/workflows/lib/seeds.ts +17 -2
- package/src/modules/workflows/lib/signal-handler.ts +4 -1
- package/src/modules/workflows/lib/start-validator.ts +10 -3
- package/src/modules/workflows/lib/step-handler.ts +4 -1
- package/src/modules/workflows/lib/task-handler.ts +4 -1
- package/src/modules/workflows/lib/transition-handler.ts +6 -3
- package/src/modules/workflows/lib/workflow-executor.ts +28 -15
- package/src/modules/workflows/subscribers/event-trigger.ts +22 -24
- package/src/modules/workflows/subscribers/task-assigned-notification.ts +4 -1
- package/src/modules/workflows/workers/workflow-activities.worker.ts +31 -20
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/modules/sales/api/settings/document-numbers/route.ts"],
|
|
4
|
-
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'\nimport type { CommandBus, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { CrudHttpError, isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { salesSettingsUpsertSchema, type SalesSettingsUpsertInput } from '../../../data/validators'\nimport { loadSalesSettings } from '../../../commands/settings'\nimport { SalesDocumentNumberGenerator } from '../../../services/salesDocumentNumberGenerator'\nimport { DOCUMENT_NUMBER_TOKENS, DEFAULT_ORDER_NUMBER_FORMAT, DEFAULT_QUOTE_NUMBER_FORMAT } from '../../../lib/documentNumberTokens'\nimport { withScopedPayload } from '../../utils'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport {\n runCrudMutationGuardAfterSuccess,\n validateCrudMutationGuard,\n} from '@open-mercato/shared/lib/crud/mutation-guard'\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['sales.settings.manage'] },\n PUT: { requireAuth: true, requireFeatures: ['sales.settings.manage'] },\n}\n\ntype SettingsRouteContext = {\n ctx: CommandRuntimeContext\n em: EntityManager\n generator: SalesDocumentNumberGenerator\n translate: (key: string, fallback?: string) => string\n organizationId: string\n tenantId: string\n}\n\nasync function resolveSettingsContext(req: Request): Promise<SettingsRouteContext> {\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(req)\n const { translate } = await resolveTranslations()\n if (!auth || !auth.tenantId) {\n throw new CrudHttpError(401, { error: translate('sales.settings.errors.unauthorized', 'Unauthorized') })\n }\n\n const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req })\n const organizationId = scope?.selectedId ?? auth.orgId ?? null\n if (!organizationId) {\n throw new CrudHttpError(400, {\n error: translate('sales.settings.errors.organization_required', 'Organization context is required'),\n })\n }\n\n const ctx: CommandRuntimeContext = {\n container,\n auth,\n organizationScope: scope,\n selectedOrganizationId: organizationId,\n organizationIds: scope?.filterIds ?? (auth.orgId ? [auth.orgId] : null),\n request: req,\n }\n\n const em = container.resolve('em') as EntityManager\n const generator = container.resolve('salesDocumentNumberGenerator') as SalesDocumentNumberGenerator\n\n return {\n ctx,\n em,\n generator,\n translate,\n tenantId: auth.tenantId,\n organizationId,\n }\n}\n\nexport async function GET(req: Request) {\n try {\n const { em, generator, organizationId, tenantId } = await resolveSettingsContext(req)\n const record = await loadSalesSettings(em, { tenantId, organizationId })\n const sequences = await generator.peekSequences({ organizationId, tenantId })\n return NextResponse.json({\n orderNumberFormat: record?.orderNumberFormat ?? DEFAULT_ORDER_NUMBER_FORMAT,\n quoteNumberFormat: record?.quoteNumberFormat ?? DEFAULT_QUOTE_NUMBER_FORMAT,\n nextOrderNumber: sequences.order,\n nextQuoteNumber: sequences.quote,\n tokens: DOCUMENT_NUMBER_TOKENS,\n })\n } catch (err) {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n const { translate } = await resolveTranslations()\n
|
|
5
|
-
"mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,SAAS;AAClB,SAAS,8BAA8B;AACvC,SAAS,0BAA0B;AACnC,SAAS,0CAA0C;AAGnD,SAAS,2BAA2B;AACpC,SAAS,eAAe,uBAAuB;AAE/C,SAAS,iCAAgE;AACzE,SAAS,yBAAyB;AAElC,SAAS,wBAAwB,6BAA6B,mCAAmC;AACjG,SAAS,yBAAyB;AAClC,SAAS,oBAAoB;AAC7B;AAAA,EACE;AAAA,EACA;AAAA,OACK;
|
|
4
|
+
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'\nimport type { CommandBus, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { CrudHttpError, isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { salesSettingsUpsertSchema, type SalesSettingsUpsertInput } from '../../../data/validators'\nimport { loadSalesSettings } from '../../../commands/settings'\nimport { SalesDocumentNumberGenerator } from '../../../services/salesDocumentNumberGenerator'\nimport { DOCUMENT_NUMBER_TOKENS, DEFAULT_ORDER_NUMBER_FORMAT, DEFAULT_QUOTE_NUMBER_FORMAT } from '../../../lib/documentNumberTokens'\nimport { withScopedPayload } from '../../utils'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport {\n runCrudMutationGuardAfterSuccess,\n validateCrudMutationGuard,\n} from '@open-mercato/shared/lib/crud/mutation-guard'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('sales')\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['sales.settings.manage'] },\n PUT: { requireAuth: true, requireFeatures: ['sales.settings.manage'] },\n}\n\ntype SettingsRouteContext = {\n ctx: CommandRuntimeContext\n em: EntityManager\n generator: SalesDocumentNumberGenerator\n translate: (key: string, fallback?: string) => string\n organizationId: string\n tenantId: string\n}\n\nasync function resolveSettingsContext(req: Request): Promise<SettingsRouteContext> {\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(req)\n const { translate } = await resolveTranslations()\n if (!auth || !auth.tenantId) {\n throw new CrudHttpError(401, { error: translate('sales.settings.errors.unauthorized', 'Unauthorized') })\n }\n\n const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req })\n const organizationId = scope?.selectedId ?? auth.orgId ?? null\n if (!organizationId) {\n throw new CrudHttpError(400, {\n error: translate('sales.settings.errors.organization_required', 'Organization context is required'),\n })\n }\n\n const ctx: CommandRuntimeContext = {\n container,\n auth,\n organizationScope: scope,\n selectedOrganizationId: organizationId,\n organizationIds: scope?.filterIds ?? (auth.orgId ? [auth.orgId] : null),\n request: req,\n }\n\n const em = container.resolve('em') as EntityManager\n const generator = container.resolve('salesDocumentNumberGenerator') as SalesDocumentNumberGenerator\n\n return {\n ctx,\n em,\n generator,\n translate,\n tenantId: auth.tenantId,\n organizationId,\n }\n}\n\nexport async function GET(req: Request) {\n try {\n const { em, generator, organizationId, tenantId } = await resolveSettingsContext(req)\n const record = await loadSalesSettings(em, { tenantId, organizationId })\n const sequences = await generator.peekSequences({ organizationId, tenantId })\n return NextResponse.json({\n orderNumberFormat: record?.orderNumberFormat ?? DEFAULT_ORDER_NUMBER_FORMAT,\n quoteNumberFormat: record?.quoteNumberFormat ?? DEFAULT_QUOTE_NUMBER_FORMAT,\n nextOrderNumber: sequences.order,\n nextQuoteNumber: sequences.quote,\n tokens: DOCUMENT_NUMBER_TOKENS,\n })\n } catch (err) {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n const { translate } = await resolveTranslations()\n logger.error('sales.settings.document-numbers.get failed', { err })\n return NextResponse.json(\n { error: translate('sales.settings.errors.load_failed', 'Failed to load sales settings') },\n { status: 400 }\n )\n }\n}\n\nexport async function PUT(req: Request) {\n try {\n const { ctx, translate, generator, organizationId, tenantId } = await resolveSettingsContext(req)\n const payload = await readJsonSafe(req, {})\n const scoped = withScopedPayload(payload, ctx, translate)\n const input = salesSettingsUpsertSchema.parse(scoped)\n\n const guardResult = await validateCrudMutationGuard(ctx.container, {\n tenantId,\n organizationId,\n userId: ctx.auth!.sub,\n resourceKind: 'sales.settings',\n resourceId: organizationId,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: input,\n })\n if (guardResult && !guardResult.ok) {\n return NextResponse.json(guardResult.body, { status: guardResult.status })\n }\n\n const commandBus = ctx.container.resolve('commandBus') as CommandBus\n const { result } = await commandBus.execute<\n SalesSettingsUpsertInput,\n {\n settingsId: string\n orderNumberFormat: string\n quoteNumberFormat: string\n nextOrderNumber: number\n nextQuoteNumber: number\n }\n >('sales.settings.save', { input, ctx })\n\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(ctx.container, {\n tenantId,\n organizationId,\n userId: ctx.auth!.sub,\n resourceKind: 'sales.settings',\n resourceId: organizationId,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n const sequences = await generator.peekSequences({ organizationId, tenantId })\n\n return NextResponse.json({\n orderNumberFormat: result?.orderNumberFormat ?? input.orderNumberFormat,\n quoteNumberFormat: result?.quoteNumberFormat ?? input.quoteNumberFormat,\n nextOrderNumber: result?.nextOrderNumber ?? sequences.order,\n nextQuoteNumber: result?.nextQuoteNumber ?? sequences.quote,\n tokens: DOCUMENT_NUMBER_TOKENS,\n })\n } catch (err) {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n const { translate } = await resolveTranslations()\n logger.error('sales.settings.document-numbers.put failed', { err })\n return NextResponse.json(\n { error: translate('sales.settings.errors.save_failed', 'Failed to save sales settings') },\n { status: 400 }\n )\n }\n}\n\nconst settingsResponseSchema = z.object({\n orderNumberFormat: z.string(),\n quoteNumberFormat: z.string(),\n nextOrderNumber: z.number(),\n nextQuoteNumber: z.number(),\n tokens: z\n .array(\n z.object({\n token: z.string(),\n description: z.string(),\n })\n )\n .optional(),\n})\n\nconst settingsErrorSchema = z.object({\n error: z.string(),\n})\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Sales',\n summary: 'Sales document numbering settings',\n methods: {\n GET: {\n summary: 'Get document numbering settings',\n responses: [\n { status: 200, description: 'Current numbering formats and counters', schema: settingsResponseSchema },\n { status: 401, description: 'Unauthorized', schema: settingsErrorSchema },\n { status: 400, description: 'Missing scope', schema: settingsErrorSchema },\n ],\n },\n PUT: {\n summary: 'Update document numbering settings',\n requestBody: {\n contentType: 'application/json',\n schema: salesSettingsUpsertSchema,\n },\n responses: [\n { status: 200, description: 'Updated numbering formats and counters', schema: settingsResponseSchema },\n { status: 401, description: 'Unauthorized', schema: settingsErrorSchema },\n { status: 400, description: 'Invalid payload', schema: settingsErrorSchema },\n ],\n },\n },\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -16,6 +16,8 @@ import {
|
|
|
16
16
|
} from "@open-mercato/shared/lib/crud/mutation-guard";
|
|
17
17
|
import { ensureSalesDictionary } from "../../../lib/dictionaries.js";
|
|
18
18
|
import { DictionaryEntry } from "@open-mercato/core/modules/dictionaries/data/entities";
|
|
19
|
+
import { createLogger } from "@open-mercato/shared/lib/logger";
|
|
20
|
+
const logger = createLogger("sales");
|
|
19
21
|
const metadata = {
|
|
20
22
|
GET: { requireAuth: true, requireFeatures: ["sales.settings.manage"] },
|
|
21
23
|
PUT: { requireAuth: true, requireFeatures: ["sales.settings.manage"] }
|
|
@@ -88,7 +90,7 @@ async function GET(req) {
|
|
|
88
90
|
return NextResponse.json(err.body, { status: err.status });
|
|
89
91
|
}
|
|
90
92
|
const { translate } = await resolveTranslations();
|
|
91
|
-
|
|
93
|
+
logger.error("sales.settings.order-editing.get failed", { err });
|
|
92
94
|
return NextResponse.json(
|
|
93
95
|
{ error: translate("sales.settings.errors.load_failed", "Failed to load sales settings") },
|
|
94
96
|
{ status: 400 }
|
|
@@ -150,7 +152,7 @@ async function PUT(req) {
|
|
|
150
152
|
return NextResponse.json(err.body, { status: err.status });
|
|
151
153
|
}
|
|
152
154
|
const { translate } = await resolveTranslations();
|
|
153
|
-
|
|
155
|
+
logger.error("sales.settings.order-editing.put failed", { err });
|
|
154
156
|
return NextResponse.json(
|
|
155
157
|
{ error: translate("sales.settings.errors.save_failed", "Failed to save sales settings") },
|
|
156
158
|
{ status: 400 }
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/modules/sales/api/settings/order-editing/route.ts"],
|
|
4
|
-
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'\nimport type { CommandBus, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { CrudHttpError, isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { salesEditingSettingsSchema, salesSettingsUpsertSchema } from '../../../data/validators'\nimport { loadSalesSettings } from '../../../commands/settings'\nimport { DEFAULT_ORDER_NUMBER_FORMAT, DEFAULT_QUOTE_NUMBER_FORMAT } from '../../../lib/documentNumberTokens'\nimport { withScopedPayload } from '../../utils'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport {\n runCrudMutationGuardAfterSuccess,\n validateCrudMutationGuard,\n} from '@open-mercato/shared/lib/crud/mutation-guard'\nimport { ensureSalesDictionary } from '../../../lib/dictionaries'\nimport { DictionaryEntry } from '@open-mercato/core/modules/dictionaries/data/entities'\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['sales.settings.manage'] },\n PUT: { requireAuth: true, requireFeatures: ['sales.settings.manage'] },\n}\n\ntype SettingsRouteContext = {\n ctx: CommandRuntimeContext\n em: EntityManager\n translate: (key: string, fallback?: string) => string\n organizationId: string\n tenantId: string\n}\n\nasync function resolveSettingsContext(req: Request): Promise<SettingsRouteContext> {\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(req)\n const { translate } = await resolveTranslations()\n if (!auth || !auth.tenantId) {\n throw new CrudHttpError(401, { error: translate('sales.settings.errors.unauthorized', 'Unauthorized') })\n }\n\n const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req })\n const organizationId = scope?.selectedId ?? auth.orgId ?? null\n if (!organizationId) {\n throw new CrudHttpError(400, {\n error: translate('sales.settings.errors.organization_required', 'Organization context is required'),\n })\n }\n\n const ctx: CommandRuntimeContext = {\n container,\n auth,\n organizationScope: scope,\n selectedOrganizationId: organizationId,\n organizationIds: scope?.filterIds ?? (auth.orgId ? [auth.orgId] : null),\n request: req,\n }\n\n const em = container.resolve('em') as EntityManager\n\n return {\n ctx,\n em,\n translate,\n tenantId: auth.tenantId,\n organizationId,\n }\n}\n\nasync function loadStatusOptions(em: EntityManager, tenantId: string, organizationId: string) {\n const dictionary = await ensureSalesDictionary({\n em,\n tenantId,\n organizationId,\n kind: 'order-status',\n })\n const entries = await em.find(\n DictionaryEntry,\n {\n dictionary,\n tenantId,\n organizationId,\n },\n { orderBy: { value: 'asc' } }\n )\n return entries.map((entry) => ({\n id: entry.id,\n value: entry.value ?? '',\n label: entry.label ?? entry.value ?? '',\n }))\n}\n\nexport async function GET(req: Request) {\n try {\n const { em, organizationId, tenantId } = await resolveSettingsContext(req)\n const record = await loadSalesSettings(em, { tenantId, organizationId })\n const orderStatuses = await loadStatusOptions(em, tenantId, organizationId)\n\n return NextResponse.json({\n orderCustomerEditableStatuses: record?.orderCustomerEditableStatuses ?? null,\n orderAddressEditableStatuses: record?.orderAddressEditableStatuses ?? null,\n orderStatuses,\n })\n } catch (err) {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n const { translate } = await resolveTranslations()\n
|
|
5
|
-
"mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,SAAS;AAClB,SAAS,8BAA8B;AACvC,SAAS,0BAA0B;AACnC,SAAS,0CAA0C;AAGnD,SAAS,2BAA2B;AACpC,SAAS,eAAe,uBAAuB;AAE/C,SAAS,4BAA4B,iCAAiC;AACtE,SAAS,yBAAyB;AAClC,SAAS,6BAA6B,mCAAmC;AACzE,SAAS,yBAAyB;AAClC,SAAS,oBAAoB;AAC7B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,6BAA6B;AACtC,SAAS,uBAAuB;
|
|
4
|
+
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'\nimport type { CommandBus, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { CrudHttpError, isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { salesEditingSettingsSchema, salesSettingsUpsertSchema } from '../../../data/validators'\nimport { loadSalesSettings } from '../../../commands/settings'\nimport { DEFAULT_ORDER_NUMBER_FORMAT, DEFAULT_QUOTE_NUMBER_FORMAT } from '../../../lib/documentNumberTokens'\nimport { withScopedPayload } from '../../utils'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport {\n runCrudMutationGuardAfterSuccess,\n validateCrudMutationGuard,\n} from '@open-mercato/shared/lib/crud/mutation-guard'\nimport { ensureSalesDictionary } from '../../../lib/dictionaries'\nimport { DictionaryEntry } from '@open-mercato/core/modules/dictionaries/data/entities'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('sales')\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['sales.settings.manage'] },\n PUT: { requireAuth: true, requireFeatures: ['sales.settings.manage'] },\n}\n\ntype SettingsRouteContext = {\n ctx: CommandRuntimeContext\n em: EntityManager\n translate: (key: string, fallback?: string) => string\n organizationId: string\n tenantId: string\n}\n\nasync function resolveSettingsContext(req: Request): Promise<SettingsRouteContext> {\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(req)\n const { translate } = await resolveTranslations()\n if (!auth || !auth.tenantId) {\n throw new CrudHttpError(401, { error: translate('sales.settings.errors.unauthorized', 'Unauthorized') })\n }\n\n const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req })\n const organizationId = scope?.selectedId ?? auth.orgId ?? null\n if (!organizationId) {\n throw new CrudHttpError(400, {\n error: translate('sales.settings.errors.organization_required', 'Organization context is required'),\n })\n }\n\n const ctx: CommandRuntimeContext = {\n container,\n auth,\n organizationScope: scope,\n selectedOrganizationId: organizationId,\n organizationIds: scope?.filterIds ?? (auth.orgId ? [auth.orgId] : null),\n request: req,\n }\n\n const em = container.resolve('em') as EntityManager\n\n return {\n ctx,\n em,\n translate,\n tenantId: auth.tenantId,\n organizationId,\n }\n}\n\nasync function loadStatusOptions(em: EntityManager, tenantId: string, organizationId: string) {\n const dictionary = await ensureSalesDictionary({\n em,\n tenantId,\n organizationId,\n kind: 'order-status',\n })\n const entries = await em.find(\n DictionaryEntry,\n {\n dictionary,\n tenantId,\n organizationId,\n },\n { orderBy: { value: 'asc' } }\n )\n return entries.map((entry) => ({\n id: entry.id,\n value: entry.value ?? '',\n label: entry.label ?? entry.value ?? '',\n }))\n}\n\nexport async function GET(req: Request) {\n try {\n const { em, organizationId, tenantId } = await resolveSettingsContext(req)\n const record = await loadSalesSettings(em, { tenantId, organizationId })\n const orderStatuses = await loadStatusOptions(em, tenantId, organizationId)\n\n return NextResponse.json({\n orderCustomerEditableStatuses: record?.orderCustomerEditableStatuses ?? null,\n orderAddressEditableStatuses: record?.orderAddressEditableStatuses ?? null,\n orderStatuses,\n })\n } catch (err) {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n const { translate } = await resolveTranslations()\n logger.error('sales.settings.order-editing.get failed', { err })\n return NextResponse.json(\n { error: translate('sales.settings.errors.load_failed', 'Failed to load sales settings') },\n { status: 400 }\n )\n }\n}\n\nexport async function PUT(req: Request) {\n try {\n const { ctx, translate, organizationId, tenantId, em } = await resolveSettingsContext(req)\n const payload = (await readJsonSafe<Record<string, unknown>>(req, {})) ?? {}\n const scoped = withScopedPayload(payload, ctx, translate)\n const parsed = salesEditingSettingsSchema.parse(scoped)\n\n const guardResult = await validateCrudMutationGuard(ctx.container, {\n tenantId,\n organizationId,\n userId: ctx.auth!.sub,\n resourceKind: 'sales.settings',\n resourceId: organizationId,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: parsed,\n })\n if (guardResult && !guardResult.ok) {\n return NextResponse.json(guardResult.body, { status: guardResult.status })\n }\n\n const current = await loadSalesSettings(em, { tenantId, organizationId })\n const commandInput = salesSettingsUpsertSchema.parse({\n ...parsed,\n orderNumberFormat: parsed.orderNumberFormat ?? current?.orderNumberFormat ?? DEFAULT_ORDER_NUMBER_FORMAT,\n quoteNumberFormat: parsed.quoteNumberFormat ?? current?.quoteNumberFormat ?? DEFAULT_QUOTE_NUMBER_FORMAT,\n orderNextNumber: payload.orderNextNumber,\n quoteNextNumber: payload.quoteNextNumber,\n })\n\n const commandBus = ctx.container.resolve('commandBus') as CommandBus\n const response = await commandBus.execute('sales.settings.save', { input: commandInput, ctx })\n const result = (response as { result?: { orderCustomerEditableStatuses?: string[] | null; orderAddressEditableStatuses?: string[] | null } }).result\n\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(ctx.container, {\n tenantId,\n organizationId,\n userId: ctx.auth!.sub,\n resourceKind: 'sales.settings',\n resourceId: organizationId,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n const orderStatuses = await loadStatusOptions(em, tenantId, organizationId)\n\n return NextResponse.json({\n orderCustomerEditableStatuses: result?.orderCustomerEditableStatuses ?? null,\n orderAddressEditableStatuses: result?.orderAddressEditableStatuses ?? null,\n orderStatuses,\n })\n } catch (err) {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n const { translate } = await resolveTranslations()\n logger.error('sales.settings.order-editing.put failed', { err })\n return NextResponse.json(\n { error: translate('sales.settings.errors.save_failed', 'Failed to save sales settings') },\n { status: 400 }\n )\n }\n}\n\nconst orderStatusOptionSchema = z.object({\n id: z.string().uuid(),\n value: z.string(),\n label: z.string(),\n})\n\nconst settingsResponseSchema = z.object({\n orderCustomerEditableStatuses: z.array(z.string()).nullable(),\n orderAddressEditableStatuses: z.array(z.string()).nullable(),\n orderStatuses: z.array(orderStatusOptionSchema),\n})\n\nconst settingsErrorSchema = z.object({\n error: z.string(),\n})\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Sales',\n summary: 'Sales order editing settings',\n methods: {\n GET: {\n summary: 'Get order editing guards',\n responses: [\n { status: 200, description: 'Current order editing guards', schema: settingsResponseSchema },\n { status: 401, description: 'Unauthorized', schema: settingsErrorSchema },\n { status: 400, description: 'Missing scope', schema: settingsErrorSchema },\n ],\n },\n PUT: {\n summary: 'Update order editing guards',\n requestBody: {\n contentType: 'application/json',\n schema: salesEditingSettingsSchema,\n },\n responses: [\n { status: 200, description: 'Updated order editing guards', schema: settingsResponseSchema },\n { status: 401, description: 'Unauthorized', schema: settingsErrorSchema },\n { status: 400, description: 'Invalid payload', schema: settingsErrorSchema },\n ],\n },\n },\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -15,6 +15,8 @@ import { useChannelFields, buildChannelPayload } from "@open-mercato/core/module
|
|
|
15
15
|
import { E } from "../../../../../../../generated/entities.ids.generated.js";
|
|
16
16
|
import { SalesChannelOffersPanel } from "@open-mercato/core/modules/sales/components/channels/SalesChannelOffersPanel";
|
|
17
17
|
import { SendObjectMessageDialog } from "@open-mercato/ui/backend/messages";
|
|
18
|
+
import { createLogger } from "@open-mercato/shared/lib/logger";
|
|
19
|
+
const logger = createLogger("sales");
|
|
18
20
|
function EditChannelPage({ params }) {
|
|
19
21
|
const channelId = params?.channelId ?? "";
|
|
20
22
|
const router = useRouter();
|
|
@@ -56,7 +58,7 @@ function EditChannelPage({ params }) {
|
|
|
56
58
|
setInitialValues(mapChannelToFormValues(item));
|
|
57
59
|
}
|
|
58
60
|
} catch (err) {
|
|
59
|
-
|
|
61
|
+
logger.error("sales.channels.load", { err });
|
|
60
62
|
if (!cancelled) {
|
|
61
63
|
if (err.status === 404) {
|
|
62
64
|
setIsNotFound(true);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../../src/modules/sales/backend/sales/channels/%5BchannelId%5D/edit/page.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useRouter, useSearchParams } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { CrudForm } from '@open-mercato/ui/backend/CrudForm'\nimport { ErrorMessage, RecordNotFoundState } from '@open-mercato/ui/backend/detail'\nimport { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'\nimport { updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { extractCustomFieldEntries } from '@open-mercato/shared/lib/crud/custom-fields-client'\nimport { useChannelFields, buildChannelPayload, type ChannelFormValues } from '@open-mercato/core/modules/sales/components/channels/channelFormFields'\nimport { E } from '#generated/entities.ids.generated'\nimport { SalesChannelOffersPanel } from '@open-mercato/core/modules/sales/components/channels/SalesChannelOffersPanel'\nimport { SendObjectMessageDialog } from '@open-mercato/ui/backend/messages'\n\ntype ChannelApiResponse = {\n items?: Array<Record<string, unknown>>\n}\n\nexport default function EditChannelPage({ params }: { params?: { channelId?: string } }) {\n const channelId = params?.channelId ?? ''\n const router = useRouter()\n const searchParams = useSearchParams()\n const t = useT()\n const { fields, groups } = useChannelFields()\n const [initialValues, setInitialValues] = React.useState<ChannelFormValues | null>(null)\n const [loading, setLoading] = React.useState(true)\n const [error, setError] = React.useState<string | null>(null)\n const [isNotFound, setIsNotFound] = React.useState(false)\n const [activeTab, setActiveTab] = React.useState<'settings' | 'offers'>('settings')\n\n React.useEffect(() => {\n const tabParam = (searchParams?.get('tab') ?? '').toLowerCase()\n if (tabParam === 'offers') {\n setActiveTab('offers')\n } else if (tabParam === 'settings') {\n setActiveTab('settings')\n }\n }, [searchParams])\n\n React.useEffect(() => {\n if (!channelId) return\n let cancelled = false\n async function loadChannel() {\n setLoading(true)\n setError(null)\n setIsNotFound(false)\n try {\n const payload = await readApiResultOrThrow<ChannelApiResponse>(\n `/api/sales/channels?id=${encodeURIComponent(channelId)}&pageSize=1`,\n undefined,\n { errorMessage: t('sales.channels.form.errors.load', 'Failed to load channel.') },\n )\n const item = Array.isArray(payload.items) ? payload.items[0] : null\n if (!item) {\n if (!cancelled) setIsNotFound(true)\n return\n }\n if (!cancelled) {\n setInitialValues(mapChannelToFormValues(item))\n }\n } catch (err) {\n console.error('sales.channels.load', err)\n if (!cancelled) {\n if ((err as { status?: number }).status === 404) {\n setIsNotFound(true)\n } else {\n setError(t('sales.channels.form.errors.load', 'Failed to load channel.'))\n }\n }\n } finally {\n if (!cancelled) setLoading(false)\n }\n }\n void loadChannel()\n return () => { cancelled = true }\n }, [channelId, t])\n\n const handleSubmit = React.useCallback(async (values: ChannelFormValues) => {\n if (!channelId) return\n const payload: Record<string, unknown> = { id: channelId, ...buildChannelPayload(values) }\n const customFields = collectCustomFieldValues(values)\n if (Object.keys(customFields).length) payload.customFields = customFields\n await updateCrud('sales/channels', payload, {\n errorMessage: t('sales.channels.form.errors.update', 'Failed to save channel.'),\n })\n flash(t('sales.channels.form.messages.updated', 'Channel updated.'), 'success')\n router.push('/backend/sales/channels')\n }, [channelId, router, t])\n\n const handleDelete = React.useCallback(async () => {\n if (!channelId) return\n await deleteCrud('sales/channels', channelId, {\n errorMessage: t('sales.channels.form.errors.delete', 'Failed to delete channel.'),\n })\n flash(t('sales.channels.form.messages.deleted', 'Channel deleted.'), 'success')\n router.push('/backend/sales/channels')\n }, [channelId, router, t])\n\n const handleTabSelect = React.useCallback((value: 'settings' | 'offers') => {\n setActiveTab(value)\n if (!channelId) return\n const basePath = `/backend/sales/channels/${channelId}/edit`\n const nextUrl = value === 'offers' ? `${basePath}?tab=offers` : basePath\n router.replace(nextUrl)\n }, [channelId, router])\n\n const tabButton = React.useCallback((value: 'settings' | 'offers', label: string) => (\n <button\n key={value}\n type=\"button\"\n className={`px-4 py-2 text-sm font-medium border-b-2 ${activeTab === value ? 'border-accent-indigo text-foreground' : 'border-transparent text-muted-foreground'}`}\n onClick={() => handleTabSelect(value)}\n >\n {label}\n </button>\n ), [activeTab, handleTabSelect])\n\n const renderTabs = React.useCallback(() => (\n <div className=\"flex items-center gap-2 border-b mb-6\">\n {tabButton('settings', t('sales.channels.form.tabs.settings', 'Settings'))}\n {tabButton('offers', t('sales.channels.form.tabs.offers', 'Offers'))}\n </div>\n ), [tabButton, t])\n\n if (isNotFound) {\n return (\n <Page>\n <PageBody>\n <RecordNotFoundState\n label={t('sales.channels.form.errors.notFound', 'Channel not found.')}\n backHref=\"/backend/sales/channels\"\n backLabel={t('sales.channels.actions.backToList', 'Back to channels')}\n />\n </PageBody>\n </Page>\n )\n }\n\n if (error && !loading && !initialValues) {\n return (\n <Page>\n <PageBody>\n <ErrorMessage label={error} />\n </PageBody>\n </Page>\n )\n }\n\n return (\n <Page>\n <PageBody>\n {activeTab === 'settings' ? (\n <CrudForm<ChannelFormValues>\n title={t('sales.channels.form.editTitle', 'Edit channel')}\n versionHistory={{ resourceKind: 'sales.channel', resourceId: channelId ? String(channelId) : '' }}\n extraActions={channelId ? (\n <SendObjectMessageDialog\n object={{\n entityModule: 'sales',\n entityType: 'channel',\n entityId: channelId,\n previewData: {\n title: initialValues?.name ?? '',\n metadata: {\n [t('sales.channels.form.contactEmail')]: initialValues?.contactEmail ?? '-',\n [t('sales.channels.form.websiteUrl')]: initialValues?.websiteUrl ?? '-',\n },\n },\n }}\n viewHref={`/backend/sales/channels/${channelId}/edit`}\n />\n ) : undefined}\n entityId={E.sales.sales_channel}\n fields={fields}\n groups={[\n ...groups,\n { id: 'custom', title: t('entities.customFields.title', 'Custom Attributes'), column: 2, kind: 'customFields' },\n ]}\n initialValues={initialValues ?? undefined}\n optimisticLockUpdatedAt={typeof initialValues?.updatedAt === 'string' ? initialValues.updatedAt : null}\n isLoading={loading}\n loadingMessage={t('sales.channels.form.loading', 'Loading channel\u2026')}\n submitLabel={t('sales.channels.form.updateSubmit', 'Save changes')}\n cancelHref=\"/backend/sales/channels\"\n backHref=\"/backend/sales/channels\"\n contentHeader={renderTabs()}\n onSubmit={handleSubmit}\n onDelete={handleDelete}\n deleteVisible\n deleteRedirect=\"/backend/sales/channels\"\n />\n ) : (\n <>\n {renderTabs()}\n <SalesChannelOffersPanel channelId={channelId} channelName={initialValues?.name ?? ''} />\n </>\n )}\n </PageBody>\n </Page>\n )\n}\n\nfunction mapChannelToFormValues(item: Record<string, unknown>): ChannelFormValues {\n const values: ChannelFormValues = {\n name: typeof item.name === 'string' ? item.name : '',\n code: typeof item.code === 'string' ? item.code : null,\n description: typeof item.description === 'string' ? item.description : null,\n websiteUrl: typeof item.websiteUrl === 'string' ? item.websiteUrl : typeof item.website_url === 'string' ? item.website_url : null,\n contactEmail: typeof item.contactEmail === 'string' ? item.contactEmail : typeof item.contact_email === 'string' ? item.contact_email : null,\n contactPhone: typeof item.contactPhone === 'string' ? item.contactPhone : typeof item.contact_phone === 'string' ? item.contact_phone : null,\n addressLine1: typeof item.addressLine1 === 'string' ? item.addressLine1 : typeof item.address_line1 === 'string' ? item.address_line1 : null,\n addressLine2: typeof item.addressLine2 === 'string' ? item.addressLine2 : typeof item.address_line2 === 'string' ? item.address_line2 : null,\n city: typeof item.city === 'string' ? item.city : null,\n region: typeof item.region === 'string' ? item.region : null,\n postalCode: typeof item.postalCode === 'string' ? item.postalCode : typeof item.postal_code === 'string' ? item.postal_code : null,\n country: typeof item.country === 'string' ? item.country : null,\n latitude: typeof item.latitude === 'number' ? item.latitude : typeof item.latitude === 'string' ? item.latitude : null,\n longitude: typeof item.longitude === 'number' ? item.longitude : typeof item.longitude === 'string' ? item.longitude : null,\n statusEntryId: typeof item.statusEntryId === 'string'\n ? item.statusEntryId\n : typeof item.status_entry_id === 'string'\n ? item.status_entry_id\n : null,\n isActive: item.isActive === true || item.is_active === true,\n updatedAt: typeof item.updatedAt === 'string'\n ? item.updatedAt\n : typeof item.updated_at === 'string'\n ? item.updated_at\n : null,\n }\n return { ...values, ...extractCustomFieldEntries(item) }\n}\n"],
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useRouter, useSearchParams } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { CrudForm } from '@open-mercato/ui/backend/CrudForm'\nimport { ErrorMessage, RecordNotFoundState } from '@open-mercato/ui/backend/detail'\nimport { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'\nimport { updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { extractCustomFieldEntries } from '@open-mercato/shared/lib/crud/custom-fields-client'\nimport { useChannelFields, buildChannelPayload, type ChannelFormValues } from '@open-mercato/core/modules/sales/components/channels/channelFormFields'\nimport { E } from '#generated/entities.ids.generated'\nimport { SalesChannelOffersPanel } from '@open-mercato/core/modules/sales/components/channels/SalesChannelOffersPanel'\nimport { SendObjectMessageDialog } from '@open-mercato/ui/backend/messages'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('sales')\n\ntype ChannelApiResponse = {\n items?: Array<Record<string, unknown>>\n}\n\nexport default function EditChannelPage({ params }: { params?: { channelId?: string } }) {\n const channelId = params?.channelId ?? ''\n const router = useRouter()\n const searchParams = useSearchParams()\n const t = useT()\n const { fields, groups } = useChannelFields()\n const [initialValues, setInitialValues] = React.useState<ChannelFormValues | null>(null)\n const [loading, setLoading] = React.useState(true)\n const [error, setError] = React.useState<string | null>(null)\n const [isNotFound, setIsNotFound] = React.useState(false)\n const [activeTab, setActiveTab] = React.useState<'settings' | 'offers'>('settings')\n\n React.useEffect(() => {\n const tabParam = (searchParams?.get('tab') ?? '').toLowerCase()\n if (tabParam === 'offers') {\n setActiveTab('offers')\n } else if (tabParam === 'settings') {\n setActiveTab('settings')\n }\n }, [searchParams])\n\n React.useEffect(() => {\n if (!channelId) return\n let cancelled = false\n async function loadChannel() {\n setLoading(true)\n setError(null)\n setIsNotFound(false)\n try {\n const payload = await readApiResultOrThrow<ChannelApiResponse>(\n `/api/sales/channels?id=${encodeURIComponent(channelId)}&pageSize=1`,\n undefined,\n { errorMessage: t('sales.channels.form.errors.load', 'Failed to load channel.') },\n )\n const item = Array.isArray(payload.items) ? payload.items[0] : null\n if (!item) {\n if (!cancelled) setIsNotFound(true)\n return\n }\n if (!cancelled) {\n setInitialValues(mapChannelToFormValues(item))\n }\n } catch (err) {\n logger.error('sales.channels.load', { err })\n if (!cancelled) {\n if ((err as { status?: number }).status === 404) {\n setIsNotFound(true)\n } else {\n setError(t('sales.channels.form.errors.load', 'Failed to load channel.'))\n }\n }\n } finally {\n if (!cancelled) setLoading(false)\n }\n }\n void loadChannel()\n return () => { cancelled = true }\n }, [channelId, t])\n\n const handleSubmit = React.useCallback(async (values: ChannelFormValues) => {\n if (!channelId) return\n const payload: Record<string, unknown> = { id: channelId, ...buildChannelPayload(values) }\n const customFields = collectCustomFieldValues(values)\n if (Object.keys(customFields).length) payload.customFields = customFields\n await updateCrud('sales/channels', payload, {\n errorMessage: t('sales.channels.form.errors.update', 'Failed to save channel.'),\n })\n flash(t('sales.channels.form.messages.updated', 'Channel updated.'), 'success')\n router.push('/backend/sales/channels')\n }, [channelId, router, t])\n\n const handleDelete = React.useCallback(async () => {\n if (!channelId) return\n await deleteCrud('sales/channels', channelId, {\n errorMessage: t('sales.channels.form.errors.delete', 'Failed to delete channel.'),\n })\n flash(t('sales.channels.form.messages.deleted', 'Channel deleted.'), 'success')\n router.push('/backend/sales/channels')\n }, [channelId, router, t])\n\n const handleTabSelect = React.useCallback((value: 'settings' | 'offers') => {\n setActiveTab(value)\n if (!channelId) return\n const basePath = `/backend/sales/channels/${channelId}/edit`\n const nextUrl = value === 'offers' ? `${basePath}?tab=offers` : basePath\n router.replace(nextUrl)\n }, [channelId, router])\n\n const tabButton = React.useCallback((value: 'settings' | 'offers', label: string) => (\n <button\n key={value}\n type=\"button\"\n className={`px-4 py-2 text-sm font-medium border-b-2 ${activeTab === value ? 'border-accent-indigo text-foreground' : 'border-transparent text-muted-foreground'}`}\n onClick={() => handleTabSelect(value)}\n >\n {label}\n </button>\n ), [activeTab, handleTabSelect])\n\n const renderTabs = React.useCallback(() => (\n <div className=\"flex items-center gap-2 border-b mb-6\">\n {tabButton('settings', t('sales.channels.form.tabs.settings', 'Settings'))}\n {tabButton('offers', t('sales.channels.form.tabs.offers', 'Offers'))}\n </div>\n ), [tabButton, t])\n\n if (isNotFound) {\n return (\n <Page>\n <PageBody>\n <RecordNotFoundState\n label={t('sales.channels.form.errors.notFound', 'Channel not found.')}\n backHref=\"/backend/sales/channels\"\n backLabel={t('sales.channels.actions.backToList', 'Back to channels')}\n />\n </PageBody>\n </Page>\n )\n }\n\n if (error && !loading && !initialValues) {\n return (\n <Page>\n <PageBody>\n <ErrorMessage label={error} />\n </PageBody>\n </Page>\n )\n }\n\n return (\n <Page>\n <PageBody>\n {activeTab === 'settings' ? (\n <CrudForm<ChannelFormValues>\n title={t('sales.channels.form.editTitle', 'Edit channel')}\n versionHistory={{ resourceKind: 'sales.channel', resourceId: channelId ? String(channelId) : '' }}\n extraActions={channelId ? (\n <SendObjectMessageDialog\n object={{\n entityModule: 'sales',\n entityType: 'channel',\n entityId: channelId,\n previewData: {\n title: initialValues?.name ?? '',\n metadata: {\n [t('sales.channels.form.contactEmail')]: initialValues?.contactEmail ?? '-',\n [t('sales.channels.form.websiteUrl')]: initialValues?.websiteUrl ?? '-',\n },\n },\n }}\n viewHref={`/backend/sales/channels/${channelId}/edit`}\n />\n ) : undefined}\n entityId={E.sales.sales_channel}\n fields={fields}\n groups={[\n ...groups,\n { id: 'custom', title: t('entities.customFields.title', 'Custom Attributes'), column: 2, kind: 'customFields' },\n ]}\n initialValues={initialValues ?? undefined}\n optimisticLockUpdatedAt={typeof initialValues?.updatedAt === 'string' ? initialValues.updatedAt : null}\n isLoading={loading}\n loadingMessage={t('sales.channels.form.loading', 'Loading channel\u2026')}\n submitLabel={t('sales.channels.form.updateSubmit', 'Save changes')}\n cancelHref=\"/backend/sales/channels\"\n backHref=\"/backend/sales/channels\"\n contentHeader={renderTabs()}\n onSubmit={handleSubmit}\n onDelete={handleDelete}\n deleteVisible\n deleteRedirect=\"/backend/sales/channels\"\n />\n ) : (\n <>\n {renderTabs()}\n <SalesChannelOffersPanel channelId={channelId} channelName={initialValues?.name ?? ''} />\n </>\n )}\n </PageBody>\n </Page>\n )\n}\n\nfunction mapChannelToFormValues(item: Record<string, unknown>): ChannelFormValues {\n const values: ChannelFormValues = {\n name: typeof item.name === 'string' ? item.name : '',\n code: typeof item.code === 'string' ? item.code : null,\n description: typeof item.description === 'string' ? item.description : null,\n websiteUrl: typeof item.websiteUrl === 'string' ? item.websiteUrl : typeof item.website_url === 'string' ? item.website_url : null,\n contactEmail: typeof item.contactEmail === 'string' ? item.contactEmail : typeof item.contact_email === 'string' ? item.contact_email : null,\n contactPhone: typeof item.contactPhone === 'string' ? item.contactPhone : typeof item.contact_phone === 'string' ? item.contact_phone : null,\n addressLine1: typeof item.addressLine1 === 'string' ? item.addressLine1 : typeof item.address_line1 === 'string' ? item.address_line1 : null,\n addressLine2: typeof item.addressLine2 === 'string' ? item.addressLine2 : typeof item.address_line2 === 'string' ? item.address_line2 : null,\n city: typeof item.city === 'string' ? item.city : null,\n region: typeof item.region === 'string' ? item.region : null,\n postalCode: typeof item.postalCode === 'string' ? item.postalCode : typeof item.postal_code === 'string' ? item.postal_code : null,\n country: typeof item.country === 'string' ? item.country : null,\n latitude: typeof item.latitude === 'number' ? item.latitude : typeof item.latitude === 'string' ? item.latitude : null,\n longitude: typeof item.longitude === 'number' ? item.longitude : typeof item.longitude === 'string' ? item.longitude : null,\n statusEntryId: typeof item.statusEntryId === 'string'\n ? item.statusEntryId\n : typeof item.status_entry_id === 'string'\n ? item.status_entry_id\n : null,\n isActive: item.isActive === true || item.is_active === true,\n updatedAt: typeof item.updatedAt === 'string'\n ? item.updatedAt\n : typeof item.updated_at === 'string'\n ? item.updated_at\n : null,\n }\n return { ...values, ...extractCustomFieldEntries(item) }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -15,6 +15,8 @@ import { useGuardedMutation } from "@open-mercato/ui/backend/injection/useGuarde
|
|
|
15
15
|
import { useOrganizationScopeVersion } from "@open-mercato/shared/lib/frontend/useOrganizationScope";
|
|
16
16
|
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
17
17
|
import { mapOfferRow, renderOfferPriceSummary } from "@open-mercato/core/modules/sales/components/channels/offerTableUtils";
|
|
18
|
+
import { createLogger } from "@open-mercato/shared/lib/logger";
|
|
19
|
+
const logger = createLogger("sales");
|
|
18
20
|
const PAGE_SIZE = 25;
|
|
19
21
|
const SAVE_CONTEXT_ID = "sales-channel-offers-list";
|
|
20
22
|
function SalesChannelOffersListPage() {
|
|
@@ -80,7 +82,7 @@ function SalesChannelOffersListPage() {
|
|
|
80
82
|
upsertChannelOptions(options);
|
|
81
83
|
return options;
|
|
82
84
|
} catch (err) {
|
|
83
|
-
|
|
85
|
+
logger.warn("sales.channels.offers failed to load channel options", { err });
|
|
84
86
|
return [];
|
|
85
87
|
}
|
|
86
88
|
}, [t, upsertChannelOptions]);
|
|
@@ -107,7 +109,7 @@ function SalesChannelOffersListPage() {
|
|
|
107
109
|
}).filter((option) => !!option);
|
|
108
110
|
upsertChannelOptions(options);
|
|
109
111
|
} catch (err) {
|
|
110
|
-
|
|
112
|
+
logger.warn("sales.channels.offers failed to hydrate channel metadata", { err });
|
|
111
113
|
}
|
|
112
114
|
}, [t, upsertChannelOptions]);
|
|
113
115
|
const columns = React.useMemo(() => [
|
|
@@ -204,7 +206,7 @@ function SalesChannelOffersListPage() {
|
|
|
204
206
|
const ids = mapped.map((row) => row.channelId).filter((value) => typeof value === "string" && value.length > 0);
|
|
205
207
|
if (ids.length) void ensureChannelMetadata(Array.from(new Set(ids)));
|
|
206
208
|
} catch (err) {
|
|
207
|
-
|
|
209
|
+
logger.error("sales.channels.offers.list", { err });
|
|
208
210
|
flash(t("sales.channels.offers.errors.load", "Failed to load offers."), "error");
|
|
209
211
|
} finally {
|
|
210
212
|
setLoading(false);
|
|
@@ -247,7 +249,7 @@ function SalesChannelOffersListPage() {
|
|
|
247
249
|
handleRefresh();
|
|
248
250
|
return;
|
|
249
251
|
}
|
|
250
|
-
|
|
252
|
+
logger.error("sales.channels.offers.delete", { err });
|
|
251
253
|
}
|
|
252
254
|
}, [handleRefresh, mutationContext, runMutation, t]);
|
|
253
255
|
const tableTitle = /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../src/modules/sales/backend/sales/channels/offers/page.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useRouter } from 'next/navigation'\nimport type { ColumnDef, SortingState } from '@tanstack/react-table'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport type { FilterOption } from '@open-mercato/ui/backend/FilterOverlay'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { BooleanIcon } from '@open-mercato/ui/backend/ValueIcons'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { mapOfferRow, renderOfferPriceSummary, type OfferRow } from '@open-mercato/core/modules/sales/components/channels/offerTableUtils'\n\ntype OffersResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n totalPages?: number\n}\n\nconst PAGE_SIZE = 25\n\nconst SAVE_CONTEXT_ID = 'sales-channel-offers-list'\n\nexport default function SalesChannelOffersListPage() {\n const t = useT()\n const router = useRouter()\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: SAVE_CONTEXT_ID,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const mutationContext = React.useMemo(\n () => ({\n formId: SAVE_CONTEXT_ID,\n resourceKind: 'sales.channels.offers',\n retryLastMutation,\n }),\n [retryLastMutation],\n )\n const scopeVersion = useOrganizationScopeVersion()\n const channelOptionsRef = React.useRef<Map<string, FilterOption>>(new Map())\n const [rows, setRows] = React.useState<OfferRow[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [sorting, setSorting] = React.useState<SortingState>([{ id: 'updatedAt', desc: true }])\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [isLoading, setLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [channelOptions, setChannelOptions] = React.useState<Map<string, FilterOption>>(channelOptionsRef.current)\n\n const selectedChannelIds = React.useMemo(() => {\n if (!Array.isArray(filterValues.channelIds)) return []\n return filterValues.channelIds\n .map((value) => (typeof value === 'string' ? value.trim() : ''))\n .filter((value): value is string => value.length > 0)\n }, [filterValues])\n\n const upsertChannelOptions = React.useCallback((options: FilterOption[]) => {\n if (!options.length) return\n setChannelOptions((prev) => {\n const next = new Map(prev)\n options.forEach((option) => {\n if (!option.value) return\n next.set(option.value, option)\n })\n channelOptionsRef.current = next\n return next\n })\n }, [])\n\n const loadChannelOptions = React.useCallback(async (term?: string): Promise<FilterOption[]> => {\n try {\n const params = new URLSearchParams({ pageSize: '100', isActive: 'true' })\n if (term && term.trim().length) params.set('search', term.trim())\n const payload = await readApiResultOrThrow<{ items?: Array<{ id?: string; name?: string; code?: string; description?: string | null }> }>(\n `/api/sales/channels?${params.toString()}`,\n undefined,\n { errorMessage: t('sales.channels.offers.filters.channelsLoadError', 'Failed to load channels') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options = items\n .map((entry) => {\n const value = typeof entry.id === 'string' ? entry.id : null\n if (!value) return null\n const label =\n typeof entry.name === 'string'\n ? entry.name\n : typeof entry.code === 'string'\n ? entry.code\n : value\n const description =\n typeof entry.code === 'string' && entry.code !== label\n ? entry.code\n : typeof entry.description === 'string' && entry.description.trim().length\n ? entry.description\n : null\n return { value, label, description }\n })\n .filter((option) => !!option) as FilterOption[]\n upsertChannelOptions(options)\n return options\n } catch (err) {\n console.warn('[sales.channels.offers] failed to load channel options', err)\n return []\n }\n }, [t, upsertChannelOptions])\n\n const ensureChannelMetadata = React.useCallback(async (ids: string[]) => {\n const missing = ids.filter((id) => !channelOptionsRef.current.has(id))\n if (!missing.length) return\n try {\n const params = new URLSearchParams({\n ids: missing.join(','),\n pageSize: String(Math.min(Math.max(missing.length, 1), 100)),\n })\n const payload = await readApiResultOrThrow<{ items?: Array<{ id?: string; name?: string; code?: string; description?: string | null }> }>(\n `/api/sales/channels?${params.toString()}`,\n undefined,\n { errorMessage: t('sales.channels.offers.filters.channelsLoadError', 'Failed to load channels') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options = items\n .map((entry) => {\n const value = typeof entry.id === 'string' ? entry.id : null\n if (!value) return null\n const label =\n typeof entry.name === 'string'\n ? entry.name\n : typeof entry.code === 'string'\n ? entry.code\n : value\n const description =\n typeof entry.code === 'string' && entry.code !== label\n ? entry.code\n : typeof entry.description === 'string' && entry.description.trim().length\n ? entry.description\n : null\n return { value, label, description }\n })\n .filter((option) => !!option) as FilterOption[]\n upsertChannelOptions(options)\n } catch (err) {\n console.warn('[sales.channels.offers] failed to hydrate channel metadata', err)\n }\n }, [t, upsertChannelOptions])\n\n const columns = React.useMemo<ColumnDef<OfferRow>[]>(() => [\n {\n accessorKey: 'title',\n header: t('sales.channels.offers.table.offer', 'Offer'),\n cell: ({ row }) => (\n <div className=\"flex items-center gap-3\">\n {row.original.productMediaUrl ? (\n <img\n src={row.original.productMediaUrl}\n alt={row.original.productTitle ?? row.original.title}\n className=\"h-12 w-12 rounded border object-cover\"\n />\n ) : (\n <div className=\"h-12 w-12 rounded border bg-muted\" />\n )}\n <div className=\"flex flex-col gap-1\">\n <div className=\"flex flex-col\">\n <span className=\"font-medium\">{row.original.title}</span>\n <div className=\"text-xs text-muted-foreground\">\n {row.original.productTitle ?? t('sales.channels.offers.table.emptyProduct', 'Unlinked product')}\n </div>\n </div>\n </div>\n </div>\n ),\n meta: { sticky: true },\n },\n {\n accessorKey: 'pricing',\n header: t('sales.channels.offers.table.pricing', 'Prices'),\n cell: ({ row }) => (\n <div className=\"text-sm\">{renderOfferPriceSummary(row.original, t as any)}</div>\n ),\n },\n {\n accessorKey: 'channelId',\n header: t('sales.channels.offers.table.channel', 'Channel'),\n cell: ({ row }) => {\n const channelId = row.original.channelId\n if (!channelId) {\n return <span className=\"text-xs text-muted-foreground\">{t('sales.channels.offers.table.channelUnassigned', 'Unassigned')}</span>\n }\n const label = channelOptions.get(channelId)?.label ?? channelId\n const description = channelOptions.get(channelId)?.description ?? null\n return (\n <div className=\"flex flex-col\">\n <span className=\"text-sm font-medium\">{label}</span>\n {description ? <span className=\"text-xs text-muted-foreground\">{description}</span> : null}\n </div>\n )\n },\n },\n {\n accessorKey: 'isActive',\n header: t('sales.channels.offers.table.active', 'Active'),\n cell: ({ row }) => <BooleanIcon value={row.original.isActive} />,\n },\n {\n accessorKey: 'updatedAt',\n header: t('sales.channels.offers.table.updated', 'Updated'),\n cell: ({ row }) =>\n row.original.updatedAt\n ? <span className=\"text-xs text-muted-foreground\">{new Date(row.original.updatedAt).toLocaleDateString()}</span>\n : <span className=\"text-xs text-muted-foreground\">\u2014</span>,\n },\n ], [channelOptions, t])\n\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'channelIds',\n label: t('sales.channels.offers.filters.channels', 'Sales channels'),\n type: 'tags',\n placeholder: t('sales.channels.offers.filters.channelsPlaceholder', 'Filter by channels\u2026'),\n loadOptions: loadChannelOptions,\n formatValue: (value: string) => channelOptions.get(value)?.label ?? value,\n formatDescription: (value: string) => channelOptions.get(value)?.description ?? null,\n },\n ], [channelOptions, loadChannelOptions, t])\n\n const loadOffers = React.useCallback(async () => {\n setLoading(true)\n try {\n const params = new URLSearchParams({\n page: String(page),\n pageSize: String(PAGE_SIZE),\n })\n if (search.trim().length) {\n params.set('search', search.trim())\n }\n const sort = sorting[0]\n if (sort?.id) {\n params.set('sortField', sort.id)\n params.set('sortDir', sort.desc ? 'desc' : 'asc')\n }\n if (selectedChannelIds.length) {\n params.set('channelIds', selectedChannelIds.join(','))\n }\n const payload = await readApiResultOrThrow<OffersResponse>(\n `/api/catalog/offers?${params.toString()}`,\n undefined,\n { errorMessage: t('sales.channels.offers.errors.load', 'Failed to load offers.') },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n const mapped = items.map(mapOfferRow)\n setRows(mapped)\n setTotal(typeof payload.total === 'number' ? payload.total : items.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : Math.max(1, Math.ceil(items.length / PAGE_SIZE)))\n const ids = mapped\n .map((row) => row.channelId)\n .filter((value): value is string => typeof value === 'string' && value.length > 0)\n if (ids.length) void ensureChannelMetadata(Array.from(new Set(ids)))\n } catch (err) {\n console.error('sales.channels.offers.list', err)\n flash(t('sales.channels.offers.errors.load', 'Failed to load offers.'), 'error')\n } finally {\n setLoading(false)\n }\n }, [ensureChannelMetadata, page, search, selectedChannelIds, sorting, t])\n\n React.useEffect(() => {\n void loadOffers()\n }, [loadOffers, scopeVersion, reloadToken])\n\n const handleSearchChange = React.useCallback((value: string) => {\n setSearch(value)\n setPage(1)\n }, [])\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n setFilterValues(values)\n setPage(1)\n }, [])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({})\n setPage(1)\n }, [])\n\n const handleRefresh = React.useCallback(() => {\n setReloadToken((token) => token + 1)\n }, [])\n\n const handleDelete = React.useCallback(async (row: OfferRow) => {\n try {\n await runMutation({\n operation: () =>\n withScopedApiRequestHeaders(\n buildOptimisticLockHeader(row.updatedAt),\n () => deleteCrud('catalog/offers', row.id, {\n errorMessage: t('sales.channels.offers.errors.delete', 'Failed to delete offer.'),\n }),\n ),\n context: mutationContext,\n mutationPayload: { action: 'delete', id: row.id },\n })\n flash(t('sales.channels.offers.messages.deleted', 'Offer deleted.'), 'success')\n handleRefresh()\n } catch (err) {\n if (surfaceRecordConflict(err, t)) { handleRefresh(); return }\n console.error('sales.channels.offers.delete', err)\n }\n }, [handleRefresh, mutationContext, runMutation, t])\n\n const tableTitle = (\n <div className=\"flex flex-col gap-1\">\n <span>{t('sales.channels.offers.listTitle', 'Sales channel offers')}</span>\n <span className=\"text-sm font-normal text-muted-foreground\">\n {t('sales.channels.offers.listSubtitle', 'Review product overrides across every sales channel.')}\n </span>\n </div>\n )\n\n return (\n <Page>\n <PageBody>\n <DataTable<OfferRow>\n title={tableTitle}\n columns={columns}\n data={rows}\n isLoading={isLoading}\n sorting={sorting}\n onSortingChange={setSorting}\n searchValue={search}\n onSearchChange={handleSearchChange}\n searchPlaceholder={t('sales.channels.offers.table.search', 'Search offers\u2026')}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n onPageChange: setPage,\n }}\n refreshButton={{\n label: t('sales.channels.offers.table.refresh', 'Refresh'),\n onRefresh: handleRefresh,\n isRefreshing: isLoading,\n }}\n rowActions={(row) => {\n if (!row.channelId) return null\n return (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('sales.channels.offers.actions.edit', 'Edit'),\n href: `/backend/sales/channels/${row.channelId}/offers/${row.id}/edit`,\n },\n {\n id: 'delete',\n label: t('sales.channels.offers.actions.delete', 'Delete'),\n onSelect: () => handleDelete(row),\n destructive: true,\n },\n ]}\n />\n )\n }}\n onRowClick={(row) => {\n if (!row.channelId) return\n router.push(`/backend/sales/channels/${row.channelId}/offers/${row.id}/edit`)\n }}\n emptyState={\n <div className=\"py-10 text-center text-sm text-muted-foreground\">\n {t('sales.channels.offers.table.emptyAll', 'No offers available yet.')}\n </div>\n }\n />\n </PageBody>\n </Page>\n )\n}\n"],
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useRouter } from 'next/navigation'\nimport type { ColumnDef, SortingState } from '@tanstack/react-table'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport type { FilterOption } from '@open-mercato/ui/backend/FilterOverlay'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { BooleanIcon } from '@open-mercato/ui/backend/ValueIcons'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { mapOfferRow, renderOfferPriceSummary, type OfferRow } from '@open-mercato/core/modules/sales/components/channels/offerTableUtils'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('sales')\n\ntype OffersResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n totalPages?: number\n}\n\nconst PAGE_SIZE = 25\n\nconst SAVE_CONTEXT_ID = 'sales-channel-offers-list'\n\nexport default function SalesChannelOffersListPage() {\n const t = useT()\n const router = useRouter()\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: SAVE_CONTEXT_ID,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const mutationContext = React.useMemo(\n () => ({\n formId: SAVE_CONTEXT_ID,\n resourceKind: 'sales.channels.offers',\n retryLastMutation,\n }),\n [retryLastMutation],\n )\n const scopeVersion = useOrganizationScopeVersion()\n const channelOptionsRef = React.useRef<Map<string, FilterOption>>(new Map())\n const [rows, setRows] = React.useState<OfferRow[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [sorting, setSorting] = React.useState<SortingState>([{ id: 'updatedAt', desc: true }])\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [isLoading, setLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [channelOptions, setChannelOptions] = React.useState<Map<string, FilterOption>>(channelOptionsRef.current)\n\n const selectedChannelIds = React.useMemo(() => {\n if (!Array.isArray(filterValues.channelIds)) return []\n return filterValues.channelIds\n .map((value) => (typeof value === 'string' ? value.trim() : ''))\n .filter((value): value is string => value.length > 0)\n }, [filterValues])\n\n const upsertChannelOptions = React.useCallback((options: FilterOption[]) => {\n if (!options.length) return\n setChannelOptions((prev) => {\n const next = new Map(prev)\n options.forEach((option) => {\n if (!option.value) return\n next.set(option.value, option)\n })\n channelOptionsRef.current = next\n return next\n })\n }, [])\n\n const loadChannelOptions = React.useCallback(async (term?: string): Promise<FilterOption[]> => {\n try {\n const params = new URLSearchParams({ pageSize: '100', isActive: 'true' })\n if (term && term.trim().length) params.set('search', term.trim())\n const payload = await readApiResultOrThrow<{ items?: Array<{ id?: string; name?: string; code?: string; description?: string | null }> }>(\n `/api/sales/channels?${params.toString()}`,\n undefined,\n { errorMessage: t('sales.channels.offers.filters.channelsLoadError', 'Failed to load channels') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options = items\n .map((entry) => {\n const value = typeof entry.id === 'string' ? entry.id : null\n if (!value) return null\n const label =\n typeof entry.name === 'string'\n ? entry.name\n : typeof entry.code === 'string'\n ? entry.code\n : value\n const description =\n typeof entry.code === 'string' && entry.code !== label\n ? entry.code\n : typeof entry.description === 'string' && entry.description.trim().length\n ? entry.description\n : null\n return { value, label, description }\n })\n .filter((option) => !!option) as FilterOption[]\n upsertChannelOptions(options)\n return options\n } catch (err) {\n logger.warn('sales.channels.offers failed to load channel options', { err })\n return []\n }\n }, [t, upsertChannelOptions])\n\n const ensureChannelMetadata = React.useCallback(async (ids: string[]) => {\n const missing = ids.filter((id) => !channelOptionsRef.current.has(id))\n if (!missing.length) return\n try {\n const params = new URLSearchParams({\n ids: missing.join(','),\n pageSize: String(Math.min(Math.max(missing.length, 1), 100)),\n })\n const payload = await readApiResultOrThrow<{ items?: Array<{ id?: string; name?: string; code?: string; description?: string | null }> }>(\n `/api/sales/channels?${params.toString()}`,\n undefined,\n { errorMessage: t('sales.channels.offers.filters.channelsLoadError', 'Failed to load channels') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options = items\n .map((entry) => {\n const value = typeof entry.id === 'string' ? entry.id : null\n if (!value) return null\n const label =\n typeof entry.name === 'string'\n ? entry.name\n : typeof entry.code === 'string'\n ? entry.code\n : value\n const description =\n typeof entry.code === 'string' && entry.code !== label\n ? entry.code\n : typeof entry.description === 'string' && entry.description.trim().length\n ? entry.description\n : null\n return { value, label, description }\n })\n .filter((option) => !!option) as FilterOption[]\n upsertChannelOptions(options)\n } catch (err) {\n logger.warn('sales.channels.offers failed to hydrate channel metadata', { err })\n }\n }, [t, upsertChannelOptions])\n\n const columns = React.useMemo<ColumnDef<OfferRow>[]>(() => [\n {\n accessorKey: 'title',\n header: t('sales.channels.offers.table.offer', 'Offer'),\n cell: ({ row }) => (\n <div className=\"flex items-center gap-3\">\n {row.original.productMediaUrl ? (\n <img\n src={row.original.productMediaUrl}\n alt={row.original.productTitle ?? row.original.title}\n className=\"h-12 w-12 rounded border object-cover\"\n />\n ) : (\n <div className=\"h-12 w-12 rounded border bg-muted\" />\n )}\n <div className=\"flex flex-col gap-1\">\n <div className=\"flex flex-col\">\n <span className=\"font-medium\">{row.original.title}</span>\n <div className=\"text-xs text-muted-foreground\">\n {row.original.productTitle ?? t('sales.channels.offers.table.emptyProduct', 'Unlinked product')}\n </div>\n </div>\n </div>\n </div>\n ),\n meta: { sticky: true },\n },\n {\n accessorKey: 'pricing',\n header: t('sales.channels.offers.table.pricing', 'Prices'),\n cell: ({ row }) => (\n <div className=\"text-sm\">{renderOfferPriceSummary(row.original, t as any)}</div>\n ),\n },\n {\n accessorKey: 'channelId',\n header: t('sales.channels.offers.table.channel', 'Channel'),\n cell: ({ row }) => {\n const channelId = row.original.channelId\n if (!channelId) {\n return <span className=\"text-xs text-muted-foreground\">{t('sales.channels.offers.table.channelUnassigned', 'Unassigned')}</span>\n }\n const label = channelOptions.get(channelId)?.label ?? channelId\n const description = channelOptions.get(channelId)?.description ?? null\n return (\n <div className=\"flex flex-col\">\n <span className=\"text-sm font-medium\">{label}</span>\n {description ? <span className=\"text-xs text-muted-foreground\">{description}</span> : null}\n </div>\n )\n },\n },\n {\n accessorKey: 'isActive',\n header: t('sales.channels.offers.table.active', 'Active'),\n cell: ({ row }) => <BooleanIcon value={row.original.isActive} />,\n },\n {\n accessorKey: 'updatedAt',\n header: t('sales.channels.offers.table.updated', 'Updated'),\n cell: ({ row }) =>\n row.original.updatedAt\n ? <span className=\"text-xs text-muted-foreground\">{new Date(row.original.updatedAt).toLocaleDateString()}</span>\n : <span className=\"text-xs text-muted-foreground\">\u2014</span>,\n },\n ], [channelOptions, t])\n\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'channelIds',\n label: t('sales.channels.offers.filters.channels', 'Sales channels'),\n type: 'tags',\n placeholder: t('sales.channels.offers.filters.channelsPlaceholder', 'Filter by channels\u2026'),\n loadOptions: loadChannelOptions,\n formatValue: (value: string) => channelOptions.get(value)?.label ?? value,\n formatDescription: (value: string) => channelOptions.get(value)?.description ?? null,\n },\n ], [channelOptions, loadChannelOptions, t])\n\n const loadOffers = React.useCallback(async () => {\n setLoading(true)\n try {\n const params = new URLSearchParams({\n page: String(page),\n pageSize: String(PAGE_SIZE),\n })\n if (search.trim().length) {\n params.set('search', search.trim())\n }\n const sort = sorting[0]\n if (sort?.id) {\n params.set('sortField', sort.id)\n params.set('sortDir', sort.desc ? 'desc' : 'asc')\n }\n if (selectedChannelIds.length) {\n params.set('channelIds', selectedChannelIds.join(','))\n }\n const payload = await readApiResultOrThrow<OffersResponse>(\n `/api/catalog/offers?${params.toString()}`,\n undefined,\n { errorMessage: t('sales.channels.offers.errors.load', 'Failed to load offers.') },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n const mapped = items.map(mapOfferRow)\n setRows(mapped)\n setTotal(typeof payload.total === 'number' ? payload.total : items.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : Math.max(1, Math.ceil(items.length / PAGE_SIZE)))\n const ids = mapped\n .map((row) => row.channelId)\n .filter((value): value is string => typeof value === 'string' && value.length > 0)\n if (ids.length) void ensureChannelMetadata(Array.from(new Set(ids)))\n } catch (err) {\n logger.error('sales.channels.offers.list', { err })\n flash(t('sales.channels.offers.errors.load', 'Failed to load offers.'), 'error')\n } finally {\n setLoading(false)\n }\n }, [ensureChannelMetadata, page, search, selectedChannelIds, sorting, t])\n\n React.useEffect(() => {\n void loadOffers()\n }, [loadOffers, scopeVersion, reloadToken])\n\n const handleSearchChange = React.useCallback((value: string) => {\n setSearch(value)\n setPage(1)\n }, [])\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n setFilterValues(values)\n setPage(1)\n }, [])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({})\n setPage(1)\n }, [])\n\n const handleRefresh = React.useCallback(() => {\n setReloadToken((token) => token + 1)\n }, [])\n\n const handleDelete = React.useCallback(async (row: OfferRow) => {\n try {\n await runMutation({\n operation: () =>\n withScopedApiRequestHeaders(\n buildOptimisticLockHeader(row.updatedAt),\n () => deleteCrud('catalog/offers', row.id, {\n errorMessage: t('sales.channels.offers.errors.delete', 'Failed to delete offer.'),\n }),\n ),\n context: mutationContext,\n mutationPayload: { action: 'delete', id: row.id },\n })\n flash(t('sales.channels.offers.messages.deleted', 'Offer deleted.'), 'success')\n handleRefresh()\n } catch (err) {\n if (surfaceRecordConflict(err, t)) { handleRefresh(); return }\n logger.error('sales.channels.offers.delete', { err })\n }\n }, [handleRefresh, mutationContext, runMutation, t])\n\n const tableTitle = (\n <div className=\"flex flex-col gap-1\">\n <span>{t('sales.channels.offers.listTitle', 'Sales channel offers')}</span>\n <span className=\"text-sm font-normal text-muted-foreground\">\n {t('sales.channels.offers.listSubtitle', 'Review product overrides across every sales channel.')}\n </span>\n </div>\n )\n\n return (\n <Page>\n <PageBody>\n <DataTable<OfferRow>\n title={tableTitle}\n columns={columns}\n data={rows}\n isLoading={isLoading}\n sorting={sorting}\n onSortingChange={setSorting}\n searchValue={search}\n onSearchChange={handleSearchChange}\n searchPlaceholder={t('sales.channels.offers.table.search', 'Search offers\u2026')}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n onPageChange: setPage,\n }}\n refreshButton={{\n label: t('sales.channels.offers.table.refresh', 'Refresh'),\n onRefresh: handleRefresh,\n isRefreshing: isLoading,\n }}\n rowActions={(row) => {\n if (!row.channelId) return null\n return (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('sales.channels.offers.actions.edit', 'Edit'),\n href: `/backend/sales/channels/${row.channelId}/offers/${row.id}/edit`,\n },\n {\n id: 'delete',\n label: t('sales.channels.offers.actions.delete', 'Delete'),\n onSelect: () => handleDelete(row),\n destructive: true,\n },\n ]}\n />\n )\n }}\n onRowClick={(row) => {\n if (!row.channelId) return\n router.push(`/backend/sales/channels/${row.channelId}/offers/${row.id}/edit`)\n }}\n emptyState={\n <div className=\"py-10 text-center text-sm text-muted-foreground\">\n {t('sales.channels.offers.table.emptyAll', 'No offers available yet.')}\n </div>\n }\n />\n </PageBody>\n </Page>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -15,6 +15,8 @@ import { buildOptimisticLockHeader, extractOptimisticLockConflict } from "@open-
|
|
|
15
15
|
import { useGuardedMutation } from "@open-mercato/ui/backend/injection/useGuardedMutation";
|
|
16
16
|
import { useOrganizationScopeVersion } from "@open-mercato/shared/lib/frontend/useOrganizationScope";
|
|
17
17
|
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
18
|
+
import { createLogger } from "@open-mercato/shared/lib/logger";
|
|
19
|
+
const logger = createLogger("sales");
|
|
18
20
|
const PAGE_SIZE = 25;
|
|
19
21
|
const SAVE_CONTEXT_ID = "sales-channels-list";
|
|
20
22
|
function SalesChannelsPage() {
|
|
@@ -97,7 +99,7 @@ function SalesChannelsPage() {
|
|
|
97
99
|
setTotal(typeof payload.total === "number" ? payload.total : items.length);
|
|
98
100
|
setTotalPages(typeof payload.totalPages === "number" ? payload.totalPages : Math.max(1, Math.ceil(items.length / PAGE_SIZE)));
|
|
99
101
|
} catch (err) {
|
|
100
|
-
|
|
102
|
+
logger.error("sales.channels.list", { err });
|
|
101
103
|
flash(t("sales.channels.table.errors.load", "Failed to load channels."), "error");
|
|
102
104
|
} finally {
|
|
103
105
|
setLoading(false);
|
|
@@ -136,7 +138,7 @@ function SalesChannelsPage() {
|
|
|
136
138
|
handleRefresh();
|
|
137
139
|
return;
|
|
138
140
|
}
|
|
139
|
-
|
|
141
|
+
logger.error("sales.channels.delete", { err });
|
|
140
142
|
}
|
|
141
143
|
}, [handleRefresh, mutationContext, runMutation, t]);
|
|
142
144
|
return /* @__PURE__ */ jsx(Page, { children: /* @__PURE__ */ jsx(PageBody, { children: /* @__PURE__ */ jsx(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/modules/sales/backend/sales/channels/page.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useRouter } from 'next/navigation'\nimport Link from 'next/link'\nimport type { ColumnDef, SortingState } from '@tanstack/react-table'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, withDataTableNamespaces } from '@open-mercato/ui/backend/DataTable'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { BooleanIcon } from '@open-mercato/ui/backend/ValueIcons'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { buildOptimisticLockHeader, extractOptimisticLockConflict } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\ntype ChannelRow = {\n id: string\n name: string\n code: string | null\n description: string | null\n offerCount: number\n isActive: boolean\n updatedAt: string | null\n}\n\ntype ChannelsResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n totalPages?: number\n}\n\nconst PAGE_SIZE = 25\n\nconst SAVE_CONTEXT_ID = 'sales-channels-list'\n\nexport default function SalesChannelsPage() {\n const t = useT()\n const router = useRouter()\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: SAVE_CONTEXT_ID,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const mutationContext = React.useMemo(\n () => ({\n formId: SAVE_CONTEXT_ID,\n resourceKind: 'sales.channels',\n retryLastMutation,\n }),\n [retryLastMutation],\n )\n const scopeVersion = useOrganizationScopeVersion()\n const [rows, setRows] = React.useState<ChannelRow[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [sorting, setSorting] = React.useState<SortingState>([])\n const [search, setSearch] = React.useState('')\n const [isLoading, setLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n\n const columns = React.useMemo<ColumnDef<ChannelRow>[]>(() => [\n {\n accessorKey: 'name',\n header: t('sales.channels.table.name', 'Name'),\n cell: ({ row }) => (\n <div className=\"flex flex-col\">\n <span className=\"font-medium\">{row.original.name}</span>\n {row.original.description ? (\n <span className=\"text-xs text-muted-foreground\">{row.original.description}</span>\n ) : null}\n </div>\n ),\n meta: { sticky: true },\n },\n {\n accessorKey: 'code',\n header: t('sales.channels.table.code', 'Code'),\n cell: ({ row }) => row.original.code ? (\n <span className=\"font-mono text-xs\">{row.original.code}</span>\n ) : (\n <span className=\"text-xs text-muted-foreground\">\u2014</span>\n ),\n },\n {\n accessorKey: 'offerCount',\n header: t('sales.channels.table.offers', 'Product offers'),\n cell: ({ row }) => (\n <span className=\"text-sm font-semibold\">{row.original.offerCount}</span>\n ),\n },\n {\n accessorKey: 'isActive',\n header: t('sales.channels.table.active', 'Active'),\n cell: ({ row }) => <BooleanIcon value={row.original.isActive} />,\n },\n {\n accessorKey: 'updatedAt',\n header: t('sales.channels.table.updated', 'Updated'),\n cell: ({ row }) =>\n row.original.updatedAt\n ? <span className=\"text-xs text-muted-foreground\">{new Date(row.original.updatedAt).toLocaleDateString()}</span>\n : <span className=\"text-xs text-muted-foreground\">\u2014</span>,\n },\n ], [t])\n\n const loadChannels = React.useCallback(async () => {\n setLoading(true)\n try {\n const params = new URLSearchParams({\n page: String(page),\n pageSize: String(PAGE_SIZE),\n })\n const sort = sorting[0]\n if (sort?.id) {\n params.set('sortField', sort.id)\n params.set('sortDir', sort.desc ? 'desc' : 'asc')\n }\n if (search.trim().length) {\n params.set('search', search.trim())\n }\n const payload = await readApiResultOrThrow<ChannelsResponse>(\n `/api/sales/channels?${params.toString()}`,\n undefined,\n { errorMessage: t('sales.channels.table.errors.load', 'Failed to load channels.') },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n setRows(items.map(mapApiChannel))\n setTotal(typeof payload.total === 'number' ? payload.total : items.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : Math.max(1, Math.ceil(items.length / PAGE_SIZE)))\n } catch (err) {\n console.error('sales.channels.list', err)\n flash(t('sales.channels.table.errors.load', 'Failed to load channels.'), 'error')\n } finally {\n setLoading(false)\n }\n }, [page, search, sorting, t])\n\n React.useEffect(() => {\n void loadChannels()\n }, [loadChannels, scopeVersion, reloadToken])\n\n const handleSearchChange = React.useCallback((value: string) => {\n setSearch(value)\n setPage(1)\n }, [])\n\n const handleRefresh = React.useCallback(() => {\n setReloadToken((token) => token + 1)\n }, [])\n\n const handleDelete = React.useCallback(async (row: ChannelRow) => {\n try {\n await runMutation({\n operation: () =>\n withScopedApiRequestHeaders(\n buildOptimisticLockHeader(row.updatedAt),\n () => deleteCrud('sales/channels', row.id, {\n errorMessage: t('sales.channels.table.errors.delete', 'Failed to delete channel.'),\n }),\n ),\n context: mutationContext,\n mutationPayload: { action: 'delete', id: row.id },\n })\n flash(t('sales.channels.table.messages.deleted', 'Channel deleted.'), 'success')\n handleRefresh()\n } catch (err) {\n if (extractOptimisticLockConflict(err)) {\n // Someone edited the channel after this list loaded \u2014 refuse the\n // stale delete, surface the conflict, and reload so the row reflects\n // the latest server state (QA #2055 channel edit/delete broken state).\n flash(\n t('ui.forms.flash.recordModified', 'This record was modified by someone else. Refresh and try again.'),\n 'error',\n )\n handleRefresh()\n return\n }\n console.error('sales.channels.delete', err)\n }\n }, [handleRefresh, mutationContext, runMutation, t])\n\n return (\n <Page>\n <PageBody>\n <DataTable<ChannelRow>\n title={(\n <div className=\"flex flex-col\">\n <span>{t('sales.channels.nav.title', 'Sales channels')}</span>\n <span className=\"text-sm font-normal text-muted-foreground\">\n {t('sales.channels.table.subtitle', 'Organize catalog offers per marketplace or storefront.')}\n </span>\n </div>\n )}\n actions={(\n <Button asChild>\n <Link href=\"/backend/sales/channels/create\">\n {t('sales.channels.actions.create', 'Add channel')}\n </Link>\n </Button>\n )}\n columns={columns}\n data={rows}\n sorting={sorting}\n onSortingChange={setSorting}\n isLoading={isLoading}\n searchValue={search}\n onSearchChange={handleSearchChange}\n searchPlaceholder={t('sales.channels.table.search', 'Search channels\u2026')}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n onPageChange: setPage,\n }}\n refreshButton={{\n label: t('sales.channels.table.refresh', 'Refresh'),\n onRefresh: handleRefresh,\n isRefreshing: isLoading,\n }}\n rowActions={(row) => (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('sales.channels.table.actions.edit', 'Edit'),\n href: `/backend/sales/channels/${row.id}/edit`,\n },\n {\n id: 'delete',\n label: t('sales.channels.table.actions.delete', 'Delete'),\n onSelect: () => handleDelete(row),\n },\n ]}\n />\n )}\n onRowClick={(row) => router.push(`/backend/sales/channels/${row.id}/edit`)}\n emptyState={\n <div className=\"py-10 text-center text-sm text-muted-foreground\">\n {t('sales.channels.table.empty', 'No channels yet.')}\n </div>\n }\n />\n </PageBody>\n </Page>\n )\n}\n\nfunction mapApiChannel(item: Record<string, unknown>): ChannelRow {\n const id = typeof item.id === 'string' ? item.id : ''\n return withDataTableNamespaces({\n id,\n name: typeof item.name === 'string' ? item.name : id,\n code: typeof item.code === 'string' && item.code.length ? item.code : null,\n description: typeof item.description === 'string' && item.description.length ? item.description : null,\n offerCount: typeof item.offerCount === 'number'\n ? item.offerCount\n : typeof item.offer_count === 'number'\n ? item.offer_count\n : 0,\n isActive: item.isActive === true || item.is_active === true,\n updatedAt: typeof item.updatedAt === 'string'\n ? item.updatedAt\n : typeof item.updated_at === 'string'\n ? item.updated_at\n : null,\n }, item)\n}\n"],
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useRouter } from 'next/navigation'\nimport Link from 'next/link'\nimport type { ColumnDef, SortingState } from '@tanstack/react-table'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, withDataTableNamespaces } from '@open-mercato/ui/backend/DataTable'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { BooleanIcon } from '@open-mercato/ui/backend/ValueIcons'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { buildOptimisticLockHeader, extractOptimisticLockConflict } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('sales')\n\ntype ChannelRow = {\n id: string\n name: string\n code: string | null\n description: string | null\n offerCount: number\n isActive: boolean\n updatedAt: string | null\n}\n\ntype ChannelsResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n totalPages?: number\n}\n\nconst PAGE_SIZE = 25\n\nconst SAVE_CONTEXT_ID = 'sales-channels-list'\n\nexport default function SalesChannelsPage() {\n const t = useT()\n const router = useRouter()\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: SAVE_CONTEXT_ID,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const mutationContext = React.useMemo(\n () => ({\n formId: SAVE_CONTEXT_ID,\n resourceKind: 'sales.channels',\n retryLastMutation,\n }),\n [retryLastMutation],\n )\n const scopeVersion = useOrganizationScopeVersion()\n const [rows, setRows] = React.useState<ChannelRow[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [sorting, setSorting] = React.useState<SortingState>([])\n const [search, setSearch] = React.useState('')\n const [isLoading, setLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n\n const columns = React.useMemo<ColumnDef<ChannelRow>[]>(() => [\n {\n accessorKey: 'name',\n header: t('sales.channels.table.name', 'Name'),\n cell: ({ row }) => (\n <div className=\"flex flex-col\">\n <span className=\"font-medium\">{row.original.name}</span>\n {row.original.description ? (\n <span className=\"text-xs text-muted-foreground\">{row.original.description}</span>\n ) : null}\n </div>\n ),\n meta: { sticky: true },\n },\n {\n accessorKey: 'code',\n header: t('sales.channels.table.code', 'Code'),\n cell: ({ row }) => row.original.code ? (\n <span className=\"font-mono text-xs\">{row.original.code}</span>\n ) : (\n <span className=\"text-xs text-muted-foreground\">\u2014</span>\n ),\n },\n {\n accessorKey: 'offerCount',\n header: t('sales.channels.table.offers', 'Product offers'),\n cell: ({ row }) => (\n <span className=\"text-sm font-semibold\">{row.original.offerCount}</span>\n ),\n },\n {\n accessorKey: 'isActive',\n header: t('sales.channels.table.active', 'Active'),\n cell: ({ row }) => <BooleanIcon value={row.original.isActive} />,\n },\n {\n accessorKey: 'updatedAt',\n header: t('sales.channels.table.updated', 'Updated'),\n cell: ({ row }) =>\n row.original.updatedAt\n ? <span className=\"text-xs text-muted-foreground\">{new Date(row.original.updatedAt).toLocaleDateString()}</span>\n : <span className=\"text-xs text-muted-foreground\">\u2014</span>,\n },\n ], [t])\n\n const loadChannels = React.useCallback(async () => {\n setLoading(true)\n try {\n const params = new URLSearchParams({\n page: String(page),\n pageSize: String(PAGE_SIZE),\n })\n const sort = sorting[0]\n if (sort?.id) {\n params.set('sortField', sort.id)\n params.set('sortDir', sort.desc ? 'desc' : 'asc')\n }\n if (search.trim().length) {\n params.set('search', search.trim())\n }\n const payload = await readApiResultOrThrow<ChannelsResponse>(\n `/api/sales/channels?${params.toString()}`,\n undefined,\n { errorMessage: t('sales.channels.table.errors.load', 'Failed to load channels.') },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n setRows(items.map(mapApiChannel))\n setTotal(typeof payload.total === 'number' ? payload.total : items.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : Math.max(1, Math.ceil(items.length / PAGE_SIZE)))\n } catch (err) {\n logger.error('sales.channels.list', { err })\n flash(t('sales.channels.table.errors.load', 'Failed to load channels.'), 'error')\n } finally {\n setLoading(false)\n }\n }, [page, search, sorting, t])\n\n React.useEffect(() => {\n void loadChannels()\n }, [loadChannels, scopeVersion, reloadToken])\n\n const handleSearchChange = React.useCallback((value: string) => {\n setSearch(value)\n setPage(1)\n }, [])\n\n const handleRefresh = React.useCallback(() => {\n setReloadToken((token) => token + 1)\n }, [])\n\n const handleDelete = React.useCallback(async (row: ChannelRow) => {\n try {\n await runMutation({\n operation: () =>\n withScopedApiRequestHeaders(\n buildOptimisticLockHeader(row.updatedAt),\n () => deleteCrud('sales/channels', row.id, {\n errorMessage: t('sales.channels.table.errors.delete', 'Failed to delete channel.'),\n }),\n ),\n context: mutationContext,\n mutationPayload: { action: 'delete', id: row.id },\n })\n flash(t('sales.channels.table.messages.deleted', 'Channel deleted.'), 'success')\n handleRefresh()\n } catch (err) {\n if (extractOptimisticLockConflict(err)) {\n // Someone edited the channel after this list loaded \u2014 refuse the\n // stale delete, surface the conflict, and reload so the row reflects\n // the latest server state (QA #2055 channel edit/delete broken state).\n flash(\n t('ui.forms.flash.recordModified', 'This record was modified by someone else. Refresh and try again.'),\n 'error',\n )\n handleRefresh()\n return\n }\n logger.error('sales.channels.delete', { err })\n }\n }, [handleRefresh, mutationContext, runMutation, t])\n\n return (\n <Page>\n <PageBody>\n <DataTable<ChannelRow>\n title={(\n <div className=\"flex flex-col\">\n <span>{t('sales.channels.nav.title', 'Sales channels')}</span>\n <span className=\"text-sm font-normal text-muted-foreground\">\n {t('sales.channels.table.subtitle', 'Organize catalog offers per marketplace or storefront.')}\n </span>\n </div>\n )}\n actions={(\n <Button asChild>\n <Link href=\"/backend/sales/channels/create\">\n {t('sales.channels.actions.create', 'Add channel')}\n </Link>\n </Button>\n )}\n columns={columns}\n data={rows}\n sorting={sorting}\n onSortingChange={setSorting}\n isLoading={isLoading}\n searchValue={search}\n onSearchChange={handleSearchChange}\n searchPlaceholder={t('sales.channels.table.search', 'Search channels\u2026')}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n onPageChange: setPage,\n }}\n refreshButton={{\n label: t('sales.channels.table.refresh', 'Refresh'),\n onRefresh: handleRefresh,\n isRefreshing: isLoading,\n }}\n rowActions={(row) => (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('sales.channels.table.actions.edit', 'Edit'),\n href: `/backend/sales/channels/${row.id}/edit`,\n },\n {\n id: 'delete',\n label: t('sales.channels.table.actions.delete', 'Delete'),\n onSelect: () => handleDelete(row),\n },\n ]}\n />\n )}\n onRowClick={(row) => router.push(`/backend/sales/channels/${row.id}/edit`)}\n emptyState={\n <div className=\"py-10 text-center text-sm text-muted-foreground\">\n {t('sales.channels.table.empty', 'No channels yet.')}\n </div>\n }\n />\n </PageBody>\n </Page>\n )\n}\n\nfunction mapApiChannel(item: Record<string, unknown>): ChannelRow {\n const id = typeof item.id === 'string' ? item.id : ''\n return withDataTableNamespaces({\n id,\n name: typeof item.name === 'string' ? item.name : id,\n code: typeof item.code === 'string' && item.code.length ? item.code : null,\n description: typeof item.description === 'string' && item.description.length ? item.description : null,\n offerCount: typeof item.offerCount === 'number'\n ? item.offerCount\n : typeof item.offer_count === 'number'\n ? item.offer_count\n : 0,\n isActive: item.isActive === true || item.is_active === true,\n updatedAt: typeof item.updatedAt === 'string'\n ? item.updatedAt\n : typeof item.updated_at === 'string'\n ? item.updated_at\n : null,\n }, item)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|