@open-mercato/core 0.7.1-develop.7151.1.00d0391847 → 0.7.1-develop.7153.1.7145d295e6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/modules/api_keys/backend/api-keys/create/page.js +1 -0
- package/dist/modules/api_keys/backend/api-keys/create/page.js.map +2 -2
- package/dist/modules/api_keys/backend/api-keys/page.js +1 -0
- package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
- package/dist/modules/attachments/components/AttachmentLibrary.js +1 -0
- package/dist/modules/attachments/components/AttachmentLibrary.js.map +2 -2
- package/dist/modules/audit_logs/backend/audit-logs/page.js +53 -50
- package/dist/modules/audit_logs/backend/audit-logs/page.js.map +2 -2
- package/dist/modules/audit_logs/components/AccessLogsTable.js +1 -0
- package/dist/modules/audit_logs/components/AccessLogsTable.js.map +2 -2
- package/dist/modules/audit_logs/components/AuditLogsActions.js +1 -0
- package/dist/modules/audit_logs/components/AuditLogsActions.js.map +2 -2
- package/dist/modules/auth/backend/roles/[id]/edit/page.js +1 -0
- package/dist/modules/auth/backend/roles/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/backend/roles/create/page.js +1 -0
- package/dist/modules/auth/backend/roles/create/page.js.map +2 -2
- package/dist/modules/auth/backend/roles/page.js +1 -0
- package/dist/modules/auth/backend/roles/page.js.map +2 -2
- package/dist/modules/auth/backend/users/[id]/edit/page.js +1 -0
- package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/backend/users/create/page.js +1 -0
- package/dist/modules/auth/backend/users/create/page.js.map +2 -2
- package/dist/modules/auth/backend/users/page.js +1 -0
- package/dist/modules/auth/backend/users/page.js.map +2 -2
- package/dist/modules/business_rules/backend/logs/page.js +1 -0
- package/dist/modules/business_rules/backend/logs/page.js.map +2 -2
- package/dist/modules/business_rules/backend/rules/[id]/page.js +1 -0
- package/dist/modules/business_rules/backend/rules/[id]/page.js.map +2 -2
- package/dist/modules/business_rules/backend/rules/create/page.js +1 -0
- package/dist/modules/business_rules/backend/rules/create/page.js.map +2 -2
- package/dist/modules/business_rules/backend/rules/page.js +1 -0
- package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
- package/dist/modules/business_rules/backend/sets/[id]/page.js +1 -0
- package/dist/modules/business_rules/backend/sets/[id]/page.js.map +2 -2
- package/dist/modules/business_rules/backend/sets/create/page.js +1 -0
- package/dist/modules/business_rules/backend/sets/create/page.js.map +2 -2
- package/dist/modules/business_rules/backend/sets/page.js +1 -0
- package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js +1 -0
- package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/categories/create/page.js +1 -0
- package/dist/modules/catalog/backend/catalog/categories/create/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js +1 -0
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js +1 -0
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/create/page.js +1 -0
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/create/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/create/page.js +1 -0
- package/dist/modules/catalog/backend/catalog/products/create/page.js.map +2 -2
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js +1 -0
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductsDataTable.js +1 -0
- package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.js +1 -0
- 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 +2 -1
- package/dist/modules/communication_channels/backend/profile/communication-channels/page.js.map +2 -2
- package/dist/modules/currencies/backend/currencies/[id]/page.js +1 -0
- package/dist/modules/currencies/backend/currencies/[id]/page.js.map +2 -2
- package/dist/modules/currencies/backend/currencies/create/page.js +1 -0
- package/dist/modules/currencies/backend/currencies/create/page.js.map +2 -2
- package/dist/modules/currencies/backend/currencies/page.js +1 -0
- package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
- package/dist/modules/currencies/backend/exchange-rates/[id]/page.js +1 -0
- package/dist/modules/currencies/backend/exchange-rates/[id]/page.js.map +2 -2
- package/dist/modules/currencies/backend/exchange-rates/create/page.js +1 -0
- package/dist/modules/currencies/backend/exchange-rates/create/page.js.map +2 -2
- package/dist/modules/currencies/backend/exchange-rates/page.js +1 -0
- package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js +1 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/create/page.js +1 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/create/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +1 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js +1 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/create/page.js +1 -0
- package/dist/modules/customers/backend/customers/companies/create/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/page.js +1 -0
- package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/page.js +1 -0
- package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/create/page.js +1 -0
- package/dist/modules/customers/backend/customers/people/create/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/page.js +1 -0
- package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
- package/dist/modules/customers/components/CustomerTodosTable.js +1 -0
- package/dist/modules/customers/components/CustomerTodosTable.js.map +2 -2
- package/dist/modules/customers/components/detail/DealForm.js +1 -0
- package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/page.js +1 -0
- package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
- package/dist/modules/devices/backend/devices/[id]/page.js +1 -0
- package/dist/modules/devices/backend/devices/[id]/page.js.map +2 -2
- package/dist/modules/devices/backend/devices/create/page.js +1 -0
- package/dist/modules/devices/backend/devices/create/page.js.map +2 -2
- package/dist/modules/devices/backend/devices/page.js +1 -0
- package/dist/modules/devices/backend/devices/page.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionaryTable.js +1 -0
- package/dist/modules/dictionaries/components/DictionaryTable.js.map +2 -2
- package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js +1 -0
- package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/organizations/create/page.js +1 -0
- package/dist/modules/directory/backend/directory/organizations/create/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/organizations/page.js +1 -0
- package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js +1 -0
- package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/tenants/create/page.js +1 -0
- package/dist/modules/directory/backend/directory/tenants/create/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/tenants/page.js +1 -0
- package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/page.js +1 -0
- package/dist/modules/entities/backend/entities/user/[entityId]/page.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js +1 -0
- package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/create/page.js +1 -0
- package/dist/modules/entities/backend/entities/user/[entityId]/records/create/page.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +1 -0
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/create/page.js +1 -0
- package/dist/modules/entities/backend/entities/user/create/page.js.map +2 -2
- package/dist/modules/entities/components/SystemEntitiesTable.js +1 -0
- package/dist/modules/entities/components/SystemEntitiesTable.js.map +2 -2
- package/dist/modules/entities/components/UserEntitiesTable.js +1 -0
- package/dist/modules/entities/components/UserEntitiesTable.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/evidence-submissions/[id]/page.js +1 -0
- package/dist/modules/eudr/backend/eudr/evidence-submissions/[id]/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/evidence-submissions/create/page.js +1 -0
- package/dist/modules/eudr/backend/eudr/evidence-submissions/create/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js +1 -0
- package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/plots/[id]/page.js +1 -0
- package/dist/modules/eudr/backend/eudr/plots/[id]/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/plots/create/page.js +1 -0
- package/dist/modules/eudr/backend/eudr/plots/create/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/plots/page.js +1 -0
- package/dist/modules/eudr/backend/eudr/plots/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/product-mappings/[id]/page.js +1 -0
- package/dist/modules/eudr/backend/eudr/product-mappings/[id]/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/product-mappings/create/page.js +1 -0
- package/dist/modules/eudr/backend/eudr/product-mappings/create/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/product-mappings/page.js +1 -0
- package/dist/modules/eudr/backend/eudr/product-mappings/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/risk-assessments/[id]/page.js +1 -0
- package/dist/modules/eudr/backend/eudr/risk-assessments/[id]/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/risk-assessments/create/page.js +1 -0
- package/dist/modules/eudr/backend/eudr/risk-assessments/create/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/risk-assessments/page.js +1 -0
- package/dist/modules/eudr/backend/eudr/risk-assessments/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/statements/[id]/page.js +2 -0
- package/dist/modules/eudr/backend/eudr/statements/[id]/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/statements/create/page.js +1 -0
- package/dist/modules/eudr/backend/eudr/statements/create/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/statements/page.js +1 -0
- package/dist/modules/eudr/backend/eudr/statements/page.js.map +2 -2
- package/dist/modules/eudr/components/MappingSuggestionsDialog.js +1 -0
- package/dist/modules/eudr/components/MappingSuggestionsDialog.js.map +2 -2
- package/dist/modules/eudr/components/MitigationActionsSection.js +1 -0
- package/dist/modules/eudr/components/MitigationActionsSection.js.map +2 -2
- package/dist/modules/eudr/components/StatementRiskSection.js +1 -0
- package/dist/modules/eudr/components/StatementRiskSection.js.map +2 -2
- package/dist/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.js +1 -0
- package/dist/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.js.map +2 -2
- package/dist/modules/feature_toggles/backend/feature-toggles/global/create/page.js +1 -0
- package/dist/modules/feature_toggles/backend/feature-toggles/global/create/page.js.map +2 -2
- package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +1 -0
- package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
- package/dist/modules/feature_toggles/components/OverridesTable.js +1 -0
- package/dist/modules/feature_toggles/components/OverridesTable.js.map +2 -2
- package/dist/modules/inbox_ops/backend/inbox-ops/page.js +1 -0
- package/dist/modules/inbox_ops/backend/inbox-ops/page.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/[id]/page.js +1 -0
- package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
- package/dist/modules/messages/components/MessagesInboxPageClient.js +1 -0
- package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
- package/dist/modules/messages/components/message-detail/panels/MainMessageHeader.js +1 -1
- package/dist/modules/messages/components/message-detail/panels/MainMessageHeader.js.map +2 -2
- package/dist/modules/payment_gateways/backend/payment-gateways/page.js +1 -0
- package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +2 -2
- package/dist/modules/planner/backend/planner/availability-rulesets/page.js +1 -0
- package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
- package/dist/modules/planner/components/AvailabilityRuleSetForm.js +1 -0
- package/dist/modules/planner/components/AvailabilityRuleSetForm.js.map +2 -2
- package/dist/modules/push_notifications/backend/push_notifications/page.js +1 -0
- package/dist/modules/push_notifications/backend/push_notifications/page.js.map +2 -2
- package/dist/modules/push_notifications/backend/push_notifications/send/page.js +1 -0
- package/dist/modules/push_notifications/backend/push_notifications/send/page.js.map +2 -2
- package/dist/modules/query_index/components/QueryIndexesTable.js +1 -0
- package/dist/modules/query_index/components/QueryIndexesTable.js.map +2 -2
- package/dist/modules/resources/backend/resources/resource-types/page.js +1 -0
- package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/create/page.js +1 -0
- package/dist/modules/resources/backend/resources/resources/create/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/page.js +1 -0
- package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
- package/dist/modules/resources/components/ResourceCrudForm.js +2 -0
- package/dist/modules/resources/components/ResourceCrudForm.js.map +2 -2
- package/dist/modules/resources/components/ResourceTypeCrudForm.js +1 -0
- package/dist/modules/resources/components/ResourceTypeCrudForm.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js +1 -0
- package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/create/page.js +1 -0
- package/dist/modules/sales/backend/sales/channels/create/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/offers/page.js +2 -2
- package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/page.js +2 -1
- package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
- package/dist/modules/sales/components/channels/ChannelOfferForm.js +1 -0
- package/dist/modules/sales/components/channels/ChannelOfferForm.js.map +2 -2
- package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +1 -1
- package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentForm.js +1 -0
- package/dist/modules/sales/components/documents/SalesDocumentForm.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js +2 -1
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
- package/dist/modules/shipping_carriers/backend/shipping-carriers/create/page.js +2 -1
- package/dist/modules/shipping_carriers/backend/shipping-carriers/create/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/leave-requests/page.js +1 -0
- package/dist/modules/staff/backend/staff/leave-requests/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/my-leave-requests/page.js +1 -0
- package/dist/modules/staff/backend/staff/my-leave-requests/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/profile/create/page.js +1 -0
- package/dist/modules/staff/backend/staff/profile/create/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/create/page.js +1 -0
- package/dist/modules/staff/backend/staff/team-members/create/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/page.js +1 -0
- package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-roles/page.js +1 -0
- package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +1 -0
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/page.js +1 -0
- package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.js +1 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/create/page.js +1 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/create/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/page.js +1 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
- package/dist/modules/staff/components/LeaveRequestForm.js +1 -0
- package/dist/modules/staff/components/LeaveRequestForm.js.map +2 -2
- package/dist/modules/staff/components/TeamForm.js +1 -0
- package/dist/modules/staff/components/TeamForm.js.map +2 -2
- package/dist/modules/staff/components/TeamMemberForm.js +2 -0
- package/dist/modules/staff/components/TeamMemberForm.js.map +2 -2
- package/dist/modules/staff/components/TeamRoleForm.js +1 -0
- package/dist/modules/staff/components/TeamRoleForm.js.map +2 -2
- package/dist/modules/warranty_claims/backend/warranty_claims/[id]/edit/page.js +1 -0
- package/dist/modules/warranty_claims/backend/warranty_claims/[id]/edit/page.js.map +2 -2
- package/dist/modules/warranty_claims/backend/warranty_claims/create/page.js +1 -0
- package/dist/modules/warranty_claims/backend/warranty_claims/create/page.js.map +2 -2
- package/dist/modules/warranty_claims/backend/warranty_claims/registrations/[id]/edit/page.js +1 -0
- package/dist/modules/warranty_claims/backend/warranty_claims/registrations/[id]/edit/page.js.map +2 -2
- package/dist/modules/warranty_claims/backend/warranty_claims/registrations/create/page.js +1 -0
- package/dist/modules/warranty_claims/backend/warranty_claims/registrations/create/page.js.map +2 -2
- package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/[id]/edit/page.js +1 -0
- package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/[id]/edit/page.js.map +2 -2
- package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/create/page.js +1 -0
- package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/create/page.js.map +2 -2
- package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/[id]/edit/page.js +1 -0
- package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/[id]/edit/page.js.map +2 -2
- package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/create/page.js +1 -0
- package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/create/page.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsConfigurationPage.js +4 -0
- package/dist/modules/wms/components/backend/WmsConfigurationPage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js +1 -0
- package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsLocationDetailPage.js +1 -0
- package/dist/modules/wms/components/backend/WmsLocationDetailPage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsLotDetailPage.js +1 -0
- package/dist/modules/wms/components/backend/WmsLotDetailPage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsLotsListPage.js +1 -0
- package/dist/modules/wms/components/backend/WmsLotsListPage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js +1 -0
- package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsSkuDetailPage.js +1 -0
- package/dist/modules/wms/components/backend/WmsSkuDetailPage.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/[id]/page.js +1 -0
- package/dist/modules/workflows/backend/definitions/[id]/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/create/page.js +1 -0
- package/dist/modules/workflows/backend/definitions/create/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/page.js +1 -0
- package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
- package/dist/modules/workflows/backend/events/page.js +1 -0
- package/dist/modules/workflows/backend/events/page.js.map +2 -2
- package/dist/modules/workflows/backend/instances/page.js +1 -0
- package/dist/modules/workflows/backend/instances/page.js.map +2 -2
- package/dist/modules/workflows/backend/tasks/page.js +1 -0
- package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
- package/package.json +7 -7
- package/src/modules/api_keys/backend/api-keys/create/page.tsx +1 -0
- package/src/modules/api_keys/backend/api-keys/page.tsx +2 -1
- package/src/modules/attachments/components/AttachmentLibrary.tsx +1 -0
- package/src/modules/audit_logs/backend/audit-logs/page.tsx +2 -1
- package/src/modules/audit_logs/components/AccessLogsTable.tsx +1 -0
- package/src/modules/audit_logs/components/AuditLogsActions.tsx +1 -0
- package/src/modules/auth/backend/roles/[id]/edit/page.tsx +1 -0
- package/src/modules/auth/backend/roles/create/page.tsx +1 -0
- package/src/modules/auth/backend/roles/page.tsx +2 -1
- package/src/modules/auth/backend/users/[id]/edit/page.tsx +1 -0
- package/src/modules/auth/backend/users/create/page.tsx +1 -0
- package/src/modules/auth/backend/users/page.tsx +2 -1
- package/src/modules/business_rules/backend/logs/page.tsx +2 -1
- package/src/modules/business_rules/backend/rules/[id]/page.tsx +1 -0
- package/src/modules/business_rules/backend/rules/create/page.tsx +1 -0
- package/src/modules/business_rules/backend/rules/page.tsx +2 -1
- package/src/modules/business_rules/backend/sets/[id]/page.tsx +1 -0
- package/src/modules/business_rules/backend/sets/create/page.tsx +1 -0
- package/src/modules/business_rules/backend/sets/page.tsx +2 -1
- package/src/modules/catalog/backend/catalog/categories/[id]/edit/page.tsx +1 -0
- package/src/modules/catalog/backend/catalog/categories/create/page.tsx +1 -0
- package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +1 -0
- package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx +1 -0
- package/src/modules/catalog/backend/catalog/products/[productId]/variants/create/page.tsx +1 -0
- package/src/modules/catalog/backend/catalog/products/create/page.tsx +1 -0
- package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +2 -1
- package/src/modules/catalog/components/products/ProductsDataTable.tsx +2 -1
- package/src/modules/communication_channels/backend/communication_channels/channels/page.tsx +1 -0
- package/src/modules/communication_channels/backend/profile/communication-channels/page.tsx +3 -2
- package/src/modules/currencies/backend/currencies/[id]/page.tsx +1 -0
- package/src/modules/currencies/backend/currencies/create/page.tsx +1 -0
- package/src/modules/currencies/backend/currencies/page.tsx +2 -1
- package/src/modules/currencies/backend/exchange-rates/[id]/page.tsx +1 -0
- package/src/modules/currencies/backend/exchange-rates/create/page.tsx +1 -0
- package/src/modules/currencies/backend/exchange-rates/page.tsx +2 -1
- package/src/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.tsx +1 -0
- package/src/modules/customer_accounts/backend/customer_accounts/roles/create/page.tsx +1 -0
- package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +2 -1
- package/src/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.tsx +1 -0
- package/src/modules/customers/backend/customers/companies/create/page.tsx +1 -0
- package/src/modules/customers/backend/customers/companies/page.tsx +1 -0
- package/src/modules/customers/backend/customers/deals/page.tsx +1 -0
- package/src/modules/customers/backend/customers/people/create/page.tsx +1 -0
- package/src/modules/customers/backend/customers/people/page.tsx +1 -0
- package/src/modules/customers/components/CustomerTodosTable.tsx +1 -0
- package/src/modules/customers/components/detail/DealForm.tsx +1 -0
- package/src/modules/data_sync/backend/data-sync/page.tsx +1 -0
- package/src/modules/devices/backend/devices/[id]/page.tsx +1 -0
- package/src/modules/devices/backend/devices/create/page.tsx +1 -0
- package/src/modules/devices/backend/devices/page.tsx +2 -1
- package/src/modules/dictionaries/components/DictionaryTable.tsx +1 -0
- package/src/modules/directory/backend/directory/organizations/[id]/edit/page.tsx +1 -0
- package/src/modules/directory/backend/directory/organizations/create/page.tsx +1 -0
- package/src/modules/directory/backend/directory/organizations/page.tsx +2 -1
- package/src/modules/directory/backend/directory/tenants/[id]/edit/page.tsx +1 -0
- package/src/modules/directory/backend/directory/tenants/create/page.tsx +1 -0
- package/src/modules/directory/backend/directory/tenants/page.tsx +2 -1
- package/src/modules/entities/backend/entities/user/[entityId]/page.tsx +1 -0
- package/src/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.tsx +1 -0
- package/src/modules/entities/backend/entities/user/[entityId]/records/create/page.tsx +1 -0
- package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +2 -1
- package/src/modules/entities/backend/entities/user/create/page.tsx +1 -0
- package/src/modules/entities/components/SystemEntitiesTable.tsx +1 -0
- package/src/modules/entities/components/UserEntitiesTable.tsx +1 -0
- package/src/modules/eudr/backend/eudr/evidence-submissions/[id]/page.tsx +1 -0
- package/src/modules/eudr/backend/eudr/evidence-submissions/create/page.tsx +1 -0
- package/src/modules/eudr/backend/eudr/evidence-submissions/page.tsx +2 -1
- package/src/modules/eudr/backend/eudr/plots/[id]/page.tsx +1 -0
- package/src/modules/eudr/backend/eudr/plots/create/page.tsx +1 -0
- package/src/modules/eudr/backend/eudr/plots/page.tsx +2 -1
- package/src/modules/eudr/backend/eudr/product-mappings/[id]/page.tsx +1 -0
- package/src/modules/eudr/backend/eudr/product-mappings/create/page.tsx +1 -0
- package/src/modules/eudr/backend/eudr/product-mappings/page.tsx +2 -1
- package/src/modules/eudr/backend/eudr/risk-assessments/[id]/page.tsx +1 -0
- package/src/modules/eudr/backend/eudr/risk-assessments/create/page.tsx +1 -0
- package/src/modules/eudr/backend/eudr/risk-assessments/page.tsx +2 -1
- package/src/modules/eudr/backend/eudr/statements/[id]/page.tsx +2 -0
- package/src/modules/eudr/backend/eudr/statements/create/page.tsx +1 -0
- package/src/modules/eudr/backend/eudr/statements/page.tsx +2 -1
- package/src/modules/eudr/components/MappingSuggestionsDialog.tsx +1 -0
- package/src/modules/eudr/components/MitigationActionsSection.tsx +1 -0
- package/src/modules/eudr/components/StatementRiskSection.tsx +1 -0
- package/src/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.tsx +1 -0
- package/src/modules/feature_toggles/backend/feature-toggles/global/create/page.tsx +1 -0
- package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +2 -1
- package/src/modules/feature_toggles/components/OverridesTable.tsx +2 -1
- package/src/modules/inbox_ops/backend/inbox-ops/page.tsx +2 -1
- package/src/modules/integrations/backend/integrations/[id]/page.tsx +2 -1
- package/src/modules/messages/components/MessagesInboxPageClient.tsx +1 -0
- package/src/modules/messages/components/message-detail/panels/MainMessageHeader.tsx +2 -2
- package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +1 -0
- package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +2 -1
- package/src/modules/planner/components/AvailabilityRuleSetForm.tsx +1 -0
- package/src/modules/push_notifications/backend/push_notifications/page.tsx +2 -1
- package/src/modules/push_notifications/backend/push_notifications/send/page.tsx +1 -0
- package/src/modules/query_index/components/QueryIndexesTable.tsx +2 -1
- package/src/modules/resources/backend/resources/resource-types/page.tsx +1 -0
- package/src/modules/resources/backend/resources/resources/create/page.tsx +1 -0
- package/src/modules/resources/backend/resources/resources/page.tsx +1 -0
- package/src/modules/resources/components/ResourceCrudForm.tsx +3 -0
- package/src/modules/resources/components/ResourceTypeCrudForm.tsx +1 -0
- package/src/modules/sales/backend/sales/channels/[channelId]/edit/page.tsx +1 -0
- package/src/modules/sales/backend/sales/channels/create/page.tsx +1 -0
- package/src/modules/sales/backend/sales/channels/offers/page.tsx +3 -3
- package/src/modules/sales/backend/sales/channels/page.tsx +3 -2
- package/src/modules/sales/components/channels/ChannelOfferForm.tsx +1 -0
- package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +2 -2
- package/src/modules/sales/components/documents/SalesDocumentForm.tsx +1 -0
- package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +3 -2
- package/src/modules/shipping_carriers/backend/shipping-carriers/create/page.tsx +2 -1
- package/src/modules/staff/backend/staff/leave-requests/page.tsx +2 -1
- package/src/modules/staff/backend/staff/my-leave-requests/page.tsx +2 -1
- package/src/modules/staff/backend/staff/profile/create/page.tsx +1 -0
- package/src/modules/staff/backend/staff/team-members/create/page.tsx +1 -0
- package/src/modules/staff/backend/staff/team-members/page.tsx +2 -2
- package/src/modules/staff/backend/staff/team-roles/page.tsx +2 -2
- package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +1 -0
- package/src/modules/staff/backend/staff/teams/page.tsx +2 -1
- package/src/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.tsx +1 -0
- package/src/modules/staff/backend/staff/timesheets/projects/create/page.tsx +1 -0
- package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +2 -1
- package/src/modules/staff/components/LeaveRequestForm.tsx +1 -0
- package/src/modules/staff/components/TeamForm.tsx +1 -0
- package/src/modules/staff/components/TeamMemberForm.tsx +3 -0
- package/src/modules/staff/components/TeamRoleForm.tsx +1 -0
- package/src/modules/warranty_claims/backend/warranty_claims/[id]/edit/page.tsx +1 -0
- package/src/modules/warranty_claims/backend/warranty_claims/create/page.tsx +1 -0
- package/src/modules/warranty_claims/backend/warranty_claims/registrations/[id]/edit/page.tsx +1 -0
- package/src/modules/warranty_claims/backend/warranty_claims/registrations/create/page.tsx +1 -0
- package/src/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/[id]/edit/page.tsx +1 -0
- package/src/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/create/page.tsx +1 -0
- package/src/modules/warranty_claims/backend/warranty_claims/vendor-policies/[id]/edit/page.tsx +1 -0
- package/src/modules/warranty_claims/backend/warranty_claims/vendor-policies/create/page.tsx +1 -0
- package/src/modules/wms/components/backend/WmsConfigurationPage.tsx +4 -0
- package/src/modules/wms/components/backend/WmsInventoryConsolePage.tsx +1 -0
- package/src/modules/wms/components/backend/WmsLocationDetailPage.tsx +1 -0
- package/src/modules/wms/components/backend/WmsLotDetailPage.tsx +1 -0
- package/src/modules/wms/components/backend/WmsLotsListPage.tsx +1 -0
- package/src/modules/wms/components/backend/WmsOperationalDashboardPage.tsx +1 -0
- package/src/modules/wms/components/backend/WmsSkuDetailPage.tsx +1 -0
- package/src/modules/workflows/backend/definitions/[id]/page.tsx +1 -0
- package/src/modules/workflows/backend/definitions/create/page.tsx +1 -0
- package/src/modules/workflows/backend/definitions/page.tsx +2 -1
- package/src/modules/workflows/backend/events/page.tsx +2 -1
- package/src/modules/workflows/backend/instances/page.tsx +2 -1
- package/src/modules/workflows/backend/tasks/page.tsx +2 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../../src/modules/sales/backend/sales/channels/%5BchannelId%5D/edit/page.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useRouter, useSearchParams } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { CrudForm } from '@open-mercato/ui/backend/CrudForm'\nimport { ErrorMessage, RecordNotFoundState } from '@open-mercato/ui/backend/detail'\nimport { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'\nimport { updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { extractCustomFieldEntries } from '@open-mercato/shared/lib/crud/custom-fields-client'\nimport { useChannelFields, buildChannelPayload, type ChannelFormValues } from '@open-mercato/core/modules/sales/components/channels/channelFormFields'\nimport { E } from '#generated/entities.ids.generated'\nimport { SalesChannelOffersPanel } from '@open-mercato/core/modules/sales/components/channels/SalesChannelOffersPanel'\nimport { SendObjectMessageDialog } from '@open-mercato/ui/backend/messages'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('sales')\n\ntype ChannelApiResponse = {\n items?: Array<Record<string, unknown>>\n}\n\nexport default function EditChannelPage({ params }: { params?: { channelId?: string } }) {\n const channelId = params?.channelId ?? ''\n const router = useRouter()\n const searchParams = useSearchParams()\n const t = useT()\n const { fields, groups } = useChannelFields()\n const [initialValues, setInitialValues] = React.useState<ChannelFormValues | null>(null)\n const [loading, setLoading] = React.useState(true)\n const [error, setError] = React.useState<string | null>(null)\n const [isNotFound, setIsNotFound] = React.useState(false)\n const [activeTab, setActiveTab] = React.useState<'settings' | 'offers'>('settings')\n\n React.useEffect(() => {\n const tabParam = (searchParams?.get('tab') ?? '').toLowerCase()\n if (tabParam === 'offers') {\n setActiveTab('offers')\n } else if (tabParam === 'settings') {\n setActiveTab('settings')\n }\n }, [searchParams])\n\n React.useEffect(() => {\n if (!channelId) return\n let cancelled = false\n async function loadChannel() {\n setLoading(true)\n setError(null)\n setIsNotFound(false)\n try {\n const payload = await readApiResultOrThrow<ChannelApiResponse>(\n `/api/sales/channels?id=${encodeURIComponent(channelId)}&pageSize=1`,\n undefined,\n { errorMessage: t('sales.channels.form.errors.load', 'Failed to load channel.') },\n )\n const item = Array.isArray(payload.items) ? payload.items[0] : null\n if (!item) {\n if (!cancelled) setIsNotFound(true)\n return\n }\n if (!cancelled) {\n setInitialValues(mapChannelToFormValues(item))\n }\n } catch (err) {\n logger.error('sales.channels.load', { err })\n if (!cancelled) {\n if ((err as { status?: number }).status === 404) {\n setIsNotFound(true)\n } else {\n setError(t('sales.channels.form.errors.load', 'Failed to load channel.'))\n }\n }\n } finally {\n if (!cancelled) setLoading(false)\n }\n }\n void loadChannel()\n return () => { cancelled = true }\n }, [channelId, t])\n\n const handleSubmit = React.useCallback(async (values: ChannelFormValues) => {\n if (!channelId) return\n const payload: Record<string, unknown> = { id: channelId, ...buildChannelPayload(values) }\n const customFields = collectCustomFieldValues(values)\n if (Object.keys(customFields).length) payload.customFields = customFields\n await updateCrud('sales/channels', payload, {\n errorMessage: t('sales.channels.form.errors.update', 'Failed to save channel.'),\n })\n flash(t('sales.channels.form.messages.updated', 'Channel updated.'), 'success')\n router.push('/backend/sales/channels')\n }, [channelId, router, t])\n\n const handleDelete = React.useCallback(async () => {\n if (!channelId) return\n await deleteCrud('sales/channels', channelId, {\n errorMessage: t('sales.channels.form.errors.delete', 'Failed to delete channel.'),\n })\n flash(t('sales.channels.form.messages.deleted', 'Channel deleted.'), 'success')\n router.push('/backend/sales/channels')\n }, [channelId, router, t])\n\n const handleTabSelect = React.useCallback((value: 'settings' | 'offers') => {\n setActiveTab(value)\n if (!channelId) return\n const basePath = `/backend/sales/channels/${channelId}/edit`\n const nextUrl = value === 'offers' ? `${basePath}?tab=offers` : basePath\n router.replace(nextUrl)\n }, [channelId, router])\n\n const tabButton = React.useCallback((value: 'settings' | 'offers', label: string) => (\n <button\n key={value}\n type=\"button\"\n className={`px-4 py-2 text-sm font-medium border-b-2 ${activeTab === value ? 'border-accent-indigo text-foreground' : 'border-transparent text-muted-foreground'}`}\n onClick={() => handleTabSelect(value)}\n >\n {label}\n </button>\n ), [activeTab, handleTabSelect])\n\n const renderTabs = React.useCallback(() => (\n <div className=\"flex items-center gap-2 border-b mb-6\">\n {tabButton('settings', t('sales.channels.form.tabs.settings', 'Settings'))}\n {tabButton('offers', t('sales.channels.form.tabs.offers', 'Offers'))}\n </div>\n ), [tabButton, t])\n\n if (isNotFound) {\n return (\n <Page>\n <PageBody>\n <RecordNotFoundState\n label={t('sales.channels.form.errors.notFound', 'Channel not found.')}\n backHref=\"/backend/sales/channels\"\n backLabel={t('sales.channels.actions.backToList', 'Back to channels')}\n />\n </PageBody>\n </Page>\n )\n }\n\n if (error && !loading && !initialValues) {\n return (\n <Page>\n <PageBody>\n <ErrorMessage label={error} />\n </PageBody>\n </Page>\n )\n }\n\n return (\n <Page>\n <PageBody>\n {activeTab === 'settings' ? (\n <CrudForm<ChannelFormValues>\n title={t('sales.channels.form.editTitle', 'Edit channel')}\n versionHistory={{ resourceKind: 'sales.channel', resourceId: channelId ? String(channelId) : '' }}\n extraActions={channelId ? (\n <SendObjectMessageDialog\n object={{\n entityModule: 'sales',\n entityType: 'channel',\n entityId: channelId,\n previewData: {\n title: initialValues?.name ?? '',\n metadata: {\n [t('sales.channels.form.contactEmail')]: initialValues?.contactEmail ?? '-',\n [t('sales.channels.form.websiteUrl')]: initialValues?.websiteUrl ?? '-',\n },\n },\n }}\n viewHref={`/backend/sales/channels/${channelId}/edit`}\n />\n ) : undefined}\n entityId={E.sales.sales_channel}\n fields={fields}\n groups={[\n ...groups,\n { id: 'custom', title: t('entities.customFields.title', 'Custom Attributes'), column: 2, kind: 'customFields' },\n ]}\n initialValues={initialValues ?? undefined}\n optimisticLockUpdatedAt={typeof initialValues?.updatedAt === 'string' ? initialValues.updatedAt : null}\n isLoading={loading}\n loadingMessage={t('sales.channels.form.loading', 'Loading channel\u2026')}\n submitLabel={t('sales.channels.form.updateSubmit', 'Save changes')}\n cancelHref=\"/backend/sales/channels\"\n backHref=\"/backend/sales/channels\"\n contentHeader={renderTabs()}\n onSubmit={handleSubmit}\n onDelete={handleDelete}\n deleteVisible\n deleteRedirect=\"/backend/sales/channels\"\n />\n ) : (\n <>\n {renderTabs()}\n <SalesChannelOffersPanel channelId={channelId} channelName={initialValues?.name ?? ''} />\n </>\n )}\n </PageBody>\n </Page>\n )\n}\n\nfunction mapChannelToFormValues(item: Record<string, unknown>): ChannelFormValues {\n const values: ChannelFormValues = {\n name: typeof item.name === 'string' ? item.name : '',\n code: typeof item.code === 'string' ? item.code : null,\n description: typeof item.description === 'string' ? item.description : null,\n websiteUrl: typeof item.websiteUrl === 'string' ? item.websiteUrl : typeof item.website_url === 'string' ? item.website_url : null,\n contactEmail: typeof item.contactEmail === 'string' ? item.contactEmail : typeof item.contact_email === 'string' ? item.contact_email : null,\n contactPhone: typeof item.contactPhone === 'string' ? item.contactPhone : typeof item.contact_phone === 'string' ? item.contact_phone : null,\n addressLine1: typeof item.addressLine1 === 'string' ? item.addressLine1 : typeof item.address_line1 === 'string' ? item.address_line1 : null,\n addressLine2: typeof item.addressLine2 === 'string' ? item.addressLine2 : typeof item.address_line2 === 'string' ? item.address_line2 : null,\n city: typeof item.city === 'string' ? item.city : null,\n region: typeof item.region === 'string' ? item.region : null,\n postalCode: typeof item.postalCode === 'string' ? item.postalCode : typeof item.postal_code === 'string' ? item.postal_code : null,\n country: typeof item.country === 'string' ? item.country : null,\n latitude: typeof item.latitude === 'number' ? item.latitude : typeof item.latitude === 'string' ? item.latitude : null,\n longitude: typeof item.longitude === 'number' ? item.longitude : typeof item.longitude === 'string' ? item.longitude : null,\n statusEntryId: typeof item.statusEntryId === 'string'\n ? item.statusEntryId\n : typeof item.status_entry_id === 'string'\n ? item.status_entry_id\n : null,\n isActive: item.isActive === true || item.is_active === true,\n updatedAt: typeof item.updatedAt === 'string'\n ? item.updatedAt\n : typeof item.updated_at === 'string'\n ? item.updated_at\n : null,\n }\n return { ...values, ...extractCustomFieldEntries(item) }\n}\n"],
|
|
5
|
-
"mappings": ";AAkHI,
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useRouter, useSearchParams } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { CrudForm } from '@open-mercato/ui/backend/CrudForm'\nimport { ErrorMessage, RecordNotFoundState } from '@open-mercato/ui/backend/detail'\nimport { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'\nimport { updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { extractCustomFieldEntries } from '@open-mercato/shared/lib/crud/custom-fields-client'\nimport { useChannelFields, buildChannelPayload, type ChannelFormValues } from '@open-mercato/core/modules/sales/components/channels/channelFormFields'\nimport { E } from '#generated/entities.ids.generated'\nimport { SalesChannelOffersPanel } from '@open-mercato/core/modules/sales/components/channels/SalesChannelOffersPanel'\nimport { SendObjectMessageDialog } from '@open-mercato/ui/backend/messages'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('sales')\n\ntype ChannelApiResponse = {\n items?: Array<Record<string, unknown>>\n}\n\nexport default function EditChannelPage({ params }: { params?: { channelId?: string } }) {\n const channelId = params?.channelId ?? ''\n const router = useRouter()\n const searchParams = useSearchParams()\n const t = useT()\n const { fields, groups } = useChannelFields()\n const [initialValues, setInitialValues] = React.useState<ChannelFormValues | null>(null)\n const [loading, setLoading] = React.useState(true)\n const [error, setError] = React.useState<string | null>(null)\n const [isNotFound, setIsNotFound] = React.useState(false)\n const [activeTab, setActiveTab] = React.useState<'settings' | 'offers'>('settings')\n\n React.useEffect(() => {\n const tabParam = (searchParams?.get('tab') ?? '').toLowerCase()\n if (tabParam === 'offers') {\n setActiveTab('offers')\n } else if (tabParam === 'settings') {\n setActiveTab('settings')\n }\n }, [searchParams])\n\n React.useEffect(() => {\n if (!channelId) return\n let cancelled = false\n async function loadChannel() {\n setLoading(true)\n setError(null)\n setIsNotFound(false)\n try {\n const payload = await readApiResultOrThrow<ChannelApiResponse>(\n `/api/sales/channels?id=${encodeURIComponent(channelId)}&pageSize=1`,\n undefined,\n { errorMessage: t('sales.channels.form.errors.load', 'Failed to load channel.') },\n )\n const item = Array.isArray(payload.items) ? payload.items[0] : null\n if (!item) {\n if (!cancelled) setIsNotFound(true)\n return\n }\n if (!cancelled) {\n setInitialValues(mapChannelToFormValues(item))\n }\n } catch (err) {\n logger.error('sales.channels.load', { err })\n if (!cancelled) {\n if ((err as { status?: number }).status === 404) {\n setIsNotFound(true)\n } else {\n setError(t('sales.channels.form.errors.load', 'Failed to load channel.'))\n }\n }\n } finally {\n if (!cancelled) setLoading(false)\n }\n }\n void loadChannel()\n return () => { cancelled = true }\n }, [channelId, t])\n\n const handleSubmit = React.useCallback(async (values: ChannelFormValues) => {\n if (!channelId) return\n const payload: Record<string, unknown> = { id: channelId, ...buildChannelPayload(values) }\n const customFields = collectCustomFieldValues(values)\n if (Object.keys(customFields).length) payload.customFields = customFields\n await updateCrud('sales/channels', payload, {\n errorMessage: t('sales.channels.form.errors.update', 'Failed to save channel.'),\n })\n flash(t('sales.channels.form.messages.updated', 'Channel updated.'), 'success')\n router.push('/backend/sales/channels')\n }, [channelId, router, t])\n\n const handleDelete = React.useCallback(async () => {\n if (!channelId) return\n await deleteCrud('sales/channels', channelId, {\n errorMessage: t('sales.channels.form.errors.delete', 'Failed to delete channel.'),\n })\n flash(t('sales.channels.form.messages.deleted', 'Channel deleted.'), 'success')\n router.push('/backend/sales/channels')\n }, [channelId, router, t])\n\n const handleTabSelect = React.useCallback((value: 'settings' | 'offers') => {\n setActiveTab(value)\n if (!channelId) return\n const basePath = `/backend/sales/channels/${channelId}/edit`\n const nextUrl = value === 'offers' ? `${basePath}?tab=offers` : basePath\n router.replace(nextUrl)\n }, [channelId, router])\n\n const tabButton = React.useCallback((value: 'settings' | 'offers', label: string) => (\n <button\n key={value}\n type=\"button\"\n className={`px-4 py-2 text-sm font-medium border-b-2 ${activeTab === value ? 'border-accent-indigo text-foreground' : 'border-transparent text-muted-foreground'}`}\n onClick={() => handleTabSelect(value)}\n >\n {label}\n </button>\n ), [activeTab, handleTabSelect])\n\n const renderTabs = React.useCallback(() => (\n <div className=\"flex items-center gap-2 border-b mb-6\">\n {tabButton('settings', t('sales.channels.form.tabs.settings', 'Settings'))}\n {tabButton('offers', t('sales.channels.form.tabs.offers', 'Offers'))}\n </div>\n ), [tabButton, t])\n\n if (isNotFound) {\n return (\n <Page>\n <PageBody>\n <RecordNotFoundState\n label={t('sales.channels.form.errors.notFound', 'Channel not found.')}\n backHref=\"/backend/sales/channels\"\n backLabel={t('sales.channels.actions.backToList', 'Back to channels')}\n />\n </PageBody>\n </Page>\n )\n }\n\n if (error && !loading && !initialValues) {\n return (\n <Page>\n <PageBody>\n <ErrorMessage label={error} />\n </PageBody>\n </Page>\n )\n }\n\n return (\n <Page>\n <PageBody>\n {activeTab === 'settings' ? (\n <CrudForm<ChannelFormValues>\n title={t('sales.channels.form.editTitle', 'Edit channel')}\n titleHeadingLevel={1}\n versionHistory={{ resourceKind: 'sales.channel', resourceId: channelId ? String(channelId) : '' }}\n extraActions={channelId ? (\n <SendObjectMessageDialog\n object={{\n entityModule: 'sales',\n entityType: 'channel',\n entityId: channelId,\n previewData: {\n title: initialValues?.name ?? '',\n metadata: {\n [t('sales.channels.form.contactEmail')]: initialValues?.contactEmail ?? '-',\n [t('sales.channels.form.websiteUrl')]: initialValues?.websiteUrl ?? '-',\n },\n },\n }}\n viewHref={`/backend/sales/channels/${channelId}/edit`}\n />\n ) : undefined}\n entityId={E.sales.sales_channel}\n fields={fields}\n groups={[\n ...groups,\n { id: 'custom', title: t('entities.customFields.title', 'Custom Attributes'), column: 2, kind: 'customFields' },\n ]}\n initialValues={initialValues ?? undefined}\n optimisticLockUpdatedAt={typeof initialValues?.updatedAt === 'string' ? initialValues.updatedAt : null}\n isLoading={loading}\n loadingMessage={t('sales.channels.form.loading', 'Loading channel\u2026')}\n submitLabel={t('sales.channels.form.updateSubmit', 'Save changes')}\n cancelHref=\"/backend/sales/channels\"\n backHref=\"/backend/sales/channels\"\n contentHeader={renderTabs()}\n onSubmit={handleSubmit}\n onDelete={handleDelete}\n deleteVisible\n deleteRedirect=\"/backend/sales/channels\"\n />\n ) : (\n <>\n {renderTabs()}\n <SalesChannelOffersPanel channelId={channelId} channelName={initialValues?.name ?? ''} />\n </>\n )}\n </PageBody>\n </Page>\n )\n}\n\nfunction mapChannelToFormValues(item: Record<string, unknown>): ChannelFormValues {\n const values: ChannelFormValues = {\n name: typeof item.name === 'string' ? item.name : '',\n code: typeof item.code === 'string' ? item.code : null,\n description: typeof item.description === 'string' ? item.description : null,\n websiteUrl: typeof item.websiteUrl === 'string' ? item.websiteUrl : typeof item.website_url === 'string' ? item.website_url : null,\n contactEmail: typeof item.contactEmail === 'string' ? item.contactEmail : typeof item.contact_email === 'string' ? item.contact_email : null,\n contactPhone: typeof item.contactPhone === 'string' ? item.contactPhone : typeof item.contact_phone === 'string' ? item.contact_phone : null,\n addressLine1: typeof item.addressLine1 === 'string' ? item.addressLine1 : typeof item.address_line1 === 'string' ? item.address_line1 : null,\n addressLine2: typeof item.addressLine2 === 'string' ? item.addressLine2 : typeof item.address_line2 === 'string' ? item.address_line2 : null,\n city: typeof item.city === 'string' ? item.city : null,\n region: typeof item.region === 'string' ? item.region : null,\n postalCode: typeof item.postalCode === 'string' ? item.postalCode : typeof item.postal_code === 'string' ? item.postal_code : null,\n country: typeof item.country === 'string' ? item.country : null,\n latitude: typeof item.latitude === 'number' ? item.latitude : typeof item.latitude === 'string' ? item.latitude : null,\n longitude: typeof item.longitude === 'number' ? item.longitude : typeof item.longitude === 'string' ? item.longitude : null,\n statusEntryId: typeof item.statusEntryId === 'string'\n ? item.statusEntryId\n : typeof item.status_entry_id === 'string'\n ? item.status_entry_id\n : null,\n isActive: item.isActive === true || item.is_active === true,\n updatedAt: typeof item.updatedAt === 'string'\n ? item.updatedAt\n : typeof item.updated_at === 'string'\n ? item.updated_at\n : null,\n }\n return { ...values, ...extractCustomFieldEntries(item) }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../src/modules/sales/backend/sales/channels/create/page.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { useRouter } from 'next/navigation'\nimport { CrudForm } from '@open-mercato/ui/backend/CrudForm'\nimport { createCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useChannelFields, buildChannelPayload, type ChannelFormValues } from '@open-mercato/core/modules/sales/components/channels/channelFormFields'\nimport { useSalesChannelsEnabled } from '@open-mercato/core/modules/sales/components/useSalesChannelsEnabled'\nimport { SalesChannelsDisabledNotice } from '@open-mercato/core/modules/sales/components/SalesChannelsDisabledNotice'\nimport { E } from '#generated/entities.ids.generated'\n\nexport default function CreateChannelPage() {\n const t = useT()\n const { fields, groups } = useChannelFields()\n const { enabled: channelsEnabled, isLoading: channelsEnabledLoading } = useSalesChannelsEnabled()\n const router = useRouter()\n\n if (!channelsEnabled && !channelsEnabledLoading) {\n return <SalesChannelsDisabledNotice />\n }\n\n return (\n <Page>\n <PageBody>\n <CrudForm<ChannelFormValues>\n title={t('sales.channels.form.createTitle', 'Create sales channel')}\n entityId={E.sales.sales_channel}\n fields={fields}\n groups={[\n ...groups,\n { id: 'custom', title: t('entities.customFields.title', 'Custom Attributes'), column: 2, kind: 'customFields' },\n ]}\n initialValues={{ isActive: true }}\n submitLabel={t('sales.channels.form.createSubmit', 'Create channel')}\n cancelHref=\"/backend/sales/channels\"\n onSubmit={async (values) => {\n const payload = buildChannelPayload(values)\n const customFields = collectCustomFieldValues(values)\n if (Object.keys(customFields).length) {\n payload.customFields = customFields\n }\n await createCrud('sales/channels', payload, {\n errorMessage: t('sales.channels.form.errors.create', 'Failed to create channel.'),\n })\n flash(t('sales.channels.form.messages.created', 'Channel created.'), 'success')\n router.push('/backend/sales/channels')\n }}\n />\n </PageBody>\n </Page>\n )\n}\n"],
|
|
5
|
-
"mappings": ";AAsBW;AAnBX,SAAS,MAAM,gBAAgB;AAC/B,SAAS,iBAAiB;AAC1B,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAC3B,SAAS,gCAAgC;AACzC,SAAS,aAAa;AACtB,SAAS,YAAY;AACrB,SAAS,kBAAkB,2BAAmD;AAC9E,SAAS,+BAA+B;AACxC,SAAS,mCAAmC;AAC5C,SAAS,SAAS;AAEH,SAAR,oBAAqC;AAC1C,QAAM,IAAI,KAAK;AACf,QAAM,EAAE,QAAQ,OAAO,IAAI,iBAAiB;AAC5C,QAAM,EAAE,SAAS,iBAAiB,WAAW,uBAAuB,IAAI,wBAAwB;AAChG,QAAM,SAAS,UAAU;AAEzB,MAAI,CAAC,mBAAmB,CAAC,wBAAwB;AAC/C,WAAO,oBAAC,+BAA4B;AAAA,EACtC;AAEA,SACE,oBAAC,QACC,8BAAC,YACC;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,mCAAmC,sBAAsB;AAAA,MAClE,UAAU,EAAE,MAAM;AAAA,MAClB;AAAA,MACA,QAAQ;AAAA,QACN,GAAG;AAAA,QACH,EAAE,IAAI,UAAU,OAAO,EAAE,+BAA+B,mBAAmB,GAAG,QAAQ,GAAG,MAAM,eAAe;AAAA,MAChH;AAAA,MACA,eAAe,EAAE,UAAU,KAAK;AAAA,MAChC,aAAa,EAAE,oCAAoC,gBAAgB;AAAA,MACnE,YAAW;AAAA,MACX,UAAU,OAAO,WAAW;AAC1B,cAAM,UAAU,oBAAoB,MAAM;AAC1C,cAAM,eAAe,yBAAyB,MAAM;AACpD,YAAI,OAAO,KAAK,YAAY,EAAE,QAAQ;AACpC,kBAAQ,eAAe;AAAA,QACzB;AACA,cAAM,WAAW,kBAAkB,SAAS;AAAA,UAC1C,cAAc,EAAE,qCAAqC,2BAA2B;AAAA,QAClF,CAAC;AACD,cAAM,EAAE,wCAAwC,kBAAkB,GAAG,SAAS;AAC9E,eAAO,KAAK,yBAAyB;AAAA,MACvC;AAAA;AAAA,EACF,GACF,GACF;AAEJ;",
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { useRouter } from 'next/navigation'\nimport { CrudForm } from '@open-mercato/ui/backend/CrudForm'\nimport { createCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useChannelFields, buildChannelPayload, type ChannelFormValues } from '@open-mercato/core/modules/sales/components/channels/channelFormFields'\nimport { useSalesChannelsEnabled } from '@open-mercato/core/modules/sales/components/useSalesChannelsEnabled'\nimport { SalesChannelsDisabledNotice } from '@open-mercato/core/modules/sales/components/SalesChannelsDisabledNotice'\nimport { E } from '#generated/entities.ids.generated'\n\nexport default function CreateChannelPage() {\n const t = useT()\n const { fields, groups } = useChannelFields()\n const { enabled: channelsEnabled, isLoading: channelsEnabledLoading } = useSalesChannelsEnabled()\n const router = useRouter()\n\n if (!channelsEnabled && !channelsEnabledLoading) {\n return <SalesChannelsDisabledNotice />\n }\n\n return (\n <Page>\n <PageBody>\n <CrudForm<ChannelFormValues>\n title={t('sales.channels.form.createTitle', 'Create sales channel')}\n titleHeadingLevel={1}\n entityId={E.sales.sales_channel}\n fields={fields}\n groups={[\n ...groups,\n { id: 'custom', title: t('entities.customFields.title', 'Custom Attributes'), column: 2, kind: 'customFields' },\n ]}\n initialValues={{ isActive: true }}\n submitLabel={t('sales.channels.form.createSubmit', 'Create channel')}\n cancelHref=\"/backend/sales/channels\"\n onSubmit={async (values) => {\n const payload = buildChannelPayload(values)\n const customFields = collectCustomFieldValues(values)\n if (Object.keys(customFields).length) {\n payload.customFields = customFields\n }\n await createCrud('sales/channels', payload, {\n errorMessage: t('sales.channels.form.errors.create', 'Failed to create channel.'),\n })\n flash(t('sales.channels.form.messages.created', 'Channel created.'), 'success')\n router.push('/backend/sales/channels')\n }}\n />\n </PageBody>\n </Page>\n )\n}\n"],
|
|
5
|
+
"mappings": ";AAsBW;AAnBX,SAAS,MAAM,gBAAgB;AAC/B,SAAS,iBAAiB;AAC1B,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAC3B,SAAS,gCAAgC;AACzC,SAAS,aAAa;AACtB,SAAS,YAAY;AACrB,SAAS,kBAAkB,2BAAmD;AAC9E,SAAS,+BAA+B;AACxC,SAAS,mCAAmC;AAC5C,SAAS,SAAS;AAEH,SAAR,oBAAqC;AAC1C,QAAM,IAAI,KAAK;AACf,QAAM,EAAE,QAAQ,OAAO,IAAI,iBAAiB;AAC5C,QAAM,EAAE,SAAS,iBAAiB,WAAW,uBAAuB,IAAI,wBAAwB;AAChG,QAAM,SAAS,UAAU;AAEzB,MAAI,CAAC,mBAAmB,CAAC,wBAAwB;AAC/C,WAAO,oBAAC,+BAA4B;AAAA,EACtC;AAEA,SACE,oBAAC,QACC,8BAAC,YACC;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,mCAAmC,sBAAsB;AAAA,MAClE,mBAAmB;AAAA,MACnB,UAAU,EAAE,MAAM;AAAA,MAClB;AAAA,MACA,QAAQ;AAAA,QACN,GAAG;AAAA,QACH,EAAE,IAAI,UAAU,OAAO,EAAE,+BAA+B,mBAAmB,GAAG,QAAQ,GAAG,MAAM,eAAe;AAAA,MAChH;AAAA,MACA,eAAe,EAAE,UAAU,KAAK;AAAA,MAChC,aAAa,EAAE,oCAAoC,gBAAgB;AAAA,MACnE,YAAW;AAAA,MACX,UAAU,OAAO,WAAW;AAC1B,cAAM,UAAU,oBAAoB,MAAM;AAC1C,cAAM,eAAe,yBAAyB,MAAM;AACpD,YAAI,OAAO,KAAK,YAAY,EAAE,QAAQ;AACpC,kBAAQ,eAAe;AAAA,QACzB;AACA,cAAM,WAAW,kBAAkB,SAAS;AAAA,UAC1C,cAAc,EAAE,qCAAqC,2BAA2B;AAAA,QAClF,CAAC;AACD,cAAM,EAAE,wCAAwC,kBAAkB,GAAG,SAAS;AAC9E,eAAO,KAAK,yBAAyB;AAAA,MACvC;AAAA;AAAA,EACF,GACF,GACF;AAEJ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -258,8 +258,8 @@ function SalesChannelOffersListPage() {
|
|
|
258
258
|
}
|
|
259
259
|
}, [handleRefresh, mutationContext, runMutation, t]);
|
|
260
260
|
const tableTitle = /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
261
|
-
/* @__PURE__ */ jsx("
|
|
262
|
-
/* @__PURE__ */ jsx("
|
|
261
|
+
/* @__PURE__ */ jsx("h1", { children: t("sales.channels.offers.listTitle", "Sales channel offers") }),
|
|
262
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-normal text-muted-foreground", children: t("sales.channels.offers.listSubtitle", "Review product overrides across every sales channel.") })
|
|
263
263
|
] });
|
|
264
264
|
if (!channelsEnabled && !channelsEnabledLoading) {
|
|
265
265
|
return /* @__PURE__ */ jsx(SalesChannelsDisabledNotice, {});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../src/modules/sales/backend/sales/channels/offers/page.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useRouter } from 'next/navigation'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport type { SortingState } from '@tanstack/react-table'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport type { FilterOption } from '@open-mercato/ui/backend/FilterOverlay'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { BooleanIcon } from '@open-mercato/ui/backend/ValueIcons'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { mapOfferRow, renderOfferPriceSummary, type OfferRow } from '@open-mercato/core/modules/sales/components/channels/offerTableUtils'\nimport { useSalesChannelsEnabled } from '@open-mercato/core/modules/sales/components/useSalesChannelsEnabled'\nimport { SalesChannelsDisabledNotice } from '@open-mercato/core/modules/sales/components/SalesChannelsDisabledNotice'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('sales')\n\ntype OffersResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n totalPages?: number\n totalIsCapped?: boolean\n}\n\nconst PAGE_SIZE = 25\n\nconst SAVE_CONTEXT_ID = 'sales-channel-offers-list'\n\nexport default function SalesChannelOffersListPage() {\n const t = useT()\n const { enabled: channelsEnabled, isLoading: channelsEnabledLoading } = useSalesChannelsEnabled()\n const router = useRouter()\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: SAVE_CONTEXT_ID,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const mutationContext = React.useMemo(\n () => ({\n formId: SAVE_CONTEXT_ID,\n resourceKind: 'sales.channels.offers',\n retryLastMutation,\n }),\n [retryLastMutation],\n )\n const scopeVersion = useOrganizationScopeVersion()\n const channelOptionsRef = React.useRef<Map<string, FilterOption>>(new Map())\n const [rows, setRows] = React.useState<OfferRow[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [totalIsCapped, setTotalIsCapped] = React.useState(false)\n const [sorting, setSorting] = React.useState<SortingState>([{ id: 'updatedAt', desc: true }])\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [isLoading, setLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [channelOptions, setChannelOptions] = React.useState<Map<string, FilterOption>>(channelOptionsRef.current)\n\n const selectedChannelIds = React.useMemo(() => {\n if (!Array.isArray(filterValues.channelIds)) return []\n return filterValues.channelIds\n .map((value) => (typeof value === 'string' ? value.trim() : ''))\n .filter((value): value is string => value.length > 0)\n }, [filterValues])\n\n const upsertChannelOptions = React.useCallback((options: FilterOption[]) => {\n if (!options.length) return\n setChannelOptions((prev) => {\n const next = new Map(prev)\n options.forEach((option) => {\n if (!option.value) return\n next.set(option.value, option)\n })\n channelOptionsRef.current = next\n return next\n })\n }, [])\n\n const loadChannelOptions = React.useCallback(async (term?: string): Promise<FilterOption[]> => {\n try {\n const params = new URLSearchParams({ pageSize: '100', isActive: 'true' })\n if (term && term.trim().length) params.set('search', term.trim())\n const payload = await readApiResultOrThrow<{ items?: Array<{ id?: string; name?: string; code?: string; description?: string | null }> }>(\n `/api/sales/channels?${params.toString()}`,\n undefined,\n { errorMessage: t('sales.channels.offers.filters.channelsLoadError', 'Failed to load channels') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options = items\n .map((entry) => {\n const value = typeof entry.id === 'string' ? entry.id : null\n if (!value) return null\n const label =\n typeof entry.name === 'string'\n ? entry.name\n : typeof entry.code === 'string'\n ? entry.code\n : value\n const description =\n typeof entry.code === 'string' && entry.code !== label\n ? entry.code\n : typeof entry.description === 'string' && entry.description.trim().length\n ? entry.description\n : null\n return { value, label, description }\n })\n .filter((option) => !!option) as FilterOption[]\n upsertChannelOptions(options)\n return options\n } catch (err) {\n logger.warn('sales.channels.offers failed to load channel options', { err })\n return []\n }\n }, [t, upsertChannelOptions])\n\n const ensureChannelMetadata = React.useCallback(async (ids: string[]) => {\n const missing = ids.filter((id) => !channelOptionsRef.current.has(id))\n if (!missing.length) return\n try {\n const params = new URLSearchParams({\n ids: missing.join(','),\n pageSize: String(Math.min(Math.max(missing.length, 1), 100)),\n })\n const payload = await readApiResultOrThrow<{ items?: Array<{ id?: string; name?: string; code?: string; description?: string | null }> }>(\n `/api/sales/channels?${params.toString()}`,\n undefined,\n { errorMessage: t('sales.channels.offers.filters.channelsLoadError', 'Failed to load channels') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options = items\n .map((entry) => {\n const value = typeof entry.id === 'string' ? entry.id : null\n if (!value) return null\n const label =\n typeof entry.name === 'string'\n ? entry.name\n : typeof entry.code === 'string'\n ? entry.code\n : value\n const description =\n typeof entry.code === 'string' && entry.code !== label\n ? entry.code\n : typeof entry.description === 'string' && entry.description.trim().length\n ? entry.description\n : null\n return { value, label, description }\n })\n .filter((option) => !!option) as FilterOption[]\n upsertChannelOptions(options)\n } catch (err) {\n logger.warn('sales.channels.offers failed to hydrate channel metadata', { err })\n }\n }, [t, upsertChannelOptions])\n\n const columns = React.useMemo<ColumnDef<OfferRow>[]>(() => [\n {\n accessorKey: 'title',\n header: t('sales.channels.offers.table.offer', 'Offer'),\n cell: ({ row }) => (\n <div className=\"flex items-center gap-3\">\n {row.original.productMediaUrl ? (\n <img\n src={row.original.productMediaUrl}\n alt={row.original.productTitle ?? row.original.title}\n className=\"h-12 w-12 rounded border object-cover\"\n />\n ) : (\n <div className=\"h-12 w-12 rounded border bg-muted\" />\n )}\n <div className=\"flex flex-col gap-1\">\n <div className=\"flex flex-col\">\n <span className=\"font-medium\">{row.original.title}</span>\n <div className=\"text-xs text-muted-foreground\">\n {row.original.productTitle ?? t('sales.channels.offers.table.emptyProduct', 'Unlinked product')}\n </div>\n </div>\n </div>\n </div>\n ),\n meta: { sticky: true },\n },\n {\n accessorKey: 'pricing',\n header: t('sales.channels.offers.table.pricing', 'Prices'),\n cell: ({ row }) => (\n <div className=\"text-sm\">{renderOfferPriceSummary(row.original, t as any)}</div>\n ),\n },\n {\n accessorKey: 'channelId',\n header: t('sales.channels.offers.table.channel', 'Channel'),\n cell: ({ row }) => {\n const channelId = row.original.channelId\n if (!channelId) {\n return <span className=\"text-xs text-muted-foreground\">{t('sales.channels.offers.table.channelUnassigned', 'Unassigned')}</span>\n }\n const label = channelOptions.get(channelId)?.label ?? channelId\n const description = channelOptions.get(channelId)?.description ?? null\n return (\n <div className=\"flex flex-col\">\n <span className=\"text-sm font-medium\">{label}</span>\n {description ? <span className=\"text-xs text-muted-foreground\">{description}</span> : null}\n </div>\n )\n },\n },\n {\n accessorKey: 'isActive',\n header: t('sales.channels.offers.table.active', 'Active'),\n cell: ({ row }) => <BooleanIcon value={row.original.isActive} />,\n },\n {\n accessorKey: 'updatedAt',\n header: t('sales.channels.offers.table.updated', 'Updated'),\n cell: ({ row }) =>\n row.original.updatedAt\n ? <span className=\"text-xs text-muted-foreground\">{new Date(row.original.updatedAt).toLocaleDateString()}</span>\n : <span className=\"text-xs text-muted-foreground\">\u2014</span>,\n },\n ], [channelOptions, t])\n\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'channelIds',\n label: t('sales.channels.offers.filters.channels', 'Sales channels'),\n type: 'tags',\n placeholder: t('sales.channels.offers.filters.channelsPlaceholder', 'Filter by channels\u2026'),\n loadOptions: loadChannelOptions,\n formatValue: (value: string) => channelOptions.get(value)?.label ?? value,\n formatDescription: (value: string) => channelOptions.get(value)?.description ?? null,\n },\n ], [channelOptions, loadChannelOptions, t])\n\n const loadOffers = React.useCallback(async () => {\n setLoading(true)\n try {\n const params = new URLSearchParams({\n page: String(page),\n pageSize: String(PAGE_SIZE),\n })\n if (search.trim().length) {\n params.set('search', search.trim())\n }\n const sort = sorting[0]\n if (sort?.id) {\n params.set('sortField', sort.id)\n params.set('sortDir', sort.desc ? 'desc' : 'asc')\n }\n if (selectedChannelIds.length) {\n params.set('channelIds', selectedChannelIds.join(','))\n }\n const payload = await readApiResultOrThrow<OffersResponse>(\n `/api/catalog/offers?${params.toString()}`,\n undefined,\n { errorMessage: t('sales.channels.offers.errors.load', 'Failed to load offers.') },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n const mapped = items.map(mapOfferRow)\n setRows(mapped)\n setTotal(typeof payload.total === 'number' ? payload.total : items.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : Math.max(1, Math.ceil(items.length / PAGE_SIZE)))\n setTotalIsCapped(payload?.totalIsCapped === true)\n const ids = mapped\n .map((row) => row.channelId)\n .filter((value): value is string => typeof value === 'string' && value.length > 0)\n if (ids.length) void ensureChannelMetadata(Array.from(new Set(ids)))\n } catch (err) {\n logger.error('sales.channels.offers.list', { err })\n flash(t('sales.channels.offers.errors.load', 'Failed to load offers.'), 'error')\n } finally {\n setLoading(false)\n }\n }, [ensureChannelMetadata, page, search, selectedChannelIds, sorting, t])\n\n React.useEffect(() => {\n void loadOffers()\n }, [loadOffers, scopeVersion, reloadToken])\n\n const handleSearchChange = React.useCallback((value: string) => {\n setSearch(value)\n setPage(1)\n }, [])\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n setFilterValues(values)\n setPage(1)\n }, [])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({})\n setPage(1)\n }, [])\n\n const handleRefresh = React.useCallback(() => {\n setReloadToken((token) => token + 1)\n }, [])\n\n const handleDelete = React.useCallback(async (row: OfferRow) => {\n try {\n await runMutation({\n operation: () =>\n withScopedApiRequestHeaders(\n buildOptimisticLockHeader(row.updatedAt),\n () => deleteCrud('catalog/offers', row.id, {\n errorMessage: t('sales.channels.offers.errors.delete', 'Failed to delete offer.'),\n }),\n ),\n context: mutationContext,\n mutationPayload: { action: 'delete', id: row.id },\n })\n flash(t('sales.channels.offers.messages.deleted', 'Offer deleted.'), 'success')\n handleRefresh()\n } catch (err) {\n if (surfaceRecordConflict(err, t)) { handleRefresh(); return }\n logger.error('sales.channels.offers.delete', { err })\n }\n }, [handleRefresh, mutationContext, runMutation, t])\n\n const tableTitle = (\n <div className=\"flex flex-col gap-1\">\n <span>{t('sales.channels.offers.listTitle', 'Sales channel offers')}</span>\n <span className=\"text-sm font-normal text-muted-foreground\">\n {t('sales.channels.offers.listSubtitle', 'Review product overrides across every sales channel.')}\n </span>\n </div>\n )\n\n if (!channelsEnabled && !channelsEnabledLoading) {\n return <SalesChannelsDisabledNotice />\n }\n\n return (\n <Page>\n <PageBody>\n <DataTable<OfferRow>\n title={tableTitle}\n columns={columns}\n data={rows}\n isLoading={isLoading}\n sorting={sorting}\n onSortingChange={setSorting}\n searchValue={search}\n onSearchChange={handleSearchChange}\n searchPlaceholder={t('sales.channels.offers.table.search', 'Search offers\u2026')}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n totalIsCapped,\n onPageChange: setPage,\n }}\n refreshButton={{\n label: t('sales.channels.offers.table.refresh', 'Refresh'),\n onRefresh: handleRefresh,\n isRefreshing: isLoading,\n }}\n rowActions={(row) => {\n if (!row.channelId) return null\n return (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('sales.channels.offers.actions.edit', 'Edit'),\n href: `/backend/sales/channels/${row.channelId}/offers/${row.id}/edit`,\n },\n {\n id: 'delete',\n label: t('sales.channels.offers.actions.delete', 'Delete'),\n onSelect: () => handleDelete(row),\n destructive: true,\n },\n ]}\n />\n )\n }}\n onRowClick={(row) => {\n if (!row.channelId) return\n router.push(`/backend/sales/channels/${row.channelId}/offers/${row.id}/edit`)\n }}\n emptyState={\n <div className=\"py-10 text-center text-sm text-muted-foreground\">\n {t('sales.channels.offers.table.emptyAll', 'No offers available yet.')}\n </div>\n }\n />\n </PageBody>\n </Page>\n )\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useRouter } from 'next/navigation'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport type { SortingState } from '@tanstack/react-table'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport type { FilterOption } from '@open-mercato/ui/backend/FilterOverlay'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { BooleanIcon } from '@open-mercato/ui/backend/ValueIcons'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { mapOfferRow, renderOfferPriceSummary, type OfferRow } from '@open-mercato/core/modules/sales/components/channels/offerTableUtils'\nimport { useSalesChannelsEnabled } from '@open-mercato/core/modules/sales/components/useSalesChannelsEnabled'\nimport { SalesChannelsDisabledNotice } from '@open-mercato/core/modules/sales/components/SalesChannelsDisabledNotice'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('sales')\n\ntype OffersResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n totalPages?: number\n totalIsCapped?: boolean\n}\n\nconst PAGE_SIZE = 25\n\nconst SAVE_CONTEXT_ID = 'sales-channel-offers-list'\n\nexport default function SalesChannelOffersListPage() {\n const t = useT()\n const { enabled: channelsEnabled, isLoading: channelsEnabledLoading } = useSalesChannelsEnabled()\n const router = useRouter()\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: SAVE_CONTEXT_ID,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const mutationContext = React.useMemo(\n () => ({\n formId: SAVE_CONTEXT_ID,\n resourceKind: 'sales.channels.offers',\n retryLastMutation,\n }),\n [retryLastMutation],\n )\n const scopeVersion = useOrganizationScopeVersion()\n const channelOptionsRef = React.useRef<Map<string, FilterOption>>(new Map())\n const [rows, setRows] = React.useState<OfferRow[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [totalIsCapped, setTotalIsCapped] = React.useState(false)\n const [sorting, setSorting] = React.useState<SortingState>([{ id: 'updatedAt', desc: true }])\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [isLoading, setLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [channelOptions, setChannelOptions] = React.useState<Map<string, FilterOption>>(channelOptionsRef.current)\n\n const selectedChannelIds = React.useMemo(() => {\n if (!Array.isArray(filterValues.channelIds)) return []\n return filterValues.channelIds\n .map((value) => (typeof value === 'string' ? value.trim() : ''))\n .filter((value): value is string => value.length > 0)\n }, [filterValues])\n\n const upsertChannelOptions = React.useCallback((options: FilterOption[]) => {\n if (!options.length) return\n setChannelOptions((prev) => {\n const next = new Map(prev)\n options.forEach((option) => {\n if (!option.value) return\n next.set(option.value, option)\n })\n channelOptionsRef.current = next\n return next\n })\n }, [])\n\n const loadChannelOptions = React.useCallback(async (term?: string): Promise<FilterOption[]> => {\n try {\n const params = new URLSearchParams({ pageSize: '100', isActive: 'true' })\n if (term && term.trim().length) params.set('search', term.trim())\n const payload = await readApiResultOrThrow<{ items?: Array<{ id?: string; name?: string; code?: string; description?: string | null }> }>(\n `/api/sales/channels?${params.toString()}`,\n undefined,\n { errorMessage: t('sales.channels.offers.filters.channelsLoadError', 'Failed to load channels') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options = items\n .map((entry) => {\n const value = typeof entry.id === 'string' ? entry.id : null\n if (!value) return null\n const label =\n typeof entry.name === 'string'\n ? entry.name\n : typeof entry.code === 'string'\n ? entry.code\n : value\n const description =\n typeof entry.code === 'string' && entry.code !== label\n ? entry.code\n : typeof entry.description === 'string' && entry.description.trim().length\n ? entry.description\n : null\n return { value, label, description }\n })\n .filter((option) => !!option) as FilterOption[]\n upsertChannelOptions(options)\n return options\n } catch (err) {\n logger.warn('sales.channels.offers failed to load channel options', { err })\n return []\n }\n }, [t, upsertChannelOptions])\n\n const ensureChannelMetadata = React.useCallback(async (ids: string[]) => {\n const missing = ids.filter((id) => !channelOptionsRef.current.has(id))\n if (!missing.length) return\n try {\n const params = new URLSearchParams({\n ids: missing.join(','),\n pageSize: String(Math.min(Math.max(missing.length, 1), 100)),\n })\n const payload = await readApiResultOrThrow<{ items?: Array<{ id?: string; name?: string; code?: string; description?: string | null }> }>(\n `/api/sales/channels?${params.toString()}`,\n undefined,\n { errorMessage: t('sales.channels.offers.filters.channelsLoadError', 'Failed to load channels') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options = items\n .map((entry) => {\n const value = typeof entry.id === 'string' ? entry.id : null\n if (!value) return null\n const label =\n typeof entry.name === 'string'\n ? entry.name\n : typeof entry.code === 'string'\n ? entry.code\n : value\n const description =\n typeof entry.code === 'string' && entry.code !== label\n ? entry.code\n : typeof entry.description === 'string' && entry.description.trim().length\n ? entry.description\n : null\n return { value, label, description }\n })\n .filter((option) => !!option) as FilterOption[]\n upsertChannelOptions(options)\n } catch (err) {\n logger.warn('sales.channels.offers failed to hydrate channel metadata', { err })\n }\n }, [t, upsertChannelOptions])\n\n const columns = React.useMemo<ColumnDef<OfferRow>[]>(() => [\n {\n accessorKey: 'title',\n header: t('sales.channels.offers.table.offer', 'Offer'),\n cell: ({ row }) => (\n <div className=\"flex items-center gap-3\">\n {row.original.productMediaUrl ? (\n <img\n src={row.original.productMediaUrl}\n alt={row.original.productTitle ?? row.original.title}\n className=\"h-12 w-12 rounded border object-cover\"\n />\n ) : (\n <div className=\"h-12 w-12 rounded border bg-muted\" />\n )}\n <div className=\"flex flex-col gap-1\">\n <div className=\"flex flex-col\">\n <span className=\"font-medium\">{row.original.title}</span>\n <div className=\"text-xs text-muted-foreground\">\n {row.original.productTitle ?? t('sales.channels.offers.table.emptyProduct', 'Unlinked product')}\n </div>\n </div>\n </div>\n </div>\n ),\n meta: { sticky: true },\n },\n {\n accessorKey: 'pricing',\n header: t('sales.channels.offers.table.pricing', 'Prices'),\n cell: ({ row }) => (\n <div className=\"text-sm\">{renderOfferPriceSummary(row.original, t as any)}</div>\n ),\n },\n {\n accessorKey: 'channelId',\n header: t('sales.channels.offers.table.channel', 'Channel'),\n cell: ({ row }) => {\n const channelId = row.original.channelId\n if (!channelId) {\n return <span className=\"text-xs text-muted-foreground\">{t('sales.channels.offers.table.channelUnassigned', 'Unassigned')}</span>\n }\n const label = channelOptions.get(channelId)?.label ?? channelId\n const description = channelOptions.get(channelId)?.description ?? null\n return (\n <div className=\"flex flex-col\">\n <span className=\"text-sm font-medium\">{label}</span>\n {description ? <span className=\"text-xs text-muted-foreground\">{description}</span> : null}\n </div>\n )\n },\n },\n {\n accessorKey: 'isActive',\n header: t('sales.channels.offers.table.active', 'Active'),\n cell: ({ row }) => <BooleanIcon value={row.original.isActive} />,\n },\n {\n accessorKey: 'updatedAt',\n header: t('sales.channels.offers.table.updated', 'Updated'),\n cell: ({ row }) =>\n row.original.updatedAt\n ? <span className=\"text-xs text-muted-foreground\">{new Date(row.original.updatedAt).toLocaleDateString()}</span>\n : <span className=\"text-xs text-muted-foreground\">\u2014</span>,\n },\n ], [channelOptions, t])\n\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'channelIds',\n label: t('sales.channels.offers.filters.channels', 'Sales channels'),\n type: 'tags',\n placeholder: t('sales.channels.offers.filters.channelsPlaceholder', 'Filter by channels\u2026'),\n loadOptions: loadChannelOptions,\n formatValue: (value: string) => channelOptions.get(value)?.label ?? value,\n formatDescription: (value: string) => channelOptions.get(value)?.description ?? null,\n },\n ], [channelOptions, loadChannelOptions, t])\n\n const loadOffers = React.useCallback(async () => {\n setLoading(true)\n try {\n const params = new URLSearchParams({\n page: String(page),\n pageSize: String(PAGE_SIZE),\n })\n if (search.trim().length) {\n params.set('search', search.trim())\n }\n const sort = sorting[0]\n if (sort?.id) {\n params.set('sortField', sort.id)\n params.set('sortDir', sort.desc ? 'desc' : 'asc')\n }\n if (selectedChannelIds.length) {\n params.set('channelIds', selectedChannelIds.join(','))\n }\n const payload = await readApiResultOrThrow<OffersResponse>(\n `/api/catalog/offers?${params.toString()}`,\n undefined,\n { errorMessage: t('sales.channels.offers.errors.load', 'Failed to load offers.') },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n const mapped = items.map(mapOfferRow)\n setRows(mapped)\n setTotal(typeof payload.total === 'number' ? payload.total : items.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : Math.max(1, Math.ceil(items.length / PAGE_SIZE)))\n setTotalIsCapped(payload?.totalIsCapped === true)\n const ids = mapped\n .map((row) => row.channelId)\n .filter((value): value is string => typeof value === 'string' && value.length > 0)\n if (ids.length) void ensureChannelMetadata(Array.from(new Set(ids)))\n } catch (err) {\n logger.error('sales.channels.offers.list', { err })\n flash(t('sales.channels.offers.errors.load', 'Failed to load offers.'), 'error')\n } finally {\n setLoading(false)\n }\n }, [ensureChannelMetadata, page, search, selectedChannelIds, sorting, t])\n\n React.useEffect(() => {\n void loadOffers()\n }, [loadOffers, scopeVersion, reloadToken])\n\n const handleSearchChange = React.useCallback((value: string) => {\n setSearch(value)\n setPage(1)\n }, [])\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n setFilterValues(values)\n setPage(1)\n }, [])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({})\n setPage(1)\n }, [])\n\n const handleRefresh = React.useCallback(() => {\n setReloadToken((token) => token + 1)\n }, [])\n\n const handleDelete = React.useCallback(async (row: OfferRow) => {\n try {\n await runMutation({\n operation: () =>\n withScopedApiRequestHeaders(\n buildOptimisticLockHeader(row.updatedAt),\n () => deleteCrud('catalog/offers', row.id, {\n errorMessage: t('sales.channels.offers.errors.delete', 'Failed to delete offer.'),\n }),\n ),\n context: mutationContext,\n mutationPayload: { action: 'delete', id: row.id },\n })\n flash(t('sales.channels.offers.messages.deleted', 'Offer deleted.'), 'success')\n handleRefresh()\n } catch (err) {\n if (surfaceRecordConflict(err, t)) { handleRefresh(); return }\n logger.error('sales.channels.offers.delete', { err })\n }\n }, [handleRefresh, mutationContext, runMutation, t])\n\n const tableTitle = (\n <div className=\"flex flex-col gap-1\">\n <h1>{t('sales.channels.offers.listTitle', 'Sales channel offers')}</h1>\n <p className=\"text-sm font-normal text-muted-foreground\">\n {t('sales.channels.offers.listSubtitle', 'Review product overrides across every sales channel.')}\n </p>\n </div>\n )\n\n if (!channelsEnabled && !channelsEnabledLoading) {\n return <SalesChannelsDisabledNotice />\n }\n\n return (\n <Page>\n <PageBody>\n <DataTable<OfferRow>\n title={tableTitle}\n columns={columns}\n data={rows}\n isLoading={isLoading}\n sorting={sorting}\n onSortingChange={setSorting}\n searchValue={search}\n onSearchChange={handleSearchChange}\n searchPlaceholder={t('sales.channels.offers.table.search', 'Search offers\u2026')}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n totalIsCapped,\n onPageChange: setPage,\n }}\n refreshButton={{\n label: t('sales.channels.offers.table.refresh', 'Refresh'),\n onRefresh: handleRefresh,\n isRefreshing: isLoading,\n }}\n rowActions={(row) => {\n if (!row.channelId) return null\n return (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('sales.channels.offers.actions.edit', 'Edit'),\n href: `/backend/sales/channels/${row.channelId}/offers/${row.id}/edit`,\n },\n {\n id: 'delete',\n label: t('sales.channels.offers.actions.delete', 'Delete'),\n onSelect: () => handleDelete(row),\n destructive: true,\n },\n ]}\n />\n )\n }}\n onRowClick={(row) => {\n if (!row.channelId) return\n router.push(`/backend/sales/channels/${row.channelId}/offers/${row.id}/edit`)\n }}\n emptyState={\n <div className=\"py-10 text-center text-sm text-muted-foreground\">\n {t('sales.channels.offers.table.emptyAll', 'No offers available yet.')}\n </div>\n }\n />\n </PageBody>\n </Page>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -152,10 +152,11 @@ function SalesChannelsPage() {
|
|
|
152
152
|
return /* @__PURE__ */ jsx(Page, { children: /* @__PURE__ */ jsx(PageBody, { children: /* @__PURE__ */ jsx(
|
|
153
153
|
DataTable,
|
|
154
154
|
{
|
|
155
|
-
title: /* @__PURE__ */ jsxs("
|
|
155
|
+
title: /* @__PURE__ */ jsxs("span", { className: "flex flex-col", children: [
|
|
156
156
|
/* @__PURE__ */ jsx("span", { children: t("sales.channels.nav.title", "Sales channels") }),
|
|
157
157
|
/* @__PURE__ */ jsx("span", { className: "text-sm font-normal text-muted-foreground", children: t("sales.channels.table.subtitle", "Organize catalog offers per marketplace or storefront.") })
|
|
158
158
|
] }),
|
|
159
|
+
titleHeadingLevel: 1,
|
|
159
160
|
actions: /* @__PURE__ */ jsx(Button, { asChild: true, children: /* @__PURE__ */ jsx(Link, { href: "/backend/sales/channels/create", children: t("sales.channels.actions.create", "Add channel") }) }),
|
|
160
161
|
columns,
|
|
161
162
|
data: rows,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/modules/sales/backend/sales/channels/page.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useRouter } from 'next/navigation'\nimport Link from 'next/link'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport type { SortingState } from '@tanstack/react-table'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, withDataTableNamespaces } from '@open-mercato/ui/backend/DataTable'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { BooleanIcon } from '@open-mercato/ui/backend/ValueIcons'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { buildOptimisticLockHeader, extractOptimisticLockConflict } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useSalesChannelsEnabled } from '../../../components/useSalesChannelsEnabled'\nimport { SalesChannelsDisabledNotice } from '../../../components/SalesChannelsDisabledNotice'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('sales')\n\ntype ChannelRow = {\n id: string\n name: string\n code: string | null\n description: string | null\n offerCount: number\n isActive: boolean\n updatedAt: string | null\n}\n\ntype ChannelsResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n totalPages?: number\n totalIsCapped?: boolean\n}\n\nconst PAGE_SIZE = 25\n\nconst SAVE_CONTEXT_ID = 'sales-channels-list'\n\nexport default function SalesChannelsPage() {\n const t = useT()\n const { enabled: channelsEnabled, isLoading: channelsEnabledLoading } = useSalesChannelsEnabled()\n const router = useRouter()\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: SAVE_CONTEXT_ID,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const mutationContext = React.useMemo(\n () => ({\n formId: SAVE_CONTEXT_ID,\n resourceKind: 'sales.channels',\n retryLastMutation,\n }),\n [retryLastMutation],\n )\n const scopeVersion = useOrganizationScopeVersion()\n const [rows, setRows] = React.useState<ChannelRow[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [totalIsCapped, setTotalIsCapped] = React.useState(false)\n const [sorting, setSorting] = React.useState<SortingState>([])\n const [search, setSearch] = React.useState('')\n const [isLoading, setLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n\n const columns = React.useMemo<ColumnDef<ChannelRow>[]>(() => [\n {\n accessorKey: 'name',\n header: t('sales.channels.table.name', 'Name'),\n cell: ({ row }) => (\n <div className=\"flex flex-col\">\n <span className=\"font-medium\">{row.original.name}</span>\n {row.original.description ? (\n <span className=\"text-xs text-muted-foreground\">{row.original.description}</span>\n ) : null}\n </div>\n ),\n meta: { sticky: true },\n },\n {\n accessorKey: 'code',\n header: t('sales.channels.table.code', 'Code'),\n cell: ({ row }) => row.original.code ? (\n <span className=\"font-mono text-xs\">{row.original.code}</span>\n ) : (\n <span className=\"text-xs text-muted-foreground\">\u2014</span>\n ),\n },\n {\n accessorKey: 'offerCount',\n header: t('sales.channels.table.offers', 'Product offers'),\n cell: ({ row }) => (\n <span className=\"text-sm font-semibold\">{row.original.offerCount}</span>\n ),\n },\n {\n accessorKey: 'isActive',\n header: t('sales.channels.table.active', 'Active'),\n cell: ({ row }) => <BooleanIcon value={row.original.isActive} />,\n },\n {\n accessorKey: 'updatedAt',\n header: t('sales.channels.table.updated', 'Updated'),\n cell: ({ row }) =>\n row.original.updatedAt\n ? <span className=\"text-xs text-muted-foreground\">{new Date(row.original.updatedAt).toLocaleDateString()}</span>\n : <span className=\"text-xs text-muted-foreground\">\u2014</span>,\n },\n ], [t])\n\n const loadChannels = React.useCallback(async () => {\n setLoading(true)\n try {\n const params = new URLSearchParams({\n page: String(page),\n pageSize: String(PAGE_SIZE),\n })\n const sort = sorting[0]\n if (sort?.id) {\n params.set('sortField', sort.id)\n params.set('sortDir', sort.desc ? 'desc' : 'asc')\n }\n if (search.trim().length) {\n params.set('search', search.trim())\n }\n const payload = await readApiResultOrThrow<ChannelsResponse>(\n `/api/sales/channels?${params.toString()}`,\n undefined,\n { errorMessage: t('sales.channels.table.errors.load', 'Failed to load channels.') },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n setRows(items.map(mapApiChannel))\n setTotal(typeof payload.total === 'number' ? payload.total : items.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : Math.max(1, Math.ceil(items.length / PAGE_SIZE)))\n setTotalIsCapped(payload?.totalIsCapped === true)\n } catch (err) {\n logger.error('sales.channels.list', { err })\n flash(t('sales.channels.table.errors.load', 'Failed to load channels.'), 'error')\n } finally {\n setLoading(false)\n }\n }, [page, search, sorting, t])\n\n React.useEffect(() => {\n void loadChannels()\n }, [loadChannels, scopeVersion, reloadToken])\n\n const handleSearchChange = React.useCallback((value: string) => {\n setSearch(value)\n setPage(1)\n }, [])\n\n const handleRefresh = React.useCallback(() => {\n setReloadToken((token) => token + 1)\n }, [])\n\n const handleDelete = React.useCallback(async (row: ChannelRow) => {\n try {\n await runMutation({\n operation: () =>\n withScopedApiRequestHeaders(\n buildOptimisticLockHeader(row.updatedAt),\n () => deleteCrud('sales/channels', row.id, {\n errorMessage: t('sales.channels.table.errors.delete', 'Failed to delete channel.'),\n }),\n ),\n context: mutationContext,\n mutationPayload: { action: 'delete', id: row.id },\n })\n flash(t('sales.channels.table.messages.deleted', 'Channel deleted.'), 'success')\n handleRefresh()\n } catch (err) {\n if (extractOptimisticLockConflict(err)) {\n // Someone edited the channel after this list loaded \u2014 refuse the\n // stale delete, surface the conflict, and reload so the row reflects\n // the latest server state (QA #2055 channel edit/delete broken state).\n flash(\n t('ui.forms.flash.recordModified', 'This record was modified by someone else. Refresh and try again.'),\n 'error',\n )\n handleRefresh()\n return\n }\n logger.error('sales.channels.delete', { err })\n }\n }, [handleRefresh, mutationContext, runMutation, t])\n\n if (!channelsEnabled && !channelsEnabledLoading) {\n return <SalesChannelsDisabledNotice />\n }\n\n return (\n <Page>\n <PageBody>\n <DataTable<ChannelRow>\n title={(\n <div className=\"flex flex-col\">\n <span>{t('sales.channels.nav.title', 'Sales channels')}</span>\n <span className=\"text-sm font-normal text-muted-foreground\">\n {t('sales.channels.table.subtitle', 'Organize catalog offers per marketplace or storefront.')}\n </span>\n </div>\n )}\n actions={(\n <Button asChild>\n <Link href=\"/backend/sales/channels/create\">\n {t('sales.channels.actions.create', 'Add channel')}\n </Link>\n </Button>\n )}\n columns={columns}\n data={rows}\n sorting={sorting}\n onSortingChange={setSorting}\n isLoading={isLoading}\n searchValue={search}\n onSearchChange={handleSearchChange}\n searchPlaceholder={t('sales.channels.table.search', 'Search channels\u2026')}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n totalIsCapped,\n onPageChange: setPage,\n }}\n refreshButton={{\n label: t('sales.channels.table.refresh', 'Refresh'),\n onRefresh: handleRefresh,\n isRefreshing: isLoading,\n }}\n rowActions={(row) => (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('sales.channels.table.actions.edit', 'Edit'),\n href: `/backend/sales/channels/${row.id}/edit`,\n },\n {\n id: 'delete',\n label: t('sales.channels.table.actions.delete', 'Delete'),\n onSelect: () => handleDelete(row),\n },\n ]}\n />\n )}\n onRowClick={(row) => router.push(`/backend/sales/channels/${row.id}/edit`)}\n emptyState={\n <div className=\"py-10 text-center text-sm text-muted-foreground\">\n {t('sales.channels.table.empty', 'No channels yet.')}\n </div>\n }\n />\n </PageBody>\n </Page>\n )\n}\n\nfunction mapApiChannel(item: Record<string, unknown>): ChannelRow {\n const id = typeof item.id === 'string' ? item.id : ''\n return withDataTableNamespaces({\n id,\n name: typeof item.name === 'string' ? item.name : id,\n code: typeof item.code === 'string' && item.code.length ? item.code : null,\n description: typeof item.description === 'string' && item.description.length ? item.description : null,\n offerCount: typeof item.offerCount === 'number'\n ? item.offerCount\n : typeof item.offer_count === 'number'\n ? item.offer_count\n : 0,\n isActive: item.isActive === true || item.is_active === true,\n updatedAt: typeof item.updatedAt === 'string'\n ? item.updatedAt\n : typeof item.updated_at === 'string'\n ? item.updated_at\n : null,\n }, item)\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useRouter } from 'next/navigation'\nimport Link from 'next/link'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport type { SortingState } from '@tanstack/react-table'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, withDataTableNamespaces } from '@open-mercato/ui/backend/DataTable'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { BooleanIcon } from '@open-mercato/ui/backend/ValueIcons'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { buildOptimisticLockHeader, extractOptimisticLockConflict } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useSalesChannelsEnabled } from '../../../components/useSalesChannelsEnabled'\nimport { SalesChannelsDisabledNotice } from '../../../components/SalesChannelsDisabledNotice'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('sales')\n\ntype ChannelRow = {\n id: string\n name: string\n code: string | null\n description: string | null\n offerCount: number\n isActive: boolean\n updatedAt: string | null\n}\n\ntype ChannelsResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n totalPages?: number\n totalIsCapped?: boolean\n}\n\nconst PAGE_SIZE = 25\n\nconst SAVE_CONTEXT_ID = 'sales-channels-list'\n\nexport default function SalesChannelsPage() {\n const t = useT()\n const { enabled: channelsEnabled, isLoading: channelsEnabledLoading } = useSalesChannelsEnabled()\n const router = useRouter()\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: SAVE_CONTEXT_ID,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const mutationContext = React.useMemo(\n () => ({\n formId: SAVE_CONTEXT_ID,\n resourceKind: 'sales.channels',\n retryLastMutation,\n }),\n [retryLastMutation],\n )\n const scopeVersion = useOrganizationScopeVersion()\n const [rows, setRows] = React.useState<ChannelRow[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [totalIsCapped, setTotalIsCapped] = React.useState(false)\n const [sorting, setSorting] = React.useState<SortingState>([])\n const [search, setSearch] = React.useState('')\n const [isLoading, setLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n\n const columns = React.useMemo<ColumnDef<ChannelRow>[]>(() => [\n {\n accessorKey: 'name',\n header: t('sales.channels.table.name', 'Name'),\n cell: ({ row }) => (\n <div className=\"flex flex-col\">\n <span className=\"font-medium\">{row.original.name}</span>\n {row.original.description ? (\n <span className=\"text-xs text-muted-foreground\">{row.original.description}</span>\n ) : null}\n </div>\n ),\n meta: { sticky: true },\n },\n {\n accessorKey: 'code',\n header: t('sales.channels.table.code', 'Code'),\n cell: ({ row }) => row.original.code ? (\n <span className=\"font-mono text-xs\">{row.original.code}</span>\n ) : (\n <span className=\"text-xs text-muted-foreground\">\u2014</span>\n ),\n },\n {\n accessorKey: 'offerCount',\n header: t('sales.channels.table.offers', 'Product offers'),\n cell: ({ row }) => (\n <span className=\"text-sm font-semibold\">{row.original.offerCount}</span>\n ),\n },\n {\n accessorKey: 'isActive',\n header: t('sales.channels.table.active', 'Active'),\n cell: ({ row }) => <BooleanIcon value={row.original.isActive} />,\n },\n {\n accessorKey: 'updatedAt',\n header: t('sales.channels.table.updated', 'Updated'),\n cell: ({ row }) =>\n row.original.updatedAt\n ? <span className=\"text-xs text-muted-foreground\">{new Date(row.original.updatedAt).toLocaleDateString()}</span>\n : <span className=\"text-xs text-muted-foreground\">\u2014</span>,\n },\n ], [t])\n\n const loadChannels = React.useCallback(async () => {\n setLoading(true)\n try {\n const params = new URLSearchParams({\n page: String(page),\n pageSize: String(PAGE_SIZE),\n })\n const sort = sorting[0]\n if (sort?.id) {\n params.set('sortField', sort.id)\n params.set('sortDir', sort.desc ? 'desc' : 'asc')\n }\n if (search.trim().length) {\n params.set('search', search.trim())\n }\n const payload = await readApiResultOrThrow<ChannelsResponse>(\n `/api/sales/channels?${params.toString()}`,\n undefined,\n { errorMessage: t('sales.channels.table.errors.load', 'Failed to load channels.') },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n setRows(items.map(mapApiChannel))\n setTotal(typeof payload.total === 'number' ? payload.total : items.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : Math.max(1, Math.ceil(items.length / PAGE_SIZE)))\n setTotalIsCapped(payload?.totalIsCapped === true)\n } catch (err) {\n logger.error('sales.channels.list', { err })\n flash(t('sales.channels.table.errors.load', 'Failed to load channels.'), 'error')\n } finally {\n setLoading(false)\n }\n }, [page, search, sorting, t])\n\n React.useEffect(() => {\n void loadChannels()\n }, [loadChannels, scopeVersion, reloadToken])\n\n const handleSearchChange = React.useCallback((value: string) => {\n setSearch(value)\n setPage(1)\n }, [])\n\n const handleRefresh = React.useCallback(() => {\n setReloadToken((token) => token + 1)\n }, [])\n\n const handleDelete = React.useCallback(async (row: ChannelRow) => {\n try {\n await runMutation({\n operation: () =>\n withScopedApiRequestHeaders(\n buildOptimisticLockHeader(row.updatedAt),\n () => deleteCrud('sales/channels', row.id, {\n errorMessage: t('sales.channels.table.errors.delete', 'Failed to delete channel.'),\n }),\n ),\n context: mutationContext,\n mutationPayload: { action: 'delete', id: row.id },\n })\n flash(t('sales.channels.table.messages.deleted', 'Channel deleted.'), 'success')\n handleRefresh()\n } catch (err) {\n if (extractOptimisticLockConflict(err)) {\n // Someone edited the channel after this list loaded \u2014 refuse the\n // stale delete, surface the conflict, and reload so the row reflects\n // the latest server state (QA #2055 channel edit/delete broken state).\n flash(\n t('ui.forms.flash.recordModified', 'This record was modified by someone else. Refresh and try again.'),\n 'error',\n )\n handleRefresh()\n return\n }\n logger.error('sales.channels.delete', { err })\n }\n }, [handleRefresh, mutationContext, runMutation, t])\n\n if (!channelsEnabled && !channelsEnabledLoading) {\n return <SalesChannelsDisabledNotice />\n }\n\n return (\n <Page>\n <PageBody>\n <DataTable<ChannelRow>\n title={(\n <span className=\"flex flex-col\">\n <span>{t('sales.channels.nav.title', 'Sales channels')}</span>\n <span className=\"text-sm font-normal text-muted-foreground\">\n {t('sales.channels.table.subtitle', 'Organize catalog offers per marketplace or storefront.')}\n </span>\n </span>\n )}\n titleHeadingLevel={1}\n actions={(\n <Button asChild>\n <Link href=\"/backend/sales/channels/create\">\n {t('sales.channels.actions.create', 'Add channel')}\n </Link>\n </Button>\n )}\n columns={columns}\n data={rows}\n sorting={sorting}\n onSortingChange={setSorting}\n isLoading={isLoading}\n searchValue={search}\n onSearchChange={handleSearchChange}\n searchPlaceholder={t('sales.channels.table.search', 'Search channels\u2026')}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n totalIsCapped,\n onPageChange: setPage,\n }}\n refreshButton={{\n label: t('sales.channels.table.refresh', 'Refresh'),\n onRefresh: handleRefresh,\n isRefreshing: isLoading,\n }}\n rowActions={(row) => (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('sales.channels.table.actions.edit', 'Edit'),\n href: `/backend/sales/channels/${row.id}/edit`,\n },\n {\n id: 'delete',\n label: t('sales.channels.table.actions.delete', 'Delete'),\n onSelect: () => handleDelete(row),\n },\n ]}\n />\n )}\n onRowClick={(row) => router.push(`/backend/sales/channels/${row.id}/edit`)}\n emptyState={\n <div className=\"py-10 text-center text-sm text-muted-foreground\">\n {t('sales.channels.table.empty', 'No channels yet.')}\n </div>\n }\n />\n </PageBody>\n </Page>\n )\n}\n\nfunction mapApiChannel(item: Record<string, unknown>): ChannelRow {\n const id = typeof item.id === 'string' ? item.id : ''\n return withDataTableNamespaces({\n id,\n name: typeof item.name === 'string' ? item.name : id,\n code: typeof item.code === 'string' && item.code.length ? item.code : null,\n description: typeof item.description === 'string' && item.description.length ? item.description : null,\n offerCount: typeof item.offerCount === 'number'\n ? item.offerCount\n : typeof item.offer_count === 'number'\n ? item.offer_count\n : 0,\n isActive: item.isActive === true || item.is_active === true,\n updatedAt: typeof item.updatedAt === 'string'\n ? item.updatedAt\n : typeof item.updated_at === 'string'\n ? item.updated_at\n : null,\n }, item)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -568,6 +568,7 @@ function ChannelOfferForm({ channelId: lockedChannelId, offerId, mode }) {
|
|
|
568
568
|
CrudForm,
|
|
569
569
|
{
|
|
570
570
|
title: mode === "create" ? t("sales.channels.offers.form.createTitle", "Create offer") : t("sales.channels.offers.form.editTitle", "Edit offer"),
|
|
571
|
+
titleHeadingLevel: 1,
|
|
571
572
|
entityId: E.catalog.catalog_offer,
|
|
572
573
|
fields,
|
|
573
574
|
groups,
|