@open-mercato/core 0.6.5-develop.5337.1.534b781eac → 0.6.5
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 +1 -1
- package/dist/bootstrap.js +46 -6
- package/dist/bootstrap.js.map +2 -2
- package/dist/generated/entities/organization/index.js +2 -0
- package/dist/generated/entities/organization/index.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +1 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/helpers/integration/crmFixtures.js +4 -0
- package/dist/helpers/integration/crmFixtures.js.map +2 -2
- package/dist/modules/attachments/api/library/route.js +2 -2
- package/dist/modules/attachments/api/library/route.js.map +2 -2
- package/dist/modules/attachments/api/route.js +2 -0
- package/dist/modules/attachments/api/route.js.map +2 -2
- package/dist/modules/attachments/components/AttachmentContentPreview.js +9 -5
- package/dist/modules/attachments/components/AttachmentContentPreview.js.map +2 -2
- package/dist/modules/attachments/lib/access.js +18 -0
- package/dist/modules/attachments/lib/access.js.map +2 -2
- package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js +3 -2
- package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js.map +2 -2
- package/dist/modules/audit_logs/data/entities.js +2 -1
- package/dist/modules/audit_logs/data/entities.js.map +2 -2
- package/dist/modules/audit_logs/migrations/Migration20260611104500.js +13 -0
- package/dist/modules/audit_logs/migrations/Migration20260611104500.js.map +7 -0
- package/dist/modules/audit_logs/services/accessLogService.js +10 -0
- package/dist/modules/audit_logs/services/accessLogService.js.map +2 -2
- package/dist/modules/auth/api/admin/nav.js +9 -0
- package/dist/modules/auth/api/admin/nav.js.map +2 -2
- package/dist/modules/auth/api/login.js +4 -13
- package/dist/modules/auth/api/login.js.map +2 -2
- package/dist/modules/auth/commands/users.js +20 -14
- package/dist/modules/auth/commands/users.js.map +2 -2
- package/dist/modules/auth/data/entities.js +4 -2
- package/dist/modules/auth/data/entities.js.map +2 -2
- package/dist/modules/auth/lib/backendChrome.js +35 -2
- package/dist/modules/auth/lib/backendChrome.js.map +2 -2
- package/dist/modules/auth/lib/consentIntegrity.js +3 -3
- package/dist/modules/auth/lib/consentIntegrity.js.map +2 -2
- package/dist/modules/auth/migrations/Migration20260610120000.js +30 -0
- package/dist/modules/auth/migrations/Migration20260610120000.js.map +7 -0
- package/dist/modules/auth/migrations/Migration20260611103000.js +15 -0
- package/dist/modules/auth/migrations/Migration20260611103000.js.map +7 -0
- package/dist/modules/auth/services/authService.js +5 -3
- package/dist/modules/auth/services/authService.js.map +2 -2
- package/dist/modules/auth/services/rbacService.js +3 -2
- package/dist/modules/auth/services/rbacService.js.map +2 -2
- package/dist/modules/catalog/ai-tools/configuration-pack.js.map +1 -1
- package/dist/modules/catalog/ai-tools/prices-offers-pack.js.map +1 -1
- package/dist/modules/catalog/ai-tools/products-pack.js.map +1 -1
- package/dist/modules/catalog/ai-tools/variants-pack.js.map +1 -1
- package/dist/modules/communication_channels/data/entities.js.map +1 -1
- package/dist/modules/communication_channels/encryption.js.map +1 -1
- package/dist/modules/communication_channels/lib/thread-matcher.js.map +1 -1
- package/dist/modules/communication_channels/lib/thread-token.js.map +1 -1
- package/dist/modules/currencies/api/currencies/route.js +4 -3
- package/dist/modules/currencies/api/currencies/route.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/roles.js +2 -1
- package/dist/modules/customer_accounts/api/admin/roles.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js +0 -3
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js.map +2 -2
- package/dist/modules/customer_accounts/events.js +1 -1
- package/dist/modules/customer_accounts/events.js.map +1 -1
- package/dist/modules/customer_accounts/lib/resolveTenantContext.js.map +1 -1
- package/dist/modules/customers/acl.js +1 -1
- package/dist/modules/customers/acl.js.map +1 -1
- package/dist/modules/customers/ai-tools/companies-pack.js.map +1 -1
- package/dist/modules/customers/ai-tools/deals-pack.js.map +1 -1
- package/dist/modules/customers/ai-tools/people-pack.js.map +1 -1
- package/dist/modules/customers/api/companies/route.js +4 -4
- package/dist/modules/customers/api/companies/route.js.map +2 -2
- package/dist/modules/customers/api/deals/route.js +43 -2
- package/dist/modules/customers/api/deals/route.js.map +2 -2
- package/dist/modules/customers/api/deals/summary/route.js +402 -0
- package/dist/modules/customers/api/deals/summary/route.js.map +7 -0
- package/dist/modules/customers/api/people/route.js +4 -4
- package/dist/modules/customers/api/people/route.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js +16 -5
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js +22 -5
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +12 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/page.js +221 -56
- package/dist/modules/customers/backend/customers/deals/page.js.map +3 -3
- package/dist/modules/customers/backend/customers/deals/pipeline/page.js +1 -1
- package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +18 -0
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/cli.js +15 -9
- package/dist/modules/customers/cli.js.map +2 -2
- package/dist/modules/customers/commands/addresses.js +5 -5
- package/dist/modules/customers/commands/addresses.js.map +2 -2
- package/dist/modules/customers/commands/comments.js +5 -5
- package/dist/modules/customers/commands/comments.js.map +2 -2
- package/dist/modules/customers/commands/deals.js +2 -2
- package/dist/modules/customers/commands/deals.js.map +2 -2
- package/dist/modules/customers/commands/entity-roles.js +2 -1
- package/dist/modules/customers/commands/entity-roles.js.map +2 -2
- package/dist/modules/customers/commands/interactions.js +8 -5
- package/dist/modules/customers/commands/interactions.js.map +2 -2
- package/dist/modules/customers/commands/shared.js +21 -6
- package/dist/modules/customers/commands/shared.js.map +2 -2
- package/dist/modules/customers/commands/tags.js +3 -3
- package/dist/modules/customers/commands/tags.js.map +2 -2
- package/dist/modules/customers/components/DealsKpiStrip.js +282 -0
- package/dist/modules/customers/components/DealsKpiStrip.js.map +7 -0
- package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js +0 -1
- package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/DealForm.js +100 -17
- package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
- package/dist/modules/customers/components/detail/PersonDetailTabs.js +11 -3
- package/dist/modules/customers/components/detail/PersonDetailTabs.js.map +2 -2
- package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +1 -2
- package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/assignableStaff.js +21 -8
- package/dist/modules/customers/components/detail/assignableStaff.js.map +2 -2
- package/dist/modules/customers/components/kpi/PipelineStageBar.js +63 -0
- package/dist/modules/customers/components/kpi/PipelineStageBar.js.map +7 -0
- package/dist/modules/customers/lib/dealsMetrics.js +82 -0
- package/dist/modules/customers/lib/dealsMetrics.js.map +7 -0
- package/dist/modules/customers/migrations/Migration20260519120000_pipeline_stage_color_tones.js.map +1 -1
- package/dist/modules/data_sync/api/run.js +1 -1
- package/dist/modules/data_sync/api/run.js.map +2 -2
- package/dist/modules/directory/api/organization-branding/route.js +214 -0
- package/dist/modules/directory/api/organization-branding/route.js.map +7 -0
- package/dist/modules/directory/api/organizations/route.js +7 -0
- package/dist/modules/directory/api/organizations/route.js.map +3 -3
- package/dist/modules/directory/backend/directory/branding/page.js +214 -0
- package/dist/modules/directory/backend/directory/branding/page.js.map +7 -0
- package/dist/modules/directory/backend/directory/branding/page.meta.js +26 -0
- package/dist/modules/directory/backend/directory/branding/page.meta.js.map +7 -0
- package/dist/modules/directory/commands/organizations.js +8 -1
- package/dist/modules/directory/commands/organizations.js.map +2 -2
- package/dist/modules/directory/data/entities.js +3 -0
- package/dist/modules/directory/data/entities.js.map +2 -2
- package/dist/modules/directory/data/validators.js +9 -0
- package/dist/modules/directory/data/validators.js.map +2 -2
- package/dist/modules/directory/migrations/Migration20260607222259_directory.js +13 -0
- package/dist/modules/directory/migrations/Migration20260607222259_directory.js.map +7 -0
- package/dist/modules/directory/subscribers/invalidateOrgScopeCache.js +2 -1
- package/dist/modules/directory/subscribers/invalidateOrgScopeCache.js.map +2 -2
- package/dist/modules/directory/utils/organizationScope.js +59 -27
- package/dist/modules/directory/utils/organizationScope.js.map +2 -2
- package/dist/modules/entities/api/definitions.batch.js +2 -1
- package/dist/modules/entities/api/definitions.batch.js.map +2 -2
- package/dist/modules/entities/api/entities.js +7 -0
- package/dist/modules/entities/api/entities.js.map +2 -2
- package/dist/modules/entities/api/records.js +26 -15
- package/dist/modules/entities/api/records.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js +14 -0
- package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/create/page.js +14 -0
- package/dist/modules/entities/backend/entities/user/[entityId]/records/create/page.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +12 -0
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
- package/dist/modules/entities/components/useRecordsEntityGuard.js +30 -0
- package/dist/modules/entities/components/useRecordsEntityGuard.js.map +7 -0
- package/dist/modules/payment_gateways/api/transactions/route.js +2 -4
- package/dist/modules/payment_gateways/api/transactions/route.js.map +2 -2
- package/dist/modules/progress/api/jobs/[id]/route.js +7 -2
- package/dist/modules/progress/api/jobs/[id]/route.js.map +2 -2
- package/dist/modules/progress/api/jobs/route.js +1 -1
- package/dist/modules/progress/api/jobs/route.js.map +2 -2
- package/dist/modules/progress/lib/progressServiceImpl.js +8 -2
- package/dist/modules/progress/lib/progressServiceImpl.js.map +2 -2
- package/dist/modules/query_index/data/entities.js +2 -1
- package/dist/modules/query_index/data/entities.js.map +2 -2
- package/dist/modules/query_index/lib/engine.js +4 -2
- package/dist/modules/query_index/lib/engine.js.map +2 -2
- package/dist/modules/query_index/migrations/Migration20260611103000_query_index.js +16 -0
- package/dist/modules/query_index/migrations/Migration20260611103000_query_index.js.map +7 -0
- package/dist/modules/resources/api/resources.js +2 -3
- package/dist/modules/resources/api/resources.js.map +2 -2
- package/dist/modules/sales/api/documents/factory.js +2 -2
- package/dist/modules/sales/api/documents/factory.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +7 -5
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js +2 -1
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
- package/dist/modules/sales/components/documents/salesDocumentsColumns.js +10 -0
- package/dist/modules/sales/components/documents/salesDocumentsColumns.js.map +7 -0
- package/dist/modules/staff/api/team-members.js +9 -2
- package/dist/modules/staff/api/team-members.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js +24 -1
- package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js +11 -6
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
- package/dist/modules/staff/commands/team-members.js +1 -1
- package/dist/modules/staff/commands/team-members.js.map +2 -2
- package/dist/modules/staff/components/TeamMemberForm.js +1 -1
- package/dist/modules/staff/components/TeamMemberForm.js.map +2 -2
- package/dist/modules/staff/lib/scheduleSwitch.js +23 -0
- package/dist/modules/staff/lib/scheduleSwitch.js.map +7 -0
- package/dist/modules/sync_excel/api/import/route.js +1 -1
- package/dist/modules/sync_excel/api/import/route.js.map +2 -2
- package/dist/modules/workflows/api/definitions/route.js +3 -2
- package/dist/modules/workflows/api/definitions/route.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/create/page.js +1 -2
- package/dist/modules/workflows/backend/definitions/create/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js +1 -2
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
- package/dist/modules/workflows/components/DefinitionTriggersEditor.js +1 -2
- package/dist/modules/workflows/components/DefinitionTriggersEditor.js.map +2 -2
- package/dist/modules/workflows/components/NodeEditDialog.js +4 -13
- package/dist/modules/workflows/components/NodeEditDialog.js.map +2 -2
- package/dist/modules/workflows/components/NodeEditDialogCrudForm.js +4 -13
- package/dist/modules/workflows/components/NodeEditDialogCrudForm.js.map +2 -2
- package/dist/modules/workflows/components/WorkflowGraphImpl.js +1 -4
- package/dist/modules/workflows/components/WorkflowGraphImpl.js.map +2 -2
- package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js +2 -5
- package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js.map +2 -2
- package/generated/entities/organization/index.ts +1 -0
- package/generated/entity-fields-registry.ts +1 -0
- package/package.json +11 -12
- package/src/bootstrap.ts +65 -7
- package/src/helpers/integration/crmFixtures.ts +21 -1
- package/src/modules/attachments/AGENTS.md +79 -0
- package/src/modules/attachments/api/library/route.ts +2 -2
- package/src/modules/attachments/api/route.ts +2 -0
- package/src/modules/attachments/components/AttachmentContentPreview.tsx +6 -6
- package/src/modules/attachments/lib/access.ts +36 -0
- package/src/modules/audit_logs/api/audit-logs/actions/redo/route.ts +14 -2
- package/src/modules/audit_logs/data/entities.ts +1 -0
- package/src/modules/audit_logs/migrations/.snapshot-open-mercato.json +10 -0
- package/src/modules/audit_logs/migrations/Migration20260611104500.ts +13 -0
- package/src/modules/audit_logs/services/accessLogService.ts +15 -0
- package/src/modules/auth/api/admin/nav.ts +9 -0
- package/src/modules/auth/api/login.ts +13 -13
- package/src/modules/auth/commands/users.ts +32 -15
- package/src/modules/auth/data/entities.ts +13 -1
- package/src/modules/auth/i18n/de.json +0 -1
- package/src/modules/auth/i18n/en.json +0 -1
- package/src/modules/auth/i18n/es.json +0 -1
- package/src/modules/auth/i18n/pl.json +0 -1
- package/src/modules/auth/lib/backendChrome.tsx +37 -1
- package/src/modules/auth/lib/consentIntegrity.ts +6 -3
- package/src/modules/auth/migrations/.snapshot-open-mercato.json +20 -10
- package/src/modules/auth/migrations/Migration20260610120000.ts +53 -0
- package/src/modules/auth/migrations/Migration20260611103000.ts +21 -0
- package/src/modules/auth/services/authService.ts +24 -4
- package/src/modules/auth/services/rbacService.ts +11 -2
- package/src/modules/catalog/ai-tools/configuration-pack.ts +1 -1
- package/src/modules/catalog/ai-tools/prices-offers-pack.ts +1 -1
- package/src/modules/catalog/ai-tools/products-pack.ts +1 -1
- package/src/modules/catalog/ai-tools/variants-pack.ts +1 -1
- package/src/modules/communication_channels/data/entities.ts +2 -2
- package/src/modules/communication_channels/encryption.ts +1 -1
- package/src/modules/communication_channels/lib/adapter.ts +1 -1
- package/src/modules/communication_channels/lib/thread-matcher.ts +1 -1
- package/src/modules/communication_channels/lib/thread-token.ts +1 -1
- package/src/modules/currencies/api/currencies/route.ts +4 -3
- package/src/modules/customer_accounts/api/admin/roles.ts +2 -1
- package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.tsx +0 -3
- package/src/modules/customer_accounts/events.ts +1 -1
- package/src/modules/customer_accounts/lib/resolveTenantContext.ts +2 -2
- package/src/modules/customers/acl.ts +1 -1
- package/src/modules/customers/ai-tools/companies-pack.ts +1 -1
- package/src/modules/customers/ai-tools/deals-pack.ts +1 -1
- package/src/modules/customers/ai-tools/people-pack.ts +1 -1
- package/src/modules/customers/api/companies/route.ts +4 -4
- package/src/modules/customers/api/deals/route.ts +51 -2
- package/src/modules/customers/api/deals/summary/route.ts +496 -0
- package/src/modules/customers/api/people/route.ts +4 -4
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.ts +28 -6
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealData.ts +33 -6
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +17 -2
- package/src/modules/customers/backend/customers/deals/page.tsx +254 -66
- package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +1 -2
- package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +18 -0
- package/src/modules/customers/cli.ts +15 -15
- package/src/modules/customers/commands/addresses.ts +5 -5
- package/src/modules/customers/commands/comments.ts +5 -5
- package/src/modules/customers/commands/deals.ts +2 -2
- package/src/modules/customers/commands/entity-roles.ts +2 -1
- package/src/modules/customers/commands/interactions.ts +8 -5
- package/src/modules/customers/commands/shared.ts +26 -4
- package/src/modules/customers/commands/tags.ts +3 -3
- package/src/modules/customers/components/DealsKpiStrip.tsx +389 -0
- package/src/modules/customers/components/detail/ConfirmDealLostDialog.tsx +0 -1
- package/src/modules/customers/components/detail/DealForm.tsx +121 -19
- package/src/modules/customers/components/detail/PersonDetailTabs.tsx +12 -2
- package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +1 -2
- package/src/modules/customers/components/detail/assignableStaff.ts +32 -8
- package/src/modules/customers/components/kpi/PipelineStageBar.tsx +77 -0
- package/src/modules/customers/i18n/de.json +43 -0
- package/src/modules/customers/i18n/en.json +43 -0
- package/src/modules/customers/i18n/es.json +43 -0
- package/src/modules/customers/i18n/pl.json +43 -0
- package/src/modules/customers/lib/dealsMetrics.ts +159 -0
- package/src/modules/customers/migrations/Migration20260519120000_pipeline_stage_color_tones.ts +1 -1
- package/src/modules/data_sync/api/run.ts +1 -1
- package/src/modules/directory/api/organization-branding/route.ts +238 -0
- package/src/modules/directory/api/organizations/route.ts +7 -0
- package/src/modules/directory/backend/directory/branding/page.meta.ts +24 -0
- package/src/modules/directory/backend/directory/branding/page.tsx +248 -0
- package/src/modules/directory/commands/organizations.ts +9 -1
- package/src/modules/directory/data/entities.ts +3 -0
- package/src/modules/directory/data/validators.ts +12 -0
- package/src/modules/directory/i18n/de.json +21 -0
- package/src/modules/directory/i18n/en.json +21 -0
- package/src/modules/directory/i18n/es.json +21 -0
- package/src/modules/directory/i18n/pl.json +21 -0
- package/src/modules/directory/migrations/.snapshot-open-mercato.json +40 -0
- package/src/modules/directory/migrations/Migration20260607222259_directory.ts +13 -0
- package/src/modules/directory/subscribers/invalidateOrgScopeCache.ts +3 -1
- package/src/modules/directory/utils/organizationScope.ts +85 -30
- package/src/modules/entities/api/definitions.batch.ts +11 -7
- package/src/modules/entities/api/entities.ts +11 -0
- package/src/modules/entities/api/records.ts +46 -25
- package/src/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.tsx +15 -0
- package/src/modules/entities/backend/entities/user/[entityId]/records/create/page.tsx +15 -0
- package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +23 -0
- package/src/modules/entities/components/useRecordsEntityGuard.ts +41 -0
- package/src/modules/entities/i18n/de.json +1 -0
- package/src/modules/entities/i18n/en.json +1 -0
- package/src/modules/entities/i18n/es.json +1 -0
- package/src/modules/entities/i18n/pl.json +1 -0
- package/src/modules/payment_gateways/api/transactions/route.ts +2 -5
- package/src/modules/progress/api/jobs/[id]/route.ts +6 -1
- package/src/modules/progress/api/jobs/route.ts +1 -1
- package/src/modules/progress/lib/progressServiceImpl.ts +7 -1
- package/src/modules/query_index/data/entities.ts +1 -0
- package/src/modules/query_index/lib/engine.ts +11 -5
- package/src/modules/query_index/migrations/.snapshot-open-mercato.json +11 -0
- package/src/modules/query_index/migrations/Migration20260611103000_query_index.ts +29 -0
- package/src/modules/resources/api/resources.ts +2 -3
- package/src/modules/sales/api/documents/factory.ts +2 -2
- package/src/modules/sales/commands/documents.ts +7 -5
- package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +2 -1
- package/src/modules/sales/components/documents/salesDocumentsColumns.ts +6 -0
- package/src/modules/staff/AGENTS.md +1 -1
- package/src/modules/staff/api/team-members.ts +9 -2
- package/src/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.ts +31 -1
- package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +18 -8
- package/src/modules/staff/commands/team-members.ts +5 -2
- package/src/modules/staff/components/TeamMemberForm.tsx +4 -1
- 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/scheduleSwitch.ts +46 -0
- package/src/modules/sync_excel/api/import/route.ts +1 -1
- package/src/modules/workflows/api/definitions/route.ts +3 -2
- package/src/modules/workflows/backend/definitions/create/page.tsx +1 -2
- package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +1 -2
- package/src/modules/workflows/components/DefinitionTriggersEditor.tsx +1 -2
- package/src/modules/workflows/components/NodeEditDialog.tsx +1 -4
- package/src/modules/workflows/components/NodeEditDialogCrudForm.tsx +4 -7
- package/src/modules/workflows/components/WorkflowGraphImpl.tsx +1 -2
- package/src/modules/workflows/components/fields/FormFieldArrayEditor.tsx +2 -3
|
@@ -19,14 +19,19 @@ import { coalesceLastOperations } from "@open-mercato/ui/backend/operations/stor
|
|
|
19
19
|
import { flash } from "@open-mercato/ui/backend/FlashMessages";
|
|
20
20
|
import { RowActions } from "@open-mercato/ui/backend/RowActions";
|
|
21
21
|
import { Button } from "@open-mercato/ui/primitives/button";
|
|
22
|
+
import { IconButton } from "@open-mercato/ui/primitives/icon-button";
|
|
23
|
+
import { StatusBadge } from "@open-mercato/ui/primitives/status-badge";
|
|
24
|
+
import { Avatar, AvatarStack } from "@open-mercato/ui/primitives/avatar";
|
|
25
|
+
import { Tag } from "@open-mercato/ui/primitives/tag";
|
|
26
|
+
import { SimpleTooltip } from "@open-mercato/ui/primitives/tooltip";
|
|
27
|
+
import { Briefcase, AlertTriangle, X } from "lucide-react";
|
|
28
|
+
import { formatRelativeTime } from "@open-mercato/shared/lib/time";
|
|
22
29
|
import { ViewTabsRow } from "./pipeline/components/ViewTabsRow.js";
|
|
30
|
+
import { DealsKpiStrip } from "../../../components/DealsKpiStrip.js";
|
|
23
31
|
import { E } from "../../../../../generated/entities.ids.generated.js";
|
|
24
32
|
import { useOrganizationScopeVersion } from "@open-mercato/shared/lib/frontend/useOrganizationScope";
|
|
25
33
|
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
26
34
|
import { useConfirmDialog } from "@open-mercato/ui/backend/confirm-dialog";
|
|
27
|
-
import {
|
|
28
|
-
DictionaryValue
|
|
29
|
-
} from "../../../lib/dictionaries.js";
|
|
30
35
|
import {
|
|
31
36
|
ensureCustomerDictionary,
|
|
32
37
|
invalidateCustomerDictionary
|
|
@@ -106,25 +111,30 @@ function extractIdsFromParams(params, key) {
|
|
|
106
111
|
const values = params.getAll(key);
|
|
107
112
|
return normalizeIdCandidates(values);
|
|
108
113
|
}
|
|
109
|
-
function formatCurrency(amount, currency, fallback) {
|
|
110
|
-
if (typeof amount !== "number" || Number.isNaN(amount)) return fallback;
|
|
111
|
-
try {
|
|
112
|
-
if (currency && currency.trim().length) {
|
|
113
|
-
const formatter2 = new Intl.NumberFormat(void 0, { style: "currency", currency });
|
|
114
|
-
return formatter2.format(amount);
|
|
115
|
-
}
|
|
116
|
-
const formatter = new Intl.NumberFormat(void 0, { style: "decimal", maximumFractionDigits: 2 });
|
|
117
|
-
return formatter.format(amount);
|
|
118
|
-
} catch {
|
|
119
|
-
return currency ? `${amount} ${currency}` : String(amount);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
114
|
function formatDateValue(value, fallback) {
|
|
123
115
|
if (!value) return fallback;
|
|
124
116
|
const date = new Date(value);
|
|
125
117
|
if (Number.isNaN(date.getTime())) return fallback;
|
|
126
118
|
return date.toLocaleDateString();
|
|
127
119
|
}
|
|
120
|
+
const STATUS_BADGE_VARIANTS = /* @__PURE__ */ new Set([
|
|
121
|
+
"success",
|
|
122
|
+
"warning",
|
|
123
|
+
"error",
|
|
124
|
+
"info",
|
|
125
|
+
"neutral"
|
|
126
|
+
]);
|
|
127
|
+
function coerceStatusBadgeVariant(tone) {
|
|
128
|
+
if (tone && STATUS_BADGE_VARIANTS.has(tone)) {
|
|
129
|
+
return tone;
|
|
130
|
+
}
|
|
131
|
+
return "neutral";
|
|
132
|
+
}
|
|
133
|
+
const groupedAmountFormatter = new Intl.NumberFormat(void 0, { maximumFractionDigits: 0 });
|
|
134
|
+
function formatGroupedAmount(amount) {
|
|
135
|
+
if (typeof amount !== "number" || Number.isNaN(amount)) return null;
|
|
136
|
+
return groupedAmountFormatter.format(amount);
|
|
137
|
+
}
|
|
128
138
|
function CustomersDealsPage() {
|
|
129
139
|
const t = useT();
|
|
130
140
|
const { confirm, ConfirmDialogElement } = useConfirmDialog();
|
|
@@ -146,6 +156,7 @@ function CustomersDealsPage() {
|
|
|
146
156
|
const [isLoading, setIsLoading] = React.useState(false);
|
|
147
157
|
const [reloadToken, setReloadToken] = React.useState(0);
|
|
148
158
|
const [pendingDeleteId, setPendingDeleteId] = React.useState(null);
|
|
159
|
+
const [needsAttentionOnly, setNeedsAttentionOnly] = React.useState(() => searchParams?.get("needsAttention") === "true");
|
|
149
160
|
const initialFilterTree = React.useMemo(() => {
|
|
150
161
|
if (!searchParams) return createEmptyTree();
|
|
151
162
|
const record = {};
|
|
@@ -260,12 +271,13 @@ function CustomersDealsPage() {
|
|
|
260
271
|
if (search.trim().length) params.set("search", search.trim());
|
|
261
272
|
if (selectedPersonIds.length) params.set("personId", selectedPersonIds.join(","));
|
|
262
273
|
if (selectedCompanyIds.length) params.set("companyId", selectedCompanyIds.join(","));
|
|
274
|
+
if (needsAttentionOnly) params.set("needsAttention", "true");
|
|
263
275
|
const advancedParams = serializeTree(advancedFilterState);
|
|
264
276
|
for (const [key, val] of Object.entries(advancedParams)) {
|
|
265
277
|
params.set(key, val);
|
|
266
278
|
}
|
|
267
279
|
return params.toString();
|
|
268
|
-
}, [advancedFilterState, page, pageSize, search, selectedCompanyIds, selectedPersonIds, sorting]);
|
|
280
|
+
}, [advancedFilterState, needsAttentionOnly, page, pageSize, search, selectedCompanyIds, selectedPersonIds, sorting]);
|
|
269
281
|
const currentParams = React.useMemo(
|
|
270
282
|
() => Object.fromEntries(new URLSearchParams(queryParams)),
|
|
271
283
|
[queryParams]
|
|
@@ -327,6 +339,7 @@ function CustomersDealsPage() {
|
|
|
327
339
|
if (search.trim().length) params.set("search", search.trim());
|
|
328
340
|
if (selectedPersonIds.length) selectedPersonIds.forEach((id) => params.append("personId", id));
|
|
329
341
|
if (selectedCompanyIds.length) selectedCompanyIds.forEach((id) => params.append("companyId", id));
|
|
342
|
+
if (needsAttentionOnly) params.set("needsAttention", "true");
|
|
330
343
|
if (page > 1) params.set("page", String(page));
|
|
331
344
|
const advancedParams = serializeTree(advancedFilterState);
|
|
332
345
|
for (const [key, val] of Object.entries(advancedParams)) {
|
|
@@ -336,7 +349,7 @@ function CustomersDealsPage() {
|
|
|
336
349
|
if (queryRef.current === next) return;
|
|
337
350
|
queryRef.current = next;
|
|
338
351
|
router.replace(next ? `${pathname}?${next}` : pathname, { scroll: false });
|
|
339
|
-
}, [pathname, router, page, search, selectedPersonIds, selectedCompanyIds, advancedFilterState]);
|
|
352
|
+
}, [pathname, router, page, search, selectedPersonIds, selectedCompanyIds, needsAttentionOnly, advancedFilterState]);
|
|
340
353
|
const handleRefresh = React.useCallback(() => {
|
|
341
354
|
void Promise.all([
|
|
342
355
|
invalidateCustomerDictionary(queryClient, "deal-statuses"),
|
|
@@ -406,6 +419,14 @@ function CustomersDealsPage() {
|
|
|
406
419
|
setPageSize(newSize);
|
|
407
420
|
setPage(1);
|
|
408
421
|
}, []);
|
|
422
|
+
const handleNeedsAttentionFilter = React.useCallback(() => {
|
|
423
|
+
setNeedsAttentionOnly(true);
|
|
424
|
+
setPage(1);
|
|
425
|
+
}, []);
|
|
426
|
+
const handleNeedsAttentionClear = React.useCallback(() => {
|
|
427
|
+
setNeedsAttentionOnly(false);
|
|
428
|
+
setPage(1);
|
|
429
|
+
}, []);
|
|
409
430
|
const handleBulkDelete = React.useCallback(async (selectedRows) => {
|
|
410
431
|
const confirmed = await confirm({
|
|
411
432
|
title: t("customers.deals.list.bulkDelete.title", "Delete {count} deals?", { count: selectedRows.length }),
|
|
@@ -486,13 +507,22 @@ function CustomersDealsPage() {
|
|
|
486
507
|
});
|
|
487
508
|
const currentUserId = useCurrentUserId();
|
|
488
509
|
const [ownerFilterOptions, setOwnerFilterOptions] = React.useState([]);
|
|
510
|
+
const [ownerNames, setOwnerNames] = React.useState({});
|
|
489
511
|
React.useEffect(() => {
|
|
490
512
|
const controller = new AbortController();
|
|
491
513
|
let cancelled = false;
|
|
492
514
|
void fetchAssignableStaffMembers("", { pageSize: 100, signal: controller.signal }).then((items) => {
|
|
493
|
-
if (
|
|
515
|
+
if (cancelled) return;
|
|
516
|
+
setOwnerFilterOptions(mapAssignableStaffToFilterOptions(items));
|
|
517
|
+
const names = {};
|
|
518
|
+
for (const item of items) {
|
|
519
|
+
if (item.userId) names[item.userId] = item.displayName;
|
|
520
|
+
}
|
|
521
|
+
setOwnerNames(names);
|
|
494
522
|
}).catch(() => {
|
|
495
|
-
if (
|
|
523
|
+
if (cancelled) return;
|
|
524
|
+
setOwnerFilterOptions([]);
|
|
525
|
+
setOwnerNames({});
|
|
496
526
|
});
|
|
497
527
|
return () => {
|
|
498
528
|
cancelled = true;
|
|
@@ -511,28 +541,18 @@ function CustomersDealsPage() {
|
|
|
511
541
|
const items = await fetchAssignableStaffMembers(query ?? "", { pageSize: 100 });
|
|
512
542
|
return mapAssignableStaffToFilterOptions(items);
|
|
513
543
|
}, []);
|
|
544
|
+
const startOfToday = React.useMemo(() => {
|
|
545
|
+
const today = /* @__PURE__ */ new Date();
|
|
546
|
+
today.setHours(0, 0, 0, 0);
|
|
547
|
+
return today;
|
|
548
|
+
}, []);
|
|
549
|
+
const isDealOverdue = React.useCallback(
|
|
550
|
+
(row) => !!row.expectedCloseAt && new Date(row.expectedCloseAt) < startOfToday && row.status === "open",
|
|
551
|
+
[startOfToday]
|
|
552
|
+
);
|
|
514
553
|
const columns = React.useMemo(() => {
|
|
515
554
|
const noValue = /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm", children: t("customers.deals.list.noValue") });
|
|
516
|
-
const
|
|
517
|
-
DictionaryValue,
|
|
518
|
-
{
|
|
519
|
-
value,
|
|
520
|
-
map: dictionaryMaps[kind],
|
|
521
|
-
fallback: value ? /* @__PURE__ */ jsx("span", { className: "text-sm", children: value }) : noValue,
|
|
522
|
-
className: "text-sm",
|
|
523
|
-
iconWrapperClassName: "inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-card",
|
|
524
|
-
iconClassName: "h-4 w-4",
|
|
525
|
-
colorClassName: "h-3 w-3 rounded-full"
|
|
526
|
-
}
|
|
527
|
-
);
|
|
528
|
-
const renderAssociationSummary = (items, fallbackLabel) => {
|
|
529
|
-
if (!items.length) return noValue;
|
|
530
|
-
const labels = normalizeCollectionLabels(
|
|
531
|
-
items.map((entry) => entry.label && entry.label.trim().length ? entry.label : fallbackLabel)
|
|
532
|
-
);
|
|
533
|
-
if (!labels.length) return noValue;
|
|
534
|
-
return /* @__PURE__ */ jsx(CollectionPreviewCell, { labels, maxVisible: 1 });
|
|
535
|
-
};
|
|
555
|
+
const unknownOwner = t("customers.deals.list.unknownOwner");
|
|
536
556
|
const customColumns = customFieldDefs.filter((def) => supportsCustomFieldColumn(def)).map((def) => ({
|
|
537
557
|
accessorKey: `cf_${def.key}`,
|
|
538
558
|
header: def.label || def.key,
|
|
@@ -577,7 +597,17 @@ function CustomersDealsPage() {
|
|
|
577
597
|
filterGroup: "Deal",
|
|
578
598
|
maxWidth: "280px"
|
|
579
599
|
},
|
|
580
|
-
cell: ({ row }) => /* @__PURE__ */
|
|
600
|
+
cell: ({ row }) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
601
|
+
/* @__PURE__ */ jsx("span", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-md bg-muted text-muted-foreground", children: /* @__PURE__ */ jsx(Briefcase, { className: "h-4 w-4" }) }),
|
|
602
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground truncate", children: row.original.title }),
|
|
603
|
+
isDealOverdue(row.original) ? /* @__PURE__ */ jsx(
|
|
604
|
+
AlertTriangle,
|
|
605
|
+
{
|
|
606
|
+
className: "h-4 w-4 shrink-0 text-status-warning-text",
|
|
607
|
+
"aria-label": t("customers.deals.list.close.overdue")
|
|
608
|
+
}
|
|
609
|
+
) : null
|
|
610
|
+
] })
|
|
581
611
|
},
|
|
582
612
|
{
|
|
583
613
|
accessorKey: "status",
|
|
@@ -589,7 +619,14 @@ function CustomersDealsPage() {
|
|
|
589
619
|
filterKey: "status",
|
|
590
620
|
filterGroup: "Deal"
|
|
591
621
|
},
|
|
592
|
-
cell: ({ row }) =>
|
|
622
|
+
cell: ({ row }) => {
|
|
623
|
+
const status = row.original.status;
|
|
624
|
+
if (!status) return noValue;
|
|
625
|
+
const entry = dictionaryMaps["deal-statuses"]?.[status];
|
|
626
|
+
const label = entry?.label ?? status;
|
|
627
|
+
const variant = coerceStatusBadgeVariant(mapDictionaryColorToTone(entry?.color));
|
|
628
|
+
return /* @__PURE__ */ jsx(StatusBadge, { variant, dot: true, children: label });
|
|
629
|
+
}
|
|
593
630
|
},
|
|
594
631
|
{
|
|
595
632
|
accessorKey: "pipelineStage",
|
|
@@ -601,7 +638,12 @@ function CustomersDealsPage() {
|
|
|
601
638
|
filterKey: "pipeline_stage",
|
|
602
639
|
filterGroup: "Deal"
|
|
603
640
|
},
|
|
604
|
-
cell: ({ row }) =>
|
|
641
|
+
cell: ({ row }) => {
|
|
642
|
+
const stage = row.original.pipelineStage;
|
|
643
|
+
if (!stage) return noValue;
|
|
644
|
+
const label = dictionaryMaps["pipeline-stages"]?.[stage]?.label ?? stage;
|
|
645
|
+
return /* @__PURE__ */ jsx("span", { className: "text-foreground", children: label });
|
|
646
|
+
}
|
|
605
647
|
},
|
|
606
648
|
{
|
|
607
649
|
accessorKey: "pipelineId",
|
|
@@ -626,7 +668,15 @@ function CustomersDealsPage() {
|
|
|
626
668
|
filterKey: "value_amount",
|
|
627
669
|
filterGroup: "Deal"
|
|
628
670
|
},
|
|
629
|
-
cell: ({ row }) =>
|
|
671
|
+
cell: ({ row }) => {
|
|
672
|
+
const amount = formatGroupedAmount(row.original.valueAmount ?? null);
|
|
673
|
+
if (amount === null) return noValue;
|
|
674
|
+
const currency = row.original.valueCurrency;
|
|
675
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
676
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: amount }),
|
|
677
|
+
currency ? /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: currency }) : null
|
|
678
|
+
] });
|
|
679
|
+
}
|
|
630
680
|
},
|
|
631
681
|
{
|
|
632
682
|
accessorKey: "probability",
|
|
@@ -640,7 +690,7 @@ function CustomersDealsPage() {
|
|
|
640
690
|
cell: ({ row }) => {
|
|
641
691
|
const value = row.original.probability;
|
|
642
692
|
if (typeof value === "number" && Number.isFinite(value)) {
|
|
643
|
-
return /* @__PURE__ */ jsx("span", { className: "text-
|
|
693
|
+
return /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: `${Math.min(Math.max(value, 0), 100)}%` });
|
|
644
694
|
}
|
|
645
695
|
return noValue;
|
|
646
696
|
}
|
|
@@ -654,7 +704,27 @@ function CustomersDealsPage() {
|
|
|
654
704
|
filterGroup: "Activity",
|
|
655
705
|
filterIconName: "calendar"
|
|
656
706
|
},
|
|
657
|
-
cell: ({ row }) =>
|
|
707
|
+
cell: ({ row }) => {
|
|
708
|
+
const expectedCloseAt = row.original.expectedCloseAt;
|
|
709
|
+
if (!expectedCloseAt) return noValue;
|
|
710
|
+
let subtitle = null;
|
|
711
|
+
if (isDealOverdue(row.original)) {
|
|
712
|
+
subtitle = /* @__PURE__ */ jsx("span", { className: "text-xs text-status-error-text", children: t("customers.deals.list.close.overdue") });
|
|
713
|
+
} else if (row.original.status === "win") {
|
|
714
|
+
subtitle = /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: t("customers.deals.list.close.won") });
|
|
715
|
+
} else if (row.original.status === "loose") {
|
|
716
|
+
subtitle = /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: t("customers.deals.list.close.lost") });
|
|
717
|
+
} else {
|
|
718
|
+
const relative = formatRelativeTime(expectedCloseAt, { translate: t });
|
|
719
|
+
if (relative) {
|
|
720
|
+
subtitle = /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: relative });
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
724
|
+
/* @__PURE__ */ jsx("span", { className: "text-foreground", children: formatDateValue(expectedCloseAt, t("customers.deals.list.noValue")) }),
|
|
725
|
+
subtitle
|
|
726
|
+
] });
|
|
727
|
+
}
|
|
658
728
|
},
|
|
659
729
|
{
|
|
660
730
|
accessorKey: "ownerUserId",
|
|
@@ -666,10 +736,17 @@ function CustomersDealsPage() {
|
|
|
666
736
|
filterLoadOptions: loadOwnerFilterOptions,
|
|
667
737
|
filterGroup: "CRM",
|
|
668
738
|
filterIconName: "user-round",
|
|
669
|
-
filterKey: "owner_user_id"
|
|
670
|
-
hidden: true
|
|
739
|
+
filterKey: "owner_user_id"
|
|
671
740
|
},
|
|
672
|
-
cell: ({ row }) =>
|
|
741
|
+
cell: ({ row }) => {
|
|
742
|
+
const ownerUserId = row.original.ownerUserId;
|
|
743
|
+
if (!ownerUserId) return noValue;
|
|
744
|
+
const label = ownerNames[ownerUserId]?.trim() || unknownOwner;
|
|
745
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
746
|
+
/* @__PURE__ */ jsx(Avatar, { label, size: "sm" }),
|
|
747
|
+
/* @__PURE__ */ jsx("span", { className: "text-foreground truncate", children: label })
|
|
748
|
+
] });
|
|
749
|
+
}
|
|
673
750
|
},
|
|
674
751
|
{
|
|
675
752
|
accessorKey: "companies",
|
|
@@ -684,7 +761,17 @@ function CustomersDealsPage() {
|
|
|
684
761
|
row.companies.map((entry) => entry.label && entry.label.trim().length ? entry.label : t("customers.deals.list.unnamedCompany"))
|
|
685
762
|
).join(", ")
|
|
686
763
|
},
|
|
687
|
-
cell: ({ row }) =>
|
|
764
|
+
cell: ({ row }) => {
|
|
765
|
+
const companies = row.original.companies;
|
|
766
|
+
if (!companies.length) return noValue;
|
|
767
|
+
const first = companies[0];
|
|
768
|
+
const firstLabel = first.label && first.label.trim().length ? first.label : t("customers.deals.list.unnamedCompany");
|
|
769
|
+
const overflow = companies.length - 1;
|
|
770
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 min-w-0", children: [
|
|
771
|
+
/* @__PURE__ */ jsx(Tag, { variant: "neutral", className: "max-w-36", children: /* @__PURE__ */ jsx("span", { className: "truncate", children: firstLabel }) }),
|
|
772
|
+
overflow > 0 ? /* @__PURE__ */ jsx(Tag, { variant: "neutral", children: `+${overflow}` }) : null
|
|
773
|
+
] });
|
|
774
|
+
}
|
|
688
775
|
},
|
|
689
776
|
{
|
|
690
777
|
accessorKey: "people",
|
|
@@ -699,7 +786,22 @@ function CustomersDealsPage() {
|
|
|
699
786
|
row.people.map((entry) => entry.label && entry.label.trim().length ? entry.label : t("customers.deals.list.unnamedPerson"))
|
|
700
787
|
).join(", ")
|
|
701
788
|
},
|
|
702
|
-
cell: ({ row }) =>
|
|
789
|
+
cell: ({ row }) => {
|
|
790
|
+
const people = row.original.people;
|
|
791
|
+
if (!people.length) return noValue;
|
|
792
|
+
const labels = normalizeCollectionLabels(
|
|
793
|
+
people.map((person) => person.label && person.label.trim().length ? person.label : t("customers.deals.list.unnamedPerson"))
|
|
794
|
+
);
|
|
795
|
+
const tooltip = labels.join(", ");
|
|
796
|
+
return /* @__PURE__ */ jsx(SimpleTooltip, { content: tooltip, side: "top", children: /* @__PURE__ */ jsx("span", { className: "inline-flex", children: /* @__PURE__ */ jsx(AvatarStack, { max: 4, size: "sm", children: people.map((person) => /* @__PURE__ */ jsx(
|
|
797
|
+
Avatar,
|
|
798
|
+
{
|
|
799
|
+
label: person.label || t("customers.deals.list.unnamedPerson"),
|
|
800
|
+
size: "sm"
|
|
801
|
+
},
|
|
802
|
+
person.id
|
|
803
|
+
)) }) }) });
|
|
804
|
+
}
|
|
703
805
|
},
|
|
704
806
|
{
|
|
705
807
|
accessorKey: "updatedAt",
|
|
@@ -714,7 +816,7 @@ function CustomersDealsPage() {
|
|
|
714
816
|
},
|
|
715
817
|
...customColumns
|
|
716
818
|
];
|
|
717
|
-
}, [customFieldDefs, dictionaryMaps, dictionaryOptions, loadOwnerFilterOptions, pipelineNames, resolvedOwnerFilterOptions, t]);
|
|
819
|
+
}, [customFieldDefs, dictionaryMaps, dictionaryOptions, isDealOverdue, loadOwnerFilterOptions, ownerNames, pipelineNames, resolvedOwnerFilterOptions, t]);
|
|
718
820
|
const { advancedFilterFields } = useAutoDiscoveredFields({ columns, customFieldDefs });
|
|
719
821
|
React.useEffect(() => {
|
|
720
822
|
setPanelFields((prev) => {
|
|
@@ -779,11 +881,24 @@ function CustomersDealsPage() {
|
|
|
779
881
|
return /* @__PURE__ */ jsxs(Page, { children: [
|
|
780
882
|
/* @__PURE__ */ jsxs(PageBody, { children: [
|
|
781
883
|
/* @__PURE__ */ jsx(ViewTabsRow, { active: "list", className: "mb-4" }),
|
|
884
|
+
/* @__PURE__ */ jsx(
|
|
885
|
+
DealsKpiStrip,
|
|
886
|
+
{
|
|
887
|
+
ownerNames,
|
|
888
|
+
stageDictionary: dictionaryMaps["pipeline-stages"] ?? {},
|
|
889
|
+
pipelineCount: Object.keys(pipelineNames).length,
|
|
890
|
+
scopeVersion,
|
|
891
|
+
reloadToken,
|
|
892
|
+
onNeedsAttentionClick: handleNeedsAttentionFilter,
|
|
893
|
+
className: "mb-4"
|
|
894
|
+
}
|
|
895
|
+
),
|
|
782
896
|
/* @__PURE__ */ jsx(
|
|
783
897
|
DataTable,
|
|
784
898
|
{
|
|
785
899
|
stickyFirstColumn: true,
|
|
786
900
|
stickyActionsColumn: true,
|
|
901
|
+
actionsColumnAlign: "center",
|
|
787
902
|
title: t("customers.deals.list.title"),
|
|
788
903
|
actions: /* @__PURE__ */ jsx(Button, { asChild: true, children: /* @__PURE__ */ jsx(Link, { href: "/backend/customers/deals/create", children: t("customers.deals.list.actions.new", "New deal") }) }),
|
|
789
904
|
columns,
|
|
@@ -871,6 +986,35 @@ function CustomersDealsPage() {
|
|
|
871
986
|
}
|
|
872
987
|
},
|
|
873
988
|
activeFilterChips: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
989
|
+
needsAttentionOnly ? /* @__PURE__ */ jsx(
|
|
990
|
+
"div",
|
|
991
|
+
{
|
|
992
|
+
className: "flex items-center gap-2 overflow-x-auto border-b border-border bg-background px-4 py-2",
|
|
993
|
+
"data-testid": "active-filter-chips",
|
|
994
|
+
children: /* @__PURE__ */ jsxs(
|
|
995
|
+
"div",
|
|
996
|
+
{
|
|
997
|
+
className: "inline-flex items-center gap-1",
|
|
998
|
+
"data-testid": "active-filter-chip",
|
|
999
|
+
"aria-label": t("customers.deals.list.filters.needsAttention"),
|
|
1000
|
+
children: [
|
|
1001
|
+
/* @__PURE__ */ jsx(Tag, { variant: "warning", dot: true, children: t("customers.deals.list.filters.needsAttention") }),
|
|
1002
|
+
/* @__PURE__ */ jsx(
|
|
1003
|
+
IconButton,
|
|
1004
|
+
{
|
|
1005
|
+
type: "button",
|
|
1006
|
+
variant: "ghost",
|
|
1007
|
+
size: "xs",
|
|
1008
|
+
"aria-label": t("customers.deals.list.filters.needsAttentionRemove"),
|
|
1009
|
+
onClick: handleNeedsAttentionClear,
|
|
1010
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-3" })
|
|
1011
|
+
}
|
|
1012
|
+
)
|
|
1013
|
+
]
|
|
1014
|
+
}
|
|
1015
|
+
)
|
|
1016
|
+
}
|
|
1017
|
+
) : null,
|
|
874
1018
|
/* @__PURE__ */ jsx(
|
|
875
1019
|
ActiveFilterChips,
|
|
876
1020
|
{
|
|
@@ -893,11 +1037,32 @@ function CustomersDealsPage() {
|
|
|
893
1037
|
)
|
|
894
1038
|
] }),
|
|
895
1039
|
filterAwareEmptyState: {
|
|
896
|
-
active: advancedFilterState.root.children.length > 0,
|
|
1040
|
+
active: needsAttentionOnly || associationFilterTree.root.children.length > 0 || advancedFilterState.root.children.length > 0,
|
|
897
1041
|
entityNamePlural: t("customers.deals.entityPlural", "deals"),
|
|
898
|
-
canRemoveLast: filterPanel.tree.root.children.length > 0,
|
|
899
|
-
onClearAll:
|
|
900
|
-
|
|
1042
|
+
canRemoveLast: needsAttentionOnly || associationFilterTree.root.children.length > 0 || filterPanel.tree.root.children.length > 0,
|
|
1043
|
+
onClearAll: () => {
|
|
1044
|
+
handleAdvancedFilterClear();
|
|
1045
|
+
setSelectedPersonIds([]);
|
|
1046
|
+
setSelectedCompanyIds([]);
|
|
1047
|
+
setNeedsAttentionOnly(false);
|
|
1048
|
+
},
|
|
1049
|
+
onRemoveLast: () => {
|
|
1050
|
+
if (needsAttentionOnly) {
|
|
1051
|
+
handleNeedsAttentionClear();
|
|
1052
|
+
return;
|
|
1053
|
+
}
|
|
1054
|
+
if (selectedCompanyIds.length > 0) {
|
|
1055
|
+
setSelectedCompanyIds([]);
|
|
1056
|
+
setPage(1);
|
|
1057
|
+
return;
|
|
1058
|
+
}
|
|
1059
|
+
if (selectedPersonIds.length > 0) {
|
|
1060
|
+
setSelectedPersonIds([]);
|
|
1061
|
+
setPage(1);
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
filterPanel.dispatch({ type: "removeLast" });
|
|
1065
|
+
}
|
|
901
1066
|
},
|
|
902
1067
|
emptyState: /* @__PURE__ */ jsx(
|
|
903
1068
|
ListEmptyState,
|