@open-mercato/core 0.6.5-develop.4534.1.b459babe6d → 0.6.5-develop.4559.1.839e136509
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/AGENTS.md +5 -0
- package/dist/generated/entities/role/index.js +3 -1
- package/dist/generated/entities/role/index.js.map +2 -2
- package/dist/generated/entities/user/index.js +3 -1
- package/dist/generated/entities/user/index.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +2 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/helpers/integration/communicationChannelsFixtures.js.map +2 -2
- package/dist/helpers/integration/dbFixtures.js +2 -1
- package/dist/helpers/integration/dbFixtures.js.map +2 -2
- package/dist/helpers/integration/optimisticLockUi.js +104 -0
- package/dist/helpers/integration/optimisticLockUi.js.map +7 -0
- package/dist/helpers/integration/salesFixtures.js +17 -0
- package/dist/helpers/integration/salesFixtures.js.map +2 -2
- package/dist/modules/api_keys/backend/api-keys/page.js +9 -5
- package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js +17 -9
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js.map +2 -2
- package/dist/modules/auth/api/roles/acl/route.js +32 -13
- package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
- package/dist/modules/auth/api/roles/route.js +3 -1
- package/dist/modules/auth/api/roles/route.js.map +2 -2
- package/dist/modules/auth/api/sidebar/preferences/route.js +71 -3
- package/dist/modules/auth/api/sidebar/preferences/route.js.map +2 -2
- package/dist/modules/auth/api/users/acl/route.js +42 -19
- package/dist/modules/auth/api/users/acl/route.js.map +2 -2
- package/dist/modules/auth/api/users/route.js +3 -1
- package/dist/modules/auth/api/users/route.js.map +2 -2
- package/dist/modules/auth/backend/roles/[id]/edit/page.js +24 -4
- package/dist/modules/auth/backend/roles/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/backend/roles/page.js +8 -4
- package/dist/modules/auth/backend/roles/page.js.map +2 -2
- package/dist/modules/auth/backend/users/[id]/edit/page.js +27 -5
- package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/backend/users/page.js +6 -2
- package/dist/modules/auth/backend/users/page.js.map +2 -2
- package/dist/modules/auth/components/AclEditor.js +3 -1
- package/dist/modules/auth/components/AclEditor.js.map +2 -2
- package/dist/modules/auth/data/entities.js +6 -0
- package/dist/modules/auth/data/entities.js.map +2 -2
- package/dist/modules/auth/services/sidebarPreferencesService.js +32 -4
- package/dist/modules/auth/services/sidebarPreferencesService.js.map +2 -2
- package/dist/modules/business_rules/api/rules/route.js +28 -0
- package/dist/modules/business_rules/api/rules/route.js.map +2 -2
- package/dist/modules/business_rules/api/sets/route.js +28 -0
- package/dist/modules/business_rules/api/sets/route.js.map +2 -2
- package/dist/modules/business_rules/backend/rules/[id]/page.js +11 -4
- package/dist/modules/business_rules/backend/rules/[id]/page.js.map +3 -3
- package/dist/modules/business_rules/backend/rules/page.js +20 -11
- package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
- package/dist/modules/business_rules/backend/sets/[id]/page.js +11 -4
- package/dist/modules/business_rules/backend/sets/[id]/page.js.map +2 -2
- package/dist/modules/business_rules/backend/sets/page.js +20 -11
- package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
- package/dist/modules/catalog/api/categories/route.js +2 -0
- package/dist/modules/catalog/api/categories/route.js.map +2 -2
- package/dist/modules/catalog/api/products/route.js +2 -1
- package/dist/modules/catalog/api/products/route.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js +2 -0
- package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js +94 -40
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js +37 -8
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/optionSchemaClient.js.map +2 -2
- package/dist/modules/catalog/commands/variants.js +32 -31
- package/dist/modules/catalog/commands/variants.js.map +2 -2
- package/dist/modules/catalog/components/PriceKindSettings.js +12 -5
- package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductMediaManager.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductsDataTable.js +5 -3
- package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
- package/dist/modules/catalog/components/products/productForm.js.map +2 -2
- package/dist/modules/catalog/components/products/variantForm.js +2 -1
- package/dist/modules/catalog/components/products/variantForm.js.map +2 -2
- package/dist/modules/communication_channels/api/post/test-seed/route.js +23 -2
- package/dist/modules/communication_channels/api/post/test-seed/route.js.map +2 -2
- package/dist/modules/communication_channels/backend/profile/communication-channels/page.js +5 -0
- package/dist/modules/communication_channels/backend/profile/communication-channels/page.js.map +2 -2
- package/dist/modules/communication_channels/commands/set-primary-channel.js +2 -1
- package/dist/modules/communication_channels/commands/set-primary-channel.js.map +2 -2
- package/dist/modules/currencies/backend/currencies/[id]/page.js +6 -3
- package/dist/modules/currencies/backend/currencies/[id]/page.js.map +2 -2
- package/dist/modules/currencies/backend/currencies/page.js +18 -11
- package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
- package/dist/modules/currencies/backend/exchange-rates/[id]/page.js +1 -0
- package/dist/modules/currencies/backend/exchange-rates/[id]/page.js.map +2 -2
- package/dist/modules/currencies/backend/exchange-rates/page.js +10 -6
- package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
- package/dist/modules/currencies/commands/currencies.js +7 -5
- package/dist/modules/currencies/commands/currencies.js.map +2 -2
- package/dist/modules/currencies/components/CurrencyFetchingConfig.js +26 -19
- package/dist/modules/currencies/components/CurrencyFetchingConfig.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/roles/[id].js +28 -5
- package/dist/modules/customer_accounts/api/admin/roles/[id].js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/roles.js +4 -2
- package/dist/modules/customer_accounts/api/admin/roles.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/users/[id].js +28 -5
- package/dist/modules/customer_accounts/api/admin/users/[id].js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/users.js +2 -0
- package/dist/modules/customer_accounts/api/admin/users.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js +16 -8
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +8 -4
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js +8 -4
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +29 -18
- package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +18 -11
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
- package/dist/modules/customers/api/companies/route.js +13 -2
- package/dist/modules/customers/api/companies/route.js.map +2 -2
- package/dist/modules/customers/api/deals/route.js +2 -0
- package/dist/modules/customers/api/deals/route.js.map +2 -2
- package/dist/modules/customers/api/people/route.js +11 -2
- package/dist/modules/customers/api/people/route.js.map +2 -2
- package/dist/modules/customers/api/todos/route.js +1 -0
- package/dist/modules/customers/api/todos/route.js.map +2 -2
- package/dist/modules/customers/backend/config/customers/deals/page.js.map +2 -2
- package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js +34 -21
- package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/[id]/page.js +45 -27
- package/dist/modules/customers/backend/customers/companies/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +22 -5
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js +30 -8
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +1 -0
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/page.js +16 -6
- package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/page.js +62 -39
- package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/[id]/page.js +41 -26
- package/dist/modules/customers/backend/customers/people/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +50 -23
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/commands/addresses.js +16 -14
- package/dist/modules/customers/commands/addresses.js.map +2 -2
- package/dist/modules/customers/commands/companies.js +1 -1
- package/dist/modules/customers/commands/companies.js.map +2 -2
- package/dist/modules/customers/commands/interactions.js +41 -4
- package/dist/modules/customers/commands/interactions.js.map +2 -2
- package/dist/modules/customers/commands/people.js +1 -1
- package/dist/modules/customers/commands/people.js.map +2 -2
- package/dist/modules/customers/commands/personCompanyLinks.js +8 -5
- package/dist/modules/customers/commands/personCompanyLinks.js.map +2 -2
- package/dist/modules/customers/commands/pipeline-stages.js +13 -11
- package/dist/modules/customers/commands/pipeline-stages.js.map +3 -3
- package/dist/modules/customers/components/AddressFormatSettings.js.map +2 -2
- package/dist/modules/customers/components/DictionarySettings.js +20 -13
- package/dist/modules/customers/components/DictionarySettings.js.map +2 -2
- package/dist/modules/customers/components/DictionarySortSettings.js +4 -0
- package/dist/modules/customers/components/DictionarySortSettings.js.map +2 -2
- package/dist/modules/customers/components/PipelineSettings.js +38 -23
- package/dist/modules/customers/components/PipelineSettings.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivityTimeline.js +1 -1
- package/dist/modules/customers/components/detail/ActivityTimeline.js.map +2 -2
- package/dist/modules/customers/components/detail/AddressesSection.js +4 -0
- package/dist/modules/customers/components/detail/AddressesSection.js.map +2 -2
- package/dist/modules/customers/components/detail/CompanyPeopleSection.js +28 -22
- package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
- package/dist/modules/customers/components/detail/DealsSection.js +36 -24
- package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
- package/dist/modules/customers/components/detail/EmailCardActions.js +5 -0
- package/dist/modules/customers/components/detail/EmailCardActions.js.map +2 -2
- package/dist/modules/customers/components/detail/EntityTagsDialog.js +7 -0
- package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/ManageTagsDialog.js +34 -22
- package/dist/modules/customers/components/detail/ManageTagsDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/PersonCompaniesSection.js +41 -29
- package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +2 -2
- package/dist/modules/customers/components/detail/RoleAssignmentRow.js +14 -8
- package/dist/modules/customers/components/detail/RoleAssignmentRow.js.map +2 -2
- package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +14 -6
- package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js +29 -13
- package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js.map +2 -2
- package/dist/modules/customers/components/detail/hooks/useInteractions.js +77 -35
- package/dist/modules/customers/components/detail/hooks/useInteractions.js.map +2 -2
- package/dist/modules/customers/components/detail/hooks/usePersonTasks.js +25 -17
- package/dist/modules/customers/components/detail/hooks/usePersonTasks.js.map +2 -2
- package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +2 -2
- package/dist/modules/customers/components/formConfig.js.map +2 -2
- package/dist/modules/customers/data/guards.js +66 -0
- package/dist/modules/customers/data/guards.js.map +7 -0
- package/dist/modules/customers/di.js +37 -0
- package/dist/modules/customers/di.js.map +2 -2
- package/dist/modules/customers/lib/todoCompatibility.js +11 -0
- package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +2 -2
- package/dist/modules/data_sync/api/options.js +4 -4
- package/dist/modules/data_sync/api/options.js.map +2 -2
- package/dist/modules/data_sync/api/schedules/route.js +9 -1
- package/dist/modules/data_sync/api/schedules/route.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/page.js +17 -8
- package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
- package/dist/modules/data_sync/components/IntegrationScheduleTab.js +43 -22
- package/dist/modules/data_sync/components/IntegrationScheduleTab.js.map +2 -2
- package/dist/modules/data_sync/lib/sync-schedule-service.js +9 -0
- package/dist/modules/data_sync/lib/sync-schedule-service.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +8 -1
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/route.js +17 -1
- package/dist/modules/dictionaries/api/[dictionaryId]/route.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionariesManager.js +31 -10
- package/dist/modules/dictionaries/components/DictionariesManager.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js +28 -15
- package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js.map +2 -2
- package/dist/modules/directory/api/organizations/route.js +3 -0
- package/dist/modules/directory/api/organizations/route.js.map +2 -2
- package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js +2 -0
- package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/organizations/page.js +9 -5
- package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js +7 -3
- package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/tenants/page.js +8 -4
- package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
- package/dist/modules/directory/commands/organizations.js +7 -2
- package/dist/modules/directory/commands/organizations.js.map +2 -2
- package/dist/modules/entities/api/records.js +66 -0
- package/dist/modules/entities/api/records.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js +1 -0
- package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +8 -4
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
- package/dist/modules/entities/lib/helpers.js +17 -0
- package/dist/modules/entities/lib/helpers.js.map +2 -2
- package/dist/modules/feature_toggles/api/global/[id]/override/route.js +2 -1
- package/dist/modules/feature_toggles/api/global/[id]/override/route.js.map +2 -2
- package/dist/modules/feature_toggles/api/overrides/route.js +15 -0
- package/dist/modules/feature_toggles/api/overrides/route.js.map +2 -2
- package/dist/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.js +15 -14
- package/dist/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.js.map +2 -2
- package/dist/modules/feature_toggles/components/FeatureToggleOverrideCard.js +20 -12
- package/dist/modules/feature_toggles/components/FeatureToggleOverrideCard.js.map +2 -2
- package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +6 -2
- package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
- package/dist/modules/feature_toggles/components/formConfig.js +2 -1
- package/dist/modules/feature_toggles/components/formConfig.js.map +2 -2
- package/dist/modules/feature_toggles/components/overrideFormConfig.js +5 -1
- package/dist/modules/feature_toggles/components/overrideFormConfig.js.map +2 -2
- package/dist/modules/feature_toggles/data/validators.js +7 -4
- package/dist/modules/feature_toggles/data/validators.js.map +2 -2
- package/dist/modules/inbox_ops/api/settings/route.js +17 -2
- package/dist/modules/inbox_ops/api/settings/route.js.map +2 -2
- package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js +13 -8
- package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js.map +2 -2
- package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js +9 -4
- package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +18 -11
- package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/page.js +12 -8
- package/dist/modules/integrations/backend/integrations/page.js.map +2 -2
- package/dist/modules/messages/commands/messages.js +13 -10
- package/dist/modules/messages/commands/messages.js.map +2 -2
- package/dist/modules/perspectives/api/[tableId]/route.js +39 -30
- package/dist/modules/perspectives/api/[tableId]/route.js.map +2 -2
- package/dist/modules/perspectives/services/perspectiveService.js +7 -0
- package/dist/modules/perspectives/services/perspectiveService.js.map +2 -2
- package/dist/modules/planner/backend/planner/availability-rulesets/[id]/page.js +6 -14
- package/dist/modules/planner/backend/planner/availability-rulesets/[id]/page.js.map +3 -3
- package/dist/modules/planner/backend/planner/availability-rulesets/page.js +4 -2
- package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
- package/dist/modules/planner/components/AvailabilityRuleSetForm.js +2 -0
- package/dist/modules/planner/components/AvailabilityRuleSetForm.js.map +2 -2
- package/dist/modules/planner/components/AvailabilityRulesEditor.js +36 -11
- package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
- package/dist/modules/planner/components/AvailabilitySchedule.js +9 -5
- package/dist/modules/planner/components/AvailabilitySchedule.js.map +2 -2
- package/dist/modules/query_index/lib/engine.js +19 -0
- package/dist/modules/query_index/lib/engine.js.map +2 -2
- package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js +1 -0
- package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resource-types/page.js +4 -2
- package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/[id]/page.js +14 -3
- package/dist/modules/resources/backend/resources/resources/[id]/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/page.js +8 -4
- package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
- package/dist/modules/resources/components/ResourceCrudForm.js +2 -0
- package/dist/modules/resources/components/ResourceCrudForm.js.map +2 -2
- package/dist/modules/resources/components/ResourceTypeCrudForm.js +1 -0
- package/dist/modules/resources/components/ResourceTypeCrudForm.js.map +2 -2
- package/dist/modules/sales/api/documents/factory.js +7 -2
- package/dist/modules/sales/api/documents/factory.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js +3 -1
- package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/offers/page.js +13 -4
- package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/page.js +16 -4
- package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +68 -22
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/documents/create/page.js.map +2 -2
- package/dist/modules/sales/commands/documentAddresses.js +181 -2
- package/dist/modules/sales/commands/documentAddresses.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +29 -1
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/commands/returns.js +12 -2
- package/dist/modules/sales/commands/returns.js.map +2 -2
- package/dist/modules/sales/commands/shared.js +15 -0
- package/dist/modules/sales/commands/shared.js.map +2 -2
- package/dist/modules/sales/commands/shipments.js +4 -1
- package/dist/modules/sales/commands/shipments.js.map +2 -2
- package/dist/modules/sales/components/AdjustmentKindSettings.js +19 -11
- package/dist/modules/sales/components/AdjustmentKindSettings.js.map +2 -2
- package/dist/modules/sales/components/DocumentNumberSettings.js.map +2 -2
- package/dist/modules/sales/components/OrderEditingSettings.js.map +2 -2
- package/dist/modules/sales/components/PaymentMethodsSettings.js +12 -4
- package/dist/modules/sales/components/PaymentMethodsSettings.js.map +2 -2
- package/dist/modules/sales/components/ShippingMethodsSettings.js +12 -4
- package/dist/modules/sales/components/ShippingMethodsSettings.js.map +2 -2
- package/dist/modules/sales/components/StatusSettings.js +18 -11
- package/dist/modules/sales/components/StatusSettings.js.map +2 -2
- package/dist/modules/sales/components/TaxRatesSettings.js +12 -4
- package/dist/modules/sales/components/TaxRatesSettings.js.map +2 -2
- package/dist/modules/sales/components/channels/ChannelOfferForm.js +47 -16
- package/dist/modules/sales/components/channels/ChannelOfferForm.js.map +2 -2
- package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +8 -4
- package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
- package/dist/modules/sales/components/documents/AddressesSection.js +44 -25
- package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
- package/dist/modules/sales/components/documents/AdjustmentsSection.js +43 -23
- package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/ItemsSection.js +22 -13
- package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/LineItemDialog.js +23 -10
- package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/PaymentDialog.js +29 -14
- package/dist/modules/sales/components/documents/PaymentDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/PaymentsSection.js +20 -10
- package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/ReturnDialog.js +26 -17
- package/dist/modules/sales/components/documents/ReturnDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/ReturnsSection.js +3 -1
- package/dist/modules/sales/components/documents/ReturnsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js +10 -5
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
- package/dist/modules/sales/components/documents/ShipmentDialog.js +21 -7
- package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/ShipmentsSection.js +19 -10
- package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/optimisticLock.js +27 -0
- package/dist/modules/sales/components/documents/optimisticLock.js.map +7 -0
- package/dist/modules/sales/di.js +18 -0
- package/dist/modules/sales/di.js.map +2 -2
- package/dist/modules/staff/api/job-histories.js +11 -2
- package/dist/modules/staff/api/job-histories.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-entries/route.js +11 -4
- package/dist/modules/staff/api/timesheets/time-entries/route.js.map +2 -2
- package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js +13 -8
- package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js +2 -1
- package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js +7 -4
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/page.js +4 -2
- package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js +1 -0
- package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-roles/page.js +4 -2
- package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +5 -2
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/page.js +12 -3
- package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/page.js +4 -1
- package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/page.js +12 -3
- package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
- package/dist/modules/staff/commands/job-histories.js +40 -3
- package/dist/modules/staff/commands/job-histories.js.map +2 -2
- package/dist/modules/staff/components/LeaveRequestForm.js +1 -0
- package/dist/modules/staff/components/LeaveRequestForm.js.map +2 -2
- package/dist/modules/staff/components/TeamForm.js +1 -0
- package/dist/modules/staff/components/TeamForm.js.map +2 -2
- package/dist/modules/staff/components/TeamMemberForm.js +1 -0
- package/dist/modules/staff/components/TeamMemberForm.js.map +2 -2
- package/dist/modules/staff/components/TeamRoleForm.js +1 -0
- package/dist/modules/staff/components/TeamRoleForm.js.map +2 -2
- package/dist/modules/staff/components/detail/JobHistorySection.js +20 -7
- package/dist/modules/staff/components/detail/JobHistorySection.js.map +2 -2
- package/dist/modules/staff/data/validators.js +7 -1
- package/dist/modules/staff/data/validators.js.map +2 -2
- package/dist/modules/staff/lib/leaveRequestHelpers.js +2 -1
- package/dist/modules/staff/lib/leaveRequestHelpers.js.map +2 -2
- package/dist/modules/translations/components/TranslationManager.js +12 -8
- package/dist/modules/translations/components/TranslationManager.js.map +2 -2
- package/dist/modules/workflows/api/definitions/[id]/route.js +106 -0
- package/dist/modules/workflows/api/definitions/[id]/route.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/[id]/page.js +11 -3
- package/dist/modules/workflows/backend/definitions/[id]/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/page.js +19 -8
- package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js +29 -16
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
- package/dist/modules/workflows/components/formConfig.js +4 -1
- package/dist/modules/workflows/components/formConfig.js.map +2 -2
- package/dist/modules/workflows/di.js +12 -0
- package/dist/modules/workflows/di.js.map +2 -2
- package/generated/entities/role/index.ts +1 -0
- package/generated/entities/user/index.ts +1 -0
- package/generated/entity-fields-registry.ts +2 -0
- package/jest.setup.ts +17 -0
- package/package.json +8 -7
- package/src/helpers/integration/communicationChannelsFixtures.ts +6 -0
- package/src/helpers/integration/dbFixtures.ts +1 -1
- package/src/helpers/integration/optimisticLockUi.ts +172 -0
- package/src/helpers/integration/salesFixtures.ts +29 -0
- package/src/modules/api_keys/backend/api-keys/page.tsx +10 -5
- package/src/modules/attachments/components/AttachmentPartitionSettings.tsx +19 -9
- package/src/modules/auth/api/roles/acl/route.ts +37 -11
- package/src/modules/auth/api/roles/route.ts +2 -0
- package/src/modules/auth/api/sidebar/preferences/route.ts +73 -0
- package/src/modules/auth/api/users/acl/route.ts +46 -18
- package/src/modules/auth/api/users/route.ts +2 -0
- package/src/modules/auth/backend/roles/[id]/edit/page.tsx +29 -4
- package/src/modules/auth/backend/roles/page.tsx +9 -4
- package/src/modules/auth/backend/users/[id]/edit/page.tsx +37 -4
- package/src/modules/auth/backend/users/page.tsx +7 -2
- package/src/modules/auth/components/AclEditor.tsx +10 -1
- package/src/modules/auth/data/entities.ts +7 -1
- package/src/modules/auth/services/sidebarPreferencesService.ts +38 -4
- package/src/modules/business_rules/api/rules/route.ts +30 -0
- package/src/modules/business_rules/api/sets/route.ts +30 -0
- package/src/modules/business_rules/backend/rules/[id]/page.tsx +16 -4
- package/src/modules/business_rules/backend/rules/page.tsx +20 -11
- package/src/modules/business_rules/backend/sets/[id]/page.tsx +16 -4
- package/src/modules/business_rules/backend/sets/page.tsx +20 -11
- package/src/modules/catalog/api/categories/route.ts +3 -0
- package/src/modules/catalog/api/products/route.ts +4 -0
- package/src/modules/catalog/backend/catalog/categories/[id]/edit/page.tsx +5 -0
- package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +112 -35
- package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx +56 -7
- package/src/modules/catalog/backend/catalog/products/optionSchemaClient.ts +2 -0
- package/src/modules/catalog/commands/variants.ts +32 -32
- package/src/modules/catalog/components/PriceKindSettings.tsx +20 -7
- package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +1 -0
- package/src/modules/catalog/components/products/ProductMediaManager.tsx +2 -0
- package/src/modules/catalog/components/products/ProductsDataTable.tsx +8 -4
- package/src/modules/catalog/components/products/productForm.ts +3 -0
- package/src/modules/catalog/components/products/variantForm.ts +9 -0
- package/src/modules/communication_channels/api/post/test-seed/route.ts +28 -1
- package/src/modules/communication_channels/backend/profile/communication-channels/page.tsx +5 -0
- package/src/modules/communication_channels/commands/set-primary-channel.ts +10 -7
- package/src/modules/currencies/backend/currencies/[id]/page.tsx +13 -6
- package/src/modules/currencies/backend/currencies/page.tsx +18 -11
- package/src/modules/currencies/backend/exchange-rates/[id]/page.tsx +3 -0
- package/src/modules/currencies/backend/exchange-rates/page.tsx +10 -6
- package/src/modules/currencies/commands/currencies.ts +10 -5
- package/src/modules/currencies/components/CurrencyFetchingConfig.tsx +31 -21
- package/src/modules/customer_accounts/api/admin/roles/[id].ts +35 -5
- package/src/modules/customer_accounts/api/admin/roles.ts +2 -0
- package/src/modules/customer_accounts/api/admin/users/[id].ts +38 -5
- package/src/modules/customer_accounts/api/admin/users.ts +2 -0
- package/src/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.tsx +34 -20
- package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +9 -4
- package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/page.tsx +11 -4
- package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +28 -17
- package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +19 -11
- package/src/modules/customers/AGENTS.md +2 -2
- package/src/modules/customers/api/companies/route.ts +14 -1
- package/src/modules/customers/api/deals/route.ts +3 -0
- package/src/modules/customers/api/people/route.ts +12 -1
- package/src/modules/customers/api/todos/route.ts +1 -0
- package/src/modules/customers/backend/config/customers/deals/page.tsx +1 -0
- package/src/modules/customers/backend/config/customers/pipeline-stages/page.tsx +36 -21
- package/src/modules/customers/backend/customers/companies/[id]/page.tsx +52 -27
- package/src/modules/customers/backend/customers/companies/page.tsx +2 -0
- package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +27 -5
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.ts +39 -7
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +1 -0
- package/src/modules/customers/backend/customers/deals/page.tsx +18 -6
- package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +64 -39
- package/src/modules/customers/backend/customers/people/[id]/page.tsx +46 -26
- package/src/modules/customers/backend/customers/people/page.tsx +2 -0
- package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +84 -24
- package/src/modules/customers/commands/addresses.ts +16 -14
- package/src/modules/customers/commands/companies.ts +3 -1
- package/src/modules/customers/commands/interactions.ts +50 -4
- package/src/modules/customers/commands/people.ts +2 -1
- package/src/modules/customers/commands/personCompanyLinks.ts +8 -5
- package/src/modules/customers/commands/pipeline-stages.ts +16 -16
- package/src/modules/customers/components/AddressFormatSettings.tsx +1 -0
- package/src/modules/customers/components/DictionarySettings.tsx +18 -13
- package/src/modules/customers/components/DictionarySortSettings.tsx +4 -0
- package/src/modules/customers/components/PipelineSettings.tsx +42 -21
- package/src/modules/customers/components/detail/ActivityTimeline.tsx +3 -3
- package/src/modules/customers/components/detail/AddressesSection.tsx +4 -0
- package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +2 -0
- package/src/modules/customers/components/detail/DealsSection.tsx +4 -0
- package/src/modules/customers/components/detail/EmailCardActions.tsx +5 -0
- package/src/modules/customers/components/detail/EntityTagsDialog.tsx +7 -0
- package/src/modules/customers/components/detail/ManageTagsDialog.tsx +4 -0
- package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +4 -0
- package/src/modules/customers/components/detail/RoleAssignmentRow.tsx +2 -0
- package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +23 -7
- package/src/modules/customers/components/detail/hooks/useInteractionMutations.ts +25 -15
- package/src/modules/customers/components/detail/hooks/useInteractions.ts +76 -35
- package/src/modules/customers/components/detail/hooks/usePersonTasks.ts +30 -17
- package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +2 -0
- package/src/modules/customers/components/detail/types.ts +1 -0
- package/src/modules/customers/components/formConfig.tsx +2 -0
- package/src/modules/customers/data/guards.ts +67 -0
- package/src/modules/customers/di.ts +66 -0
- package/src/modules/customers/i18n/de.json +2 -0
- package/src/modules/customers/i18n/en.json +2 -0
- package/src/modules/customers/i18n/es.json +2 -0
- package/src/modules/customers/i18n/pl.json +2 -0
- package/src/modules/customers/lib/todoCompatibility.ts +14 -0
- package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +2 -0
- package/src/modules/data_sync/api/options.ts +7 -4
- package/src/modules/data_sync/api/schedules/route.ts +9 -1
- package/src/modules/data_sync/backend/data-sync/page.tsx +18 -5
- package/src/modules/data_sync/components/IntegrationScheduleTab.tsx +46 -19
- package/src/modules/data_sync/lib/sync-schedule-service.ts +11 -0
- package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +8 -1
- package/src/modules/dictionaries/api/[dictionaryId]/route.ts +23 -0
- package/src/modules/dictionaries/components/DictionariesManager.tsx +32 -9
- package/src/modules/dictionaries/components/DictionaryEntriesEditor.tsx +30 -14
- package/src/modules/dictionaries/i18n/de.json +1 -0
- package/src/modules/dictionaries/i18n/en.json +1 -0
- package/src/modules/dictionaries/i18n/es.json +1 -0
- package/src/modules/dictionaries/i18n/pl.json +1 -0
- package/src/modules/directory/api/organizations/route.ts +3 -0
- package/src/modules/directory/backend/directory/organizations/[id]/edit/page.tsx +8 -0
- package/src/modules/directory/backend/directory/organizations/page.tsx +10 -5
- package/src/modules/directory/backend/directory/tenants/[id]/edit/page.tsx +16 -5
- package/src/modules/directory/backend/directory/tenants/page.tsx +8 -4
- package/src/modules/directory/commands/organizations.ts +7 -4
- package/src/modules/entities/api/records.ts +99 -0
- package/src/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.tsx +7 -0
- package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +8 -4
- package/src/modules/entities/lib/helpers.ts +17 -0
- package/src/modules/feature_toggles/api/global/[id]/override/route.ts +1 -0
- package/src/modules/feature_toggles/api/overrides/route.ts +19 -0
- package/src/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.tsx +19 -13
- package/src/modules/feature_toggles/components/FeatureToggleOverrideCard.tsx +22 -12
- package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +7 -2
- package/src/modules/feature_toggles/components/formConfig.tsx +2 -1
- package/src/modules/feature_toggles/components/overrideFormConfig.tsx +10 -1
- package/src/modules/feature_toggles/data/validators.ts +11 -3
- package/src/modules/inbox_ops/api/settings/route.ts +18 -0
- package/src/modules/inbox_ops/backend/inbox-ops/settings/page.tsx +15 -10
- package/src/modules/inbox_ops/components/proposals/EditActionDialog.tsx +9 -4
- package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +20 -11
- package/src/modules/integrations/backend/integrations/page.tsx +13 -8
- package/src/modules/messages/commands/messages.ts +27 -15
- package/src/modules/perspectives/api/[tableId]/route.ts +11 -2
- package/src/modules/perspectives/services/perspectiveService.ts +13 -1
- package/src/modules/planner/backend/planner/availability-rulesets/[id]/page.tsx +16 -14
- package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +6 -3
- package/src/modules/planner/components/AvailabilityRuleSetForm.tsx +3 -0
- package/src/modules/planner/components/AvailabilityRulesEditor.tsx +58 -15
- package/src/modules/planner/components/AvailabilitySchedule.tsx +22 -7
- package/src/modules/query_index/lib/engine.ts +34 -0
- package/src/modules/resources/backend/resources/resource-types/[id]/edit/page.tsx +7 -1
- package/src/modules/resources/backend/resources/resource-types/page.tsx +6 -3
- package/src/modules/resources/backend/resources/resources/[id]/page.tsx +23 -3
- package/src/modules/resources/backend/resources/resources/page.tsx +15 -4
- package/src/modules/resources/components/ResourceCrudForm.tsx +3 -0
- package/src/modules/resources/components/ResourceTypeCrudForm.tsx +2 -0
- package/src/modules/sales/api/documents/factory.ts +13 -1
- package/src/modules/sales/backend/sales/channels/[channelId]/edit/page.tsx +6 -0
- package/src/modules/sales/backend/sales/channels/offers/page.tsx +10 -4
- package/src/modules/sales/backend/sales/channels/page.tsx +19 -4
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +73 -20
- package/src/modules/sales/backend/sales/documents/create/page.tsx +2 -0
- package/src/modules/sales/commands/documentAddresses.ts +226 -4
- package/src/modules/sales/commands/documents.ts +28 -0
- package/src/modules/sales/commands/returns.ts +12 -3
- package/src/modules/sales/commands/shared.ts +36 -0
- package/src/modules/sales/commands/shipments.ts +17 -1
- package/src/modules/sales/components/AdjustmentKindSettings.tsx +20 -11
- package/src/modules/sales/components/DocumentNumberSettings.tsx +1 -0
- package/src/modules/sales/components/OrderEditingSettings.tsx +1 -0
- package/src/modules/sales/components/PaymentMethodsSettings.tsx +12 -4
- package/src/modules/sales/components/ShippingMethodsSettings.tsx +12 -4
- package/src/modules/sales/components/StatusSettings.tsx +20 -11
- package/src/modules/sales/components/TaxRatesSettings.tsx +12 -5
- package/src/modules/sales/components/channels/ChannelOfferForm.tsx +67 -14
- package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +7 -4
- package/src/modules/sales/components/documents/AddressesSection.tsx +35 -25
- package/src/modules/sales/components/documents/AdjustmentsSection.tsx +50 -25
- package/src/modules/sales/components/documents/ItemsSection.tsx +24 -13
- package/src/modules/sales/components/documents/LineItemDialog.tsx +26 -9
- package/src/modules/sales/components/documents/PaymentDialog.tsx +33 -14
- package/src/modules/sales/components/documents/PaymentsSection.tsx +22 -10
- package/src/modules/sales/components/documents/ReturnDialog.tsx +28 -17
- package/src/modules/sales/components/documents/ReturnsSection.tsx +4 -1
- package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +11 -4
- package/src/modules/sales/components/documents/ShipmentDialog.tsx +23 -8
- package/src/modules/sales/components/documents/ShipmentsSection.tsx +20 -10
- package/src/modules/sales/components/documents/optimisticLock.ts +34 -0
- package/src/modules/sales/components/documents/shipmentTypes.ts +1 -0
- package/src/modules/sales/di.ts +35 -0
- package/src/modules/sales/i18n/de.json +3 -0
- package/src/modules/sales/i18n/en.json +3 -0
- package/src/modules/sales/i18n/es.json +3 -0
- package/src/modules/sales/i18n/pl.json +3 -0
- package/src/modules/staff/api/job-histories.ts +12 -2
- package/src/modules/staff/api/timesheets/time-entries/route.ts +16 -4
- package/src/modules/staff/backend/staff/leave-requests/[id]/page.tsx +12 -7
- package/src/modules/staff/backend/staff/my-leave-requests/[id]/page.tsx +2 -0
- package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +16 -5
- package/src/modules/staff/backend/staff/team-members/page.tsx +6 -2
- package/src/modules/staff/backend/staff/team-roles/[id]/edit/page.tsx +8 -0
- package/src/modules/staff/backend/staff/team-roles/page.tsx +6 -2
- package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +13 -3
- package/src/modules/staff/backend/staff/teams/page.tsx +9 -3
- package/src/modules/staff/backend/staff/timesheets/page.tsx +10 -1
- package/src/modules/staff/backend/staff/timesheets/projects/[id]/page.tsx +4 -0
- package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +9 -3
- package/src/modules/staff/commands/job-histories.ts +42 -3
- package/src/modules/staff/components/LeaveRequestForm.tsx +2 -0
- package/src/modules/staff/components/TeamForm.tsx +2 -0
- package/src/modules/staff/components/TeamMemberForm.tsx +2 -0
- package/src/modules/staff/components/TeamRoleForm.tsx +2 -0
- package/src/modules/staff/components/detail/JobHistorySection.tsx +28 -6
- package/src/modules/staff/data/validators.ts +6 -0
- package/src/modules/staff/i18n/de.json +1 -0
- package/src/modules/staff/i18n/en.json +1 -0
- package/src/modules/staff/i18n/es.json +1 -0
- package/src/modules/staff/i18n/pl.json +1 -0
- package/src/modules/staff/lib/leaveRequestHelpers.ts +4 -0
- package/src/modules/translations/components/TranslationManager.tsx +13 -8
- package/src/modules/workflows/api/definitions/[id]/route.ts +112 -0
- package/src/modules/workflows/backend/definitions/[id]/page.tsx +20 -4
- package/src/modules/workflows/backend/definitions/page.tsx +20 -9
- package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +29 -16
- package/src/modules/workflows/components/formConfig.tsx +5 -0
- package/src/modules/workflows/di.ts +20 -0
- package/src/modules/workflows/i18n/de.json +1 -0
- package/src/modules/workflows/i18n/en.json +1 -0
- package/src/modules/workflows/i18n/es.json +1 -0
- package/src/modules/workflows/i18n/pl.json +1 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../../src/modules/staff/backend/staff/teams/%5Bid%5D/edit/page.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter, useSearchParams } from 'next/navigation'\nimport type { ColumnDef, SortingState } from '@tanstack/react-table'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { ErrorMessage, RecordNotFoundState } from '@open-mercato/ui/backend/detail'\nimport { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { DataTable, withDataTableNamespaces } from '@open-mercato/ui/backend/DataTable'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { BooleanIcon } from '@open-mercato/ui/backend/ValueIcons'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { TeamForm, type TeamFormValues, buildTeamPayload } from '@open-mercato/core/modules/staff/components/TeamForm'\nimport { SendObjectMessageDialog } from '@open-mercato/ui/backend/messages'\nimport { extractCustomFieldEntries } from '@open-mercato/shared/lib/crud/custom-fields-client'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { Plus } from 'lucide-react'\nimport { formatDateTime } from '@open-mercato/shared/lib/time'\n\nconst TEAM_MEMBERS_PAGE_SIZE = 50\n\ntype TeamRecord = {\n id: string\n name: string\n description?: string | null\n isActive?: boolean\n is_active?: boolean\n} & Record<string, unknown>\n\ntype TeamResponse = {\n items?: TeamRecord[]\n}\n\ntype TeamMemberRow = {\n id: string\n displayName: string\n description: string | null\n userEmail: string | null\n roleNames: string[]\n tags: string[]\n isActive: boolean\n updatedAt: string | null\n teamId: string | null\n}\n\ntype TeamMembersResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n totalPages?: number\n}\n\nexport default function StaffTeamEditPage({ params }: { params?: { id?: string } }) {\n const teamId = params?.id\n const t = useT()\n const router = useRouter()\n const searchParams = useSearchParams()\n const scopeVersion = useOrganizationScopeVersion()\n const [initialValues, setInitialValues] = React.useState<TeamFormValues | null>(null)\n const [error, setError] = React.useState<string | null>(null)\n const [isNotFound, setIsNotFound] = React.useState(false)\n const [activeTab, setActiveTab] = React.useState<'details' | 'members'>('details')\n const [memberRows, setMemberRows] = React.useState<TeamMemberRow[]>([])\n const [memberPage, setMemberPage] = React.useState(1)\n const [memberTotal, setMemberTotal] = React.useState(0)\n const [memberTotalPages, setMemberTotalPages] = React.useState(1)\n const [memberSorting, setMemberSorting] = React.useState<SortingState>([{ id: 'displayName', desc: false }])\n const [memberSearch, setMemberSearch] = React.useState('')\n const [membersLoading, setMembersLoading] = React.useState(false)\n const [memberReloadToken, setMemberReloadToken] = React.useState(0)\n\n const memberLabels = React.useMemo(() => ({\n title: t('staff.teams.tabs.members', 'Team members'),\n description: t('staff.teamMembers.page.description', 'Manage employees and their team assignments.'),\n table: {\n name: t('staff.teamMembers.table.name', 'Name'),\n user: t('staff.teamMembers.table.user', 'User'),\n roles: t('staff.teamMembers.table.roles', 'Roles'),\n tags: t('staff.teamMembers.table.tags', 'Tags'),\n active: t('staff.teamMembers.table.active', 'Active'),\n updatedAt: t('staff.teamMembers.table.updatedAt', 'Updated'),\n empty: t('staff.teamMembers.table.empty', 'No team members yet.'),\n search: t('staff.teamMembers.table.search', 'Search team members...'),\n },\n actions: {\n add: t('staff.teamMembers.actions.add', 'Add team member'),\n edit: t('staff.teamMembers.actions.edit', 'Edit'),\n unassign: t('staff.teamMembers.actions.unassign', 'Unassign'),\n refresh: t('staff.teamMembers.actions.refresh', 'Refresh'),\n },\n messages: {\n unassigned: t('staff.teamMembers.messages.unassigned', 'Team member unassigned.'),\n },\n errors: {\n load: t('staff.teamMembers.errors.load', 'Failed to load team members.'),\n unassign: t('staff.teamMembers.errors.unassign', 'Failed to unassign team member.'),\n },\n tabs: {\n details: t('staff.teams.tabs.details', 'Details'),\n members: t('staff.teams.tabs.members', 'Team members'),\n label: t('staff.teams.tabs.label', 'Team sections'),\n },\n }), [t])\n\n const memberColumns = React.useMemo<ColumnDef<TeamMemberRow>[]>(() => [\n {\n accessorKey: 'displayName',\n header: memberLabels.table.name,\n meta: { priority: 1, sticky: true },\n cell: ({ row }) => (\n <div className=\"flex flex-col\">\n <span className=\"font-medium\">{row.original.displayName}</span>\n {row.original.description ? (\n <span className=\"text-xs text-muted-foreground line-clamp-2\">{row.original.description}</span>\n ) : null}\n </div>\n ),\n },\n {\n accessorKey: 'userEmail',\n header: memberLabels.table.user,\n meta: { priority: 2 },\n cell: ({ row }) => row.original.userEmail\n ? <span className=\"text-sm\">{row.original.userEmail}</span>\n : <span className=\"text-xs text-muted-foreground\">-</span>,\n },\n {\n accessorKey: 'roleNames',\n header: memberLabels.table.roles,\n meta: { priority: 3 },\n cell: ({ row }) => row.original.roleNames.length\n ? <span className=\"text-sm\">{row.original.roleNames.join(', ')}</span>\n : <span className=\"text-xs text-muted-foreground\">-</span>,\n },\n {\n accessorKey: 'tags',\n header: memberLabels.table.tags,\n meta: { priority: 4 },\n cell: ({ row }) => row.original.tags.length\n ? <span className=\"text-xs text-muted-foreground\">{row.original.tags.join(', ')}</span>\n : <span className=\"text-xs text-muted-foreground\">-</span>,\n },\n {\n accessorKey: 'isActive',\n header: memberLabels.table.active,\n meta: { priority: 5 },\n cell: ({ row }) => <BooleanIcon value={row.original.isActive} />,\n },\n {\n accessorKey: 'updatedAt',\n header: memberLabels.table.updatedAt,\n meta: { priority: 6 },\n cell: ({ row }) => row.original.updatedAt\n ? <span className=\"text-xs text-muted-foreground\">{formatDateTime(row.original.updatedAt)}</span>\n : <span className=\"text-xs text-muted-foreground\">-</span>,\n },\n ], [\n memberLabels.table.active,\n memberLabels.table.name,\n memberLabels.table.roles,\n memberLabels.table.tags,\n memberLabels.table.updatedAt,\n memberLabels.table.user,\n ])\n\n React.useEffect(() => {\n if (!teamId) return\n const teamIdValue = teamId\n let cancelled = false\n async function loadTeam() {\n if (!cancelled) {\n setError(null)\n setIsNotFound(false)\n }\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '1', ids: teamIdValue })\n const payload = await readApiResultOrThrow<TeamResponse>(\n `/api/staff/teams?${params.toString()}`,\n undefined,\n { errorMessage: t('staff.teams.errors.load', 'Failed to load team.') },\n )\n const record = Array.isArray(payload.items) ? payload.items[0] : null\n if (!record) {\n if (!cancelled) setIsNotFound(true)\n return\n }\n const customFields = extractCustomFieldEntries(record)\n const isActive = typeof record.isActive === 'boolean'\n ? record.isActive\n : typeof record.is_active === 'boolean'\n ? record.is_active\n : true\n if (!cancelled) {\n setInitialValues({\n id: record.id,\n name: record.name ?? '',\n description: record.description ?? '',\n isActive,\n ...customFields,\n })\n }\n } catch (err) {\n if (!cancelled) {\n if ((err as { status?: number }).status === 404) {\n setIsNotFound(true)\n } else {\n const message = err instanceof Error ? err.message : t('staff.teams.errors.load', 'Failed to load team.')\n setError(message)\n }\n }\n }\n }\n loadTeam()\n return () => { cancelled = true }\n }, [teamId, t])\n\n React.useEffect(() => {\n if (!searchParams) return\n const tabParam = searchParams.get('tab')\n if (tabParam === 'members') {\n setActiveTab('members')\n }\n }, [searchParams])\n\n const loadTeamMembers = React.useCallback(async () => {\n if (!teamId) return\n setMembersLoading(true)\n try {\n const params = new URLSearchParams({\n page: String(memberPage),\n pageSize: String(TEAM_MEMBERS_PAGE_SIZE),\n teamId,\n })\n const sort = memberSorting[0]\n if (sort?.id) {\n params.set('sortField', sort.id)\n params.set('sortDir', sort.desc ? 'desc' : 'asc')\n }\n if (memberSearch.trim()) params.set('search', memberSearch.trim())\n const payload = await readApiResultOrThrow<TeamMembersResponse>(\n `/api/staff/team-members?${params.toString()}`,\n undefined,\n { errorMessage: memberLabels.errors.load, fallback: { items: [], total: 0, totalPages: 1 } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n setMemberRows(items.map(mapApiTeamMember))\n setMemberTotal(typeof payload.total === 'number' ? payload.total : items.length)\n setMemberTotalPages(\n typeof payload.totalPages === 'number'\n ? payload.totalPages\n : Math.max(1, Math.ceil(items.length / TEAM_MEMBERS_PAGE_SIZE)),\n )\n } catch (error) {\n console.error('staff.teams.team-members.list', error)\n flash(memberLabels.errors.load, 'error')\n } finally {\n setMembersLoading(false)\n }\n }, [memberLabels.errors.load, memberPage, memberSearch, memberSorting, teamId])\n\n React.useEffect(() => {\n if (activeTab !== 'members') return\n void loadTeamMembers()\n }, [activeTab, loadTeamMembers, memberReloadToken, scopeVersion])\n\n const handleMemberSearchChange = React.useCallback((value: string) => {\n setMemberSearch(value)\n setMemberPage(1)\n }, [])\n\n const handleMemberRefresh = React.useCallback(() => {\n setMemberReloadToken((token) => token + 1)\n }, [])\n\n const handleUnassignMember = React.useCallback(async (entry: TeamMemberRow) => {\n if (!teamId || entry.teamId !== teamId) return\n try {\n await updateCrud('staff/team-members', { id: entry.id, teamId: null }, { errorMessage: memberLabels.errors.unassign })\n flash(memberLabels.messages.unassigned, 'success')\n handleMemberRefresh()\n } catch (error) {\n console.error('staff.teams.team-members.unassign', error)\n flash(memberLabels.errors.unassign, 'error')\n }\n }, [handleMemberRefresh, memberLabels.errors.unassign, memberLabels.messages.unassigned, teamId])\n\n const handleSubmit = React.useCallback(async (values: TeamFormValues) => {\n if (!teamId) return\n const payload = buildTeamPayload(values, { id: teamId })\n await updateCrud('staff/teams', payload, {\n errorMessage: t('staff.teams.errors.save', 'Failed to save team.'),\n })\n flash(t('staff.teams.messages.saved', 'Team saved.'), 'success')\n }, [teamId, t])\n\n const handleDelete = React.useCallback(async () => {\n if (!teamId) return\n await deleteCrud('staff/teams', teamId, {\n errorMessage: t('staff.teams.errors.delete', 'Failed to delete team.'),\n })\n router.push('/backend/staff/teams')\n }, [teamId, router, t])\n\n if (isNotFound) {\n return (\n <Page>\n <PageBody>\n <RecordNotFoundState\n label={t('staff.teams.errors.notFound', 'Team not found.')}\n backHref=\"/backend/staff/teams\"\n backLabel={t('staff.teams.actions.backToList', 'Back to teams')}\n />\n </PageBody>\n </Page>\n )\n }\n\n if (error && !initialValues) {\n return (\n <Page>\n <PageBody>\n <ErrorMessage label={error} />\n </PageBody>\n </Page>\n )\n }\n\n return (\n <Page>\n <PageBody>\n <div className=\"space-y-6\">\n <div className=\"border-b\">\n <nav className=\"flex flex-wrap items-center gap-5 text-sm\" aria-label={memberLabels.tabs.label}>\n {[\n { id: 'details', label: memberLabels.tabs.details },\n { id: 'members', label: memberLabels.tabs.members },\n ].map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={activeTab === tab.id}\n onClick={() => setActiveTab(tab.id as 'details' | 'members')}\n className={`relative -mb-px border-b-2 px-0 py-2 text-sm font-medium transition-colors ${\n activeTab === tab.id\n ? 'border-accent-indigo text-foreground'\n : 'border-transparent text-muted-foreground hover:text-foreground'\n }`}\n >\n {tab.label}\n </button>\n ))}\n </nav>\n </div>\n\n {activeTab === 'details' ? (\n <TeamForm\n title={t('staff.teams.form.editTitle', 'Edit team')}\n backHref=\"/backend/staff/teams\"\n cancelHref=\"/backend/staff/teams\"\n initialValues={initialValues ?? { name: '', description: '', isActive: true }}\n onSubmit={handleSubmit}\n onDelete={handleDelete}\n isLoading={!initialValues}\n loadingMessage={t('staff.teams.form.loading', 'Loading team...')}\n extraActions={teamId ? (\n <SendObjectMessageDialog\n object={{\n entityModule: 'staff',\n entityType: 'team',\n entityId: teamId,\n previewData: { title: initialValues?.name ?? ''},\n }}\n viewHref={`/backend/staff/teams/${teamId}/edit`}\n />\n ) : undefined}\n />\n ) : (\n <DataTable<TeamMemberRow>\n title={memberLabels.title}\n data={memberRows}\n columns={memberColumns}\n isLoading={membersLoading}\n searchValue={memberSearch}\n onSearchChange={handleMemberSearchChange}\n searchPlaceholder={memberLabels.table.search}\n emptyState={<p className=\"py-8 text-center text-sm text-muted-foreground\">{memberLabels.table.empty}</p>}\n actions={(\n <Button asChild size=\"sm\">\n <Link href={`/backend/staff/team-members/create?teamId=${encodeURIComponent(teamId ?? '')}`}>\n <Plus className=\"mr-2 h-4 w-4\" aria-hidden />\n {memberLabels.actions.add}\n </Link>\n </Button>\n )}\n refreshButton={{\n label: memberLabels.actions.refresh,\n onRefresh: handleMemberRefresh,\n isRefreshing: membersLoading,\n }}\n sortable\n sorting={memberSorting}\n onSortingChange={setMemberSorting}\n pagination={{\n page: memberPage,\n pageSize: TEAM_MEMBERS_PAGE_SIZE,\n total: memberTotal,\n totalPages: memberTotalPages,\n onPageChange: setMemberPage,\n }}\n rowActions={(row) => (\n <RowActions\n items={[\n { id: 'edit', label: memberLabels.actions.edit, onSelect: () => { router.push(`/backend/staff/team-members/${row.id}`) } },\n { id: 'unassign', label: memberLabels.actions.unassign, onSelect: () => { void handleUnassignMember(row) } },\n ]}\n />\n )}\n />\n )}\n </div>\n </PageBody>\n </Page>\n )\n}\n\nfunction mapApiTeamMember(item: Record<string, unknown>): TeamMemberRow {\n const id = typeof item.id === 'string' ? item.id : ''\n const displayName = typeof item.displayName === 'string'\n ? item.displayName\n : typeof item.display_name === 'string'\n ? item.display_name\n : id\n const description = typeof item.description === 'string' && item.description.trim().length\n ? item.description.trim()\n : null\n const user = item.user && typeof item.user === 'object' ? item.user as { email?: unknown } : null\n const userEmail = user && typeof user.email === 'string' && user.email.length ? user.email : null\n const roleNames = Array.isArray(item.roleNames) ? item.roleNames.filter((value): value is string => typeof value === 'string') : []\n const tags = Array.isArray(item.tags) ? item.tags.filter((value): value is string => typeof value === 'string') : []\n const updatedAt = typeof item.updatedAt === 'string'\n ? item.updatedAt\n : typeof item.updated_at === 'string'\n ? item.updated_at\n : null\n const isActive = typeof item.isActive === 'boolean'\n ? item.isActive\n : typeof item.is_active === 'boolean'\n ? item.is_active\n : true\n const teamId = typeof item.teamId === 'string'\n ? item.teamId\n : typeof item.team_id === 'string'\n ? item.team_id\n : null\n return withDataTableNamespaces({\n id,\n displayName,\n description,\n userEmail,\n roleNames,\n tags,\n isActive,\n updatedAt,\n teamId,\n }, item)\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, useSearchParams } from 'next/navigation'\nimport type { ColumnDef, SortingState } from '@tanstack/react-table'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { ErrorMessage, RecordNotFoundState } from '@open-mercato/ui/backend/detail'\nimport { readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { DataTable, withDataTableNamespaces } from '@open-mercato/ui/backend/DataTable'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { BooleanIcon } from '@open-mercato/ui/backend/ValueIcons'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { TeamForm, type TeamFormValues, buildTeamPayload } from '@open-mercato/core/modules/staff/components/TeamForm'\nimport { SendObjectMessageDialog } from '@open-mercato/ui/backend/messages'\nimport { extractCustomFieldEntries } from '@open-mercato/shared/lib/crud/custom-fields-client'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { Plus } from 'lucide-react'\nimport { formatDateTime } from '@open-mercato/shared/lib/time'\n\nconst TEAM_MEMBERS_PAGE_SIZE = 50\n\ntype TeamRecord = {\n id: string\n name: string\n description?: string | null\n isActive?: boolean\n is_active?: boolean\n updatedAt?: string | null\n updated_at?: string | null\n} & Record<string, unknown>\n\ntype TeamResponse = {\n items?: TeamRecord[]\n}\n\ntype TeamMemberRow = {\n id: string\n displayName: string\n description: string | null\n userEmail: string | null\n roleNames: string[]\n tags: string[]\n isActive: boolean\n updatedAt: string | null\n teamId: string | null\n}\n\ntype TeamMembersResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n totalPages?: number\n}\n\nexport default function StaffTeamEditPage({ params }: { params?: { id?: string } }) {\n const teamId = params?.id\n const t = useT()\n const router = useRouter()\n const searchParams = useSearchParams()\n const scopeVersion = useOrganizationScopeVersion()\n const [initialValues, setInitialValues] = React.useState<TeamFormValues | null>(null)\n const [error, setError] = React.useState<string | null>(null)\n const [isNotFound, setIsNotFound] = React.useState(false)\n const [activeTab, setActiveTab] = React.useState<'details' | 'members'>('details')\n const [memberRows, setMemberRows] = React.useState<TeamMemberRow[]>([])\n const [memberPage, setMemberPage] = React.useState(1)\n const [memberTotal, setMemberTotal] = React.useState(0)\n const [memberTotalPages, setMemberTotalPages] = React.useState(1)\n const [memberSorting, setMemberSorting] = React.useState<SortingState>([{ id: 'displayName', desc: false }])\n const [memberSearch, setMemberSearch] = React.useState('')\n const [membersLoading, setMembersLoading] = React.useState(false)\n const [memberReloadToken, setMemberReloadToken] = React.useState(0)\n\n const memberLabels = React.useMemo(() => ({\n title: t('staff.teams.tabs.members', 'Team members'),\n description: t('staff.teamMembers.page.description', 'Manage employees and their team assignments.'),\n table: {\n name: t('staff.teamMembers.table.name', 'Name'),\n user: t('staff.teamMembers.table.user', 'User'),\n roles: t('staff.teamMembers.table.roles', 'Roles'),\n tags: t('staff.teamMembers.table.tags', 'Tags'),\n active: t('staff.teamMembers.table.active', 'Active'),\n updatedAt: t('staff.teamMembers.table.updatedAt', 'Updated'),\n empty: t('staff.teamMembers.table.empty', 'No team members yet.'),\n search: t('staff.teamMembers.table.search', 'Search team members...'),\n },\n actions: {\n add: t('staff.teamMembers.actions.add', 'Add team member'),\n edit: t('staff.teamMembers.actions.edit', 'Edit'),\n unassign: t('staff.teamMembers.actions.unassign', 'Unassign'),\n refresh: t('staff.teamMembers.actions.refresh', 'Refresh'),\n },\n messages: {\n unassigned: t('staff.teamMembers.messages.unassigned', 'Team member unassigned.'),\n },\n errors: {\n load: t('staff.teamMembers.errors.load', 'Failed to load team members.'),\n unassign: t('staff.teamMembers.errors.unassign', 'Failed to unassign team member.'),\n },\n tabs: {\n details: t('staff.teams.tabs.details', 'Details'),\n members: t('staff.teams.tabs.members', 'Team members'),\n label: t('staff.teams.tabs.label', 'Team sections'),\n },\n }), [t])\n\n const memberColumns = React.useMemo<ColumnDef<TeamMemberRow>[]>(() => [\n {\n accessorKey: 'displayName',\n header: memberLabels.table.name,\n meta: { priority: 1, sticky: true },\n cell: ({ row }) => (\n <div className=\"flex flex-col\">\n <span className=\"font-medium\">{row.original.displayName}</span>\n {row.original.description ? (\n <span className=\"text-xs text-muted-foreground line-clamp-2\">{row.original.description}</span>\n ) : null}\n </div>\n ),\n },\n {\n accessorKey: 'userEmail',\n header: memberLabels.table.user,\n meta: { priority: 2 },\n cell: ({ row }) => row.original.userEmail\n ? <span className=\"text-sm\">{row.original.userEmail}</span>\n : <span className=\"text-xs text-muted-foreground\">-</span>,\n },\n {\n accessorKey: 'roleNames',\n header: memberLabels.table.roles,\n meta: { priority: 3 },\n cell: ({ row }) => row.original.roleNames.length\n ? <span className=\"text-sm\">{row.original.roleNames.join(', ')}</span>\n : <span className=\"text-xs text-muted-foreground\">-</span>,\n },\n {\n accessorKey: 'tags',\n header: memberLabels.table.tags,\n meta: { priority: 4 },\n cell: ({ row }) => row.original.tags.length\n ? <span className=\"text-xs text-muted-foreground\">{row.original.tags.join(', ')}</span>\n : <span className=\"text-xs text-muted-foreground\">-</span>,\n },\n {\n accessorKey: 'isActive',\n header: memberLabels.table.active,\n meta: { priority: 5 },\n cell: ({ row }) => <BooleanIcon value={row.original.isActive} />,\n },\n {\n accessorKey: 'updatedAt',\n header: memberLabels.table.updatedAt,\n meta: { priority: 6 },\n cell: ({ row }) => row.original.updatedAt\n ? <span className=\"text-xs text-muted-foreground\">{formatDateTime(row.original.updatedAt)}</span>\n : <span className=\"text-xs text-muted-foreground\">-</span>,\n },\n ], [\n memberLabels.table.active,\n memberLabels.table.name,\n memberLabels.table.roles,\n memberLabels.table.tags,\n memberLabels.table.updatedAt,\n memberLabels.table.user,\n ])\n\n React.useEffect(() => {\n if (!teamId) return\n const teamIdValue = teamId\n let cancelled = false\n async function loadTeam() {\n if (!cancelled) {\n setError(null)\n setIsNotFound(false)\n }\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '1', ids: teamIdValue })\n const payload = await readApiResultOrThrow<TeamResponse>(\n `/api/staff/teams?${params.toString()}`,\n undefined,\n { errorMessage: t('staff.teams.errors.load', 'Failed to load team.') },\n )\n const record = Array.isArray(payload.items) ? payload.items[0] : null\n if (!record) {\n if (!cancelled) setIsNotFound(true)\n return\n }\n const customFields = extractCustomFieldEntries(record)\n const isActive = typeof record.isActive === 'boolean'\n ? record.isActive\n : typeof record.is_active === 'boolean'\n ? record.is_active\n : true\n if (!cancelled) {\n setInitialValues({\n id: record.id,\n name: record.name ?? '',\n description: record.description ?? '',\n isActive,\n updatedAt: typeof record.updatedAt === 'string'\n ? record.updatedAt\n : typeof record.updated_at === 'string'\n ? record.updated_at\n : null,\n ...customFields,\n })\n }\n } catch (err) {\n if (!cancelled) {\n if ((err as { status?: number }).status === 404) {\n setIsNotFound(true)\n } else {\n const message = err instanceof Error ? err.message : t('staff.teams.errors.load', 'Failed to load team.')\n setError(message)\n }\n }\n }\n }\n loadTeam()\n return () => { cancelled = true }\n }, [teamId, t])\n\n React.useEffect(() => {\n if (!searchParams) return\n const tabParam = searchParams.get('tab')\n if (tabParam === 'members') {\n setActiveTab('members')\n }\n }, [searchParams])\n\n const loadTeamMembers = React.useCallback(async () => {\n if (!teamId) return\n setMembersLoading(true)\n try {\n const params = new URLSearchParams({\n page: String(memberPage),\n pageSize: String(TEAM_MEMBERS_PAGE_SIZE),\n teamId,\n })\n const sort = memberSorting[0]\n if (sort?.id) {\n params.set('sortField', sort.id)\n params.set('sortDir', sort.desc ? 'desc' : 'asc')\n }\n if (memberSearch.trim()) params.set('search', memberSearch.trim())\n const payload = await readApiResultOrThrow<TeamMembersResponse>(\n `/api/staff/team-members?${params.toString()}`,\n undefined,\n { errorMessage: memberLabels.errors.load, fallback: { items: [], total: 0, totalPages: 1 } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n setMemberRows(items.map(mapApiTeamMember))\n setMemberTotal(typeof payload.total === 'number' ? payload.total : items.length)\n setMemberTotalPages(\n typeof payload.totalPages === 'number'\n ? payload.totalPages\n : Math.max(1, Math.ceil(items.length / TEAM_MEMBERS_PAGE_SIZE)),\n )\n } catch (error) {\n console.error('staff.teams.team-members.list', error)\n flash(memberLabels.errors.load, 'error')\n } finally {\n setMembersLoading(false)\n }\n }, [memberLabels.errors.load, memberPage, memberSearch, memberSorting, teamId])\n\n React.useEffect(() => {\n if (activeTab !== 'members') return\n void loadTeamMembers()\n }, [activeTab, loadTeamMembers, memberReloadToken, scopeVersion])\n\n const handleMemberSearchChange = React.useCallback((value: string) => {\n setMemberSearch(value)\n setMemberPage(1)\n }, [])\n\n const handleMemberRefresh = React.useCallback(() => {\n setMemberReloadToken((token) => token + 1)\n }, [])\n\n const handleUnassignMember = React.useCallback(async (entry: TeamMemberRow) => {\n if (!teamId || entry.teamId !== teamId) return\n try {\n const headers = buildOptimisticLockHeader(entry.updatedAt)\n await withScopedApiRequestHeaders(headers, () => (\n updateCrud('staff/team-members', { id: entry.id, teamId: null }, { errorMessage: memberLabels.errors.unassign })\n ))\n flash(memberLabels.messages.unassigned, 'success')\n handleMemberRefresh()\n } catch (error) {\n console.error('staff.teams.team-members.unassign', error)\n flash(memberLabels.errors.unassign, 'error')\n }\n }, [handleMemberRefresh, memberLabels.errors.unassign, memberLabels.messages.unassigned, teamId])\n\n const handleSubmit = React.useCallback(async (values: TeamFormValues) => {\n if (!teamId) return\n const payload = buildTeamPayload(values, { id: teamId })\n await updateCrud('staff/teams', payload, {\n errorMessage: t('staff.teams.errors.save', 'Failed to save team.'),\n })\n flash(t('staff.teams.messages.saved', 'Team saved.'), 'success')\n }, [teamId, t])\n\n const handleDelete = React.useCallback(async () => {\n if (!teamId) return\n await deleteCrud('staff/teams', teamId, {\n errorMessage: t('staff.teams.errors.delete', 'Failed to delete team.'),\n })\n router.push('/backend/staff/teams')\n }, [teamId, router, t])\n\n if (isNotFound) {\n return (\n <Page>\n <PageBody>\n <RecordNotFoundState\n label={t('staff.teams.errors.notFound', 'Team not found.')}\n backHref=\"/backend/staff/teams\"\n backLabel={t('staff.teams.actions.backToList', 'Back to teams')}\n />\n </PageBody>\n </Page>\n )\n }\n\n if (error && !initialValues) {\n return (\n <Page>\n <PageBody>\n <ErrorMessage label={error} />\n </PageBody>\n </Page>\n )\n }\n\n return (\n <Page>\n <PageBody>\n <div className=\"space-y-6\">\n <div className=\"border-b\">\n <nav className=\"flex flex-wrap items-center gap-5 text-sm\" aria-label={memberLabels.tabs.label}>\n {[\n { id: 'details', label: memberLabels.tabs.details },\n { id: 'members', label: memberLabels.tabs.members },\n ].map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={activeTab === tab.id}\n onClick={() => setActiveTab(tab.id as 'details' | 'members')}\n className={`relative -mb-px border-b-2 px-0 py-2 text-sm font-medium transition-colors ${\n activeTab === tab.id\n ? 'border-accent-indigo text-foreground'\n : 'border-transparent text-muted-foreground hover:text-foreground'\n }`}\n >\n {tab.label}\n </button>\n ))}\n </nav>\n </div>\n\n {activeTab === 'details' ? (\n <TeamForm\n title={t('staff.teams.form.editTitle', 'Edit team')}\n backHref=\"/backend/staff/teams\"\n cancelHref=\"/backend/staff/teams\"\n initialValues={initialValues ?? { name: '', description: '', isActive: true }}\n onSubmit={handleSubmit}\n onDelete={handleDelete}\n isLoading={!initialValues}\n loadingMessage={t('staff.teams.form.loading', 'Loading team...')}\n extraActions={teamId ? (\n <SendObjectMessageDialog\n object={{\n entityModule: 'staff',\n entityType: 'team',\n entityId: teamId,\n previewData: { title: initialValues?.name ?? ''},\n }}\n viewHref={`/backend/staff/teams/${teamId}/edit`}\n />\n ) : undefined}\n />\n ) : (\n <DataTable<TeamMemberRow>\n title={memberLabels.title}\n data={memberRows}\n columns={memberColumns}\n isLoading={membersLoading}\n searchValue={memberSearch}\n onSearchChange={handleMemberSearchChange}\n searchPlaceholder={memberLabels.table.search}\n emptyState={<p className=\"py-8 text-center text-sm text-muted-foreground\">{memberLabels.table.empty}</p>}\n actions={(\n <Button asChild size=\"sm\">\n <Link href={`/backend/staff/team-members/create?teamId=${encodeURIComponent(teamId ?? '')}`}>\n <Plus className=\"mr-2 h-4 w-4\" aria-hidden />\n {memberLabels.actions.add}\n </Link>\n </Button>\n )}\n refreshButton={{\n label: memberLabels.actions.refresh,\n onRefresh: handleMemberRefresh,\n isRefreshing: membersLoading,\n }}\n sortable\n sorting={memberSorting}\n onSortingChange={setMemberSorting}\n pagination={{\n page: memberPage,\n pageSize: TEAM_MEMBERS_PAGE_SIZE,\n total: memberTotal,\n totalPages: memberTotalPages,\n onPageChange: setMemberPage,\n }}\n rowActions={(row) => (\n <RowActions\n items={[\n { id: 'edit', label: memberLabels.actions.edit, onSelect: () => { router.push(`/backend/staff/team-members/${row.id}`) } },\n { id: 'unassign', label: memberLabels.actions.unassign, onSelect: () => { void handleUnassignMember(row) } },\n ]}\n />\n )}\n />\n )}\n </div>\n </PageBody>\n </Page>\n )\n}\n\nfunction mapApiTeamMember(item: Record<string, unknown>): TeamMemberRow {\n const id = typeof item.id === 'string' ? item.id : ''\n const displayName = typeof item.displayName === 'string'\n ? item.displayName\n : typeof item.display_name === 'string'\n ? item.display_name\n : id\n const description = typeof item.description === 'string' && item.description.trim().length\n ? item.description.trim()\n : null\n const user = item.user && typeof item.user === 'object' ? item.user as { email?: unknown } : null\n const userEmail = user && typeof user.email === 'string' && user.email.length ? user.email : null\n const roleNames = Array.isArray(item.roleNames) ? item.roleNames.filter((value): value is string => typeof value === 'string') : []\n const tags = Array.isArray(item.tags) ? item.tags.filter((value): value is string => typeof value === 'string') : []\n const updatedAt = typeof item.updatedAt === 'string'\n ? item.updatedAt\n : typeof item.updated_at === 'string'\n ? item.updated_at\n : null\n const isActive = typeof item.isActive === 'boolean'\n ? item.isActive\n : typeof item.is_active === 'boolean'\n ? item.is_active\n : true\n const teamId = typeof item.teamId === 'string'\n ? item.teamId\n : typeof item.team_id === 'string'\n ? item.team_id\n : null\n return withDataTableNamespaces({\n id,\n displayName,\n description,\n userEmail,\n roleNames,\n tags,\n isActive,\n updatedAt,\n teamId,\n }, item)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["params", "error"]
|
|
7
7
|
}
|
|
@@ -9,7 +9,9 @@ import { RowActions } from "@open-mercato/ui/backend/RowActions";
|
|
|
9
9
|
import { MarkdownPreview } from "@open-mercato/ui/backend/markdown/MarkdownContent";
|
|
10
10
|
import { Button } from "@open-mercato/ui/primitives/button";
|
|
11
11
|
import { BooleanIcon } from "@open-mercato/ui/backend/ValueIcons";
|
|
12
|
-
import { readApiResultOrThrow } from "@open-mercato/ui/backend/utils/apiCall";
|
|
12
|
+
import { readApiResultOrThrow, withScopedApiRequestHeaders } from "@open-mercato/ui/backend/utils/apiCall";
|
|
13
|
+
import { buildOptimisticLockHeader } from "@open-mercato/ui/backend/utils/optimisticLock";
|
|
14
|
+
import { surfaceRecordConflict } from "@open-mercato/ui/backend/conflicts";
|
|
13
15
|
import { deleteCrud } from "@open-mercato/ui/backend/utils/crud";
|
|
14
16
|
import { flash } from "@open-mercato/ui/backend/FlashMessages";
|
|
15
17
|
import { useConfirmDialog } from "@open-mercato/ui/backend/confirm-dialog";
|
|
@@ -173,14 +175,21 @@ function StaffTeamsPage() {
|
|
|
173
175
|
});
|
|
174
176
|
if (!confirmed) return;
|
|
175
177
|
try {
|
|
176
|
-
await
|
|
178
|
+
await withScopedApiRequestHeaders(
|
|
179
|
+
buildOptimisticLockHeader(entry.updatedAt),
|
|
180
|
+
() => deleteCrud("staff/teams", entry.id, { errorMessage: labels.errors.delete })
|
|
181
|
+
);
|
|
177
182
|
flash(labels.messages.deleted, "success");
|
|
178
183
|
handleRefresh();
|
|
179
184
|
} catch (error) {
|
|
185
|
+
if (surfaceRecordConflict(error, t)) {
|
|
186
|
+
handleRefresh();
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
180
189
|
console.error("staff.teams.delete", error);
|
|
181
190
|
flash(labels.errors.delete, "error");
|
|
182
191
|
}
|
|
183
|
-
}, [confirm, handleRefresh, labels.actions.deleteConfirm, labels.actions.delete, labels.errors.delete, labels.errors.deleteAssigned, labels.messages.deleted]);
|
|
192
|
+
}, [confirm, handleRefresh, labels.actions.deleteConfirm, labels.actions.delete, labels.errors.delete, labels.errors.deleteAssigned, labels.messages.deleted, t]);
|
|
184
193
|
return /* @__PURE__ */ jsxs(Page, { children: [
|
|
185
194
|
/* @__PURE__ */ jsx(PageBody, { children: /* @__PURE__ */ jsx(
|
|
186
195
|
DataTable,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/modules/staff/backend/staff/teams/page.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport type { ColumnDef, SortingState } from '@tanstack/react-table'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, withDataTableNamespaces } from '@open-mercato/ui/backend/DataTable'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { MarkdownPreview } from '@open-mercato/ui/backend/markdown/MarkdownContent'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { BooleanIcon } from '@open-mercato/ui/backend/ValueIcons'\nimport { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Users } from 'lucide-react'\nimport { formatDateTime } from '@open-mercato/shared/lib/time'\n\nconst PAGE_SIZE = 50\nconst MARKDOWN_CLASSNAME =\n 'text-sm text-foreground break-words [&>*]:mb-2 [&>*:last-child]:mb-0 [&_ul]:ml-4 [&_ul]:list-disc [&_ol]:ml-4 [&_ol]:list-decimal [&_code]:rounded [&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_pre]:rounded-md [&_pre]:bg-muted [&_pre]:p-3 [&_pre]:text-xs'\n\ntype TeamRow = {\n id: string\n name: string\n description: string | null\n isActive: boolean\n updatedAt: string | null\n memberCount: number\n}\n\ntype TeamsResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n totalPages?: number\n}\n\nexport default function StaffTeamsPage() {\n const t = useT()\n const router = useRouter()\n const scopeVersion = useOrganizationScopeVersion()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const [rows, setRows] = React.useState<TeamRow[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [sorting, setSorting] = React.useState<SortingState>([{ id: 'name', desc: false }])\n const [search, setSearch] = React.useState('')\n const [isLoading, setIsLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n\n const labels = React.useMemo(() => ({\n title: t('staff.teams.page.title', 'Teams'),\n description: t('staff.teams.page.description', 'Group team members and roles.'),\n table: {\n name: t('staff.teams.table.name', 'Name'),\n description: t('staff.teams.table.description', 'Description'),\n active: t('staff.teams.table.active', 'Active'),\n members: t('staff.teams.table.members', 'Team members'),\n updatedAt: t('staff.teams.table.updatedAt', 'Updated'),\n empty: t('staff.teams.table.empty', 'No teams yet.'),\n search: t('staff.teams.table.search', 'Search teams...'),\n },\n actions: {\n add: t('staff.teams.actions.add', 'Add team'),\n edit: t('staff.teams.actions.edit', 'Edit'),\n delete: t('staff.teams.actions.delete', 'Delete'),\n deleteConfirm: t('staff.teams.actions.deleteConfirm', 'Delete team \"{{name}}\"?'),\n showMembers: t('staff.teams.actions.showMembers', 'Show team members ({{count}})'),\n refresh: t('staff.teams.actions.refresh', 'Refresh'),\n },\n messages: {\n deleted: t('staff.teams.messages.deleted', 'Team deleted.'),\n },\n errors: {\n load: t('staff.teams.errors.load', 'Failed to load teams.'),\n delete: t('staff.teams.errors.delete', 'Failed to delete team.'),\n deleteAssigned: t('staff.teams.errors.deleteAssigned', 'Team has assigned members and cannot be deleted.'),\n },\n }), [t])\n\n const columns = React.useMemo<ColumnDef<TeamRow>[]>(() => [\n {\n accessorKey: 'name',\n header: labels.table.name,\n meta: { priority: 1, sticky: true },\n cell: ({ row }) => (\n <div className=\"flex flex-col\">\n <span className=\"font-medium\">{row.original.name}</span>\n {row.original.description ? (\n <MarkdownPreview\n className={`${MARKDOWN_CLASSNAME} text-xs text-muted-foreground line-clamp-2`}\n >\n {row.original.description}\n </MarkdownPreview>\n ) : null}\n </div>\n ),\n },\n {\n accessorKey: 'description',\n header: labels.table.description,\n meta: { priority: 4 },\n cell: ({ row }) => row.original.description\n ? (\n <MarkdownPreview className={MARKDOWN_CLASSNAME}>\n {row.original.description}\n </MarkdownPreview>\n )\n : <span className=\"text-xs text-muted-foreground\">-</span>,\n },\n {\n accessorKey: 'isActive',\n header: labels.table.active,\n meta: { priority: 2 },\n cell: ({ row }) => <BooleanIcon value={row.original.isActive} />,\n },\n {\n accessorKey: 'memberCount',\n header: () => <span className=\"inline-block min-w-[250px]\">{labels.table.members}</span>,\n meta: { priority: 3 },\n enableSorting: false,\n cell: ({ row }) => (\n <Link\n className=\"inline-flex min-w-[220px] items-center gap-2 text-sm text-muted-foreground hover:text-foreground\"\n href={`/backend/staff/team-members?teamId=${encodeURIComponent(row.original.id)}`}\n onClick={(event) => event.stopPropagation()}\n >\n <Users className=\"h-4 w-4\" aria-hidden />\n {labels.actions.showMembers.replace('{{count}}', String(row.original.memberCount))}\n </Link>\n ),\n },\n {\n accessorKey: 'updatedAt',\n header: labels.table.updatedAt,\n meta: { priority: 5 },\n cell: ({ row }) => row.original.updatedAt\n ? <span className=\"text-xs text-muted-foreground\">{formatDateTime(row.original.updatedAt)}</span>\n : <span className=\"text-xs text-muted-foreground\">-</span>,\n },\n ], [\n labels.actions.showMembers,\n labels.table.active,\n labels.table.description,\n labels.table.members,\n labels.table.name,\n labels.table.updatedAt,\n ])\n\n const loadTeams = React.useCallback(async () => {\n setIsLoading(true)\n try {\n const params = new URLSearchParams({\n page: String(page),\n pageSize: String(PAGE_SIZE),\n })\n const sort = sorting[0]\n if (sort?.id) {\n params.set('sortField', sort.id)\n params.set('sortDir', sort.desc ? 'desc' : 'asc')\n }\n if (search.trim()) params.set('search', search.trim())\n const payload = await readApiResultOrThrow<TeamsResponse>(\n `/api/staff/teams?${params.toString()}`,\n undefined,\n { errorMessage: labels.errors.load, fallback: { items: [], total: 0, totalPages: 1 } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n setRows(items.map(mapApiTeam))\n setTotal(typeof payload.total === 'number' ? payload.total : items.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : Math.max(1, Math.ceil(items.length / PAGE_SIZE)))\n } catch (error) {\n console.error('staff.teams.list', error)\n flash(labels.errors.load, 'error')\n } finally {\n setIsLoading(false)\n }\n }, [labels.errors.load, page, search, sorting])\n\n React.useEffect(() => {\n void loadTeams()\n }, [loadTeams, scopeVersion, reloadToken])\n\n const handleSearchChange = React.useCallback((value: string) => {\n setSearch(value)\n setPage(1)\n }, [])\n\n const handleRefresh = React.useCallback(() => {\n setReloadToken((token) => token + 1)\n }, [])\n\n const handleDelete = React.useCallback(async (entry: TeamRow) => {\n if (entry.memberCount > 0) {\n flash(labels.errors.deleteAssigned, 'error')\n return\n }\n const message = labels.actions.deleteConfirm.replace('{{name}}', entry.name)\n const confirmed = await confirm({\n title: labels.actions.delete,\n text: message,\n variant: 'destructive',\n })\n if (!confirmed) return\n try {\n await deleteCrud('staff/teams', entry.id, { errorMessage: labels.errors.delete })\n flash(labels.messages.deleted, 'success')\n handleRefresh()\n } catch (error) {\n console.error('staff.teams.delete', error)\n flash(labels.errors.delete, 'error')\n }\n }, [confirm, handleRefresh, labels.actions.deleteConfirm, labels.actions.delete, labels.errors.delete, labels.errors.deleteAssigned, labels.messages.deleted])\n\n return (\n <Page>\n <PageBody>\n <DataTable<TeamRow>\n title={labels.title}\n data={rows}\n columns={columns}\n isLoading={isLoading}\n searchValue={search}\n onSearchChange={handleSearchChange}\n searchPlaceholder={labels.table.search}\n emptyState={<p className=\"py-8 text-center text-sm text-muted-foreground\">{labels.table.empty}</p>}\n actions={(\n <Button asChild size=\"sm\">\n <Link href=\"/backend/staff/teams/create\">\n {labels.actions.add}\n </Link>\n </Button>\n )}\n refreshButton={{\n label: labels.actions.refresh,\n onRefresh: handleRefresh,\n isRefreshing: isLoading,\n }}\n sortable\n sorting={sorting}\n onSortingChange={setSorting}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n onPageChange: setPage,\n }}\n rowActions={(row) => (\n <RowActions\n items={[\n { id: 'edit', label: labels.actions.edit, href: `/backend/staff/teams/${row.id}/edit` },\n ...(row.memberCount > 0\n ? []\n : [{ id: 'delete', label: labels.actions.delete, destructive: true, onSelect: () => { void handleDelete(row) } }]),\n ]}\n />\n )}\n onRowClick={(row) => router.push(`/backend/staff/teams/${row.id}/edit`)}\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n\nfunction mapApiTeam(item: Record<string, unknown>): TeamRow {\n const id = typeof item.id === 'string' ? item.id : ''\n const name = typeof item.name === 'string' ? item.name : id\n const description = typeof item.description === 'string' && item.description.trim().length ? item.description.trim() : null\n const updatedAt = typeof item.updatedAt === 'string'\n ? item.updatedAt\n : typeof item.updated_at === 'string'\n ? item.updated_at\n : null\n const isActive = typeof item.isActive === 'boolean'\n ? item.isActive\n : typeof item.is_active === 'boolean'\n ? item.is_active\n : true\n const memberCount = typeof item.memberCount === 'number'\n ? item.memberCount\n : typeof item.member_count === 'number'\n ? item.member_count\n : 0\n return withDataTableNamespaces({ id, name, description, isActive, updatedAt, memberCount }, item)\n}\n"],
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport type { ColumnDef, SortingState } from '@tanstack/react-table'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, withDataTableNamespaces } from '@open-mercato/ui/backend/DataTable'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { MarkdownPreview } from '@open-mercato/ui/backend/markdown/MarkdownContent'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { BooleanIcon } from '@open-mercato/ui/backend/ValueIcons'\nimport { readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Users } from 'lucide-react'\nimport { formatDateTime } from '@open-mercato/shared/lib/time'\n\nconst PAGE_SIZE = 50\nconst MARKDOWN_CLASSNAME =\n 'text-sm text-foreground break-words [&>*]:mb-2 [&>*:last-child]:mb-0 [&_ul]:ml-4 [&_ul]:list-disc [&_ol]:ml-4 [&_ol]:list-decimal [&_code]:rounded [&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_pre]:rounded-md [&_pre]:bg-muted [&_pre]:p-3 [&_pre]:text-xs'\n\ntype TeamRow = {\n id: string\n name: string\n description: string | null\n isActive: boolean\n updatedAt: string | null\n memberCount: number\n}\n\ntype TeamsResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n totalPages?: number\n}\n\nexport default function StaffTeamsPage() {\n const t = useT()\n const router = useRouter()\n const scopeVersion = useOrganizationScopeVersion()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const [rows, setRows] = React.useState<TeamRow[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [sorting, setSorting] = React.useState<SortingState>([{ id: 'name', desc: false }])\n const [search, setSearch] = React.useState('')\n const [isLoading, setIsLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n\n const labels = React.useMemo(() => ({\n title: t('staff.teams.page.title', 'Teams'),\n description: t('staff.teams.page.description', 'Group team members and roles.'),\n table: {\n name: t('staff.teams.table.name', 'Name'),\n description: t('staff.teams.table.description', 'Description'),\n active: t('staff.teams.table.active', 'Active'),\n members: t('staff.teams.table.members', 'Team members'),\n updatedAt: t('staff.teams.table.updatedAt', 'Updated'),\n empty: t('staff.teams.table.empty', 'No teams yet.'),\n search: t('staff.teams.table.search', 'Search teams...'),\n },\n actions: {\n add: t('staff.teams.actions.add', 'Add team'),\n edit: t('staff.teams.actions.edit', 'Edit'),\n delete: t('staff.teams.actions.delete', 'Delete'),\n deleteConfirm: t('staff.teams.actions.deleteConfirm', 'Delete team \"{{name}}\"?'),\n showMembers: t('staff.teams.actions.showMembers', 'Show team members ({{count}})'),\n refresh: t('staff.teams.actions.refresh', 'Refresh'),\n },\n messages: {\n deleted: t('staff.teams.messages.deleted', 'Team deleted.'),\n },\n errors: {\n load: t('staff.teams.errors.load', 'Failed to load teams.'),\n delete: t('staff.teams.errors.delete', 'Failed to delete team.'),\n deleteAssigned: t('staff.teams.errors.deleteAssigned', 'Team has assigned members and cannot be deleted.'),\n },\n }), [t])\n\n const columns = React.useMemo<ColumnDef<TeamRow>[]>(() => [\n {\n accessorKey: 'name',\n header: labels.table.name,\n meta: { priority: 1, sticky: true },\n cell: ({ row }) => (\n <div className=\"flex flex-col\">\n <span className=\"font-medium\">{row.original.name}</span>\n {row.original.description ? (\n <MarkdownPreview\n className={`${MARKDOWN_CLASSNAME} text-xs text-muted-foreground line-clamp-2`}\n >\n {row.original.description}\n </MarkdownPreview>\n ) : null}\n </div>\n ),\n },\n {\n accessorKey: 'description',\n header: labels.table.description,\n meta: { priority: 4 },\n cell: ({ row }) => row.original.description\n ? (\n <MarkdownPreview className={MARKDOWN_CLASSNAME}>\n {row.original.description}\n </MarkdownPreview>\n )\n : <span className=\"text-xs text-muted-foreground\">-</span>,\n },\n {\n accessorKey: 'isActive',\n header: labels.table.active,\n meta: { priority: 2 },\n cell: ({ row }) => <BooleanIcon value={row.original.isActive} />,\n },\n {\n accessorKey: 'memberCount',\n header: () => <span className=\"inline-block min-w-[250px]\">{labels.table.members}</span>,\n meta: { priority: 3 },\n enableSorting: false,\n cell: ({ row }) => (\n <Link\n className=\"inline-flex min-w-[220px] items-center gap-2 text-sm text-muted-foreground hover:text-foreground\"\n href={`/backend/staff/team-members?teamId=${encodeURIComponent(row.original.id)}`}\n onClick={(event) => event.stopPropagation()}\n >\n <Users className=\"h-4 w-4\" aria-hidden />\n {labels.actions.showMembers.replace('{{count}}', String(row.original.memberCount))}\n </Link>\n ),\n },\n {\n accessorKey: 'updatedAt',\n header: labels.table.updatedAt,\n meta: { priority: 5 },\n cell: ({ row }) => row.original.updatedAt\n ? <span className=\"text-xs text-muted-foreground\">{formatDateTime(row.original.updatedAt)}</span>\n : <span className=\"text-xs text-muted-foreground\">-</span>,\n },\n ], [\n labels.actions.showMembers,\n labels.table.active,\n labels.table.description,\n labels.table.members,\n labels.table.name,\n labels.table.updatedAt,\n ])\n\n const loadTeams = React.useCallback(async () => {\n setIsLoading(true)\n try {\n const params = new URLSearchParams({\n page: String(page),\n pageSize: String(PAGE_SIZE),\n })\n const sort = sorting[0]\n if (sort?.id) {\n params.set('sortField', sort.id)\n params.set('sortDir', sort.desc ? 'desc' : 'asc')\n }\n if (search.trim()) params.set('search', search.trim())\n const payload = await readApiResultOrThrow<TeamsResponse>(\n `/api/staff/teams?${params.toString()}`,\n undefined,\n { errorMessage: labels.errors.load, fallback: { items: [], total: 0, totalPages: 1 } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n setRows(items.map(mapApiTeam))\n setTotal(typeof payload.total === 'number' ? payload.total : items.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : Math.max(1, Math.ceil(items.length / PAGE_SIZE)))\n } catch (error) {\n console.error('staff.teams.list', error)\n flash(labels.errors.load, 'error')\n } finally {\n setIsLoading(false)\n }\n }, [labels.errors.load, page, search, sorting])\n\n React.useEffect(() => {\n void loadTeams()\n }, [loadTeams, scopeVersion, reloadToken])\n\n const handleSearchChange = React.useCallback((value: string) => {\n setSearch(value)\n setPage(1)\n }, [])\n\n const handleRefresh = React.useCallback(() => {\n setReloadToken((token) => token + 1)\n }, [])\n\n const handleDelete = React.useCallback(async (entry: TeamRow) => {\n if (entry.memberCount > 0) {\n flash(labels.errors.deleteAssigned, 'error')\n return\n }\n const message = labels.actions.deleteConfirm.replace('{{name}}', entry.name)\n const confirmed = await confirm({\n title: labels.actions.delete,\n text: message,\n variant: 'destructive',\n })\n if (!confirmed) return\n try {\n await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(entry.updatedAt),\n () => deleteCrud('staff/teams', entry.id, { errorMessage: labels.errors.delete }),\n )\n flash(labels.messages.deleted, 'success')\n handleRefresh()\n } catch (error) {\n if (surfaceRecordConflict(error, t)) { handleRefresh(); return }\n console.error('staff.teams.delete', error)\n flash(labels.errors.delete, 'error')\n }\n }, [confirm, handleRefresh, labels.actions.deleteConfirm, labels.actions.delete, labels.errors.delete, labels.errors.deleteAssigned, labels.messages.deleted, t])\n\n return (\n <Page>\n <PageBody>\n <DataTable<TeamRow>\n title={labels.title}\n data={rows}\n columns={columns}\n isLoading={isLoading}\n searchValue={search}\n onSearchChange={handleSearchChange}\n searchPlaceholder={labels.table.search}\n emptyState={<p className=\"py-8 text-center text-sm text-muted-foreground\">{labels.table.empty}</p>}\n actions={(\n <Button asChild size=\"sm\">\n <Link href=\"/backend/staff/teams/create\">\n {labels.actions.add}\n </Link>\n </Button>\n )}\n refreshButton={{\n label: labels.actions.refresh,\n onRefresh: handleRefresh,\n isRefreshing: isLoading,\n }}\n sortable\n sorting={sorting}\n onSortingChange={setSorting}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n onPageChange: setPage,\n }}\n rowActions={(row) => (\n <RowActions\n items={[\n { id: 'edit', label: labels.actions.edit, href: `/backend/staff/teams/${row.id}/edit` },\n ...(row.memberCount > 0\n ? []\n : [{ id: 'delete', label: labels.actions.delete, destructive: true, onSelect: () => { void handleDelete(row) } }]),\n ]}\n />\n )}\n onRowClick={(row) => router.push(`/backend/staff/teams/${row.id}/edit`)}\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n\nfunction mapApiTeam(item: Record<string, unknown>): TeamRow {\n const id = typeof item.id === 'string' ? item.id : ''\n const name = typeof item.name === 'string' ? item.name : id\n const description = typeof item.description === 'string' && item.description.trim().length ? item.description.trim() : null\n const updatedAt = typeof item.updatedAt === 'string'\n ? item.updatedAt\n : typeof item.updated_at === 'string'\n ? item.updated_at\n : null\n const isActive = typeof item.isActive === 'boolean'\n ? item.isActive\n : typeof item.is_active === 'boolean'\n ? item.is_active\n : true\n const memberCount = typeof item.memberCount === 'number'\n ? item.memberCount\n : typeof item.member_count === 'number'\n ? item.member_count\n : 0\n return withDataTableNamespaces({ id, name, description, isActive, updatedAt, memberCount }, item)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -230,6 +230,9 @@ function MyTimesheetsPage() {
|
|
|
230
230
|
const visibleProjectIdSet = new Set(
|
|
231
231
|
assignmentItems.filter((item) => item.show_in_grid === true || item.showInGrid === true).map((item) => String(item.time_project_id ?? item.timeProjectId ?? "")).filter((id) => id.length > 0)
|
|
232
232
|
);
|
|
233
|
+
const entriesParams = new URLSearchParams({ pageSize: "100", staffMemberId: memberId });
|
|
234
|
+
if (dateRange.from) entriesParams.set("from", dateRange.from);
|
|
235
|
+
if (dateRange.to) entriesParams.set("to", dateRange.to);
|
|
233
236
|
const [projectsRes, entriesRes] = await Promise.all([
|
|
234
237
|
assignedProjectIds.length > 0 ? readApiResultOrThrow(
|
|
235
238
|
`/api/staff/timesheets/time-projects?ids=${assignedProjectIds.join(",")}&pageSize=100`,
|
|
@@ -237,7 +240,7 @@ function MyTimesheetsPage() {
|
|
|
237
240
|
{ errorMessage: t("staff.timesheets.my.errors.load", "Failed to load timesheets."), fallback: { items: [] } }
|
|
238
241
|
) : Promise.resolve({ items: [] }),
|
|
239
242
|
readApiResultOrThrow(
|
|
240
|
-
`/api/staff/timesheets/time-entries
|
|
243
|
+
`/api/staff/timesheets/time-entries?${entriesParams.toString()}`,
|
|
241
244
|
void 0,
|
|
242
245
|
{ errorMessage: t("staff.timesheets.my.errors.load", "Failed to load timesheets."), fallback: { items: [] } }
|
|
243
246
|
)
|