@open-mercato/core 0.5.1-develop.2663.2c29774b5b → 0.5.1-develop.2681.c559bb2bc3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/dist/generated/entities/action_log/index.js +8 -0
- package/dist/generated/entities/action_log/index.js.map +2 -2
- package/dist/generated/entities/customer_company_billing/index.js +23 -0
- package/dist/generated/entities/customer_company_billing/index.js.map +7 -0
- package/dist/generated/entities/customer_deal/index.js +8 -0
- package/dist/generated/entities/customer_deal/index.js.map +2 -2
- package/dist/generated/entities/customer_deal_stage_transition/index.js +31 -0
- package/dist/generated/entities/customer_deal_stage_transition/index.js.map +7 -0
- package/dist/generated/entities/customer_dictionary_kind_setting/index.js +21 -0
- package/dist/generated/entities/customer_dictionary_kind_setting/index.js.map +7 -0
- package/dist/generated/entities/customer_entity/index.js +8 -0
- package/dist/generated/entities/customer_entity/index.js.map +2 -2
- package/dist/generated/entities/customer_entity_role/index.js +23 -0
- package/dist/generated/entities/customer_entity_role/index.js.map +7 -0
- package/dist/generated/entities/customer_interaction/index.js +23 -1
- package/dist/generated/entities/customer_interaction/index.js.map +2 -2
- package/dist/generated/entities/customer_label/index.js +19 -0
- package/dist/generated/entities/customer_label/index.js.map +7 -0
- package/dist/generated/entities/customer_label_assignment/index.js +17 -0
- package/dist/generated/entities/customer_label_assignment/index.js.map +7 -0
- package/dist/generated/entities/customer_person_company_link/index.js +21 -0
- package/dist/generated/entities/customer_person_company_link/index.js.map +7 -0
- package/dist/generated/entities/customer_person_company_role/index.js +17 -0
- package/dist/generated/entities/customer_person_company_role/index.js.map +7 -0
- package/dist/generated/entities/dictionary_entry/index.js +4 -0
- package/dist/generated/entities/dictionary_entry/index.js.map +2 -2
- package/dist/generated/entities.ids.generated.js +9 -1
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +116 -1
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/attachments/api/route.js +46 -8
- package/dist/modules/attachments/api/route.js.map +2 -2
- package/dist/modules/audit_logs/api/audit-logs/actions/export/route.js +208 -0
- package/dist/modules/audit_logs/api/audit-logs/actions/export/route.js.map +7 -0
- package/dist/modules/audit_logs/api/audit-logs/actions/route.js +52 -6
- package/dist/modules/audit_logs/api/audit-logs/actions/route.js.map +2 -2
- package/dist/modules/audit_logs/cli.js +62 -0
- package/dist/modules/audit_logs/cli.js.map +7 -0
- package/dist/modules/audit_logs/data/entities.js +21 -1
- package/dist/modules/audit_logs/data/entities.js.map +2 -2
- package/dist/modules/audit_logs/data/validators.js +9 -1
- package/dist/modules/audit_logs/data/validators.js.map +2 -2
- package/dist/modules/audit_logs/lib/changeRows.js +34 -0
- package/dist/modules/audit_logs/lib/changeRows.js.map +7 -0
- package/dist/modules/audit_logs/lib/display-helpers.js +2 -20
- package/dist/modules/audit_logs/lib/display-helpers.js.map +3 -3
- package/dist/modules/audit_logs/lib/projections.js +58 -0
- package/dist/modules/audit_logs/lib/projections.js.map +7 -0
- package/dist/modules/audit_logs/migrations/Migration20260412160533.js +21 -0
- package/dist/modules/audit_logs/migrations/Migration20260412160533.js.map +7 -0
- package/dist/modules/audit_logs/services/actionLogService.js +313 -79
- package/dist/modules/audit_logs/services/actionLogService.js.map +2 -2
- package/dist/modules/customers/acl.js +3 -1
- package/dist/modules/customers/acl.js.map +2 -2
- package/dist/modules/customers/api/activities/route.js +4 -0
- package/dist/modules/customers/api/activities/route.js.map +2 -2
- package/dist/modules/customers/api/assignable-staff/route.js +208 -0
- package/dist/modules/customers/api/assignable-staff/route.js.map +7 -0
- package/dist/modules/customers/api/companies/[id]/people/route.js +205 -0
- package/dist/modules/customers/api/companies/[id]/people/route.js.map +7 -0
- package/dist/modules/customers/api/companies/[id]/roles/route.js +22 -0
- package/dist/modules/customers/api/companies/[id]/roles/route.js.map +7 -0
- package/dist/modules/customers/api/companies/[id]/route.js +374 -32
- package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/companies/route.js +82 -7
- package/dist/modules/customers/api/companies/route.js.map +2 -2
- package/dist/modules/customers/api/deals/[id]/companies/route.js +172 -0
- package/dist/modules/customers/api/deals/[id]/companies/route.js.map +7 -0
- package/dist/modules/customers/api/deals/[id]/people/route.js +156 -0
- package/dist/modules/customers/api/deals/[id]/people/route.js.map +7 -0
- package/dist/modules/customers/api/deals/[id]/route.js +459 -53
- package/dist/modules/customers/api/deals/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/deals/[id]/stats/route.js +195 -0
- package/dist/modules/customers/api/deals/[id]/stats/route.js.map +7 -0
- package/dist/modules/customers/api/deals/route.js +20 -10
- package/dist/modules/customers/api/deals/route.js.map +3 -3
- package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js +105 -4
- package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/dictionaries/[kind]/route.js +118 -42
- package/dist/modules/customers/api/dictionaries/[kind]/route.js.map +2 -2
- package/dist/modules/customers/api/dictionaries/context.js +30 -6
- package/dist/modules/customers/api/dictionaries/context.js.map +2 -2
- package/dist/modules/customers/api/dictionaries/kind-settings/route.js +207 -0
- package/dist/modules/customers/api/dictionaries/kind-settings/route.js.map +7 -0
- package/dist/modules/customers/api/entity-roles-factory.js +471 -0
- package/dist/modules/customers/api/entity-roles-factory.js.map +7 -0
- package/dist/modules/customers/api/interactions/conflicts/route.js +158 -0
- package/dist/modules/customers/api/interactions/conflicts/route.js.map +7 -0
- package/dist/modules/customers/api/interactions/counts/route.js +92 -0
- package/dist/modules/customers/api/interactions/counts/route.js.map +7 -0
- package/dist/modules/customers/api/interactions/route.js +83 -4
- package/dist/modules/customers/api/interactions/route.js.map +2 -2
- package/dist/modules/customers/api/labels/assign/route.js +189 -0
- package/dist/modules/customers/api/labels/assign/route.js.map +7 -0
- package/dist/modules/customers/api/labels/auth.js +17 -0
- package/dist/modules/customers/api/labels/auth.js.map +7 -0
- package/dist/modules/customers/api/labels/route.js +281 -0
- package/dist/modules/customers/api/labels/route.js.map +7 -0
- package/dist/modules/customers/api/labels/table-errors.js +38 -0
- package/dist/modules/customers/api/labels/table-errors.js.map +7 -0
- package/dist/modules/customers/api/labels/unassign/route.js +184 -0
- package/dist/modules/customers/api/labels/unassign/route.js.map +7 -0
- package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js +292 -0
- package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js.map +7 -0
- package/dist/modules/customers/api/people/[id]/companies/context.js +66 -0
- package/dist/modules/customers/api/people/[id]/companies/context.js.map +7 -0
- package/dist/modules/customers/api/people/[id]/companies/enriched/route.js +334 -0
- package/dist/modules/customers/api/people/[id]/companies/enriched/route.js.map +7 -0
- package/dist/modules/customers/api/people/[id]/companies/route.js +205 -0
- package/dist/modules/customers/api/people/[id]/companies/route.js.map +7 -0
- package/dist/modules/customers/api/people/[id]/roles/route.js +22 -0
- package/dist/modules/customers/api/people/[id]/roles/route.js.map +7 -0
- package/dist/modules/customers/api/people/[id]/route.js +134 -21
- package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/people/route.js +122 -23
- package/dist/modules/customers/api/people/route.js.map +2 -2
- package/dist/modules/customers/api/todos/route.js +4 -0
- package/dist/modules/customers/api/todos/route.js.map +2 -2
- package/dist/modules/customers/api/utils.js +22 -0
- package/dist/modules/customers/api/utils.js.map +2 -2
- package/dist/modules/customers/backend/config/customers/page.js +2 -6
- package/dist/modules/customers/backend/config/customers/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/page.js +37 -26
- package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +265 -262
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +3 -3
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/formatters.js +23 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/formatters.js.map +7 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/types.js +1 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/types.js.map +7 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js +43 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js.map +7 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.js +264 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.js.map +7 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.js +88 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.js.map +7 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js +41 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js.map +7 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js +66 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js.map +7 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealInjectedTabs.js +39 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealInjectedTabs.js.map +7 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealMutationContext.js +49 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealMutationContext.js.map +7 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.js +43 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.js.map +7 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useScheduleDialog.js +28 -0
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useScheduleDialog.js.map +7 -0
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +556 -503
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +3 -3
- package/dist/modules/customers/backend/customers/deals/page.js +66 -21
- package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/page.js +36 -28
- package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +318 -203
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +3 -3
- package/dist/modules/customers/cli.js +105 -13
- package/dist/modules/customers/cli.js.map +2 -2
- package/dist/modules/customers/commands/activities.js +6 -0
- package/dist/modules/customers/commands/activities.js.map +2 -2
- package/dist/modules/customers/commands/deals.js +315 -107
- package/dist/modules/customers/commands/deals.js.map +2 -2
- package/dist/modules/customers/commands/dictionaries.js +166 -32
- package/dist/modules/customers/commands/dictionaries.js.map +2 -2
- package/dist/modules/customers/commands/dictionaryKindSettings.js +208 -0
- package/dist/modules/customers/commands/dictionaryKindSettings.js.map +7 -0
- package/dist/modules/customers/commands/entity-roles.js +415 -0
- package/dist/modules/customers/commands/entity-roles.js.map +7 -0
- package/dist/modules/customers/commands/index.js +4 -0
- package/dist/modules/customers/commands/index.js.map +2 -2
- package/dist/modules/customers/commands/interactions.js +108 -21
- package/dist/modules/customers/commands/interactions.js.map +2 -2
- package/dist/modules/customers/commands/labels.js +539 -0
- package/dist/modules/customers/commands/labels.js.map +7 -0
- package/dist/modules/customers/commands/people.js +560 -463
- package/dist/modules/customers/commands/people.js.map +3 -3
- package/dist/modules/customers/commands/personCompanyLinks.js +568 -0
- package/dist/modules/customers/commands/personCompanyLinks.js.map +7 -0
- package/dist/modules/customers/commands/shared.js +12 -4
- package/dist/modules/customers/commands/shared.js.map +2 -2
- package/dist/modules/customers/commands/todos.js +10 -1
- package/dist/modules/customers/commands/todos.js.map +2 -2
- package/dist/modules/customers/components/AddressEditor.js +1 -1
- package/dist/modules/customers/components/AddressEditor.js.map +2 -2
- package/dist/modules/customers/components/CustomersConfigurationSections.js +31 -0
- package/dist/modules/customers/components/CustomersConfigurationSections.js.map +7 -0
- package/dist/modules/customers/components/DictionarySettings.js +37 -2
- package/dist/modules/customers/components/DictionarySettings.js.map +2 -2
- package/dist/modules/customers/components/detail/ActiveDealCard.js +121 -0
- package/dist/modules/customers/components/detail/ActiveDealCard.js.map +7 -0
- package/dist/modules/customers/components/detail/ActivitiesSection.js +222 -331
- package/dist/modules/customers/components/detail/ActivitiesSection.js.map +3 -3
- package/dist/modules/customers/components/detail/ActivityAiActions.js +36 -0
- package/dist/modules/customers/components/detail/ActivityAiActions.js.map +7 -0
- package/dist/modules/customers/components/detail/ActivityCard.js +126 -0
- package/dist/modules/customers/components/detail/ActivityCard.js.map +7 -0
- package/dist/modules/customers/components/detail/ActivityHistorySection.js +340 -0
- package/dist/modules/customers/components/detail/ActivityHistorySection.js.map +7 -0
- package/dist/modules/customers/components/detail/ActivityLogTab.js +56 -0
- package/dist/modules/customers/components/detail/ActivityLogTab.js.map +7 -0
- package/dist/modules/customers/components/detail/ActivityTimeline.js +108 -0
- package/dist/modules/customers/components/detail/ActivityTimeline.js.map +7 -0
- package/dist/modules/customers/components/detail/ActivityTimelineFilters.js +139 -0
- package/dist/modules/customers/components/detail/ActivityTimelineFilters.js.map +7 -0
- package/dist/modules/customers/components/detail/ActivityTypeSelector.js +42 -0
- package/dist/modules/customers/components/detail/ActivityTypeSelector.js.map +7 -0
- package/dist/modules/customers/components/detail/AiActionChips.js +38 -0
- package/dist/modules/customers/components/detail/AiActionChips.js.map +7 -0
- package/dist/modules/customers/components/detail/AssignRoleDialog.js +534 -0
- package/dist/modules/customers/components/detail/AssignRoleDialog.js.map +7 -0
- package/dist/modules/customers/components/detail/ChangelogEntryRow.js +79 -0
- package/dist/modules/customers/components/detail/ChangelogEntryRow.js.map +7 -0
- package/dist/modules/customers/components/detail/ChangelogFilters.js +176 -0
- package/dist/modules/customers/components/detail/ChangelogFilters.js.map +7 -0
- package/dist/modules/customers/components/detail/ChangelogKpiCards.js +88 -0
- package/dist/modules/customers/components/detail/ChangelogKpiCards.js.map +7 -0
- package/dist/modules/customers/components/detail/ChangelogTab.js +470 -0
- package/dist/modules/customers/components/detail/ChangelogTab.js.map +7 -0
- package/dist/modules/customers/components/detail/ComingSoonPlaceholder.js +16 -0
- package/dist/modules/customers/components/detail/ComingSoonPlaceholder.js.map +7 -0
- package/dist/modules/customers/components/detail/CompanyCard.js +283 -0
- package/dist/modules/customers/components/detail/CompanyCard.js.map +7 -0
- package/dist/modules/customers/components/detail/CompanyDashboardTab.js +133 -0
- package/dist/modules/customers/components/detail/CompanyDashboardTab.js.map +7 -0
- package/dist/modules/customers/components/detail/CompanyDetailHeader.js +191 -0
- package/dist/modules/customers/components/detail/CompanyDetailHeader.js.map +7 -0
- package/dist/modules/customers/components/detail/CompanyDetailTabs.js +123 -0
- package/dist/modules/customers/components/detail/CompanyDetailTabs.js.map +7 -0
- package/dist/modules/customers/components/detail/CompanyKpiBar.js +174 -0
- package/dist/modules/customers/components/detail/CompanyKpiBar.js.map +7 -0
- package/dist/modules/customers/components/detail/CompanyPeopleSection.js +514 -230
- package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
- package/dist/modules/customers/components/detail/CompanyTagsDialog.js +22 -0
- package/dist/modules/customers/components/detail/CompanyTagsDialog.js.map +7 -0
- package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js +159 -0
- package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js.map +7 -0
- package/dist/modules/customers/components/detail/CreatePersonDialog.js +135 -0
- package/dist/modules/customers/components/detail/CreatePersonDialog.js.map +7 -0
- package/dist/modules/customers/components/detail/DealClosureActionBar.js +59 -0
- package/dist/modules/customers/components/detail/DealClosureActionBar.js.map +7 -0
- package/dist/modules/customers/components/detail/DealDetailHeader.js +237 -0
- package/dist/modules/customers/components/detail/DealDetailHeader.js.map +7 -0
- package/dist/modules/customers/components/detail/DealDetailTabs.js +109 -0
- package/dist/modules/customers/components/detail/DealDetailTabs.js.map +7 -0
- package/dist/modules/customers/components/detail/DealForm.js +219 -92
- package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
- package/dist/modules/customers/components/detail/DealLinkedEntitiesTab.js +295 -0
- package/dist/modules/customers/components/detail/DealLinkedEntitiesTab.js.map +7 -0
- package/dist/modules/customers/components/detail/DealLostSummaryDialog.js +107 -0
- package/dist/modules/customers/components/detail/DealLostSummaryDialog.js.map +7 -0
- package/dist/modules/customers/components/detail/DealWonPopup.js +113 -0
- package/dist/modules/customers/components/detail/DealWonPopup.js.map +7 -0
- package/dist/modules/customers/components/detail/DealsSection.js +206 -193
- package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
- package/dist/modules/customers/components/detail/DecisionMakersFooter.js +39 -0
- package/dist/modules/customers/components/detail/DecisionMakersFooter.js.map +7 -0
- package/dist/modules/customers/components/detail/EntityTagsDialog.js +1096 -0
- package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +7 -0
- package/dist/modules/customers/components/detail/InlineActivityComposer.js +197 -0
- package/dist/modules/customers/components/detail/InlineActivityComposer.js.map +7 -0
- package/dist/modules/customers/components/detail/ManageTagsDialog.js +1091 -0
- package/dist/modules/customers/components/detail/ManageTagsDialog.js.map +7 -0
- package/dist/modules/customers/components/detail/MiniWeekCalendar.js +272 -0
- package/dist/modules/customers/components/detail/MiniWeekCalendar.js.map +7 -0
- package/dist/modules/customers/components/detail/MobilePersonDetail.js +106 -0
- package/dist/modules/customers/components/detail/MobilePersonDetail.js.map +7 -0
- package/dist/modules/customers/components/detail/NextStepCard.js +72 -0
- package/dist/modules/customers/components/detail/NextStepCard.js.map +7 -0
- package/dist/modules/customers/components/detail/PersonCard.js +192 -0
- package/dist/modules/customers/components/detail/PersonCard.js.map +7 -0
- package/dist/modules/customers/components/detail/PersonCompaniesSection.js +345 -0
- package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +7 -0
- package/dist/modules/customers/components/detail/PersonDetailHeader.js +220 -0
- package/dist/modules/customers/components/detail/PersonDetailHeader.js.map +7 -0
- package/dist/modules/customers/components/detail/PersonDetailTabs.js +122 -0
- package/dist/modules/customers/components/detail/PersonDetailTabs.js.map +7 -0
- package/dist/modules/customers/components/detail/PersonTagsDialog.js +24 -0
- package/dist/modules/customers/components/detail/PersonTagsDialog.js.map +7 -0
- package/dist/modules/customers/components/detail/PipelineStepper.js +191 -0
- package/dist/modules/customers/components/detail/PipelineStepper.js.map +7 -0
- package/dist/modules/customers/components/detail/PlannedActivitiesSection.js +222 -0
- package/dist/modules/customers/components/detail/PlannedActivitiesSection.js.map +7 -0
- package/dist/modules/customers/components/detail/RelationshipHealthCard.js +49 -0
- package/dist/modules/customers/components/detail/RelationshipHealthCard.js.map +7 -0
- package/dist/modules/customers/components/detail/RoleAssignmentRow.js +189 -0
- package/dist/modules/customers/components/detail/RoleAssignmentRow.js.map +7 -0
- package/dist/modules/customers/components/detail/RolesSection.js +234 -0
- package/dist/modules/customers/components/detail/RolesSection.js.map +7 -0
- package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +410 -0
- package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +7 -0
- package/dist/modules/customers/components/detail/aiActionCatalog.js +41 -0
- package/dist/modules/customers/components/detail/aiActionCatalog.js.map +7 -0
- package/dist/modules/customers/components/detail/assignableStaff.js +48 -0
- package/dist/modules/customers/components/detail/assignableStaff.js.map +7 -0
- package/dist/modules/customers/components/detail/dashboard/ActiveDealWidget.js +48 -0
- package/dist/modules/customers/components/detail/dashboard/ActiveDealWidget.js.map +7 -0
- package/dist/modules/customers/components/detail/dashboard/OpenTasksWidget.js +86 -0
- package/dist/modules/customers/components/detail/dashboard/OpenTasksWidget.js.map +7 -0
- package/dist/modules/customers/components/detail/dashboard/RecentActivityWidget.js +53 -0
- package/dist/modules/customers/components/detail/dashboard/RecentActivityWidget.js.map +7 -0
- package/dist/modules/customers/components/detail/dashboard/RelationshipHealthWidget.js +30 -0
- package/dist/modules/customers/components/detail/dashboard/RelationshipHealthWidget.js.map +7 -0
- package/dist/modules/customers/components/detail/dashboard/UpcomingMeetingsWidget.js +43 -0
- package/dist/modules/customers/components/detail/dashboard/UpcomingMeetingsWidget.js.map +7 -0
- package/dist/modules/customers/components/detail/dashboard/helpers.js +71 -0
- package/dist/modules/customers/components/detail/dashboard/helpers.js.map +7 -0
- package/dist/modules/customers/components/detail/healthScoreUtils.js +69 -0
- package/dist/modules/customers/components/detail/healthScoreUtils.js.map +7 -0
- package/dist/modules/customers/components/detail/hooks/useCurrencyDictionary.js +5 -5
- package/dist/modules/customers/components/detail/hooks/useCurrencyDictionary.js.map +2 -2
- package/dist/modules/customers/components/detail/hooks/useCustomerDictionary.js +9 -8
- package/dist/modules/customers/components/detail/hooks/useCustomerDictionary.js.map +3 -3
- package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js +65 -0
- package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js.map +7 -0
- package/dist/modules/customers/components/detail/notesAdapter.js +70 -30
- package/dist/modules/customers/components/detail/notesAdapter.js.map +2 -2
- package/dist/modules/customers/components/detail/pipelineStageUtils.js +26 -0
- package/dist/modules/customers/components/detail/pipelineStageUtils.js.map +7 -0
- package/dist/modules/customers/components/detail/schedule/DateTimeFields.js +144 -0
- package/dist/modules/customers/components/detail/schedule/DateTimeFields.js.map +7 -0
- package/dist/modules/customers/components/detail/schedule/FooterFields.js +60 -0
- package/dist/modules/customers/components/detail/schedule/FooterFields.js.map +7 -0
- package/dist/modules/customers/components/detail/schedule/LinkedEntitiesField.js +216 -0
- package/dist/modules/customers/components/detail/schedule/LinkedEntitiesField.js.map +7 -0
- package/dist/modules/customers/components/detail/schedule/LocationField.js +34 -0
- package/dist/modules/customers/components/detail/schedule/LocationField.js.map +7 -0
- package/dist/modules/customers/components/detail/schedule/ParticipantsField.js +226 -0
- package/dist/modules/customers/components/detail/schedule/ParticipantsField.js.map +7 -0
- package/dist/modules/customers/components/detail/schedule/fieldConfig.js +69 -0
- package/dist/modules/customers/components/detail/schedule/fieldConfig.js.map +7 -0
- package/dist/modules/customers/components/detail/schedule/index.js +21 -0
- package/dist/modules/customers/components/detail/schedule/index.js.map +7 -0
- package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js +172 -0
- package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +7 -0
- package/dist/modules/customers/components/detail/utils.js +23 -0
- package/dist/modules/customers/components/detail/utils.js.map +2 -2
- package/dist/modules/customers/components/formConfig.js +144 -22
- package/dist/modules/customers/components/formConfig.js.map +2 -2
- package/dist/modules/customers/components/linking/LinkEntityDialog.js +661 -0
- package/dist/modules/customers/components/linking/LinkEntityDialog.js.map +7 -0
- package/dist/modules/customers/components/linking/adapters/companyAdapter.js +252 -0
- package/dist/modules/customers/components/linking/adapters/companyAdapter.js.map +7 -0
- package/dist/modules/customers/components/linking/adapters/dealAdapter.js +384 -0
- package/dist/modules/customers/components/linking/adapters/dealAdapter.js.map +7 -0
- package/dist/modules/customers/components/linking/adapters/personAdapter.js +324 -0
- package/dist/modules/customers/components/linking/adapters/personAdapter.js.map +7 -0
- package/dist/modules/customers/components/list/CollectionPreviewCell.js +53 -0
- package/dist/modules/customers/components/list/CollectionPreviewCell.js.map +7 -0
- package/dist/modules/customers/data/entities.js +407 -1
- package/dist/modules/customers/data/entities.js.map +2 -2
- package/dist/modules/customers/data/validators.js +139 -21
- package/dist/modules/customers/data/validators.js.map +2 -2
- package/dist/modules/customers/events.js +19 -1
- package/dist/modules/customers/events.js.map +2 -2
- package/dist/modules/customers/lib/customerRoleTypes.js +19 -0
- package/dist/modules/customers/lib/customerRoleTypes.js.map +7 -0
- package/dist/modules/customers/lib/dealClosureNotification.js +39 -0
- package/dist/modules/customers/lib/dealClosureNotification.js.map +7 -0
- package/dist/modules/customers/lib/dealStageTransitionTable.js +29 -0
- package/dist/modules/customers/lib/dealStageTransitionTable.js.map +7 -0
- package/dist/modules/customers/lib/dictionaries.js +25 -0
- package/dist/modules/customers/lib/dictionaries.js.map +2 -2
- package/dist/modules/customers/lib/interactionReadModel.js +10 -0
- package/dist/modules/customers/lib/interactionReadModel.js.map +2 -2
- package/dist/modules/customers/lib/personCompanies.js +235 -0
- package/dist/modules/customers/lib/personCompanies.js.map +7 -0
- package/dist/modules/customers/lib/personCompanyLinkTable.js +42 -0
- package/dist/modules/customers/lib/personCompanyLinkTable.js.map +7 -0
- package/dist/modules/customers/lib/roleTypeUsage.js +104 -0
- package/dist/modules/customers/lib/roleTypeUsage.js.map +7 -0
- package/dist/modules/customers/migrations/Migration20260406214502.js +18 -0
- package/dist/modules/customers/migrations/Migration20260406214502.js.map +7 -0
- package/dist/modules/customers/migrations/Migration20260408135736.js +17 -0
- package/dist/modules/customers/migrations/Migration20260408135736.js.map +7 -0
- package/dist/modules/customers/migrations/Migration20260408225345.js +21 -0
- package/dist/modules/customers/migrations/Migration20260408225345.js.map +7 -0
- package/dist/modules/customers/migrations/Migration20260411075533.js +27 -0
- package/dist/modules/customers/migrations/Migration20260411075533.js.map +7 -0
- package/dist/modules/customers/migrations/Migration20260411103551.js +13 -0
- package/dist/modules/customers/migrations/Migration20260411103551.js.map +7 -0
- package/dist/modules/customers/migrations/Migration20260411130944.js +26 -0
- package/dist/modules/customers/migrations/Migration20260411130944.js.map +7 -0
- package/dist/modules/customers/migrations/Migration20260415095203.js +13 -0
- package/dist/modules/customers/migrations/Migration20260415095203.js.map +7 -0
- package/dist/modules/customers/migrations/Migration20260415135056.js +20 -0
- package/dist/modules/customers/migrations/Migration20260415135056.js.map +7 -0
- package/dist/modules/customers/migrations/Migration20260417140000.js +15 -0
- package/dist/modules/customers/migrations/Migration20260417140000.js.map +7 -0
- package/dist/modules/customers/migrations/Migration20260417160000.js +17 -0
- package/dist/modules/customers/migrations/Migration20260417160000.js.map +7 -0
- package/dist/modules/customers/migrations/Migration20260417235407.js +13 -0
- package/dist/modules/customers/migrations/Migration20260417235407.js.map +7 -0
- package/dist/modules/customers/setup.js +16 -1
- package/dist/modules/customers/setup.js.map +2 -2
- package/dist/modules/customers/subscribers/deal-closure-notification.js +16 -0
- package/dist/modules/customers/subscribers/deal-closure-notification.js.map +7 -0
- package/dist/modules/customers/subscribers/deal-lost-notification.js +16 -0
- package/dist/modules/customers/subscribers/deal-lost-notification.js.map +7 -0
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +2 -0
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.js +154 -0
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.js.map +7 -0
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js +6 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.js +154 -0
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.js.map +7 -0
- package/dist/modules/dictionaries/api/context.js +8 -1
- package/dist/modules/dictionaries/api/context.js.map +2 -2
- package/dist/modules/dictionaries/api/openapi.js +18 -1
- package/dist/modules/dictionaries/api/openapi.js.map +2 -2
- package/dist/modules/dictionaries/commands/entry-operations.js +388 -0
- package/dist/modules/dictionaries/commands/entry-operations.js.map +7 -0
- package/dist/modules/dictionaries/commands/factory.js +24 -3
- package/dist/modules/dictionaries/commands/factory.js.map +2 -2
- package/dist/modules/dictionaries/commands/index.js +1 -0
- package/dist/modules/dictionaries/commands/index.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionaryTable.js +6 -3
- package/dist/modules/dictionaries/components/DictionaryTable.js.map +2 -2
- package/dist/modules/dictionaries/data/entities.js +11 -1
- package/dist/modules/dictionaries/data/entities.js.map +2 -2
- package/dist/modules/dictionaries/data/validators.js +28 -2
- package/dist/modules/dictionaries/data/validators.js.map +2 -2
- package/dist/modules/dictionaries/events.js +18 -0
- package/dist/modules/dictionaries/events.js.map +7 -0
- package/dist/modules/dictionaries/lib/clientEntries.js +43 -0
- package/dist/modules/dictionaries/lib/clientEntries.js.map +7 -0
- package/dist/modules/dictionaries/migrations/Migration20260410171544.js +45 -0
- package/dist/modules/dictionaries/migrations/Migration20260410171544.js.map +7 -0
- package/dist/modules/inbox_ops/api/proposals/[id]/route.js +4 -1
- package/dist/modules/inbox_ops/api/proposals/[id]/route.js.map +2 -2
- package/dist/modules/query_index/lib/engine.js +1 -1
- package/dist/modules/query_index/lib/engine.js.map +2 -2
- package/dist/modules/sales/components/documents/AddressesSection.js +82 -42
- package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
- package/dist/modules/sales/lib/dictionaries.js +16 -0
- package/dist/modules/sales/lib/dictionaries.js.map +2 -2
- package/dist/modules/sales/widgets/injection-table.js +5 -1
- package/dist/modules/sales/widgets/injection-table.js.map +2 -2
- package/generated/entities/action_log/index.ts +4 -0
- package/generated/entities/customer_company_billing/index.ts +10 -0
- package/generated/entities/customer_deal/index.ts +4 -0
- package/generated/entities/customer_deal_stage_transition/index.ts +14 -0
- package/generated/entities/customer_dictionary_kind_setting/index.ts +9 -0
- package/generated/entities/customer_entity/index.ts +4 -0
- package/generated/entities/customer_entity_role/index.ts +10 -0
- package/generated/entities/customer_interaction/index.ts +11 -0
- package/generated/entities/customer_label/index.ts +8 -0
- package/generated/entities/customer_label_assignment/index.ts +7 -0
- package/generated/entities/customer_person_company_link/index.ts +9 -0
- package/generated/entities/customer_person_company_role/index.ts +7 -0
- package/generated/entities/dictionary_entry/index.ts +2 -0
- package/generated/entities.ids.generated.ts +9 -1
- package/generated/entity-fields-registry.ts +116 -1
- package/package.json +3 -3
- package/src/modules/attachments/api/route.ts +48 -6
- package/src/modules/attachments/i18n/de.json +4 -0
- package/src/modules/attachments/i18n/en.json +4 -0
- package/src/modules/attachments/i18n/es.json +4 -0
- package/src/modules/attachments/i18n/pl.json +4 -0
- package/src/modules/audit_logs/api/audit-logs/actions/export/route.ts +260 -0
- package/src/modules/audit_logs/api/audit-logs/actions/route.ts +81 -6
- package/src/modules/audit_logs/cli.ts +79 -0
- package/src/modules/audit_logs/data/entities.ts +17 -0
- package/src/modules/audit_logs/data/validators.ts +9 -1
- package/src/modules/audit_logs/lib/changeRows.ts +47 -0
- package/src/modules/audit_logs/lib/display-helpers.tsx +4 -30
- package/src/modules/audit_logs/lib/projections.ts +110 -0
- package/src/modules/audit_logs/migrations/.snapshot-open-mercato.json +325 -2
- package/src/modules/audit_logs/migrations/Migration20260412160533.ts +21 -0
- package/src/modules/audit_logs/services/actionLogService.ts +455 -85
- package/src/modules/catalog/i18n/de.json +1 -0
- package/src/modules/catalog/i18n/en.json +1 -0
- package/src/modules/catalog/i18n/es.json +1 -0
- package/src/modules/catalog/i18n/pl.json +1 -0
- package/src/modules/customer_accounts/i18n/de.json +2 -0
- package/src/modules/customer_accounts/i18n/en.json +2 -0
- package/src/modules/customer_accounts/i18n/es.json +2 -0
- package/src/modules/customer_accounts/i18n/pl.json +2 -0
- package/src/modules/customers/acl.ts +2 -0
- package/src/modules/customers/api/activities/route.ts +4 -0
- package/src/modules/customers/api/assignable-staff/route.ts +250 -0
- package/src/modules/customers/api/companies/[id]/people/route.ts +244 -0
- package/src/modules/customers/api/companies/[id]/roles/route.ts +15 -0
- package/src/modules/customers/api/companies/[id]/route.ts +458 -40
- package/src/modules/customers/api/companies/route.ts +93 -15
- package/src/modules/customers/api/deals/[id]/companies/route.ts +203 -0
- package/src/modules/customers/api/deals/[id]/people/route.ts +182 -0
- package/src/modules/customers/api/deals/[id]/route.ts +554 -57
- package/src/modules/customers/api/deals/[id]/stats/route.ts +221 -0
- package/src/modules/customers/api/deals/route.ts +35 -46
- package/src/modules/customers/api/dictionaries/[kind]/[id]/route.ts +105 -3
- package/src/modules/customers/api/dictionaries/[kind]/route.ts +143 -44
- package/src/modules/customers/api/dictionaries/context.ts +45 -16
- package/src/modules/customers/api/dictionaries/kind-settings/route.ts +232 -0
- package/src/modules/customers/api/entity-roles-factory.ts +520 -0
- package/src/modules/customers/api/interactions/conflicts/route.ts +196 -0
- package/src/modules/customers/api/interactions/counts/route.ts +112 -0
- package/src/modules/customers/api/interactions/route.ts +95 -2
- package/src/modules/customers/api/labels/assign/route.ts +202 -0
- package/src/modules/customers/api/labels/auth.ts +19 -0
- package/src/modules/customers/api/labels/route.ts +310 -0
- package/src/modules/customers/api/labels/table-errors.ts +36 -0
- package/src/modules/customers/api/labels/unassign/route.ts +197 -0
- package/src/modules/customers/api/people/[id]/companies/[linkId]/route.ts +331 -0
- package/src/modules/customers/api/people/[id]/companies/context.ts +70 -0
- package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +384 -0
- package/src/modules/customers/api/people/[id]/companies/route.ts +215 -0
- package/src/modules/customers/api/people/[id]/roles/route.ts +15 -0
- package/src/modules/customers/api/people/[id]/route.ts +153 -26
- package/src/modules/customers/api/people/route.ts +134 -31
- package/src/modules/customers/api/todos/route.ts +4 -0
- package/src/modules/customers/api/utils.ts +36 -0
- package/src/modules/customers/backend/config/customers/page.tsx +2 -6
- package/src/modules/customers/backend/customers/companies/page.tsx +36 -26
- package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +277 -262
- package/src/modules/customers/backend/customers/deals/[id]/hooks/formatters.ts +19 -0
- package/src/modules/customers/backend/customers/deals/[id]/hooks/types.ts +104 -0
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.ts +60 -0
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.ts +362 -0
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.ts +113 -0
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealData.ts +52 -0
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.ts +86 -0
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealInjectedTabs.tsx +60 -0
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealMutationContext.ts +76 -0
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.ts +56 -0
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useScheduleDialog.ts +38 -0
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +587 -624
- package/src/modules/customers/backend/customers/deals/page.tsx +71 -28
- package/src/modules/customers/backend/customers/people/page.tsx +35 -29
- package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +343 -209
- package/src/modules/customers/cli.ts +107 -12
- package/src/modules/customers/commands/activities.ts +13 -0
- package/src/modules/customers/commands/deals.ts +386 -114
- package/src/modules/customers/commands/dictionaries.ts +175 -32
- package/src/modules/customers/commands/dictionaryKindSettings.ts +268 -0
- package/src/modules/customers/commands/entity-roles.ts +494 -0
- package/src/modules/customers/commands/index.ts +4 -0
- package/src/modules/customers/commands/interactions.ts +125 -21
- package/src/modules/customers/commands/labels.ts +626 -0
- package/src/modules/customers/commands/people.ts +373 -259
- package/src/modules/customers/commands/personCompanyLinks.ts +654 -0
- package/src/modules/customers/commands/shared.ts +16 -15
- package/src/modules/customers/commands/todos.ts +17 -1
- package/src/modules/customers/components/AddressEditor.tsx +1 -1
- package/src/modules/customers/components/CustomersConfigurationSections.tsx +36 -0
- package/src/modules/customers/components/DictionarySettings.tsx +43 -2
- package/src/modules/customers/components/detail/ActiveDealCard.tsx +175 -0
- package/src/modules/customers/components/detail/ActivitiesSection.tsx +267 -361
- package/src/modules/customers/components/detail/ActivityAiActions.tsx +49 -0
- package/src/modules/customers/components/detail/ActivityCard.tsx +154 -0
- package/src/modules/customers/components/detail/ActivityHistorySection.tsx +412 -0
- package/src/modules/customers/components/detail/ActivityLogTab.tsx +67 -0
- package/src/modules/customers/components/detail/ActivityTimeline.tsx +158 -0
- package/src/modules/customers/components/detail/ActivityTimelineFilters.tsx +163 -0
- package/src/modules/customers/components/detail/ActivityTypeSelector.tsx +53 -0
- package/src/modules/customers/components/detail/AiActionChips.tsx +48 -0
- package/src/modules/customers/components/detail/AssignRoleDialog.tsx +672 -0
- package/src/modules/customers/components/detail/ChangelogEntryRow.tsx +132 -0
- package/src/modules/customers/components/detail/ChangelogFilters.tsx +193 -0
- package/src/modules/customers/components/detail/ChangelogKpiCards.tsx +107 -0
- package/src/modules/customers/components/detail/ChangelogTab.tsx +629 -0
- package/src/modules/customers/components/detail/ComingSoonPlaceholder.tsx +21 -0
- package/src/modules/customers/components/detail/CompanyCard.tsx +419 -0
- package/src/modules/customers/components/detail/CompanyDashboardTab.tsx +161 -0
- package/src/modules/customers/components/detail/CompanyDetailHeader.tsx +243 -0
- package/src/modules/customers/components/detail/CompanyDetailTabs.tsx +172 -0
- package/src/modules/customers/components/detail/CompanyKpiBar.tsx +206 -0
- package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +582 -288
- package/src/modules/customers/components/detail/CompanyTagsDialog.tsx +23 -0
- package/src/modules/customers/components/detail/ConfirmDealLostDialog.tsx +210 -0
- package/src/modules/customers/components/detail/CreatePersonDialog.tsx +178 -0
- package/src/modules/customers/components/detail/DealClosureActionBar.tsx +63 -0
- package/src/modules/customers/components/detail/DealDetailHeader.tsx +335 -0
- package/src/modules/customers/components/detail/DealDetailTabs.tsx +154 -0
- package/src/modules/customers/components/detail/DealForm.tsx +253 -101
- package/src/modules/customers/components/detail/DealLinkedEntitiesTab.tsx +349 -0
- package/src/modules/customers/components/detail/DealLostSummaryDialog.tsx +156 -0
- package/src/modules/customers/components/detail/DealWonPopup.tsx +164 -0
- package/src/modules/customers/components/detail/DealsSection.tsx +276 -221
- package/src/modules/customers/components/detail/DecisionMakersFooter.tsx +56 -0
- package/src/modules/customers/components/detail/EntityTagsDialog.tsx +1372 -0
- package/src/modules/customers/components/detail/InlineActivityComposer.tsx +239 -0
- package/src/modules/customers/components/detail/ManageTagsDialog.tsx +1331 -0
- package/src/modules/customers/components/detail/MiniWeekCalendar.tsx +338 -0
- package/src/modules/customers/components/detail/MobilePersonDetail.tsx +124 -0
- package/src/modules/customers/components/detail/NextStepCard.tsx +104 -0
- package/src/modules/customers/components/detail/PersonCard.tsx +238 -0
- package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +426 -0
- package/src/modules/customers/components/detail/PersonDetailHeader.tsx +294 -0
- package/src/modules/customers/components/detail/PersonDetailTabs.tsx +172 -0
- package/src/modules/customers/components/detail/PersonTagsDialog.tsx +26 -0
- package/src/modules/customers/components/detail/PipelineStepper.tsx +245 -0
- package/src/modules/customers/components/detail/PlannedActivitiesSection.tsx +255 -0
- package/src/modules/customers/components/detail/RelationshipHealthCard.tsx +63 -0
- package/src/modules/customers/components/detail/RoleAssignmentRow.tsx +248 -0
- package/src/modules/customers/components/detail/RolesSection.tsx +311 -0
- package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +481 -0
- package/src/modules/customers/components/detail/aiActionCatalog.ts +77 -0
- package/src/modules/customers/components/detail/assignableStaff.ts +124 -0
- package/src/modules/customers/components/detail/dashboard/ActiveDealWidget.tsx +63 -0
- package/src/modules/customers/components/detail/dashboard/OpenTasksWidget.tsx +114 -0
- package/src/modules/customers/components/detail/dashboard/RecentActivityWidget.tsx +69 -0
- package/src/modules/customers/components/detail/dashboard/RelationshipHealthWidget.tsx +40 -0
- package/src/modules/customers/components/detail/dashboard/UpcomingMeetingsWidget.tsx +64 -0
- package/src/modules/customers/components/detail/dashboard/helpers.ts +78 -0
- package/src/modules/customers/components/detail/healthScoreUtils.ts +91 -0
- package/src/modules/customers/components/detail/hooks/useCurrencyDictionary.ts +8 -8
- package/src/modules/customers/components/detail/hooks/useCustomerDictionary.ts +10 -6
- package/src/modules/customers/components/detail/hooks/useInteractionMutations.ts +91 -0
- package/src/modules/customers/components/detail/notesAdapter.ts +91 -30
- package/src/modules/customers/components/detail/pipelineStageUtils.ts +29 -0
- package/src/modules/customers/components/detail/schedule/DateTimeFields.tsx +187 -0
- package/src/modules/customers/components/detail/schedule/FooterFields.tsx +79 -0
- package/src/modules/customers/components/detail/schedule/LinkedEntitiesField.tsx +277 -0
- package/src/modules/customers/components/detail/schedule/LocationField.tsx +42 -0
- package/src/modules/customers/components/detail/schedule/ParticipantsField.tsx +255 -0
- package/src/modules/customers/components/detail/schedule/fieldConfig.ts +70 -0
- package/src/modules/customers/components/detail/schedule/index.ts +9 -0
- package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +221 -0
- package/src/modules/customers/components/detail/types.ts +16 -0
- package/src/modules/customers/components/detail/utils.ts +25 -0
- package/src/modules/customers/components/formConfig.tsx +223 -28
- package/src/modules/customers/components/linking/LinkEntityDialog.tsx +920 -0
- package/src/modules/customers/components/linking/adapters/companyAdapter.tsx +398 -0
- package/src/modules/customers/components/linking/adapters/dealAdapter.tsx +578 -0
- package/src/modules/customers/components/linking/adapters/personAdapter.tsx +512 -0
- package/src/modules/customers/components/list/CollectionPreviewCell.tsx +66 -0
- package/src/modules/customers/data/entities.ts +353 -1
- package/src/modules/customers/data/validators.ts +170 -19
- package/src/modules/customers/events.ts +22 -0
- package/src/modules/customers/i18n/de.json +841 -2
- package/src/modules/customers/i18n/en.json +841 -2
- package/src/modules/customers/i18n/es.json +840 -1
- package/src/modules/customers/i18n/pl.json +841 -2
- package/src/modules/customers/lib/customerRoleTypes.ts +24 -0
- package/src/modules/customers/lib/dealClosureNotification.ts +64 -0
- package/src/modules/customers/lib/dealStageTransitionTable.ts +32 -0
- package/src/modules/customers/lib/dictionaries.ts +26 -10
- package/src/modules/customers/lib/interactionReadModel.ts +10 -0
- package/src/modules/customers/lib/personCompanies.ts +317 -0
- package/src/modules/customers/lib/personCompanyLinkTable.ts +58 -0
- package/src/modules/customers/lib/roleTypeUsage.ts +146 -0
- package/src/modules/customers/migrations/.snapshot-open-mercato.json +2747 -798
- package/src/modules/customers/migrations/Migration20260406214502.ts +19 -0
- package/src/modules/customers/migrations/Migration20260408135736.ts +15 -0
- package/src/modules/customers/migrations/Migration20260408225345.ts +23 -0
- package/src/modules/customers/migrations/Migration20260411075533.ts +30 -0
- package/src/modules/customers/migrations/Migration20260411103551.ts +13 -0
- package/src/modules/customers/migrations/Migration20260411130944.ts +30 -0
- package/src/modules/customers/migrations/Migration20260415095203.ts +13 -0
- package/src/modules/customers/migrations/Migration20260415135056.ts +22 -0
- package/src/modules/customers/migrations/Migration20260417140000.ts +15 -0
- package/src/modules/customers/migrations/Migration20260417160000.ts +17 -0
- package/src/modules/customers/migrations/Migration20260417235407.ts +13 -0
- package/src/modules/customers/setup.ts +15 -0
- package/src/modules/customers/subscribers/deal-closure-notification.ts +22 -0
- package/src/modules/customers/subscribers/deal-lost-notification.ts +22 -0
- package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +2 -0
- package/src/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.ts +162 -0
- package/src/modules/dictionaries/api/[dictionaryId]/entries/route.ts +6 -2
- package/src/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.ts +162 -0
- package/src/modules/dictionaries/api/context.ts +9 -0
- package/src/modules/dictionaries/api/openapi.ts +17 -0
- package/src/modules/dictionaries/commands/entry-operations.ts +457 -0
- package/src/modules/dictionaries/commands/factory.ts +31 -3
- package/src/modules/dictionaries/commands/index.ts +1 -0
- package/src/modules/dictionaries/components/DictionaryTable.tsx +15 -6
- package/src/modules/dictionaries/data/entities.ts +9 -0
- package/src/modules/dictionaries/data/validators.ts +34 -0
- package/src/modules/dictionaries/events.ts +20 -0
- package/src/modules/dictionaries/i18n/de.json +2 -0
- package/src/modules/dictionaries/i18n/en.json +2 -0
- package/src/modules/dictionaries/i18n/es.json +2 -0
- package/src/modules/dictionaries/i18n/pl.json +2 -0
- package/src/modules/dictionaries/lib/clientEntries.ts +66 -0
- package/src/modules/dictionaries/migrations/.snapshot-open-mercato.json +185 -3
- package/src/modules/dictionaries/migrations/Migration20260410171544.ts +49 -0
- package/src/modules/inbox_ops/api/proposals/[id]/route.ts +4 -1
- package/src/modules/query_index/lib/engine.ts +9 -1
- package/src/modules/sales/components/documents/AddressesSection.tsx +92 -42
- package/src/modules/sales/i18n/de.json +28 -0
- package/src/modules/sales/i18n/en.json +28 -0
- package/src/modules/sales/i18n/es.json +28 -0
- package/src/modules/sales/i18n/pl.json +28 -0
- package/src/modules/sales/lib/dictionaries.ts +18 -0
- package/src/modules/sales/widgets/injection-table.ts +4 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/customers/components/detail/schedule/FooterFields.tsx"],
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport { Bell, Eye, ChevronDown } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type { ActivityType, ScheduleFieldId } from './fieldConfig'\nimport { isVisible, getFieldLabel } from './fieldConfig'\n\nconst REMINDER_OPTIONS = [0, 5, 10, 15, 30, 60]\n\ninterface FooterFieldsProps {\n visible: Set<ScheduleFieldId>\n activityType: ActivityType\n reminderMinutes: number\n setReminderMinutes: (value: number) => void\n visibility: string\n setVisibility: (value: string) => void\n}\n\nexport function FooterFields({\n visible,\n activityType,\n reminderMinutes,\n setReminderMinutes,\n visibility,\n setVisibility,\n}: FooterFieldsProps) {\n const t = useT()\n\n const showReminder = isVisible(activityType, 'reminder')\n const showVisibility = isVisible(activityType, 'visibility')\n\n if (!showReminder && !showVisibility) return null\n\n return (\n <div className=\"flex gap-3\">\n {showReminder && (\n <div className=\"flex flex-1 flex-col gap-1.5\">\n <label className=\"text-overline font-semibold text-muted-foreground tracking-wider\">\n {getFieldLabel(activityType, 'reminder', t, 'customers.schedule.reminder', 'Reminder')}\n </label>\n <div className=\"flex items-center gap-2 rounded-md border border-border bg-background px-3 py-2.5\">\n <Bell className=\"size-3.5 text-muted-foreground\" />\n <select\n value={reminderMinutes}\n onChange={(e) => setReminderMinutes(Number(e.target.value))}\n className=\"flex-1 appearance-none bg-transparent text-sm text-foreground focus:outline-none\"\n >\n {REMINDER_OPTIONS.map((m) => (\n <option key={m} value={m}>\n {m === 0 ? t('customers.schedule.reminder.none', 'None') : `${m} min`}\n </option>\n ))}\n </select>\n <ChevronDown className=\"size-3.5 text-muted-foreground\" />\n </div>\n </div>\n )}\n {showVisibility && (\n <div className=\"flex flex-1 flex-col gap-1.5\">\n <label className=\"text-overline font-semibold text-muted-foreground tracking-wider\">\n {getFieldLabel(activityType, 'visibility', t, 'customers.schedule.visibility', 'Visibility')}\n </label>\n <div className=\"flex items-center gap-2 rounded-md border border-border bg-background px-3 py-2.5\">\n <Eye className=\"size-3.5 text-muted-foreground\" />\n <select\n value={visibility}\n onChange={(e) => setVisibility(e.target.value)}\n className=\"flex-1 appearance-none bg-transparent text-sm text-foreground focus:outline-none\"\n >\n <option value=\"team\">{t('customers.schedule.visibility.team', 'Team only')}</option>\n <option value=\"public\">{t('customers.schedule.visibility.public', 'Public')}</option>\n </select>\n <ChevronDown className=\"size-3.5 text-muted-foreground\" />\n </div>\n </div>\n )}\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": ";AAqCU,cAGA,YAHA;AAnCV,SAAS,MAAM,KAAK,mBAAmB;AACvC,SAAS,YAAY;AAErB,SAAS,WAAW,qBAAqB;AAEzC,MAAM,mBAAmB,CAAC,GAAG,GAAG,IAAI,IAAI,IAAI,EAAE;AAWvC,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,QAAM,IAAI,KAAK;AAEf,QAAM,eAAe,UAAU,cAAc,UAAU;AACvD,QAAM,iBAAiB,UAAU,cAAc,YAAY;AAE3D,MAAI,CAAC,gBAAgB,CAAC,eAAgB,QAAO;AAE7C,SACE,qBAAC,SAAI,WAAU,cACZ;AAAA,oBACC,qBAAC,SAAI,WAAU,gCACb;AAAA,0BAAC,WAAM,WAAU,oEACd,wBAAc,cAAc,YAAY,GAAG,+BAA+B,UAAU,GACvF;AAAA,MACA,qBAAC,SAAI,WAAU,qFACb;AAAA,4BAAC,QAAK,WAAU,kCAAiC;AAAA,QACjD;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,mBAAmB,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,YAC1D,WAAU;AAAA,YAET,2BAAiB,IAAI,CAAC,MACrB,oBAAC,YAAe,OAAO,GACpB,gBAAM,IAAI,EAAE,oCAAoC,MAAM,IAAI,GAAG,CAAC,UADpD,CAEb,CACD;AAAA;AAAA,QACH;AAAA,QACA,oBAAC,eAAY,WAAU,kCAAiC;AAAA,SAC1D;AAAA,OACF;AAAA,IAED,kBACC,qBAAC,SAAI,WAAU,gCACb;AAAA,0BAAC,WAAM,WAAU,oEACd,wBAAc,cAAc,cAAc,GAAG,iCAAiC,YAAY,GAC7F;AAAA,MACA,qBAAC,SAAI,WAAU,qFACb;AAAA,4BAAC,OAAI,WAAU,kCAAiC;AAAA,QAChD;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,cAAc,EAAE,OAAO,KAAK;AAAA,YAC7C,WAAU;AAAA,YAEV;AAAA,kCAAC,YAAO,OAAM,QAAQ,YAAE,sCAAsC,WAAW,GAAE;AAAA,cAC3E,oBAAC,YAAO,OAAM,UAAU,YAAE,wCAAwC,QAAQ,GAAE;AAAA;AAAA;AAAA,QAC9E;AAAA,QACA,oBAAC,eAAY,WAAU,kCAAiC;AAAA,SAC1D;AAAA,OACF;AAAA,KAEJ;AAEJ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Building2, Briefcase, FileText, Search, X } from "lucide-react";
|
|
5
|
+
import { cn } from "@open-mercato/shared/lib/utils";
|
|
6
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
7
|
+
import { readApiResultOrThrow } from "@open-mercato/ui/backend/utils/apiCall";
|
|
8
|
+
import { Button } from "@open-mercato/ui/primitives/button";
|
|
9
|
+
import { IconButton } from "@open-mercato/ui/primitives/icon-button";
|
|
10
|
+
import { Popover, PopoverContent, PopoverTrigger } from "@open-mercato/ui/primitives/popover";
|
|
11
|
+
import { isVisible } from "./fieldConfig.js";
|
|
12
|
+
const ENTITY_LINK_TYPES = ["company", "deal", "offer"];
|
|
13
|
+
function readLabelCandidate(value) {
|
|
14
|
+
if (typeof value !== "string") return null;
|
|
15
|
+
const trimmed = value.trim();
|
|
16
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
17
|
+
}
|
|
18
|
+
function resolveLinkedEntityLabel(item, linkType) {
|
|
19
|
+
if (linkType === "offer") {
|
|
20
|
+
const quoteNumber = readLabelCandidate(item.quoteNumber) ?? readLabelCandidate(item.quote_number) ?? readLabelCandidate(item.documentNumber) ?? readLabelCandidate(item.document_number) ?? readLabelCandidate(item.externalReference) ?? readLabelCandidate(item.external_reference);
|
|
21
|
+
const customerName = readLabelCandidate(item.customerName) ?? readLabelCandidate(item.customer_name) ?? readLabelCandidate(item.display_name) ?? readLabelCandidate(item.displayName) ?? readLabelCandidate(item.name) ?? readLabelCandidate(item.title);
|
|
22
|
+
if (quoteNumber && customerName) return `${quoteNumber} \xB7 ${customerName}`;
|
|
23
|
+
if (quoteNumber) return quoteNumber;
|
|
24
|
+
if (customerName) return customerName;
|
|
25
|
+
}
|
|
26
|
+
if (linkType === "deal") {
|
|
27
|
+
const dealLabel = readLabelCandidate(item.title) ?? readLabelCandidate(item.name) ?? readLabelCandidate(item.display_name) ?? readLabelCandidate(item.displayName);
|
|
28
|
+
if (dealLabel) return dealLabel;
|
|
29
|
+
}
|
|
30
|
+
return readLabelCandidate(item.display_name) ?? readLabelCandidate(item.displayName) ?? readLabelCandidate(item.name) ?? readLabelCandidate(item.title) ?? String(item.id ?? "");
|
|
31
|
+
}
|
|
32
|
+
function EntityLinkSearchPopover({
|
|
33
|
+
existingIds,
|
|
34
|
+
onAdd,
|
|
35
|
+
onAddMany,
|
|
36
|
+
t
|
|
37
|
+
}) {
|
|
38
|
+
const [open, setOpen] = React.useState(false);
|
|
39
|
+
const [linkType, setLinkType] = React.useState("company");
|
|
40
|
+
const [query, setQuery] = React.useState("");
|
|
41
|
+
const [results, setResults] = React.useState([]);
|
|
42
|
+
const [page, setPage] = React.useState(1);
|
|
43
|
+
const [totalPages, setTotalPages] = React.useState(1);
|
|
44
|
+
const [loading, setLoading] = React.useState(false);
|
|
45
|
+
const selectableResults = React.useMemo(
|
|
46
|
+
() => results.filter((result) => !existingIds.has(result.id)),
|
|
47
|
+
[existingIds, results]
|
|
48
|
+
);
|
|
49
|
+
React.useEffect(() => {
|
|
50
|
+
if (!open) return;
|
|
51
|
+
const controller = new AbortController();
|
|
52
|
+
setLoading(true);
|
|
53
|
+
const searchParam = query.trim() ? `&search=${encodeURIComponent(query.trim())}` : "";
|
|
54
|
+
const pagingParam = `&page=${page}&pageSize=20`;
|
|
55
|
+
const endpoint = linkType === "company" ? `/api/customers/companies?sortField=name&sortDir=asc${pagingParam}${searchParam}` : linkType === "deal" ? `/api/customers/deals?pageSize=20&page=${page}${searchParam}` : `/api/sales/quotes?pageSize=20&page=${page}${searchParam}`;
|
|
56
|
+
readApiResultOrThrow(endpoint, { signal: controller.signal }).then((data) => {
|
|
57
|
+
const items = Array.isArray(data?.items) ? data.items : [];
|
|
58
|
+
const nextResults = items.map((item) => ({
|
|
59
|
+
id: typeof item?.id === "string" ? item.id : "",
|
|
60
|
+
label: resolveLinkedEntityLabel(item, linkType)
|
|
61
|
+
})).filter((r) => r.id);
|
|
62
|
+
setResults((current) => {
|
|
63
|
+
if (page <= 1) return nextResults;
|
|
64
|
+
const merged = new Map(current.map((entry) => [entry.id, entry]));
|
|
65
|
+
nextResults.forEach((entry) => merged.set(entry.id, entry));
|
|
66
|
+
return Array.from(merged.values());
|
|
67
|
+
});
|
|
68
|
+
if (typeof data?.totalPages === "number") {
|
|
69
|
+
setTotalPages(data.totalPages);
|
|
70
|
+
} else if (typeof data?.total === "number" && typeof data?.pageSize === "number") {
|
|
71
|
+
setTotalPages(Math.max(1, Math.ceil(data.total / data.pageSize)));
|
|
72
|
+
} else {
|
|
73
|
+
setTotalPages(1);
|
|
74
|
+
}
|
|
75
|
+
}).catch(() => setResults([])).finally(() => setLoading(false));
|
|
76
|
+
return () => controller.abort();
|
|
77
|
+
}, [open, page, query, linkType]);
|
|
78
|
+
React.useEffect(() => {
|
|
79
|
+
if (!open) return;
|
|
80
|
+
setPage(1);
|
|
81
|
+
}, [open, query, linkType]);
|
|
82
|
+
return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
|
|
83
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "h-auto inline-flex items-center gap-1.5 rounded-full border border-border bg-background px-2.5 py-1.5 text-xs text-muted-foreground", children: [
|
|
84
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm", children: "+" }),
|
|
85
|
+
t("customers.schedule.addLink", "Add link")
|
|
86
|
+
] }) }),
|
|
87
|
+
/* @__PURE__ */ jsxs(PopoverContent, { align: "start", className: "w-72 p-2", children: [
|
|
88
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-1 mb-2", children: ENTITY_LINK_TYPES.map((type) => /* @__PURE__ */ jsxs(
|
|
89
|
+
Button,
|
|
90
|
+
{
|
|
91
|
+
type: "button",
|
|
92
|
+
variant: linkType === type ? "default" : "ghost",
|
|
93
|
+
size: "sm",
|
|
94
|
+
className: "h-6 text-xs flex-1",
|
|
95
|
+
onClick: () => {
|
|
96
|
+
setLinkType(type);
|
|
97
|
+
setQuery("");
|
|
98
|
+
},
|
|
99
|
+
children: [
|
|
100
|
+
type === "company" ? /* @__PURE__ */ jsx(Building2, { className: "mr-1 size-3" }) : type === "deal" ? /* @__PURE__ */ jsx(Briefcase, { className: "mr-1 size-3" }) : /* @__PURE__ */ jsx(FileText, { className: "mr-1 size-3" }),
|
|
101
|
+
type === "company" ? t("customers.schedule.linkType.company", "Company") : type === "deal" ? t("customers.schedule.linkType.deal", "Deal") : t("customers.schedule.linkType.offer", "Offer")
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
type
|
|
105
|
+
)) }),
|
|
106
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 rounded-md border bg-background px-2 py-1.5 mb-2", children: [
|
|
107
|
+
/* @__PURE__ */ jsx(Search, { className: "size-3.5 text-muted-foreground shrink-0" }),
|
|
108
|
+
/* @__PURE__ */ jsx(
|
|
109
|
+
"input",
|
|
110
|
+
{
|
|
111
|
+
type: "text",
|
|
112
|
+
value: query,
|
|
113
|
+
onChange: (e) => setQuery(e.target.value),
|
|
114
|
+
placeholder: t("customers.schedule.searchEntity", "Search..."),
|
|
115
|
+
className: "flex-1 bg-transparent text-sm focus:outline-none",
|
|
116
|
+
autoFocus: true
|
|
117
|
+
}
|
|
118
|
+
)
|
|
119
|
+
] }),
|
|
120
|
+
selectableResults.length ? /* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsx(
|
|
121
|
+
Button,
|
|
122
|
+
{
|
|
123
|
+
type: "button",
|
|
124
|
+
variant: "outline",
|
|
125
|
+
size: "sm",
|
|
126
|
+
className: "w-full",
|
|
127
|
+
onClick: () => {
|
|
128
|
+
onAddMany(
|
|
129
|
+
selectableResults.map((result) => ({
|
|
130
|
+
id: result.id,
|
|
131
|
+
type: linkType,
|
|
132
|
+
label: result.label
|
|
133
|
+
}))
|
|
134
|
+
);
|
|
135
|
+
setOpen(false);
|
|
136
|
+
setQuery("");
|
|
137
|
+
},
|
|
138
|
+
children: t("customers.schedule.addVisibleLinks", "Add all visible")
|
|
139
|
+
}
|
|
140
|
+
) }) : null,
|
|
141
|
+
/* @__PURE__ */ jsxs("div", { className: "max-h-48 overflow-y-auto space-y-0.5", children: [
|
|
142
|
+
loading && /* @__PURE__ */ jsx("p", { className: "px-2 py-3 text-xs text-muted-foreground text-center", children: t("customers.schedule.searching", "Searching...") }),
|
|
143
|
+
!loading && results.length === 0 && /* @__PURE__ */ jsx("p", { className: "px-2 py-3 text-xs text-muted-foreground text-center", children: t("customers.schedule.noResults", "No results") }),
|
|
144
|
+
results.map((r) => {
|
|
145
|
+
const alreadyLinked = existingIds.has(r.id);
|
|
146
|
+
return /* @__PURE__ */ jsxs(
|
|
147
|
+
Button,
|
|
148
|
+
{
|
|
149
|
+
type: "button",
|
|
150
|
+
variant: "ghost",
|
|
151
|
+
size: "sm",
|
|
152
|
+
disabled: alreadyLinked,
|
|
153
|
+
onClick: () => {
|
|
154
|
+
onAdd({ id: r.id, type: linkType, label: r.label });
|
|
155
|
+
setOpen(false);
|
|
156
|
+
setQuery("");
|
|
157
|
+
},
|
|
158
|
+
className: cn(
|
|
159
|
+
"h-auto flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors",
|
|
160
|
+
alreadyLinked ? "opacity-40 cursor-default" : "hover:bg-accent cursor-pointer"
|
|
161
|
+
),
|
|
162
|
+
children: [
|
|
163
|
+
linkType === "company" ? /* @__PURE__ */ jsx(Building2, { className: "size-3.5 text-muted-foreground shrink-0" }) : linkType === "deal" ? /* @__PURE__ */ jsx(Briefcase, { className: "size-3.5 text-muted-foreground shrink-0" }) : /* @__PURE__ */ jsx(FileText, { className: "size-3.5 text-muted-foreground shrink-0" }),
|
|
164
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: r.label })
|
|
165
|
+
]
|
|
166
|
+
},
|
|
167
|
+
r.id
|
|
168
|
+
);
|
|
169
|
+
}),
|
|
170
|
+
!loading && page < totalPages ? /* @__PURE__ */ jsx("div", { className: "px-2 py-2", children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", className: "w-full", onClick: () => setPage((current) => current + 1), children: t("customers.schedule.loadMore", "Load more") }) }) : null
|
|
171
|
+
] })
|
|
172
|
+
] })
|
|
173
|
+
] });
|
|
174
|
+
}
|
|
175
|
+
function LinkedEntitiesField({
|
|
176
|
+
visible,
|
|
177
|
+
activityType,
|
|
178
|
+
linkedEntities,
|
|
179
|
+
setLinkedEntities
|
|
180
|
+
}) {
|
|
181
|
+
const t = useT();
|
|
182
|
+
if (!isVisible(activityType, "linkedEntities")) return null;
|
|
183
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
184
|
+
/* @__PURE__ */ jsx("label", { className: "text-overline font-semibold uppercase text-muted-foreground tracking-wider", children: t("customers.schedule.linkedEntities", "Linked entities") }),
|
|
185
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-2.5 flex flex-wrap content-center items-center gap-2", children: [
|
|
186
|
+
linkedEntities.map((entity) => /* @__PURE__ */ jsxs(
|
|
187
|
+
"div",
|
|
188
|
+
{
|
|
189
|
+
className: cn(
|
|
190
|
+
"inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1.5 text-xs",
|
|
191
|
+
entity.type === "deal" ? "border-status-success-border bg-status-success-bg font-semibold text-foreground" : "border-border bg-muted text-foreground"
|
|
192
|
+
),
|
|
193
|
+
children: [
|
|
194
|
+
entity.type === "company" ? /* @__PURE__ */ jsx(Building2, { className: "size-3" }) : entity.type === "deal" ? /* @__PURE__ */ jsx(Briefcase, { className: "size-3" }) : /* @__PURE__ */ jsx(FileText, { className: "size-3" }),
|
|
195
|
+
entity.label,
|
|
196
|
+
/* @__PURE__ */ jsx(IconButton, { type: "button", variant: "ghost", size: "sm", onClick: () => setLinkedEntities((prev) => prev.filter((e) => e.id !== entity.id)), className: "h-auto text-muted-foreground hover:text-foreground p-0", "aria-label": t("customers.schedule.removeLink", "Remove link"), children: /* @__PURE__ */ jsx(X, { className: "size-2.5" }) })
|
|
197
|
+
]
|
|
198
|
+
},
|
|
199
|
+
entity.id
|
|
200
|
+
)),
|
|
201
|
+
/* @__PURE__ */ jsx(
|
|
202
|
+
EntityLinkSearchPopover,
|
|
203
|
+
{
|
|
204
|
+
existingIds: new Set(linkedEntities.map((e) => e.id)),
|
|
205
|
+
onAdd: (entity) => setLinkedEntities((prev) => [...prev, entity]),
|
|
206
|
+
onAddMany: (entities) => setLinkedEntities((prev) => [...prev, ...entities]),
|
|
207
|
+
t
|
|
208
|
+
}
|
|
209
|
+
)
|
|
210
|
+
] })
|
|
211
|
+
] });
|
|
212
|
+
}
|
|
213
|
+
export {
|
|
214
|
+
LinkedEntitiesField
|
|
215
|
+
};
|
|
216
|
+
//# sourceMappingURL=LinkedEntitiesField.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/customers/components/detail/schedule/LinkedEntitiesField.tsx"],
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { Building2, Briefcase, FileText, Search, X } from 'lucide-react'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { IconButton } from '@open-mercato/ui/primitives/icon-button'\nimport { Popover, PopoverContent, PopoverTrigger } from '@open-mercato/ui/primitives/popover'\nimport type { ActivityType, ScheduleFieldId } from './fieldConfig'\nimport { isVisible } from './fieldConfig'\nimport type { LinkedEntity } from './useScheduleFormState'\n\nconst ENTITY_LINK_TYPES = ['company', 'deal', 'offer'] as const\n\nfunction readLabelCandidate(value: unknown): string | null {\n if (typeof value !== 'string') return null\n const trimmed = value.trim()\n return trimmed.length > 0 ? trimmed : null\n}\n\nfunction resolveLinkedEntityLabel(\n item: Record<string, unknown>,\n linkType: 'company' | 'deal' | 'offer',\n): string {\n if (linkType === 'offer') {\n const quoteNumber =\n readLabelCandidate(item.quoteNumber)\n ?? readLabelCandidate(item.quote_number)\n ?? readLabelCandidate(item.documentNumber)\n ?? readLabelCandidate(item.document_number)\n ?? readLabelCandidate(item.externalReference)\n ?? readLabelCandidate(item.external_reference)\n const customerName =\n readLabelCandidate(item.customerName)\n ?? readLabelCandidate(item.customer_name)\n ?? readLabelCandidate(item.display_name)\n ?? readLabelCandidate(item.displayName)\n ?? readLabelCandidate(item.name)\n ?? readLabelCandidate(item.title)\n if (quoteNumber && customerName) return `${quoteNumber} \u00B7 ${customerName}`\n if (quoteNumber) return quoteNumber\n if (customerName) return customerName\n }\n\n if (linkType === 'deal') {\n const dealLabel =\n readLabelCandidate(item.title)\n ?? readLabelCandidate(item.name)\n ?? readLabelCandidate(item.display_name)\n ?? readLabelCandidate(item.displayName)\n if (dealLabel) return dealLabel\n }\n\n return (\n readLabelCandidate(item.display_name)\n ?? readLabelCandidate(item.displayName)\n ?? readLabelCandidate(item.name)\n ?? readLabelCandidate(item.title)\n ?? String(item.id ?? '')\n )\n}\n\nfunction EntityLinkSearchPopover({\n existingIds,\n onAdd,\n onAddMany,\n t,\n}: {\n existingIds: Set<string>\n onAdd: (entity: LinkedEntity) => void\n onAddMany: (entities: LinkedEntity[]) => void\n t: (key: string, fallback: string) => string\n}) {\n const [open, setOpen] = React.useState(false)\n const [linkType, setLinkType] = React.useState<'company' | 'deal' | 'offer'>('company')\n const [query, setQuery] = React.useState('')\n const [results, setResults] = React.useState<Array<{ id: string; label: string }>>([])\n const [page, setPage] = React.useState(1)\n const [totalPages, setTotalPages] = React.useState(1)\n const [loading, setLoading] = React.useState(false)\n const selectableResults = React.useMemo(\n () => results.filter((result) => !existingIds.has(result.id)),\n [existingIds, results],\n )\n\n React.useEffect(() => {\n if (!open) return\n const controller = new AbortController()\n setLoading(true)\n const searchParam = query.trim() ? `&search=${encodeURIComponent(query.trim())}` : ''\n const pagingParam = `&page=${page}&pageSize=20`\n const endpoint = linkType === 'company'\n ? `/api/customers/companies?sortField=name&sortDir=asc${pagingParam}${searchParam}`\n : linkType === 'deal'\n ? `/api/customers/deals?pageSize=20&page=${page}${searchParam}`\n : `/api/sales/quotes?pageSize=20&page=${page}${searchParam}`\n readApiResultOrThrow<{ items?: Array<Record<string, unknown>>; totalPages?: number; page?: number; pageSize?: number; total?: number }>(endpoint, { signal: controller.signal })\n .then((data) => {\n const items = Array.isArray(data?.items) ? data.items : []\n const nextResults = items.map((item) => ({\n id: typeof item?.id === 'string' ? item.id : '',\n label: resolveLinkedEntityLabel(item, linkType),\n })).filter((r) => r.id)\n setResults((current) => {\n if (page <= 1) return nextResults\n const merged = new Map(current.map((entry) => [entry.id, entry]))\n nextResults.forEach((entry) => merged.set(entry.id, entry))\n return Array.from(merged.values())\n })\n if (typeof data?.totalPages === 'number') {\n setTotalPages(data.totalPages)\n } else if (typeof data?.total === 'number' && typeof data?.pageSize === 'number') {\n setTotalPages(Math.max(1, Math.ceil(data.total / data.pageSize)))\n } else {\n setTotalPages(1)\n }\n })\n .catch(() => setResults([]))\n .finally(() => setLoading(false))\n return () => controller.abort()\n }, [open, page, query, linkType])\n\n React.useEffect(() => {\n if (!open) return\n setPage(1)\n }, [open, query, linkType])\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"h-auto inline-flex items-center gap-1.5 rounded-full border border-border bg-background px-2.5 py-1.5 text-xs text-muted-foreground\">\n <span className=\"text-sm\">+</span>\n {t('customers.schedule.addLink', 'Add link')}\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-72 p-2\">\n <div className=\"flex gap-1 mb-2\">\n {ENTITY_LINK_TYPES.map((type) => (\n <Button\n key={type}\n type=\"button\"\n variant={linkType === type ? 'default' : 'ghost'}\n size=\"sm\"\n className=\"h-6 text-xs flex-1\"\n onClick={() => { setLinkType(type as typeof linkType); setQuery('') }}\n >\n {type === 'company' ? <Building2 className=\"mr-1 size-3\" /> : type === 'deal' ? <Briefcase className=\"mr-1 size-3\" /> : <FileText className=\"mr-1 size-3\" />}\n {type === 'company' ? t('customers.schedule.linkType.company', 'Company') : type === 'deal' ? t('customers.schedule.linkType.deal', 'Deal') : t('customers.schedule.linkType.offer', 'Offer')}\n </Button>\n ))}\n </div>\n <div className=\"flex items-center gap-2 rounded-md border bg-background px-2 py-1.5 mb-2\">\n <Search className=\"size-3.5 text-muted-foreground shrink-0\" />\n <input\n type=\"text\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder={t('customers.schedule.searchEntity', 'Search...')}\n className=\"flex-1 bg-transparent text-sm focus:outline-none\"\n autoFocus\n />\n </div>\n {selectableResults.length ? (\n <div className=\"mb-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"w-full\"\n onClick={() => {\n onAddMany(\n selectableResults.map((result) => ({\n id: result.id,\n type: linkType,\n label: result.label,\n })),\n )\n setOpen(false)\n setQuery('')\n }}\n >\n {t('customers.schedule.addVisibleLinks', 'Add all visible')}\n </Button>\n </div>\n ) : null}\n <div className=\"max-h-48 overflow-y-auto space-y-0.5\">\n {loading && <p className=\"px-2 py-3 text-xs text-muted-foreground text-center\">{t('customers.schedule.searching', 'Searching...')}</p>}\n {!loading && results.length === 0 && <p className=\"px-2 py-3 text-xs text-muted-foreground text-center\">{t('customers.schedule.noResults', 'No results')}</p>}\n {results.map((r) => {\n const alreadyLinked = existingIds.has(r.id)\n return (\n <Button\n key={r.id}\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n disabled={alreadyLinked}\n onClick={() => {\n onAdd({ id: r.id, type: linkType, label: r.label })\n setOpen(false)\n setQuery('')\n }}\n className={cn(\n 'h-auto flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors',\n alreadyLinked ? 'opacity-40 cursor-default' : 'hover:bg-accent cursor-pointer',\n )}\n >\n {linkType === 'company' ? <Building2 className=\"size-3.5 text-muted-foreground shrink-0\" /> : linkType === 'deal' ? <Briefcase className=\"size-3.5 text-muted-foreground shrink-0\" /> : <FileText className=\"size-3.5 text-muted-foreground shrink-0\" />}\n <span className=\"min-w-0 flex-1 truncate\">{r.label}</span>\n </Button>\n )\n })}\n {!loading && page < totalPages ? (\n <div className=\"px-2 py-2\">\n <Button type=\"button\" variant=\"outline\" size=\"sm\" className=\"w-full\" onClick={() => setPage((current) => current + 1)}>\n {t('customers.schedule.loadMore', 'Load more')}\n </Button>\n </div>\n ) : null}\n </div>\n </PopoverContent>\n </Popover>\n )\n}\n\ninterface LinkedEntitiesFieldProps {\n visible: Set<ScheduleFieldId>\n activityType: ActivityType\n linkedEntities: LinkedEntity[]\n setLinkedEntities: React.Dispatch<React.SetStateAction<LinkedEntity[]>>\n}\n\nexport function LinkedEntitiesField({\n visible,\n activityType,\n linkedEntities,\n setLinkedEntities,\n}: LinkedEntitiesFieldProps) {\n const t = useT()\n\n if (!isVisible(activityType, 'linkedEntities')) return null\n\n return (\n <div>\n <label className=\"text-overline font-semibold uppercase text-muted-foreground tracking-wider\">\n {t('customers.schedule.linkedEntities', 'Linked entities')}\n </label>\n <div className=\"mt-2.5 flex flex-wrap content-center items-center gap-2\">\n {linkedEntities.map((entity) => (\n <div\n key={entity.id}\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1.5 text-xs',\n entity.type === 'deal'\n ? 'border-status-success-border bg-status-success-bg font-semibold text-foreground'\n : 'border-border bg-muted text-foreground',\n )}\n >\n {entity.type === 'company' ? <Building2 className=\"size-3\" /> : entity.type === 'deal' ? <Briefcase className=\"size-3\" /> : <FileText className=\"size-3\" />}\n {entity.label}\n <IconButton type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => setLinkedEntities((prev) => prev.filter((e) => e.id !== entity.id))} className=\"h-auto text-muted-foreground hover:text-foreground p-0\" aria-label={t('customers.schedule.removeLink', 'Remove link')}>\n <X className=\"size-2.5\" />\n </IconButton>\n </div>\n ))}\n <EntityLinkSearchPopover\n existingIds={new Set(linkedEntities.map((e) => e.id))}\n onAdd={(entity) => setLinkedEntities((prev) => [...prev, entity])}\n onAddMany={(entities) => setLinkedEntities((prev) => [...prev, ...entities])}\n t={t}\n />\n </div>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { MapPin } from "lucide-react";
|
|
4
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
5
|
+
import { isVisible, getFieldLabel } from "./fieldConfig.js";
|
|
6
|
+
function LocationField({
|
|
7
|
+
visible,
|
|
8
|
+
activityType,
|
|
9
|
+
location,
|
|
10
|
+
setLocation
|
|
11
|
+
}) {
|
|
12
|
+
const t = useT();
|
|
13
|
+
if (!isVisible(activityType, "location")) return null;
|
|
14
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
15
|
+
/* @__PURE__ */ jsx("label", { className: "text-overline font-semibold text-muted-foreground tracking-wider", children: getFieldLabel(activityType, "location", t, "customers.schedule.location", "Location") }),
|
|
16
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 rounded-md border border-border bg-background px-3 py-2.5", children: [
|
|
17
|
+
/* @__PURE__ */ jsx(MapPin, { className: "size-3.5 text-muted-foreground shrink-0" }),
|
|
18
|
+
/* @__PURE__ */ jsx(
|
|
19
|
+
"input",
|
|
20
|
+
{
|
|
21
|
+
type: "text",
|
|
22
|
+
value: location,
|
|
23
|
+
onChange: (e) => setLocation(e.target.value),
|
|
24
|
+
placeholder: t("customers.schedule.locationPlaceholder", "Add location or meeting link..."),
|
|
25
|
+
className: "flex-1 bg-transparent text-sm text-foreground placeholder:text-muted-foreground focus:outline-none"
|
|
26
|
+
}
|
|
27
|
+
)
|
|
28
|
+
] })
|
|
29
|
+
] });
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
LocationField
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=LocationField.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/customers/components/detail/schedule/LocationField.tsx"],
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport { MapPin } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type { ActivityType, ScheduleFieldId } from './fieldConfig'\nimport { isVisible, getFieldLabel } from './fieldConfig'\n\ninterface LocationFieldProps {\n visible: Set<ScheduleFieldId>\n activityType: ActivityType\n location: string\n setLocation: (value: string) => void\n}\n\nexport function LocationField({\n visible,\n activityType,\n location,\n setLocation,\n}: LocationFieldProps) {\n const t = useT()\n\n if (!isVisible(activityType, 'location')) return null\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n <label className=\"text-overline font-semibold text-muted-foreground tracking-wider\">\n {getFieldLabel(activityType, 'location', t, 'customers.schedule.location', 'Location')}\n </label>\n <div className=\"flex items-center gap-2 rounded-md border border-border bg-background px-3 py-2.5\">\n <MapPin className=\"size-3.5 text-muted-foreground shrink-0\" />\n <input\n type=\"text\"\n value={location}\n onChange={(e) => setLocation(e.target.value)}\n placeholder={t('customers.schedule.locationPlaceholder', 'Add location or meeting link...')}\n className=\"flex-1 bg-transparent text-sm text-foreground placeholder:text-muted-foreground focus:outline-none\"\n />\n </div>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": ";AA0BM,cAGA,YAHA;AAxBN,SAAS,cAAc;AACvB,SAAS,YAAY;AAErB,SAAS,WAAW,qBAAqB;AASlC,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuB;AACrB,QAAM,IAAI,KAAK;AAEf,MAAI,CAAC,UAAU,cAAc,UAAU,EAAG,QAAO;AAEjD,SACE,qBAAC,SAAI,WAAU,yBACb;AAAA,wBAAC,WAAM,WAAU,oEACd,wBAAc,cAAc,YAAY,GAAG,+BAA+B,UAAU,GACvF;AAAA,IACA,qBAAC,SAAI,WAAU,qFACb;AAAA,0BAAC,UAAO,WAAU,2CAA0C;AAAA,MAC5D;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,YAAY,EAAE,OAAO,KAAK;AAAA,UAC3C,aAAa,EAAE,0CAA0C,iCAAiC;AAAA,UAC1F,WAAU;AAAA;AAAA,MACZ;AAAA,OACF;AAAA,KACF;AAEJ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Users, Search, X, Clock, CheckCircle2, XCircle } from "lucide-react";
|
|
5
|
+
import { cn } from "@open-mercato/shared/lib/utils";
|
|
6
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
7
|
+
import { Button } from "@open-mercato/ui/primitives/button";
|
|
8
|
+
import { IconButton } from "@open-mercato/ui/primitives/icon-button";
|
|
9
|
+
import { Popover, PopoverContent, PopoverTrigger } from "@open-mercato/ui/primitives/popover";
|
|
10
|
+
import { fetchAssignableStaffMembersPage } from "../assignableStaff.js";
|
|
11
|
+
import { isVisible } from "./fieldConfig.js";
|
|
12
|
+
import { PARTICIPANT_COLORS } from "./useScheduleFormState.js";
|
|
13
|
+
function ParticipantSearchPopover({
|
|
14
|
+
existingIds,
|
|
15
|
+
onAdd,
|
|
16
|
+
onAddMany,
|
|
17
|
+
t
|
|
18
|
+
}) {
|
|
19
|
+
const [open, setOpen] = React.useState(false);
|
|
20
|
+
const [query, setQuery] = React.useState("");
|
|
21
|
+
const [results, setResults] = React.useState([]);
|
|
22
|
+
const [page, setPage] = React.useState(1);
|
|
23
|
+
const [totalPages, setTotalPages] = React.useState(1);
|
|
24
|
+
const [loading, setLoading] = React.useState(false);
|
|
25
|
+
const [loadError, setLoadError] = React.useState(null);
|
|
26
|
+
const selectableResults = React.useMemo(
|
|
27
|
+
() => results.filter((result) => !existingIds.has(result.userId)),
|
|
28
|
+
[existingIds, results]
|
|
29
|
+
);
|
|
30
|
+
React.useEffect(() => {
|
|
31
|
+
if (!open) return;
|
|
32
|
+
const controller = new AbortController();
|
|
33
|
+
setLoading(true);
|
|
34
|
+
fetchAssignableStaffMembersPage(query, { page, pageSize: 20, signal: controller.signal }).then((result) => {
|
|
35
|
+
const members = result.items;
|
|
36
|
+
const nextResults = members.map((member) => ({
|
|
37
|
+
userId: member.userId,
|
|
38
|
+
name: member.displayName,
|
|
39
|
+
email: member.email ?? ""
|
|
40
|
+
}));
|
|
41
|
+
setResults((current) => {
|
|
42
|
+
if (page <= 1) return nextResults;
|
|
43
|
+
const merged = new Map(current.map((entry) => [entry.userId, entry]));
|
|
44
|
+
nextResults.forEach((entry) => merged.set(entry.userId, entry));
|
|
45
|
+
return Array.from(merged.values());
|
|
46
|
+
});
|
|
47
|
+
setTotalPages(result.total > 0 ? Math.max(1, Math.ceil(result.total / result.pageSize)) : 1);
|
|
48
|
+
setLoadError(null);
|
|
49
|
+
}).catch(() => {
|
|
50
|
+
setResults([]);
|
|
51
|
+
setLoadError(
|
|
52
|
+
t(
|
|
53
|
+
"customers.assignableStaff.loadError",
|
|
54
|
+
"Unable to load team members. Check your permissions and try again."
|
|
55
|
+
)
|
|
56
|
+
);
|
|
57
|
+
}).finally(() => setLoading(false));
|
|
58
|
+
return () => controller.abort();
|
|
59
|
+
}, [open, page, query, t]);
|
|
60
|
+
React.useEffect(() => {
|
|
61
|
+
if (!open) return;
|
|
62
|
+
setPage(1);
|
|
63
|
+
}, [open, query]);
|
|
64
|
+
return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
|
|
65
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "h-auto inline-flex items-center gap-1.5 rounded-full border border-status-success-border bg-status-success-bg px-2.5 py-1.5 text-xs font-semibold text-foreground", children: [
|
|
66
|
+
/* @__PURE__ */ jsx(Users, { className: "size-3" }),
|
|
67
|
+
t("customers.schedule.addParticipant", "Add participant")
|
|
68
|
+
] }) }),
|
|
69
|
+
/* @__PURE__ */ jsxs(PopoverContent, { align: "start", className: "w-72 p-2", children: [
|
|
70
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 rounded-md border bg-background px-2 py-1.5 mb-2", children: [
|
|
71
|
+
/* @__PURE__ */ jsx(Search, { className: "size-3.5 text-muted-foreground shrink-0" }),
|
|
72
|
+
/* @__PURE__ */ jsx(
|
|
73
|
+
"input",
|
|
74
|
+
{
|
|
75
|
+
type: "text",
|
|
76
|
+
value: query,
|
|
77
|
+
onChange: (e) => setQuery(e.target.value),
|
|
78
|
+
placeholder: t("customers.schedule.searchParticipant", "Search team members..."),
|
|
79
|
+
className: "flex-1 bg-transparent text-sm focus:outline-none",
|
|
80
|
+
autoFocus: true
|
|
81
|
+
}
|
|
82
|
+
)
|
|
83
|
+
] }),
|
|
84
|
+
selectableResults.length ? /* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsx(
|
|
85
|
+
Button,
|
|
86
|
+
{
|
|
87
|
+
type: "button",
|
|
88
|
+
variant: "outline",
|
|
89
|
+
size: "sm",
|
|
90
|
+
className: "w-full",
|
|
91
|
+
onClick: () => {
|
|
92
|
+
onAddMany(
|
|
93
|
+
selectableResults.map((participant, index) => ({
|
|
94
|
+
userId: participant.userId,
|
|
95
|
+
name: participant.name,
|
|
96
|
+
email: participant.email,
|
|
97
|
+
color: PARTICIPANT_COLORS[(existingIds.size + index) % PARTICIPANT_COLORS.length]
|
|
98
|
+
}))
|
|
99
|
+
);
|
|
100
|
+
setOpen(false);
|
|
101
|
+
setQuery("");
|
|
102
|
+
},
|
|
103
|
+
children: t("customers.schedule.addVisibleParticipants", "Add all visible")
|
|
104
|
+
}
|
|
105
|
+
) }) : null,
|
|
106
|
+
/* @__PURE__ */ jsxs("div", { className: "max-h-48 overflow-y-auto space-y-0.5", children: [
|
|
107
|
+
loading && /* @__PURE__ */ jsx("p", { className: "px-2 py-3 text-xs text-muted-foreground text-center", children: t("customers.schedule.searching", "Searching...") }),
|
|
108
|
+
!loading && loadError && /* @__PURE__ */ jsx("p", { className: "px-2 py-3 text-xs text-destructive text-center", children: loadError }),
|
|
109
|
+
!loading && !loadError && results.length === 0 && /* @__PURE__ */ jsx("p", { className: "px-2 py-3 text-xs text-muted-foreground text-center", children: t("customers.schedule.noResults", "No results") }),
|
|
110
|
+
results.map((r) => {
|
|
111
|
+
const alreadyAdded = existingIds.has(r.userId);
|
|
112
|
+
return /* @__PURE__ */ jsxs(
|
|
113
|
+
Button,
|
|
114
|
+
{
|
|
115
|
+
type: "button",
|
|
116
|
+
variant: "ghost",
|
|
117
|
+
size: "sm",
|
|
118
|
+
disabled: alreadyAdded,
|
|
119
|
+
onClick: () => {
|
|
120
|
+
onAdd({ userId: r.userId, name: r.name, email: r.email, color: PARTICIPANT_COLORS[existingIds.size % PARTICIPANT_COLORS.length] });
|
|
121
|
+
setOpen(false);
|
|
122
|
+
setQuery("");
|
|
123
|
+
},
|
|
124
|
+
className: cn(
|
|
125
|
+
"h-auto flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors",
|
|
126
|
+
alreadyAdded ? "opacity-40 cursor-default" : "hover:bg-accent cursor-pointer"
|
|
127
|
+
),
|
|
128
|
+
children: [
|
|
129
|
+
/* @__PURE__ */ jsx("span", { className: "inline-flex size-6 items-center justify-center rounded-full bg-muted text-xs font-bold shrink-0", children: r.name.charAt(0).toUpperCase() }),
|
|
130
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: r.name }),
|
|
131
|
+
r.email && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground truncate", children: r.email })
|
|
132
|
+
]
|
|
133
|
+
},
|
|
134
|
+
r.userId
|
|
135
|
+
);
|
|
136
|
+
}),
|
|
137
|
+
!loading && !loadError && page < totalPages ? /* @__PURE__ */ jsx("div", { className: "px-2 py-2", children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", className: "w-full", onClick: () => setPage((current) => current + 1), children: t("customers.schedule.loadMore", "Load more") }) }) : null
|
|
138
|
+
] })
|
|
139
|
+
] })
|
|
140
|
+
] });
|
|
141
|
+
}
|
|
142
|
+
function ParticipantsField({
|
|
143
|
+
visible,
|
|
144
|
+
activityType,
|
|
145
|
+
participants,
|
|
146
|
+
setParticipants,
|
|
147
|
+
removeParticipant,
|
|
148
|
+
guestPermissions,
|
|
149
|
+
setGuestPermissions
|
|
150
|
+
}) {
|
|
151
|
+
const t = useT();
|
|
152
|
+
if (!isVisible(activityType, "participants")) return null;
|
|
153
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
154
|
+
/* @__PURE__ */ jsx("label", { className: "text-overline font-semibold uppercase text-muted-foreground tracking-wider", children: t("customers.schedule.participants", "Participants") }),
|
|
155
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-2.5 flex flex-wrap content-center items-center gap-2 rounded-lg border border-border bg-background px-3 py-2.5", children: [
|
|
156
|
+
participants.map((p) => /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1.5 rounded-full border border-border bg-muted px-2.5 py-1.5", children: [
|
|
157
|
+
/* @__PURE__ */ jsx("span", { className: cn("inline-flex size-5 items-center justify-center rounded-full text-xs font-bold text-white", p.color ?? "bg-primary"), children: p.name.charAt(0).toUpperCase() }),
|
|
158
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-foreground", children: p.name }),
|
|
159
|
+
/* @__PURE__ */ jsx(IconButton, { type: "button", variant: "ghost", size: "sm", onClick: () => removeParticipant(p.userId), className: "h-auto text-muted-foreground hover:text-foreground p-0", "aria-label": t("customers.schedule.removeParticipant", "Remove participant"), children: /* @__PURE__ */ jsx(X, { className: "size-3" }) })
|
|
160
|
+
] }, p.userId)),
|
|
161
|
+
/* @__PURE__ */ jsx(
|
|
162
|
+
ParticipantSearchPopover,
|
|
163
|
+
{
|
|
164
|
+
existingIds: new Set(participants.map((p) => p.userId)),
|
|
165
|
+
onAdd: (p) => setParticipants((prev) => [...prev, { ...p, status: "pending" }]),
|
|
166
|
+
onAddMany: (nextParticipants) => {
|
|
167
|
+
setParticipants((prev) => [
|
|
168
|
+
...prev,
|
|
169
|
+
...nextParticipants.map((participant) => ({ ...participant, status: "pending" }))
|
|
170
|
+
]);
|
|
171
|
+
},
|
|
172
|
+
t
|
|
173
|
+
}
|
|
174
|
+
)
|
|
175
|
+
] }),
|
|
176
|
+
participants.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-x-[16px] gap-y-[6px] text-xs", children: [
|
|
177
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-muted-foreground", children: t("customers.schedule.guestPermissions", "Guest permissions:") }),
|
|
178
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-1.5 cursor-pointer", children: [
|
|
179
|
+
/* @__PURE__ */ jsx("input", { type: "checkbox", checked: guestPermissions.canInviteOthers, onChange: (e) => setGuestPermissions((p) => ({ ...p, canInviteOthers: e.target.checked })), className: "rounded" }),
|
|
180
|
+
t("customers.schedule.guestPerm.invite", "Invite others")
|
|
181
|
+
] }),
|
|
182
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-1.5 cursor-pointer", children: [
|
|
183
|
+
/* @__PURE__ */ jsx("input", { type: "checkbox", checked: guestPermissions.canModify, onChange: (e) => setGuestPermissions((p) => ({ ...p, canModify: e.target.checked })), className: "rounded" }),
|
|
184
|
+
t("customers.schedule.guestPerm.modify", "Modify")
|
|
185
|
+
] }),
|
|
186
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-1.5 cursor-pointer", children: [
|
|
187
|
+
/* @__PURE__ */ jsx("input", { type: "checkbox", checked: guestPermissions.canSeeList, onChange: (e) => setGuestPermissions((p) => ({ ...p, canSeeList: e.target.checked })), className: "rounded" }),
|
|
188
|
+
t("customers.schedule.guestPerm.seeList", "See list")
|
|
189
|
+
] })
|
|
190
|
+
] }),
|
|
191
|
+
participants.length > 0 && (() => {
|
|
192
|
+
const accepted = participants.filter((p) => p.status === "accepted").length;
|
|
193
|
+
const pending = participants.filter((p) => !p.status || p.status === "pending").length;
|
|
194
|
+
const declined = participants.filter((p) => p.status === "declined").length;
|
|
195
|
+
if (accepted === 0 && pending === 0 && declined === 0) return null;
|
|
196
|
+
return /* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-center gap-3 text-xs", children: [
|
|
197
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: t("customers.schedule.rsvp.label", "Responses:") }),
|
|
198
|
+
accepted > 0 && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 font-medium text-status-success-text", children: [
|
|
199
|
+
/* @__PURE__ */ jsx(CheckCircle2, { className: "size-3.5" }),
|
|
200
|
+
" ",
|
|
201
|
+
accepted,
|
|
202
|
+
" ",
|
|
203
|
+
t("customers.schedule.rsvp.accepted", "tak")
|
|
204
|
+
] }),
|
|
205
|
+
pending > 0 && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 font-medium text-status-warning-text", children: [
|
|
206
|
+
/* @__PURE__ */ jsx(Clock, { className: "size-3.5" }),
|
|
207
|
+
" ",
|
|
208
|
+
pending,
|
|
209
|
+
" ",
|
|
210
|
+
t("customers.schedule.rsvp.pending", "czeka")
|
|
211
|
+
] }),
|
|
212
|
+
declined > 0 && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 font-medium text-status-error-text", children: [
|
|
213
|
+
/* @__PURE__ */ jsx(XCircle, { className: "size-3.5" }),
|
|
214
|
+
" ",
|
|
215
|
+
declined,
|
|
216
|
+
" ",
|
|
217
|
+
t("customers.schedule.rsvp.declined", "nie")
|
|
218
|
+
] })
|
|
219
|
+
] });
|
|
220
|
+
})()
|
|
221
|
+
] });
|
|
222
|
+
}
|
|
223
|
+
export {
|
|
224
|
+
ParticipantsField
|
|
225
|
+
};
|
|
226
|
+
//# sourceMappingURL=ParticipantsField.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/customers/components/detail/schedule/ParticipantsField.tsx"],
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { Users, Search, X, Clock, CheckCircle2, XCircle } from 'lucide-react'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { IconButton } from '@open-mercato/ui/primitives/icon-button'\nimport { Popover, PopoverContent, PopoverTrigger } from '@open-mercato/ui/primitives/popover'\nimport { fetchAssignableStaffMembersPage } from '../assignableStaff'\nimport type { ActivityType, ScheduleFieldId } from './fieldConfig'\nimport { isVisible } from './fieldConfig'\nimport type { Participant, RsvpStatus } from './useScheduleFormState'\nimport { PARTICIPANT_COLORS } from './useScheduleFormState'\n\nfunction ParticipantSearchPopover({\n existingIds,\n onAdd,\n onAddMany,\n t,\n}: {\n existingIds: Set<string>\n onAdd: (p: Participant) => void\n onAddMany: (participants: Participant[]) => void\n t: (key: string, fallback: string) => string\n}) {\n const [open, setOpen] = React.useState(false)\n const [query, setQuery] = React.useState('')\n const [results, setResults] = React.useState<Array<{ userId: string; name: string; email: string }>>([])\n const [page, setPage] = React.useState(1)\n const [totalPages, setTotalPages] = React.useState(1)\n const [loading, setLoading] = React.useState(false)\n const [loadError, setLoadError] = React.useState<string | null>(null)\n const selectableResults = React.useMemo(\n () => results.filter((result) => !existingIds.has(result.userId)),\n [existingIds, results],\n )\n\n React.useEffect(() => {\n if (!open) return\n const controller = new AbortController()\n setLoading(true)\n fetchAssignableStaffMembersPage(query, { page, pageSize: 20, signal: controller.signal })\n .then((result) => {\n const members = result.items\n const nextResults = members.map((member) => ({\n userId: member.userId,\n name: member.displayName,\n email: member.email ?? '',\n }))\n setResults((current) => {\n if (page <= 1) return nextResults\n const merged = new Map(current.map((entry) => [entry.userId, entry]))\n nextResults.forEach((entry) => merged.set(entry.userId, entry))\n return Array.from(merged.values())\n })\n setTotalPages(result.total > 0 ? Math.max(1, Math.ceil(result.total / result.pageSize)) : 1)\n setLoadError(null)\n })\n .catch(() => {\n setResults([])\n setLoadError(\n t(\n 'customers.assignableStaff.loadError',\n 'Unable to load team members. Check your permissions and try again.',\n ),\n )\n })\n .finally(() => setLoading(false))\n return () => controller.abort()\n }, [open, page, query, t])\n\n React.useEffect(() => {\n if (!open) return\n setPage(1)\n }, [open, query])\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"h-auto inline-flex items-center gap-1.5 rounded-full border border-status-success-border bg-status-success-bg px-2.5 py-1.5 text-xs font-semibold text-foreground\">\n <Users className=\"size-3\" />\n {t('customers.schedule.addParticipant', 'Add participant')}\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-72 p-2\">\n <div className=\"flex items-center gap-2 rounded-md border bg-background px-2 py-1.5 mb-2\">\n <Search className=\"size-3.5 text-muted-foreground shrink-0\" />\n <input\n type=\"text\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder={t('customers.schedule.searchParticipant', 'Search team members...')}\n className=\"flex-1 bg-transparent text-sm focus:outline-none\"\n autoFocus\n />\n </div>\n {selectableResults.length ? (\n <div className=\"mb-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"w-full\"\n onClick={() => {\n onAddMany(\n selectableResults.map((participant, index) => ({\n userId: participant.userId,\n name: participant.name,\n email: participant.email,\n color: PARTICIPANT_COLORS[(existingIds.size + index) % PARTICIPANT_COLORS.length],\n })),\n )\n setOpen(false)\n setQuery('')\n }}\n >\n {t('customers.schedule.addVisibleParticipants', 'Add all visible')}\n </Button>\n </div>\n ) : null}\n <div className=\"max-h-48 overflow-y-auto space-y-0.5\">\n {loading && <p className=\"px-2 py-3 text-xs text-muted-foreground text-center\">{t('customers.schedule.searching', 'Searching...')}</p>}\n {!loading && loadError && <p className=\"px-2 py-3 text-xs text-destructive text-center\">{loadError}</p>}\n {!loading && !loadError && results.length === 0 && <p className=\"px-2 py-3 text-xs text-muted-foreground text-center\">{t('customers.schedule.noResults', 'No results')}</p>}\n {results.map((r) => {\n const alreadyAdded = existingIds.has(r.userId)\n return (\n <Button\n key={r.userId}\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n disabled={alreadyAdded}\n onClick={() => {\n onAdd({ userId: r.userId, name: r.name, email: r.email, color: PARTICIPANT_COLORS[existingIds.size % PARTICIPANT_COLORS.length] })\n setOpen(false)\n setQuery('')\n }}\n className={cn(\n 'h-auto flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors',\n alreadyAdded ? 'opacity-40 cursor-default' : 'hover:bg-accent cursor-pointer',\n )}\n >\n <span className=\"inline-flex size-6 items-center justify-center rounded-full bg-muted text-xs font-bold shrink-0\">\n {r.name.charAt(0).toUpperCase()}\n </span>\n <span className=\"min-w-0 flex-1 truncate\">{r.name}</span>\n {r.email && <span className=\"text-xs text-muted-foreground truncate\">{r.email}</span>}\n </Button>\n )\n })}\n {!loading && !loadError && page < totalPages ? (\n <div className=\"px-2 py-2\">\n <Button type=\"button\" variant=\"outline\" size=\"sm\" className=\"w-full\" onClick={() => setPage((current) => current + 1)}>\n {t('customers.schedule.loadMore', 'Load more')}\n </Button>\n </div>\n ) : null}\n </div>\n </PopoverContent>\n </Popover>\n )\n}\n\ninterface ParticipantsFieldProps {\n visible: Set<ScheduleFieldId>\n activityType: ActivityType\n participants: Participant[]\n setParticipants: React.Dispatch<React.SetStateAction<Participant[]>>\n removeParticipant: (userId: string) => void\n guestPermissions: { canInviteOthers: boolean; canModify: boolean; canSeeList: boolean }\n setGuestPermissions: React.Dispatch<React.SetStateAction<{ canInviteOthers: boolean; canModify: boolean; canSeeList: boolean }>>\n}\n\nexport function ParticipantsField({\n visible,\n activityType,\n participants,\n setParticipants,\n removeParticipant,\n guestPermissions,\n setGuestPermissions,\n}: ParticipantsFieldProps) {\n const t = useT()\n\n if (!isVisible(activityType, 'participants')) return null\n\n return (\n <div>\n <label className=\"text-overline font-semibold uppercase text-muted-foreground tracking-wider\">\n {t('customers.schedule.participants', 'Participants')}\n </label>\n <div className=\"mt-2.5 flex flex-wrap content-center items-center gap-2 rounded-lg border border-border bg-background px-3 py-2.5\">\n {participants.map((p) => (\n <div key={p.userId} className=\"inline-flex items-center gap-1.5 rounded-full border border-border bg-muted px-2.5 py-1.5\">\n <span className={cn('inline-flex size-5 items-center justify-center rounded-full text-xs font-bold text-white', p.color ?? 'bg-primary')}>\n {p.name.charAt(0).toUpperCase()}\n </span>\n <span className=\"text-xs text-foreground\">{p.name}</span>\n <IconButton type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => removeParticipant(p.userId)} className=\"h-auto text-muted-foreground hover:text-foreground p-0\" aria-label={t('customers.schedule.removeParticipant', 'Remove participant')}>\n <X className=\"size-3\" />\n </IconButton>\n </div>\n ))}\n <ParticipantSearchPopover\n existingIds={new Set(participants.map((p) => p.userId))}\n onAdd={(p) => setParticipants((prev) => [...prev, { ...p, status: 'pending' as RsvpStatus }])}\n onAddMany={(nextParticipants) => {\n setParticipants((prev) => [\n ...prev,\n ...nextParticipants.map((participant) => ({ ...participant, status: 'pending' as RsvpStatus })),\n ])\n }}\n t={t}\n />\n </div>\n\n {/* Guest permissions -- shown when participants exist */}\n {participants.length > 0 && (\n <div className=\"mt-3 flex flex-wrap items-center gap-x-[16px] gap-y-[6px] text-xs\">\n <span className=\"font-medium text-muted-foreground\">{t('customers.schedule.guestPermissions', 'Guest permissions:')}</span>\n <label className=\"flex items-center gap-1.5 cursor-pointer\">\n <input type=\"checkbox\" checked={guestPermissions.canInviteOthers} onChange={(e) => setGuestPermissions((p) => ({ ...p, canInviteOthers: e.target.checked }))} className=\"rounded\" />\n {t('customers.schedule.guestPerm.invite', 'Invite others')}\n </label>\n <label className=\"flex items-center gap-1.5 cursor-pointer\">\n <input type=\"checkbox\" checked={guestPermissions.canModify} onChange={(e) => setGuestPermissions((p) => ({ ...p, canModify: e.target.checked }))} className=\"rounded\" />\n {t('customers.schedule.guestPerm.modify', 'Modify')}\n </label>\n <label className=\"flex items-center gap-1.5 cursor-pointer\">\n <input type=\"checkbox\" checked={guestPermissions.canSeeList} onChange={(e) => setGuestPermissions((p) => ({ ...p, canSeeList: e.target.checked }))} className=\"rounded\" />\n {t('customers.schedule.guestPerm.seeList', 'See list')}\n </label>\n </div>\n )}\n\n {/* RSVP summary -- shown when participants exist */}\n {participants.length > 0 && (() => {\n const accepted = participants.filter((p) => p.status === 'accepted').length\n const pending = participants.filter((p) => !p.status || p.status === 'pending').length\n const declined = participants.filter((p) => p.status === 'declined').length\n if (accepted === 0 && pending === 0 && declined === 0) return null\n return (\n <div className=\"mt-2 flex items-center gap-3 text-xs\">\n <span className=\"text-muted-foreground\">{t('customers.schedule.rsvp.label', 'Responses:')}</span>\n {accepted > 0 && <span className=\"flex items-center gap-1 font-medium text-status-success-text\"><CheckCircle2 className=\"size-3.5\" /> {accepted} {t('customers.schedule.rsvp.accepted', 'tak')}</span>}\n {pending > 0 && <span className=\"flex items-center gap-1 font-medium text-status-warning-text\"><Clock className=\"size-3.5\" /> {pending} {t('customers.schedule.rsvp.pending', 'czeka')}</span>}\n {declined > 0 && <span className=\"flex items-center gap-1 font-medium text-status-error-text\"><XCircle className=\"size-3.5\" /> {declined} {t('customers.schedule.rsvp.declined', 'nie')}</span>}\n </div>\n )\n })()}\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|