@open-mercato/core 0.7.0 → 0.7.1-develop.7103.1.41ff100d93
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/dist/helpers/integration/api.js +13 -1
- package/dist/helpers/integration/api.js.map +2 -2
- package/dist/helpers/integration/communicationChannelsFixtures.js +19 -0
- package/dist/helpers/integration/communicationChannelsFixtures.js.map +2 -2
- package/dist/modules/api_keys/api/keys/route.js +1 -1
- package/dist/modules/api_keys/api/keys/route.js.map +2 -2
- package/dist/modules/api_keys/backend/api-keys/page.js +3 -1
- package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
- package/dist/modules/api_keys/di.js +9 -0
- package/dist/modules/api_keys/di.js.map +7 -0
- package/dist/modules/api_keys/services/principalService.js +31 -0
- package/dist/modules/api_keys/services/principalService.js.map +7 -0
- package/dist/modules/attachments/api/route.js +2 -2
- package/dist/modules/attachments/api/route.js.map +2 -2
- package/dist/modules/attachments/components/AttachmentLibrary.js +2 -0
- package/dist/modules/attachments/components/AttachmentLibrary.js.map +2 -2
- package/dist/modules/attachments/di.js +11 -1
- package/dist/modules/attachments/di.js.map +2 -2
- package/dist/modules/attachments/index.js.map +1 -1
- package/dist/modules/attachments/lib/attachment-service.js +313 -0
- package/dist/modules/attachments/lib/attachment-service.js.map +7 -0
- package/dist/modules/attachments/lib/scoped-upload-service.js +15 -2
- package/dist/modules/attachments/lib/scoped-upload-service.js.map +2 -2
- package/dist/modules/attachments/lib/upload-limits.js +6 -2
- package/dist/modules/attachments/lib/upload-limits.js.map +2 -2
- package/dist/modules/audit_logs/backend/audit-logs/page.js +6 -0
- package/dist/modules/audit_logs/backend/audit-logs/page.js.map +2 -2
- package/dist/modules/audit_logs/lib/display-helpers.js +19 -11
- package/dist/modules/audit_logs/lib/display-helpers.js.map +2 -2
- package/dist/modules/audit_logs/services/actionLogService.js +57 -12
- package/dist/modules/audit_logs/services/actionLogService.js.map +3 -3
- package/dist/modules/auth/acl.js +30 -5
- package/dist/modules/auth/acl.js.map +2 -2
- package/dist/modules/auth/api/feature-check.js +8 -2
- package/dist/modules/auth/api/feature-check.js.map +2 -2
- package/dist/modules/auth/api/login.js +4 -1
- package/dist/modules/auth/api/login.js.map +2 -2
- package/dist/modules/auth/api/reset/validate.js +55 -0
- package/dist/modules/auth/api/reset/validate.js.map +7 -0
- package/dist/modules/auth/api/roles/acl/route.js +28 -33
- package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
- package/dist/modules/auth/api/session/refresh.js +25 -1
- package/dist/modules/auth/api/session/refresh.js.map +2 -2
- package/dist/modules/auth/api/users/acl/route.js +96 -51
- package/dist/modules/auth/api/users/acl/route.js.map +2 -2
- package/dist/modules/auth/api/users/route.js +13 -5
- package/dist/modules/auth/api/users/route.js.map +2 -2
- package/dist/modules/auth/backend/roles/[id]/edit/page.meta.js +5 -1
- package/dist/modules/auth/backend/roles/[id]/edit/page.meta.js.map +2 -2
- package/dist/modules/auth/backend/roles/page.js +3 -1
- package/dist/modules/auth/backend/roles/page.js.map +2 -2
- package/dist/modules/auth/backend/users/[id]/edit/page.meta.js +5 -1
- package/dist/modules/auth/backend/users/[id]/edit/page.meta.js.map +2 -2
- package/dist/modules/auth/backend/users/page.js +2 -1
- package/dist/modules/auth/backend/users/page.js.map +2 -2
- package/dist/modules/auth/commands/acl.js +254 -0
- package/dist/modules/auth/commands/acl.js.map +7 -0
- package/dist/modules/auth/components/AclEditor.js +39 -30
- package/dist/modules/auth/components/AclEditor.js.map +2 -2
- package/dist/modules/auth/data/entities.js.map +2 -2
- package/dist/modules/auth/data/validators.js +5 -1
- package/dist/modules/auth/data/validators.js.map +2 -2
- package/dist/modules/auth/di.js +35 -9
- package/dist/modules/auth/di.js.map +2 -2
- package/dist/modules/auth/frontend/reset/[token]/page.js +46 -0
- package/dist/modules/auth/frontend/reset/[token]/page.js.map +2 -2
- package/dist/modules/auth/lib/grantChecks.js.map +2 -2
- package/dist/modules/auth/lib/userIdFilter.js +16 -0
- package/dist/modules/auth/lib/userIdFilter.js.map +7 -0
- package/dist/modules/auth/services/authService.js +16 -2
- package/dist/modules/auth/services/authService.js.map +2 -2
- package/dist/modules/auth/services/principalService.js +200 -0
- package/dist/modules/auth/services/principalService.js.map +7 -0
- package/dist/modules/auth/services/rbacService.js +67 -24
- package/dist/modules/auth/services/rbacService.js.map +3 -3
- package/dist/modules/auth/services/roleOrganizationScope.js +41 -0
- package/dist/modules/auth/services/roleOrganizationScope.js.map +7 -0
- package/dist/modules/business_rules/backend/logs/page.js +3 -1
- package/dist/modules/business_rules/backend/logs/page.js.map +2 -2
- package/dist/modules/business_rules/backend/rules/page.js +3 -1
- package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
- package/dist/modules/business_rules/backend/sets/page.js +3 -1
- package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
- package/dist/modules/business_rules/lib/expression-evaluator.js +9 -9
- package/dist/modules/business_rules/lib/expression-evaluator.js.map +2 -2
- package/dist/modules/business_rules/lib/rule-evaluator.js +10 -9
- package/dist/modules/business_rules/lib/rule-evaluator.js.map +2 -2
- package/dist/modules/catalog/ai-agents.js +1 -1
- package/dist/modules/catalog/ai-agents.js.map +1 -1
- package/dist/modules/catalog/ai-tools/merchandising-pack.js +2 -2
- package/dist/modules/catalog/ai-tools/merchandising-pack.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js +5 -2
- package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js.map +2 -2
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js +2 -0
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductsDataTable.js +7 -1
- package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
- package/dist/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.js +2 -0
- package/dist/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.js.map +2 -2
- package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js +9 -1
- package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js.map +2 -2
- package/dist/modules/communication_channels/api/post/test-seed/route.js +95 -10
- package/dist/modules/communication_channels/api/post/test-seed/route.js.map +2 -2
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.js +3 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.js.map +2 -2
- package/dist/modules/communication_channels/commands/ingest-inbound-message.js +14 -1
- package/dist/modules/communication_channels/commands/ingest-inbound-message.js.map +2 -2
- package/dist/modules/communication_channels/di.js +7 -1
- package/dist/modules/communication_channels/di.js.map +2 -2
- package/dist/modules/communication_channels/lib/email-capabilities.js +4 -1
- package/dist/modules/communication_channels/lib/email-capabilities.js.map +2 -2
- package/dist/modules/communication_channels/lib/outbound-recipient.js +33 -0
- package/dist/modules/communication_channels/lib/outbound-recipient.js.map +7 -0
- package/dist/modules/communication_channels/lib/resolve-channel-type.js +51 -0
- package/dist/modules/communication_channels/lib/resolve-channel-type.js.map +7 -0
- package/dist/modules/communication_channels/lib/test-seed.js +41 -2
- package/dist/modules/communication_channels/lib/test-seed.js.map +2 -2
- package/dist/modules/configs/lib/system-status.js +9 -0
- package/dist/modules/configs/lib/system-status.js.map +2 -2
- package/dist/modules/currencies/backend/currencies/page.js +3 -1
- package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
- package/dist/modules/currencies/backend/exchange-rates/page.js +3 -1
- package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
- package/dist/modules/currencies/services/rateFetchingService.js +6 -1
- package/dist/modules/currencies/services/rateFetchingService.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/domain-mappings.js +9 -0
- package/dist/modules/customer_accounts/api/admin/domain-mappings.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +3 -1
- 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 +3 -1
- package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js.map +2 -2
- package/dist/modules/customer_accounts/services/domainMappingService.js +10 -0
- package/dist/modules/customer_accounts/services/domainMappingService.js.map +2 -2
- package/dist/modules/customers/ai-tools/companies-pack.js +4 -1
- package/dist/modules/customers/ai-tools/companies-pack.js.map +2 -2
- package/dist/modules/customers/ai-tools/deal-analyzer-pack.js +13 -2
- package/dist/modules/customers/ai-tools/deal-analyzer-pack.js.map +2 -2
- package/dist/modules/customers/ai-tools/deals-pack.js +52 -6
- package/dist/modules/customers/ai-tools/deals-pack.js.map +2 -2
- package/dist/modules/customers/ai-tools/people-pack.js +4 -1
- package/dist/modules/customers/ai-tools/people-pack.js.map +2 -2
- package/dist/modules/customers/api/activities/route.js +48 -6
- package/dist/modules/customers/api/activities/route.js.map +2 -2
- package/dist/modules/customers/api/companies/[id]/people/route.js +20 -64
- package/dist/modules/customers/api/companies/[id]/people/route.js.map +2 -2
- package/dist/modules/customers/api/companies/[id]/route.js +17 -94
- package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js +8 -5
- package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js.map +2 -2
- package/dist/modules/customers/api/deals/[id]/companies/route.js +1 -1
- package/dist/modules/customers/api/deals/[id]/companies/route.js.map +2 -2
- package/dist/modules/customers/api/deals/[id]/people/route.js +1 -1
- package/dist/modules/customers/api/deals/[id]/people/route.js.map +2 -2
- package/dist/modules/customers/api/deals/[id]/route.js +8 -25
- package/dist/modules/customers/api/deals/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/deals/[id]/stats/route.js +3 -22
- package/dist/modules/customers/api/deals/[id]/stats/route.js.map +2 -2
- package/dist/modules/customers/api/deals/aggregate/route.js +14 -9
- package/dist/modules/customers/api/deals/aggregate/route.js.map +2 -2
- package/dist/modules/customers/api/deals/map/route.js +5 -5
- package/dist/modules/customers/api/deals/map/route.js.map +2 -2
- package/dist/modules/customers/api/deals/route.js +38 -1
- package/dist/modules/customers/api/deals/route.js.map +2 -2
- package/dist/modules/customers/api/entity-roles-factory.js +4 -4
- package/dist/modules/customers/api/entity-roles-factory.js.map +2 -2
- package/dist/modules/customers/api/interactions/route.js +3 -1
- package/dist/modules/customers/api/interactions/route.js.map +2 -2
- package/dist/modules/customers/api/interactions/tasks/route.js +27 -4
- package/dist/modules/customers/api/interactions/tasks/route.js.map +2 -2
- package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js +4 -3
- package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js.map +2 -2
- package/dist/modules/customers/api/people/[id]/companies/context.js +1 -1
- package/dist/modules/customers/api/people/[id]/companies/context.js.map +2 -2
- package/dist/modules/customers/api/people/[id]/companies/enriched/route.js +1 -1
- package/dist/modules/customers/api/people/[id]/companies/enriched/route.js.map +2 -2
- package/dist/modules/customers/api/people/[id]/route.js +11 -10
- package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/people/check-phone/route.js +51 -9
- package/dist/modules/customers/api/people/check-phone/route.js.map +2 -2
- package/dist/modules/customers/api/todos/route.js +30 -5
- package/dist/modules/customers/api/todos/route.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/page.js +4 -2
- package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +6 -1
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/page.js +5 -2
- package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/components/Lane.js +4 -13
- package/dist/modules/customers/backend/customers/deals/pipeline/components/Lane.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.js +85 -14
- package/dist/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/components/toneClasses.js +18 -0
- package/dist/modules/customers/backend/customers/deals/pipeline/components/toneClasses.js.map +7 -0
- package/dist/modules/customers/backend/customers/people/page.js +4 -2
- package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
- package/dist/modules/customers/backend/hooks/useEmailDuplicateCheck.js +9 -3
- package/dist/modules/customers/backend/hooks/useEmailDuplicateCheck.js.map +2 -2
- package/dist/modules/customers/commands/deals.js +21 -34
- package/dist/modules/customers/commands/deals.js.map +2 -2
- package/dist/modules/customers/commands/interactions.js.map +1 -1
- package/dist/modules/customers/commands/personCompanyLinks.js +131 -2
- package/dist/modules/customers/commands/personCompanyLinks.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/DealsKpiStrip.js +7 -6
- package/dist/modules/customers/components/DealsKpiStrip.js.map +2 -2
- package/dist/modules/customers/components/calendar/AgendaList.js +2 -2
- package/dist/modules/customers/components/calendar/AgendaList.js.map +2 -2
- package/dist/modules/customers/components/calendar/CalendarEventEditor.js +1 -1
- package/dist/modules/customers/components/calendar/CalendarEventEditor.js.map +2 -2
- package/dist/modules/customers/components/calendar/CalendarScreen.js +1 -1
- package/dist/modules/customers/components/calendar/CalendarScreen.js.map +2 -2
- package/dist/modules/customers/components/calendar/CalendarSettingsModal.js +1 -1
- package/dist/modules/customers/components/calendar/CalendarSettingsModal.js.map +2 -2
- package/dist/modules/customers/components/calendar/EventBlock.js +1 -1
- package/dist/modules/customers/components/calendar/EventBlock.js.map +2 -2
- package/dist/modules/customers/components/calendar/EventPeekPopover.js +3 -2
- package/dist/modules/customers/components/calendar/EventPeekPopover.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/PeopleField.js +40 -5
- package/dist/modules/customers/components/calendar/editor/PeopleField.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/hooks.js +2 -1
- package/dist/modules/customers/components/calendar/editor/hooks.js.map +2 -2
- package/dist/modules/customers/components/calendar/types.js +1 -1
- package/dist/modules/customers/components/calendar/types.js.map +2 -2
- package/dist/modules/customers/components/detail/CompanyKpiBar.js +5 -4
- package/dist/modules/customers/components/detail/CompanyKpiBar.js.map +2 -2
- package/dist/modules/customers/components/detail/CompanyPeopleSection.js +3 -1
- package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
- package/dist/modules/customers/components/detail/DealForm.js +19 -7
- package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
- package/dist/modules/customers/components/detail/DealsSection.js +6 -5
- package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
- package/dist/modules/customers/components/detail/EntityTagsDialog.js +35 -11
- package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/PersonCompaniesSection.js +3 -1
- package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +2 -2
- package/dist/modules/customers/components/detail/hooks/usePersonTasks.js +19 -13
- package/dist/modules/customers/components/detail/hooks/usePersonTasks.js.map +2 -2
- package/dist/modules/customers/components/detail/schedule/ParticipantsField.js +4 -4
- package/dist/modules/customers/components/detail/schedule/ParticipantsField.js.map +2 -2
- package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js +3 -3
- package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +2 -2
- package/dist/modules/customers/components/detail/utils.js +5 -5
- package/dist/modules/customers/components/detail/utils.js.map +2 -2
- package/dist/modules/customers/data/entities.js.map +1 -1
- package/dist/modules/customers/data/validators.js +32 -3
- package/dist/modules/customers/data/validators.js.map +2 -2
- package/dist/modules/customers/events.js +5 -0
- package/dist/modules/customers/events.js.map +2 -2
- package/dist/modules/customers/lib/calendar/conflicts.js +8 -2
- package/dist/modules/customers/lib/calendar/conflicts.js.map +2 -2
- package/dist/modules/customers/lib/calendar/editorPayload.js +3 -2
- package/dist/modules/customers/lib/calendar/editorPayload.js.map +2 -2
- package/dist/modules/customers/lib/calendar/mapItem.js +8 -3
- package/dist/modules/customers/lib/calendar/mapItem.js.map +2 -2
- package/dist/modules/customers/lib/calendar/participantIdentity.js +9 -0
- package/dist/modules/customers/lib/calendar/participantIdentity.js.map +7 -0
- package/dist/modules/customers/lib/closureStage.js +45 -0
- package/dist/modules/customers/lib/closureStage.js.map +7 -0
- package/dist/modules/customers/lib/dealStatus.js +30 -0
- package/dist/modules/customers/lib/dealStatus.js.map +2 -2
- package/dist/modules/customers/lib/detailReadAccess.js +12 -0
- package/dist/modules/customers/lib/detailReadAccess.js.map +7 -0
- package/dist/modules/customers/lib/findPeopleByAddresses.js +1 -0
- package/dist/modules/customers/lib/findPeopleByAddresses.js.map +2 -2
- package/dist/modules/customers/lib/personCompanies.js +100 -2
- package/dist/modules/customers/lib/personCompanies.js.map +2 -2
- package/dist/modules/customers/lib/todoCompatibility.js +12 -0
- package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
- package/dist/modules/dashboards/lib/widgetScope.js +6 -1
- package/dist/modules/dashboards/lib/widgetScope.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/page.js +3 -1
- package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
- package/dist/modules/data_sync/lib/abandoned-run.js +19 -0
- package/dist/modules/data_sync/lib/abandoned-run.js.map +7 -0
- package/dist/modules/data_sync/lib/sync-engine.js +72 -6
- package/dist/modules/data_sync/lib/sync-engine.js.map +2 -2
- package/dist/modules/data_sync/workers/sync-export.js +5 -1
- package/dist/modules/data_sync/workers/sync-export.js.map +2 -2
- package/dist/modules/data_sync/workers/sync-import.js +5 -1
- package/dist/modules/data_sync/workers/sync-import.js.map +2 -2
- package/dist/modules/devices/acl.js +9 -1
- package/dist/modules/devices/acl.js.map +2 -2
- package/dist/modules/devices/api/admin/devices/[id]/route.js +5 -32
- package/dist/modules/devices/api/admin/devices/[id]/route.js.map +2 -2
- package/dist/modules/devices/api/admin/devices/route.js +14 -1
- package/dist/modules/devices/api/admin/devices/route.js.map +2 -2
- package/dist/modules/devices/api/deviceList.js +99 -12
- package/dist/modules/devices/api/deviceList.js.map +2 -2
- package/dist/modules/devices/api/deviceSerialization.js +46 -0
- package/dist/modules/devices/api/deviceSerialization.js.map +7 -0
- package/dist/modules/devices/api/openapi.js +3 -1
- package/dist/modules/devices/api/openapi.js.map +2 -2
- package/dist/modules/devices/api/route.js +9 -1
- package/dist/modules/devices/api/route.js.map +2 -2
- package/dist/modules/devices/backend/devices/[id]/page.js +10 -26
- package/dist/modules/devices/backend/devices/[id]/page.js.map +2 -2
- package/dist/modules/devices/backend/devices/create/page.js +17 -1
- package/dist/modules/devices/backend/devices/create/page.js.map +2 -2
- package/dist/modules/devices/backend/devices/page.js +28 -34
- package/dist/modules/devices/backend/devices/page.js.map +2 -2
- package/dist/modules/devices/backend/devices/useDeviceUserLabels.js +34 -0
- package/dist/modules/devices/backend/devices/useDeviceUserLabels.js.map +7 -0
- package/dist/modules/devices/backend/devices/userOptions.js +52 -0
- package/dist/modules/devices/backend/devices/userOptions.js.map +7 -0
- package/dist/modules/devices/setup.js +6 -2
- package/dist/modules/devices/setup.js.map +2 -2
- package/dist/modules/directory/backend/directory/organizations/page.js +2 -1
- package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/tenants/page.js +2 -1
- package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
- package/dist/modules/directory/di.js +9 -0
- package/dist/modules/directory/di.js.map +2 -2
- package/dist/modules/directory/services/organizationHierarchyService.js +29 -0
- package/dist/modules/directory/services/organizationHierarchyService.js.map +7 -0
- package/dist/modules/directory/services/organizationScopeService.js +56 -0
- package/dist/modules/directory/services/organizationScopeService.js.map +7 -0
- package/dist/modules/directory/utils/organizationScope.js.map +2 -2
- package/dist/modules/entities/api/records.js +4 -2
- package/dist/modules/entities/api/records.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +3 -1
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
- package/dist/modules/eudr/api/plots/route.js +5 -1
- package/dist/modules/eudr/api/plots/route.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js +3 -0
- package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/plots/page.js +3 -0
- package/dist/modules/eudr/backend/eudr/plots/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/product-mappings/page.js +3 -0
- package/dist/modules/eudr/backend/eudr/product-mappings/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/risk-assessments/page.js +3 -0
- package/dist/modules/eudr/backend/eudr/risk-assessments/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/statements/page.js +3 -0
- package/dist/modules/eudr/backend/eudr/statements/page.js.map +2 -2
- package/dist/modules/eudr/commands/statements.js +0 -3
- package/dist/modules/eudr/commands/statements.js.map +2 -2
- package/dist/modules/eudr/data/validators.js +4 -1
- package/dist/modules/eudr/data/validators.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/feature_toggles/defaults.json +0 -8
- package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js +3 -0
- package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js.map +2 -2
- package/dist/modules/inbox_ops/backend/inbox-ops/page.js +3 -0
- package/dist/modules/inbox_ops/backend/inbox-ops/page.js.map +2 -2
- package/dist/modules/inbox_ops/lib/htmlToPlainText.js +1 -12
- package/dist/modules/inbox_ops/lib/htmlToPlainText.js.map +2 -2
- package/dist/modules/integrations/api/[id]/credentials/route.js +6 -1
- package/dist/modules/integrations/api/[id]/credentials/route.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/[id]/page.js +38 -29
- package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +36 -9
- package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/credential-secret-fields.js +55 -0
- package/dist/modules/integrations/backend/integrations/credential-secret-fields.js.map +7 -0
- package/dist/modules/integrations/data/validators.js +11 -3
- package/dist/modules/integrations/data/validators.js.map +2 -2
- package/dist/modules/integrations/lib/credentials-masking.js +6 -2
- package/dist/modules/integrations/lib/credentials-masking.js.map +2 -2
- package/dist/modules/messages/api/[id]/route.js +29 -1
- package/dist/modules/messages/api/[id]/route.js.map +2 -2
- package/dist/modules/messages/api/openapi.js +17 -2
- package/dist/modules/messages/api/openapi.js.map +2 -2
- package/dist/modules/messages/api/route.js +17 -2
- package/dist/modules/messages/api/route.js.map +2 -2
- package/dist/modules/messages/components/MessagesInboxPageClient.js +7 -14
- package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
- package/dist/modules/messages/components/inboxFilters.js +15 -0
- package/dist/modules/messages/components/inboxFilters.js.map +2 -2
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js +11 -1
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js.map +2 -2
- package/dist/modules/messages/components/message-detail/panels/MessageHeader.js +3 -1
- package/dist/modules/messages/components/message-detail/panels/MessageHeader.js.map +2 -2
- package/dist/modules/messages/components/message-detail/panels/thread-panel.js +2 -1
- package/dist/modules/messages/components/message-detail/panels/thread-panel.js.map +2 -2
- package/dist/modules/messages/components/messageListLabels.js +14 -2
- package/dist/modules/messages/components/messageListLabels.js.map +2 -2
- package/dist/modules/messages/data/validators.js +18 -4
- package/dist/modules/messages/data/validators.js.map +2 -2
- package/dist/modules/messages/lib/channel-sender-identity.js +26 -0
- package/dist/modules/messages/lib/channel-sender-identity.js.map +7 -0
- package/dist/modules/messages/lib/composeSourceChannelType.js +41 -0
- package/dist/modules/messages/lib/composeSourceChannelType.js.map +7 -0
- package/dist/modules/payment_gateways/api/webhook/[provider]/route.js +4 -6
- package/dist/modules/payment_gateways/api/webhook/[provider]/route.js.map +2 -2
- package/dist/modules/payment_gateways/backend/payment-gateways/page.js +3 -1
- package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +2 -2
- package/dist/modules/payment_gateways/lib/webhook-processor.js +7 -0
- package/dist/modules/payment_gateways/lib/webhook-processor.js.map +2 -2
- package/dist/modules/planner/backend/planner/availability-rulesets/page.js +3 -0
- package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
- package/dist/modules/push_notifications/backend/push_notifications/page.js +3 -1
- 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 -1
- package/dist/modules/push_notifications/backend/push_notifications/send/page.js.map +2 -2
- package/dist/modules/query_index/lib/engine.js +150 -51
- package/dist/modules/query_index/lib/engine.js.map +2 -2
- package/dist/modules/query_index/lib/search-entity-policy.js +14 -0
- package/dist/modules/query_index/lib/search-entity-policy.js.map +7 -0
- package/dist/modules/query_index/lib/search-tokens.js +79 -3
- package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
- package/dist/modules/resources/backend/resources/resource-types/page.js +3 -1
- package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/page.js +3 -1
- package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/offers/page.js +3 -0
- package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/page.js +3 -0
- package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +10 -8
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +79 -1
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/components/PriceWithCurrency.js +7 -5
- package/dist/modules/sales/components/PriceWithCurrency.js.map +2 -2
- package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +3 -0
- package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
- package/dist/modules/sales/components/documents/AdjustmentsSection.js +8 -6
- package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/ItemsSection.js +51 -22
- package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/LineItemDialog.js +83 -18
- package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/PaymentsSection.js +23 -9
- package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/ReturnsSection.js +8 -6
- package/dist/modules/sales/components/documents/ReturnsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js +68 -14
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesOrderDraftLines.js +6 -5
- package/dist/modules/sales/components/documents/SalesOrderDraftLines.js.map +2 -2
- package/dist/modules/sales/components/documents/ShipmentDialog.js +5 -4
- package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/ShipmentsSection.js +8 -6
- package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/lineItemShipmentLock.js +54 -0
- package/dist/modules/sales/components/documents/lineItemShipmentLock.js.map +7 -0
- package/dist/modules/sales/components/documents/lineItemUtils.js +2 -2
- package/dist/modules/sales/components/documents/lineItemUtils.js.map +2 -2
- package/dist/modules/sales/data/entities.js +8 -2
- package/dist/modules/sales/data/entities.js.map +2 -2
- package/dist/modules/sales/extension-points.js +1 -0
- package/dist/modules/sales/extension-points.js.map +2 -2
- package/dist/modules/sales/lib/salesChannelsToggleSeed.js +33 -0
- package/dist/modules/sales/lib/salesChannelsToggleSeed.js.map +7 -0
- package/dist/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.js +32 -0
- package/dist/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.js.map +7 -0
- package/dist/modules/sales/setup.js +2 -0
- package/dist/modules/sales/setup.js.map +2 -2
- package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js +10 -2
- package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js.map +2 -2
- package/dist/modules/sales/widgets/injection-table.js +4 -7
- package/dist/modules/sales/widgets/injection-table.js.map +2 -2
- package/dist/modules/staff/backend/staff/leave-requests/page.js +3 -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 +3 -0
- package/dist/modules/staff/backend/staff/my-leave-requests/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/page.js +3 -0
- package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-roles/page.js +3 -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 +3 -0
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/page.js +3 -0
- package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/page.js +29 -18
- package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/page.js +3 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
- package/dist/modules/sync_excel/lib/adapters/customers.js +1 -0
- package/dist/modules/sync_excel/lib/adapters/customers.js.map +2 -2
- package/dist/modules/warranty_claims/api/assignees/route.js +3 -3
- package/dist/modules/warranty_claims/api/assignees/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/portal/attachments/route.js +2 -2
- package/dist/modules/warranty_claims/api/portal/attachments/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/portal/claims/route.js +12 -9
- package/dist/modules/warranty_claims/api/portal/claims/route.js.map +2 -2
- package/dist/modules/warranty_claims/backend/page.js +3 -0
- package/dist/modules/warranty_claims/backend/page.js.map +2 -2
- package/dist/modules/warranty_claims/backend/warranty_claims/registrations/page.js +3 -0
- package/dist/modules/warranty_claims/backend/warranty_claims/registrations/page.js.map +2 -2
- package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js +3 -0
- package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js.map +2 -2
- package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.js +3 -0
- package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.js.map +2 -2
- package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js +3 -0
- package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js.map +2 -2
- package/dist/modules/wms/api/warehouseSearch.js +21 -0
- package/dist/modules/wms/api/warehouseSearch.js.map +7 -0
- package/dist/modules/wms/api/warehouses/route.js +13 -9
- package/dist/modules/wms/api/warehouses/route.js.map +2 -2
- package/dist/modules/wms/api/zones/route.js +15 -2
- package/dist/modules/wms/api/zones/route.js.map +2 -2
- package/dist/modules/wms/commands/configuration.js +121 -9
- package/dist/modules/wms/commands/configuration.js.map +2 -2
- package/dist/modules/wms/commands/inventory-actions.js +3 -0
- package/dist/modules/wms/commands/inventory-actions.js.map +2 -2
- package/dist/modules/wms/commands/shared.js +9 -1
- package/dist/modules/wms/commands/shared.js.map +2 -2
- package/dist/modules/wms/components/backend/WarehouseEditDialog.js +158 -0
- package/dist/modules/wms/components/backend/WarehouseEditDialog.js.map +7 -0
- package/dist/modules/wms/components/backend/WmsConfigurationPage.js +76 -111
- package/dist/modules/wms/components/backend/WmsConfigurationPage.js.map +3 -3
- 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/WmsLotsListPage.js +1 -0
- package/dist/modules/wms/components/backend/WmsLotsListPage.js.map +2 -2
- package/dist/modules/wms/components/backend/inventoryMutationLoaders.js +27 -20
- package/dist/modules/wms/components/backend/inventoryMutationLoaders.js.map +2 -2
- package/dist/modules/wms/components/backend/warehouseFormOptions.js +66 -0
- package/dist/modules/wms/components/backend/warehouseFormOptions.js.map +7 -0
- package/dist/modules/workflows/backend/definitions/page.js +3 -1
- package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
- package/dist/modules/workflows/backend/events/page.js +3 -1
- package/dist/modules/workflows/backend/events/page.js.map +2 -2
- package/dist/modules/workflows/backend/instances/page.js +3 -1
- package/dist/modules/workflows/backend/instances/page.js.map +2 -2
- package/dist/modules/workflows/backend/tasks/page.js +3 -1
- package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
- package/dist/modules/workflows/lib/activity-executor.js +4 -0
- package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
- package/package.json +9 -10
- package/src/helpers/integration/api.ts +33 -1
- package/src/helpers/integration/communicationChannelsFixtures.ts +69 -1
- package/src/modules/api_keys/api/keys/route.ts +3 -1
- package/src/modules/api_keys/backend/api-keys/page.tsx +4 -1
- package/src/modules/api_keys/di.ts +7 -0
- package/src/modules/api_keys/services/principalService.ts +33 -0
- package/src/modules/attachments/AGENTS.md +15 -0
- package/src/modules/attachments/api/route.ts +2 -2
- package/src/modules/attachments/components/AttachmentLibrary.tsx +3 -0
- package/src/modules/attachments/di.ts +16 -0
- package/src/modules/attachments/i18n/de.json +5 -0
- package/src/modules/attachments/i18n/en.json +5 -0
- package/src/modules/attachments/i18n/es.json +5 -0
- package/src/modules/attachments/i18n/ko.json +5 -0
- package/src/modules/attachments/i18n/pl.json +5 -0
- package/src/modules/attachments/index.ts +10 -0
- package/src/modules/attachments/lib/attachment-service.ts +468 -0
- package/src/modules/attachments/lib/scoped-upload-service.ts +46 -0
- package/src/modules/attachments/lib/upload-limits.ts +6 -2
- package/src/modules/audit_logs/backend/audit-logs/page.tsx +8 -0
- package/src/modules/audit_logs/lib/display-helpers.tsx +42 -32
- package/src/modules/audit_logs/services/actionLogService.ts +74 -11
- package/src/modules/auth/acl.ts +30 -6
- package/src/modules/auth/api/feature-check.ts +10 -3
- package/src/modules/auth/api/login.ts +9 -1
- package/src/modules/auth/api/reset/validate.ts +57 -0
- package/src/modules/auth/api/roles/acl/route.ts +42 -39
- package/src/modules/auth/api/session/refresh.ts +32 -1
- package/src/modules/auth/api/users/acl/route.ts +177 -53
- package/src/modules/auth/api/users/route.ts +18 -5
- package/src/modules/auth/backend/roles/[id]/edit/page.meta.ts +5 -2
- package/src/modules/auth/backend/roles/page.tsx +4 -2
- package/src/modules/auth/backend/users/[id]/edit/page.meta.ts +5 -2
- package/src/modules/auth/backend/users/page.tsx +3 -2
- package/src/modules/auth/commands/acl.ts +495 -0
- package/src/modules/auth/components/AclEditor.tsx +63 -33
- package/src/modules/auth/data/entities.ts +4 -1
- package/src/modules/auth/data/validators.ts +5 -0
- package/src/modules/auth/di.ts +46 -16
- package/src/modules/auth/frontend/reset/[token]/page.tsx +74 -0
- package/src/modules/auth/i18n/de.json +389 -0
- package/src/modules/auth/i18n/en.json +389 -0
- package/src/modules/auth/i18n/es.json +389 -0
- package/src/modules/auth/i18n/ko.json +389 -0
- package/src/modules/auth/i18n/pl.json +391 -2
- package/src/modules/auth/lib/grantChecks.ts +6 -0
- package/src/modules/auth/lib/userIdFilter.ts +31 -0
- package/src/modules/auth/services/authService.ts +18 -2
- package/src/modules/auth/services/principalService.ts +266 -0
- package/src/modules/auth/services/rbacService.ts +110 -24
- package/src/modules/auth/services/roleOrganizationScope.ts +70 -0
- package/src/modules/business_rules/backend/logs/page.tsx +4 -1
- package/src/modules/business_rules/backend/rules/page.tsx +4 -1
- package/src/modules/business_rules/backend/sets/page.tsx +4 -1
- package/src/modules/business_rules/lib/expression-evaluator.ts +9 -9
- package/src/modules/business_rules/lib/rule-evaluator.ts +10 -9
- package/src/modules/catalog/ai-agents.ts +1 -1
- package/src/modules/catalog/ai-tools/merchandising-pack.ts +2 -2
- package/src/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.tsx +12 -5
- package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +3 -0
- package/src/modules/catalog/components/products/ProductsDataTable.tsx +7 -0
- package/src/modules/catalog/i18n/de.json +1 -0
- package/src/modules/catalog/i18n/en.json +1 -0
- package/src/modules/catalog/i18n/es.json +1 -0
- package/src/modules/catalog/i18n/ko.json +1 -0
- package/src/modules/catalog/i18n/pl.json +1 -0
- package/src/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.tsx +4 -0
- package/src/modules/communication_channels/api/post/channels/[id]/test-send/route.ts +17 -1
- package/src/modules/communication_channels/api/post/test-seed/route.ts +155 -16
- package/src/modules/communication_channels/backend/communication_channels/channels/page.tsx +4 -0
- package/src/modules/communication_channels/commands/ingest-inbound-message.ts +38 -1
- package/src/modules/communication_channels/di.ts +7 -0
- package/src/modules/communication_channels/lib/adapter.ts +14 -0
- package/src/modules/communication_channels/lib/email-capabilities.ts +4 -0
- package/src/modules/communication_channels/lib/outbound-recipient.ts +71 -0
- package/src/modules/communication_channels/lib/resolve-channel-type.ts +99 -0
- package/src/modules/communication_channels/lib/test-seed.ts +64 -4
- package/src/modules/configs/i18n/de.json +2 -0
- package/src/modules/configs/i18n/en.json +2 -0
- package/src/modules/configs/i18n/es.json +2 -0
- package/src/modules/configs/i18n/ko.json +2 -0
- package/src/modules/configs/i18n/pl.json +2 -0
- package/src/modules/configs/lib/system-status.ts +9 -0
- package/src/modules/currencies/AGENTS.md +3 -0
- package/src/modules/currencies/backend/currencies/page.tsx +4 -1
- package/src/modules/currencies/backend/exchange-rates/page.tsx +4 -1
- package/src/modules/currencies/services/README.md +45 -0
- package/src/modules/currencies/services/rateFetchingService.ts +6 -1
- package/src/modules/customer_accounts/api/admin/domain-mappings.ts +7 -0
- package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +4 -1
- package/src/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.tsx +4 -1
- package/src/modules/customer_accounts/services/domainMappingService.ts +10 -0
- package/src/modules/customers/ai-tools/companies-pack.ts +4 -1
- package/src/modules/customers/ai-tools/deal-analyzer-pack.ts +17 -2
- package/src/modules/customers/ai-tools/deals-pack.ts +66 -1
- package/src/modules/customers/ai-tools/people-pack.ts +4 -1
- package/src/modules/customers/api/activities/route.ts +45 -0
- package/src/modules/customers/api/companies/[id]/people/route.ts +24 -73
- package/src/modules/customers/api/companies/[id]/route.ts +24 -107
- package/src/modules/customers/api/dashboard/widgets/customer-todos/route.ts +16 -8
- package/src/modules/customers/api/deals/[id]/companies/route.ts +4 -1
- package/src/modules/customers/api/deals/[id]/people/route.ts +4 -1
- package/src/modules/customers/api/deals/[id]/route.ts +17 -28
- package/src/modules/customers/api/deals/[id]/stats/route.ts +10 -25
- package/src/modules/customers/api/deals/aggregate/route.ts +17 -9
- package/src/modules/customers/api/deals/map/route.ts +4 -4
- package/src/modules/customers/api/deals/route.ts +50 -1
- package/src/modules/customers/api/entity-roles-factory.ts +8 -4
- package/src/modules/customers/api/interactions/route.ts +8 -2
- package/src/modules/customers/api/interactions/tasks/route.ts +24 -1
- package/src/modules/customers/api/people/[id]/companies/[linkId]/route.ts +12 -4
- package/src/modules/customers/api/people/[id]/companies/context.ts +4 -1
- package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +4 -1
- package/src/modules/customers/api/people/[id]/route.ts +16 -11
- package/src/modules/customers/api/people/check-phone/route.ts +75 -10
- package/src/modules/customers/api/todos/route.ts +27 -2
- package/src/modules/customers/backend/customers/companies/page.tsx +5 -2
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +7 -2
- package/src/modules/customers/backend/customers/deals/page.tsx +8 -2
- package/src/modules/customers/backend/customers/deals/pipeline/components/Lane.tsx +5 -14
- package/src/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.tsx +109 -27
- package/src/modules/customers/backend/customers/deals/pipeline/components/toneClasses.ts +21 -0
- package/src/modules/customers/backend/customers/people/page.tsx +5 -2
- package/src/modules/customers/backend/hooks/useEmailDuplicateCheck.ts +12 -4
- package/src/modules/customers/commands/deals.ts +34 -59
- package/src/modules/customers/commands/interactions.ts +1 -1
- package/src/modules/customers/commands/personCompanyLinks.ts +224 -8
- package/src/modules/customers/components/CustomerTodosTable.tsx +2 -0
- package/src/modules/customers/components/DealsKpiStrip.tsx +7 -7
- package/src/modules/customers/components/calendar/AgendaList.tsx +3 -3
- package/src/modules/customers/components/calendar/CalendarEventEditor.tsx +1 -1
- package/src/modules/customers/components/calendar/CalendarScreen.tsx +1 -1
- package/src/modules/customers/components/calendar/CalendarSettingsModal.tsx +1 -1
- package/src/modules/customers/components/calendar/EventBlock.tsx +2 -2
- package/src/modules/customers/components/calendar/EventPeekPopover.tsx +4 -2
- package/src/modules/customers/components/calendar/editor/PeopleField.tsx +61 -5
- package/src/modules/customers/components/calendar/editor/hooks.ts +7 -1
- package/src/modules/customers/components/calendar/types.ts +2 -2
- package/src/modules/customers/components/detail/CompanyKpiBar.tsx +5 -4
- package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +8 -1
- package/src/modules/customers/components/detail/DealForm.tsx +22 -2
- package/src/modules/customers/components/detail/DealsSection.tsx +11 -5
- package/src/modules/customers/components/detail/EntityTagsDialog.tsx +58 -12
- package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +8 -1
- package/src/modules/customers/components/detail/hooks/usePersonTasks.ts +23 -14
- package/src/modules/customers/components/detail/schedule/ParticipantsField.tsx +5 -5
- package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +5 -5
- package/src/modules/customers/components/detail/types.ts +1 -1
- package/src/modules/customers/components/detail/utils.ts +15 -5
- package/src/modules/customers/data/entities.ts +1 -1
- package/src/modules/customers/data/validators.ts +50 -9
- package/src/modules/customers/events.ts +5 -0
- package/src/modules/customers/i18n/de.json +9 -1
- package/src/modules/customers/i18n/en.json +9 -1
- package/src/modules/customers/i18n/es.json +9 -1
- package/src/modules/customers/i18n/ko.json +9 -1
- package/src/modules/customers/i18n/pl.json +9 -1
- package/src/modules/customers/lib/calendar/conflicts.ts +10 -2
- package/src/modules/customers/lib/calendar/editorPayload.ts +4 -3
- package/src/modules/customers/lib/calendar/mapItem.ts +8 -3
- package/src/modules/customers/lib/calendar/participantIdentity.ts +17 -0
- package/src/modules/customers/lib/closureStage.ts +76 -0
- package/src/modules/customers/lib/dealStatus.ts +42 -0
- package/src/modules/customers/lib/detailReadAccess.ts +35 -0
- package/src/modules/customers/lib/findPeopleByAddresses.ts +8 -6
- package/src/modules/customers/lib/personCompanies.ts +136 -1
- package/src/modules/customers/lib/todoCompatibility.ts +19 -1
- package/src/modules/dashboards/i18n/es.json +4 -4
- package/src/modules/dashboards/i18n/pl.json +7 -7
- package/src/modules/dashboards/lib/widgetScope.ts +6 -0
- package/src/modules/data_sync/AGENTS.md +1 -1
- package/src/modules/data_sync/backend/data-sync/page.tsx +4 -1
- package/src/modules/data_sync/lib/abandoned-run.ts +56 -0
- package/src/modules/data_sync/lib/adapter.ts +36 -0
- package/src/modules/data_sync/lib/sync-engine.ts +113 -5
- package/src/modules/data_sync/workers/sync-export.ts +4 -0
- package/src/modules/data_sync/workers/sync-import.ts +4 -0
- package/src/modules/devices/AGENTS.md +20 -1
- package/src/modules/devices/acl.ts +9 -1
- package/src/modules/devices/api/admin/devices/[id]/route.ts +5 -34
- package/src/modules/devices/api/admin/devices/route.ts +14 -1
- package/src/modules/devices/api/deviceList.ts +135 -11
- package/src/modules/devices/api/deviceSerialization.ts +50 -0
- package/src/modules/devices/api/openapi.ts +9 -1
- package/src/modules/devices/api/route.ts +9 -1
- package/src/modules/devices/backend/devices/[id]/page.tsx +18 -32
- package/src/modules/devices/backend/devices/create/page.tsx +17 -1
- package/src/modules/devices/backend/devices/page.tsx +44 -45
- package/src/modules/devices/backend/devices/useDeviceUserLabels.ts +45 -0
- package/src/modules/devices/backend/devices/userOptions.ts +99 -0
- package/src/modules/devices/i18n/de.json +3 -2
- package/src/modules/devices/i18n/en.json +3 -2
- package/src/modules/devices/i18n/es.json +3 -2
- package/src/modules/devices/i18n/ko.json +3 -2
- package/src/modules/devices/i18n/pl.json +3 -2
- package/src/modules/devices/setup.ts +6 -2
- package/src/modules/directory/backend/directory/organizations/page.tsx +3 -1
- package/src/modules/directory/backend/directory/tenants/page.tsx +3 -1
- package/src/modules/directory/di.ts +14 -2
- package/src/modules/directory/services/organizationHierarchyService.ts +34 -0
- package/src/modules/directory/services/organizationScopeService.ts +85 -0
- package/src/modules/directory/utils/organizationScope.ts +4 -15
- package/src/modules/entities/api/records.ts +2 -0
- package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +4 -1
- package/src/modules/eudr/api/plots/route.ts +4 -0
- package/src/modules/eudr/backend/eudr/evidence-submissions/page.tsx +4 -0
- package/src/modules/eudr/backend/eudr/plots/page.tsx +4 -0
- package/src/modules/eudr/backend/eudr/product-mappings/page.tsx +4 -0
- package/src/modules/eudr/backend/eudr/risk-assessments/page.tsx +4 -0
- package/src/modules/eudr/backend/eudr/statements/page.tsx +4 -0
- package/src/modules/eudr/commands/statements.ts +0 -3
- package/src/modules/eudr/data/validators.ts +16 -1
- package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +2 -1
- package/src/modules/feature_toggles/components/OverridesTable.tsx +2 -1
- package/src/modules/feature_toggles/defaults.json +0 -8
- package/src/modules/inbox_ops/backend/inbox-ops/log/page.tsx +4 -0
- package/src/modules/inbox_ops/backend/inbox-ops/page.tsx +4 -0
- package/src/modules/inbox_ops/lib/htmlToPlainText.ts +1 -17
- package/src/modules/integrations/api/[id]/credentials/route.ts +6 -4
- package/src/modules/integrations/backend/integrations/[id]/page.tsx +61 -31
- package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +44 -9
- package/src/modules/integrations/backend/integrations/credential-secret-fields.ts +84 -0
- package/src/modules/integrations/data/validators.ts +12 -2
- package/src/modules/integrations/i18n/de.json +1 -0
- package/src/modules/integrations/i18n/en.json +1 -0
- package/src/modules/integrations/i18n/es.json +1 -0
- package/src/modules/integrations/i18n/ko.json +1 -0
- package/src/modules/integrations/i18n/pl.json +1 -0
- package/src/modules/integrations/lib/credentials-masking.ts +10 -6
- package/src/modules/messages/api/[id]/route.ts +55 -1
- package/src/modules/messages/api/openapi.ts +20 -0
- package/src/modules/messages/api/route.ts +31 -2
- package/src/modules/messages/components/MessagesInboxPageClient.tsx +9 -16
- package/src/modules/messages/components/inboxFilters.ts +36 -0
- package/src/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.ts +14 -1
- package/src/modules/messages/components/message-detail/panels/MessageHeader.tsx +3 -1
- package/src/modules/messages/components/message-detail/panels/thread-panel.tsx +2 -1
- package/src/modules/messages/components/message-detail/types.ts +3 -0
- package/src/modules/messages/components/messageListLabels.ts +52 -3
- package/src/modules/messages/data/validators.ts +43 -4
- package/src/modules/messages/lib/channel-sender-identity.ts +55 -0
- package/src/modules/messages/lib/composeSourceChannelType.ts +95 -0
- package/src/modules/payment_gateways/api/webhook/[provider]/route.ts +4 -6
- package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +4 -1
- package/src/modules/payment_gateways/lib/webhook-processor.ts +11 -0
- package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +4 -0
- package/src/modules/push_notifications/backend/push_notifications/page.tsx +4 -1
- package/src/modules/push_notifications/backend/push_notifications/send/page.tsx +4 -4
- package/src/modules/query_index/lib/engine.ts +249 -61
- package/src/modules/query_index/lib/search-entity-policy.ts +46 -0
- package/src/modules/query_index/lib/search-tokens.ts +135 -3
- package/src/modules/resources/backend/resources/resource-types/page.tsx +4 -1
- package/src/modules/resources/backend/resources/resources/page.tsx +4 -1
- package/src/modules/sales/backend/sales/channels/offers/page.tsx +4 -0
- package/src/modules/sales/backend/sales/channels/page.tsx +4 -0
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +14 -8
- package/src/modules/sales/commands/documents.ts +93 -0
- package/src/modules/sales/components/PriceWithCurrency.tsx +17 -5
- package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +4 -0
- package/src/modules/sales/components/documents/AdjustmentsSection.tsx +6 -5
- package/src/modules/sales/components/documents/ItemsSection.tsx +56 -18
- package/src/modules/sales/components/documents/LineItemDialog.tsx +137 -20
- package/src/modules/sales/components/documents/PaymentsSection.tsx +20 -9
- package/src/modules/sales/components/documents/ReturnsSection.tsx +6 -5
- package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +106 -14
- package/src/modules/sales/components/documents/SalesOrderDraftLines.tsx +6 -5
- package/src/modules/sales/components/documents/ShipmentDialog.tsx +5 -4
- package/src/modules/sales/components/documents/ShipmentsSection.tsx +6 -5
- package/src/modules/sales/components/documents/lineItemShipmentLock.ts +74 -0
- package/src/modules/sales/components/documents/lineItemUtils.ts +7 -2
- package/src/modules/sales/data/entities.ts +6 -0
- package/src/modules/sales/extension-points.ts +1 -0
- package/src/modules/sales/i18n/de.json +8 -0
- package/src/modules/sales/i18n/en.json +8 -0
- package/src/modules/sales/i18n/es.json +8 -0
- package/src/modules/sales/i18n/ko.json +8 -0
- package/src/modules/sales/i18n/pl.json +8 -0
- package/src/modules/sales/lib/salesChannelsToggleSeed.ts +42 -0
- package/src/modules/sales/migrations/.snapshot-open-mercato.json +60 -0
- package/src/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.ts +87 -0
- package/src/modules/sales/setup.ts +2 -0
- package/src/modules/sales/widgets/injection/payment-gateway-status-column/widget.ts +9 -1
- package/src/modules/sales/widgets/injection-table.ts +4 -7
- package/src/modules/staff/backend/staff/leave-requests/page.tsx +4 -0
- package/src/modules/staff/backend/staff/my-leave-requests/page.tsx +4 -0
- package/src/modules/staff/backend/staff/team-members/page.tsx +6 -0
- package/src/modules/staff/backend/staff/team-roles/page.tsx +4 -0
- package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +4 -0
- package/src/modules/staff/backend/staff/teams/page.tsx +4 -0
- package/src/modules/staff/backend/staff/timesheets/page.tsx +12 -1
- package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +4 -0
- package/src/modules/sync_excel/lib/adapters/customers.ts +5 -0
- package/src/modules/warranty_claims/api/assignees/route.ts +3 -3
- package/src/modules/warranty_claims/api/portal/attachments/route.ts +2 -2
- package/src/modules/warranty_claims/api/portal/claims/route.ts +12 -9
- package/src/modules/warranty_claims/backend/page.tsx +4 -0
- package/src/modules/warranty_claims/backend/warranty_claims/registrations/page.tsx +4 -0
- package/src/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.tsx +4 -0
- package/src/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.tsx +4 -0
- package/src/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.tsx +4 -0
- package/src/modules/wms/api/warehouseSearch.ts +23 -0
- package/src/modules/wms/api/warehouses/route.ts +13 -9
- package/src/modules/wms/api/zones/route.ts +16 -0
- package/src/modules/wms/commands/configuration.ts +159 -10
- package/src/modules/wms/commands/inventory-actions.ts +3 -0
- package/src/modules/wms/commands/shared.ts +17 -0
- package/src/modules/wms/components/backend/WarehouseEditDialog.tsx +216 -0
- package/src/modules/wms/components/backend/WmsConfigurationPage.tsx +95 -141
- package/src/modules/wms/components/backend/WmsInventoryConsolePage.tsx +2 -0
- package/src/modules/wms/components/backend/WmsLotsListPage.tsx +2 -0
- package/src/modules/wms/components/backend/inventoryMutationLoaders.ts +36 -20
- package/src/modules/wms/components/backend/warehouseFormOptions.ts +72 -0
- package/src/modules/wms/i18n/de.json +2 -0
- package/src/modules/wms/i18n/en.json +2 -0
- package/src/modules/wms/i18n/es.json +2 -0
- package/src/modules/wms/i18n/ko.json +2 -0
- package/src/modules/wms/i18n/pl.json +2 -0
- package/src/modules/workflows/backend/definitions/page.tsx +4 -1
- package/src/modules/workflows/backend/events/page.tsx +4 -1
- package/src/modules/workflows/backend/instances/page.tsx +4 -1
- package/src/modules/workflows/backend/tasks/page.tsx +4 -1
- package/src/modules/workflows/lib/activity-executor.ts +9 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/modules/warranty_claims/backend/warranty_claims/registrations/page.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, type BulkAction, type DataTableExportFormat } from '@open-mercato/ui/backend/DataTable'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { ListEmptyState } from '@open-mercato/ui/backend/filters/ListEmptyState'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { StatusBadge } from '@open-mercato/ui/primitives/status-badge'\nimport { apiCall, readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { runBulkDelete } from '@open-mercato/ui/backend/utils/bulkDelete'\nimport { buildCrudExportUrl, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useLocale, useT, type TranslateFn } from '@open-mercato/shared/lib/i18n/context'\nimport { Plus } from 'lucide-react'\nimport { REGISTRATION_COVERAGE_TYPES, REGISTRATION_SOURCES } from '../../../data/validators'\nimport { normalizeRegistration, type RegistrationRecord } from './registrationForm'\nimport { WarrantyWorkspace } from '../../components/WarrantyWorkspace'\nimport { extensionPoints } from '../../../extension-points'\n\ntype RegistrationsResponse = {\n items?: unknown[]\n total?: number\n totalPages?: number\n error?: string\n}\n\nconst PAGE_SIZE = 20\ntype RegistrationSegment = 'all' | 'standard' | 'extended' | 'expiring' | 'none'\n\nfunction toStringOrNull(value: unknown): string | null {\n return typeof value === 'string' && value.trim().length ? value.trim() : null\n}\n\nfunction getCustomerDisplayName(record: Record<string, unknown>): string | null {\n return toStringOrNull(record.display_name) ?? toStringOrNull(record.displayName)\n}\n\nfunction useCustomerDisplayNames(customerIds: readonly (string | null | undefined)[]): Record<string, string> {\n const [customerNames, setCustomerNames] = React.useState<Record<string, string>>({})\n const resolvedCustomerIdsRef = React.useRef<Set<string>>(new Set())\n\n React.useEffect(() => {\n const unresolvedIds = new Set<string>()\n for (const customerId of customerIds) {\n const normalized = toStringOrNull(customerId)\n if (normalized && !resolvedCustomerIdsRef.current.has(normalized)) {\n unresolvedIds.add(normalized)\n }\n }\n if (!unresolvedIds.size) return\n\n for (const customerId of unresolvedIds) resolvedCustomerIdsRef.current.add(customerId)\n\n const controller = new AbortController()\n const idsParam = [...unresolvedIds].map(encodeURIComponent).join(',')\n Promise.all([\n readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/customers/people?ids=${idsParam}&pageSize=100`,\n { signal: controller.signal },\n { fallback: { items: [] }, errorMessage: '[internal] Failed to load customer display names' },\n ),\n readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/customers/companies?ids=${idsParam}&pageSize=100`,\n { signal: controller.signal },\n { fallback: { items: [] }, errorMessage: '[internal] Failed to load customer display names' },\n ),\n ])\n .then(([people, companies]) => {\n const nextNames: Record<string, string> = {}\n for (const record of [...(people.items ?? []), ...(companies.items ?? [])]) {\n const customerId = toStringOrNull(record.id)\n const displayName = getCustomerDisplayName(record)\n if (customerId && displayName) nextNames[customerId] = displayName\n }\n if (Object.keys(nextNames).length) {\n setCustomerNames((current) => ({ ...current, ...nextNames }))\n }\n })\n .catch(() => {})\n return () => controller.abort()\n }, [customerIds])\n\n return customerNames\n}\n\nfunction coverageVariant(value: string | null): 'success' | 'warning' | 'neutral' {\n if (value === 'standard') return 'success'\n if (value === 'extended') return 'warning'\n return 'neutral'\n}\n\nfunction coverageLabel(value: string | null, t: TranslateFn): string {\n if (value === 'standard') return t('warranty_claims.registrations.coverageType.standard', 'Standard')\n if (value === 'extended') return t('warranty_claims.registrations.coverageType.extended', 'Extended')\n if (value === 'none') return t('warranty_claims.registrations.coverageType.none', 'No coverage')\n return t('warranty_claims.common.noValue', 'Not set')\n}\n\nfunction sourceLabel(value: string | null, t: TranslateFn): string {\n if (value === 'order') return t('warranty_claims.registrations.source.order', 'Order')\n if (value === 'manual') return t('warranty_claims.registrations.source.manual', 'Manual')\n if (value === 'third_party') return t('warranty_claims.registrations.source.thirdParty', 'Third party')\n return t('warranty_claims.common.noValue', 'Not set')\n}\n\nfunction registrationSegmentQuery(segment: RegistrationSegment): Record<string, string> {\n if (segment === 'standard' || segment === 'extended' || segment === 'none') return { coverageType: segment }\n if (segment === 'expiring') return { expiry: 'expiring_30d' }\n return {}\n}\n\nfunction formatDate(value: string | null, locale: string): string | null {\n if (!value) return null\n const date = new Date(value)\n return Number.isNaN(date.getTime()) ? null : date.toLocaleDateString(locale || undefined)\n}\n\nfunction hasExpired(value: string | null): boolean {\n if (!value) return false\n const date = new Date(value)\n return !Number.isNaN(date.getTime()) && date.getTime() < Date.now()\n}\n\nexport default function WarrantyClaimRegistrationsPage() {\n const t = useT()\n const locale = useLocale()\n const router = useRouter()\n const scopeVersion = useOrganizationScopeVersion()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const [rows, setRows] = React.useState<RegistrationRecord[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [tabCounts, setTabCounts] = React.useState<Partial<Record<RegistrationSegment, number>>>({})\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [loading, setLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n const customerIds = React.useMemo(() => rows.map((row) => row.customerId), [rows])\n const customerNames = useCustomerDisplayNames(customerIds)\n\n const mutationContextId = 'warranty-claim-registrations-list'\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n resourceId?: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: mutationContextId,\n blockedMessage: t('warranty_claims.registrations.list.error.blocked', 'Save blocked by validation.'),\n })\n\n const reload = React.useCallback(() => {\n setReloadToken((current) => current + 1)\n }, [])\n\n const listQueryString = React.useMemo(() => {\n const params = new URLSearchParams({\n page: String(page),\n pageSize: String(PAGE_SIZE),\n sortField: 'updatedAt',\n sortDir: 'desc',\n })\n if (search.trim()) params.set('search', search.trim())\n const coverageType = toStringOrNull(filterValues.coverageType)\n if (coverageType) params.set('coverageType', coverageType)\n const source = toStringOrNull(filterValues.source)\n if (source) params.set('source', source)\n const expiry = toStringOrNull(filterValues.expiry)\n if (expiry) params.set('expiry', expiry)\n return params.toString()\n }, [filterValues, page, search])\n\n const currentParams = React.useMemo(\n () => Object.fromEntries(new URLSearchParams(listQueryString)),\n [listQueryString],\n )\n\n const exportConfig = React.useMemo(() => ({\n view: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('warranty_claims/registrations', { ...currentParams, exportScope: 'view' }, format),\n },\n full: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('warranty_claims/registrations', { ...currentParams, exportScope: 'full', all: 'true' }, format),\n },\n }), [currentParams])\n\n React.useEffect(() => {\n let cancelled = false\n async function loadRegistrations() {\n setLoading(true)\n try {\n const fallback: RegistrationsResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<RegistrationsResponse>(\n `/api/warranty_claims/registrations?${listQueryString}`,\n undefined,\n { fallback },\n )\n if (!call.ok) {\n const message = call.result?.error ?? t('warranty_claims.registrations.list.error.load', 'Failed to load warranty registrations.')\n flash(message, 'error')\n return\n }\n if (cancelled) return\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n setRows(items.map(normalizeRegistration).filter((row): row is RegistrationRecord => row !== null))\n setTotal(typeof call.result?.total === 'number' ? call.result.total : items.length)\n setTotalPages(typeof call.result?.totalPages === 'number' ? call.result.totalPages : 1)\n } catch (error) {\n if (!cancelled) {\n const message = error instanceof Error\n ? error.message\n : t('warranty_claims.registrations.list.error.load', 'Failed to load warranty registrations.')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setLoading(false)\n }\n }\n void loadRegistrations()\n return () => {\n cancelled = true\n }\n }, [listQueryString, reloadToken, scopeVersion, t])\n\n React.useEffect(() => {\n const controller = new AbortController()\n const segments: RegistrationSegment[] = ['all', 'standard', 'extended', 'expiring', 'none']\n Promise.all(segments.map(async (segment) => {\n const params = new URLSearchParams({ page: '1', pageSize: '1', ...registrationSegmentQuery(segment) })\n const fallback: RegistrationsResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<RegistrationsResponse>(\n `/api/warranty_claims/registrations?${params.toString()}`,\n { signal: controller.signal },\n { fallback },\n )\n if (!call.ok) throw new Error('[internal] Failed to load registration counts')\n return [segment, typeof call.result?.total === 'number' ? call.result.total : 0] as const\n }))\n .then((entries) => {\n if (!controller.signal.aborted) setTabCounts(Object.fromEntries(entries))\n })\n .catch(() => {\n if (!controller.signal.aborted) setTabCounts({})\n })\n return () => controller.abort()\n }, [reloadToken, scopeVersion])\n\n const executeDelete = React.useCallback(async (registration: RegistrationRecord): Promise<unknown> => {\n try {\n await runMutation({\n operation: () => withScopedApiRequestHeaders(\n buildOptimisticLockHeader(registration.updatedAt),\n () => deleteCrud('warranty_claims/registrations', registration.id, {\n errorMessage: t('warranty_claims.registrations.list.error.delete', 'Failed to delete warranty registration.'),\n }),\n ),\n mutationPayload: { id: registration.id },\n context: {\n formId: mutationContextId,\n resourceKind: 'warranty_claims.warranty_claim_registration',\n resourceId: registration.id,\n retryLastMutation,\n },\n })\n return null\n } catch (error) {\n return error\n }\n }, [mutationContextId, retryLastMutation, runMutation, t])\n\n const handleDelete = React.useCallback(async (registration: RegistrationRecord) => {\n const confirmed = await confirm({\n title: t('warranty_claims.registrations.confirm.deleteTitle', 'Delete this warranty registration?'),\n variant: 'destructive',\n })\n if (!confirmed) return\n const error = await executeDelete(registration)\n if (error) {\n if (surfaceRecordConflict(error, t, { onRefresh: reload })) return\n flash(\n error instanceof Error\n ? error.message\n : t('warranty_claims.registrations.list.error.delete', 'Failed to delete warranty registration.'),\n 'error',\n )\n return\n }\n flash(t('warranty_claims.registrations.list.success.delete', 'Warranty registration deleted.'), 'success')\n reload()\n }, [confirm, executeDelete, reload, t])\n\n const handleBulkDelete = React.useCallback(async (selectedRows: RegistrationRecord[]) => {\n const { succeeded, failures } = await runBulkDelete(\n selectedRows,\n async (registration) => {\n const error = await executeDelete(registration)\n if (error) throw error\n },\n {\n fallbackErrorMessage: t('warranty_claims.registrations.list.error.delete', 'Failed to delete warranty registration.'),\n logTag: 'warranty_claims.registrations.list',\n progress: {\n jobType: 'warranty_claims.registrations.bulk_delete',\n name: t('warranty_claims.registrations.bulk.delete', 'Delete selected'),\n },\n },\n )\n const summary = t(\n 'warranty_claims.bulk.summary',\n 'Bulk action finished: {succeeded} succeeded, {failed} failed.',\n { succeeded: succeeded.length, failed: failures.length },\n )\n if (failures.length) {\n flash(`${summary} ${t('warranty_claims.bulk.firstError', 'First error: {message}', { message: failures[0].message })}`, 'warning')\n } else {\n flash(summary, 'success')\n }\n reload()\n return { ok: true as const, affectedCount: succeeded.length }\n }, [executeDelete, reload, t])\n\n const bulkActions = React.useMemo<BulkAction<RegistrationRecord>[]>(() => [\n {\n id: 'bulk-delete',\n label: t('warranty_claims.registrations.bulk.delete', 'Delete selected'),\n destructive: true,\n onExecute: async (selectedRows) => {\n if (!selectedRows.length) return false\n const confirmed = await confirm({\n title: t('warranty_claims.registrations.bulk.deleteTitle', 'Delete selected warranty registrations?'),\n variant: 'destructive',\n })\n if (!confirmed) return false\n return handleBulkDelete(selectedRows)\n },\n },\n ], [confirm, handleBulkDelete, t])\n\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'coverageType',\n label: t('warranty_claims.registrations.list.filter.coverageType', 'Coverage'),\n type: 'select',\n options: REGISTRATION_COVERAGE_TYPES.map((value) => ({ value, label: coverageLabel(value, t) })),\n },\n {\n id: 'source',\n label: t('warranty_claims.registrations.list.filter.source', 'Source'),\n type: 'select',\n options: REGISTRATION_SOURCES.map((value) => ({ value, label: sourceLabel(value, t) })),\n },\n {\n id: 'expiry',\n label: t('warranty_claims.registrations.list.filter.expiry', 'Warranty expiry'),\n type: 'select',\n options: [\n { value: 'expired', label: t('warranty_claims.registrations.list.expiry.expired', 'Expired') },\n { value: 'expiring_30d', label: t('warranty_claims.registrations.list.expiry.expiringSoon', 'Expiring in 30 days') },\n { value: 'active', label: t('warranty_claims.registrations.list.expiry.active', 'Active') },\n ],\n },\n ], [t])\n\n const columns = React.useMemo<ColumnDef<RegistrationRecord>[]>(() => {\n const noValue = <span className=\"text-sm text-muted-foreground\">{t('warranty_claims.common.noValue', 'Not set')}</span>\n return [\n {\n accessorKey: 'serialNumber',\n header: t('warranty_claims.registrations.list.column.serial', 'Serial'),\n meta: { alwaysVisible: true, maxWidth: '150px' },\n cell: ({ row }) => (\n <Link\n href={`/backend/warranty_claims/registrations/${row.original.id}/edit`}\n className=\"font-medium hover:underline\"\n >\n {row.original.serialNumber ?? '\u2014'}\n </Link>\n ),\n },\n {\n accessorKey: 'productName',\n header: t('warranty_claims.registrations.list.column.product', 'Product'),\n meta: { truncate: true, maxWidth: '260px' },\n cell: ({ row }) => row.original.productName ? <span>{row.original.productName}</span> : noValue,\n },\n {\n accessorKey: 'customerId',\n header: t('warranty_claims.registrations.list.column.customer', 'Customer'),\n meta: { maxWidth: '190px' },\n cell: ({ row }) => {\n const customerId = row.original.customerId\n const displayName = customerId ? customerNames[customerId] : undefined\n return displayName\n ? <span>{displayName}</span>\n : <span className=\"text-sm text-muted-foreground\">\u2014</span>\n },\n },\n {\n accessorKey: 'coverageType',\n header: t('warranty_claims.registrations.list.column.coverage', 'Coverage'),\n meta: { maxWidth: '140px' },\n cell: ({ row }) => (\n <StatusBadge variant={coverageVariant(row.original.coverageType)}>\n {coverageLabel(row.original.coverageType, t)}\n </StatusBadge>\n ),\n },\n {\n accessorKey: 'warrantyExpiresAt',\n header: t('warranty_claims.registrations.list.column.warrantyExpiry', 'Warranty expiry'),\n cell: ({ row }) => (\n <span className={hasExpired(row.original.warrantyExpiresAt) ? 'text-sm text-status-error-text' : 'text-sm text-muted-foreground'}>\n {formatDate(row.original.warrantyExpiresAt, locale) ?? t('warranty_claims.common.noValue', 'Not set')}\n </span>\n ),\n },\n {\n accessorKey: 'source',\n header: t('warranty_claims.registrations.list.column.source', 'Source'),\n meta: { maxWidth: '110px' },\n cell: ({ row }) => <span className=\"text-sm text-muted-foreground\">{sourceLabel(row.original.source, t)}</span>,\n },\n ]\n }, [customerNames, locale, t])\n\n const activeTab = toStringOrNull(filterValues.coverageType) === 'standard'\n ? 'standard'\n : toStringOrNull(filterValues.coverageType) === 'extended'\n ? 'extended'\n : toStringOrNull(filterValues.coverageType) === 'none'\n ? 'none'\n : toStringOrNull(filterValues.expiry) === 'expiring_30d'\n ? 'expiring'\n : 'all'\n\n const handleTabChange = React.useCallback((value: string) => {\n if (value === 'standard') setFilterValues({ coverageType: 'standard' })\n else if (value === 'extended') setFilterValues({ coverageType: 'extended' })\n else if (value === 'none') setFilterValues({ coverageType: 'none' })\n else if (value === 'expiring') setFilterValues({ expiry: 'expiring_30d' })\n else setFilterValues({})\n setPage(1)\n }, [])\n\n return (\n <Page>\n <PageBody>\n <WarrantyWorkspace\n title={t('warranty_claims.registrations.list.title', 'Warranty registrations')}\n action={(\n <Button asChild>\n <Link href=\"/backend/warranty_claims/registrations/create\">\n <Plus className=\"size-4\" aria-hidden />\n {t('warranty_claims.registrations.list.actions.add', 'Add registration')}\n </Link>\n </Button>\n )}\n contentClassName=\"[&>[data-component-handle]>div:first-child]:px-8 [&>[data-component-handle]>div:first-child]:py-4 [&_:has(>[data-slot=search-input-wrapper])]:lg:w-56\"\n activeTab={activeTab}\n onTabChange={handleTabChange}\n tabs={[\n { id: 'all', label: t('warranty_claims.registrations.list.tabs.all', 'All'), count: tabCounts.all },\n { id: 'standard', label: t('warranty_claims.registrations.list.tabs.standard', 'Standard'), count: tabCounts.standard },\n { id: 'extended', label: t('warranty_claims.registrations.list.tabs.extended', 'Extended'), count: tabCounts.extended },\n { id: 'expiring', label: t('warranty_claims.registrations.list.tabs.expiring', 'Expiring in 30 days'), count: tabCounts.expiring },\n { id: 'none', label: t('warranty_claims.registrations.list.tabs.none', 'No coverage'), count: tabCounts.none },\n ]}\n >\n <DataTable<RegistrationRecord>\n embedded\n stickyFirstColumn\n stickyActionsColumn\n refreshButton={{\n label: t('warranty_claims.registrations.list.actions.refresh', 'Refresh'),\n onRefresh: reload,\n isRefreshing: loading,\n }}\n columns={columns}\n columnChooser={{ auto: true }}\n data={rows}\n exporter={exportConfig}\n searchValue={search}\n onSearchChange={(value) => {\n setSearch(value)\n setPage(1)\n }}\n searchPlaceholder={t('warranty_claims.registrations.list.searchPlaceholder', 'Search serial, product or customer\u2026')}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={(values) => {\n setFilterValues(values)\n setPage(1)\n }}\n onFiltersClear={() => {\n setFilterValues({})\n setPage(1)\n }}\n perspective={{ tableId: extensionPoints.hosts.registrationsTable.tableId }}\n onRowClick={(row) => router.push(`/backend/warranty_claims/registrations/${row.id}/edit`)}\n isLoading={loading}\n bulkActions={bulkActions}\n rowActions={(row) => (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('warranty_claims.registrations.list.actions.edit', 'Edit'),\n onSelect: () => router.push(`/backend/warranty_claims/registrations/${row.id}/edit`),\n },\n {\n id: 'delete',\n label: t('warranty_claims.registrations.list.actions.delete', 'Delete'),\n destructive: true,\n onSelect: () => {\n void handleDelete(row)\n },\n },\n ]}\n />\n )}\n emptyState={(\n <ListEmptyState\n title={t('warranty_claims.registrations.list.empty.title', 'No warranty registrations yet')}\n description={t('warranty_claims.registrations.list.empty.description', 'Create a registration to resolve warranty entitlement by serial number.')}\n createHref=\"/backend/warranty_claims/registrations/create\"\n createLabel={t('warranty_claims.registrations.list.actions.new', 'New registration')}\n />\n )}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n onPageChange: setPage,\n }}\n />\n </WarrantyWorkspace>\n {ConfirmDialogElement}\n </PageBody>\n </Page>\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, type BulkAction, type DataTableExportFormat } from '@open-mercato/ui/backend/DataTable'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { ListEmptyState } from '@open-mercato/ui/backend/filters/ListEmptyState'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { StatusBadge } from '@open-mercato/ui/primitives/status-badge'\nimport { apiCall, readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { runBulkDelete } from '@open-mercato/ui/backend/utils/bulkDelete'\nimport { buildCrudExportUrl, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useLocale, useT, type TranslateFn } from '@open-mercato/shared/lib/i18n/context'\nimport { Plus } from 'lucide-react'\nimport { REGISTRATION_COVERAGE_TYPES, REGISTRATION_SOURCES } from '../../../data/validators'\nimport { normalizeRegistration, type RegistrationRecord } from './registrationForm'\nimport { WarrantyWorkspace } from '../../components/WarrantyWorkspace'\nimport { extensionPoints } from '../../../extension-points'\n\ntype RegistrationsResponse = {\n items?: unknown[]\n total?: number\n totalPages?: number\n totalIsCapped?: boolean\n error?: string\n}\n\nconst PAGE_SIZE = 20\ntype RegistrationSegment = 'all' | 'standard' | 'extended' | 'expiring' | 'none'\n\nfunction toStringOrNull(value: unknown): string | null {\n return typeof value === 'string' && value.trim().length ? value.trim() : null\n}\n\nfunction getCustomerDisplayName(record: Record<string, unknown>): string | null {\n return toStringOrNull(record.display_name) ?? toStringOrNull(record.displayName)\n}\n\nfunction useCustomerDisplayNames(customerIds: readonly (string | null | undefined)[]): Record<string, string> {\n const [customerNames, setCustomerNames] = React.useState<Record<string, string>>({})\n const resolvedCustomerIdsRef = React.useRef<Set<string>>(new Set())\n\n React.useEffect(() => {\n const unresolvedIds = new Set<string>()\n for (const customerId of customerIds) {\n const normalized = toStringOrNull(customerId)\n if (normalized && !resolvedCustomerIdsRef.current.has(normalized)) {\n unresolvedIds.add(normalized)\n }\n }\n if (!unresolvedIds.size) return\n\n for (const customerId of unresolvedIds) resolvedCustomerIdsRef.current.add(customerId)\n\n const controller = new AbortController()\n const idsParam = [...unresolvedIds].map(encodeURIComponent).join(',')\n Promise.all([\n readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/customers/people?ids=${idsParam}&pageSize=100`,\n { signal: controller.signal },\n { fallback: { items: [] }, errorMessage: '[internal] Failed to load customer display names' },\n ),\n readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/customers/companies?ids=${idsParam}&pageSize=100`,\n { signal: controller.signal },\n { fallback: { items: [] }, errorMessage: '[internal] Failed to load customer display names' },\n ),\n ])\n .then(([people, companies]) => {\n const nextNames: Record<string, string> = {}\n for (const record of [...(people.items ?? []), ...(companies.items ?? [])]) {\n const customerId = toStringOrNull(record.id)\n const displayName = getCustomerDisplayName(record)\n if (customerId && displayName) nextNames[customerId] = displayName\n }\n if (Object.keys(nextNames).length) {\n setCustomerNames((current) => ({ ...current, ...nextNames }))\n }\n })\n .catch(() => {})\n return () => controller.abort()\n }, [customerIds])\n\n return customerNames\n}\n\nfunction coverageVariant(value: string | null): 'success' | 'warning' | 'neutral' {\n if (value === 'standard') return 'success'\n if (value === 'extended') return 'warning'\n return 'neutral'\n}\n\nfunction coverageLabel(value: string | null, t: TranslateFn): string {\n if (value === 'standard') return t('warranty_claims.registrations.coverageType.standard', 'Standard')\n if (value === 'extended') return t('warranty_claims.registrations.coverageType.extended', 'Extended')\n if (value === 'none') return t('warranty_claims.registrations.coverageType.none', 'No coverage')\n return t('warranty_claims.common.noValue', 'Not set')\n}\n\nfunction sourceLabel(value: string | null, t: TranslateFn): string {\n if (value === 'order') return t('warranty_claims.registrations.source.order', 'Order')\n if (value === 'manual') return t('warranty_claims.registrations.source.manual', 'Manual')\n if (value === 'third_party') return t('warranty_claims.registrations.source.thirdParty', 'Third party')\n return t('warranty_claims.common.noValue', 'Not set')\n}\n\nfunction registrationSegmentQuery(segment: RegistrationSegment): Record<string, string> {\n if (segment === 'standard' || segment === 'extended' || segment === 'none') return { coverageType: segment }\n if (segment === 'expiring') return { expiry: 'expiring_30d' }\n return {}\n}\n\nfunction formatDate(value: string | null, locale: string): string | null {\n if (!value) return null\n const date = new Date(value)\n return Number.isNaN(date.getTime()) ? null : date.toLocaleDateString(locale || undefined)\n}\n\nfunction hasExpired(value: string | null): boolean {\n if (!value) return false\n const date = new Date(value)\n return !Number.isNaN(date.getTime()) && date.getTime() < Date.now()\n}\n\nexport default function WarrantyClaimRegistrationsPage() {\n const t = useT()\n const locale = useLocale()\n const router = useRouter()\n const scopeVersion = useOrganizationScopeVersion()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const [rows, setRows] = React.useState<RegistrationRecord[]>([])\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 [tabCounts, setTabCounts] = React.useState<Partial<Record<RegistrationSegment, number>>>({})\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [loading, setLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n const customerIds = React.useMemo(() => rows.map((row) => row.customerId), [rows])\n const customerNames = useCustomerDisplayNames(customerIds)\n\n const mutationContextId = 'warranty-claim-registrations-list'\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n resourceId?: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: mutationContextId,\n blockedMessage: t('warranty_claims.registrations.list.error.blocked', 'Save blocked by validation.'),\n })\n\n const reload = React.useCallback(() => {\n setReloadToken((current) => current + 1)\n }, [])\n\n const listQueryString = React.useMemo(() => {\n const params = new URLSearchParams({\n page: String(page),\n pageSize: String(PAGE_SIZE),\n sortField: 'updatedAt',\n sortDir: 'desc',\n })\n if (search.trim()) params.set('search', search.trim())\n const coverageType = toStringOrNull(filterValues.coverageType)\n if (coverageType) params.set('coverageType', coverageType)\n const source = toStringOrNull(filterValues.source)\n if (source) params.set('source', source)\n const expiry = toStringOrNull(filterValues.expiry)\n if (expiry) params.set('expiry', expiry)\n return params.toString()\n }, [filterValues, page, search])\n\n const currentParams = React.useMemo(\n () => Object.fromEntries(new URLSearchParams(listQueryString)),\n [listQueryString],\n )\n\n const exportConfig = React.useMemo(() => ({\n view: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('warranty_claims/registrations', { ...currentParams, exportScope: 'view' }, format),\n },\n full: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('warranty_claims/registrations', { ...currentParams, exportScope: 'full', all: 'true' }, format),\n },\n }), [currentParams])\n\n React.useEffect(() => {\n let cancelled = false\n async function loadRegistrations() {\n setLoading(true)\n try {\n const fallback: RegistrationsResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<RegistrationsResponse>(\n `/api/warranty_claims/registrations?${listQueryString}`,\n undefined,\n { fallback },\n )\n if (!call.ok) {\n const message = call.result?.error ?? t('warranty_claims.registrations.list.error.load', 'Failed to load warranty registrations.')\n flash(message, 'error')\n return\n }\n if (cancelled) return\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n setRows(items.map(normalizeRegistration).filter((row): row is RegistrationRecord => row !== null))\n setTotal(typeof call.result?.total === 'number' ? call.result.total : items.length)\n setTotalPages(typeof call.result?.totalPages === 'number' ? call.result.totalPages : 1)\n setTotalIsCapped(call.result?.totalIsCapped === true)\n } catch (error) {\n if (!cancelled) {\n const message = error instanceof Error\n ? error.message\n : t('warranty_claims.registrations.list.error.load', 'Failed to load warranty registrations.')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setLoading(false)\n }\n }\n void loadRegistrations()\n return () => {\n cancelled = true\n }\n }, [listQueryString, reloadToken, scopeVersion, t])\n\n React.useEffect(() => {\n const controller = new AbortController()\n const segments: RegistrationSegment[] = ['all', 'standard', 'extended', 'expiring', 'none']\n Promise.all(segments.map(async (segment) => {\n const params = new URLSearchParams({ page: '1', pageSize: '1', ...registrationSegmentQuery(segment) })\n const fallback: RegistrationsResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<RegistrationsResponse>(\n `/api/warranty_claims/registrations?${params.toString()}`,\n { signal: controller.signal },\n { fallback },\n )\n if (!call.ok) throw new Error('[internal] Failed to load registration counts')\n return [segment, typeof call.result?.total === 'number' ? call.result.total : 0] as const\n }))\n .then((entries) => {\n if (!controller.signal.aborted) setTabCounts(Object.fromEntries(entries))\n })\n .catch(() => {\n if (!controller.signal.aborted) setTabCounts({})\n })\n return () => controller.abort()\n }, [reloadToken, scopeVersion])\n\n const executeDelete = React.useCallback(async (registration: RegistrationRecord): Promise<unknown> => {\n try {\n await runMutation({\n operation: () => withScopedApiRequestHeaders(\n buildOptimisticLockHeader(registration.updatedAt),\n () => deleteCrud('warranty_claims/registrations', registration.id, {\n errorMessage: t('warranty_claims.registrations.list.error.delete', 'Failed to delete warranty registration.'),\n }),\n ),\n mutationPayload: { id: registration.id },\n context: {\n formId: mutationContextId,\n resourceKind: 'warranty_claims.warranty_claim_registration',\n resourceId: registration.id,\n retryLastMutation,\n },\n })\n return null\n } catch (error) {\n return error\n }\n }, [mutationContextId, retryLastMutation, runMutation, t])\n\n const handleDelete = React.useCallback(async (registration: RegistrationRecord) => {\n const confirmed = await confirm({\n title: t('warranty_claims.registrations.confirm.deleteTitle', 'Delete this warranty registration?'),\n variant: 'destructive',\n })\n if (!confirmed) return\n const error = await executeDelete(registration)\n if (error) {\n if (surfaceRecordConflict(error, t, { onRefresh: reload })) return\n flash(\n error instanceof Error\n ? error.message\n : t('warranty_claims.registrations.list.error.delete', 'Failed to delete warranty registration.'),\n 'error',\n )\n return\n }\n flash(t('warranty_claims.registrations.list.success.delete', 'Warranty registration deleted.'), 'success')\n reload()\n }, [confirm, executeDelete, reload, t])\n\n const handleBulkDelete = React.useCallback(async (selectedRows: RegistrationRecord[]) => {\n const { succeeded, failures } = await runBulkDelete(\n selectedRows,\n async (registration) => {\n const error = await executeDelete(registration)\n if (error) throw error\n },\n {\n fallbackErrorMessage: t('warranty_claims.registrations.list.error.delete', 'Failed to delete warranty registration.'),\n logTag: 'warranty_claims.registrations.list',\n progress: {\n jobType: 'warranty_claims.registrations.bulk_delete',\n name: t('warranty_claims.registrations.bulk.delete', 'Delete selected'),\n },\n },\n )\n const summary = t(\n 'warranty_claims.bulk.summary',\n 'Bulk action finished: {succeeded} succeeded, {failed} failed.',\n { succeeded: succeeded.length, failed: failures.length },\n )\n if (failures.length) {\n flash(`${summary} ${t('warranty_claims.bulk.firstError', 'First error: {message}', { message: failures[0].message })}`, 'warning')\n } else {\n flash(summary, 'success')\n }\n reload()\n return { ok: true as const, affectedCount: succeeded.length }\n }, [executeDelete, reload, t])\n\n const bulkActions = React.useMemo<BulkAction<RegistrationRecord>[]>(() => [\n {\n id: 'bulk-delete',\n label: t('warranty_claims.registrations.bulk.delete', 'Delete selected'),\n destructive: true,\n onExecute: async (selectedRows) => {\n if (!selectedRows.length) return false\n const confirmed = await confirm({\n title: t('warranty_claims.registrations.bulk.deleteTitle', 'Delete selected warranty registrations?'),\n variant: 'destructive',\n })\n if (!confirmed) return false\n return handleBulkDelete(selectedRows)\n },\n },\n ], [confirm, handleBulkDelete, t])\n\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'coverageType',\n label: t('warranty_claims.registrations.list.filter.coverageType', 'Coverage'),\n type: 'select',\n options: REGISTRATION_COVERAGE_TYPES.map((value) => ({ value, label: coverageLabel(value, t) })),\n },\n {\n id: 'source',\n label: t('warranty_claims.registrations.list.filter.source', 'Source'),\n type: 'select',\n options: REGISTRATION_SOURCES.map((value) => ({ value, label: sourceLabel(value, t) })),\n },\n {\n id: 'expiry',\n label: t('warranty_claims.registrations.list.filter.expiry', 'Warranty expiry'),\n type: 'select',\n options: [\n { value: 'expired', label: t('warranty_claims.registrations.list.expiry.expired', 'Expired') },\n { value: 'expiring_30d', label: t('warranty_claims.registrations.list.expiry.expiringSoon', 'Expiring in 30 days') },\n { value: 'active', label: t('warranty_claims.registrations.list.expiry.active', 'Active') },\n ],\n },\n ], [t])\n\n const columns = React.useMemo<ColumnDef<RegistrationRecord>[]>(() => {\n const noValue = <span className=\"text-sm text-muted-foreground\">{t('warranty_claims.common.noValue', 'Not set')}</span>\n return [\n {\n accessorKey: 'serialNumber',\n header: t('warranty_claims.registrations.list.column.serial', 'Serial'),\n meta: { alwaysVisible: true, maxWidth: '150px' },\n cell: ({ row }) => (\n <Link\n href={`/backend/warranty_claims/registrations/${row.original.id}/edit`}\n className=\"font-medium hover:underline\"\n >\n {row.original.serialNumber ?? '\u2014'}\n </Link>\n ),\n },\n {\n accessorKey: 'productName',\n header: t('warranty_claims.registrations.list.column.product', 'Product'),\n meta: { truncate: true, maxWidth: '260px' },\n cell: ({ row }) => row.original.productName ? <span>{row.original.productName}</span> : noValue,\n },\n {\n accessorKey: 'customerId',\n header: t('warranty_claims.registrations.list.column.customer', 'Customer'),\n meta: { maxWidth: '190px' },\n cell: ({ row }) => {\n const customerId = row.original.customerId\n const displayName = customerId ? customerNames[customerId] : undefined\n return displayName\n ? <span>{displayName}</span>\n : <span className=\"text-sm text-muted-foreground\">\u2014</span>\n },\n },\n {\n accessorKey: 'coverageType',\n header: t('warranty_claims.registrations.list.column.coverage', 'Coverage'),\n meta: { maxWidth: '140px' },\n cell: ({ row }) => (\n <StatusBadge variant={coverageVariant(row.original.coverageType)}>\n {coverageLabel(row.original.coverageType, t)}\n </StatusBadge>\n ),\n },\n {\n accessorKey: 'warrantyExpiresAt',\n header: t('warranty_claims.registrations.list.column.warrantyExpiry', 'Warranty expiry'),\n cell: ({ row }) => (\n <span className={hasExpired(row.original.warrantyExpiresAt) ? 'text-sm text-status-error-text' : 'text-sm text-muted-foreground'}>\n {formatDate(row.original.warrantyExpiresAt, locale) ?? t('warranty_claims.common.noValue', 'Not set')}\n </span>\n ),\n },\n {\n accessorKey: 'source',\n header: t('warranty_claims.registrations.list.column.source', 'Source'),\n meta: { maxWidth: '110px' },\n cell: ({ row }) => <span className=\"text-sm text-muted-foreground\">{sourceLabel(row.original.source, t)}</span>,\n },\n ]\n }, [customerNames, locale, t])\n\n const activeTab = toStringOrNull(filterValues.coverageType) === 'standard'\n ? 'standard'\n : toStringOrNull(filterValues.coverageType) === 'extended'\n ? 'extended'\n : toStringOrNull(filterValues.coverageType) === 'none'\n ? 'none'\n : toStringOrNull(filterValues.expiry) === 'expiring_30d'\n ? 'expiring'\n : 'all'\n\n const handleTabChange = React.useCallback((value: string) => {\n if (value === 'standard') setFilterValues({ coverageType: 'standard' })\n else if (value === 'extended') setFilterValues({ coverageType: 'extended' })\n else if (value === 'none') setFilterValues({ coverageType: 'none' })\n else if (value === 'expiring') setFilterValues({ expiry: 'expiring_30d' })\n else setFilterValues({})\n setPage(1)\n }, [])\n\n return (\n <Page>\n <PageBody>\n <WarrantyWorkspace\n title={t('warranty_claims.registrations.list.title', 'Warranty registrations')}\n action={(\n <Button asChild>\n <Link href=\"/backend/warranty_claims/registrations/create\">\n <Plus className=\"size-4\" aria-hidden />\n {t('warranty_claims.registrations.list.actions.add', 'Add registration')}\n </Link>\n </Button>\n )}\n contentClassName=\"[&>[data-component-handle]>div:first-child]:px-8 [&>[data-component-handle]>div:first-child]:py-4 [&_:has(>[data-slot=search-input-wrapper])]:lg:w-56\"\n activeTab={activeTab}\n onTabChange={handleTabChange}\n tabs={[\n { id: 'all', label: t('warranty_claims.registrations.list.tabs.all', 'All'), count: tabCounts.all },\n { id: 'standard', label: t('warranty_claims.registrations.list.tabs.standard', 'Standard'), count: tabCounts.standard },\n { id: 'extended', label: t('warranty_claims.registrations.list.tabs.extended', 'Extended'), count: tabCounts.extended },\n { id: 'expiring', label: t('warranty_claims.registrations.list.tabs.expiring', 'Expiring in 30 days'), count: tabCounts.expiring },\n { id: 'none', label: t('warranty_claims.registrations.list.tabs.none', 'No coverage'), count: tabCounts.none },\n ]}\n >\n <DataTable<RegistrationRecord>\n embedded\n stickyFirstColumn\n stickyActionsColumn\n refreshButton={{\n label: t('warranty_claims.registrations.list.actions.refresh', 'Refresh'),\n onRefresh: reload,\n isRefreshing: loading,\n }}\n columns={columns}\n columnChooser={{ auto: true }}\n data={rows}\n exporter={exportConfig}\n searchValue={search}\n onSearchChange={(value) => {\n setSearch(value)\n setPage(1)\n }}\n searchPlaceholder={t('warranty_claims.registrations.list.searchPlaceholder', 'Search serial, product or customer\u2026')}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={(values) => {\n setFilterValues(values)\n setPage(1)\n }}\n onFiltersClear={() => {\n setFilterValues({})\n setPage(1)\n }}\n perspective={{ tableId: extensionPoints.hosts.registrationsTable.tableId }}\n onRowClick={(row) => router.push(`/backend/warranty_claims/registrations/${row.id}/edit`)}\n isLoading={loading}\n bulkActions={bulkActions}\n rowActions={(row) => (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('warranty_claims.registrations.list.actions.edit', 'Edit'),\n onSelect: () => router.push(`/backend/warranty_claims/registrations/${row.id}/edit`),\n },\n {\n id: 'delete',\n label: t('warranty_claims.registrations.list.actions.delete', 'Delete'),\n destructive: true,\n onSelect: () => {\n void handleDelete(row)\n },\n },\n ]}\n />\n )}\n emptyState={(\n <ListEmptyState\n title={t('warranty_claims.registrations.list.empty.title', 'No warranty registrations yet')}\n description={t('warranty_claims.registrations.list.empty.description', 'Create a registration to resolve warranty entitlement by serial number.')}\n createHref=\"/backend/warranty_claims/registrations/create\"\n createLabel={t('warranty_claims.registrations.list.actions.new', 'New registration')}\n />\n )}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n totalIsCapped,\n onPageChange: setPage,\n }}\n />\n </WarrantyWorkspace>\n {ConfirmDialogElement}\n </PageBody>\n </Page>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -53,6 +53,7 @@ function WarrantyTroubleshootingGuidesPage() {
|
|
|
53
53
|
const [page, setPage] = React.useState(1);
|
|
54
54
|
const [total, setTotal] = React.useState(0);
|
|
55
55
|
const [totalPages, setTotalPages] = React.useState(1);
|
|
56
|
+
const [totalIsCapped, setTotalIsCapped] = React.useState(false);
|
|
56
57
|
const [tabCounts, setTabCounts] = React.useState({});
|
|
57
58
|
const [search, setSearch] = React.useState("");
|
|
58
59
|
const [filterValues, setFilterValues] = React.useState({});
|
|
@@ -125,6 +126,7 @@ function WarrantyTroubleshootingGuidesPage() {
|
|
|
125
126
|
setRows(items.map(normalizeTroubleshootingGuide).filter((row) => row !== null));
|
|
126
127
|
setTotal(typeof call.result?.total === "number" ? call.result.total : items.length);
|
|
127
128
|
setTotalPages(typeof call.result?.totalPages === "number" ? call.result.totalPages : 1);
|
|
129
|
+
setTotalIsCapped(call.result?.totalIsCapped === true);
|
|
128
130
|
} catch (error) {
|
|
129
131
|
if (!cancelled) {
|
|
130
132
|
const message = error instanceof Error ? error.message : t("warranty_claims.troubleshootingGuides.list.error.load", "Failed to load troubleshooting guides.");
|
|
@@ -399,6 +401,7 @@ function WarrantyTroubleshootingGuidesPage() {
|
|
|
399
401
|
pageSize: PAGE_SIZE,
|
|
400
402
|
total,
|
|
401
403
|
totalPages,
|
|
404
|
+
totalIsCapped,
|
|
402
405
|
onPageChange: setPage
|
|
403
406
|
}
|
|
404
407
|
}
|
package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, type BulkAction, type DataTableExportFormat } from '@open-mercato/ui/backend/DataTable'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { ListEmptyState } from '@open-mercato/ui/backend/filters/ListEmptyState'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { StatusBadge } from '@open-mercato/ui/primitives/status-badge'\nimport { apiCall, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { runBulkDelete } from '@open-mercato/ui/backend/utils/bulkDelete'\nimport { buildCrudExportUrl, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useLocale, useT, type TranslateFn } from '@open-mercato/shared/lib/i18n/context'\nimport { formatDateTime, formatRelativeTime } from '@open-mercato/shared/lib/time'\nimport { Plus } from 'lucide-react'\nimport type { TroubleshootingNode } from '../../../lib/troubleshooting'\nimport { CLAIM_TYPES } from '../../../data/validators'\nimport { localizeDictionaryLabel } from '../../../lib/dictionaryLabels'\nimport { fetchClaimReasonOptions } from '../../components/claimReasonOptions'\nimport {\n activeLabel,\n claimTypeLabel,\n normalizeTroubleshootingGuide,\n type TroubleshootingGuideRecord,\n} from './troubleshootingGuideForm'\nimport { WarrantyWorkspace } from '../../components/WarrantyWorkspace'\nimport { extensionPoints } from '../../../extension-points'\n\ntype TroubleshootingGuidesResponse = {\n items?: unknown[]\n total?: number\n totalPages?: number\n error?: string\n}\n\nconst PAGE_SIZE = 20\ntype GuideSegment = 'all' | 'published' | 'draft'\n\nfunction reasonLabel(value: string | null, t: TranslateFn, storedLabels: Record<string, string>): string {\n if (!value) return t('warranty_claims.troubleshootingGuides.reason.any', 'Any reason')\n return localizeDictionaryLabel(t, 'reason', value, storedLabels[value] ?? value)\n}\n\nfunction toFilterString(value: unknown): string | null {\n return typeof value === 'string' && value.trim().length ? value.trim() : null\n}\n\nfunction countGuideSteps(node: TroubleshootingNode | null): number {\n if (!node) return 0\n return 1 + node.options.reduce((count, option) => count + (option.next ? countGuideSteps(option.next) : 1), 0)\n}\n\nexport default function WarrantyTroubleshootingGuidesPage() {\n const t = useT()\n const locale = useLocale()\n const router = useRouter()\n const scopeVersion = useOrganizationScopeVersion()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const [rows, setRows] = React.useState<TroubleshootingGuideRecord[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [tabCounts, setTabCounts] = React.useState<Partial<Record<GuideSegment, number>>>({})\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [loading, setLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [reasonLabels, setReasonLabels] = React.useState<Record<string, string>>({})\n\n React.useEffect(() => {\n let cancelled = false\n void fetchClaimReasonOptions(t)\n .then((options) => {\n if (cancelled) return\n setReasonLabels(Object.fromEntries(options.map((option) => [option.value, option.label])))\n })\n .catch(() => {})\n return () => { cancelled = true }\n }, [t])\n\n const mutationContextId = 'warranty-claim-troubleshooting-guides-list'\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n resourceId?: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: mutationContextId,\n blockedMessage: t('warranty_claims.troubleshootingGuides.list.error.blocked', 'Save blocked by validation.'),\n })\n\n const reload = React.useCallback(() => {\n setReloadToken((current) => current + 1)\n }, [])\n\n const listQueryString = React.useMemo(() => {\n const params = new URLSearchParams({\n page: String(page),\n pageSize: String(PAGE_SIZE),\n sortField: 'updatedAt',\n sortDir: 'desc',\n })\n if (search.trim()) params.set('search', search.trim())\n const claimType = toFilterString(filterValues.claimType)\n const isActive = toFilterString(filterValues.isActive)\n if (claimType) params.set('claimType', claimType)\n if (isActive) params.set('isActive', isActive)\n return params.toString()\n }, [filterValues.claimType, filterValues.isActive, page, search])\n\n const currentParams = React.useMemo(\n () => Object.fromEntries(new URLSearchParams(listQueryString)),\n [listQueryString],\n )\n\n const exportConfig = React.useMemo(() => ({\n view: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('warranty_claims/troubleshooting-guides', { ...currentParams, exportScope: 'view' }, format),\n },\n full: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('warranty_claims/troubleshooting-guides', { ...currentParams, exportScope: 'full', all: 'true' }, format),\n },\n }), [currentParams])\n\n React.useEffect(() => {\n let cancelled = false\n async function loadGuides() {\n setLoading(true)\n try {\n const fallback: TroubleshootingGuidesResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<TroubleshootingGuidesResponse>(\n `/api/warranty_claims/troubleshooting-guides?${listQueryString}`,\n undefined,\n { fallback },\n )\n if (!call.ok) {\n const message = call.result?.error ?? t('warranty_claims.troubleshootingGuides.list.error.load', 'Failed to load troubleshooting guides.')\n flash(message, 'error')\n return\n }\n if (cancelled) return\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n setRows(items.map(normalizeTroubleshootingGuide).filter((row): row is TroubleshootingGuideRecord => row !== null))\n setTotal(typeof call.result?.total === 'number' ? call.result.total : items.length)\n setTotalPages(typeof call.result?.totalPages === 'number' ? call.result.totalPages : 1)\n } catch (error) {\n if (!cancelled) {\n const message = error instanceof Error\n ? error.message\n : t('warranty_claims.troubleshootingGuides.list.error.load', 'Failed to load troubleshooting guides.')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setLoading(false)\n }\n }\n void loadGuides()\n return () => {\n cancelled = true\n }\n }, [listQueryString, reloadToken, scopeVersion, t])\n\n React.useEffect(() => {\n const controller = new AbortController()\n const segments: Array<readonly [GuideSegment, Record<string, string>]> = [\n ['all', {}],\n ['published', { isActive: 'true' }],\n ['draft', { isActive: 'false' }],\n ]\n Promise.all(segments.map(async ([segment, query]) => {\n const params = new URLSearchParams({ page: '1', pageSize: '1', ...query })\n const fallback: TroubleshootingGuidesResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<TroubleshootingGuidesResponse>(\n `/api/warranty_claims/troubleshooting-guides?${params.toString()}`,\n { signal: controller.signal },\n { fallback },\n )\n if (!call.ok) throw new Error('[internal] Failed to load guide counts')\n return [segment, typeof call.result?.total === 'number' ? call.result.total : 0] as const\n }))\n .then((entries) => {\n if (!controller.signal.aborted) setTabCounts(Object.fromEntries(entries))\n })\n .catch(() => {\n if (!controller.signal.aborted) setTabCounts({})\n })\n return () => controller.abort()\n }, [reloadToken, scopeVersion])\n\n const executeDelete = React.useCallback(async (guide: TroubleshootingGuideRecord): Promise<unknown> => {\n try {\n await runMutation({\n operation: () => withScopedApiRequestHeaders(\n buildOptimisticLockHeader(guide.updatedAt),\n () => deleteCrud('warranty_claims/troubleshooting-guides', guide.id, {\n errorMessage: t('warranty_claims.troubleshootingGuides.list.error.delete', 'Failed to delete troubleshooting guide.'),\n }),\n ),\n mutationPayload: { id: guide.id },\n context: {\n formId: mutationContextId,\n resourceKind: 'warranty_claims.warranty_troubleshooting_guide',\n resourceId: guide.id,\n retryLastMutation,\n },\n })\n return null\n } catch (error) {\n return error\n }\n }, [mutationContextId, retryLastMutation, runMutation, t])\n\n const handleDelete = React.useCallback(async (guide: TroubleshootingGuideRecord) => {\n const confirmed = await confirm({\n title: t('warranty_claims.troubleshootingGuides.confirm.deleteTitle', 'Delete this troubleshooting guide?'),\n variant: 'destructive',\n })\n if (!confirmed) return\n const error = await executeDelete(guide)\n if (error) {\n if (surfaceRecordConflict(error, t, { onRefresh: reload })) return\n flash(\n error instanceof Error\n ? error.message\n : t('warranty_claims.troubleshootingGuides.list.error.delete', 'Failed to delete troubleshooting guide.'),\n 'error',\n )\n return\n }\n flash(t('warranty_claims.troubleshootingGuides.list.success.delete', 'Troubleshooting guide deleted.'), 'success')\n reload()\n }, [confirm, executeDelete, reload, t])\n\n const handleBulkDelete = React.useCallback(async (selectedRows: TroubleshootingGuideRecord[]) => {\n const { succeeded, failures } = await runBulkDelete(\n selectedRows,\n async (guide) => {\n const error = await executeDelete(guide)\n if (error) throw error\n },\n {\n fallbackErrorMessage: t('warranty_claims.troubleshootingGuides.list.error.delete', 'Failed to delete troubleshooting guide.'),\n logTag: 'warranty_claims.troubleshooting_guides.list',\n progress: {\n jobType: 'warranty_claims.troubleshooting_guides.bulk_delete',\n name: t('warranty_claims.troubleshootingGuides.bulk.delete', 'Delete selected'),\n },\n },\n )\n const summary = t(\n 'warranty_claims.bulk.summary',\n 'Bulk action finished: {succeeded} succeeded, {failed} failed.',\n { succeeded: succeeded.length, failed: failures.length },\n )\n if (failures.length) {\n flash(`${summary} ${t('warranty_claims.bulk.firstError', 'First error: {message}', { message: failures[0].message })}`, 'warning')\n } else {\n flash(summary, 'success')\n }\n reload()\n return { ok: true as const, affectedCount: succeeded.length }\n }, [executeDelete, reload, t])\n\n const bulkActions = React.useMemo<BulkAction<TroubleshootingGuideRecord>[]>(() => [\n {\n id: 'bulk-delete',\n label: t('warranty_claims.troubleshootingGuides.bulk.delete', 'Delete selected'),\n destructive: true,\n onExecute: async (selectedRows) => {\n if (!selectedRows.length) return false\n const confirmed = await confirm({\n title: t('warranty_claims.troubleshootingGuides.bulk.deleteTitle', 'Delete selected troubleshooting guides?'),\n variant: 'destructive',\n })\n if (!confirmed) return false\n return handleBulkDelete(selectedRows)\n },\n },\n ], [confirm, handleBulkDelete, t])\n\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'claimType',\n label: t('warranty_claims.troubleshootingGuides.list.filter.claimType', 'Claim type'),\n type: 'select',\n options: CLAIM_TYPES.map((value) => ({ value, label: claimTypeLabel(value, t) })),\n },\n {\n id: 'isActive',\n label: t('warranty_claims.troubleshootingGuides.list.filter.status', 'Status'),\n type: 'select',\n options: [\n { value: 'true', label: t('warranty_claims.troubleshootingGuides.status.active', 'Active') },\n { value: 'false', label: t('warranty_claims.troubleshootingGuides.status.inactive', 'Inactive') },\n ],\n },\n ], [t])\n\n const columns = React.useMemo<ColumnDef<TroubleshootingGuideRecord>[]>(() => [\n {\n accessorKey: 'title',\n header: t('warranty_claims.troubleshootingGuides.list.column.title', 'Title'),\n meta: { alwaysVisible: true, truncate: true, maxWidth: '280px' },\n cell: ({ row }) => (\n <Link\n href={`/backend/warranty_claims/troubleshooting-guides/${row.original.id}/edit`}\n className=\"font-medium hover:underline\"\n >\n {row.original.title ?? t('warranty_claims.troubleshootingGuides.list.untitled', 'Untitled guide')}\n </Link>\n ),\n },\n {\n accessorKey: 'claimType',\n header: t('warranty_claims.troubleshootingGuides.list.column.claimType', 'Claim type'),\n cell: ({ row }) => (\n <span className=\"text-sm text-muted-foreground\">\n {claimTypeLabel(row.original.claimType, t)}\n </span>\n ),\n },\n {\n accessorKey: 'reasonCode',\n header: t('warranty_claims.troubleshootingGuides.list.column.reason', 'Reason'),\n meta: { truncate: true, maxWidth: '220px' },\n cell: ({ row }) => (\n <span className=\"text-sm text-foreground\">\n {reasonLabel(row.original.reasonCode, t, reasonLabels)}\n </span>\n ),\n },\n {\n id: 'steps',\n header: t('warranty_claims.troubleshootingGuides.list.column.steps', 'Steps'),\n meta: { maxWidth: '100px' },\n cell: ({ row }) => <span className=\"text-sm text-muted-foreground\">{countGuideSteps(row.original.steps)}</span>,\n },\n {\n accessorKey: 'isActive',\n header: t('warranty_claims.troubleshootingGuides.list.column.active', 'Status'),\n cell: ({ row }) => (\n <StatusBadge variant={row.original.isActive ? 'success' : 'neutral'}>\n {activeLabel(row.original.isActive, t)}\n </StatusBadge>\n ),\n },\n {\n accessorKey: 'updatedAt',\n header: t('warranty_claims.troubleshootingGuides.list.column.updated', 'Updated'),\n cell: ({ row }) => (\n <span className=\"text-sm text-muted-foreground\" title={formatDateTime(row.original.updatedAt) ?? undefined}>\n {formatRelativeTime(row.original.updatedAt, { locale }) ?? t('warranty_claims.common.noValue', 'Not set')}\n </span>\n ),\n },\n ], [reasonLabels, locale, t])\n\n const activeTab = toFilterString(filterValues.isActive) === 'true'\n ? 'published'\n : toFilterString(filterValues.isActive) === 'false'\n ? 'draft'\n : 'all'\n\n const handleTabChange = React.useCallback((value: string) => {\n if (value === 'published') setFilterValues({ isActive: 'true' })\n else if (value === 'draft') setFilterValues({ isActive: 'false' })\n else setFilterValues({})\n setPage(1)\n }, [])\n\n return (\n <Page>\n <PageBody>\n <WarrantyWorkspace\n title={t('warranty_claims.troubleshootingGuides.list.title', 'Troubleshooting guides')}\n action={(\n <Button asChild>\n <Link href=\"/backend/warranty_claims/troubleshooting-guides/create\">\n <Plus className=\"size-4\" aria-hidden />\n {t('warranty_claims.troubleshootingGuides.list.actions.new', 'New guide')}\n </Link>\n </Button>\n )}\n contentClassName=\"[&>[data-component-handle]>div:first-child]:px-8 [&>[data-component-handle]>div:first-child]:py-4 [&_:has(>[data-slot=search-input-wrapper])]:lg:w-56\"\n activeTab={activeTab}\n onTabChange={handleTabChange}\n tabs={[\n { id: 'all', label: t('warranty_claims.troubleshootingGuides.list.tabs.all', 'All'), count: tabCounts.all },\n { id: 'published', label: t('warranty_claims.troubleshootingGuides.list.tabs.published', 'Published'), count: tabCounts.published },\n { id: 'draft', label: t('warranty_claims.troubleshootingGuides.list.tabs.draft', 'Draft'), count: tabCounts.draft },\n ]}\n >\n <DataTable<TroubleshootingGuideRecord>\n embedded\n stickyFirstColumn\n stickyActionsColumn\n refreshButton={{\n label: t('warranty_claims.troubleshootingGuides.list.actions.refresh', 'Refresh'),\n onRefresh: reload,\n isRefreshing: loading,\n }}\n columns={columns}\n data={rows}\n exporter={exportConfig}\n searchValue={search}\n onSearchChange={(value) => {\n setSearch(value)\n setPage(1)\n }}\n searchPlaceholder={t('warranty_claims.troubleshootingGuides.list.searchPlaceholder', 'Search guides\u2026')}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={(values) => {\n setFilterValues(values)\n setPage(1)\n }}\n onFiltersClear={() => {\n setFilterValues({})\n setPage(1)\n }}\n perspective={{ tableId: extensionPoints.hosts.troubleshootingGuidesTable.tableId }}\n onRowClick={(row) => router.push(`/backend/warranty_claims/troubleshooting-guides/${row.id}/edit`)}\n isLoading={loading}\n bulkActions={bulkActions}\n rowActions={(row) => (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('warranty_claims.troubleshootingGuides.list.actions.edit', 'Edit'),\n onSelect: () => router.push(`/backend/warranty_claims/troubleshooting-guides/${row.id}/edit`),\n },\n {\n id: 'delete',\n label: t('warranty_claims.troubleshootingGuides.list.actions.delete', 'Delete'),\n destructive: true,\n onSelect: () => {\n void handleDelete(row)\n },\n },\n ]}\n />\n )}\n emptyState={(\n <ListEmptyState\n title={t('warranty_claims.troubleshootingGuides.list.empty.title', 'No troubleshooting guides yet')}\n description={t('warranty_claims.troubleshootingGuides.list.empty.description', 'Create a guide to offer guided decisions during claim intake and triage.')}\n createHref=\"/backend/warranty_claims/troubleshooting-guides/create\"\n createLabel={t('warranty_claims.troubleshootingGuides.list.actions.new', 'New guide')}\n />\n )}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n onPageChange: setPage,\n }}\n />\n </WarrantyWorkspace>\n {ConfirmDialogElement}\n </PageBody>\n </Page>\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, type BulkAction, type DataTableExportFormat } from '@open-mercato/ui/backend/DataTable'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { ListEmptyState } from '@open-mercato/ui/backend/filters/ListEmptyState'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { StatusBadge } from '@open-mercato/ui/primitives/status-badge'\nimport { apiCall, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { runBulkDelete } from '@open-mercato/ui/backend/utils/bulkDelete'\nimport { buildCrudExportUrl, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useLocale, useT, type TranslateFn } from '@open-mercato/shared/lib/i18n/context'\nimport { formatDateTime, formatRelativeTime } from '@open-mercato/shared/lib/time'\nimport { Plus } from 'lucide-react'\nimport type { TroubleshootingNode } from '../../../lib/troubleshooting'\nimport { CLAIM_TYPES } from '../../../data/validators'\nimport { localizeDictionaryLabel } from '../../../lib/dictionaryLabels'\nimport { fetchClaimReasonOptions } from '../../components/claimReasonOptions'\nimport {\n activeLabel,\n claimTypeLabel,\n normalizeTroubleshootingGuide,\n type TroubleshootingGuideRecord,\n} from './troubleshootingGuideForm'\nimport { WarrantyWorkspace } from '../../components/WarrantyWorkspace'\nimport { extensionPoints } from '../../../extension-points'\n\ntype TroubleshootingGuidesResponse = {\n items?: unknown[]\n total?: number\n totalPages?: number\n totalIsCapped?: boolean\n error?: string\n}\n\nconst PAGE_SIZE = 20\ntype GuideSegment = 'all' | 'published' | 'draft'\n\nfunction reasonLabel(value: string | null, t: TranslateFn, storedLabels: Record<string, string>): string {\n if (!value) return t('warranty_claims.troubleshootingGuides.reason.any', 'Any reason')\n return localizeDictionaryLabel(t, 'reason', value, storedLabels[value] ?? value)\n}\n\nfunction toFilterString(value: unknown): string | null {\n return typeof value === 'string' && value.trim().length ? value.trim() : null\n}\n\nfunction countGuideSteps(node: TroubleshootingNode | null): number {\n if (!node) return 0\n return 1 + node.options.reduce((count, option) => count + (option.next ? countGuideSteps(option.next) : 1), 0)\n}\n\nexport default function WarrantyTroubleshootingGuidesPage() {\n const t = useT()\n const locale = useLocale()\n const router = useRouter()\n const scopeVersion = useOrganizationScopeVersion()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const [rows, setRows] = React.useState<TroubleshootingGuideRecord[]>([])\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 [tabCounts, setTabCounts] = React.useState<Partial<Record<GuideSegment, number>>>({})\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [loading, setLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [reasonLabels, setReasonLabels] = React.useState<Record<string, string>>({})\n\n React.useEffect(() => {\n let cancelled = false\n void fetchClaimReasonOptions(t)\n .then((options) => {\n if (cancelled) return\n setReasonLabels(Object.fromEntries(options.map((option) => [option.value, option.label])))\n })\n .catch(() => {})\n return () => { cancelled = true }\n }, [t])\n\n const mutationContextId = 'warranty-claim-troubleshooting-guides-list'\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n resourceId?: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: mutationContextId,\n blockedMessage: t('warranty_claims.troubleshootingGuides.list.error.blocked', 'Save blocked by validation.'),\n })\n\n const reload = React.useCallback(() => {\n setReloadToken((current) => current + 1)\n }, [])\n\n const listQueryString = React.useMemo(() => {\n const params = new URLSearchParams({\n page: String(page),\n pageSize: String(PAGE_SIZE),\n sortField: 'updatedAt',\n sortDir: 'desc',\n })\n if (search.trim()) params.set('search', search.trim())\n const claimType = toFilterString(filterValues.claimType)\n const isActive = toFilterString(filterValues.isActive)\n if (claimType) params.set('claimType', claimType)\n if (isActive) params.set('isActive', isActive)\n return params.toString()\n }, [filterValues.claimType, filterValues.isActive, page, search])\n\n const currentParams = React.useMemo(\n () => Object.fromEntries(new URLSearchParams(listQueryString)),\n [listQueryString],\n )\n\n const exportConfig = React.useMemo(() => ({\n view: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('warranty_claims/troubleshooting-guides', { ...currentParams, exportScope: 'view' }, format),\n },\n full: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('warranty_claims/troubleshooting-guides', { ...currentParams, exportScope: 'full', all: 'true' }, format),\n },\n }), [currentParams])\n\n React.useEffect(() => {\n let cancelled = false\n async function loadGuides() {\n setLoading(true)\n try {\n const fallback: TroubleshootingGuidesResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<TroubleshootingGuidesResponse>(\n `/api/warranty_claims/troubleshooting-guides?${listQueryString}`,\n undefined,\n { fallback },\n )\n if (!call.ok) {\n const message = call.result?.error ?? t('warranty_claims.troubleshootingGuides.list.error.load', 'Failed to load troubleshooting guides.')\n flash(message, 'error')\n return\n }\n if (cancelled) return\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n setRows(items.map(normalizeTroubleshootingGuide).filter((row): row is TroubleshootingGuideRecord => row !== null))\n setTotal(typeof call.result?.total === 'number' ? call.result.total : items.length)\n setTotalPages(typeof call.result?.totalPages === 'number' ? call.result.totalPages : 1)\n setTotalIsCapped(call.result?.totalIsCapped === true)\n } catch (error) {\n if (!cancelled) {\n const message = error instanceof Error\n ? error.message\n : t('warranty_claims.troubleshootingGuides.list.error.load', 'Failed to load troubleshooting guides.')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setLoading(false)\n }\n }\n void loadGuides()\n return () => {\n cancelled = true\n }\n }, [listQueryString, reloadToken, scopeVersion, t])\n\n React.useEffect(() => {\n const controller = new AbortController()\n const segments: Array<readonly [GuideSegment, Record<string, string>]> = [\n ['all', {}],\n ['published', { isActive: 'true' }],\n ['draft', { isActive: 'false' }],\n ]\n Promise.all(segments.map(async ([segment, query]) => {\n const params = new URLSearchParams({ page: '1', pageSize: '1', ...query })\n const fallback: TroubleshootingGuidesResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<TroubleshootingGuidesResponse>(\n `/api/warranty_claims/troubleshooting-guides?${params.toString()}`,\n { signal: controller.signal },\n { fallback },\n )\n if (!call.ok) throw new Error('[internal] Failed to load guide counts')\n return [segment, typeof call.result?.total === 'number' ? call.result.total : 0] as const\n }))\n .then((entries) => {\n if (!controller.signal.aborted) setTabCounts(Object.fromEntries(entries))\n })\n .catch(() => {\n if (!controller.signal.aborted) setTabCounts({})\n })\n return () => controller.abort()\n }, [reloadToken, scopeVersion])\n\n const executeDelete = React.useCallback(async (guide: TroubleshootingGuideRecord): Promise<unknown> => {\n try {\n await runMutation({\n operation: () => withScopedApiRequestHeaders(\n buildOptimisticLockHeader(guide.updatedAt),\n () => deleteCrud('warranty_claims/troubleshooting-guides', guide.id, {\n errorMessage: t('warranty_claims.troubleshootingGuides.list.error.delete', 'Failed to delete troubleshooting guide.'),\n }),\n ),\n mutationPayload: { id: guide.id },\n context: {\n formId: mutationContextId,\n resourceKind: 'warranty_claims.warranty_troubleshooting_guide',\n resourceId: guide.id,\n retryLastMutation,\n },\n })\n return null\n } catch (error) {\n return error\n }\n }, [mutationContextId, retryLastMutation, runMutation, t])\n\n const handleDelete = React.useCallback(async (guide: TroubleshootingGuideRecord) => {\n const confirmed = await confirm({\n title: t('warranty_claims.troubleshootingGuides.confirm.deleteTitle', 'Delete this troubleshooting guide?'),\n variant: 'destructive',\n })\n if (!confirmed) return\n const error = await executeDelete(guide)\n if (error) {\n if (surfaceRecordConflict(error, t, { onRefresh: reload })) return\n flash(\n error instanceof Error\n ? error.message\n : t('warranty_claims.troubleshootingGuides.list.error.delete', 'Failed to delete troubleshooting guide.'),\n 'error',\n )\n return\n }\n flash(t('warranty_claims.troubleshootingGuides.list.success.delete', 'Troubleshooting guide deleted.'), 'success')\n reload()\n }, [confirm, executeDelete, reload, t])\n\n const handleBulkDelete = React.useCallback(async (selectedRows: TroubleshootingGuideRecord[]) => {\n const { succeeded, failures } = await runBulkDelete(\n selectedRows,\n async (guide) => {\n const error = await executeDelete(guide)\n if (error) throw error\n },\n {\n fallbackErrorMessage: t('warranty_claims.troubleshootingGuides.list.error.delete', 'Failed to delete troubleshooting guide.'),\n logTag: 'warranty_claims.troubleshooting_guides.list',\n progress: {\n jobType: 'warranty_claims.troubleshooting_guides.bulk_delete',\n name: t('warranty_claims.troubleshootingGuides.bulk.delete', 'Delete selected'),\n },\n },\n )\n const summary = t(\n 'warranty_claims.bulk.summary',\n 'Bulk action finished: {succeeded} succeeded, {failed} failed.',\n { succeeded: succeeded.length, failed: failures.length },\n )\n if (failures.length) {\n flash(`${summary} ${t('warranty_claims.bulk.firstError', 'First error: {message}', { message: failures[0].message })}`, 'warning')\n } else {\n flash(summary, 'success')\n }\n reload()\n return { ok: true as const, affectedCount: succeeded.length }\n }, [executeDelete, reload, t])\n\n const bulkActions = React.useMemo<BulkAction<TroubleshootingGuideRecord>[]>(() => [\n {\n id: 'bulk-delete',\n label: t('warranty_claims.troubleshootingGuides.bulk.delete', 'Delete selected'),\n destructive: true,\n onExecute: async (selectedRows) => {\n if (!selectedRows.length) return false\n const confirmed = await confirm({\n title: t('warranty_claims.troubleshootingGuides.bulk.deleteTitle', 'Delete selected troubleshooting guides?'),\n variant: 'destructive',\n })\n if (!confirmed) return false\n return handleBulkDelete(selectedRows)\n },\n },\n ], [confirm, handleBulkDelete, t])\n\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'claimType',\n label: t('warranty_claims.troubleshootingGuides.list.filter.claimType', 'Claim type'),\n type: 'select',\n options: CLAIM_TYPES.map((value) => ({ value, label: claimTypeLabel(value, t) })),\n },\n {\n id: 'isActive',\n label: t('warranty_claims.troubleshootingGuides.list.filter.status', 'Status'),\n type: 'select',\n options: [\n { value: 'true', label: t('warranty_claims.troubleshootingGuides.status.active', 'Active') },\n { value: 'false', label: t('warranty_claims.troubleshootingGuides.status.inactive', 'Inactive') },\n ],\n },\n ], [t])\n\n const columns = React.useMemo<ColumnDef<TroubleshootingGuideRecord>[]>(() => [\n {\n accessorKey: 'title',\n header: t('warranty_claims.troubleshootingGuides.list.column.title', 'Title'),\n meta: { alwaysVisible: true, truncate: true, maxWidth: '280px' },\n cell: ({ row }) => (\n <Link\n href={`/backend/warranty_claims/troubleshooting-guides/${row.original.id}/edit`}\n className=\"font-medium hover:underline\"\n >\n {row.original.title ?? t('warranty_claims.troubleshootingGuides.list.untitled', 'Untitled guide')}\n </Link>\n ),\n },\n {\n accessorKey: 'claimType',\n header: t('warranty_claims.troubleshootingGuides.list.column.claimType', 'Claim type'),\n cell: ({ row }) => (\n <span className=\"text-sm text-muted-foreground\">\n {claimTypeLabel(row.original.claimType, t)}\n </span>\n ),\n },\n {\n accessorKey: 'reasonCode',\n header: t('warranty_claims.troubleshootingGuides.list.column.reason', 'Reason'),\n meta: { truncate: true, maxWidth: '220px' },\n cell: ({ row }) => (\n <span className=\"text-sm text-foreground\">\n {reasonLabel(row.original.reasonCode, t, reasonLabels)}\n </span>\n ),\n },\n {\n id: 'steps',\n header: t('warranty_claims.troubleshootingGuides.list.column.steps', 'Steps'),\n meta: { maxWidth: '100px' },\n cell: ({ row }) => <span className=\"text-sm text-muted-foreground\">{countGuideSteps(row.original.steps)}</span>,\n },\n {\n accessorKey: 'isActive',\n header: t('warranty_claims.troubleshootingGuides.list.column.active', 'Status'),\n cell: ({ row }) => (\n <StatusBadge variant={row.original.isActive ? 'success' : 'neutral'}>\n {activeLabel(row.original.isActive, t)}\n </StatusBadge>\n ),\n },\n {\n accessorKey: 'updatedAt',\n header: t('warranty_claims.troubleshootingGuides.list.column.updated', 'Updated'),\n cell: ({ row }) => (\n <span className=\"text-sm text-muted-foreground\" title={formatDateTime(row.original.updatedAt) ?? undefined}>\n {formatRelativeTime(row.original.updatedAt, { locale }) ?? t('warranty_claims.common.noValue', 'Not set')}\n </span>\n ),\n },\n ], [reasonLabels, locale, t])\n\n const activeTab = toFilterString(filterValues.isActive) === 'true'\n ? 'published'\n : toFilterString(filterValues.isActive) === 'false'\n ? 'draft'\n : 'all'\n\n const handleTabChange = React.useCallback((value: string) => {\n if (value === 'published') setFilterValues({ isActive: 'true' })\n else if (value === 'draft') setFilterValues({ isActive: 'false' })\n else setFilterValues({})\n setPage(1)\n }, [])\n\n return (\n <Page>\n <PageBody>\n <WarrantyWorkspace\n title={t('warranty_claims.troubleshootingGuides.list.title', 'Troubleshooting guides')}\n action={(\n <Button asChild>\n <Link href=\"/backend/warranty_claims/troubleshooting-guides/create\">\n <Plus className=\"size-4\" aria-hidden />\n {t('warranty_claims.troubleshootingGuides.list.actions.new', 'New guide')}\n </Link>\n </Button>\n )}\n contentClassName=\"[&>[data-component-handle]>div:first-child]:px-8 [&>[data-component-handle]>div:first-child]:py-4 [&_:has(>[data-slot=search-input-wrapper])]:lg:w-56\"\n activeTab={activeTab}\n onTabChange={handleTabChange}\n tabs={[\n { id: 'all', label: t('warranty_claims.troubleshootingGuides.list.tabs.all', 'All'), count: tabCounts.all },\n { id: 'published', label: t('warranty_claims.troubleshootingGuides.list.tabs.published', 'Published'), count: tabCounts.published },\n { id: 'draft', label: t('warranty_claims.troubleshootingGuides.list.tabs.draft', 'Draft'), count: tabCounts.draft },\n ]}\n >\n <DataTable<TroubleshootingGuideRecord>\n embedded\n stickyFirstColumn\n stickyActionsColumn\n refreshButton={{\n label: t('warranty_claims.troubleshootingGuides.list.actions.refresh', 'Refresh'),\n onRefresh: reload,\n isRefreshing: loading,\n }}\n columns={columns}\n data={rows}\n exporter={exportConfig}\n searchValue={search}\n onSearchChange={(value) => {\n setSearch(value)\n setPage(1)\n }}\n searchPlaceholder={t('warranty_claims.troubleshootingGuides.list.searchPlaceholder', 'Search guides\u2026')}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={(values) => {\n setFilterValues(values)\n setPage(1)\n }}\n onFiltersClear={() => {\n setFilterValues({})\n setPage(1)\n }}\n perspective={{ tableId: extensionPoints.hosts.troubleshootingGuidesTable.tableId }}\n onRowClick={(row) => router.push(`/backend/warranty_claims/troubleshooting-guides/${row.id}/edit`)}\n isLoading={loading}\n bulkActions={bulkActions}\n rowActions={(row) => (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('warranty_claims.troubleshootingGuides.list.actions.edit', 'Edit'),\n onSelect: () => router.push(`/backend/warranty_claims/troubleshooting-guides/${row.id}/edit`),\n },\n {\n id: 'delete',\n label: t('warranty_claims.troubleshootingGuides.list.actions.delete', 'Delete'),\n destructive: true,\n onSelect: () => {\n void handleDelete(row)\n },\n },\n ]}\n />\n )}\n emptyState={(\n <ListEmptyState\n title={t('warranty_claims.troubleshootingGuides.list.empty.title', 'No troubleshooting guides yet')}\n description={t('warranty_claims.troubleshootingGuides.list.empty.description', 'Create a guide to offer guided decisions during claim intake and triage.')}\n createHref=\"/backend/warranty_claims/troubleshooting-guides/create\"\n createLabel={t('warranty_claims.troubleshootingGuides.list.actions.new', 'New guide')}\n />\n )}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n totalIsCapped,\n onPageChange: setPage,\n }}\n />\n </WarrantyWorkspace>\n {ConfirmDialogElement}\n </PageBody>\n </Page>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -57,6 +57,7 @@ function WarrantyVendorPoliciesPage() {
|
|
|
57
57
|
const [page, setPage] = React.useState(1);
|
|
58
58
|
const [total, setTotal] = React.useState(0);
|
|
59
59
|
const [totalPages, setTotalPages] = React.useState(1);
|
|
60
|
+
const [totalIsCapped, setTotalIsCapped] = React.useState(false);
|
|
60
61
|
const [tabCounts, setTabCounts] = React.useState({});
|
|
61
62
|
const [search, setSearch] = React.useState("");
|
|
62
63
|
const [filterValues, setFilterValues] = React.useState({});
|
|
@@ -129,6 +130,7 @@ function WarrantyVendorPoliciesPage() {
|
|
|
129
130
|
setRows(items.map(normalizeVendorPolicy).filter((row) => row !== null));
|
|
130
131
|
setTotal(typeof call.result?.total === "number" ? call.result.total : items.length);
|
|
131
132
|
setTotalPages(typeof call.result?.totalPages === "number" ? call.result.totalPages : 1);
|
|
133
|
+
setTotalIsCapped(call.result?.totalIsCapped === true);
|
|
132
134
|
} catch (error) {
|
|
133
135
|
if (!cancelled) {
|
|
134
136
|
const message = error instanceof Error ? error.message : t("warranty_claims.vendorPolicies.list.error.load", "Failed to load vendor policies.");
|
|
@@ -414,6 +416,7 @@ function WarrantyVendorPoliciesPage() {
|
|
|
414
416
|
pageSize: PAGE_SIZE,
|
|
415
417
|
total,
|
|
416
418
|
totalPages,
|
|
419
|
+
totalIsCapped,
|
|
417
420
|
onPageChange: setPage
|
|
418
421
|
}
|
|
419
422
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, type BulkAction, type DataTableExportFormat } from '@open-mercato/ui/backend/DataTable'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { ListEmptyState } from '@open-mercato/ui/backend/filters/ListEmptyState'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { StatusBadge } from '@open-mercato/ui/primitives/status-badge'\nimport { apiCall, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { runBulkDelete } from '@open-mercato/ui/backend/utils/bulkDelete'\nimport { buildCrudExportUrl, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { localizeDictionaryLabel } from '../../../lib/dictionaryLabels'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT, type TranslateFn } from '@open-mercato/shared/lib/i18n/context'\nimport { Plus } from 'lucide-react'\nimport { normalizeVendorPolicy, type VendorPolicyRecord } from './vendorPolicyForm'\nimport { fetchClaimReasonOptions } from '../../components/claimReasonOptions'\nimport { WarrantyWorkspace } from '../../components/WarrantyWorkspace'\nimport { extensionPoints } from '../../../extension-points'\nimport { vendorPolicySegmentQuery, type VendorPolicySegment } from '../../../lib/listSegments'\n\ntype VendorPoliciesResponse = {\n items?: unknown[]\n total?: number\n totalPages?: number\n error?: string\n}\n\nconst PAGE_SIZE = 20\n\nfunction formatCoverageMonths(value: number | null, t: TranslateFn): string {\n if (value === null) return t('warranty_claims.common.noValue', 'Not set')\n return t('warranty_claims.vendorPolicies.list.months', '{count} months', { count: value })\n}\n\nfunction formatReasonCodes(value: string[] | null, t: TranslateFn, storedLabels: Record<string, string>): string {\n if (!value?.length) return t('warranty_claims.vendorPolicies.list.anyReason', 'Any reason')\n return value.map((code) => localizeDictionaryLabel(t, 'reason', code, storedLabels[code] ?? code)).join(', ')\n}\n\nfunction formatRecoveryRate(value: string | null, t: TranslateFn): string {\n if (!value) return t('warranty_claims.common.noValue', 'Not set')\n return `${value}%`\n}\n\nfunction activeLabel(value: boolean, t: TranslateFn): string {\n return value\n ? t('warranty_claims.vendorPolicies.status.active', 'Active')\n : t('warranty_claims.vendorPolicies.status.inactive', 'Inactive')\n}\n\nfunction autoLabel(value: boolean, t: TranslateFn): string {\n return value\n ? t('warranty_claims.vendorPolicies.status.auto', 'Automatic')\n : t('warranty_claims.vendorPolicies.status.manual', 'Manual')\n}\n\nfunction toFilterString(value: unknown): string | null {\n return typeof value === 'string' && value.trim().length ? value.trim() : null\n}\n\nexport default function WarrantyVendorPoliciesPage() {\n const t = useT()\n const router = useRouter()\n const scopeVersion = useOrganizationScopeVersion()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const [rows, setRows] = React.useState<VendorPolicyRecord[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [tabCounts, setTabCounts] = React.useState<Partial<Record<VendorPolicySegment, number>>>({})\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [loading, setLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [reasonLabels, setReasonLabels] = React.useState<Record<string, string>>({})\n\n React.useEffect(() => {\n let cancelled = false\n void fetchClaimReasonOptions(t)\n .then((options) => {\n if (cancelled) return\n setReasonLabels(Object.fromEntries(options.map((option) => [option.value, option.label])))\n })\n .catch(() => {})\n return () => { cancelled = true }\n }, [t])\n\n const mutationContextId = 'warranty-claim-vendor-policies-list'\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n resourceId?: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: mutationContextId,\n blockedMessage: t('warranty_claims.vendorPolicies.list.error.blocked', 'Save blocked by validation.'),\n })\n\n const reload = React.useCallback(() => {\n setReloadToken((current) => current + 1)\n }, [])\n\n const listQueryString = React.useMemo(() => {\n const params = new URLSearchParams({\n page: String(page),\n pageSize: String(PAGE_SIZE),\n sortField: 'updatedAt',\n sortDir: 'desc',\n })\n if (search.trim()) params.set('search', search.trim())\n const isActive = toFilterString(filterValues.isActive)\n const autoGenerateRecovery = toFilterString(filterValues.autoGenerateRecovery)\n if (isActive) params.set('isActive', isActive)\n if (autoGenerateRecovery) params.set('autoGenerateRecovery', autoGenerateRecovery)\n return params.toString()\n }, [filterValues.autoGenerateRecovery, filterValues.isActive, page, search])\n\n const currentParams = React.useMemo(\n () => Object.fromEntries(new URLSearchParams(listQueryString)),\n [listQueryString],\n )\n\n const exportConfig = React.useMemo(() => ({\n view: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('warranty_claims/vendor-policies', { ...currentParams, exportScope: 'view' }, format),\n },\n full: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('warranty_claims/vendor-policies', { ...currentParams, exportScope: 'full', all: 'true' }, format),\n },\n }), [currentParams])\n\n React.useEffect(() => {\n let cancelled = false\n async function loadPolicies() {\n setLoading(true)\n try {\n const fallback: VendorPoliciesResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<VendorPoliciesResponse>(\n `/api/warranty_claims/vendor-policies?${listQueryString}`,\n undefined,\n { fallback },\n )\n if (!call.ok) {\n const message = call.result?.error ?? t('warranty_claims.vendorPolicies.list.error.load', 'Failed to load vendor policies.')\n flash(message, 'error')\n return\n }\n if (cancelled) return\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n setRows(items.map(normalizeVendorPolicy).filter((row): row is VendorPolicyRecord => row !== null))\n setTotal(typeof call.result?.total === 'number' ? call.result.total : items.length)\n setTotalPages(typeof call.result?.totalPages === 'number' ? call.result.totalPages : 1)\n } catch (error) {\n if (!cancelled) {\n const message = error instanceof Error\n ? error.message\n : t('warranty_claims.vendorPolicies.list.error.load', 'Failed to load vendor policies.')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setLoading(false)\n }\n }\n void loadPolicies()\n return () => {\n cancelled = true\n }\n }, [listQueryString, reloadToken, scopeVersion, t])\n\n React.useEffect(() => {\n const controller = new AbortController()\n const segments: VendorPolicySegment[] = ['all', 'active', 'automatic', 'manual', 'inactive']\n Promise.all(segments.map(async (segment) => {\n const params = new URLSearchParams({ page: '1', pageSize: '1', ...vendorPolicySegmentQuery(segment) })\n const fallback: VendorPoliciesResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<VendorPoliciesResponse>(\n `/api/warranty_claims/vendor-policies?${params.toString()}`,\n { signal: controller.signal },\n { fallback },\n )\n if (!call.ok) throw new Error('[internal] Failed to load vendor policy counts')\n return [segment, typeof call.result?.total === 'number' ? call.result.total : 0] as const\n }))\n .then((entries) => {\n if (!controller.signal.aborted) setTabCounts(Object.fromEntries(entries))\n })\n .catch(() => {\n if (!controller.signal.aborted) setTabCounts({})\n })\n return () => controller.abort()\n }, [reloadToken, scopeVersion])\n\n const executeDelete = React.useCallback(async (policy: VendorPolicyRecord): Promise<unknown> => {\n try {\n await runMutation({\n operation: async () => {\n const call = await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(policy.updatedAt),\n () => deleteCrud('warranty_claims/vendor-policies', policy.id, {\n errorMessage: t('warranty_claims.vendorPolicies.list.error.delete', 'Failed to delete vendor policy.'),\n }),\n )\n return call\n },\n mutationPayload: { id: policy.id },\n context: {\n formId: mutationContextId,\n resourceKind: 'warranty_claims.warranty_vendor_policy',\n resourceId: policy.id,\n retryLastMutation,\n },\n })\n return null\n } catch (error) {\n return error\n }\n }, [mutationContextId, retryLastMutation, runMutation, t])\n\n const handleDelete = React.useCallback(async (policy: VendorPolicyRecord) => {\n const confirmed = await confirm({\n title: t('warranty_claims.vendorPolicies.confirm.deleteTitle', 'Delete this vendor policy?'),\n variant: 'destructive',\n })\n if (!confirmed) return\n const error = await executeDelete(policy)\n if (error) {\n if (surfaceRecordConflict(error, t, { onRefresh: reload })) return\n flash(\n error instanceof Error\n ? error.message\n : t('warranty_claims.vendorPolicies.list.error.delete', 'Failed to delete vendor policy.'),\n 'error',\n )\n return\n }\n flash(t('warranty_claims.vendorPolicies.list.success.delete', 'Vendor policy deleted.'), 'success')\n reload()\n }, [confirm, executeDelete, reload, t])\n\n const handleBulkDelete = React.useCallback(async (selectedRows: VendorPolicyRecord[]) => {\n const { succeeded, failures } = await runBulkDelete(\n selectedRows,\n async (policy) => {\n const error = await executeDelete(policy)\n if (error) throw error\n },\n {\n fallbackErrorMessage: t('warranty_claims.vendorPolicies.list.error.delete', 'Failed to delete vendor policy.'),\n logTag: 'warranty_claims.vendor_policies.list',\n progress: {\n jobType: 'warranty_claims.vendor_policies.bulk_delete',\n name: t('warranty_claims.vendorPolicies.bulk.delete', 'Delete selected'),\n },\n },\n )\n const summary = t(\n 'warranty_claims.bulk.summary',\n 'Bulk action finished: {succeeded} succeeded, {failed} failed.',\n { succeeded: succeeded.length, failed: failures.length },\n )\n if (failures.length) {\n flash(`${summary} ${t('warranty_claims.bulk.firstError', 'First error: {message}', { message: failures[0].message })}`, 'warning')\n } else {\n flash(summary, 'success')\n }\n reload()\n return { ok: true as const, affectedCount: succeeded.length }\n }, [executeDelete, reload, t])\n\n const bulkActions = React.useMemo<BulkAction<VendorPolicyRecord>[]>(() => [\n {\n id: 'bulk-delete',\n label: t('warranty_claims.vendorPolicies.bulk.delete', 'Delete selected'),\n destructive: true,\n onExecute: async (selectedRows) => {\n if (!selectedRows.length) return false\n const confirmed = await confirm({\n title: t('warranty_claims.vendorPolicies.bulk.deleteTitle', 'Delete selected vendor policies?'),\n variant: 'destructive',\n })\n if (!confirmed) return false\n return handleBulkDelete(selectedRows)\n },\n },\n ], [confirm, handleBulkDelete, t])\n\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'isActive',\n label: t('warranty_claims.vendorPolicies.list.filter.status', 'Status'),\n type: 'select',\n options: [\n { value: 'true', label: t('warranty_claims.vendorPolicies.status.active', 'Active') },\n { value: 'false', label: t('warranty_claims.vendorPolicies.status.inactive', 'Inactive') },\n ],\n },\n {\n id: 'autoGenerateRecovery',\n label: t('warranty_claims.vendorPolicies.list.filter.mode', 'Recovery mode'),\n type: 'select',\n options: [\n { value: 'true', label: t('warranty_claims.vendorPolicies.status.auto', 'Automatic') },\n { value: 'false', label: t('warranty_claims.vendorPolicies.status.manual', 'Manual') },\n ],\n },\n ], [t])\n\n const columns = React.useMemo<ColumnDef<VendorPolicyRecord>[]>(() => {\n const noValue = <span className=\"text-sm text-muted-foreground\">{t('warranty_claims.common.noValue', 'Not set')}</span>\n return [\n {\n accessorKey: 'vendorName',\n header: t('warranty_claims.vendorPolicies.list.column.vendor', 'Vendor'),\n meta: { alwaysVisible: true, truncate: true, maxWidth: '240px' },\n cell: ({ row }) => (\n <Link\n href={`/backend/warranty_claims/vendor-policies/${row.original.id}/edit`}\n className=\"font-medium hover:underline\"\n >\n {row.original.vendorName ?? t('warranty_claims.vendorPolicies.list.unnamed', 'Untitled policy')}\n </Link>\n ),\n },\n {\n accessorKey: 'vendorRef',\n header: t('warranty_claims.vendorPolicies.list.column.vendorRef', 'Reference'),\n meta: { truncate: true, maxWidth: '180px' },\n cell: ({ row }) => row.original.vendorRef ? <span>{row.original.vendorRef}</span> : noValue,\n },\n {\n accessorKey: 'coverageMonths',\n header: t('warranty_claims.vendorPolicies.list.column.coverageMonths', 'Coverage'),\n cell: ({ row }) => (\n <span className=\"text-sm text-muted-foreground\">\n {formatCoverageMonths(row.original.coverageMonths, t)}\n </span>\n ),\n },\n {\n accessorKey: 'claimableReasonCodes',\n header: t('warranty_claims.vendorPolicies.list.column.reasons', 'Reasons'),\n meta: { truncate: true, maxWidth: '260px' },\n cell: ({ row }) => (\n <span className=\"text-sm text-muted-foreground\">\n {formatReasonCodes(row.original.claimableReasonCodes, t, reasonLabels)}\n </span>\n ),\n },\n {\n accessorKey: 'recoveryRatePct',\n header: t('warranty_claims.vendorPolicies.list.column.recoveryRate', 'Recovery'),\n cell: ({ row }) => (\n <span className=\"text-sm font-semibold text-foreground\">\n {formatRecoveryRate(row.original.recoveryRatePct, t)}\n </span>\n ),\n },\n {\n accessorKey: 'autoGenerateRecovery',\n header: t('warranty_claims.vendorPolicies.list.column.auto', 'Mode'),\n cell: ({ row }) => (\n <span className={row.original.autoGenerateRecovery ? 'text-sm text-status-warning-text' : 'text-sm text-muted-foreground'}>\n {autoLabel(row.original.autoGenerateRecovery, t)}\n </span>\n ),\n },\n {\n accessorKey: 'isActive',\n header: t('warranty_claims.vendorPolicies.list.column.active', 'Status'),\n cell: ({ row }) => (\n <StatusBadge variant={row.original.isActive ? 'success' : 'neutral'}>\n {activeLabel(row.original.isActive, t)}\n </StatusBadge>\n ),\n },\n ]\n }, [reasonLabels, t])\n\n const activeTab = toFilterString(filterValues.autoGenerateRecovery) === 'true'\n ? 'automatic'\n : toFilterString(filterValues.autoGenerateRecovery) === 'false'\n ? 'manual'\n : toFilterString(filterValues.isActive) === 'true'\n ? 'active'\n : toFilterString(filterValues.isActive) === 'false'\n ? 'inactive'\n : 'all'\n\n const handleTabChange = React.useCallback((value: string) => {\n const segment: VendorPolicySegment = value === 'active' || value === 'inactive' || value === 'automatic' || value === 'manual'\n ? value\n : 'all'\n setFilterValues(vendorPolicySegmentQuery(segment))\n setPage(1)\n }, [])\n\n return (\n <Page>\n <PageBody>\n <WarrantyWorkspace\n title={t('warranty_claims.vendorPolicies.list.title', 'Vendor policies')}\n action={(\n <Button asChild>\n <Link href=\"/backend/warranty_claims/vendor-policies/create\">\n <Plus className=\"size-4\" aria-hidden />\n {t('warranty_claims.vendorPolicies.list.actions.add', 'Add policy')}\n </Link>\n </Button>\n )}\n contentClassName=\"[&>[data-component-handle]>div:first-child]:px-8 [&>[data-component-handle]>div:first-child]:py-4 [&_:has(>[data-slot=search-input-wrapper])]:lg:w-56\"\n activeTab={activeTab}\n onTabChange={handleTabChange}\n tabs={[\n { id: 'all', label: t('warranty_claims.vendorPolicies.list.tabs.all', 'All'), count: tabCounts.all },\n { id: 'active', label: t('warranty_claims.vendorPolicies.list.tabs.active', 'Active'), count: tabCounts.active },\n { id: 'automatic', label: t('warranty_claims.vendorPolicies.list.tabs.automatic', 'Automatic'), count: tabCounts.automatic },\n { id: 'manual', label: t('warranty_claims.vendorPolicies.list.tabs.manual', 'Manual'), count: tabCounts.manual },\n { id: 'inactive', label: t('warranty_claims.vendorPolicies.list.tabs.inactive', 'Inactive'), count: tabCounts.inactive },\n ]}\n >\n <DataTable<VendorPolicyRecord>\n embedded\n stickyFirstColumn\n stickyActionsColumn\n refreshButton={{\n label: t('warranty_claims.vendorPolicies.list.actions.refresh', 'Refresh'),\n onRefresh: reload,\n isRefreshing: loading,\n }}\n columns={columns}\n data={rows}\n exporter={exportConfig}\n searchValue={search}\n onSearchChange={(value) => {\n setSearch(value)\n setPage(1)\n }}\n searchPlaceholder={t('warranty_claims.vendorPolicies.list.searchPlaceholder', 'Search vendor or reference')}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={(values) => {\n setFilterValues(values)\n setPage(1)\n }}\n onFiltersClear={() => {\n setFilterValues({})\n setPage(1)\n }}\n perspective={{ tableId: extensionPoints.hosts.vendorPoliciesTable.tableId }}\n onRowClick={(row) => router.push(`/backend/warranty_claims/vendor-policies/${row.id}/edit`)}\n isLoading={loading}\n bulkActions={bulkActions}\n rowActions={(row) => (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('warranty_claims.vendorPolicies.list.actions.edit', 'Edit'),\n onSelect: () => router.push(`/backend/warranty_claims/vendor-policies/${row.id}/edit`),\n },\n {\n id: 'delete',\n label: t('warranty_claims.vendorPolicies.list.actions.delete', 'Delete'),\n destructive: true,\n onSelect: () => {\n void handleDelete(row)\n },\n },\n ]}\n />\n )}\n emptyState={(\n <ListEmptyState\n title={t('warranty_claims.vendorPolicies.list.empty.title', 'No vendor policies yet')}\n description={t('warranty_claims.vendorPolicies.list.empty.description', 'Create policies to suggest or automate supplier recovery for resolved claim lines.')}\n createHref=\"/backend/warranty_claims/vendor-policies/create\"\n createLabel={t('warranty_claims.vendorPolicies.list.actions.new', 'New vendor policy')}\n />\n )}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n onPageChange: setPage,\n }}\n />\n </WarrantyWorkspace>\n {ConfirmDialogElement}\n </PageBody>\n </Page>\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, type BulkAction, type DataTableExportFormat } from '@open-mercato/ui/backend/DataTable'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { ListEmptyState } from '@open-mercato/ui/backend/filters/ListEmptyState'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { StatusBadge } from '@open-mercato/ui/primitives/status-badge'\nimport { apiCall, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { runBulkDelete } from '@open-mercato/ui/backend/utils/bulkDelete'\nimport { buildCrudExportUrl, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { localizeDictionaryLabel } from '../../../lib/dictionaryLabels'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT, type TranslateFn } from '@open-mercato/shared/lib/i18n/context'\nimport { Plus } from 'lucide-react'\nimport { normalizeVendorPolicy, type VendorPolicyRecord } from './vendorPolicyForm'\nimport { fetchClaimReasonOptions } from '../../components/claimReasonOptions'\nimport { WarrantyWorkspace } from '../../components/WarrantyWorkspace'\nimport { extensionPoints } from '../../../extension-points'\nimport { vendorPolicySegmentQuery, type VendorPolicySegment } from '../../../lib/listSegments'\n\ntype VendorPoliciesResponse = {\n items?: unknown[]\n total?: number\n totalPages?: number\n totalIsCapped?: boolean\n error?: string\n}\n\nconst PAGE_SIZE = 20\n\nfunction formatCoverageMonths(value: number | null, t: TranslateFn): string {\n if (value === null) return t('warranty_claims.common.noValue', 'Not set')\n return t('warranty_claims.vendorPolicies.list.months', '{count} months', { count: value })\n}\n\nfunction formatReasonCodes(value: string[] | null, t: TranslateFn, storedLabels: Record<string, string>): string {\n if (!value?.length) return t('warranty_claims.vendorPolicies.list.anyReason', 'Any reason')\n return value.map((code) => localizeDictionaryLabel(t, 'reason', code, storedLabels[code] ?? code)).join(', ')\n}\n\nfunction formatRecoveryRate(value: string | null, t: TranslateFn): string {\n if (!value) return t('warranty_claims.common.noValue', 'Not set')\n return `${value}%`\n}\n\nfunction activeLabel(value: boolean, t: TranslateFn): string {\n return value\n ? t('warranty_claims.vendorPolicies.status.active', 'Active')\n : t('warranty_claims.vendorPolicies.status.inactive', 'Inactive')\n}\n\nfunction autoLabel(value: boolean, t: TranslateFn): string {\n return value\n ? t('warranty_claims.vendorPolicies.status.auto', 'Automatic')\n : t('warranty_claims.vendorPolicies.status.manual', 'Manual')\n}\n\nfunction toFilterString(value: unknown): string | null {\n return typeof value === 'string' && value.trim().length ? value.trim() : null\n}\n\nexport default function WarrantyVendorPoliciesPage() {\n const t = useT()\n const router = useRouter()\n const scopeVersion = useOrganizationScopeVersion()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const [rows, setRows] = React.useState<VendorPolicyRecord[]>([])\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 [tabCounts, setTabCounts] = React.useState<Partial<Record<VendorPolicySegment, number>>>({})\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [loading, setLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [reasonLabels, setReasonLabels] = React.useState<Record<string, string>>({})\n\n React.useEffect(() => {\n let cancelled = false\n void fetchClaimReasonOptions(t)\n .then((options) => {\n if (cancelled) return\n setReasonLabels(Object.fromEntries(options.map((option) => [option.value, option.label])))\n })\n .catch(() => {})\n return () => { cancelled = true }\n }, [t])\n\n const mutationContextId = 'warranty-claim-vendor-policies-list'\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n resourceId?: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: mutationContextId,\n blockedMessage: t('warranty_claims.vendorPolicies.list.error.blocked', 'Save blocked by validation.'),\n })\n\n const reload = React.useCallback(() => {\n setReloadToken((current) => current + 1)\n }, [])\n\n const listQueryString = React.useMemo(() => {\n const params = new URLSearchParams({\n page: String(page),\n pageSize: String(PAGE_SIZE),\n sortField: 'updatedAt',\n sortDir: 'desc',\n })\n if (search.trim()) params.set('search', search.trim())\n const isActive = toFilterString(filterValues.isActive)\n const autoGenerateRecovery = toFilterString(filterValues.autoGenerateRecovery)\n if (isActive) params.set('isActive', isActive)\n if (autoGenerateRecovery) params.set('autoGenerateRecovery', autoGenerateRecovery)\n return params.toString()\n }, [filterValues.autoGenerateRecovery, filterValues.isActive, page, search])\n\n const currentParams = React.useMemo(\n () => Object.fromEntries(new URLSearchParams(listQueryString)),\n [listQueryString],\n )\n\n const exportConfig = React.useMemo(() => ({\n view: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('warranty_claims/vendor-policies', { ...currentParams, exportScope: 'view' }, format),\n },\n full: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('warranty_claims/vendor-policies', { ...currentParams, exportScope: 'full', all: 'true' }, format),\n },\n }), [currentParams])\n\n React.useEffect(() => {\n let cancelled = false\n async function loadPolicies() {\n setLoading(true)\n try {\n const fallback: VendorPoliciesResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<VendorPoliciesResponse>(\n `/api/warranty_claims/vendor-policies?${listQueryString}`,\n undefined,\n { fallback },\n )\n if (!call.ok) {\n const message = call.result?.error ?? t('warranty_claims.vendorPolicies.list.error.load', 'Failed to load vendor policies.')\n flash(message, 'error')\n return\n }\n if (cancelled) return\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n setRows(items.map(normalizeVendorPolicy).filter((row): row is VendorPolicyRecord => row !== null))\n setTotal(typeof call.result?.total === 'number' ? call.result.total : items.length)\n setTotalPages(typeof call.result?.totalPages === 'number' ? call.result.totalPages : 1)\n setTotalIsCapped(call.result?.totalIsCapped === true)\n } catch (error) {\n if (!cancelled) {\n const message = error instanceof Error\n ? error.message\n : t('warranty_claims.vendorPolicies.list.error.load', 'Failed to load vendor policies.')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setLoading(false)\n }\n }\n void loadPolicies()\n return () => {\n cancelled = true\n }\n }, [listQueryString, reloadToken, scopeVersion, t])\n\n React.useEffect(() => {\n const controller = new AbortController()\n const segments: VendorPolicySegment[] = ['all', 'active', 'automatic', 'manual', 'inactive']\n Promise.all(segments.map(async (segment) => {\n const params = new URLSearchParams({ page: '1', pageSize: '1', ...vendorPolicySegmentQuery(segment) })\n const fallback: VendorPoliciesResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<VendorPoliciesResponse>(\n `/api/warranty_claims/vendor-policies?${params.toString()}`,\n { signal: controller.signal },\n { fallback },\n )\n if (!call.ok) throw new Error('[internal] Failed to load vendor policy counts')\n return [segment, typeof call.result?.total === 'number' ? call.result.total : 0] as const\n }))\n .then((entries) => {\n if (!controller.signal.aborted) setTabCounts(Object.fromEntries(entries))\n })\n .catch(() => {\n if (!controller.signal.aborted) setTabCounts({})\n })\n return () => controller.abort()\n }, [reloadToken, scopeVersion])\n\n const executeDelete = React.useCallback(async (policy: VendorPolicyRecord): Promise<unknown> => {\n try {\n await runMutation({\n operation: async () => {\n const call = await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(policy.updatedAt),\n () => deleteCrud('warranty_claims/vendor-policies', policy.id, {\n errorMessage: t('warranty_claims.vendorPolicies.list.error.delete', 'Failed to delete vendor policy.'),\n }),\n )\n return call\n },\n mutationPayload: { id: policy.id },\n context: {\n formId: mutationContextId,\n resourceKind: 'warranty_claims.warranty_vendor_policy',\n resourceId: policy.id,\n retryLastMutation,\n },\n })\n return null\n } catch (error) {\n return error\n }\n }, [mutationContextId, retryLastMutation, runMutation, t])\n\n const handleDelete = React.useCallback(async (policy: VendorPolicyRecord) => {\n const confirmed = await confirm({\n title: t('warranty_claims.vendorPolicies.confirm.deleteTitle', 'Delete this vendor policy?'),\n variant: 'destructive',\n })\n if (!confirmed) return\n const error = await executeDelete(policy)\n if (error) {\n if (surfaceRecordConflict(error, t, { onRefresh: reload })) return\n flash(\n error instanceof Error\n ? error.message\n : t('warranty_claims.vendorPolicies.list.error.delete', 'Failed to delete vendor policy.'),\n 'error',\n )\n return\n }\n flash(t('warranty_claims.vendorPolicies.list.success.delete', 'Vendor policy deleted.'), 'success')\n reload()\n }, [confirm, executeDelete, reload, t])\n\n const handleBulkDelete = React.useCallback(async (selectedRows: VendorPolicyRecord[]) => {\n const { succeeded, failures } = await runBulkDelete(\n selectedRows,\n async (policy) => {\n const error = await executeDelete(policy)\n if (error) throw error\n },\n {\n fallbackErrorMessage: t('warranty_claims.vendorPolicies.list.error.delete', 'Failed to delete vendor policy.'),\n logTag: 'warranty_claims.vendor_policies.list',\n progress: {\n jobType: 'warranty_claims.vendor_policies.bulk_delete',\n name: t('warranty_claims.vendorPolicies.bulk.delete', 'Delete selected'),\n },\n },\n )\n const summary = t(\n 'warranty_claims.bulk.summary',\n 'Bulk action finished: {succeeded} succeeded, {failed} failed.',\n { succeeded: succeeded.length, failed: failures.length },\n )\n if (failures.length) {\n flash(`${summary} ${t('warranty_claims.bulk.firstError', 'First error: {message}', { message: failures[0].message })}`, 'warning')\n } else {\n flash(summary, 'success')\n }\n reload()\n return { ok: true as const, affectedCount: succeeded.length }\n }, [executeDelete, reload, t])\n\n const bulkActions = React.useMemo<BulkAction<VendorPolicyRecord>[]>(() => [\n {\n id: 'bulk-delete',\n label: t('warranty_claims.vendorPolicies.bulk.delete', 'Delete selected'),\n destructive: true,\n onExecute: async (selectedRows) => {\n if (!selectedRows.length) return false\n const confirmed = await confirm({\n title: t('warranty_claims.vendorPolicies.bulk.deleteTitle', 'Delete selected vendor policies?'),\n variant: 'destructive',\n })\n if (!confirmed) return false\n return handleBulkDelete(selectedRows)\n },\n },\n ], [confirm, handleBulkDelete, t])\n\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'isActive',\n label: t('warranty_claims.vendorPolicies.list.filter.status', 'Status'),\n type: 'select',\n options: [\n { value: 'true', label: t('warranty_claims.vendorPolicies.status.active', 'Active') },\n { value: 'false', label: t('warranty_claims.vendorPolicies.status.inactive', 'Inactive') },\n ],\n },\n {\n id: 'autoGenerateRecovery',\n label: t('warranty_claims.vendorPolicies.list.filter.mode', 'Recovery mode'),\n type: 'select',\n options: [\n { value: 'true', label: t('warranty_claims.vendorPolicies.status.auto', 'Automatic') },\n { value: 'false', label: t('warranty_claims.vendorPolicies.status.manual', 'Manual') },\n ],\n },\n ], [t])\n\n const columns = React.useMemo<ColumnDef<VendorPolicyRecord>[]>(() => {\n const noValue = <span className=\"text-sm text-muted-foreground\">{t('warranty_claims.common.noValue', 'Not set')}</span>\n return [\n {\n accessorKey: 'vendorName',\n header: t('warranty_claims.vendorPolicies.list.column.vendor', 'Vendor'),\n meta: { alwaysVisible: true, truncate: true, maxWidth: '240px' },\n cell: ({ row }) => (\n <Link\n href={`/backend/warranty_claims/vendor-policies/${row.original.id}/edit`}\n className=\"font-medium hover:underline\"\n >\n {row.original.vendorName ?? t('warranty_claims.vendorPolicies.list.unnamed', 'Untitled policy')}\n </Link>\n ),\n },\n {\n accessorKey: 'vendorRef',\n header: t('warranty_claims.vendorPolicies.list.column.vendorRef', 'Reference'),\n meta: { truncate: true, maxWidth: '180px' },\n cell: ({ row }) => row.original.vendorRef ? <span>{row.original.vendorRef}</span> : noValue,\n },\n {\n accessorKey: 'coverageMonths',\n header: t('warranty_claims.vendorPolicies.list.column.coverageMonths', 'Coverage'),\n cell: ({ row }) => (\n <span className=\"text-sm text-muted-foreground\">\n {formatCoverageMonths(row.original.coverageMonths, t)}\n </span>\n ),\n },\n {\n accessorKey: 'claimableReasonCodes',\n header: t('warranty_claims.vendorPolicies.list.column.reasons', 'Reasons'),\n meta: { truncate: true, maxWidth: '260px' },\n cell: ({ row }) => (\n <span className=\"text-sm text-muted-foreground\">\n {formatReasonCodes(row.original.claimableReasonCodes, t, reasonLabels)}\n </span>\n ),\n },\n {\n accessorKey: 'recoveryRatePct',\n header: t('warranty_claims.vendorPolicies.list.column.recoveryRate', 'Recovery'),\n cell: ({ row }) => (\n <span className=\"text-sm font-semibold text-foreground\">\n {formatRecoveryRate(row.original.recoveryRatePct, t)}\n </span>\n ),\n },\n {\n accessorKey: 'autoGenerateRecovery',\n header: t('warranty_claims.vendorPolicies.list.column.auto', 'Mode'),\n cell: ({ row }) => (\n <span className={row.original.autoGenerateRecovery ? 'text-sm text-status-warning-text' : 'text-sm text-muted-foreground'}>\n {autoLabel(row.original.autoGenerateRecovery, t)}\n </span>\n ),\n },\n {\n accessorKey: 'isActive',\n header: t('warranty_claims.vendorPolicies.list.column.active', 'Status'),\n cell: ({ row }) => (\n <StatusBadge variant={row.original.isActive ? 'success' : 'neutral'}>\n {activeLabel(row.original.isActive, t)}\n </StatusBadge>\n ),\n },\n ]\n }, [reasonLabels, t])\n\n const activeTab = toFilterString(filterValues.autoGenerateRecovery) === 'true'\n ? 'automatic'\n : toFilterString(filterValues.autoGenerateRecovery) === 'false'\n ? 'manual'\n : toFilterString(filterValues.isActive) === 'true'\n ? 'active'\n : toFilterString(filterValues.isActive) === 'false'\n ? 'inactive'\n : 'all'\n\n const handleTabChange = React.useCallback((value: string) => {\n const segment: VendorPolicySegment = value === 'active' || value === 'inactive' || value === 'automatic' || value === 'manual'\n ? value\n : 'all'\n setFilterValues(vendorPolicySegmentQuery(segment))\n setPage(1)\n }, [])\n\n return (\n <Page>\n <PageBody>\n <WarrantyWorkspace\n title={t('warranty_claims.vendorPolicies.list.title', 'Vendor policies')}\n action={(\n <Button asChild>\n <Link href=\"/backend/warranty_claims/vendor-policies/create\">\n <Plus className=\"size-4\" aria-hidden />\n {t('warranty_claims.vendorPolicies.list.actions.add', 'Add policy')}\n </Link>\n </Button>\n )}\n contentClassName=\"[&>[data-component-handle]>div:first-child]:px-8 [&>[data-component-handle]>div:first-child]:py-4 [&_:has(>[data-slot=search-input-wrapper])]:lg:w-56\"\n activeTab={activeTab}\n onTabChange={handleTabChange}\n tabs={[\n { id: 'all', label: t('warranty_claims.vendorPolicies.list.tabs.all', 'All'), count: tabCounts.all },\n { id: 'active', label: t('warranty_claims.vendorPolicies.list.tabs.active', 'Active'), count: tabCounts.active },\n { id: 'automatic', label: t('warranty_claims.vendorPolicies.list.tabs.automatic', 'Automatic'), count: tabCounts.automatic },\n { id: 'manual', label: t('warranty_claims.vendorPolicies.list.tabs.manual', 'Manual'), count: tabCounts.manual },\n { id: 'inactive', label: t('warranty_claims.vendorPolicies.list.tabs.inactive', 'Inactive'), count: tabCounts.inactive },\n ]}\n >\n <DataTable<VendorPolicyRecord>\n embedded\n stickyFirstColumn\n stickyActionsColumn\n refreshButton={{\n label: t('warranty_claims.vendorPolicies.list.actions.refresh', 'Refresh'),\n onRefresh: reload,\n isRefreshing: loading,\n }}\n columns={columns}\n data={rows}\n exporter={exportConfig}\n searchValue={search}\n onSearchChange={(value) => {\n setSearch(value)\n setPage(1)\n }}\n searchPlaceholder={t('warranty_claims.vendorPolicies.list.searchPlaceholder', 'Search vendor or reference')}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={(values) => {\n setFilterValues(values)\n setPage(1)\n }}\n onFiltersClear={() => {\n setFilterValues({})\n setPage(1)\n }}\n perspective={{ tableId: extensionPoints.hosts.vendorPoliciesTable.tableId }}\n onRowClick={(row) => router.push(`/backend/warranty_claims/vendor-policies/${row.id}/edit`)}\n isLoading={loading}\n bulkActions={bulkActions}\n rowActions={(row) => (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('warranty_claims.vendorPolicies.list.actions.edit', 'Edit'),\n onSelect: () => router.push(`/backend/warranty_claims/vendor-policies/${row.id}/edit`),\n },\n {\n id: 'delete',\n label: t('warranty_claims.vendorPolicies.list.actions.delete', 'Delete'),\n destructive: true,\n onSelect: () => {\n void handleDelete(row)\n },\n },\n ]}\n />\n )}\n emptyState={(\n <ListEmptyState\n title={t('warranty_claims.vendorPolicies.list.empty.title', 'No vendor policies yet')}\n description={t('warranty_claims.vendorPolicies.list.empty.description', 'Create policies to suggest or automate supplier recovery for resolved claim lines.')}\n createHref=\"/backend/warranty_claims/vendor-policies/create\"\n createLabel={t('warranty_claims.vendorPolicies.list.actions.new', 'New vendor policy')}\n />\n )}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n totalIsCapped,\n onPageChange: setPage,\n }}\n />\n </WarrantyWorkspace>\n {ConfirmDialogElement}\n </PageBody>\n </Page>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|