@open-mercato/core 0.6.7 → 0.6.8-develop.6874.1.982d6097d8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +2 -2
- package/AGENTS.md +3 -3
- package/agentic/standalone-guide.md +13 -0
- package/dist/bootstrap.js +16 -1
- package/dist/bootstrap.js.map +2 -2
- package/dist/generated/entities/attachment_quota_reservation/index.js +33 -0
- package/dist/generated/entities/attachment_quota_reservation/index.js.map +7 -0
- package/dist/generated/entities/customer_deal_person_link/index.js +2 -0
- package/dist/generated/entities/customer_deal_person_link/index.js.map +2 -2
- package/dist/generated/entities/customer_user_invitation/index.js +2 -0
- package/dist/generated/entities/customer_user_invitation/index.js.map +2 -2
- package/dist/generated/entities/gateway_payment_operation/index.js +2 -0
- package/dist/generated/entities/gateway_payment_operation/index.js.map +2 -2
- package/dist/generated/entities/gateway_transaction/index.js +2 -0
- package/dist/generated/entities/gateway_transaction/index.js.map +2 -2
- package/dist/generated/entities/organization/index.js +2 -0
- package/dist/generated/entities/organization/index.js.map +2 -2
- package/dist/generated/entities/resources_resource/index.js +2 -0
- package/dist/generated/entities/resources_resource/index.js.map +2 -2
- package/dist/generated/entities.ids.generated.js +3 -1
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +23 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/helpers/integration/salesFixtures.js +31 -2
- package/dist/helpers/integration/salesFixtures.js.map +2 -2
- package/dist/helpers/integration/salesUi.js +5 -0
- package/dist/helpers/integration/salesUi.js.map +2 -2
- package/dist/modules/api_keys/backend/api-keys/page.js +2 -1
- package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
- package/dist/modules/api_keys/extension-points.js +16 -0
- package/dist/modules/api_keys/extension-points.js.map +7 -0
- package/dist/modules/attachments/api/route.js +120 -10
- package/dist/modules/attachments/api/route.js.map +2 -2
- package/dist/modules/attachments/backend/config/attachments/page.js +1 -1
- package/dist/modules/attachments/backend/config/attachments/page.js.map +2 -2
- package/dist/modules/attachments/data/entities.js +67 -1
- package/dist/modules/attachments/data/entities.js.map +2 -2
- package/dist/modules/attachments/di.js +7 -1
- package/dist/modules/attachments/di.js.map +2 -2
- package/dist/modules/attachments/fields/attachment.js +1 -1
- package/dist/modules/attachments/fields/attachment.js.map +2 -2
- package/dist/modules/attachments/lib/drivers/index.js.map +1 -1
- package/dist/modules/attachments/lib/drivers/localDriver.js +19 -6
- package/dist/modules/attachments/lib/drivers/localDriver.js.map +2 -2
- package/dist/modules/attachments/lib/quota-recovery-queue.js +9 -0
- package/dist/modules/attachments/lib/quota-recovery-queue.js.map +7 -0
- package/dist/modules/attachments/lib/quota-service.js +224 -0
- package/dist/modules/attachments/lib/quota-service.js.map +7 -0
- package/dist/modules/attachments/lib/upload-limits.js +33 -0
- package/dist/modules/attachments/lib/upload-limits.js.map +2 -2
- package/dist/modules/attachments/migrations/Migration20260709234741_attachments.js +13 -0
- package/dist/modules/attachments/migrations/Migration20260709234741_attachments.js.map +7 -0
- package/dist/modules/attachments/workers/quota-recovery.js +45 -0
- package/dist/modules/attachments/workers/quota-recovery.js.map +7 -0
- package/dist/modules/audit_logs/api/audit-logs/access/route.js +5 -1
- package/dist/modules/audit_logs/api/audit-logs/access/route.js.map +2 -2
- package/dist/modules/audit_logs/api/audit-logs/actions/export/route.js +5 -1
- package/dist/modules/audit_logs/api/audit-logs/actions/export/route.js.map +2 -2
- package/dist/modules/audit_logs/api/audit-logs/actions/route.js +5 -1
- package/dist/modules/audit_logs/api/audit-logs/actions/route.js.map +2 -2
- package/dist/modules/audit_logs/api/audit-logs/readScope.js +12 -0
- package/dist/modules/audit_logs/api/audit-logs/readScope.js.map +7 -0
- package/dist/modules/audit_logs/components/AccessLogsTable.js +2 -1
- package/dist/modules/audit_logs/components/AccessLogsTable.js.map +2 -2
- package/dist/modules/audit_logs/components/AuditLogsActions.js +3 -2
- package/dist/modules/audit_logs/components/AuditLogsActions.js.map +2 -2
- package/dist/modules/audit_logs/extension-points.js +14 -0
- package/dist/modules/audit_logs/extension-points.js.map +7 -0
- package/dist/modules/auth/api/admin/nav.js +17 -4
- package/dist/modules/auth/api/admin/nav.js.map +2 -2
- package/dist/modules/auth/api/profile/route.js +8 -2
- package/dist/modules/auth/api/profile/route.js.map +2 -2
- package/dist/modules/auth/api/users/route.js +8 -19
- package/dist/modules/auth/api/users/route.js.map +2 -2
- package/dist/modules/auth/backend/auth/profile/page.js.map +2 -2
- package/dist/modules/auth/backend/profile/change-password/page.js.map +2 -2
- package/dist/modules/auth/backend/roles/page.js +2 -1
- package/dist/modules/auth/backend/roles/page.js.map +2 -2
- package/dist/modules/auth/backend/settings/page.js +14 -9
- package/dist/modules/auth/backend/settings/page.js.map +2 -2
- package/dist/modules/auth/backend/users/page.js +2 -1
- package/dist/modules/auth/backend/users/page.js.map +2 -2
- package/dist/modules/auth/cli.js +1 -1
- package/dist/modules/auth/cli.js.map +2 -2
- package/dist/modules/auth/components/UserConsentsPanel.js +9 -9
- package/dist/modules/auth/components/UserConsentsPanel.js.map +2 -2
- package/dist/modules/auth/extension-points.js +21 -0
- package/dist/modules/auth/extension-points.js.map +7 -0
- package/dist/modules/auth/frontend/login.js +7 -3
- package/dist/modules/auth/frontend/login.js.map +2 -2
- package/dist/modules/auth/frontend/reset.js +2 -2
- package/dist/modules/auth/frontend/reset.js.map +2 -2
- package/dist/modules/auth/lib/backendChrome.js +45 -29
- package/dist/modules/auth/lib/backendChrome.js.map +2 -2
- package/dist/modules/auth/lib/setup-app.js +17 -2
- package/dist/modules/auth/lib/setup-app.js.map +2 -2
- package/dist/modules/auth/lib/tenantAccess.js +7 -0
- package/dist/modules/auth/lib/tenantAccess.js.map +2 -2
- package/dist/modules/auth/services/rbacService.js +29 -44
- package/dist/modules/auth/services/rbacService.js.map +2 -2
- package/dist/modules/business_rules/api/openmercato-call-options/route.js +85 -0
- package/dist/modules/business_rules/api/openmercato-call-options/route.js.map +7 -0
- package/dist/modules/business_rules/api/rules/route.js +71 -4
- package/dist/modules/business_rules/api/rules/route.js.map +2 -2
- package/dist/modules/business_rules/backend/rules/page.js +2 -1
- package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
- package/dist/modules/business_rules/components/ActionBuilder.js +47 -4
- package/dist/modules/business_rules/components/ActionBuilder.js.map +3 -3
- package/dist/modules/business_rules/components/ActionRow.js +106 -16
- package/dist/modules/business_rules/components/ActionRow.js.map +2 -2
- package/dist/modules/business_rules/components/ConditionRow.js +8 -4
- package/dist/modules/business_rules/components/ConditionRow.js.map +2 -2
- package/dist/modules/business_rules/components/utils/actionValidation.js +6 -0
- package/dist/modules/business_rules/components/utils/actionValidation.js.map +2 -2
- package/dist/modules/business_rules/events.js +13 -0
- package/dist/modules/business_rules/events.js.map +7 -0
- package/dist/modules/business_rules/extension-points.js +13 -0
- package/dist/modules/business_rules/extension-points.js.map +7 -0
- package/dist/modules/business_rules/lib/action-executor.js +148 -0
- package/dist/modules/business_rules/lib/action-executor.js.map +2 -2
- package/dist/modules/business_rules/lib/openmercato-call-options-types.js +5 -0
- package/dist/modules/business_rules/lib/openmercato-call-options-types.js.map +7 -0
- package/dist/modules/business_rules/lib/openmercato-call-options.js +231 -0
- package/dist/modules/business_rules/lib/openmercato-call-options.js.map +7 -0
- package/dist/modules/business_rules/lib/rule-engine.js +5 -1
- package/dist/modules/business_rules/lib/rule-engine.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js +6 -5
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/create/page.js +7 -6
- package/dist/modules/catalog/backend/catalog/products/create/page.js.map +2 -2
- package/dist/modules/catalog/components/PriceKindSettings.js +3 -3
- package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js +2 -1
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductCategorizeSection.js +3 -3
- package/dist/modules/catalog/components/products/ProductCategorizeSection.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductMediaManager.js +1 -1
- package/dist/modules/catalog/components/products/ProductMediaManager.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductsDataTable.js +3 -2
- package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
- package/dist/modules/catalog/components/products/VariantBuilder.js +5 -5
- package/dist/modules/catalog/components/products/VariantBuilder.js.map +2 -2
- package/dist/modules/catalog/events.js +1 -0
- package/dist/modules/catalog/events.js.map +2 -2
- package/dist/modules/catalog/extension-points.js +27 -0
- package/dist/modules/catalog/extension-points.js.map +7 -0
- package/dist/modules/catalog/widgets/injection/product-bulk-delete/widget.js +10 -5
- package/dist/modules/catalog/widgets/injection/product-bulk-delete/widget.js.map +2 -2
- package/dist/modules/catalog/widgets/injection/product-seo/widget.js +1 -1
- package/dist/modules/catalog/widgets/injection/product-seo/widget.js.map +2 -2
- package/dist/modules/communication_channels/api/post/test-seed/route.js +52 -2
- package/dist/modules/communication_channels/api/post/test-seed/route.js.map +2 -2
- package/dist/modules/communication_channels/api/post/webhook/[provider]/route.js +11 -1
- 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 +11 -6
- package/dist/modules/communication_channels/api/post/webhooks/gmail/route.js.map +2 -2
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.js +2 -1
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.js.map +2 -2
- package/dist/modules/communication_channels/backend/profile/communication-channels/page.js +8 -7
- package/dist/modules/communication_channels/backend/profile/communication-channels/page.js.map +2 -2
- package/dist/modules/communication_channels/data/enrichers.js +4 -4
- package/dist/modules/communication_channels/data/enrichers.js.map +2 -2
- package/dist/modules/communication_channels/extension-points.js +20 -0
- package/dist/modules/communication_channels/extension-points.js.map +7 -0
- package/dist/modules/communication_channels/lib/access-control.js +2 -2
- package/dist/modules/communication_channels/lib/access-control.js.map +2 -2
- package/dist/modules/configs/backend/config/system-status/page.js +2 -1
- package/dist/modules/configs/backend/config/system-status/page.js.map +2 -2
- package/dist/modules/configs/extension-points.js +18 -0
- package/dist/modules/configs/extension-points.js.map +7 -0
- package/dist/modules/configs/lib/upgrade-actions.js +12 -0
- package/dist/modules/configs/lib/upgrade-actions.js.map +2 -2
- package/dist/modules/currencies/backend/currencies/page.js +2 -1
- package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
- package/dist/modules/currencies/backend/exchange-rates/page.js +2 -1
- package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
- package/dist/modules/currencies/di.js +4 -0
- package/dist/modules/currencies/di.js.map +2 -2
- package/dist/modules/currencies/extension-points.js +14 -0
- package/dist/modules/currencies/extension-points.js.map +7 -0
- package/dist/modules/currencies/services/baseCurrencyService.js +42 -0
- package/dist/modules/currencies/services/baseCurrencyService.js.map +7 -0
- package/dist/modules/customer_accounts/api/admin/users/[id].js +10 -1
- package/dist/modules/customer_accounts/api/admin/users/[id].js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/users-invite.js +63 -4
- package/dist/modules/customer_accounts/api/admin/users-invite.js.map +2 -2
- package/dist/modules/customer_accounts/api/invitations/accept.js +1 -2
- package/dist/modules/customer_accounts/api/invitations/accept.js.map +2 -2
- package/dist/modules/customer_accounts/api/login.js +4 -2
- package/dist/modules/customer_accounts/api/login.js.map +2 -2
- package/dist/modules/customer_accounts/api/magic-link/verify.js +4 -2
- package/dist/modules/customer_accounts/api/magic-link/verify.js.map +2 -2
- package/dist/modules/customer_accounts/api/portal/feature-check.js +5 -4
- package/dist/modules/customer_accounts/api/portal/feature-check.js.map +2 -2
- package/dist/modules/customer_accounts/api/portal/nav.js +6 -4
- package/dist/modules/customer_accounts/api/portal/nav.js.map +2 -2
- package/dist/modules/customer_accounts/api/portal/profile.js +5 -1
- package/dist/modules/customer_accounts/api/portal/profile.js.map +2 -2
- package/dist/modules/customer_accounts/api/portal/sessions-refresh.js +3 -3
- package/dist/modules/customer_accounts/api/portal/sessions-refresh.js.map +2 -2
- package/dist/modules/customer_accounts/api/portal/users-invite.js +22 -2
- package/dist/modules/customer_accounts/api/portal/users-invite.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +2 -1
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +2 -1
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
- package/dist/modules/customer_accounts/data/entities.js +3 -0
- package/dist/modules/customer_accounts/data/entities.js.map +2 -2
- package/dist/modules/customer_accounts/data/validators.js +1 -0
- package/dist/modules/customer_accounts/data/validators.js.map +2 -2
- package/dist/modules/customer_accounts/emails/CustomerInvitationEmail.js +26 -0
- package/dist/modules/customer_accounts/emails/CustomerInvitationEmail.js.map +7 -0
- package/dist/modules/customer_accounts/extension-points.js +14 -0
- package/dist/modules/customer_accounts/extension-points.js.map +7 -0
- package/dist/modules/customer_accounts/lib/customerAuth.js +7 -2
- package/dist/modules/customer_accounts/lib/customerAuth.js.map +2 -2
- package/dist/modules/customer_accounts/lib/customerAuthServer.js +2 -1
- package/dist/modules/customer_accounts/lib/customerAuthServer.js.map +2 -2
- package/dist/modules/customer_accounts/lib/customerEntityOwnership.js +29 -3
- package/dist/modules/customer_accounts/lib/customerEntityOwnership.js.map +2 -2
- package/dist/modules/customer_accounts/lib/customerUrl.js +19 -10
- package/dist/modules/customer_accounts/lib/customerUrl.js.map +2 -2
- package/dist/modules/customer_accounts/lib/invitationEmail.js +35 -0
- package/dist/modules/customer_accounts/lib/invitationEmail.js.map +7 -0
- package/dist/modules/customer_accounts/migrations/Migration20260723120000_customer_accounts.js +13 -0
- package/dist/modules/customer_accounts/migrations/Migration20260723120000_customer_accounts.js.map +7 -0
- package/dist/modules/customer_accounts/services/customerInvitationService.js +32 -2
- package/dist/modules/customer_accounts/services/customerInvitationService.js.map +2 -2
- package/dist/modules/customer_accounts/services/customerRbacService.js +12 -3
- package/dist/modules/customer_accounts/services/customerRbacService.js.map +2 -2
- package/dist/modules/customer_accounts/setup.js +6 -0
- package/dist/modules/customer_accounts/setup.js.map +2 -2
- package/dist/modules/customer_accounts/subscribers/autoLinkCrm.js +47 -7
- package/dist/modules/customer_accounts/subscribers/autoLinkCrm.js.map +2 -2
- package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js +2 -2
- package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js.map +2 -2
- package/dist/modules/customer_accounts/widgets/injection/portal-ai-assistant-trigger/widget.client.js +1 -1
- package/dist/modules/customer_accounts/widgets/injection/portal-ai-assistant-trigger/widget.client.js.map +2 -2
- package/dist/modules/customer_accounts/widgets/injection-table.js +1 -1
- package/dist/modules/customer_accounts/widgets/injection-table.js.map +2 -2
- package/dist/modules/customers/analytics.js +4 -1
- package/dist/modules/customers/analytics.js.map +2 -2
- package/dist/modules/customers/api/companies/[id]/route.js +3 -4
- package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/deals/[id]/people/route.js +4 -2
- package/dist/modules/customers/api/deals/[id]/people/route.js.map +2 -2
- package/dist/modules/customers/api/deals/[id]/route.js +7 -3
- package/dist/modules/customers/api/deals/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/deals/aggregate/route.js +5 -4
- package/dist/modules/customers/api/deals/aggregate/route.js.map +2 -2
- package/dist/modules/customers/api/deals/summary/route.js +14 -119
- package/dist/modules/customers/api/deals/summary/route.js.map +2 -2
- package/dist/modules/customers/api/people/[id]/companies/enriched/route.js +3 -2
- package/dist/modules/customers/api/people/[id]/companies/enriched/route.js.map +2 -2
- package/dist/modules/customers/api/utils.js +21 -24
- package/dist/modules/customers/api/utils.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/[id]/page.js +2 -1
- package/dist/modules/customers/backend/customers/companies/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/page.js +2 -1
- package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +16 -5
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +18 -11
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/page.js +2 -1
- package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/components/QuickDealDialog.js +17 -3
- package/dist/modules/customers/backend/customers/deals/pipeline/components/QuickDealDialog.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/page.js +8 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/[id]/page.js +2 -1
- package/dist/modules/customers/backend/customers/people/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/page.js +2 -1
- package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +26 -10
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/cli.js +28 -11
- package/dist/modules/customers/cli.js.map +2 -2
- package/dist/modules/customers/commands/deals.js +48 -10
- package/dist/modules/customers/commands/deals.js.map +2 -2
- package/dist/modules/customers/commands/people.js +2 -0
- package/dist/modules/customers/commands/people.js.map +2 -2
- package/dist/modules/customers/components/CustomerTodosTable.js +2 -1
- package/dist/modules/customers/components/CustomerTodosTable.js.map +2 -2
- package/dist/modules/customers/components/calendar/CalendarEventEditor.js +1 -1
- package/dist/modules/customers/components/calendar/CalendarEventEditor.js.map +2 -2
- package/dist/modules/customers/components/detail/ActiveDealCard.js +2 -1
- package/dist/modules/customers/components/detail/ActiveDealCard.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivitiesDayStrip.js +2 -3
- package/dist/modules/customers/components/detail/ActivitiesDayStrip.js.map +2 -2
- package/dist/modules/customers/components/detail/CompanyDetailTabs.js +26 -6
- package/dist/modules/customers/components/detail/CompanyDetailTabs.js.map +2 -2
- package/dist/modules/customers/components/detail/CompanyKpiBar.js +6 -5
- package/dist/modules/customers/components/detail/CompanyKpiBar.js.map +2 -2
- package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js +2 -2
- package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/DealDetailTabs.js +30 -8
- package/dist/modules/customers/components/detail/DealDetailTabs.js.map +2 -2
- package/dist/modules/customers/components/detail/DealForm.js +2 -1
- package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
- package/dist/modules/customers/components/detail/DealsSection.js +1 -1
- package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
- package/dist/modules/customers/components/detail/MiniWeekCalendar.js +7 -52
- package/dist/modules/customers/components/detail/MiniWeekCalendar.js.map +2 -2
- package/dist/modules/customers/components/detail/PersonDetailTabs.js +30 -8
- package/dist/modules/customers/components/detail/PersonDetailTabs.js.map +2 -2
- package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +231 -216
- package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/dashboard/helpers.js +4 -3
- package/dist/modules/customers/components/detail/dashboard/helpers.js.map +2 -2
- package/dist/modules/customers/components/detail/legacyActivities.js +69 -0
- package/dist/modules/customers/components/detail/legacyActivities.js.map +7 -0
- package/dist/modules/customers/components/formConfig.js +14 -10
- package/dist/modules/customers/components/formConfig.js.map +2 -2
- package/dist/modules/customers/data/entities.js +8 -0
- package/dist/modules/customers/data/entities.js.map +2 -2
- package/dist/modules/customers/data/validators.js +5 -2
- package/dist/modules/customers/data/validators.js.map +2 -2
- package/dist/modules/customers/extension-points.js +42 -0
- package/dist/modules/customers/extension-points.js.map +7 -0
- package/dist/modules/customers/lib/calendar/format.js +8 -4
- package/dist/modules/customers/lib/calendar/format.js.map +2 -2
- package/dist/modules/customers/lib/dealStatus.js +38 -0
- package/dist/modules/customers/lib/dealStatus.js.map +7 -0
- package/dist/modules/customers/lib/dealsSummaryQueries.js +144 -0
- package/dist/modules/customers/lib/dealsSummaryQueries.js.map +7 -0
- package/dist/modules/customers/lib/optionalBaseCurrency.js +19 -0
- package/dist/modules/customers/lib/optionalBaseCurrency.js.map +7 -0
- package/dist/modules/customers/lib/visibilityFilter.js +6 -4
- package/dist/modules/customers/lib/visibilityFilter.js.map +2 -2
- package/dist/modules/customers/migrations/Migration20260723210000_customers.js +15 -0
- package/dist/modules/customers/migrations/Migration20260723210000_customers.js.map +7 -0
- package/dist/modules/customers/search.js +50 -29
- package/dist/modules/customers/search.js.map +2 -2
- package/dist/modules/customers/utils/phoneDuplicates.js +1 -2
- package/dist/modules/customers/utils/phoneDuplicates.js.map +2 -2
- package/dist/modules/dashboards/api/layout/[itemId]/route.js +6 -3
- package/dist/modules/dashboards/api/layout/[itemId]/route.js.map +2 -2
- package/dist/modules/dashboards/api/layout/route.js +22 -9
- package/dist/modules/dashboards/api/layout/route.js.map +2 -2
- package/dist/modules/dashboards/api/roles/widgets/route.js +9 -3
- package/dist/modules/dashboards/api/roles/widgets/route.js.map +2 -2
- package/dist/modules/dashboards/api/users/widgets/route.js +9 -3
- package/dist/modules/dashboards/api/users/widgets/route.js.map +2 -2
- package/dist/modules/dashboards/api/widgets/catalog.js +6 -3
- package/dist/modules/dashboards/api/widgets/catalog.js.map +2 -2
- package/dist/modules/dashboards/api/widgets/data/batch/route.js +12 -3
- package/dist/modules/dashboards/api/widgets/data/batch/route.js.map +2 -2
- package/dist/modules/dashboards/api/widgets/data/route.js +28 -3
- package/dist/modules/dashboards/api/widgets/data/route.js.map +2 -2
- package/dist/modules/dashboards/api/widgets/data/schema.js +28 -18
- package/dist/modules/dashboards/api/widgets/data/schema.js.map +2 -2
- package/dist/modules/dashboards/components/UnlabelledAmountNotice.js +33 -0
- package/dist/modules/dashboards/components/UnlabelledAmountNotice.js.map +7 -0
- package/dist/modules/dashboards/lib/access.js +5 -3
- package/dist/modules/dashboards/lib/access.js.map +2 -2
- package/dist/modules/dashboards/lib/aggregations.js +113 -46
- package/dist/modules/dashboards/lib/aggregations.js.map +2 -2
- package/dist/modules/dashboards/lib/exactDecimal.js +69 -0
- package/dist/modules/dashboards/lib/exactDecimal.js.map +7 -0
- package/dist/modules/dashboards/lib/formatters.js +84 -11
- package/dist/modules/dashboards/lib/formatters.js.map +2 -2
- package/dist/modules/dashboards/lib/optionalBaseCurrency.js +11 -0
- package/dist/modules/dashboards/lib/optionalBaseCurrency.js.map +7 -0
- package/dist/modules/dashboards/services/widgetDataService.js +316 -14
- package/dist/modules/dashboards/services/widgetDataService.js.map +2 -2
- package/dist/modules/dashboards/subscribers/invalidateWidgetDataCache.js +26 -0
- package/dist/modules/dashboards/subscribers/invalidateWidgetDataCache.js.map +7 -0
- package/dist/modules/dashboards/widgets/dashboard/aov-kpi/widget.client.js +9 -3
- package/dist/modules/dashboards/widgets/dashboard/aov-kpi/widget.client.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/config.js +52 -2
- package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/config.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/widget.client.js +52 -30
- package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/widget.client.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/widget.js +2 -2
- package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/widget.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/revenue-kpi/widget.client.js +9 -3
- 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 +8 -3
- 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 +26 -18
- 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 +22 -14
- 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 +10 -4
- package/dist/modules/dashboards/widgets/dashboard/top-products/widget.client.js.map +2 -2
- package/dist/modules/data_sync/api/mappings/[id]/route.js +22 -9
- package/dist/modules/data_sync/api/mappings/[id]/route.js.map +2 -2
- package/dist/modules/data_sync/api/mappings/route.js +13 -4
- package/dist/modules/data_sync/api/mappings/route.js.map +2 -2
- package/dist/modules/data_sync/api/options.js +7 -2
- package/dist/modules/data_sync/api/options.js.map +2 -2
- package/dist/modules/data_sync/api/run.js +7 -2
- package/dist/modules/data_sync/api/run.js.map +2 -2
- package/dist/modules/data_sync/api/runs/[id]/cancel.js +8 -3
- package/dist/modules/data_sync/api/runs/[id]/cancel.js.map +2 -2
- package/dist/modules/data_sync/api/runs/[id]/retry.js +7 -2
- package/dist/modules/data_sync/api/runs/[id]/retry.js.map +2 -2
- package/dist/modules/data_sync/api/runs/[id]/route.js +8 -3
- package/dist/modules/data_sync/api/runs/[id]/route.js.map +2 -2
- package/dist/modules/data_sync/api/runs.js +7 -2
- package/dist/modules/data_sync/api/runs.js.map +2 -2
- package/dist/modules/data_sync/api/schedules/[id]/route.js +19 -6
- package/dist/modules/data_sync/api/schedules/[id]/route.js.map +2 -2
- package/dist/modules/data_sync/api/schedules/route.js +13 -4
- package/dist/modules/data_sync/api/schedules/route.js.map +2 -2
- package/dist/modules/data_sync/api/validate.js +9 -4
- package/dist/modules/data_sync/api/validate.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/page.js +5 -4
- package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
- package/dist/modules/data_sync/components/IntegrationScheduleTab.js +5 -5
- package/dist/modules/data_sync/components/IntegrationScheduleTab.js.map +2 -2
- package/dist/modules/data_sync/extension-points.js +13 -0
- package/dist/modules/data_sync/extension-points.js.map +7 -0
- package/dist/modules/data_sync/lib/queue-policy.js +15 -0
- package/dist/modules/data_sync/lib/queue-policy.js.map +7 -0
- package/dist/modules/data_sync/lib/queue.js +16 -1
- package/dist/modules/data_sync/lib/queue.js.map +2 -2
- package/dist/modules/data_sync/lib/start-run.js +2 -1
- package/dist/modules/data_sync/lib/start-run.js.map +2 -2
- package/dist/modules/data_sync/lib/sync-engine.js +35 -2
- package/dist/modules/data_sync/lib/sync-engine.js.map +2 -2
- package/dist/modules/data_sync/lib/sync-run-service.js +70 -2
- package/dist/modules/data_sync/lib/sync-run-service.js.map +2 -2
- package/dist/modules/data_sync/workers/sync-export.js +9 -2
- package/dist/modules/data_sync/workers/sync-export.js.map +2 -2
- package/dist/modules/data_sync/workers/sync-import.js +9 -2
- package/dist/modules/data_sync/workers/sync-import.js.map +2 -2
- package/dist/modules/design_system/acl.js +9 -0
- package/dist/modules/design_system/acl.js.map +7 -0
- package/dist/modules/design_system/backend/design-system/page.js +11 -0
- package/dist/modules/design_system/backend/design-system/page.js.map +7 -0
- package/dist/modules/design_system/backend/design-system/page.meta.js +15 -0
- package/dist/modules/design_system/backend/design-system/page.meta.js.map +7 -0
- package/dist/modules/design_system/gallery/components/CodeSnippet.js +52 -0
- package/dist/modules/design_system/gallery/components/CodeSnippet.js.map +7 -0
- package/dist/modules/design_system/gallery/components/EntryCard.js +63 -0
- package/dist/modules/design_system/gallery/components/EntryCard.js.map +7 -0
- package/dist/modules/design_system/gallery/components/GalleryShell.js +163 -0
- package/dist/modules/design_system/gallery/components/GalleryShell.js.map +7 -0
- package/dist/modules/design_system/gallery/components/VariantPreview.js +9 -0
- package/dist/modules/design_system/gallery/components/VariantPreview.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/banners.js +186 -0
- package/dist/modules/design_system/gallery/entries/banners.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/buttons.js +361 -0
- package/dist/modules/design_system/gallery/entries/buttons.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/charts.js +457 -0
- package/dist/modules/design_system/gallery/entries/charts.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/dates.js +306 -0
- package/dist/modules/design_system/gallery/entries/dates.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/detail.js +358 -0
- package/dist/modules/design_system/gallery/entries/detail.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/display.js +785 -0
- package/dist/modules/design_system/gallery/entries/display.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/feedback.js +658 -0
- package/dist/modules/design_system/gallery/entries/feedback.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/filters.js +505 -0
- package/dist/modules/design_system/gallery/entries/filters.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/foundations.js +453 -0
- package/dist/modules/design_system/gallery/entries/foundations.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/icons.js +140 -0
- package/dist/modules/design_system/gallery/entries/icons.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/inputs.js +1217 -0
- package/dist/modules/design_system/gallery/entries/inputs.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/messages.js +334 -0
- package/dist/modules/design_system/gallery/entries/messages.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/navigation.js +475 -0
- package/dist/modules/design_system/gallery/entries/navigation.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/notifications.js +257 -0
- package/dist/modules/design_system/gallery/entries/notifications.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/overlays.js +576 -0
- package/dist/modules/design_system/gallery/entries/overlays.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/scaffolding.js +378 -0
- package/dist/modules/design_system/gallery/entries/scaffolding.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/schedule.js +297 -0
- package/dist/modules/design_system/gallery/entries/schedule.js.map +7 -0
- package/dist/modules/design_system/gallery/registry.js +139 -0
- package/dist/modules/design_system/gallery/registry.js.map +7 -0
- package/dist/modules/design_system/gallery/types.js +1 -0
- package/dist/modules/design_system/gallery/types.js.map +7 -0
- package/dist/modules/design_system/index.js +9 -0
- package/dist/modules/design_system/index.js.map +7 -0
- package/dist/modules/design_system/setup.js +14 -0
- package/dist/modules/design_system/setup.js.map +7 -0
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js +34 -12
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js.map +2 -2
- package/dist/modules/dictionaries/api/openapi.js +15 -2
- package/dist/modules/dictionaries/api/openapi.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionaryEntrySelect.js +1 -1
- package/dist/modules/dictionaries/components/DictionaryEntrySelect.js.map +2 -2
- package/dist/modules/dictionaries/components/hooks/useDictionaryEntries.js +30 -29
- package/dist/modules/dictionaries/components/hooks/useDictionaryEntries.js.map +2 -2
- package/dist/modules/dictionaries/data/validators.js +7 -0
- package/dist/modules/dictionaries/data/validators.js.map +2 -2
- package/dist/modules/dictionaries/lib/clientEntries.js +4 -3
- package/dist/modules/dictionaries/lib/clientEntries.js.map +2 -2
- package/dist/modules/dictionaries/lib/fetchAllEntries.js +43 -0
- package/dist/modules/dictionaries/lib/fetchAllEntries.js.map +7 -0
- package/dist/modules/directory/api/organization-branding/route.js +10 -3
- package/dist/modules/directory/api/organization-branding/route.js.map +2 -2
- package/dist/modules/directory/api/organization-switcher/route.js +84 -20
- package/dist/modules/directory/api/organization-switcher/route.js.map +2 -2
- package/dist/modules/directory/api/organizations/route.js +7 -0
- package/dist/modules/directory/api/organizations/route.js.map +3 -3
- package/dist/modules/directory/api/tenants/route.js +8 -2
- package/dist/modules/directory/api/tenants/route.js.map +2 -2
- package/dist/modules/directory/backend/directory/branding/page.js +31 -8
- package/dist/modules/directory/backend/directory/branding/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js +7 -16
- package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/organizations/page.js +2 -1
- package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/tenants/page.js +2 -1
- package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
- package/dist/modules/directory/commands/organizations.js +8 -1
- package/dist/modules/directory/commands/organizations.js.map +2 -2
- package/dist/modules/directory/commands/tenants.js +6 -0
- package/dist/modules/directory/commands/tenants.js.map +2 -2
- package/dist/modules/directory/data/entities.js +4 -0
- package/dist/modules/directory/data/entities.js.map +2 -2
- package/dist/modules/directory/data/validators.js +2 -0
- package/dist/modules/directory/data/validators.js.map +2 -2
- package/dist/modules/directory/extension-points.js +14 -0
- package/dist/modules/directory/extension-points.js.map +7 -0
- package/dist/modules/directory/migrations/Migration20260626145500_directory_logo_preserve_aspect_ratio.js +13 -0
- package/dist/modules/directory/migrations/Migration20260626145500_directory_logo_preserve_aspect_ratio.js.map +7 -0
- package/dist/modules/directory/subscribers/invalidateOrgScopeCache.js +5 -1
- package/dist/modules/directory/subscribers/invalidateOrgScopeCache.js.map +2 -2
- package/dist/modules/directory/utils/organizationScope.js +11 -3
- package/dist/modules/directory/utils/organizationScope.js.map +2 -2
- package/dist/modules/entities/api/definitions.js +53 -3
- package/dist/modules/entities/api/definitions.js.map +2 -2
- package/dist/modules/entities/api/entities.js +21 -2
- package/dist/modules/entities/api/entities.js.map +2 -2
- package/dist/modules/entities/api/entity-settings.js +59 -9
- package/dist/modules/entities/api/entity-settings.js.map +2 -2
- package/dist/modules/entities/api/records.js +11 -28
- package/dist/modules/entities/api/records.js.map +2 -2
- package/dist/modules/entities/api/sidebar-entities.js +34 -12
- package/dist/modules/entities/api/sidebar-entities.js.map +2 -2
- package/dist/modules/entities/backend/config/settings/page.js +10 -0
- package/dist/modules/entities/backend/config/settings/page.js.map +7 -0
- package/dist/modules/entities/backend/config/settings/page.meta.js +36 -0
- package/dist/modules/entities/backend/config/settings/page.meta.js.map +7 -0
- package/dist/modules/entities/backend/entities/user/[entityId]/page.js +1 -1
- package/dist/modules/entities/backend/entities/user/[entityId]/page.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +23 -4
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/create/page.js +16 -7
- package/dist/modules/entities/backend/entities/user/create/page.js.map +2 -2
- package/dist/modules/entities/cli.js +193 -19
- package/dist/modules/entities/cli.js.map +2 -2
- package/dist/modules/entities/components/EntitySettingsManager.js +136 -0
- package/dist/modules/entities/components/EntitySettingsManager.js.map +7 -0
- package/dist/modules/entities/components/RecordListRelationCell.js +63 -0
- package/dist/modules/entities/components/RecordListRelationCell.js.map +7 -0
- package/dist/modules/entities/components/SystemEntitiesTable.js +2 -1
- package/dist/modules/entities/components/SystemEntitiesTable.js.map +2 -2
- package/dist/modules/entities/components/UserEntitiesTable.js +2 -1
- package/dist/modules/entities/components/UserEntitiesTable.js.map +2 -2
- package/dist/modules/entities/components/recordListRelationDisplays.js +80 -0
- package/dist/modules/entities/components/recordListRelationDisplays.js.map +7 -0
- package/dist/modules/entities/extension-points.js +21 -0
- package/dist/modules/entities/extension-points.js.map +7 -0
- package/dist/modules/entities/lib/entityAcl.js +87 -9
- package/dist/modules/entities/lib/entityAcl.js.map +3 -3
- package/dist/modules/feature_toggles/components/FeatureGuard.js +3 -2
- package/dist/modules/feature_toggles/components/FeatureGuard.js.map +2 -2
- package/dist/modules/feature_toggles/components/FeatureToggleOverrideCard.js +1 -1
- package/dist/modules/feature_toggles/components/FeatureToggleOverrideCard.js.map +2 -2
- package/dist/modules/feature_toggles/components/hooks/staleTime.js +5 -0
- package/dist/modules/feature_toggles/components/hooks/staleTime.js.map +7 -0
- package/dist/modules/feature_toggles/components/hooks/useFeatureFlagBoolean.js +5 -2
- package/dist/modules/feature_toggles/components/hooks/useFeatureFlagBoolean.js.map +2 -2
- package/dist/modules/feature_toggles/components/hooks/useFeatureFlagJson.js +5 -2
- package/dist/modules/feature_toggles/components/hooks/useFeatureFlagJson.js.map +2 -2
- package/dist/modules/feature_toggles/components/hooks/useFeatureFlagNumber.js +5 -2
- package/dist/modules/feature_toggles/components/hooks/useFeatureFlagNumber.js.map +2 -2
- package/dist/modules/feature_toggles/components/hooks/useFeatureFlagString.js +5 -2
- package/dist/modules/feature_toggles/components/hooks/useFeatureFlagString.js.map +2 -2
- package/dist/modules/inbox_ops/ai-tools.js +5 -2
- package/dist/modules/inbox_ops/ai-tools.js.map +2 -2
- package/dist/modules/inbox_ops/api/proposals/[id]/actions/[actionId]/route.js +14 -1
- package/dist/modules/inbox_ops/api/proposals/[id]/actions/[actionId]/route.js.map +2 -2
- package/dist/modules/inbox_ops/api/proposals/route.js +16 -1
- package/dist/modules/inbox_ops/api/proposals/route.js.map +2 -2
- package/dist/modules/inbox_ops/api/webhook/inbound.js +14 -10
- package/dist/modules/inbox_ops/api/webhook/inbound.js.map +2 -2
- package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js +6 -6
- package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js.map +2 -2
- package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js +25 -20
- package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js.map +2 -2
- package/dist/modules/inbox_ops/search.js +15 -4
- package/dist/modules/inbox_ops/search.js.map +2 -2
- package/dist/modules/inbox_ops/subscribers/search-reindex-proposal-created.js +32 -0
- package/dist/modules/inbox_ops/subscribers/search-reindex-proposal-created.js.map +7 -0
- package/dist/modules/integrations/api/[id]/credentials/route.js +11 -5
- package/dist/modules/integrations/api/[id]/credentials/route.js.map +2 -2
- package/dist/modules/integrations/api/[id]/health/route.js +6 -3
- package/dist/modules/integrations/api/[id]/health/route.js.map +2 -2
- package/dist/modules/integrations/api/[id]/route.js +6 -3
- package/dist/modules/integrations/api/[id]/route.js.map +2 -2
- package/dist/modules/integrations/api/[id]/state/route.js +6 -3
- package/dist/modules/integrations/api/[id]/state/route.js.map +2 -2
- package/dist/modules/integrations/api/[id]/version/route.js +6 -3
- package/dist/modules/integrations/api/[id]/version/route.js.map +2 -2
- package/dist/modules/integrations/api/logs/route.js +6 -3
- package/dist/modules/integrations/api/logs/route.js.map +2 -2
- package/dist/modules/integrations/api/route.js +6 -3
- package/dist/modules/integrations/api/route.js.map +2 -2
- package/dist/modules/integrations/api/umes-read.js +2 -2
- package/dist/modules/integrations/api/umes-read.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/[id]/page.js +2 -4
- package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
- package/dist/modules/integrations/extension-points.js +30 -0
- package/dist/modules/integrations/extension-points.js.map +7 -0
- package/dist/modules/integrations/lib/organization-scope.js +2 -9
- package/dist/modules/integrations/lib/organization-scope.js.map +2 -2
- package/dist/modules/integrations/widgets/injection/external-ids/widget.client.js +0 -5
- package/dist/modules/integrations/widgets/injection/external-ids/widget.client.js.map +2 -2
- package/dist/modules/integrations/widgets/injection/external-ids/widget.js +14 -0
- package/dist/modules/integrations/widgets/injection/external-ids/widget.js.map +7 -0
- package/dist/modules/messages/api/[id]/route.js +15 -0
- package/dist/modules/messages/api/[id]/route.js.map +2 -2
- package/dist/modules/messages/api/route.js +77 -8
- package/dist/modules/messages/api/route.js.map +2 -2
- package/dist/modules/messages/components/ComposeMessagePageClient.js +2 -1
- package/dist/modules/messages/components/ComposeMessagePageClient.js.map +2 -2
- package/dist/modules/messages/components/MessageDetailPageClient.js +3 -2
- package/dist/modules/messages/components/MessageDetailPageClient.js.map +2 -2
- package/dist/modules/messages/components/MessagesInboxPageClient.js +2 -1
- package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
- package/dist/modules/messages/components/message-detail/panels/dialogs.js +1 -1
- package/dist/modules/messages/components/message-detail/panels/dialogs.js.map +1 -1
- package/dist/modules/messages/extension-points.js +16 -0
- package/dist/modules/messages/extension-points.js.map +7 -0
- package/dist/modules/messages/lib/participantScope.js +15 -0
- package/dist/modules/messages/lib/participantScope.js.map +7 -0
- package/dist/modules/messages/lib/routeHelpers.js +1 -3
- package/dist/modules/messages/lib/routeHelpers.js.map +2 -2
- package/dist/modules/messages/lib/searchLookup.js +8 -16
- package/dist/modules/messages/lib/searchLookup.js.map +2 -2
- package/dist/modules/messages/search.js +10 -5
- package/dist/modules/messages/search.js.map +2 -2
- package/dist/modules/notifications/api/route.js +83 -4
- package/dist/modules/notifications/api/route.js.map +2 -2
- package/dist/modules/notifications/api/unread-count/route.js +25 -6
- package/dist/modules/notifications/api/unread-count/route.js.map +2 -2
- package/dist/modules/notifications/di.js +1 -1
- package/dist/modules/notifications/di.js.map +2 -2
- package/dist/modules/notifications/events.js +4 -2
- package/dist/modules/notifications/events.js.map +2 -2
- package/dist/modules/notifications/lib/notificationRecipients.js +6 -7
- package/dist/modules/notifications/lib/notificationRecipients.js.map +2 -2
- package/dist/modules/notifications/lib/notificationScope.js +26 -0
- package/dist/modules/notifications/lib/notificationScope.js.map +7 -0
- package/dist/modules/notifications/lib/notificationService.js +48 -4
- package/dist/modules/notifications/lib/notificationService.js.map +2 -2
- package/dist/modules/notifications/lib/routeHelpers.js +16 -2
- package/dist/modules/notifications/lib/routeHelpers.js.map +2 -2
- package/dist/modules/payment_gateways/api/capture/route.js +1 -1
- package/dist/modules/payment_gateways/api/capture/route.js.map +2 -2
- package/dist/modules/payment_gateways/api/sessions/route.js +6 -3
- package/dist/modules/payment_gateways/api/sessions/route.js.map +2 -2
- package/dist/modules/payment_gateways/api/webhook/[provider]/route.js +11 -1
- package/dist/modules/payment_gateways/api/webhook/[provider]/route.js.map +2 -2
- package/dist/modules/payment_gateways/backend/payment-gateways/page.js +3 -2
- package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +2 -2
- package/dist/modules/payment_gateways/data/entities.js +11 -0
- package/dist/modules/payment_gateways/data/entities.js.map +2 -2
- package/dist/modules/payment_gateways/di.js +17 -1
- package/dist/modules/payment_gateways/di.js.map +2 -2
- package/dist/modules/payment_gateways/extension-points.js +19 -0
- package/dist/modules/payment_gateways/extension-points.js.map +7 -0
- package/dist/modules/payment_gateways/lib/capture-ledger.js +183 -0
- package/dist/modules/payment_gateways/lib/capture-ledger.js.map +7 -0
- package/dist/modules/payment_gateways/lib/gateway-service.js +93 -14
- package/dist/modules/payment_gateways/lib/gateway-service.js.map +2 -2
- package/dist/modules/payment_gateways/lib/order-amount-reconciliation.js +58 -0
- package/dist/modules/payment_gateways/lib/order-amount-reconciliation.js.map +7 -0
- package/dist/modules/payment_gateways/lib/payment-operation-idempotency.js +1 -0
- package/dist/modules/payment_gateways/lib/payment-operation-idempotency.js.map +2 -2
- package/dist/modules/payment_gateways/lib/session-idempotency.js +33 -0
- package/dist/modules/payment_gateways/lib/session-idempotency.js.map +2 -2
- package/dist/modules/payment_gateways/migrations/Migration20260725101500_payment_gateways.js +16 -0
- package/dist/modules/payment_gateways/migrations/Migration20260725101500_payment_gateways.js.map +7 -0
- package/dist/modules/payment_gateways/migrations/Migration20260803103035_payment_gateways.js +18 -0
- package/dist/modules/payment_gateways/migrations/Migration20260803103035_payment_gateways.js.map +7 -0
- package/dist/modules/payment_gateways/setup.js +47 -0
- package/dist/modules/payment_gateways/setup.js.map +2 -2
- package/dist/modules/payment_gateways/workers/session-initialization-prune.js +50 -0
- package/dist/modules/payment_gateways/workers/session-initialization-prune.js.map +7 -0
- package/dist/modules/planner/components/AvailabilityRulesEditor.js +4 -4
- package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
- package/dist/modules/planner/components/unavailabilityReasons.js +3 -3
- package/dist/modules/planner/components/unavailabilityReasons.js.map +2 -2
- package/dist/modules/portal/extension-points.js +32 -0
- package/dist/modules/portal/extension-points.js.map +7 -0
- package/dist/modules/portal/frontend/[orgSlug]/portal/dashboard/page.js +3 -3
- package/dist/modules/portal/frontend/[orgSlug]/portal/dashboard/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/invite/page.js +134 -0
- package/dist/modules/portal/frontend/[orgSlug]/portal/invite/page.js.map +7 -0
- package/dist/modules/portal/frontend/[orgSlug]/portal/invite/page.meta.js +11 -0
- package/dist/modules/portal/frontend/[orgSlug]/portal/invite/page.meta.js.map +7 -0
- package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js +4 -4
- package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/page.js +3 -3
- package/dist/modules/portal/frontend/[orgSlug]/portal/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/profile/page.js +3 -3
- package/dist/modules/portal/frontend/[orgSlug]/portal/profile/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js +4 -4
- package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/signup/page.js +4 -4
- package/dist/modules/portal/frontend/[orgSlug]/portal/signup/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/verify/page.js +1 -1
- package/dist/modules/portal/frontend/[orgSlug]/portal/verify/page.js.map +2 -2
- package/dist/modules/portal/lib/navigation.js +7 -0
- package/dist/modules/portal/lib/navigation.js.map +7 -0
- package/dist/modules/progress/lib/progressService.js +2 -0
- package/dist/modules/progress/lib/progressService.js.map +2 -2
- package/dist/modules/progress/lib/progressServiceImpl.js +322 -104
- package/dist/modules/progress/lib/progressServiceImpl.js.map +2 -2
- package/dist/modules/query_index/api/openapi.js +13 -1
- package/dist/modules/query_index/api/openapi.js.map +2 -2
- package/dist/modules/query_index/api/reindex.js +10 -0
- package/dist/modules/query_index/api/reindex.js.map +2 -2
- package/dist/modules/query_index/api/status.js +165 -105
- package/dist/modules/query_index/api/status.js.map +2 -2
- package/dist/modules/query_index/cli.js +125 -1
- package/dist/modules/query_index/cli.js.map +2 -2
- package/dist/modules/query_index/components/QueryIndexesTable.js +130 -42
- package/dist/modules/query_index/components/QueryIndexesTable.js.map +2 -2
- package/dist/modules/query_index/data/entities.js +2 -1
- package/dist/modules/query_index/data/entities.js.map +2 -2
- package/dist/modules/query_index/di.js +3 -0
- package/dist/modules/query_index/di.js.map +2 -2
- package/dist/modules/query_index/events.js +20 -0
- package/dist/modules/query_index/events.js.map +7 -0
- package/dist/modules/query_index/extension-points.js +13 -0
- package/dist/modules/query_index/extension-points.js.map +7 -0
- package/dist/modules/query_index/lib/batch.js +11 -4
- package/dist/modules/query_index/lib/batch.js.map +2 -2
- package/dist/modules/query_index/lib/coverage.js +21 -9
- package/dist/modules/query_index/lib/coverage.js.map +2 -2
- package/dist/modules/query_index/lib/document.js +12 -5
- package/dist/modules/query_index/lib/document.js.map +2 -2
- package/dist/modules/query_index/lib/engine.js +105 -48
- package/dist/modules/query_index/lib/engine.js.map +2 -2
- package/dist/modules/query_index/lib/indexer.js +95 -19
- package/dist/modules/query_index/lib/indexer.js.map +2 -2
- package/dist/modules/query_index/lib/reindexer.js +43 -37
- package/dist/modules/query_index/lib/reindexer.js.map +2 -2
- package/dist/modules/query_index/lib/search-tokens.js +34 -15
- package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
- package/dist/modules/query_index/lib/subscriber-scope.js +2 -3
- package/dist/modules/query_index/lib/subscriber-scope.js.map +2 -2
- package/dist/modules/query_index/migrations/Migration20260731105052_query_index.js +17 -0
- package/dist/modules/query_index/migrations/Migration20260731105052_query_index.js.map +7 -0
- package/dist/modules/query_index/subscribers/coverage_refresh.js +4 -0
- package/dist/modules/query_index/subscribers/coverage_refresh.js.map +2 -2
- package/dist/modules/query_index/subscribers/delete_one.js +53 -1
- package/dist/modules/query_index/subscribers/delete_one.js.map +3 -3
- package/dist/modules/query_index/subscribers/upsert_one.js +60 -0
- package/dist/modules/query_index/subscribers/upsert_one.js.map +3 -3
- package/dist/modules/resources/api/resources.js +2 -0
- package/dist/modules/resources/api/resources.js.map +2 -2
- package/dist/modules/resources/backend/resources/resource-types/page.js +2 -1
- package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/[id]/page.js +3 -2
- package/dist/modules/resources/backend/resources/resources/[id]/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/page.js +2 -1
- package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
- package/dist/modules/resources/commands/resources.js +9 -0
- package/dist/modules/resources/commands/resources.js.map +2 -2
- package/dist/modules/resources/components/detail/dictionaries.js +3 -3
- package/dist/modules/resources/components/detail/dictionaries.js.map +2 -2
- package/dist/modules/resources/data/entities.js +3 -0
- package/dist/modules/resources/data/entities.js.map +2 -2
- package/dist/modules/resources/data/validators.js +6 -2
- package/dist/modules/resources/data/validators.js.map +2 -2
- package/dist/modules/resources/extension-points.js +14 -0
- package/dist/modules/resources/extension-points.js.map +7 -0
- package/dist/modules/resources/lib/seeds.js +16 -9
- package/dist/modules/resources/lib/seeds.js.map +2 -2
- package/dist/modules/resources/migrations/Migration20260608231000.js +13 -0
- package/dist/modules/resources/migrations/Migration20260608231000.js.map +7 -0
- package/dist/modules/sales/analytics.js +7 -3
- package/dist/modules/sales/analytics.js.map +2 -2
- package/dist/modules/sales/api/document-history/route.js +2 -1
- package/dist/modules/sales/api/document-history/route.js.map +2 -2
- package/dist/modules/sales/api/documents/factory.js +14 -3
- package/dist/modules/sales/api/documents/factory.js.map +2 -2
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +11 -3
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/documents/create/page.js +11 -14
- package/dist/modules/sales/backend/sales/documents/create/page.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +184 -23
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/components/documents/ItemsSection.js +31 -11
- package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/LineItemDialog.js +12 -5
- package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentForm.js +48 -2
- package/dist/modules/sales/components/documents/SalesDocumentForm.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js +4 -1
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesOrderDraftLines.js +167 -0
- package/dist/modules/sales/components/documents/SalesOrderDraftLines.js.map +7 -0
- package/dist/modules/sales/components/useSalesChannelsEnabled.js +2 -35
- package/dist/modules/sales/components/useSalesChannelsEnabled.js.map +2 -2
- package/dist/modules/sales/data/validators.js +32 -5
- package/dist/modules/sales/data/validators.js.map +2 -2
- package/dist/modules/sales/di.js +7 -0
- package/dist/modules/sales/di.js.map +2 -2
- package/dist/modules/sales/events.js +1 -0
- package/dist/modules/sales/events.js.map +2 -2
- package/dist/modules/sales/extension-points.js +36 -0
- package/dist/modules/sales/extension-points.js.map +7 -0
- package/dist/modules/sales/lib/historyHelpers.js +69 -1
- package/dist/modules/sales/lib/historyHelpers.js.map +2 -2
- package/dist/modules/sales/services/paymentOrderTotalResolver.js +52 -0
- package/dist/modules/sales/services/paymentOrderTotalResolver.js.map +7 -0
- package/dist/modules/sales/widgets/injection/document-history/widget.client.js +51 -2
- package/dist/modules/sales/widgets/injection/document-history/widget.client.js.map +2 -2
- package/dist/modules/sales/workflows.js +10 -7
- package/dist/modules/sales/workflows.js.map +2 -2
- package/dist/modules/shipping_carriers/api/webhook/[provider]/route.js +11 -1
- package/dist/modules/shipping_carriers/api/webhook/[provider]/route.js.map +2 -2
- package/dist/modules/shipping_carriers/lib/shipment-wizard/components/PackageEditor.js +1 -1
- package/dist/modules/shipping_carriers/lib/shipment-wizard/components/PackageEditor.js.map +1 -1
- package/dist/modules/staff/api/interceptors.js +5 -3
- package/dist/modules/staff/api/interceptors.js.map +2 -2
- package/dist/modules/staff/api/leave-requests.js +45 -42
- package/dist/modules/staff/api/leave-requests.js.map +2 -2
- package/dist/modules/staff/components/detail/dictionaries.js +3 -3
- package/dist/modules/staff/components/detail/dictionaries.js.map +2 -2
- package/dist/modules/sync_excel/api/upload/route.js +15 -2
- package/dist/modules/sync_excel/api/upload/route.js.map +2 -2
- package/dist/modules/sync_excel/widgets/injection/upload-config/widget.client.js +1 -1
- package/dist/modules/sync_excel/widgets/injection/upload-config/widget.client.js.map +2 -2
- package/dist/modules/wms/components/backend/ReleaseReservationDialog.js +1 -1
- package/dist/modules/wms/components/backend/ReleaseReservationDialog.js.map +1 -1
- package/dist/modules/wms/components/backend/WmsConfigurationPage.js +5 -4
- package/dist/modules/wms/components/backend/WmsConfigurationPage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js +4 -3
- package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsLocationDetailPage.js +3 -2
- package/dist/modules/wms/components/backend/WmsLocationDetailPage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsLotDetailPage.js +3 -2
- package/dist/modules/wms/components/backend/WmsLotDetailPage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsLotsListPage.js +2 -1
- package/dist/modules/wms/components/backend/WmsLotsListPage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsSkuDetailPage.js +3 -2
- package/dist/modules/wms/components/backend/WmsSkuDetailPage.js.map +2 -2
- package/dist/modules/wms/extension-points.js +26 -0
- package/dist/modules/wms/extension-points.js.map +7 -0
- package/dist/modules/workflows/backend/definitions/[id]/page.js +2 -2
- package/dist/modules/workflows/backend/definitions/[id]/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/create/page.js +1 -1
- package/dist/modules/workflows/backend/definitions/create/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/page.js +3 -2
- package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js +9 -6
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
- package/dist/modules/workflows/backend/instances/page.js +10 -9
- package/dist/modules/workflows/backend/instances/page.js.map +2 -2
- package/dist/modules/workflows/backend/tasks/page.js +8 -7
- package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
- package/dist/modules/workflows/components/ActivitiesEditor.js +69 -13
- package/dist/modules/workflows/components/ActivitiesEditor.js.map +2 -2
- package/dist/modules/workflows/components/BusinessRulesSelector.js +1 -1
- package/dist/modules/workflows/components/BusinessRulesSelector.js.map +2 -2
- package/dist/modules/workflows/components/DefinitionTriggersEditor.js +3 -3
- package/dist/modules/workflows/components/DefinitionTriggersEditor.js.map +2 -2
- package/dist/modules/workflows/components/EdgeEditDialogCrudForm.js +1 -2
- package/dist/modules/workflows/components/EdgeEditDialogCrudForm.js.map +2 -2
- package/dist/modules/workflows/components/NodeEditDialog.js +3 -3
- package/dist/modules/workflows/components/NodeEditDialog.js.map +2 -2
- package/dist/modules/workflows/components/NodeEditDialogCrudForm.js +4 -5
- package/dist/modules/workflows/components/NodeEditDialogCrudForm.js.map +2 -2
- package/dist/modules/workflows/components/StepsEditor.js +2 -2
- package/dist/modules/workflows/components/StepsEditor.js.map +2 -2
- package/dist/modules/workflows/components/TransitionsEditor.js +207 -165
- package/dist/modules/workflows/components/TransitionsEditor.js.map +2 -2
- package/dist/modules/workflows/components/WorkflowGraphImpl.js +1 -1
- package/dist/modules/workflows/components/WorkflowGraphImpl.js.map +2 -2
- package/dist/modules/workflows/components/WorkflowLegend.js +1 -1
- package/dist/modules/workflows/components/WorkflowLegend.js.map +2 -2
- package/dist/modules/workflows/components/WorkflowSelector.js +1 -1
- package/dist/modules/workflows/components/WorkflowSelector.js.map +2 -2
- package/dist/modules/workflows/components/fields/BusinessRuleConditionsEditor.js +1 -1
- package/dist/modules/workflows/components/fields/BusinessRuleConditionsEditor.js.map +2 -2
- package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js +2 -2
- package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js.map +2 -2
- package/dist/modules/workflows/components/fields/MappingArrayEditor.js +1 -1
- package/dist/modules/workflows/components/fields/MappingArrayEditor.js.map +2 -2
- package/dist/modules/workflows/components/fields/StartPreConditionsEditor.js +1 -1
- package/dist/modules/workflows/components/fields/StartPreConditionsEditor.js.map +2 -2
- package/dist/modules/workflows/components/fields/WorkflowSelectorField.js +4 -4
- package/dist/modules/workflows/components/fields/WorkflowSelectorField.js.map +2 -2
- package/dist/modules/workflows/data/validators.js +34 -1
- package/dist/modules/workflows/data/validators.js.map +3 -3
- package/dist/modules/workflows/events.js +1 -0
- package/dist/modules/workflows/events.js.map +2 -2
- package/dist/modules/workflows/extension-points.js +15 -0
- package/dist/modules/workflows/extension-points.js.map +7 -0
- package/dist/modules/workflows/lib/activity-executor.js +59 -14
- package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
- package/dist/modules/workflows/lib/format-validation-error.js +46 -1
- package/dist/modules/workflows/lib/format-validation-error.js.map +2 -2
- package/dist/modules/workflows/widgets/injection/order-approval/context-keys.js +10 -0
- package/dist/modules/workflows/widgets/injection/order-approval/context-keys.js.map +7 -0
- package/dist/modules/workflows/widgets/injection/order-approval/widget.client.js +21 -10
- package/dist/modules/workflows/widgets/injection/order-approval/widget.client.js.map +2 -2
- package/generated/entities/attachment_quota_reservation/index.ts +15 -0
- package/generated/entities/customer_deal_person_link/index.ts +1 -0
- package/generated/entities/customer_user_invitation/index.ts +1 -0
- package/generated/entities/gateway_payment_operation/index.ts +1 -0
- package/generated/entities/gateway_transaction/index.ts +1 -0
- package/generated/entities/organization/index.ts +1 -0
- package/generated/entities/resources_resource/index.ts +1 -0
- package/generated/entities.ids.generated.ts +3 -1
- package/generated/entity-fields-registry.ts +23 -0
- package/package.json +19 -18
- package/src/bootstrap.ts +17 -2
- package/src/helpers/integration/salesFixtures.ts +34 -2
- package/src/helpers/integration/salesUi.ts +8 -0
- package/src/modules/api_keys/backend/api-keys/page.tsx +2 -1
- package/src/modules/api_keys/extension-points.ts +13 -0
- package/src/modules/api_keys/i18n/ko.json +42 -0
- package/src/modules/attachments/api/route.ts +130 -9
- package/src/modules/attachments/backend/config/attachments/page.tsx +1 -1
- package/src/modules/attachments/data/entities.ts +59 -0
- package/src/modules/attachments/di.ts +9 -1
- package/src/modules/attachments/fields/attachment.tsx +1 -1
- package/src/modules/attachments/i18n/de.json +15 -0
- package/src/modules/attachments/i18n/en.json +15 -0
- package/src/modules/attachments/i18n/es.json +15 -0
- package/src/modules/attachments/i18n/ko.json +175 -0
- package/src/modules/attachments/i18n/pl.json +15 -0
- package/src/modules/attachments/lib/drivers/index.ts +1 -1
- package/src/modules/attachments/lib/drivers/localDriver.ts +23 -8
- package/src/modules/attachments/lib/drivers/types.ts +5 -0
- package/src/modules/attachments/lib/quota-recovery-queue.ts +16 -0
- package/src/modules/attachments/lib/quota-service.ts +442 -0
- package/src/modules/attachments/lib/upload-limits.ts +35 -0
- package/src/modules/attachments/migrations/.snapshot-open-mercato.json +648 -120
- package/src/modules/attachments/migrations/Migration20260709234741_attachments.ts +12 -0
- package/src/modules/attachments/workers/quota-recovery.ts +68 -0
- package/src/modules/audit_logs/api/audit-logs/access/route.ts +5 -0
- package/src/modules/audit_logs/api/audit-logs/actions/export/route.ts +5 -0
- package/src/modules/audit_logs/api/audit-logs/actions/route.ts +5 -0
- package/src/modules/audit_logs/api/audit-logs/readScope.ts +28 -0
- package/src/modules/audit_logs/components/AccessLogsTable.tsx +2 -1
- package/src/modules/audit_logs/components/AuditLogsActions.tsx +3 -2
- package/src/modules/audit_logs/extension-points.ts +11 -0
- package/src/modules/audit_logs/i18n/ko.json +66 -0
- package/src/modules/auth/AGENTS.md +12 -8
- package/src/modules/auth/api/admin/nav.ts +28 -4
- package/src/modules/auth/api/profile/route.ts +8 -2
- package/src/modules/auth/api/users/route.ts +8 -28
- package/src/modules/auth/backend/auth/profile/page.tsx +1 -0
- package/src/modules/auth/backend/profile/change-password/page.tsx +1 -0
- package/src/modules/auth/backend/roles/page.tsx +2 -1
- package/src/modules/auth/backend/settings/page.tsx +17 -8
- package/src/modules/auth/backend/users/page.tsx +2 -1
- package/src/modules/auth/cli.ts +1 -1
- package/src/modules/auth/components/UserConsentsPanel.tsx +9 -9
- package/src/modules/auth/extension-points.ts +18 -0
- package/src/modules/auth/frontend/login.tsx +7 -3
- package/src/modules/auth/frontend/reset.tsx +2 -2
- package/src/modules/auth/i18n/de.json +1 -0
- package/src/modules/auth/i18n/en.json +1 -0
- package/src/modules/auth/i18n/es.json +1 -0
- package/src/modules/auth/i18n/ko.json +255 -0
- package/src/modules/auth/i18n/pl.json +1 -0
- package/src/modules/auth/lib/backendChrome.tsx +71 -33
- package/src/modules/auth/lib/setup-app.ts +21 -2
- package/src/modules/auth/lib/tenantAccess.ts +8 -0
- package/src/modules/auth/services/rbacService.ts +41 -46
- package/src/modules/business_rules/api/openmercato-call-options/route.ts +94 -0
- package/src/modules/business_rules/api/rules/route.ts +92 -4
- package/src/modules/business_rules/backend/rules/page.tsx +2 -1
- package/src/modules/business_rules/components/ActionBuilder.tsx +54 -5
- package/src/modules/business_rules/components/ActionRow.tsx +156 -18
- package/src/modules/business_rules/components/ConditionRow.tsx +9 -6
- package/src/modules/business_rules/components/utils/actionValidation.ts +6 -0
- package/src/modules/business_rules/events.ts +10 -0
- package/src/modules/business_rules/extension-points.ts +10 -0
- package/src/modules/business_rules/i18n/de.json +12 -0
- package/src/modules/business_rules/i18n/en.json +12 -0
- package/src/modules/business_rules/i18n/es.json +12 -0
- package/src/modules/business_rules/i18n/ko.json +396 -0
- package/src/modules/business_rules/i18n/pl.json +12 -0
- package/src/modules/business_rules/lib/action-executor.ts +198 -0
- package/src/modules/business_rules/lib/openmercato-call-options-types.ts +31 -0
- package/src/modules/business_rules/lib/openmercato-call-options.ts +297 -0
- package/src/modules/business_rules/lib/rule-engine.ts +4 -0
- package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +6 -5
- package/src/modules/catalog/backend/catalog/products/create/page.tsx +7 -6
- package/src/modules/catalog/components/PriceKindSettings.tsx +3 -3
- package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +2 -1
- package/src/modules/catalog/components/products/ProductCategorizeSection.tsx +3 -3
- package/src/modules/catalog/components/products/ProductMediaManager.tsx +1 -1
- package/src/modules/catalog/components/products/ProductsDataTable.tsx +3 -2
- package/src/modules/catalog/components/products/VariantBuilder.tsx +5 -5
- package/src/modules/catalog/events.ts +1 -0
- package/src/modules/catalog/extension-points.ts +24 -0
- package/src/modules/catalog/i18n/de.json +18 -0
- package/src/modules/catalog/i18n/en.json +18 -0
- package/src/modules/catalog/i18n/es.json +18 -0
- package/src/modules/catalog/i18n/ko.json +723 -0
- package/src/modules/catalog/i18n/pl.json +18 -0
- package/src/modules/catalog/widgets/injection/product-bulk-delete/widget.ts +15 -5
- package/src/modules/catalog/widgets/injection/product-seo/widget.ts +1 -1
- package/src/modules/communication_channels/api/post/test-seed/route.ts +69 -2
- package/src/modules/communication_channels/api/post/webhook/[provider]/route.ts +11 -1
- package/src/modules/communication_channels/api/post/webhooks/gmail/route.ts +17 -11
- package/src/modules/communication_channels/backend/communication_channels/channels/page.tsx +2 -1
- package/src/modules/communication_channels/backend/profile/communication-channels/page.tsx +8 -7
- package/src/modules/communication_channels/data/enrichers.ts +6 -26
- package/src/modules/communication_channels/extension-points.ts +17 -0
- package/src/modules/communication_channels/i18n/de.json +2 -2
- package/src/modules/communication_channels/i18n/en.json +2 -2
- package/src/modules/communication_channels/i18n/es.json +2 -2
- package/src/modules/communication_channels/i18n/ko.json +138 -0
- package/src/modules/communication_channels/i18n/pl.json +2 -2
- package/src/modules/communication_channels/lib/access-control.ts +3 -3
- package/src/modules/configs/backend/config/system-status/page.tsx +2 -1
- package/src/modules/configs/extension-points.ts +15 -0
- package/src/modules/configs/i18n/ko.json +197 -0
- package/src/modules/configs/lib/upgrade-actions.ts +14 -0
- package/src/modules/currencies/backend/currencies/page.tsx +2 -1
- package/src/modules/currencies/backend/exchange-rates/page.tsx +2 -1
- package/src/modules/currencies/di.ts +4 -1
- package/src/modules/currencies/extension-points.ts +11 -0
- package/src/modules/currencies/i18n/de.json +1 -0
- package/src/modules/currencies/i18n/en.json +1 -0
- package/src/modules/currencies/i18n/es.json +1 -0
- package/src/modules/currencies/i18n/ko.json +160 -0
- package/src/modules/currencies/i18n/pl.json +1 -0
- package/src/modules/currencies/services/baseCurrencyService.ts +59 -0
- package/src/modules/customer_accounts/AGENTS.md +3 -3
- package/src/modules/customer_accounts/api/admin/users/[id].ts +16 -1
- package/src/modules/customer_accounts/api/admin/users-invite.ts +81 -3
- package/src/modules/customer_accounts/api/invitations/accept.ts +1 -2
- package/src/modules/customer_accounts/api/login.ts +4 -2
- package/src/modules/customer_accounts/api/magic-link/verify.ts +4 -2
- package/src/modules/customer_accounts/api/portal/feature-check.ts +5 -7
- package/src/modules/customer_accounts/api/portal/nav.ts +5 -3
- package/src/modules/customer_accounts/api/portal/profile.ts +5 -1
- package/src/modules/customer_accounts/api/portal/sessions-refresh.ts +3 -3
- package/src/modules/customer_accounts/api/portal/users-invite.ts +25 -1
- package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +2 -1
- package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.tsx +2 -2
- package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +2 -1
- package/src/modules/customer_accounts/data/entities.ts +3 -0
- package/src/modules/customer_accounts/data/validators.ts +1 -0
- package/src/modules/customer_accounts/emails/CustomerInvitationEmail.tsx +45 -0
- package/src/modules/customer_accounts/extension-points.ts +11 -0
- package/src/modules/customer_accounts/i18n/de.json +6 -0
- package/src/modules/customer_accounts/i18n/en.json +6 -0
- package/src/modules/customer_accounts/i18n/es.json +6 -0
- package/src/modules/customer_accounts/i18n/ko.json +354 -0
- package/src/modules/customer_accounts/i18n/pl.json +6 -0
- package/src/modules/customer_accounts/lib/customerAuth.ts +8 -2
- package/src/modules/customer_accounts/lib/customerAuthServer.ts +1 -0
- package/src/modules/customer_accounts/lib/customerEntityOwnership.ts +68 -2
- package/src/modules/customer_accounts/lib/customerUrl.ts +27 -11
- package/src/modules/customer_accounts/lib/invitationEmail.ts +42 -0
- package/src/modules/customer_accounts/migrations/.snapshot-open-mercato.json +16 -0
- package/src/modules/customer_accounts/migrations/Migration20260723120000_customer_accounts.ts +13 -0
- package/src/modules/customer_accounts/services/customerInvitationService.ts +56 -3
- package/src/modules/customer_accounts/services/customerRbacService.ts +16 -3
- package/src/modules/customer_accounts/setup.ts +7 -0
- package/src/modules/customer_accounts/subscribers/autoLinkCrm.ts +75 -8
- package/src/modules/customer_accounts/widgets/injection/account-status/widget.client.tsx +2 -2
- package/src/modules/customer_accounts/widgets/injection/portal-ai-assistant-trigger/widget.client.tsx +1 -3
- package/src/modules/customer_accounts/widgets/injection-table.ts +4 -1
- package/src/modules/customers/analytics.ts +3 -0
- package/src/modules/customers/api/companies/[id]/route.ts +3 -4
- package/src/modules/customers/api/deals/[id]/people/route.ts +3 -0
- package/src/modules/customers/api/deals/[id]/route.ts +10 -2
- package/src/modules/customers/api/deals/aggregate/route.ts +5 -4
- package/src/modules/customers/api/deals/summary/route.ts +15 -162
- package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +3 -2
- package/src/modules/customers/api/utils.ts +25 -37
- package/src/modules/customers/backend/customers/companies/[id]/page.tsx +2 -1
- package/src/modules/customers/backend/customers/companies/page.tsx +2 -1
- package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +17 -5
- package/src/modules/customers/backend/customers/deals/[id]/hooks/types.ts +1 -0
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +19 -12
- package/src/modules/customers/backend/customers/deals/page.tsx +2 -1
- package/src/modules/customers/backend/customers/deals/pipeline/components/QuickDealDialog.tsx +35 -3
- package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +11 -2
- package/src/modules/customers/backend/customers/people/[id]/page.tsx +2 -1
- package/src/modules/customers/backend/customers/people/page.tsx +2 -1
- package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +29 -10
- package/src/modules/customers/cli.ts +28 -11
- package/src/modules/customers/commands/deals.ts +50 -9
- package/src/modules/customers/commands/people.ts +3 -0
- package/src/modules/customers/components/CustomerTodosTable.tsx +2 -1
- package/src/modules/customers/components/calendar/CalendarEventEditor.tsx +1 -1
- package/src/modules/customers/components/detail/ActiveDealCard.tsx +2 -1
- package/src/modules/customers/components/detail/ActivitiesDayStrip.tsx +2 -3
- package/src/modules/customers/components/detail/CompanyDetailTabs.tsx +30 -7
- package/src/modules/customers/components/detail/CompanyKpiBar.tsx +6 -5
- package/src/modules/customers/components/detail/ConfirmDealLostDialog.tsx +2 -2
- package/src/modules/customers/components/detail/DealDetailTabs.tsx +34 -9
- package/src/modules/customers/components/detail/DealForm.tsx +5 -1
- package/src/modules/customers/components/detail/DealsSection.tsx +1 -1
- package/src/modules/customers/components/detail/MiniWeekCalendar.tsx +8 -57
- package/src/modules/customers/components/detail/PersonDetailTabs.tsx +34 -9
- package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +29 -14
- package/src/modules/customers/components/detail/dashboard/helpers.ts +4 -3
- package/src/modules/customers/components/detail/legacyActivities.ts +79 -0
- package/src/modules/customers/components/formConfig.tsx +12 -8
- package/src/modules/customers/data/entities.ts +9 -1
- package/src/modules/customers/data/validators.ts +6 -1
- package/src/modules/customers/extension-points.ts +40 -0
- package/src/modules/customers/i18n/de.json +72 -0
- package/src/modules/customers/i18n/en.json +72 -0
- package/src/modules/customers/i18n/es.json +72 -0
- package/src/modules/customers/i18n/ko.json +2855 -0
- package/src/modules/customers/i18n/pl.json +72 -0
- package/src/modules/customers/lib/calendar/format.ts +10 -4
- package/src/modules/customers/lib/dealStatus.ts +48 -0
- package/src/modules/customers/lib/dealsSummaryQueries.ts +211 -0
- package/src/modules/customers/lib/optionalBaseCurrency.ts +34 -0
- package/src/modules/customers/lib/visibilityFilter.ts +7 -5
- package/src/modules/customers/migrations/.snapshot-open-mercato.json +27 -1
- package/src/modules/customers/migrations/Migration20260723210000_customers.ts +15 -0
- package/src/modules/customers/search.ts +59 -27
- package/src/modules/customers/utils/phoneDuplicates.ts +6 -3
- package/src/modules/dashboards/api/layout/[itemId]/route.ts +6 -3
- package/src/modules/dashboards/api/layout/route.ts +22 -9
- package/src/modules/dashboards/api/roles/widgets/route.ts +9 -3
- package/src/modules/dashboards/api/users/widgets/route.ts +9 -3
- package/src/modules/dashboards/api/widgets/catalog.ts +6 -3
- package/src/modules/dashboards/api/widgets/data/batch/route.ts +12 -1
- package/src/modules/dashboards/api/widgets/data/route.ts +29 -1
- package/src/modules/dashboards/api/widgets/data/schema.ts +49 -19
- package/src/modules/dashboards/components/UnlabelledAmountNotice.tsx +43 -0
- package/src/modules/dashboards/i18n/de.json +5 -0
- package/src/modules/dashboards/i18n/en.json +5 -0
- package/src/modules/dashboards/i18n/es.json +5 -0
- package/src/modules/dashboards/i18n/ko.json +118 -0
- package/src/modules/dashboards/i18n/pl.json +5 -0
- package/src/modules/dashboards/lib/access.ts +5 -3
- package/src/modules/dashboards/lib/aggregations.ts +198 -48
- package/src/modules/dashboards/lib/exactDecimal.ts +96 -0
- package/src/modules/dashboards/lib/formatters.ts +137 -12
- package/src/modules/dashboards/lib/optionalBaseCurrency.ts +22 -0
- package/src/modules/dashboards/services/widgetDataService.ts +453 -12
- package/src/modules/dashboards/subscribers/invalidateWidgetDataCache.ts +32 -0
- package/src/modules/dashboards/widgets/dashboard/aov-kpi/widget.client.tsx +9 -3
- package/src/modules/dashboards/widgets/dashboard/pipeline-summary/config.ts +86 -0
- package/src/modules/dashboards/widgets/dashboard/pipeline-summary/widget.client.tsx +42 -21
- package/src/modules/dashboards/widgets/dashboard/pipeline-summary/widget.ts +2 -2
- package/src/modules/dashboards/widgets/dashboard/revenue-kpi/widget.client.tsx +9 -3
- package/src/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.tsx +7 -2
- package/src/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.tsx +25 -15
- package/src/modules/dashboards/widgets/dashboard/top-customers/widget.client.tsx +21 -11
- package/src/modules/dashboards/widgets/dashboard/top-products/widget.client.tsx +9 -3
- package/src/modules/data_sync/AGENTS.md +1 -0
- package/src/modules/data_sync/api/mappings/[id]/route.ts +22 -9
- package/src/modules/data_sync/api/mappings/route.ts +13 -4
- package/src/modules/data_sync/api/options.ts +7 -2
- package/src/modules/data_sync/api/run.ts +7 -2
- package/src/modules/data_sync/api/runs/[id]/cancel.ts +8 -3
- package/src/modules/data_sync/api/runs/[id]/retry.ts +7 -2
- package/src/modules/data_sync/api/runs/[id]/route.ts +8 -3
- package/src/modules/data_sync/api/runs.ts +7 -2
- package/src/modules/data_sync/api/schedules/[id]/route.ts +19 -6
- package/src/modules/data_sync/api/schedules/route.ts +13 -4
- package/src/modules/data_sync/api/validate.ts +9 -4
- package/src/modules/data_sync/backend/data-sync/page.tsx +5 -4
- package/src/modules/data_sync/components/IntegrationScheduleTab.tsx +5 -5
- package/src/modules/data_sync/extension-points.ts +10 -0
- package/src/modules/data_sync/i18n/ko.json +125 -0
- package/src/modules/data_sync/lib/adapter.ts +18 -0
- package/src/modules/data_sync/lib/queue-policy.ts +30 -0
- package/src/modules/data_sync/lib/queue.ts +19 -1
- package/src/modules/data_sync/lib/start-run.ts +2 -1
- package/src/modules/data_sync/lib/sync-engine.ts +46 -0
- package/src/modules/data_sync/lib/sync-run-service.ts +82 -1
- package/src/modules/data_sync/workers/sync-export.ts +8 -1
- package/src/modules/data_sync/workers/sync-import.ts +8 -1
- package/src/modules/design_system/AGENTS.md +34 -0
- package/src/modules/design_system/acl.ts +5 -0
- package/src/modules/design_system/backend/design-system/page.meta.ts +11 -0
- package/src/modules/design_system/backend/design-system/page.tsx +14 -0
- package/src/modules/design_system/gallery/components/CodeSnippet.tsx +55 -0
- package/src/modules/design_system/gallery/components/EntryCard.tsx +95 -0
- package/src/modules/design_system/gallery/components/GalleryShell.tsx +206 -0
- package/src/modules/design_system/gallery/components/VariantPreview.tsx +15 -0
- package/src/modules/design_system/gallery/entries/banners.tsx +226 -0
- package/src/modules/design_system/gallery/entries/buttons.tsx +422 -0
- package/src/modules/design_system/gallery/entries/charts.tsx +518 -0
- package/src/modules/design_system/gallery/entries/dates.tsx +325 -0
- package/src/modules/design_system/gallery/entries/detail.tsx +403 -0
- package/src/modules/design_system/gallery/entries/display.tsx +893 -0
- package/src/modules/design_system/gallery/entries/feedback.tsx +746 -0
- package/src/modules/design_system/gallery/entries/filters.tsx +570 -0
- package/src/modules/design_system/gallery/entries/foundations.tsx +529 -0
- package/src/modules/design_system/gallery/entries/icons.tsx +168 -0
- package/src/modules/design_system/gallery/entries/inputs.tsx +1516 -0
- package/src/modules/design_system/gallery/entries/messages.tsx +339 -0
- package/src/modules/design_system/gallery/entries/navigation.tsx +573 -0
- package/src/modules/design_system/gallery/entries/notifications.tsx +285 -0
- package/src/modules/design_system/gallery/entries/overlays.tsx +677 -0
- package/src/modules/design_system/gallery/entries/scaffolding.tsx +430 -0
- package/src/modules/design_system/gallery/entries/schedule.tsx +307 -0
- package/src/modules/design_system/gallery/registry.ts +152 -0
- package/src/modules/design_system/gallery/types.ts +32 -0
- package/src/modules/design_system/i18n/.hardcoded-allowlist.json +71 -0
- package/src/modules/design_system/i18n/de.json +58 -0
- package/src/modules/design_system/i18n/en.json +58 -0
- package/src/modules/design_system/i18n/es.json +58 -0
- package/src/modules/design_system/i18n/ko.json +58 -0
- package/src/modules/design_system/i18n/pl.json +58 -0
- package/src/modules/design_system/index.ts +7 -0
- package/src/modules/design_system/setup.ts +12 -0
- package/src/modules/dictionaries/api/[dictionaryId]/entries/route.ts +39 -11
- package/src/modules/dictionaries/api/openapi.ts +19 -0
- package/src/modules/dictionaries/components/DictionaryEntrySelect.tsx +1 -1
- package/src/modules/dictionaries/components/hooks/useDictionaryEntries.ts +35 -36
- package/src/modules/dictionaries/data/validators.ts +14 -0
- package/src/modules/dictionaries/i18n/ko.json +130 -0
- package/src/modules/dictionaries/lib/clientEntries.ts +4 -3
- package/src/modules/dictionaries/lib/fetchAllEntries.ts +72 -0
- package/src/modules/directory/api/organization-branding/route.ts +12 -1
- package/src/modules/directory/api/organization-switcher/route.ts +97 -26
- package/src/modules/directory/api/organizations/route.ts +7 -0
- package/src/modules/directory/api/tenants/route.ts +9 -1
- package/src/modules/directory/backend/directory/branding/page.tsx +34 -9
- package/src/modules/directory/backend/directory/organizations/[id]/edit/page.tsx +10 -14
- package/src/modules/directory/backend/directory/organizations/page.tsx +2 -1
- package/src/modules/directory/backend/directory/tenants/page.tsx +2 -1
- package/src/modules/directory/commands/organizations.ts +9 -1
- package/src/modules/directory/commands/tenants.ts +6 -0
- package/src/modules/directory/data/entities.ts +3 -0
- package/src/modules/directory/data/validators.ts +2 -0
- package/src/modules/directory/extension-points.ts +11 -0
- package/src/modules/directory/i18n/de.json +4 -1
- package/src/modules/directory/i18n/en.json +4 -1
- package/src/modules/directory/i18n/es.json +4 -1
- package/src/modules/directory/i18n/ko.json +105 -0
- package/src/modules/directory/i18n/pl.json +4 -1
- package/src/modules/directory/migrations/.snapshot-open-mercato.json +18 -1
- package/src/modules/directory/migrations/Migration20260626145500_directory_logo_preserve_aspect_ratio.ts +13 -0
- package/src/modules/directory/subscribers/invalidateOrgScopeCache.ts +4 -1
- package/src/modules/directory/utils/organizationScope.ts +9 -3
- package/src/modules/entities/api/definitions.ts +55 -3
- package/src/modules/entities/api/entities.ts +30 -2
- package/src/modules/entities/api/entity-settings.ts +66 -22
- package/src/modules/entities/api/records.ts +15 -31
- package/src/modules/entities/api/sidebar-entities.ts +43 -14
- package/src/modules/entities/backend/config/settings/page.meta.ts +34 -0
- package/src/modules/entities/backend/config/settings/page.tsx +12 -0
- package/src/modules/entities/backend/entities/user/[entityId]/page.tsx +1 -1
- package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +96 -75
- package/src/modules/entities/backend/entities/user/create/page.tsx +16 -7
- package/src/modules/entities/cli.ts +238 -21
- package/src/modules/entities/components/EntitySettingsManager.tsx +160 -0
- package/src/modules/entities/components/RecordListRelationCell.tsx +90 -0
- package/src/modules/entities/components/SystemEntitiesTable.tsx +2 -1
- package/src/modules/entities/components/UserEntitiesTable.tsx +2 -1
- package/src/modules/entities/components/recordListRelationDisplays.ts +109 -0
- package/src/modules/entities/extension-points.ts +18 -0
- package/src/modules/entities/i18n/de.json +9 -0
- package/src/modules/entities/i18n/en.json +9 -0
- package/src/modules/entities/i18n/es.json +9 -0
- package/src/modules/entities/i18n/ko.json +260 -0
- package/src/modules/entities/i18n/pl.json +9 -0
- package/src/modules/entities/lib/entityAcl.ts +98 -11
- package/src/modules/feature_toggles/components/FeatureGuard.tsx +9 -2
- package/src/modules/feature_toggles/components/FeatureToggleOverrideCard.tsx +1 -1
- package/src/modules/feature_toggles/components/hooks/staleTime.ts +5 -0
- package/src/modules/feature_toggles/components/hooks/useFeatureFlagBoolean.ts +13 -1
- package/src/modules/feature_toggles/components/hooks/useFeatureFlagJson.ts +12 -3
- package/src/modules/feature_toggles/components/hooks/useFeatureFlagNumber.ts +10 -1
- package/src/modules/feature_toggles/components/hooks/useFeatureFlagString.ts +10 -1
- package/src/modules/feature_toggles/i18n/ko.json +96 -0
- package/src/modules/inbox_ops/ai-tools.ts +5 -3
- package/src/modules/inbox_ops/api/proposals/[id]/actions/[actionId]/route.ts +17 -1
- package/src/modules/inbox_ops/api/proposals/route.ts +20 -1
- package/src/modules/inbox_ops/api/webhook/inbound.ts +14 -12
- package/src/modules/inbox_ops/backend/inbox-ops/log/page.tsx +6 -6
- package/src/modules/inbox_ops/components/proposals/EditActionDialog.tsx +24 -19
- package/src/modules/inbox_ops/components/proposals/types.ts +1 -0
- package/src/modules/inbox_ops/i18n/de.json +3 -0
- package/src/modules/inbox_ops/i18n/en.json +3 -0
- package/src/modules/inbox_ops/i18n/es.json +3 -0
- package/src/modules/inbox_ops/i18n/ko.json +196 -0
- package/src/modules/inbox_ops/i18n/pl.json +3 -0
- package/src/modules/inbox_ops/search.ts +20 -4
- package/src/modules/inbox_ops/subscribers/search-reindex-proposal-created.ts +39 -0
- package/src/modules/integrations/api/[id]/credentials/route.ts +11 -5
- package/src/modules/integrations/api/[id]/health/route.ts +6 -3
- package/src/modules/integrations/api/[id]/route.ts +6 -3
- package/src/modules/integrations/api/[id]/state/route.ts +6 -3
- package/src/modules/integrations/api/[id]/version/route.ts +6 -3
- package/src/modules/integrations/api/logs/route.ts +6 -3
- package/src/modules/integrations/api/route.ts +6 -3
- package/src/modules/integrations/api/umes-read.ts +2 -2
- package/src/modules/integrations/backend/integrations/[id]/page.tsx +2 -2
- package/src/modules/integrations/extension-points.ts +27 -0
- package/src/modules/integrations/i18n/ko.json +129 -0
- package/src/modules/integrations/lib/organization-scope.ts +5 -25
- package/src/modules/integrations/widgets/injection/external-ids/widget.client.tsx +0 -5
- package/src/modules/integrations/widgets/injection/external-ids/widget.ts +13 -0
- package/src/modules/messages/api/[id]/route.ts +21 -0
- package/src/modules/messages/api/route.ts +109 -9
- package/src/modules/messages/components/ComposeMessagePageClient.tsx +2 -1
- package/src/modules/messages/components/MessageDetailPageClient.tsx +3 -2
- package/src/modules/messages/components/MessagesInboxPageClient.tsx +2 -1
- package/src/modules/messages/components/message-detail/panels/dialogs.tsx +1 -1
- package/src/modules/messages/extension-points.ts +13 -0
- package/src/modules/messages/i18n/de.json +2 -0
- package/src/modules/messages/i18n/en.json +2 -0
- package/src/modules/messages/i18n/es.json +2 -0
- package/src/modules/messages/i18n/ko.json +263 -0
- package/src/modules/messages/i18n/pl.json +2 -0
- package/src/modules/messages/lib/participantScope.ts +64 -0
- package/src/modules/messages/lib/routeHelpers.ts +4 -6
- package/src/modules/messages/lib/searchLookup.ts +11 -34
- package/src/modules/messages/search.ts +11 -5
- package/src/modules/notifications/api/route.ts +123 -3
- package/src/modules/notifications/api/unread-count/route.ts +42 -5
- package/src/modules/notifications/di.ts +1 -1
- package/src/modules/notifications/events.ts +2 -0
- package/src/modules/notifications/i18n/ko.json +55 -0
- package/src/modules/notifications/lib/notificationRecipients.ts +6 -8
- package/src/modules/notifications/lib/notificationScope.ts +40 -0
- package/src/modules/notifications/lib/notificationService.ts +63 -1
- package/src/modules/notifications/lib/routeHelpers.ts +19 -2
- package/src/modules/payment_gateways/api/capture/route.ts +1 -1
- package/src/modules/payment_gateways/api/sessions/route.ts +6 -3
- package/src/modules/payment_gateways/api/webhook/[provider]/route.ts +13 -1
- package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +3 -2
- package/src/modules/payment_gateways/data/entities.ts +13 -2
- package/src/modules/payment_gateways/di.ts +28 -2
- package/src/modules/payment_gateways/extension-points.ts +16 -0
- package/src/modules/payment_gateways/i18n/de.json +8 -1
- package/src/modules/payment_gateways/i18n/en.json +8 -1
- package/src/modules/payment_gateways/i18n/es.json +8 -1
- package/src/modules/payment_gateways/i18n/ko.json +87 -0
- package/src/modules/payment_gateways/i18n/pl.json +8 -1
- package/src/modules/payment_gateways/lib/capture-ledger.ts +260 -0
- package/src/modules/payment_gateways/lib/gateway-service.ts +114 -18
- package/src/modules/payment_gateways/lib/order-amount-reconciliation.ts +93 -0
- package/src/modules/payment_gateways/lib/payment-operation-idempotency.ts +1 -0
- package/src/modules/payment_gateways/lib/session-idempotency.ts +36 -0
- package/src/modules/payment_gateways/migrations/.snapshot-open-mercato.json +44 -1
- package/src/modules/payment_gateways/migrations/Migration20260725101500_payment_gateways.ts +21 -0
- package/src/modules/payment_gateways/migrations/Migration20260803103035_payment_gateways.ts +17 -0
- package/src/modules/payment_gateways/setup.ts +62 -0
- package/src/modules/payment_gateways/workers/session-initialization-prune.ts +63 -0
- package/src/modules/planner/components/AvailabilityRulesEditor.tsx +4 -4
- package/src/modules/planner/components/unavailabilityReasons.ts +3 -3
- package/src/modules/planner/i18n/ko.json +565 -0
- package/src/modules/portal/extension-points.ts +30 -0
- package/src/modules/portal/frontend/[orgSlug]/portal/dashboard/page.tsx +3 -3
- package/src/modules/portal/frontend/[orgSlug]/portal/invite/page.meta.ts +9 -0
- package/src/modules/portal/frontend/[orgSlug]/portal/invite/page.tsx +164 -0
- package/src/modules/portal/frontend/[orgSlug]/portal/login/page.tsx +4 -4
- package/src/modules/portal/frontend/[orgSlug]/portal/page.tsx +3 -3
- package/src/modules/portal/frontend/[orgSlug]/portal/profile/page.tsx +3 -3
- package/src/modules/portal/frontend/[orgSlug]/portal/reset-password/page.tsx +5 -5
- package/src/modules/portal/frontend/[orgSlug]/portal/signup/page.tsx +4 -4
- package/src/modules/portal/frontend/[orgSlug]/portal/verify/page.tsx +1 -1
- package/src/modules/portal/i18n/de.json +18 -0
- package/src/modules/portal/i18n/en.json +18 -0
- package/src/modules/portal/i18n/es.json +18 -0
- package/src/modules/portal/i18n/ko.json +143 -0
- package/src/modules/portal/i18n/pl.json +18 -0
- package/src/modules/portal/lib/navigation.ts +3 -0
- package/src/modules/progress/AGENTS.md +11 -1
- package/src/modules/progress/i18n/ko.json +20 -0
- package/src/modules/progress/lib/progressService.ts +1 -0
- package/src/modules/progress/lib/progressServiceImpl.ts +385 -117
- package/src/modules/query_index/api/openapi.ts +12 -0
- package/src/modules/query_index/api/reindex.ts +15 -0
- package/src/modules/query_index/api/status.ts +238 -136
- package/src/modules/query_index/cli.ts +180 -1
- package/src/modules/query_index/components/QueryIndexesTable.tsx +194 -47
- package/src/modules/query_index/data/entities.ts +7 -0
- package/src/modules/query_index/di.ts +6 -0
- package/src/modules/query_index/events.ts +17 -0
- package/src/modules/query_index/extension-points.ts +10 -0
- package/src/modules/query_index/i18n/de.json +5 -3
- package/src/modules/query_index/i18n/en.json +5 -3
- package/src/modules/query_index/i18n/es.json +5 -3
- package/src/modules/query_index/i18n/ko.json +69 -0
- package/src/modules/query_index/i18n/pl.json +5 -3
- package/src/modules/query_index/lib/batch.ts +11 -4
- package/src/modules/query_index/lib/coverage.ts +47 -14
- package/src/modules/query_index/lib/document.ts +35 -4
- package/src/modules/query_index/lib/engine.ts +136 -59
- package/src/modules/query_index/lib/indexer.ts +130 -21
- package/src/modules/query_index/lib/reindexer.ts +62 -40
- package/src/modules/query_index/lib/search-tokens.ts +48 -16
- package/src/modules/query_index/lib/subscriber-scope.ts +2 -7
- package/src/modules/query_index/migrations/.snapshot-open-mercato.json +12 -0
- package/src/modules/query_index/migrations/Migration20260731105052_query_index.ts +35 -0
- package/src/modules/query_index/subscribers/coverage_refresh.ts +4 -0
- package/src/modules/query_index/subscribers/delete_one.ts +65 -1
- package/src/modules/query_index/subscribers/upsert_one.ts +68 -1
- package/src/modules/resources/api/resources.ts +2 -0
- package/src/modules/resources/backend/resources/resource-types/page.tsx +2 -1
- package/src/modules/resources/backend/resources/resources/[id]/page.tsx +9 -3
- package/src/modules/resources/backend/resources/resources/page.tsx +2 -1
- package/src/modules/resources/commands/resources.ts +10 -0
- package/src/modules/resources/components/detail/dictionaries.ts +3 -3
- package/src/modules/resources/data/entities.ts +3 -0
- package/src/modules/resources/data/validators.ts +5 -0
- package/src/modules/resources/extension-points.ts +11 -0
- package/src/modules/resources/i18n/ko.json +770 -0
- package/src/modules/resources/lib/seeds.ts +16 -9
- package/src/modules/resources/migrations/.snapshot-open-mercato.json +17 -1
- package/src/modules/resources/migrations/Migration20260608231000.ts +13 -0
- package/src/modules/sales/analytics.ts +4 -0
- package/src/modules/sales/api/document-history/route.ts +1 -0
- package/src/modules/sales/api/documents/factory.ts +28 -3
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +11 -3
- package/src/modules/sales/backend/sales/documents/create/page.tsx +2 -4
- package/src/modules/sales/commands/documents.ts +298 -31
- package/src/modules/sales/components/documents/ItemsSection.tsx +34 -11
- package/src/modules/sales/components/documents/LineItemDialog.tsx +13 -5
- package/src/modules/sales/components/documents/SalesDocumentForm.tsx +48 -6
- package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +6 -1
- package/src/modules/sales/components/documents/SalesOrderDraftLines.tsx +198 -0
- package/src/modules/sales/components/documents/lineItemTypes.ts +1 -0
- package/src/modules/sales/components/useSalesChannelsEnabled.ts +2 -48
- package/src/modules/sales/data/validators.ts +59 -6
- package/src/modules/sales/di.ts +9 -0
- package/src/modules/sales/events.ts +1 -0
- package/src/modules/sales/extension-points.ts +33 -0
- package/src/modules/sales/i18n/de.json +22 -0
- package/src/modules/sales/i18n/en.json +22 -0
- package/src/modules/sales/i18n/es.json +22 -0
- package/src/modules/sales/i18n/ko.json +1442 -0
- package/src/modules/sales/i18n/pl.json +22 -0
- package/src/modules/sales/lib/historyHelpers.ts +88 -1
- package/src/modules/sales/services/paymentOrderTotalResolver.ts +67 -0
- package/src/modules/sales/widgets/injection/document-history/widget.client.tsx +64 -3
- package/src/modules/sales/workflows.ts +10 -7
- package/src/modules/shipping_carriers/api/webhook/[provider]/route.ts +11 -1
- package/src/modules/shipping_carriers/i18n/ko.json +85 -0
- package/src/modules/shipping_carriers/lib/shipment-wizard/components/PackageEditor.tsx +1 -1
- package/src/modules/staff/api/interceptors.ts +6 -4
- package/src/modules/staff/api/leave-requests.ts +54 -47
- package/src/modules/staff/components/detail/dictionaries.ts +3 -3
- package/src/modules/staff/i18n/ko.json +1162 -0
- package/src/modules/sync_excel/api/upload/route.ts +15 -2
- package/src/modules/sync_excel/i18n/ko.json +107 -0
- package/src/modules/sync_excel/widgets/injection/upload-config/widget.client.tsx +1 -1
- package/src/modules/translations/i18n/ko.json +45 -0
- package/src/modules/wms/components/backend/ReleaseReservationDialog.tsx +1 -1
- package/src/modules/wms/components/backend/WmsConfigurationPage.tsx +5 -4
- package/src/modules/wms/components/backend/WmsInventoryConsolePage.tsx +4 -3
- package/src/modules/wms/components/backend/WmsLocationDetailPage.tsx +3 -2
- package/src/modules/wms/components/backend/WmsLotDetailPage.tsx +3 -2
- package/src/modules/wms/components/backend/WmsLotsListPage.tsx +2 -1
- package/src/modules/wms/components/backend/WmsSkuDetailPage.tsx +3 -2
- package/src/modules/wms/extension-points.ts +23 -0
- package/src/modules/wms/i18n/de.json +2 -0
- package/src/modules/wms/i18n/en.json +2 -0
- package/src/modules/wms/i18n/es.json +2 -0
- package/src/modules/wms/i18n/ko.json +1053 -0
- package/src/modules/wms/i18n/pl.json +2 -0
- package/src/modules/workflows/backend/definitions/[id]/page.tsx +2 -2
- package/src/modules/workflows/backend/definitions/create/page.tsx +1 -1
- package/src/modules/workflows/backend/definitions/page.tsx +3 -2
- package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +16 -7
- package/src/modules/workflows/backend/instances/page.tsx +10 -9
- package/src/modules/workflows/backend/tasks/page.tsx +8 -7
- package/src/modules/workflows/components/ActivitiesEditor.tsx +98 -14
- package/src/modules/workflows/components/BusinessRulesSelector.tsx +1 -1
- package/src/modules/workflows/components/DefinitionTriggersEditor.tsx +3 -3
- package/src/modules/workflows/components/EdgeEditDialogCrudForm.tsx +1 -2
- package/src/modules/workflows/components/NodeEditDialog.tsx +3 -3
- package/src/modules/workflows/components/NodeEditDialogCrudForm.tsx +4 -5
- package/src/modules/workflows/components/StepsEditor.tsx +2 -2
- package/src/modules/workflows/components/TransitionsEditor.tsx +78 -20
- package/src/modules/workflows/components/WorkflowGraphImpl.tsx +1 -1
- package/src/modules/workflows/components/WorkflowLegend.tsx +1 -1
- package/src/modules/workflows/components/WorkflowSelector.tsx +1 -1
- package/src/modules/workflows/components/fields/BusinessRuleConditionsEditor.tsx +1 -1
- package/src/modules/workflows/components/fields/FormFieldArrayEditor.tsx +2 -2
- package/src/modules/workflows/components/fields/MappingArrayEditor.tsx +1 -1
- package/src/modules/workflows/components/fields/StartPreConditionsEditor.tsx +1 -1
- package/src/modules/workflows/components/fields/WorkflowSelectorField.tsx +4 -4
- package/src/modules/workflows/data/validators.ts +52 -1
- package/src/modules/workflows/events.ts +1 -0
- package/src/modules/workflows/extension-points.ts +12 -0
- package/src/modules/workflows/i18n/de.json +3 -0
- package/src/modules/workflows/i18n/en.json +3 -0
- package/src/modules/workflows/i18n/es.json +3 -0
- package/src/modules/workflows/i18n/ko.json +1204 -0
- package/src/modules/workflows/i18n/pl.json +3 -0
- package/src/modules/workflows/lib/activity-executor.ts +99 -20
- package/src/modules/workflows/lib/format-validation-error.ts +60 -0
- package/src/modules/workflows/widgets/injection/order-approval/context-keys.ts +18 -0
- package/src/modules/workflows/widgets/injection/order-approval/widget.client.tsx +27 -11
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/modules/sync_excel/widgets/injection/upload-config/widget.client.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { usePathname, useRouter, useSearchParams } from 'next/navigation'\nimport type { InjectionWidgetComponentProps } from '@open-mercato/shared/modules/widgets/injection'\nimport type { FieldMapping } from '../../../../data_sync/lib/adapter'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useCustomFieldDefs } from '@open-mercato/ui/backend/utils/customFieldDefs'\nimport { Alert, AlertDescription, AlertTitle } from '@open-mercato/ui/primitives/alert'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { StatusBadge, type StatusMap } from '@open-mercato/ui/primitives/status-badge'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@open-mercato/ui/primitives/card'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Progress } from '@open-mercato/ui/primitives/progress'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@open-mercato/ui/primitives/table'\nimport { AlertTriangle, CheckCircle2, Play, RefreshCw, Upload, XCircle } from 'lucide-react'\nimport {\n buildPeopleSuggestedMapping,\n buildPeopleTargetOptions,\n buildSuggestedMappingSignature,\n findMappingTargetOption,\n SYNC_EXCEL_PEOPLE_CUSTOM_FIELD_ENTITY_IDS,\n type MappingTargetOption,\n type SuggestedMapping,\n} from './target-options'\n\ntype SyncExcelIntegrationContext = {\n formId?: string\n integrationDetailWidgetSpotId?: string\n integrationId?: string\n activeTab?: string\n state?: {\n isEnabled?: boolean\n } | null\n refreshDetail?: () => Promise<void>\n refreshLogs?: () => Promise<void>\n refreshHealthSnapshot?: () => Promise<void>\n}\n\ntype SyncExcelIntegrationData = {\n state?: {\n isEnabled?: boolean\n } | null\n}\n\ntype PreviewRow = Record<string, string | null>\n\ntype UploadResponse = {\n uploadId: string\n filename: string\n mimeType: string\n fileSize: number\n entityType: 'customers.person'\n headers: string[]\n sampleRows: PreviewRow[]\n totalRows: number\n suggestedMapping: SuggestedMapping\n}\n\ntype ImportResponse = {\n runId: string\n progressJobId: string | null\n status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled'\n}\n\ntype SyncRunDetail = {\n id: string\n status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled' | 'paused'\n createdCount: number\n updatedCount: number\n skippedCount: number\n failedCount: number\n lastError: string | null\n progressJobId: string | null\n progressJob: {\n id: string\n status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled'\n progressPercent: number\n processedCount: number\n totalCount: number | null\n etaSeconds: number | null\n } | null\n}\n\ntype MappingRowState = {\n sourceColumn: string\n targetField: string\n}\n\ntype MappingDiagnostics = {\n duplicateTargets: string[]\n hasNameTarget: boolean\n hasIdentityTarget: boolean\n mappedCount: number\n unmappedCount: number\n}\n\ntype PersistedSessionSnapshot = {\n uploadId: string\n filename: string\n preview: UploadResponse | null\n mappingRows: MappingRowState[]\n matchStrategy: SuggestedMapping['matchStrategy']\n runId: string | null\n progressJobId: string | null\n}\n\nconst ENTITY_TYPE = 'customers.person' as const\nconst SESSION_STORAGE_PREFIX = 'om:sync_excel:session'\nconst RUN_POLL_INTERVAL_MS = 4_000\n\nconst SELECT_CLASS_NAME = 'flex h-9 w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50'\n\nfunction buildMappingRows(headers: string[], suggestedMapping: SuggestedMapping): MappingRowState[] {\n const mappedFields = new Map(suggestedMapping.fields.map((field) => [field.externalField, field.localField]))\n return headers.map((header) => ({\n sourceColumn: header,\n targetField: mappedFields.get(header) ?? '',\n }))\n}\n\nfunction buildFieldMapping(sourceColumn: string, targetField: string, targetOptions: MappingTargetOption[]): FieldMapping {\n const matchedOption = findMappingTargetOption(targetOptions, targetField)\n const mappingKind = matchedOption?.mappingKind ?? (targetField.startsWith('cf:') ? 'custom_field' : 'core')\n const dedupeRole = matchedOption?.dedupeRole\n\n return {\n externalField: sourceColumn,\n localField: targetField,\n mappingKind,\n ...(dedupeRole ? { dedupeRole } : {}),\n }\n}\n\nfunction inferMatchStrategy(rows: MappingRowState[]): SuggestedMapping['matchStrategy'] {\n if (rows.some((row) => row.targetField === 'person.externalId')) return 'externalId'\n if (rows.some((row) => row.targetField === 'person.primaryEmail')) return 'email'\n return 'custom'\n}\n\nfunction buildMapping(\n rows: MappingRowState[],\n matchStrategy: SuggestedMapping['matchStrategy'],\n targetOptions: MappingTargetOption[],\n): SuggestedMapping {\n const mappedRows = rows.filter((row) => row.targetField.trim().length > 0)\n const fields = mappedRows.map((row) => buildFieldMapping(row.sourceColumn, row.targetField, targetOptions))\n const resolvedMatchStrategy = matchStrategy === 'custom' ? inferMatchStrategy(rows) : matchStrategy\n const matchField = resolvedMatchStrategy === 'externalId'\n ? 'person.externalId'\n : resolvedMatchStrategy === 'email'\n ? 'person.primaryEmail'\n : undefined\n\n return {\n entityType: ENTITY_TYPE,\n matchStrategy: resolvedMatchStrategy,\n ...(matchField ? { matchField } : {}),\n fields,\n unmappedColumns: rows.filter((row) => row.targetField.trim().length === 0).map((row) => row.sourceColumn),\n }\n}\n\nfunction buildDiagnostics(rows: MappingRowState[]): MappingDiagnostics {\n const duplicateTargets = Array.from(\n rows\n .filter((row) => row.targetField.trim().length > 0)\n .reduce((accumulator, row) => {\n const nextCount = (accumulator.get(row.targetField) ?? 0) + 1\n accumulator.set(row.targetField, nextCount)\n return accumulator\n }, new Map<string, number>())\n .entries(),\n )\n .filter(([, count]) => count > 1)\n .map(([target]) => target)\n\n const hasNameTarget = rows.some((row) => row.targetField === 'person.lastName' || row.targetField === 'person.displayName')\n const hasIdentityTarget = rows.some((row) => row.targetField === 'person.externalId' || row.targetField === 'person.primaryEmail')\n const mappedCount = rows.filter((row) => row.targetField.trim().length > 0).length\n\n return {\n duplicateTargets,\n hasNameTarget,\n hasIdentityTarget,\n mappedCount,\n unmappedCount: rows.length - mappedCount,\n }\n}\n\nfunction formatTargetLabel(\n targetField: string,\n t: ReturnType<typeof useT>,\n targetOptions: MappingTargetOption[],\n): string {\n const option = findMappingTargetOption(targetOptions, targetField)\n if (!option) return targetField\n return option.labelKey ? t(option.labelKey, option.fallback) : option.fallback\n}\n\nfunction getMatchStrategyLabel(\n matchStrategy: SuggestedMapping['matchStrategy'],\n t: ReturnType<typeof useT>,\n): string {\n if (matchStrategy === 'externalId') {\n return t('sync_excel.widget.matchStrategy.externalId', 'Source record ID (Recommended)')\n }\n if (matchStrategy === 'email') {\n return t('sync_excel.widget.matchStrategy.email', 'Email address')\n }\n return t('sync_excel.widget.matchStrategy.custom', 'Custom matching')\n}\n\nfunction formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n\nfunction readApiErrorMessage(result: Record<string, unknown> | null | undefined, fallback: string): string {\n const value = result?.error\n if (typeof value === 'string' && value.trim().length > 0) return value\n return fallback\n}\n\nfunction normalizeStatus(status: SyncRunDetail['status'] | ImportResponse['status'] | null | undefined): 'pending' | 'running' | 'completed' | 'failed' | 'cancelled' | 'idle' {\n if (status === 'pending' || status === 'running' || status === 'completed' || status === 'failed' || status === 'cancelled') {\n return status\n }\n return 'idle'\n}\n\nfunction getSessionStorageKey(integrationId: string | undefined): string {\n return `${SESSION_STORAGE_PREFIX}:${integrationId ?? 'sync_excel'}`\n}\n\nfunction readPersistedSessionSnapshot(integrationId: string | undefined): PersistedSessionSnapshot | null {\n if (typeof window === 'undefined') return null\n try {\n const raw = window.sessionStorage.getItem(getSessionStorageKey(integrationId))\n if (!raw) return null\n const parsed = JSON.parse(raw) as Partial<PersistedSessionSnapshot> | null\n if (!parsed || typeof parsed !== 'object') return null\n if (typeof parsed.uploadId !== 'string' || parsed.uploadId.trim().length === 0) return null\n if (typeof parsed.filename !== 'string') return null\n if (!Array.isArray(parsed.mappingRows)) return null\n if (parsed.matchStrategy !== 'externalId' && parsed.matchStrategy !== 'email' && parsed.matchStrategy !== 'custom') {\n return null\n }\n const preview = (\n parsed.preview\n && typeof parsed.preview === 'object'\n && typeof parsed.preview.uploadId === 'string'\n && parsed.preview.uploadId.trim().length > 0\n && typeof parsed.preview.filename === 'string'\n && Array.isArray(parsed.preview.headers)\n && Array.isArray(parsed.preview.sampleRows)\n && typeof parsed.preview.totalRows === 'number'\n && typeof parsed.preview.fileSize === 'number'\n && parsed.preview.entityType === ENTITY_TYPE\n && parsed.preview.suggestedMapping\n )\n ? parsed.preview as UploadResponse\n : null\n\n return {\n uploadId: parsed.uploadId,\n filename: parsed.filename,\n preview,\n mappingRows: parsed.mappingRows\n .filter((row): row is MappingRowState => (\n Boolean(row)\n && typeof row.sourceColumn === 'string'\n && typeof row.targetField === 'string'\n )),\n matchStrategy: parsed.matchStrategy,\n runId: typeof parsed.runId === 'string' && parsed.runId.trim().length > 0 ? parsed.runId : null,\n progressJobId: typeof parsed.progressJobId === 'string' && parsed.progressJobId.trim().length > 0 ? parsed.progressJobId : null,\n }\n } catch {\n return null\n }\n}\n\nfunction writePersistedSessionSnapshot(\n integrationId: string | undefined,\n snapshot: PersistedSessionSnapshot | null,\n): void {\n if (typeof window === 'undefined') return\n try {\n const key = getSessionStorageKey(integrationId)\n if (!snapshot) {\n window.sessionStorage.removeItem(key)\n return\n }\n window.sessionStorage.setItem(key, JSON.stringify(snapshot))\n } catch {\n // sessionStorage can be unavailable in private/locked-down browser contexts; persistence is best-effort.\n }\n}\n\nexport default function SyncExcelUploadConfigWidget({\n context,\n data,\n}: InjectionWidgetComponentProps<SyncExcelIntegrationContext, SyncExcelIntegrationData>) {\n const pathname = usePathname()\n const router = useRouter()\n const searchParams = useSearchParams()\n const t = useT()\n const { data: customFieldDefs = [] } = useCustomFieldDefs([...SYNC_EXCEL_PEOPLE_CUSTOM_FIELD_ENTITY_IDS])\n const [selectedFile, setSelectedFile] = React.useState<File | null>(null)\n const [preview, setPreview] = React.useState<UploadResponse | null>(null)\n const [mappingRows, setMappingRows] = React.useState<MappingRowState[]>([])\n const [matchStrategy, setMatchStrategy] = React.useState<SuggestedMapping['matchStrategy']>('custom')\n const [isMappingDirty, setIsMappingDirty] = React.useState(false)\n const [runDetail, setRunDetail] = React.useState<SyncRunDetail | null>(null)\n const [runId, setRunId] = React.useState<string | null>(null)\n const [progressJobId, setProgressJobId] = React.useState<string | null>(null)\n const [isUploading, setIsUploading] = React.useState(false)\n const [isRefreshingPreview, setIsRefreshingPreview] = React.useState(false)\n const [isStartingImport, setIsStartingImport] = React.useState(false)\n const [isCancelling, setIsCancelling] = React.useState(false)\n const [isRestoringSession, setIsRestoringSession] = React.useState(true)\n const mutationContextId = `${context.formId ?? 'sync-excel'}:sync-excel-import`\n const lastAppliedSuggestionSignatureRef = React.useRef<string | null>(null)\n const restoringSnapshotRef = React.useRef<PersistedSessionSnapshot | null>(null)\n const lastRestoreRequestKeyRef = React.useRef<string | null>(null)\n const { runMutation } = useGuardedMutation<Record<string, unknown>>({\n contextId: mutationContextId,\n spotId: context.integrationDetailWidgetSpotId,\n })\n\n const targetOptions = React.useMemo(\n () => buildPeopleTargetOptions(customFieldDefs),\n [customFieldDefs],\n )\n const previewSuggestion = React.useMemo(\n () => preview ? buildPeopleSuggestedMapping(preview.headers, preview.suggestedMapping, customFieldDefs) : null,\n [customFieldDefs, preview],\n )\n const resolvedIntegrationEnabled = data?.state?.isEnabled ?? context.state?.isEnabled ?? true\n const diagnostics = React.useMemo(() => buildDiagnostics(mappingRows), [mappingRows])\n const canStartImport = Boolean(preview)\n && diagnostics.duplicateTargets.length === 0\n && diagnostics.hasNameTarget\n && diagnostics.hasIdentityTarget\n && mappingRows.some((row) => row.targetField.trim().length > 0)\n const importStatus = normalizeStatus(runDetail?.status ?? (runId ? 'pending' : null))\n const progressValue = runDetail?.progressJob?.progressPercent ?? 0\n const isRunActive = importStatus === 'pending' || importStatus === 'running'\n const searchParamsKey = searchParams?.toString() ?? ''\n const uploadIdFromUrl = searchParams?.get('uploadId') ?? null\n const runIdFromUrl = searchParams?.get('runId') ?? null\n const shouldHideInteractiveContent = isRestoringSession && Boolean(uploadIdFromUrl)\n const hasExistingRunForCurrentUpload = Boolean(preview?.uploadId && runId)\n const hasSafeDedupeStrategy = matchStrategy === 'externalId' || matchStrategy === 'email'\n\n const replaceQueryParams = React.useCallback((updates: Record<string, string | null | undefined>) => {\n const params = new URLSearchParams(searchParamsKey)\n for (const [key, value] of Object.entries(updates)) {\n if (typeof value === 'string' && value.trim().length > 0) {\n params.set(key, value)\n } else {\n params.delete(key)\n }\n }\n const query = params.toString()\n if (query === searchParamsKey) return\n router.replace(query ? `${pathname}?${query}` : pathname)\n }, [pathname, router, searchParamsKey])\n\n const clearPersistedSession = React.useCallback(() => {\n writePersistedSessionSnapshot(context.integrationId, null)\n replaceQueryParams({ uploadId: null, runId: null })\n }, [context.integrationId, replaceQueryParams])\n\n const persistCurrentSession = React.useCallback((next?: Partial<PersistedSessionSnapshot>) => {\n const persistedPreview = next?.preview ?? preview ?? null\n const uploadId = next?.uploadId ?? persistedPreview?.uploadId ?? null\n const filename = next?.filename ?? persistedPreview?.filename ?? null\n if (!uploadId || !filename) {\n writePersistedSessionSnapshot(context.integrationId, null)\n return\n }\n\n writePersistedSessionSnapshot(context.integrationId, {\n uploadId,\n filename,\n preview: persistedPreview,\n mappingRows: next?.mappingRows ?? mappingRows,\n matchStrategy: next?.matchStrategy ?? matchStrategy,\n runId: next?.runId ?? runId,\n progressJobId: next?.progressJobId ?? progressJobId,\n })\n }, [context.integrationId, mappingRows, matchStrategy, preview, progressJobId, runId])\n\n const syncPreviewState = React.useCallback((nextPreview: UploadResponse, options?: {\n preserveManualState?: boolean\n restoredSnapshot?: PersistedSessionSnapshot | null\n }) => {\n const nextSuggestedMapping = buildPeopleSuggestedMapping(nextPreview.headers, nextPreview.suggestedMapping, customFieldDefs)\n setPreview(nextPreview)\n\n const restoredSnapshot = options?.restoredSnapshot\n const shouldRestoreSnapshot = Boolean(\n restoredSnapshot\n && restoredSnapshot.uploadId === nextPreview.uploadId\n && restoredSnapshot.mappingRows.length > 0,\n )\n\n if (shouldRestoreSnapshot) {\n setMappingRows(restoredSnapshot!.mappingRows)\n setMatchStrategy(restoredSnapshot!.matchStrategy)\n setRunId(restoredSnapshot!.runId)\n setProgressJobId(restoredSnapshot!.progressJobId)\n setIsMappingDirty(true)\n lastAppliedSuggestionSignatureRef.current = null\n persistCurrentSession({\n uploadId: nextPreview.uploadId,\n filename: nextPreview.filename,\n preview: nextPreview,\n mappingRows: restoredSnapshot!.mappingRows,\n matchStrategy: restoredSnapshot!.matchStrategy,\n runId: restoredSnapshot!.runId,\n progressJobId: restoredSnapshot!.progressJobId,\n })\n replaceQueryParams({\n uploadId: nextPreview.uploadId,\n runId: restoredSnapshot!.runId,\n })\n return\n }\n\n if (options?.preserveManualState && preview?.uploadId === nextPreview.uploadId) {\n persistCurrentSession({\n uploadId: nextPreview.uploadId,\n filename: nextPreview.filename,\n preview: nextPreview,\n })\n replaceQueryParams({ uploadId: nextPreview.uploadId })\n return\n }\n\n const nextRows = buildMappingRows(nextPreview.headers, nextSuggestedMapping)\n setMappingRows(nextRows)\n setMatchStrategy(nextSuggestedMapping.matchStrategy)\n setIsMappingDirty(false)\n lastAppliedSuggestionSignatureRef.current = buildSuggestedMappingSignature(nextPreview.headers, nextSuggestedMapping)\n persistCurrentSession({\n uploadId: nextPreview.uploadId,\n filename: nextPreview.filename,\n preview: nextPreview,\n mappingRows: nextRows,\n matchStrategy: nextSuggestedMapping.matchStrategy,\n runId: null,\n progressJobId: null,\n })\n replaceQueryParams({\n uploadId: nextPreview.uploadId,\n runId: null,\n })\n }, [customFieldDefs, persistCurrentSession, preview?.uploadId, replaceQueryParams])\n\n React.useEffect(() => {\n if (!preview || !previewSuggestion) return\n if (isMappingDirty) return\n const nextSignature = buildSuggestedMappingSignature(preview.headers, previewSuggestion)\n if (lastAppliedSuggestionSignatureRef.current === nextSignature) return\n setMappingRows(buildMappingRows(preview.headers, previewSuggestion))\n setMatchStrategy(previewSuggestion.matchStrategy)\n lastAppliedSuggestionSignatureRef.current = nextSignature\n }, [isMappingDirty, preview, previewSuggestion])\n\n const refreshRunDetail = React.useCallback(async (currentRunId: string) => {\n const call = await apiCall<SyncRunDetail>(`/api/data_sync/runs/${encodeURIComponent(currentRunId)}`, undefined, { fallback: null })\n if (call.ok && call.result) {\n setRunDetail(call.result)\n setProgressJobId(call.result.progressJobId ?? null)\n persistCurrentSession({\n runId: currentRunId,\n progressJobId: call.result.progressJobId ?? null,\n })\n return call.result\n }\n return null\n }, [persistCurrentSession])\n\n React.useEffect(() => {\n if (!preview?.uploadId) return\n persistCurrentSession()\n }, [mappingRows, matchStrategy, persistCurrentSession, preview?.uploadId, progressJobId, runId])\n\n React.useEffect(() => {\n const persistedSnapshot = readPersistedSessionSnapshot(context.integrationId)\n const resolvedUploadId = uploadIdFromUrl ?? persistedSnapshot?.uploadId ?? null\n const resolvedRunId = runIdFromUrl ?? persistedSnapshot?.runId ?? null\n\n if (!resolvedUploadId) {\n restoringSnapshotRef.current = null\n lastRestoreRequestKeyRef.current = null\n setIsRestoringSession(false)\n return\n }\n\n if (!uploadIdFromUrl && persistedSnapshot?.uploadId === resolvedUploadId) {\n replaceQueryParams({\n uploadId: resolvedUploadId,\n runId: resolvedRunId,\n })\n }\n\n if (preview?.uploadId === resolvedUploadId && mappingRows.length > 0) {\n if (resolvedRunId && runId !== resolvedRunId) {\n setRunId(resolvedRunId)\n }\n setIsRestoringSession(false)\n return\n }\n\n const restoreRequestKey = `${resolvedUploadId}:${resolvedRunId ?? ''}`\n if (lastRestoreRequestKeyRef.current === restoreRequestKey) {\n setIsRestoringSession(false)\n return\n }\n\n lastRestoreRequestKeyRef.current = restoreRequestKey\n\n let cancelled = false\n restoringSnapshotRef.current = persistedSnapshot\n const persistedPreview = restoringSnapshotRef.current?.preview?.uploadId === resolvedUploadId\n ? restoringSnapshotRef.current.preview\n : null\n\n if (persistedPreview) {\n syncPreviewState(persistedPreview, {\n restoredSnapshot: restoringSnapshotRef.current,\n })\n setIsRestoringSession(false)\n } else {\n setIsRestoringSession(true)\n }\n\n const restoreSession = async () => {\n const call = await apiCall<UploadResponse>(\n `/api/sync_excel/preview?uploadId=${encodeURIComponent(resolvedUploadId)}&entityType=${encodeURIComponent(ENTITY_TYPE)}`,\n undefined,\n { fallback: null },\n )\n\n if (cancelled) return\n\n if (!call.ok || !call.result) {\n setPreview(null)\n setMappingRows([])\n setMatchStrategy('custom')\n setRunId(null)\n setRunDetail(null)\n setProgressJobId(null)\n clearPersistedSession()\n lastRestoreRequestKeyRef.current = null\n setIsRestoringSession(false)\n return\n }\n\n syncPreviewState(call.result, {\n restoredSnapshot: restoringSnapshotRef.current,\n })\n\n if (resolvedRunId && !(restoringSnapshotRef.current?.runId)) {\n setRunId(resolvedRunId)\n }\n\n setIsRestoringSession(false)\n }\n\n void restoreSession()\n\n return () => {\n cancelled = true\n }\n }, [clearPersistedSession, context.integrationId, mappingRows.length, preview?.uploadId, replaceQueryParams, runId, runIdFromUrl, syncPreviewState, uploadIdFromUrl])\n\n React.useEffect(() => {\n if (!runId) return\n\n let cancelled = false\n let timeoutId: ReturnType<typeof setTimeout> | null = null\n\n const poll = async () => {\n const detail = await refreshRunDetail(runId)\n if (cancelled) return\n if (context.activeTab === 'logs') {\n await context.refreshLogs?.()\n }\n if (context.activeTab === 'health' || normalizeStatus(detail?.status) !== 'idle') {\n await context.refreshHealthSnapshot?.()\n }\n const status = normalizeStatus(detail?.status)\n if (status === 'pending' || status === 'running') {\n timeoutId = setTimeout(() => {\n void poll()\n }, RUN_POLL_INTERVAL_MS)\n }\n }\n\n void poll()\n\n return () => {\n cancelled = true\n if (timeoutId) clearTimeout(timeoutId)\n }\n }, [context.activeTab, context.refreshHealthSnapshot, context.refreshLogs, refreshRunDetail, runId])\n\n const handleUpload = React.useCallback(async () => {\n if (!selectedFile) {\n flash(t('sync_excel.widget.messages.fileRequired', 'Select a CSV file first.'), 'error')\n return\n }\n\n setIsUploading(true)\n try {\n const formData = new FormData()\n formData.set('file', selectedFile)\n formData.set('entityType', ENTITY_TYPE)\n\n const call = await runMutation({\n operation: () => apiCall<UploadResponse>('/api/sync_excel/upload', {\n method: 'POST',\n body: formData,\n }, { fallback: null }),\n mutationPayload: {\n integrationId: context.integrationId ?? 'sync_excel',\n entityType: ENTITY_TYPE,\n fileName: selectedFile.name,\n },\n context: {\n ...context,\n operation: 'create',\n actionId: 'sync-excel-upload',\n },\n })\n\n if (!call.ok || !call.result) {\n flash(\n readApiErrorMessage(call.result as Record<string, unknown> | null, t('sync_excel.widget.messages.uploadError', 'Failed to upload CSV file.')),\n 'error',\n )\n return\n }\n\n syncPreviewState(call.result)\n setSelectedFile(null)\n setRunId(null)\n setRunDetail(null)\n setProgressJobId(null)\n flash(t('sync_excel.widget.messages.uploadSuccess', 'CSV preview is ready.'), 'success')\n } catch {\n flash(t('sync_excel.widget.messages.uploadError', 'Failed to upload CSV file.'), 'error')\n } finally {\n setIsUploading(false)\n }\n }, [context, runMutation, selectedFile, syncPreviewState, t])\n\n const handleRefreshPreview = React.useCallback(async () => {\n if (!preview) return\n setIsRefreshingPreview(true)\n try {\n const call = await apiCall<UploadResponse>(\n `/api/sync_excel/preview?uploadId=${encodeURIComponent(preview.uploadId)}&entityType=${encodeURIComponent(ENTITY_TYPE)}`,\n undefined,\n { fallback: null },\n )\n if (!call.ok || !call.result) {\n flash(t('sync_excel.widget.messages.previewError', 'Failed to refresh preview.'), 'error')\n return\n }\n syncPreviewState(call.result, { preserveManualState: true })\n flash(t('sync_excel.widget.messages.previewRefreshed', 'Preview refreshed.'), 'success')\n } catch {\n flash(t('sync_excel.widget.messages.previewError', 'Failed to refresh preview.'), 'error')\n } finally {\n setIsRefreshingPreview(false)\n }\n }, [preview, syncPreviewState, t])\n\n const handleTargetFieldChange = React.useCallback((sourceColumn: string, targetField: string) => {\n setIsMappingDirty(true)\n setMappingRows((current) => current.map((row) => row.sourceColumn === sourceColumn ? { ...row, targetField } : row))\n }, [])\n\n const handleResetToSuggested = React.useCallback(() => {\n if (!preview || !previewSuggestion) return\n setMappingRows(buildMappingRows(preview.headers, previewSuggestion))\n setMatchStrategy(previewSuggestion.matchStrategy)\n setIsMappingDirty(false)\n lastAppliedSuggestionSignatureRef.current = buildSuggestedMappingSignature(preview.headers, previewSuggestion)\n flash(t('sync_excel.widget.messages.mappingReset', 'Suggested mapping restored.'), 'success')\n }, [preview, previewSuggestion, t])\n\n const handleStartImport = React.useCallback(async () => {\n if (!preview) return\n\n const mapping = buildMapping(mappingRows, matchStrategy, targetOptions)\n setIsStartingImport(true)\n\n try {\n const call = await runMutation({\n operation: () => apiCall<ImportResponse>('/api/sync_excel/import', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n uploadId: preview.uploadId,\n entityType: ENTITY_TYPE,\n mapping,\n }),\n }, { fallback: null }),\n mutationPayload: {\n integrationId: context.integrationId ?? 'sync_excel',\n uploadId: preview.uploadId,\n entityType: ENTITY_TYPE,\n mapping,\n },\n context: {\n ...context,\n operation: 'create',\n actionId: 'sync-excel-start-import',\n },\n })\n\n if (!call.ok || !call.result) {\n flash(\n readApiErrorMessage(call.result as Record<string, unknown> | null, t('sync_excel.widget.messages.importError', 'Failed to start import run.')),\n 'error',\n )\n return\n }\n\n setRunId(call.result.runId)\n setProgressJobId(call.result.progressJobId)\n replaceQueryParams({\n uploadId: preview.uploadId,\n runId: call.result.runId,\n })\n persistCurrentSession({\n uploadId: preview.uploadId,\n filename: preview.filename,\n runId: call.result.runId,\n progressJobId: call.result.progressJobId,\n })\n flash(t('sync_excel.widget.messages.importStarted', 'Import run started.'), 'success')\n await refreshRunDetail(call.result.runId)\n await context.refreshLogs?.()\n await context.refreshHealthSnapshot?.()\n } catch {\n flash(t('sync_excel.widget.messages.importError', 'Failed to start import run.'), 'error')\n } finally {\n setIsStartingImport(false)\n }\n }, [context, mappingRows, matchStrategy, persistCurrentSession, preview, refreshRunDetail, replaceQueryParams, runMutation, t, targetOptions])\n\n const handleCancelRun = React.useCallback(async () => {\n if (!runId) return\n\n setIsCancelling(true)\n try {\n const call = await runMutation({\n operation: () => apiCall<{ ok?: boolean }>(`/api/data_sync/runs/${encodeURIComponent(runId)}/cancel`, {\n method: 'POST',\n }, { fallback: null }),\n mutationPayload: {\n integrationId: context.integrationId ?? 'sync_excel',\n runId,\n },\n context: {\n ...context,\n operation: 'update',\n actionId: 'sync-excel-cancel-import',\n },\n })\n\n if (!call.ok) {\n flash(t('sync_excel.widget.messages.cancelError', 'Failed to cancel import run.'), 'error')\n return\n }\n\n flash(t('sync_excel.widget.messages.cancelSuccess', 'Import run cancelled.'), 'success')\n await refreshRunDetail(runId)\n await context.refreshLogs?.()\n await context.refreshHealthSnapshot?.()\n } catch {\n flash(t('sync_excel.widget.messages.cancelError', 'Failed to cancel import run.'), 'error')\n } finally {\n setIsCancelling(false)\n }\n }, [context, refreshRunDetail, runId, runMutation, t])\n\n const handleRefreshAll = React.useCallback(async () => {\n if (!runId) return\n await refreshRunDetail(runId)\n await context.refreshLogs?.()\n await context.refreshHealthSnapshot?.()\n }, [context, refreshRunDetail, runId])\n\n const firstSampleRow = preview?.sampleRows[0] ?? null\n\n return (\n <div className=\"space-y-6\">\n {isRestoringSession ? (\n <Card>\n <CardContent className=\"flex items-center gap-3 py-6\">\n <Spinner className=\"size-4\" />\n <div className=\"text-sm text-muted-foreground\">\n {t('sync_excel.widget.messages.restoringSession', 'Restoring the last CSV session...')}\n </div>\n </CardContent>\n </Card>\n ) : null}\n\n {!resolvedIntegrationEnabled ? (\n <StatusAlert\n variant=\"warning\"\n title={t('sync_excel.widget.disabled.title', 'Integration disabled')}\n message={t('sync_excel.widget.disabled.message', 'Enable this integration to upload CSV files and start imports.')}\n />\n ) : null}\n\n {!shouldHideInteractiveContent ? (\n <Card>\n <CardHeader>\n <CardTitle>{t('sync_excel.widget.upload.title', 'Upload CSV')}</CardTitle>\n <CardDescription>\n {t('sync_excel.widget.upload.description', 'Upload a CSV file, review the suggested people mapping, and start a background import run.')}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"sync-excel-upload-file\">{t('sync_excel.widget.upload.fileLabel', 'CSV file')}</Label>\n <Input\n id=\"sync-excel-upload-file\"\n type=\"file\"\n accept=\".csv,text/csv\"\n onChange={(event) => setSelectedFile(event.target.files?.[0] ?? null)}\n disabled={isUploading || isRunActive || isRestoringSession}\n />\n </div>\n\n <div className=\"flex flex-wrap items-center gap-3\">\n <Button type=\"button\" onClick={() => void handleUpload()} disabled={!selectedFile || isUploading || isRunActive || isRestoringSession}>\n {isUploading ? <Spinner className=\"mr-2 size-4\" /> : <Upload className=\"mr-2 size-4\" />}\n {isUploading\n ? t('sync_excel.widget.actions.uploadPending', 'Uploading...')\n : t('sync_excel.widget.actions.upload', 'Upload and preview')}\n </Button>\n {preview ? (\n <Button type=\"button\" variant=\"outline\" onClick={() => void handleRefreshPreview()} disabled={isRefreshingPreview || isUploading || isRunActive || isRestoringSession}>\n {isRefreshingPreview ? <Spinner className=\"mr-2 size-4\" /> : <RefreshCw className=\"mr-2 size-4\" />}\n {isRefreshingPreview\n ? t('sync_excel.widget.actions.refreshPending', 'Refreshing...')\n : t('sync_excel.widget.actions.refresh', 'Refresh preview')}\n </Button>\n ) : null}\n </div>\n\n {selectedFile ? (\n <div className=\"text-sm text-muted-foreground\">\n {t('sync_excel.widget.upload.selectedFile', 'Selected file')}: <span className=\"font-medium text-foreground\">{selectedFile.name}</span>\n </div>\n ) : null}\n </CardContent>\n </Card>\n ) : null}\n\n {preview && !shouldHideInteractiveContent ? (\n <Card>\n <CardHeader>\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"space-y-1\">\n <CardTitle>{t('sync_excel.widget.preview.title', 'Preview and mapping')}</CardTitle>\n <CardDescription>\n {t('sync_excel.widget.preview.description', 'Every source column stays visible here. Leave a target empty to keep the column unmapped for now.')}\n </CardDescription>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <Badge variant=\"outline\">{preview.filename}</Badge>\n <Badge variant=\"outline\">{t('sync_excel.widget.preview.rows', '{count} rows', { count: preview.totalRows })}</Badge>\n <Badge variant=\"outline\">{formatFileSize(preview.fileSize)}</Badge>\n </div>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n <MetricCard\n label={t('sync_excel.widget.metrics.mapped', 'Mapped columns')}\n value={String(diagnostics.mappedCount)}\n />\n <MetricCard\n label={t('sync_excel.widget.metrics.unmapped', 'Unmapped columns')}\n value={String(diagnostics.unmappedCount)}\n />\n <MetricCard\n label={t('sync_excel.widget.metrics.identity', 'Identity strategy')}\n value={getMatchStrategyLabel(matchStrategy, t)}\n />\n <MetricCard\n label={t('sync_excel.widget.metrics.entity', 'Target entity')}\n value={ENTITY_TYPE}\n />\n </div>\n\n <div className=\"grid gap-4 lg:grid-cols-[minmax(0,1fr)_280px]\">\n <div className=\"overflow-hidden rounded-lg border\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('sync_excel.widget.mapping.sourceColumn', 'Source column')}</TableHead>\n <TableHead>{t('sync_excel.widget.mapping.sampleValue', 'Sample value')}</TableHead>\n <TableHead>{t('sync_excel.widget.mapping.targetField', 'Target field')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {mappingRows.map((row) => (\n <TableRow key={row.sourceColumn}>\n <TableCell className=\"font-medium\">{row.sourceColumn}</TableCell>\n <TableCell className=\"max-w-[260px] truncate text-muted-foreground\">\n {firstSampleRow?.[row.sourceColumn] ?? '\u2014'}\n </TableCell>\n <TableCell>\n <select\n className={SELECT_CLASS_NAME}\n value={row.targetField}\n onChange={(event) => handleTargetFieldChange(row.sourceColumn, event.target.value)}\n disabled={isStartingImport || isRunActive}\n >\n <option value=\"\">{t('sync_excel.mapping.targets.ignore', 'Leave unmapped')}</option>\n {targetOptions.map((option) => (\n <option key={option.value} value={option.value}>\n {option.labelKey ? t(option.labelKey, option.fallback) : option.fallback}\n </option>\n ))}\n </select>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"sync-excel-match-strategy\">\n {t('sync_excel.widget.matchStrategy.label', 'How to match existing people')}\n </Label>\n <p className=\"text-sm text-muted-foreground\">\n {t(\n 'sync_excel.widget.matchStrategy.help',\n 'This decides whether imported rows update existing people or create new ones.',\n )}\n </p>\n <select\n id=\"sync-excel-match-strategy\"\n className={SELECT_CLASS_NAME}\n value={matchStrategy}\n onChange={(event) => {\n setIsMappingDirty(true)\n setMatchStrategy(event.target.value as SuggestedMapping['matchStrategy'])\n }}\n disabled={isStartingImport || isRunActive}\n >\n <option value=\"externalId\">\n {t('sync_excel.widget.matchStrategy.externalId', 'Source record ID (Recommended)')}\n </option>\n <option value=\"email\">{t('sync_excel.widget.matchStrategy.email', 'Email address')}</option>\n <option value=\"custom\">{t('sync_excel.widget.matchStrategy.custom', 'Custom matching')}</option>\n </select>\n <p className=\"text-sm text-muted-foreground\">\n {matchStrategy === 'externalId'\n ? t(\n 'sync_excel.widget.matchStrategy.externalIdDescription',\n 'Best for repeated imports from the same source. Future imports update the same people instead of creating duplicates.',\n )\n : matchStrategy === 'email'\n ? t(\n 'sync_excel.widget.matchStrategy.emailDescription',\n 'Matches people by email. Works best when each person has one reliable, unique email address.',\n )\n : t(\n 'sync_excel.widget.matchStrategy.customDescription',\n 'Advanced option. Use only if you know how existing records should be identified in this import.',\n )}\n </p>\n </div>\n\n <div className=\"flex flex-wrap gap-2\">\n <Button type=\"button\" variant=\"outline\" onClick={handleResetToSuggested} disabled={isStartingImport || isRunActive}>\n <RefreshCw className=\"mr-2 size-4\" />\n {t('sync_excel.widget.actions.reset', 'Reset to suggestion')}\n </Button>\n <Button type=\"button\" onClick={() => void handleStartImport()} disabled={!canStartImport || isStartingImport || isRunActive}>\n {isStartingImport ? <Spinner className=\"mr-2 size-4\" /> : <Play className=\"mr-2 size-4\" />}\n {isStartingImport\n ? t('sync_excel.widget.actions.startPending', 'Starting...')\n : t('sync_excel.widget.actions.start', 'Start import')}\n </Button>\n </div>\n\n {matchStrategy === 'custom' ? (\n <StatusAlert\n variant=\"warning\"\n title={t('sync_excel.widget.matchStrategy.customWarningTitle', 'Use custom matching with care')}\n message={t(\n 'sync_excel.widget.matchStrategy.customWarningMessage',\n 'Custom matching may create duplicates if the mapped fields do not uniquely identify a person.',\n )}\n />\n ) : null}\n\n {hasExistingRunForCurrentUpload ? (\n <StatusAlert\n variant=\"warning\"\n title={t('sync_excel.widget.validation.reimportTitle', 'This upload already has a run')}\n message={t(\n 'sync_excel.widget.validation.reimportMessage',\n 'Starting another import from the same uploaded CSV may create duplicates unless your matching strategy reliably identifies existing people.',\n )}\n />\n ) : null}\n\n {!hasSafeDedupeStrategy ? (\n <StatusAlert\n variant=\"warning\"\n title={t('sync_excel.widget.validation.duplicateRiskTitle', 'Duplicate risk')}\n message={t(\n 'sync_excel.widget.validation.duplicateRiskMessage',\n 'This mapping does not use the recommended External ID or Email matching strategy. Re-importing the same dataset may create duplicate people.',\n )}\n />\n ) : null}\n\n {diagnostics.duplicateTargets.length > 0 ? (\n <StatusAlert\n variant=\"error\"\n title={t('sync_excel.widget.validation.duplicateTargetsTitle', 'Duplicate target fields')}\n message={t(\n 'sync_excel.widget.validation.duplicateTargetsMessage',\n 'Each target field can only be mapped once in this foundation slice: {targets}',\n { targets: diagnostics.duplicateTargets.map((target) => formatTargetLabel(target, t, targetOptions)).join(', ') },\n )}\n />\n ) : null}\n\n {!diagnostics.hasIdentityTarget ? (\n <StatusAlert\n variant=\"warning\"\n title={t('sync_excel.widget.validation.identityTitle', 'Map an identity field')}\n message={t('sync_excel.widget.validation.identityMessage', 'Map either External ID or Primary email so reimports can match existing people.')}\n />\n ) : null}\n\n {!diagnostics.hasNameTarget ? (\n <StatusAlert\n variant=\"warning\"\n title={t('sync_excel.widget.validation.nameTitle', 'Map a name field')}\n message={t('sync_excel.widget.validation.nameMessage', 'Map Last name or Display name so the importer can build person records.')}\n />\n ) : null}\n\n {diagnostics.hasIdentityTarget && diagnostics.hasNameTarget && diagnostics.duplicateTargets.length === 0 ? (\n <StatusAlert\n variant=\"info\"\n title={t('sync_excel.widget.validation.readyTitle', 'Ready to import')}\n message={t('sync_excel.widget.validation.readyMessage', 'The current mapping is valid for the first customers.person slice.')}\n />\n ) : null}\n </div>\n </div>\n </CardContent>\n </Card>\n ) : null}\n\n {runId && !shouldHideInteractiveContent ? (\n <Card>\n <CardHeader>\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"space-y-1\">\n <CardTitle>{t('sync_excel.widget.run.title', 'Import run status')}</CardTitle>\n <CardDescription>\n {t('sync_excel.widget.run.description', 'The import runs in the background through Data Sync and updates this view as progress changes.')}\n </CardDescription>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <RunStatusBadge status={importStatus} t={t} />\n {progressJobId ? <Badge variant=\"outline\">{progressJobId}</Badge> : null}\n </div>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"text-muted-foreground\">{t('sync_excel.widget.run.progressLabel', 'Progress')}</span>\n <span className=\"font-medium\">{progressValue}%</span>\n </div>\n <Progress value={progressValue} className=\"h-2.5\" />\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-5\">\n <MetricCard label={t('sync_excel.widget.run.metrics.created', 'Created')} value={String(runDetail?.createdCount ?? 0)} />\n <MetricCard label={t('sync_excel.widget.run.metrics.updated', 'Updated')} value={String(runDetail?.updatedCount ?? 0)} />\n <MetricCard label={t('sync_excel.widget.run.metrics.skipped', 'Skipped')} value={String(runDetail?.skippedCount ?? 0)} />\n <MetricCard label={t('sync_excel.widget.run.metrics.failed', 'Failed')} value={String(runDetail?.failedCount ?? 0)} />\n <MetricCard label={t('sync_excel.widget.run.metrics.processed', 'Processed')} value={String(runDetail?.progressJob?.processedCount ?? 0)} />\n </div>\n\n {runDetail?.lastError ? (\n <StatusAlert\n variant=\"error\"\n title={t('sync_excel.widget.run.errorTitle', 'Run error')}\n message={runDetail.lastError}\n />\n ) : null}\n\n <div className=\"flex flex-wrap gap-2\">\n <Button type=\"button\" variant=\"outline\" onClick={() => void handleRefreshAll()} disabled={isRefreshingPreview || isRestoringSession}>\n <RefreshCw className=\"mr-2 size-4\" />\n {t('sync_excel.widget.actions.refreshRun', 'Refresh run status')}\n </Button>\n {isRunActive ? (\n <Button type=\"button\" variant=\"destructive\" onClick={() => void handleCancelRun()} disabled={isCancelling}>\n {isCancelling ? <Spinner className=\"mr-2 size-4\" /> : <XCircle className=\"mr-2 size-4\" />}\n {isCancelling\n ? t('sync_excel.widget.actions.cancelPending', 'Cancelling...')\n : t('sync_excel.widget.actions.cancel', 'Cancel run')}\n </Button>\n ) : null}\n </div>\n </CardContent>\n </Card>\n ) : null}\n </div>\n )\n}\n\nfunction StatusAlert({\n variant,\n title,\n message,\n}: {\n variant: 'warning' | 'error' | 'info'\n title: string\n message: string\n}) {\n return (\n <Alert variant={variant === 'error' ? 'destructive' : variant}>\n <AlertTitle>{title}</AlertTitle>\n <AlertDescription>{message}</AlertDescription>\n </Alert>\n )\n}\n\nfunction MetricCard({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"rounded-lg border bg-muted/30 p-4\">\n <div className=\"text-xs font-medium uppercase tracking-wide text-muted-foreground\">{label}</div>\n <div className=\"mt-2 text-lg font-semibold text-foreground\">{value}</div>\n </div>\n )\n}\n\ntype RunStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled' | 'idle'\n\nexport const RUN_STATUS_BADGE_VARIANTS: StatusMap<RunStatus> = {\n completed: 'success',\n failed: 'error',\n cancelled: 'neutral',\n pending: 'info',\n running: 'info',\n idle: 'neutral',\n}\n\nexport function RunStatusBadge({\n status,\n t,\n}: {\n status: RunStatus\n t: ReturnType<typeof useT>\n}) {\n const variant = RUN_STATUS_BADGE_VARIANTS[status] ?? 'neutral'\n\n if (status === 'completed') {\n return (\n <StatusBadge variant={variant} className=\"gap-1.5\">\n <CheckCircle2 className=\"size-3.5\" />\n {t('sync_excel.widget.run.status.completed', 'Completed')}\n </StatusBadge>\n )\n }\n\n if (status === 'failed') {\n return (\n <StatusBadge variant={variant} className=\"gap-1.5\">\n <AlertTriangle className=\"size-3.5\" />\n {t('sync_excel.widget.run.status.failed', 'Failed')}\n </StatusBadge>\n )\n }\n\n if (status === 'cancelled') {\n return (\n <StatusBadge variant={variant} className=\"gap-1.5\">\n <XCircle className=\"size-3.5\" />\n {t('sync_excel.widget.run.status.cancelled', 'Cancelled')}\n </StatusBadge>\n )\n }\n\n if (status === 'pending' || status === 'running') {\n return (\n <StatusBadge variant={variant} className=\"gap-1.5\">\n <RefreshCw className={cn('size-3.5', status === 'running' ? 'animate-spin' : '')} />\n {status === 'pending'\n ? t('sync_excel.widget.run.status.pending', 'Pending')\n : t('sync_excel.widget.run.status.running', 'Running')}\n </StatusBadge>\n )\n }\n\n return (\n <StatusBadge variant={variant}>\n {t('sync_excel.widget.run.status.idle', 'Idle')}\n </StatusBadge>\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { usePathname, useRouter, useSearchParams } from 'next/navigation'\nimport type { InjectionWidgetComponentProps } from '@open-mercato/shared/modules/widgets/injection'\nimport type { FieldMapping } from '../../../../data_sync/lib/adapter'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useCustomFieldDefs } from '@open-mercato/ui/backend/utils/customFieldDefs'\nimport { Alert, AlertDescription, AlertTitle } from '@open-mercato/ui/primitives/alert'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { StatusBadge, type StatusMap } from '@open-mercato/ui/primitives/status-badge'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@open-mercato/ui/primitives/card'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Progress } from '@open-mercato/ui/primitives/progress'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@open-mercato/ui/primitives/table'\nimport { AlertTriangle, CheckCircle2, Play, RefreshCw, Upload, XCircle } from 'lucide-react'\nimport {\n buildPeopleSuggestedMapping,\n buildPeopleTargetOptions,\n buildSuggestedMappingSignature,\n findMappingTargetOption,\n SYNC_EXCEL_PEOPLE_CUSTOM_FIELD_ENTITY_IDS,\n type MappingTargetOption,\n type SuggestedMapping,\n} from './target-options'\n\ntype SyncExcelIntegrationContext = {\n formId?: string\n integrationDetailWidgetSpotId?: string\n integrationId?: string\n activeTab?: string\n state?: {\n isEnabled?: boolean\n } | null\n refreshDetail?: () => Promise<void>\n refreshLogs?: () => Promise<void>\n refreshHealthSnapshot?: () => Promise<void>\n}\n\ntype SyncExcelIntegrationData = {\n state?: {\n isEnabled?: boolean\n } | null\n}\n\ntype PreviewRow = Record<string, string | null>\n\ntype UploadResponse = {\n uploadId: string\n filename: string\n mimeType: string\n fileSize: number\n entityType: 'customers.person'\n headers: string[]\n sampleRows: PreviewRow[]\n totalRows: number\n suggestedMapping: SuggestedMapping\n}\n\ntype ImportResponse = {\n runId: string\n progressJobId: string | null\n status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled'\n}\n\ntype SyncRunDetail = {\n id: string\n status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled' | 'paused'\n createdCount: number\n updatedCount: number\n skippedCount: number\n failedCount: number\n lastError: string | null\n progressJobId: string | null\n progressJob: {\n id: string\n status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled'\n progressPercent: number\n processedCount: number\n totalCount: number | null\n etaSeconds: number | null\n } | null\n}\n\ntype MappingRowState = {\n sourceColumn: string\n targetField: string\n}\n\ntype MappingDiagnostics = {\n duplicateTargets: string[]\n hasNameTarget: boolean\n hasIdentityTarget: boolean\n mappedCount: number\n unmappedCount: number\n}\n\ntype PersistedSessionSnapshot = {\n uploadId: string\n filename: string\n preview: UploadResponse | null\n mappingRows: MappingRowState[]\n matchStrategy: SuggestedMapping['matchStrategy']\n runId: string | null\n progressJobId: string | null\n}\n\nconst ENTITY_TYPE = 'customers.person' as const\nconst SESSION_STORAGE_PREFIX = 'om:sync_excel:session'\nconst RUN_POLL_INTERVAL_MS = 4_000\n\nconst SELECT_CLASS_NAME = 'flex h-9 w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50'\n\nfunction buildMappingRows(headers: string[], suggestedMapping: SuggestedMapping): MappingRowState[] {\n const mappedFields = new Map(suggestedMapping.fields.map((field) => [field.externalField, field.localField]))\n return headers.map((header) => ({\n sourceColumn: header,\n targetField: mappedFields.get(header) ?? '',\n }))\n}\n\nfunction buildFieldMapping(sourceColumn: string, targetField: string, targetOptions: MappingTargetOption[]): FieldMapping {\n const matchedOption = findMappingTargetOption(targetOptions, targetField)\n const mappingKind = matchedOption?.mappingKind ?? (targetField.startsWith('cf:') ? 'custom_field' : 'core')\n const dedupeRole = matchedOption?.dedupeRole\n\n return {\n externalField: sourceColumn,\n localField: targetField,\n mappingKind,\n ...(dedupeRole ? { dedupeRole } : {}),\n }\n}\n\nfunction inferMatchStrategy(rows: MappingRowState[]): SuggestedMapping['matchStrategy'] {\n if (rows.some((row) => row.targetField === 'person.externalId')) return 'externalId'\n if (rows.some((row) => row.targetField === 'person.primaryEmail')) return 'email'\n return 'custom'\n}\n\nfunction buildMapping(\n rows: MappingRowState[],\n matchStrategy: SuggestedMapping['matchStrategy'],\n targetOptions: MappingTargetOption[],\n): SuggestedMapping {\n const mappedRows = rows.filter((row) => row.targetField.trim().length > 0)\n const fields = mappedRows.map((row) => buildFieldMapping(row.sourceColumn, row.targetField, targetOptions))\n const resolvedMatchStrategy = matchStrategy === 'custom' ? inferMatchStrategy(rows) : matchStrategy\n const matchField = resolvedMatchStrategy === 'externalId'\n ? 'person.externalId'\n : resolvedMatchStrategy === 'email'\n ? 'person.primaryEmail'\n : undefined\n\n return {\n entityType: ENTITY_TYPE,\n matchStrategy: resolvedMatchStrategy,\n ...(matchField ? { matchField } : {}),\n fields,\n unmappedColumns: rows.filter((row) => row.targetField.trim().length === 0).map((row) => row.sourceColumn),\n }\n}\n\nfunction buildDiagnostics(rows: MappingRowState[]): MappingDiagnostics {\n const duplicateTargets = Array.from(\n rows\n .filter((row) => row.targetField.trim().length > 0)\n .reduce((accumulator, row) => {\n const nextCount = (accumulator.get(row.targetField) ?? 0) + 1\n accumulator.set(row.targetField, nextCount)\n return accumulator\n }, new Map<string, number>())\n .entries(),\n )\n .filter(([, count]) => count > 1)\n .map(([target]) => target)\n\n const hasNameTarget = rows.some((row) => row.targetField === 'person.lastName' || row.targetField === 'person.displayName')\n const hasIdentityTarget = rows.some((row) => row.targetField === 'person.externalId' || row.targetField === 'person.primaryEmail')\n const mappedCount = rows.filter((row) => row.targetField.trim().length > 0).length\n\n return {\n duplicateTargets,\n hasNameTarget,\n hasIdentityTarget,\n mappedCount,\n unmappedCount: rows.length - mappedCount,\n }\n}\n\nfunction formatTargetLabel(\n targetField: string,\n t: ReturnType<typeof useT>,\n targetOptions: MappingTargetOption[],\n): string {\n const option = findMappingTargetOption(targetOptions, targetField)\n if (!option) return targetField\n return option.labelKey ? t(option.labelKey, option.fallback) : option.fallback\n}\n\nfunction getMatchStrategyLabel(\n matchStrategy: SuggestedMapping['matchStrategy'],\n t: ReturnType<typeof useT>,\n): string {\n if (matchStrategy === 'externalId') {\n return t('sync_excel.widget.matchStrategy.externalId', 'Source record ID (Recommended)')\n }\n if (matchStrategy === 'email') {\n return t('sync_excel.widget.matchStrategy.email', 'Email address')\n }\n return t('sync_excel.widget.matchStrategy.custom', 'Custom matching')\n}\n\nfunction formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n\nfunction readApiErrorMessage(result: Record<string, unknown> | null | undefined, fallback: string): string {\n const value = result?.error\n if (typeof value === 'string' && value.trim().length > 0) return value\n return fallback\n}\n\nfunction normalizeStatus(status: SyncRunDetail['status'] | ImportResponse['status'] | null | undefined): 'pending' | 'running' | 'completed' | 'failed' | 'cancelled' | 'idle' {\n if (status === 'pending' || status === 'running' || status === 'completed' || status === 'failed' || status === 'cancelled') {\n return status\n }\n return 'idle'\n}\n\nfunction getSessionStorageKey(integrationId: string | undefined): string {\n return `${SESSION_STORAGE_PREFIX}:${integrationId ?? 'sync_excel'}`\n}\n\nfunction readPersistedSessionSnapshot(integrationId: string | undefined): PersistedSessionSnapshot | null {\n if (typeof window === 'undefined') return null\n try {\n const raw = window.sessionStorage.getItem(getSessionStorageKey(integrationId))\n if (!raw) return null\n const parsed = JSON.parse(raw) as Partial<PersistedSessionSnapshot> | null\n if (!parsed || typeof parsed !== 'object') return null\n if (typeof parsed.uploadId !== 'string' || parsed.uploadId.trim().length === 0) return null\n if (typeof parsed.filename !== 'string') return null\n if (!Array.isArray(parsed.mappingRows)) return null\n if (parsed.matchStrategy !== 'externalId' && parsed.matchStrategy !== 'email' && parsed.matchStrategy !== 'custom') {\n return null\n }\n const preview = (\n parsed.preview\n && typeof parsed.preview === 'object'\n && typeof parsed.preview.uploadId === 'string'\n && parsed.preview.uploadId.trim().length > 0\n && typeof parsed.preview.filename === 'string'\n && Array.isArray(parsed.preview.headers)\n && Array.isArray(parsed.preview.sampleRows)\n && typeof parsed.preview.totalRows === 'number'\n && typeof parsed.preview.fileSize === 'number'\n && parsed.preview.entityType === ENTITY_TYPE\n && parsed.preview.suggestedMapping\n )\n ? parsed.preview as UploadResponse\n : null\n\n return {\n uploadId: parsed.uploadId,\n filename: parsed.filename,\n preview,\n mappingRows: parsed.mappingRows\n .filter((row): row is MappingRowState => (\n Boolean(row)\n && typeof row.sourceColumn === 'string'\n && typeof row.targetField === 'string'\n )),\n matchStrategy: parsed.matchStrategy,\n runId: typeof parsed.runId === 'string' && parsed.runId.trim().length > 0 ? parsed.runId : null,\n progressJobId: typeof parsed.progressJobId === 'string' && parsed.progressJobId.trim().length > 0 ? parsed.progressJobId : null,\n }\n } catch {\n return null\n }\n}\n\nfunction writePersistedSessionSnapshot(\n integrationId: string | undefined,\n snapshot: PersistedSessionSnapshot | null,\n): void {\n if (typeof window === 'undefined') return\n try {\n const key = getSessionStorageKey(integrationId)\n if (!snapshot) {\n window.sessionStorage.removeItem(key)\n return\n }\n window.sessionStorage.setItem(key, JSON.stringify(snapshot))\n } catch {\n // sessionStorage can be unavailable in private/locked-down browser contexts; persistence is best-effort.\n }\n}\n\nexport default function SyncExcelUploadConfigWidget({\n context,\n data,\n}: InjectionWidgetComponentProps<SyncExcelIntegrationContext, SyncExcelIntegrationData>) {\n const pathname = usePathname()\n const router = useRouter()\n const searchParams = useSearchParams()\n const t = useT()\n const { data: customFieldDefs = [] } = useCustomFieldDefs([...SYNC_EXCEL_PEOPLE_CUSTOM_FIELD_ENTITY_IDS])\n const [selectedFile, setSelectedFile] = React.useState<File | null>(null)\n const [preview, setPreview] = React.useState<UploadResponse | null>(null)\n const [mappingRows, setMappingRows] = React.useState<MappingRowState[]>([])\n const [matchStrategy, setMatchStrategy] = React.useState<SuggestedMapping['matchStrategy']>('custom')\n const [isMappingDirty, setIsMappingDirty] = React.useState(false)\n const [runDetail, setRunDetail] = React.useState<SyncRunDetail | null>(null)\n const [runId, setRunId] = React.useState<string | null>(null)\n const [progressJobId, setProgressJobId] = React.useState<string | null>(null)\n const [isUploading, setIsUploading] = React.useState(false)\n const [isRefreshingPreview, setIsRefreshingPreview] = React.useState(false)\n const [isStartingImport, setIsStartingImport] = React.useState(false)\n const [isCancelling, setIsCancelling] = React.useState(false)\n const [isRestoringSession, setIsRestoringSession] = React.useState(true)\n const mutationContextId = `${context.formId ?? 'sync-excel'}:sync-excel-import`\n const lastAppliedSuggestionSignatureRef = React.useRef<string | null>(null)\n const restoringSnapshotRef = React.useRef<PersistedSessionSnapshot | null>(null)\n const lastRestoreRequestKeyRef = React.useRef<string | null>(null)\n const { runMutation } = useGuardedMutation<Record<string, unknown>>({\n contextId: mutationContextId,\n spotId: context.integrationDetailWidgetSpotId,\n })\n\n const targetOptions = React.useMemo(\n () => buildPeopleTargetOptions(customFieldDefs),\n [customFieldDefs],\n )\n const previewSuggestion = React.useMemo(\n () => preview ? buildPeopleSuggestedMapping(preview.headers, preview.suggestedMapping, customFieldDefs) : null,\n [customFieldDefs, preview],\n )\n const resolvedIntegrationEnabled = data?.state?.isEnabled ?? context.state?.isEnabled ?? true\n const diagnostics = React.useMemo(() => buildDiagnostics(mappingRows), [mappingRows])\n const canStartImport = Boolean(preview)\n && diagnostics.duplicateTargets.length === 0\n && diagnostics.hasNameTarget\n && diagnostics.hasIdentityTarget\n && mappingRows.some((row) => row.targetField.trim().length > 0)\n const importStatus = normalizeStatus(runDetail?.status ?? (runId ? 'pending' : null))\n const progressValue = runDetail?.progressJob?.progressPercent ?? 0\n const isRunActive = importStatus === 'pending' || importStatus === 'running'\n const searchParamsKey = searchParams?.toString() ?? ''\n const uploadIdFromUrl = searchParams?.get('uploadId') ?? null\n const runIdFromUrl = searchParams?.get('runId') ?? null\n const shouldHideInteractiveContent = isRestoringSession && Boolean(uploadIdFromUrl)\n const hasExistingRunForCurrentUpload = Boolean(preview?.uploadId && runId)\n const hasSafeDedupeStrategy = matchStrategy === 'externalId' || matchStrategy === 'email'\n\n const replaceQueryParams = React.useCallback((updates: Record<string, string | null | undefined>) => {\n const params = new URLSearchParams(searchParamsKey)\n for (const [key, value] of Object.entries(updates)) {\n if (typeof value === 'string' && value.trim().length > 0) {\n params.set(key, value)\n } else {\n params.delete(key)\n }\n }\n const query = params.toString()\n if (query === searchParamsKey) return\n router.replace(query ? `${pathname}?${query}` : pathname)\n }, [pathname, router, searchParamsKey])\n\n const clearPersistedSession = React.useCallback(() => {\n writePersistedSessionSnapshot(context.integrationId, null)\n replaceQueryParams({ uploadId: null, runId: null })\n }, [context.integrationId, replaceQueryParams])\n\n const persistCurrentSession = React.useCallback((next?: Partial<PersistedSessionSnapshot>) => {\n const persistedPreview = next?.preview ?? preview ?? null\n const uploadId = next?.uploadId ?? persistedPreview?.uploadId ?? null\n const filename = next?.filename ?? persistedPreview?.filename ?? null\n if (!uploadId || !filename) {\n writePersistedSessionSnapshot(context.integrationId, null)\n return\n }\n\n writePersistedSessionSnapshot(context.integrationId, {\n uploadId,\n filename,\n preview: persistedPreview,\n mappingRows: next?.mappingRows ?? mappingRows,\n matchStrategy: next?.matchStrategy ?? matchStrategy,\n runId: next?.runId ?? runId,\n progressJobId: next?.progressJobId ?? progressJobId,\n })\n }, [context.integrationId, mappingRows, matchStrategy, preview, progressJobId, runId])\n\n const syncPreviewState = React.useCallback((nextPreview: UploadResponse, options?: {\n preserveManualState?: boolean\n restoredSnapshot?: PersistedSessionSnapshot | null\n }) => {\n const nextSuggestedMapping = buildPeopleSuggestedMapping(nextPreview.headers, nextPreview.suggestedMapping, customFieldDefs)\n setPreview(nextPreview)\n\n const restoredSnapshot = options?.restoredSnapshot\n const shouldRestoreSnapshot = Boolean(\n restoredSnapshot\n && restoredSnapshot.uploadId === nextPreview.uploadId\n && restoredSnapshot.mappingRows.length > 0,\n )\n\n if (shouldRestoreSnapshot) {\n setMappingRows(restoredSnapshot!.mappingRows)\n setMatchStrategy(restoredSnapshot!.matchStrategy)\n setRunId(restoredSnapshot!.runId)\n setProgressJobId(restoredSnapshot!.progressJobId)\n setIsMappingDirty(true)\n lastAppliedSuggestionSignatureRef.current = null\n persistCurrentSession({\n uploadId: nextPreview.uploadId,\n filename: nextPreview.filename,\n preview: nextPreview,\n mappingRows: restoredSnapshot!.mappingRows,\n matchStrategy: restoredSnapshot!.matchStrategy,\n runId: restoredSnapshot!.runId,\n progressJobId: restoredSnapshot!.progressJobId,\n })\n replaceQueryParams({\n uploadId: nextPreview.uploadId,\n runId: restoredSnapshot!.runId,\n })\n return\n }\n\n if (options?.preserveManualState && preview?.uploadId === nextPreview.uploadId) {\n persistCurrentSession({\n uploadId: nextPreview.uploadId,\n filename: nextPreview.filename,\n preview: nextPreview,\n })\n replaceQueryParams({ uploadId: nextPreview.uploadId })\n return\n }\n\n const nextRows = buildMappingRows(nextPreview.headers, nextSuggestedMapping)\n setMappingRows(nextRows)\n setMatchStrategy(nextSuggestedMapping.matchStrategy)\n setIsMappingDirty(false)\n lastAppliedSuggestionSignatureRef.current = buildSuggestedMappingSignature(nextPreview.headers, nextSuggestedMapping)\n persistCurrentSession({\n uploadId: nextPreview.uploadId,\n filename: nextPreview.filename,\n preview: nextPreview,\n mappingRows: nextRows,\n matchStrategy: nextSuggestedMapping.matchStrategy,\n runId: null,\n progressJobId: null,\n })\n replaceQueryParams({\n uploadId: nextPreview.uploadId,\n runId: null,\n })\n }, [customFieldDefs, persistCurrentSession, preview?.uploadId, replaceQueryParams])\n\n React.useEffect(() => {\n if (!preview || !previewSuggestion) return\n if (isMappingDirty) return\n const nextSignature = buildSuggestedMappingSignature(preview.headers, previewSuggestion)\n if (lastAppliedSuggestionSignatureRef.current === nextSignature) return\n setMappingRows(buildMappingRows(preview.headers, previewSuggestion))\n setMatchStrategy(previewSuggestion.matchStrategy)\n lastAppliedSuggestionSignatureRef.current = nextSignature\n }, [isMappingDirty, preview, previewSuggestion])\n\n const refreshRunDetail = React.useCallback(async (currentRunId: string) => {\n const call = await apiCall<SyncRunDetail>(`/api/data_sync/runs/${encodeURIComponent(currentRunId)}`, undefined, { fallback: null })\n if (call.ok && call.result) {\n setRunDetail(call.result)\n setProgressJobId(call.result.progressJobId ?? null)\n persistCurrentSession({\n runId: currentRunId,\n progressJobId: call.result.progressJobId ?? null,\n })\n return call.result\n }\n return null\n }, [persistCurrentSession])\n\n React.useEffect(() => {\n if (!preview?.uploadId) return\n persistCurrentSession()\n }, [mappingRows, matchStrategy, persistCurrentSession, preview?.uploadId, progressJobId, runId])\n\n React.useEffect(() => {\n const persistedSnapshot = readPersistedSessionSnapshot(context.integrationId)\n const resolvedUploadId = uploadIdFromUrl ?? persistedSnapshot?.uploadId ?? null\n const resolvedRunId = runIdFromUrl ?? persistedSnapshot?.runId ?? null\n\n if (!resolvedUploadId) {\n restoringSnapshotRef.current = null\n lastRestoreRequestKeyRef.current = null\n setIsRestoringSession(false)\n return\n }\n\n if (!uploadIdFromUrl && persistedSnapshot?.uploadId === resolvedUploadId) {\n replaceQueryParams({\n uploadId: resolvedUploadId,\n runId: resolvedRunId,\n })\n }\n\n if (preview?.uploadId === resolvedUploadId && mappingRows.length > 0) {\n if (resolvedRunId && runId !== resolvedRunId) {\n setRunId(resolvedRunId)\n }\n setIsRestoringSession(false)\n return\n }\n\n const restoreRequestKey = `${resolvedUploadId}:${resolvedRunId ?? ''}`\n if (lastRestoreRequestKeyRef.current === restoreRequestKey) {\n setIsRestoringSession(false)\n return\n }\n\n lastRestoreRequestKeyRef.current = restoreRequestKey\n\n let cancelled = false\n restoringSnapshotRef.current = persistedSnapshot\n const persistedPreview = restoringSnapshotRef.current?.preview?.uploadId === resolvedUploadId\n ? restoringSnapshotRef.current.preview\n : null\n\n if (persistedPreview) {\n syncPreviewState(persistedPreview, {\n restoredSnapshot: restoringSnapshotRef.current,\n })\n setIsRestoringSession(false)\n } else {\n setIsRestoringSession(true)\n }\n\n const restoreSession = async () => {\n const call = await apiCall<UploadResponse>(\n `/api/sync_excel/preview?uploadId=${encodeURIComponent(resolvedUploadId)}&entityType=${encodeURIComponent(ENTITY_TYPE)}`,\n undefined,\n { fallback: null },\n )\n\n if (cancelled) return\n\n if (!call.ok || !call.result) {\n setPreview(null)\n setMappingRows([])\n setMatchStrategy('custom')\n setRunId(null)\n setRunDetail(null)\n setProgressJobId(null)\n clearPersistedSession()\n lastRestoreRequestKeyRef.current = null\n setIsRestoringSession(false)\n return\n }\n\n syncPreviewState(call.result, {\n restoredSnapshot: restoringSnapshotRef.current,\n })\n\n if (resolvedRunId && !(restoringSnapshotRef.current?.runId)) {\n setRunId(resolvedRunId)\n }\n\n setIsRestoringSession(false)\n }\n\n void restoreSession()\n\n return () => {\n cancelled = true\n }\n }, [clearPersistedSession, context.integrationId, mappingRows.length, preview?.uploadId, replaceQueryParams, runId, runIdFromUrl, syncPreviewState, uploadIdFromUrl])\n\n React.useEffect(() => {\n if (!runId) return\n\n let cancelled = false\n let timeoutId: ReturnType<typeof setTimeout> | null = null\n\n const poll = async () => {\n const detail = await refreshRunDetail(runId)\n if (cancelled) return\n if (context.activeTab === 'logs') {\n await context.refreshLogs?.()\n }\n if (context.activeTab === 'health' || normalizeStatus(detail?.status) !== 'idle') {\n await context.refreshHealthSnapshot?.()\n }\n const status = normalizeStatus(detail?.status)\n if (status === 'pending' || status === 'running') {\n timeoutId = setTimeout(() => {\n void poll()\n }, RUN_POLL_INTERVAL_MS)\n }\n }\n\n void poll()\n\n return () => {\n cancelled = true\n if (timeoutId) clearTimeout(timeoutId)\n }\n }, [context.activeTab, context.refreshHealthSnapshot, context.refreshLogs, refreshRunDetail, runId])\n\n const handleUpload = React.useCallback(async () => {\n if (!selectedFile) {\n flash(t('sync_excel.widget.messages.fileRequired', 'Select a CSV file first.'), 'error')\n return\n }\n\n setIsUploading(true)\n try {\n const formData = new FormData()\n formData.set('file', selectedFile)\n formData.set('entityType', ENTITY_TYPE)\n\n const call = await runMutation({\n operation: () => apiCall<UploadResponse>('/api/sync_excel/upload', {\n method: 'POST',\n body: formData,\n }, { fallback: null }),\n mutationPayload: {\n integrationId: context.integrationId ?? 'sync_excel',\n entityType: ENTITY_TYPE,\n fileName: selectedFile.name,\n },\n context: {\n ...context,\n operation: 'create',\n actionId: 'sync-excel-upload',\n },\n })\n\n if (!call.ok || !call.result) {\n flash(\n readApiErrorMessage(call.result as Record<string, unknown> | null, t('sync_excel.widget.messages.uploadError', 'Failed to upload CSV file.')),\n 'error',\n )\n return\n }\n\n syncPreviewState(call.result)\n setSelectedFile(null)\n setRunId(null)\n setRunDetail(null)\n setProgressJobId(null)\n flash(t('sync_excel.widget.messages.uploadSuccess', 'CSV preview is ready.'), 'success')\n } catch {\n flash(t('sync_excel.widget.messages.uploadError', 'Failed to upload CSV file.'), 'error')\n } finally {\n setIsUploading(false)\n }\n }, [context, runMutation, selectedFile, syncPreviewState, t])\n\n const handleRefreshPreview = React.useCallback(async () => {\n if (!preview) return\n setIsRefreshingPreview(true)\n try {\n const call = await apiCall<UploadResponse>(\n `/api/sync_excel/preview?uploadId=${encodeURIComponent(preview.uploadId)}&entityType=${encodeURIComponent(ENTITY_TYPE)}`,\n undefined,\n { fallback: null },\n )\n if (!call.ok || !call.result) {\n flash(t('sync_excel.widget.messages.previewError', 'Failed to refresh preview.'), 'error')\n return\n }\n syncPreviewState(call.result, { preserveManualState: true })\n flash(t('sync_excel.widget.messages.previewRefreshed', 'Preview refreshed.'), 'success')\n } catch {\n flash(t('sync_excel.widget.messages.previewError', 'Failed to refresh preview.'), 'error')\n } finally {\n setIsRefreshingPreview(false)\n }\n }, [preview, syncPreviewState, t])\n\n const handleTargetFieldChange = React.useCallback((sourceColumn: string, targetField: string) => {\n setIsMappingDirty(true)\n setMappingRows((current) => current.map((row) => row.sourceColumn === sourceColumn ? { ...row, targetField } : row))\n }, [])\n\n const handleResetToSuggested = React.useCallback(() => {\n if (!preview || !previewSuggestion) return\n setMappingRows(buildMappingRows(preview.headers, previewSuggestion))\n setMatchStrategy(previewSuggestion.matchStrategy)\n setIsMappingDirty(false)\n lastAppliedSuggestionSignatureRef.current = buildSuggestedMappingSignature(preview.headers, previewSuggestion)\n flash(t('sync_excel.widget.messages.mappingReset', 'Suggested mapping restored.'), 'success')\n }, [preview, previewSuggestion, t])\n\n const handleStartImport = React.useCallback(async () => {\n if (!preview) return\n\n const mapping = buildMapping(mappingRows, matchStrategy, targetOptions)\n setIsStartingImport(true)\n\n try {\n const call = await runMutation({\n operation: () => apiCall<ImportResponse>('/api/sync_excel/import', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n uploadId: preview.uploadId,\n entityType: ENTITY_TYPE,\n mapping,\n }),\n }, { fallback: null }),\n mutationPayload: {\n integrationId: context.integrationId ?? 'sync_excel',\n uploadId: preview.uploadId,\n entityType: ENTITY_TYPE,\n mapping,\n },\n context: {\n ...context,\n operation: 'create',\n actionId: 'sync-excel-start-import',\n },\n })\n\n if (!call.ok || !call.result) {\n flash(\n readApiErrorMessage(call.result as Record<string, unknown> | null, t('sync_excel.widget.messages.importError', 'Failed to start import run.')),\n 'error',\n )\n return\n }\n\n setRunId(call.result.runId)\n setProgressJobId(call.result.progressJobId)\n replaceQueryParams({\n uploadId: preview.uploadId,\n runId: call.result.runId,\n })\n persistCurrentSession({\n uploadId: preview.uploadId,\n filename: preview.filename,\n runId: call.result.runId,\n progressJobId: call.result.progressJobId,\n })\n flash(t('sync_excel.widget.messages.importStarted', 'Import run started.'), 'success')\n await refreshRunDetail(call.result.runId)\n await context.refreshLogs?.()\n await context.refreshHealthSnapshot?.()\n } catch {\n flash(t('sync_excel.widget.messages.importError', 'Failed to start import run.'), 'error')\n } finally {\n setIsStartingImport(false)\n }\n }, [context, mappingRows, matchStrategy, persistCurrentSession, preview, refreshRunDetail, replaceQueryParams, runMutation, t, targetOptions])\n\n const handleCancelRun = React.useCallback(async () => {\n if (!runId) return\n\n setIsCancelling(true)\n try {\n const call = await runMutation({\n operation: () => apiCall<{ ok?: boolean }>(`/api/data_sync/runs/${encodeURIComponent(runId)}/cancel`, {\n method: 'POST',\n }, { fallback: null }),\n mutationPayload: {\n integrationId: context.integrationId ?? 'sync_excel',\n runId,\n },\n context: {\n ...context,\n operation: 'update',\n actionId: 'sync-excel-cancel-import',\n },\n })\n\n if (!call.ok) {\n flash(t('sync_excel.widget.messages.cancelError', 'Failed to cancel import run.'), 'error')\n return\n }\n\n flash(t('sync_excel.widget.messages.cancelSuccess', 'Import run cancelled.'), 'success')\n await refreshRunDetail(runId)\n await context.refreshLogs?.()\n await context.refreshHealthSnapshot?.()\n } catch {\n flash(t('sync_excel.widget.messages.cancelError', 'Failed to cancel import run.'), 'error')\n } finally {\n setIsCancelling(false)\n }\n }, [context, refreshRunDetail, runId, runMutation, t])\n\n const handleRefreshAll = React.useCallback(async () => {\n if (!runId) return\n await refreshRunDetail(runId)\n await context.refreshLogs?.()\n await context.refreshHealthSnapshot?.()\n }, [context, refreshRunDetail, runId])\n\n const firstSampleRow = preview?.sampleRows[0] ?? null\n\n return (\n <div className=\"space-y-6\">\n {isRestoringSession ? (\n <Card>\n <CardContent className=\"flex items-center gap-3 py-6\">\n <Spinner className=\"size-4\" />\n <div className=\"text-sm text-muted-foreground\">\n {t('sync_excel.widget.messages.restoringSession', 'Restoring the last CSV session...')}\n </div>\n </CardContent>\n </Card>\n ) : null}\n\n {!resolvedIntegrationEnabled ? (\n <StatusAlert\n variant=\"warning\"\n title={t('sync_excel.widget.disabled.title', 'Integration disabled')}\n message={t('sync_excel.widget.disabled.message', 'Enable this integration to upload CSV files and start imports.')}\n />\n ) : null}\n\n {!shouldHideInteractiveContent ? (\n <Card>\n <CardHeader>\n <CardTitle>{t('sync_excel.widget.upload.title', 'Upload CSV')}</CardTitle>\n <CardDescription>\n {t('sync_excel.widget.upload.description', 'Upload a CSV file, review the suggested people mapping, and start a background import run.')}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"sync-excel-upload-file\">{t('sync_excel.widget.upload.fileLabel', 'CSV file')}</Label>\n <Input\n id=\"sync-excel-upload-file\"\n type=\"file\"\n accept=\".csv,text/csv\"\n onChange={(event) => setSelectedFile(event.target.files?.[0] ?? null)}\n disabled={isUploading || isRunActive || isRestoringSession}\n />\n </div>\n\n <div className=\"flex flex-wrap items-center gap-3\">\n <Button type=\"button\" onClick={() => void handleUpload()} disabled={!selectedFile || isUploading || isRunActive || isRestoringSession}>\n {isUploading ? <Spinner className=\"mr-2 size-4\" /> : <Upload className=\"mr-2 size-4\" />}\n {isUploading\n ? t('sync_excel.widget.actions.uploadPending', 'Uploading...')\n : t('sync_excel.widget.actions.upload', 'Upload and preview')}\n </Button>\n {preview ? (\n <Button type=\"button\" variant=\"outline\" onClick={() => void handleRefreshPreview()} disabled={isRefreshingPreview || isUploading || isRunActive || isRestoringSession}>\n {isRefreshingPreview ? <Spinner className=\"mr-2 size-4\" /> : <RefreshCw className=\"mr-2 size-4\" />}\n {isRefreshingPreview\n ? t('sync_excel.widget.actions.refreshPending', 'Refreshing...')\n : t('sync_excel.widget.actions.refresh', 'Refresh preview')}\n </Button>\n ) : null}\n </div>\n\n {selectedFile ? (\n <div className=\"text-sm text-muted-foreground\">\n {t('sync_excel.widget.upload.selectedFile', 'Selected file')}: <span className=\"font-medium text-foreground\">{selectedFile.name}</span>\n </div>\n ) : null}\n </CardContent>\n </Card>\n ) : null}\n\n {preview && !shouldHideInteractiveContent ? (\n <Card>\n <CardHeader>\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"space-y-1\">\n <CardTitle>{t('sync_excel.widget.preview.title', 'Preview and mapping')}</CardTitle>\n <CardDescription>\n {t('sync_excel.widget.preview.description', 'Every source column stays visible here. Leave a target empty to keep the column unmapped for now.')}\n </CardDescription>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <Badge variant=\"outline\">{preview.filename}</Badge>\n <Badge variant=\"outline\">{t('sync_excel.widget.preview.rows', '{count} rows', { count: preview.totalRows })}</Badge>\n <Badge variant=\"outline\">{formatFileSize(preview.fileSize)}</Badge>\n </div>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n <MetricCard\n label={t('sync_excel.widget.metrics.mapped', 'Mapped columns')}\n value={String(diagnostics.mappedCount)}\n />\n <MetricCard\n label={t('sync_excel.widget.metrics.unmapped', 'Unmapped columns')}\n value={String(diagnostics.unmappedCount)}\n />\n <MetricCard\n label={t('sync_excel.widget.metrics.identity', 'Identity strategy')}\n value={getMatchStrategyLabel(matchStrategy, t)}\n />\n <MetricCard\n label={t('sync_excel.widget.metrics.entity', 'Target entity')}\n value={ENTITY_TYPE}\n />\n </div>\n\n <div className=\"grid gap-4 lg:grid-cols-[minmax(0,1fr)_280px]\">\n <div className=\"overflow-hidden rounded-lg border\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('sync_excel.widget.mapping.sourceColumn', 'Source column')}</TableHead>\n <TableHead>{t('sync_excel.widget.mapping.sampleValue', 'Sample value')}</TableHead>\n <TableHead>{t('sync_excel.widget.mapping.targetField', 'Target field')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {mappingRows.map((row) => (\n <TableRow key={row.sourceColumn}>\n <TableCell className=\"font-medium\">{row.sourceColumn}</TableCell>\n <TableCell className=\"max-w-[260px] truncate text-muted-foreground\">\n {firstSampleRow?.[row.sourceColumn] ?? '\u2014'}\n </TableCell>\n <TableCell>\n <select\n className={SELECT_CLASS_NAME}\n value={row.targetField}\n onChange={(event) => handleTargetFieldChange(row.sourceColumn, event.target.value)}\n disabled={isStartingImport || isRunActive}\n >\n <option value=\"\">{t('sync_excel.mapping.targets.ignore', 'Leave unmapped')}</option>\n {targetOptions.map((option) => (\n <option key={option.value} value={option.value}>\n {option.labelKey ? t(option.labelKey, option.fallback) : option.fallback}\n </option>\n ))}\n </select>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"sync-excel-match-strategy\">\n {t('sync_excel.widget.matchStrategy.label', 'How to match existing people')}\n </Label>\n <p className=\"text-sm text-muted-foreground\">\n {t(\n 'sync_excel.widget.matchStrategy.help',\n 'This decides whether imported rows update existing people or create new ones.',\n )}\n </p>\n <select\n id=\"sync-excel-match-strategy\"\n className={SELECT_CLASS_NAME}\n value={matchStrategy}\n onChange={(event) => {\n setIsMappingDirty(true)\n setMatchStrategy(event.target.value as SuggestedMapping['matchStrategy'])\n }}\n disabled={isStartingImport || isRunActive}\n >\n <option value=\"externalId\">\n {t('sync_excel.widget.matchStrategy.externalId', 'Source record ID (Recommended)')}\n </option>\n <option value=\"email\">{t('sync_excel.widget.matchStrategy.email', 'Email address')}</option>\n <option value=\"custom\">{t('sync_excel.widget.matchStrategy.custom', 'Custom matching')}</option>\n </select>\n <p className=\"text-sm text-muted-foreground\">\n {matchStrategy === 'externalId'\n ? t(\n 'sync_excel.widget.matchStrategy.externalIdDescription',\n 'Best for repeated imports from the same source. Future imports update the same people instead of creating duplicates.',\n )\n : matchStrategy === 'email'\n ? t(\n 'sync_excel.widget.matchStrategy.emailDescription',\n 'Matches people by email. Works best when each person has one reliable, unique email address.',\n )\n : t(\n 'sync_excel.widget.matchStrategy.customDescription',\n 'Advanced option. Use only if you know how existing records should be identified in this import.',\n )}\n </p>\n </div>\n\n <div className=\"flex flex-wrap gap-2\">\n <Button type=\"button\" variant=\"outline\" onClick={handleResetToSuggested} disabled={isStartingImport || isRunActive}>\n <RefreshCw className=\"mr-2 size-4\" />\n {t('sync_excel.widget.actions.reset', 'Reset to suggestion')}\n </Button>\n <Button type=\"button\" onClick={() => void handleStartImport()} disabled={!canStartImport || isStartingImport || isRunActive}>\n {isStartingImport ? <Spinner className=\"mr-2 size-4\" /> : <Play className=\"mr-2 size-4\" />}\n {isStartingImport\n ? t('sync_excel.widget.actions.startPending', 'Starting...')\n : t('sync_excel.widget.actions.start', 'Start import')}\n </Button>\n </div>\n\n {matchStrategy === 'custom' ? (\n <StatusAlert\n variant=\"warning\"\n title={t('sync_excel.widget.matchStrategy.customWarningTitle', 'Use custom matching with care')}\n message={t(\n 'sync_excel.widget.matchStrategy.customWarningMessage',\n 'Custom matching may create duplicates if the mapped fields do not uniquely identify a person.',\n )}\n />\n ) : null}\n\n {hasExistingRunForCurrentUpload ? (\n <StatusAlert\n variant=\"warning\"\n title={t('sync_excel.widget.validation.reimportTitle', 'This upload already has a run')}\n message={t(\n 'sync_excel.widget.validation.reimportMessage',\n 'Starting another import from the same uploaded CSV may create duplicates unless your matching strategy reliably identifies existing people.',\n )}\n />\n ) : null}\n\n {!hasSafeDedupeStrategy ? (\n <StatusAlert\n variant=\"warning\"\n title={t('sync_excel.widget.validation.duplicateRiskTitle', 'Duplicate risk')}\n message={t(\n 'sync_excel.widget.validation.duplicateRiskMessage',\n 'This mapping does not use the recommended External ID or Email matching strategy. Re-importing the same dataset may create duplicate people.',\n )}\n />\n ) : null}\n\n {diagnostics.duplicateTargets.length > 0 ? (\n <StatusAlert\n variant=\"error\"\n title={t('sync_excel.widget.validation.duplicateTargetsTitle', 'Duplicate target fields')}\n message={t(\n 'sync_excel.widget.validation.duplicateTargetsMessage',\n 'Each target field can only be mapped once in this foundation slice: {targets}',\n { targets: diagnostics.duplicateTargets.map((target) => formatTargetLabel(target, t, targetOptions)).join(', ') },\n )}\n />\n ) : null}\n\n {!diagnostics.hasIdentityTarget ? (\n <StatusAlert\n variant=\"warning\"\n title={t('sync_excel.widget.validation.identityTitle', 'Map an identity field')}\n message={t('sync_excel.widget.validation.identityMessage', 'Map either External ID or Primary email so reimports can match existing people.')}\n />\n ) : null}\n\n {!diagnostics.hasNameTarget ? (\n <StatusAlert\n variant=\"warning\"\n title={t('sync_excel.widget.validation.nameTitle', 'Map a name field')}\n message={t('sync_excel.widget.validation.nameMessage', 'Map Last name or Display name so the importer can build person records.')}\n />\n ) : null}\n\n {diagnostics.hasIdentityTarget && diagnostics.hasNameTarget && diagnostics.duplicateTargets.length === 0 ? (\n <StatusAlert\n variant=\"info\"\n title={t('sync_excel.widget.validation.readyTitle', 'Ready to import')}\n message={t('sync_excel.widget.validation.readyMessage', 'The current mapping is valid for the first customers.person slice.')}\n />\n ) : null}\n </div>\n </div>\n </CardContent>\n </Card>\n ) : null}\n\n {runId && !shouldHideInteractiveContent ? (\n <Card>\n <CardHeader>\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"space-y-1\">\n <CardTitle>{t('sync_excel.widget.run.title', 'Import run status')}</CardTitle>\n <CardDescription>\n {t('sync_excel.widget.run.description', 'The import runs in the background through Data Sync and updates this view as progress changes.')}\n </CardDescription>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <RunStatusBadge status={importStatus} t={t} />\n {progressJobId ? <Badge variant=\"outline\">{progressJobId}</Badge> : null}\n </div>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"text-muted-foreground\">{t('sync_excel.widget.run.progressLabel', 'Progress')}</span>\n <span className=\"font-medium\">{progressValue}%</span>\n </div>\n <Progress value={progressValue} className=\"h-2.5\" />\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-5\">\n <MetricCard label={t('sync_excel.widget.run.metrics.created', 'Created')} value={String(runDetail?.createdCount ?? 0)} />\n <MetricCard label={t('sync_excel.widget.run.metrics.updated', 'Updated')} value={String(runDetail?.updatedCount ?? 0)} />\n <MetricCard label={t('sync_excel.widget.run.metrics.skipped', 'Skipped')} value={String(runDetail?.skippedCount ?? 0)} />\n <MetricCard label={t('sync_excel.widget.run.metrics.failed', 'Failed')} value={String(runDetail?.failedCount ?? 0)} />\n <MetricCard label={t('sync_excel.widget.run.metrics.processed', 'Processed')} value={String(runDetail?.progressJob?.processedCount ?? 0)} />\n </div>\n\n {runDetail?.lastError ? (\n <StatusAlert\n variant=\"error\"\n title={t('sync_excel.widget.run.errorTitle', 'Run error')}\n message={runDetail.lastError}\n />\n ) : null}\n\n <div className=\"flex flex-wrap gap-2\">\n <Button type=\"button\" variant=\"outline\" onClick={() => void handleRefreshAll()} disabled={isRefreshingPreview || isRestoringSession}>\n <RefreshCw className=\"mr-2 size-4\" />\n {t('sync_excel.widget.actions.refreshRun', 'Refresh run status')}\n </Button>\n {isRunActive ? (\n <Button type=\"button\" variant=\"destructive\" onClick={() => void handleCancelRun()} disabled={isCancelling}>\n {isCancelling ? <Spinner className=\"mr-2 size-4\" /> : <XCircle className=\"mr-2 size-4\" />}\n {isCancelling\n ? t('sync_excel.widget.actions.cancelPending', 'Cancelling...')\n : t('sync_excel.widget.actions.cancel', 'Cancel run')}\n </Button>\n ) : null}\n </div>\n </CardContent>\n </Card>\n ) : null}\n </div>\n )\n}\n\nfunction StatusAlert({\n variant,\n title,\n message,\n}: {\n variant: 'warning' | 'error' | 'info'\n title: string\n message: string\n}) {\n return (\n <Alert status={variant === 'info' ? 'information' : variant}>\n <AlertTitle>{title}</AlertTitle>\n <AlertDescription>{message}</AlertDescription>\n </Alert>\n )\n}\n\nfunction MetricCard({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"rounded-lg border bg-muted/30 p-4\">\n <div className=\"text-xs font-medium uppercase tracking-wide text-muted-foreground\">{label}</div>\n <div className=\"mt-2 text-lg font-semibold text-foreground\">{value}</div>\n </div>\n )\n}\n\ntype RunStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled' | 'idle'\n\nexport const RUN_STATUS_BADGE_VARIANTS: StatusMap<RunStatus> = {\n completed: 'success',\n failed: 'error',\n cancelled: 'neutral',\n pending: 'info',\n running: 'info',\n idle: 'neutral',\n}\n\nexport function RunStatusBadge({\n status,\n t,\n}: {\n status: RunStatus\n t: ReturnType<typeof useT>\n}) {\n const variant = RUN_STATUS_BADGE_VARIANTS[status] ?? 'neutral'\n\n if (status === 'completed') {\n return (\n <StatusBadge variant={variant} className=\"gap-1.5\">\n <CheckCircle2 className=\"size-3.5\" />\n {t('sync_excel.widget.run.status.completed', 'Completed')}\n </StatusBadge>\n )\n }\n\n if (status === 'failed') {\n return (\n <StatusBadge variant={variant} className=\"gap-1.5\">\n <AlertTriangle className=\"size-3.5\" />\n {t('sync_excel.widget.run.status.failed', 'Failed')}\n </StatusBadge>\n )\n }\n\n if (status === 'cancelled') {\n return (\n <StatusBadge variant={variant} className=\"gap-1.5\">\n <XCircle className=\"size-3.5\" />\n {t('sync_excel.widget.run.status.cancelled', 'Cancelled')}\n </StatusBadge>\n )\n }\n\n if (status === 'pending' || status === 'running') {\n return (\n <StatusBadge variant={variant} className=\"gap-1.5\">\n <RefreshCw className={cn('size-3.5', status === 'running' ? 'animate-spin' : '')} />\n {status === 'pending'\n ? t('sync_excel.widget.run.status.pending', 'Pending')\n : t('sync_excel.widget.run.status.running', 'Running')}\n </StatusBadge>\n )\n }\n\n return (\n <StatusBadge variant={variant}>\n {t('sync_excel.widget.run.status.idle', 'Idle')}\n </StatusBadge>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -325,7 +325,7 @@ function ReleaseReservationDialog({
|
|
|
325
325
|
Button,
|
|
326
326
|
{
|
|
327
327
|
type: "submit",
|
|
328
|
-
variant: "destructive",
|
|
328
|
+
variant: "destructive-solid",
|
|
329
329
|
disabled: submitDisabled,
|
|
330
330
|
"data-testid": "wms-inventory-release-submit",
|
|
331
331
|
children: t("wms.backend.inventory.release.dialog.submit", "Release reservation")
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/wms/components/backend/ReleaseReservationDialog.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { ShieldOff } from 'lucide-react'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { flashMutationError } from '../../lib/flashMutationError'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { raiseCrudError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@open-mercato/ui/primitives/dialog'\nimport { FormField } from '@open-mercato/ui/primitives/form-field'\nimport { KbdShortcut } from '@open-mercato/ui/primitives/kbd'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { Textarea } from '@open-mercato/ui/primitives/textarea'\nimport { useLocale, useT } from '@open-mercato/shared/lib/i18n/context'\nimport {\n createInventoryQuantityFormatter,\n formatReservationSourceLabel,\n} from '../../lib/inventoryDisplayUi'\nimport { parseInventoryQuantity } from '../../lib/inventoryMutationUi'\nimport type { WmsInventoryMutationAccess } from './useWmsInventoryMutationAccess'\n\nconst RELEASE_REASON_CODES = ['order_cancelled', 'manual_release', 'correction', 'other'] as const\n\ntype ReleaseReasonCode = (typeof RELEASE_REASON_CODES)[number]\n\ntype ReservationSummary = {\n id: string\n warehouse_name?: string | null\n warehouse_code?: string | null\n variant_name?: string | null\n variant_sku?: string | null\n quantity?: string | number | null\n source_type?: string | null\n source_id?: string | null\n source_label?: string | null\n status?: string | null\n}\n\ntype ReleaseReservationDialogProps = {\n open: boolean\n onOpenChange: (open: boolean) => void\n access: WmsInventoryMutationAccess\n reservation: ReservationSummary | null\n onSuccess?: () => void\n}\n\nfunction formatVariantLabel(\n row: ReservationSummary,\n notAvailableLabel: string,\n): string {\n const name = (row.variant_name ?? '').trim()\n const sku = (row.variant_sku ?? '').trim()\n if (name && sku) return `${name} (${sku})`\n if (name) return name\n if (sku) return sku\n return notAvailableLabel\n}\n\nfunction formatWarehouseLabel(\n row: ReservationSummary,\n notAvailableLabel: string,\n): string {\n return (\n row.warehouse_name?.trim() ||\n row.warehouse_code?.trim() ||\n notAvailableLabel\n )\n}\n\nexport function ReleaseReservationDialog({\n open,\n onOpenChange,\n access,\n reservation,\n onSuccess,\n}: ReleaseReservationDialogProps) {\n const t = useT()\n const locale = useLocale()\n const quantityFormatter = React.useMemo(\n () => createInventoryQuantityFormatter(locale),\n [locale],\n )\n const notAvailableLabel = t('wms.backend.inventory.common.notAvailable', '\u2014')\n const queryClient = useQueryClient()\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: 'wms-inventory-release',\n })\n const mutationContext = React.useMemo(\n () => ({ retryLastMutation }),\n [retryLastMutation],\n )\n const releaseFormSchema = React.useMemo(\n () =>\n z.object({\n reasonCode: z.enum(RELEASE_REASON_CODES),\n notes: z.string().trim().max(500).optional(),\n }),\n [],\n )\n const [submitting, setSubmitting] = React.useState(false)\n const [reasonCode, setReasonCode] = React.useState<ReleaseReasonCode | ''>('')\n const [notes, setNotes] = React.useState('')\n const [fieldErrors, setFieldErrors] = React.useState<Record<string, string>>({})\n\n const reasonLabel = React.useCallback(\n (code: ReleaseReasonCode) => {\n const fallbacks: Record<ReleaseReasonCode, string> = {\n order_cancelled: 'Order cancelled',\n manual_release: 'Manual release',\n correction: 'Correction',\n other: 'Other',\n }\n return t(`wms.backend.inventory.release.reasons.${code}`, fallbacks[code])\n },\n [t],\n )\n\n const resetDialog = React.useCallback(() => {\n setReasonCode('')\n setNotes('')\n setFieldErrors({})\n setSubmitting(false)\n }, [])\n\n React.useEffect(() => {\n if (!open || !reservation?.id) return\n setReasonCode('manual_release')\n setNotes('')\n setFieldErrors({})\n setSubmitting(false)\n }, [open, reservation?.id])\n\n const closeDialog = React.useCallback(() => {\n onOpenChange(false)\n resetDialog()\n }, [onOpenChange, resetDialog])\n\n const handleSubmit = React.useCallback(\n async (event?: React.FormEvent) => {\n event?.preventDefault()\n if (!reservation?.id) {\n flash(\n t(\n 'wms.backend.inventory.release.errors.missingReservation',\n 'Reservation context is missing. Close the dialog and try again from the reservations table.',\n ),\n 'error',\n )\n return\n }\n\n const parsed = releaseFormSchema.safeParse({\n reasonCode,\n notes: notes.trim() || undefined,\n })\n if (!parsed.success) {\n const nextErrors: Record<string, string> = {}\n for (const issue of parsed.error.issues) {\n const key = String(issue.path[0] ?? 'form')\n if (!nextErrors[key]) nextErrors[key] = issue.message\n }\n setFieldErrors(nextErrors)\n return\n }\n\n if (!access.scopeReady || !access.organizationId || !access.tenantId) {\n flash(\n t(\n 'wms.backend.inventory.mutations.errors.scope',\n 'Select an organization and sign in before posting inventory changes.',\n ),\n 'error',\n )\n return\n }\n\n setSubmitting(true)\n try {\n const reasonParts = [reasonLabel(parsed.data.reasonCode)]\n if (parsed.data.notes?.trim()) reasonParts.push(parsed.data.notes.trim())\n const payload = {\n organizationId: access.organizationId,\n tenantId: access.tenantId,\n reservationId: reservation.id,\n reason: reasonParts.join(' \u2014 ').slice(0, 120),\n reasonCode: parsed.data.reasonCode,\n }\n\n await runMutation({\n operation: async () => {\n const call = await apiCall<{ ok?: boolean }>('/api/wms/inventory/release', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n if (!call.ok) {\n if (call.response.status === 409 && (call.result as { error?: string } | null)?.error === 'balance_integrity_violation') {\n flash(\n t(\n 'wms.backend.inventory.release.errors.balanceIntegrityViolation',\n 'Balance integrity error \u2014 run \"mercato wms verify-balances --repair\" to diagnose and fix drift before retrying.',\n ),\n 'error',\n )\n return {}\n }\n await raiseCrudError(\n call.response,\n t('wms.backend.inventory.release.errors.submit', 'Failed to release reservation.'),\n )\n }\n return call.result ?? {}\n },\n context: mutationContext,\n mutationPayload: payload,\n })\n\n flash(t('wms.backend.inventory.release.flash.success', 'Reservation released'), 'success')\n await queryClient.invalidateQueries({ queryKey: ['wms-inventory-console'] })\n await queryClient.invalidateQueries({ queryKey: ['wms-sku-detail'] })\n await queryClient.invalidateQueries({ queryKey: ['wms-location-detail'] })\n await queryClient.invalidateQueries({ queryKey: ['wms-lot-detail'] })\n closeDialog()\n onSuccess?.()\n } catch (error) {\n flashMutationError(error, t('wms.backend.inventory.release.errors.submit', 'Failed to release reservation.'), t)\n } finally {\n setSubmitting(false)\n }\n },\n [\n access,\n closeDialog,\n mutationContext,\n notes,\n onSuccess,\n queryClient,\n reasonCode,\n reasonLabel,\n releaseFormSchema,\n reservation,\n runMutation,\n t,\n ],\n )\n\n const submitDisabled = submitting || access.loading || !access.scopeReady\n\n const handleDialogKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === 'Escape') {\n event.preventDefault()\n closeDialog()\n return\n }\n if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {\n event.preventDefault()\n if (!submitDisabled) void handleSubmit()\n }\n },\n [closeDialog, handleSubmit, submitDisabled],\n )\n\n if (!reservation) return null\n\n return (\n <Dialog open={open} onOpenChange={(next) => (next ? onOpenChange(true) : closeDialog())}>\n <DialogContent\n className=\"max-w-lg gap-0 overflow-hidden p-0\"\n onKeyDown={handleDialogKeyDown}\n >\n <div className=\"border-b px-6 py-4 pr-12\">\n <DialogHeader className=\"space-y-1 text-left\">\n <DialogTitle>\n {t('wms.backend.inventory.release.dialog.title', 'Release reservation')}\n </DialogTitle>\n <DialogDescription>\n {t(\n 'wms.backend.inventory.release.dialog.description',\n 'Return reserved quantity to available stock for this bucket.',\n )}\n </DialogDescription>\n </DialogHeader>\n </div>\n\n <form onSubmit={handleSubmit} className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"flex flex-col gap-5 overflow-y-auto px-6 py-6\">\n <div className=\"rounded-lg border bg-muted/40 px-4 py-3.5\">\n <div className=\"flex items-start gap-3\">\n <ShieldOff className=\"mt-0.5 size-4 text-muted-foreground\" aria-hidden=\"true\" />\n <dl className=\"grid gap-2 text-sm\">\n <div className=\"flex flex-wrap gap-x-2\">\n <dt className=\"text-muted-foreground\">\n {t('wms.backend.inventory.release.summary.variant', 'Variant')}\n </dt>\n <dd className=\"font-medium\">\n {formatVariantLabel(reservation, notAvailableLabel)}\n </dd>\n </div>\n <div className=\"flex flex-wrap gap-x-2\">\n <dt className=\"text-muted-foreground\">\n {t('wms.backend.inventory.release.summary.warehouse', 'Warehouse')}\n </dt>\n <dd className=\"font-medium\">\n {formatWarehouseLabel(reservation, notAvailableLabel)}\n </dd>\n </div>\n <div className=\"flex flex-wrap gap-x-2\">\n <dt className=\"text-muted-foreground\">\n {t('wms.backend.inventory.release.summary.quantity', 'Quantity')}\n </dt>\n <dd className=\"font-medium tabular-nums\">\n {quantityFormatter.format(parseInventoryQuantity(reservation.quantity))}\n </dd>\n </div>\n <div className=\"flex flex-wrap gap-x-2\">\n <dt className=\"text-muted-foreground\">\n {t('wms.backend.inventory.release.summary.source', 'Source')}\n </dt>\n <dd className=\"font-medium\">\n {formatReservationSourceLabel(reservation, t) || notAvailableLabel}\n </dd>\n </div>\n </dl>\n </div>\n </div>\n\n <p className=\"rounded-lg border border-status-warning-border bg-status-warning-bg px-3 py-2.5 text-sm text-status-warning-text\">\n {t(\n 'wms.backend.inventory.release.warning',\n 'This action cannot be undone \u2014 the reserved quantity will be released immediately.',\n )}\n </p>\n\n <FormField\n label={t('wms.backend.inventory.release.form.reason', 'Reason')}\n required\n error={fieldErrors.reasonCode}\n >\n <Select\n value={reasonCode || undefined}\n onValueChange={(next) => {\n setReasonCode(next as ReleaseReasonCode)\n setFieldErrors({})\n }}\n disabled={submitting}\n >\n <SelectTrigger>\n <SelectValue\n placeholder={t(\n 'wms.backend.inventory.release.form.reasonPlaceholder',\n 'Select reason',\n )}\n />\n </SelectTrigger>\n <SelectContent>\n {RELEASE_REASON_CODES.map((code) => (\n <SelectItem key={code} value={code}>\n {reasonLabel(code)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </FormField>\n\n <FormField label={t('wms.backend.inventory.release.form.notes', 'Notes')}>\n <Textarea\n value={notes}\n onChange={(event) => setNotes(event.target.value)}\n placeholder={t(\n 'wms.backend.inventory.release.form.notesPlaceholder',\n 'Optional \u2014 additional context',\n )}\n rows={3}\n disabled={submitting}\n />\n </FormField>\n </div>\n\n <DialogFooter bordered={false} className=\"border-t px-6 py-4 sm:justify-between\">\n <p className=\"hidden text-xs text-muted-foreground sm:inline-flex sm:items-center sm:gap-1.5\">\n <KbdShortcut keys={['\u2318', 'Enter']} />\n <span>/</span>\n <KbdShortcut keys={['Ctrl', 'Enter']} />\n <span>{t('wms.backend.inventory.release.dialog.shortcutSave', 'to confirm')}</span>\n </p>\n <div className=\"flex w-full flex-col-reverse gap-2 sm:w-auto sm:flex-row\">\n <Button type=\"button\" variant=\"outline\" onClick={closeDialog} disabled={submitting}>\n {t('common.cancel', 'Cancel')}\n </Button>\n <Button\n type=\"submit\"\n variant=\"destructive\"\n disabled={submitDisabled}\n data-testid=\"wms-inventory-release-submit\"\n >\n {t('wms.backend.inventory.release.dialog.submit', 'Release reservation')}\n </Button>\n </div>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n )\n}\n"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { ShieldOff } from 'lucide-react'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { flashMutationError } from '../../lib/flashMutationError'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { raiseCrudError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@open-mercato/ui/primitives/dialog'\nimport { FormField } from '@open-mercato/ui/primitives/form-field'\nimport { KbdShortcut } from '@open-mercato/ui/primitives/kbd'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { Textarea } from '@open-mercato/ui/primitives/textarea'\nimport { useLocale, useT } from '@open-mercato/shared/lib/i18n/context'\nimport {\n createInventoryQuantityFormatter,\n formatReservationSourceLabel,\n} from '../../lib/inventoryDisplayUi'\nimport { parseInventoryQuantity } from '../../lib/inventoryMutationUi'\nimport type { WmsInventoryMutationAccess } from './useWmsInventoryMutationAccess'\n\nconst RELEASE_REASON_CODES = ['order_cancelled', 'manual_release', 'correction', 'other'] as const\n\ntype ReleaseReasonCode = (typeof RELEASE_REASON_CODES)[number]\n\ntype ReservationSummary = {\n id: string\n warehouse_name?: string | null\n warehouse_code?: string | null\n variant_name?: string | null\n variant_sku?: string | null\n quantity?: string | number | null\n source_type?: string | null\n source_id?: string | null\n source_label?: string | null\n status?: string | null\n}\n\ntype ReleaseReservationDialogProps = {\n open: boolean\n onOpenChange: (open: boolean) => void\n access: WmsInventoryMutationAccess\n reservation: ReservationSummary | null\n onSuccess?: () => void\n}\n\nfunction formatVariantLabel(\n row: ReservationSummary,\n notAvailableLabel: string,\n): string {\n const name = (row.variant_name ?? '').trim()\n const sku = (row.variant_sku ?? '').trim()\n if (name && sku) return `${name} (${sku})`\n if (name) return name\n if (sku) return sku\n return notAvailableLabel\n}\n\nfunction formatWarehouseLabel(\n row: ReservationSummary,\n notAvailableLabel: string,\n): string {\n return (\n row.warehouse_name?.trim() ||\n row.warehouse_code?.trim() ||\n notAvailableLabel\n )\n}\n\nexport function ReleaseReservationDialog({\n open,\n onOpenChange,\n access,\n reservation,\n onSuccess,\n}: ReleaseReservationDialogProps) {\n const t = useT()\n const locale = useLocale()\n const quantityFormatter = React.useMemo(\n () => createInventoryQuantityFormatter(locale),\n [locale],\n )\n const notAvailableLabel = t('wms.backend.inventory.common.notAvailable', '\u2014')\n const queryClient = useQueryClient()\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: 'wms-inventory-release',\n })\n const mutationContext = React.useMemo(\n () => ({ retryLastMutation }),\n [retryLastMutation],\n )\n const releaseFormSchema = React.useMemo(\n () =>\n z.object({\n reasonCode: z.enum(RELEASE_REASON_CODES),\n notes: z.string().trim().max(500).optional(),\n }),\n [],\n )\n const [submitting, setSubmitting] = React.useState(false)\n const [reasonCode, setReasonCode] = React.useState<ReleaseReasonCode | ''>('')\n const [notes, setNotes] = React.useState('')\n const [fieldErrors, setFieldErrors] = React.useState<Record<string, string>>({})\n\n const reasonLabel = React.useCallback(\n (code: ReleaseReasonCode) => {\n const fallbacks: Record<ReleaseReasonCode, string> = {\n order_cancelled: 'Order cancelled',\n manual_release: 'Manual release',\n correction: 'Correction',\n other: 'Other',\n }\n return t(`wms.backend.inventory.release.reasons.${code}`, fallbacks[code])\n },\n [t],\n )\n\n const resetDialog = React.useCallback(() => {\n setReasonCode('')\n setNotes('')\n setFieldErrors({})\n setSubmitting(false)\n }, [])\n\n React.useEffect(() => {\n if (!open || !reservation?.id) return\n setReasonCode('manual_release')\n setNotes('')\n setFieldErrors({})\n setSubmitting(false)\n }, [open, reservation?.id])\n\n const closeDialog = React.useCallback(() => {\n onOpenChange(false)\n resetDialog()\n }, [onOpenChange, resetDialog])\n\n const handleSubmit = React.useCallback(\n async (event?: React.FormEvent) => {\n event?.preventDefault()\n if (!reservation?.id) {\n flash(\n t(\n 'wms.backend.inventory.release.errors.missingReservation',\n 'Reservation context is missing. Close the dialog and try again from the reservations table.',\n ),\n 'error',\n )\n return\n }\n\n const parsed = releaseFormSchema.safeParse({\n reasonCode,\n notes: notes.trim() || undefined,\n })\n if (!parsed.success) {\n const nextErrors: Record<string, string> = {}\n for (const issue of parsed.error.issues) {\n const key = String(issue.path[0] ?? 'form')\n if (!nextErrors[key]) nextErrors[key] = issue.message\n }\n setFieldErrors(nextErrors)\n return\n }\n\n if (!access.scopeReady || !access.organizationId || !access.tenantId) {\n flash(\n t(\n 'wms.backend.inventory.mutations.errors.scope',\n 'Select an organization and sign in before posting inventory changes.',\n ),\n 'error',\n )\n return\n }\n\n setSubmitting(true)\n try {\n const reasonParts = [reasonLabel(parsed.data.reasonCode)]\n if (parsed.data.notes?.trim()) reasonParts.push(parsed.data.notes.trim())\n const payload = {\n organizationId: access.organizationId,\n tenantId: access.tenantId,\n reservationId: reservation.id,\n reason: reasonParts.join(' \u2014 ').slice(0, 120),\n reasonCode: parsed.data.reasonCode,\n }\n\n await runMutation({\n operation: async () => {\n const call = await apiCall<{ ok?: boolean }>('/api/wms/inventory/release', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n if (!call.ok) {\n if (call.response.status === 409 && (call.result as { error?: string } | null)?.error === 'balance_integrity_violation') {\n flash(\n t(\n 'wms.backend.inventory.release.errors.balanceIntegrityViolation',\n 'Balance integrity error \u2014 run \"mercato wms verify-balances --repair\" to diagnose and fix drift before retrying.',\n ),\n 'error',\n )\n return {}\n }\n await raiseCrudError(\n call.response,\n t('wms.backend.inventory.release.errors.submit', 'Failed to release reservation.'),\n )\n }\n return call.result ?? {}\n },\n context: mutationContext,\n mutationPayload: payload,\n })\n\n flash(t('wms.backend.inventory.release.flash.success', 'Reservation released'), 'success')\n await queryClient.invalidateQueries({ queryKey: ['wms-inventory-console'] })\n await queryClient.invalidateQueries({ queryKey: ['wms-sku-detail'] })\n await queryClient.invalidateQueries({ queryKey: ['wms-location-detail'] })\n await queryClient.invalidateQueries({ queryKey: ['wms-lot-detail'] })\n closeDialog()\n onSuccess?.()\n } catch (error) {\n flashMutationError(error, t('wms.backend.inventory.release.errors.submit', 'Failed to release reservation.'), t)\n } finally {\n setSubmitting(false)\n }\n },\n [\n access,\n closeDialog,\n mutationContext,\n notes,\n onSuccess,\n queryClient,\n reasonCode,\n reasonLabel,\n releaseFormSchema,\n reservation,\n runMutation,\n t,\n ],\n )\n\n const submitDisabled = submitting || access.loading || !access.scopeReady\n\n const handleDialogKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === 'Escape') {\n event.preventDefault()\n closeDialog()\n return\n }\n if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {\n event.preventDefault()\n if (!submitDisabled) void handleSubmit()\n }\n },\n [closeDialog, handleSubmit, submitDisabled],\n )\n\n if (!reservation) return null\n\n return (\n <Dialog open={open} onOpenChange={(next) => (next ? onOpenChange(true) : closeDialog())}>\n <DialogContent\n className=\"max-w-lg gap-0 overflow-hidden p-0\"\n onKeyDown={handleDialogKeyDown}\n >\n <div className=\"border-b px-6 py-4 pr-12\">\n <DialogHeader className=\"space-y-1 text-left\">\n <DialogTitle>\n {t('wms.backend.inventory.release.dialog.title', 'Release reservation')}\n </DialogTitle>\n <DialogDescription>\n {t(\n 'wms.backend.inventory.release.dialog.description',\n 'Return reserved quantity to available stock for this bucket.',\n )}\n </DialogDescription>\n </DialogHeader>\n </div>\n\n <form onSubmit={handleSubmit} className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"flex flex-col gap-5 overflow-y-auto px-6 py-6\">\n <div className=\"rounded-lg border bg-muted/40 px-4 py-3.5\">\n <div className=\"flex items-start gap-3\">\n <ShieldOff className=\"mt-0.5 size-4 text-muted-foreground\" aria-hidden=\"true\" />\n <dl className=\"grid gap-2 text-sm\">\n <div className=\"flex flex-wrap gap-x-2\">\n <dt className=\"text-muted-foreground\">\n {t('wms.backend.inventory.release.summary.variant', 'Variant')}\n </dt>\n <dd className=\"font-medium\">\n {formatVariantLabel(reservation, notAvailableLabel)}\n </dd>\n </div>\n <div className=\"flex flex-wrap gap-x-2\">\n <dt className=\"text-muted-foreground\">\n {t('wms.backend.inventory.release.summary.warehouse', 'Warehouse')}\n </dt>\n <dd className=\"font-medium\">\n {formatWarehouseLabel(reservation, notAvailableLabel)}\n </dd>\n </div>\n <div className=\"flex flex-wrap gap-x-2\">\n <dt className=\"text-muted-foreground\">\n {t('wms.backend.inventory.release.summary.quantity', 'Quantity')}\n </dt>\n <dd className=\"font-medium tabular-nums\">\n {quantityFormatter.format(parseInventoryQuantity(reservation.quantity))}\n </dd>\n </div>\n <div className=\"flex flex-wrap gap-x-2\">\n <dt className=\"text-muted-foreground\">\n {t('wms.backend.inventory.release.summary.source', 'Source')}\n </dt>\n <dd className=\"font-medium\">\n {formatReservationSourceLabel(reservation, t) || notAvailableLabel}\n </dd>\n </div>\n </dl>\n </div>\n </div>\n\n <p className=\"rounded-lg border border-status-warning-border bg-status-warning-bg px-3 py-2.5 text-sm text-status-warning-text\">\n {t(\n 'wms.backend.inventory.release.warning',\n 'This action cannot be undone \u2014 the reserved quantity will be released immediately.',\n )}\n </p>\n\n <FormField\n label={t('wms.backend.inventory.release.form.reason', 'Reason')}\n required\n error={fieldErrors.reasonCode}\n >\n <Select\n value={reasonCode || undefined}\n onValueChange={(next) => {\n setReasonCode(next as ReleaseReasonCode)\n setFieldErrors({})\n }}\n disabled={submitting}\n >\n <SelectTrigger>\n <SelectValue\n placeholder={t(\n 'wms.backend.inventory.release.form.reasonPlaceholder',\n 'Select reason',\n )}\n />\n </SelectTrigger>\n <SelectContent>\n {RELEASE_REASON_CODES.map((code) => (\n <SelectItem key={code} value={code}>\n {reasonLabel(code)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </FormField>\n\n <FormField label={t('wms.backend.inventory.release.form.notes', 'Notes')}>\n <Textarea\n value={notes}\n onChange={(event) => setNotes(event.target.value)}\n placeholder={t(\n 'wms.backend.inventory.release.form.notesPlaceholder',\n 'Optional \u2014 additional context',\n )}\n rows={3}\n disabled={submitting}\n />\n </FormField>\n </div>\n\n <DialogFooter bordered={false} className=\"border-t px-6 py-4 sm:justify-between\">\n <p className=\"hidden text-xs text-muted-foreground sm:inline-flex sm:items-center sm:gap-1.5\">\n <KbdShortcut keys={['\u2318', 'Enter']} />\n <span>/</span>\n <KbdShortcut keys={['Ctrl', 'Enter']} />\n <span>{t('wms.backend.inventory.release.dialog.shortcutSave', 'to confirm')}</span>\n </p>\n <div className=\"flex w-full flex-col-reverse gap-2 sm:w-auto sm:flex-row\">\n <Button type=\"button\" variant=\"outline\" onClick={closeDialog} disabled={submitting}>\n {t('common.cancel', 'Cancel')}\n </Button>\n <Button\n type=\"submit\"\n variant=\"destructive-solid\"\n disabled={submitDisabled}\n data-testid=\"wms-inventory-release-submit\"\n >\n {t('wms.backend.inventory.release.dialog.submit', 'Release reservation')}\n </Button>\n </div>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n )\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
|
+
import { extensionPoints } from "@open-mercato/core/modules/wms/extension-points";
|
|
4
5
|
import Link from "next/link";
|
|
5
6
|
import { useRouter } from "next/navigation";
|
|
6
7
|
import { z } from "zod";
|
|
@@ -356,7 +357,7 @@ function WarehouseSection({ viewAllHref } = {}) {
|
|
|
356
357
|
totalPages: query.data?.totalPages ?? 1,
|
|
357
358
|
onPageChange: setPage
|
|
358
359
|
},
|
|
359
|
-
perspective: { tableId:
|
|
360
|
+
perspective: { tableId: extensionPoints.hosts.warehousesTable.tableId },
|
|
360
361
|
emptyState: /* @__PURE__ */ jsx(
|
|
361
362
|
EmptyState,
|
|
362
363
|
{
|
|
@@ -594,7 +595,7 @@ function ZoneSection({ viewAllHref } = {}) {
|
|
|
594
595
|
totalPages: query.data?.totalPages ?? 1,
|
|
595
596
|
onPageChange: setPage
|
|
596
597
|
},
|
|
597
|
-
perspective: { tableId:
|
|
598
|
+
perspective: { tableId: extensionPoints.hosts.zonesTable.tableId },
|
|
598
599
|
emptyState: /* @__PURE__ */ jsx(
|
|
599
600
|
EmptyState,
|
|
600
601
|
{
|
|
@@ -781,7 +782,7 @@ function LocationSection({ viewAllHref } = {}) {
|
|
|
781
782
|
totalPages: query.data?.totalPages ?? 1,
|
|
782
783
|
onPageChange: setPage
|
|
783
784
|
},
|
|
784
|
-
perspective: { tableId:
|
|
785
|
+
perspective: { tableId: extensionPoints.hosts.locationsTable.tableId },
|
|
785
786
|
emptyState: /* @__PURE__ */ jsx(
|
|
786
787
|
EmptyState,
|
|
787
788
|
{
|
|
@@ -1056,7 +1057,7 @@ function InventoryProfilesSection() {
|
|
|
1056
1057
|
totalPages: query.data?.totalPages ?? 1,
|
|
1057
1058
|
onPageChange: setPage
|
|
1058
1059
|
},
|
|
1059
|
-
perspective: { tableId:
|
|
1060
|
+
perspective: { tableId: extensionPoints.hosts.inventoryProfilesTable.tableId },
|
|
1060
1061
|
emptyState: /* @__PURE__ */ jsx(
|
|
1061
1062
|
EmptyState,
|
|
1062
1063
|
{
|