@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.
Files changed (687) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/generated/entities/action_log/index.js +8 -0
  3. package/dist/generated/entities/action_log/index.js.map +2 -2
  4. package/dist/generated/entities/customer_company_billing/index.js +23 -0
  5. package/dist/generated/entities/customer_company_billing/index.js.map +7 -0
  6. package/dist/generated/entities/customer_deal/index.js +8 -0
  7. package/dist/generated/entities/customer_deal/index.js.map +2 -2
  8. package/dist/generated/entities/customer_deal_stage_transition/index.js +31 -0
  9. package/dist/generated/entities/customer_deal_stage_transition/index.js.map +7 -0
  10. package/dist/generated/entities/customer_dictionary_kind_setting/index.js +21 -0
  11. package/dist/generated/entities/customer_dictionary_kind_setting/index.js.map +7 -0
  12. package/dist/generated/entities/customer_entity/index.js +8 -0
  13. package/dist/generated/entities/customer_entity/index.js.map +2 -2
  14. package/dist/generated/entities/customer_entity_role/index.js +23 -0
  15. package/dist/generated/entities/customer_entity_role/index.js.map +7 -0
  16. package/dist/generated/entities/customer_interaction/index.js +23 -1
  17. package/dist/generated/entities/customer_interaction/index.js.map +2 -2
  18. package/dist/generated/entities/customer_label/index.js +19 -0
  19. package/dist/generated/entities/customer_label/index.js.map +7 -0
  20. package/dist/generated/entities/customer_label_assignment/index.js +17 -0
  21. package/dist/generated/entities/customer_label_assignment/index.js.map +7 -0
  22. package/dist/generated/entities/customer_person_company_link/index.js +21 -0
  23. package/dist/generated/entities/customer_person_company_link/index.js.map +7 -0
  24. package/dist/generated/entities/customer_person_company_role/index.js +17 -0
  25. package/dist/generated/entities/customer_person_company_role/index.js.map +7 -0
  26. package/dist/generated/entities/dictionary_entry/index.js +4 -0
  27. package/dist/generated/entities/dictionary_entry/index.js.map +2 -2
  28. package/dist/generated/entities.ids.generated.js +9 -1
  29. package/dist/generated/entities.ids.generated.js.map +2 -2
  30. package/dist/generated/entity-fields-registry.js +116 -1
  31. package/dist/generated/entity-fields-registry.js.map +2 -2
  32. package/dist/modules/attachments/api/route.js +46 -8
  33. package/dist/modules/attachments/api/route.js.map +2 -2
  34. package/dist/modules/audit_logs/api/audit-logs/actions/export/route.js +208 -0
  35. package/dist/modules/audit_logs/api/audit-logs/actions/export/route.js.map +7 -0
  36. package/dist/modules/audit_logs/api/audit-logs/actions/route.js +52 -6
  37. package/dist/modules/audit_logs/api/audit-logs/actions/route.js.map +2 -2
  38. package/dist/modules/audit_logs/cli.js +62 -0
  39. package/dist/modules/audit_logs/cli.js.map +7 -0
  40. package/dist/modules/audit_logs/data/entities.js +21 -1
  41. package/dist/modules/audit_logs/data/entities.js.map +2 -2
  42. package/dist/modules/audit_logs/data/validators.js +9 -1
  43. package/dist/modules/audit_logs/data/validators.js.map +2 -2
  44. package/dist/modules/audit_logs/lib/changeRows.js +34 -0
  45. package/dist/modules/audit_logs/lib/changeRows.js.map +7 -0
  46. package/dist/modules/audit_logs/lib/display-helpers.js +2 -20
  47. package/dist/modules/audit_logs/lib/display-helpers.js.map +3 -3
  48. package/dist/modules/audit_logs/lib/projections.js +58 -0
  49. package/dist/modules/audit_logs/lib/projections.js.map +7 -0
  50. package/dist/modules/audit_logs/migrations/Migration20260412160533.js +21 -0
  51. package/dist/modules/audit_logs/migrations/Migration20260412160533.js.map +7 -0
  52. package/dist/modules/audit_logs/services/actionLogService.js +313 -79
  53. package/dist/modules/audit_logs/services/actionLogService.js.map +2 -2
  54. package/dist/modules/customers/acl.js +3 -1
  55. package/dist/modules/customers/acl.js.map +2 -2
  56. package/dist/modules/customers/api/activities/route.js +4 -0
  57. package/dist/modules/customers/api/activities/route.js.map +2 -2
  58. package/dist/modules/customers/api/assignable-staff/route.js +208 -0
  59. package/dist/modules/customers/api/assignable-staff/route.js.map +7 -0
  60. package/dist/modules/customers/api/companies/[id]/people/route.js +205 -0
  61. package/dist/modules/customers/api/companies/[id]/people/route.js.map +7 -0
  62. package/dist/modules/customers/api/companies/[id]/roles/route.js +22 -0
  63. package/dist/modules/customers/api/companies/[id]/roles/route.js.map +7 -0
  64. package/dist/modules/customers/api/companies/[id]/route.js +374 -32
  65. package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
  66. package/dist/modules/customers/api/companies/route.js +82 -7
  67. package/dist/modules/customers/api/companies/route.js.map +2 -2
  68. package/dist/modules/customers/api/deals/[id]/companies/route.js +172 -0
  69. package/dist/modules/customers/api/deals/[id]/companies/route.js.map +7 -0
  70. package/dist/modules/customers/api/deals/[id]/people/route.js +156 -0
  71. package/dist/modules/customers/api/deals/[id]/people/route.js.map +7 -0
  72. package/dist/modules/customers/api/deals/[id]/route.js +459 -53
  73. package/dist/modules/customers/api/deals/[id]/route.js.map +2 -2
  74. package/dist/modules/customers/api/deals/[id]/stats/route.js +195 -0
  75. package/dist/modules/customers/api/deals/[id]/stats/route.js.map +7 -0
  76. package/dist/modules/customers/api/deals/route.js +20 -10
  77. package/dist/modules/customers/api/deals/route.js.map +3 -3
  78. package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js +105 -4
  79. package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js.map +2 -2
  80. package/dist/modules/customers/api/dictionaries/[kind]/route.js +118 -42
  81. package/dist/modules/customers/api/dictionaries/[kind]/route.js.map +2 -2
  82. package/dist/modules/customers/api/dictionaries/context.js +30 -6
  83. package/dist/modules/customers/api/dictionaries/context.js.map +2 -2
  84. package/dist/modules/customers/api/dictionaries/kind-settings/route.js +207 -0
  85. package/dist/modules/customers/api/dictionaries/kind-settings/route.js.map +7 -0
  86. package/dist/modules/customers/api/entity-roles-factory.js +471 -0
  87. package/dist/modules/customers/api/entity-roles-factory.js.map +7 -0
  88. package/dist/modules/customers/api/interactions/conflicts/route.js +158 -0
  89. package/dist/modules/customers/api/interactions/conflicts/route.js.map +7 -0
  90. package/dist/modules/customers/api/interactions/counts/route.js +92 -0
  91. package/dist/modules/customers/api/interactions/counts/route.js.map +7 -0
  92. package/dist/modules/customers/api/interactions/route.js +83 -4
  93. package/dist/modules/customers/api/interactions/route.js.map +2 -2
  94. package/dist/modules/customers/api/labels/assign/route.js +189 -0
  95. package/dist/modules/customers/api/labels/assign/route.js.map +7 -0
  96. package/dist/modules/customers/api/labels/auth.js +17 -0
  97. package/dist/modules/customers/api/labels/auth.js.map +7 -0
  98. package/dist/modules/customers/api/labels/route.js +281 -0
  99. package/dist/modules/customers/api/labels/route.js.map +7 -0
  100. package/dist/modules/customers/api/labels/table-errors.js +38 -0
  101. package/dist/modules/customers/api/labels/table-errors.js.map +7 -0
  102. package/dist/modules/customers/api/labels/unassign/route.js +184 -0
  103. package/dist/modules/customers/api/labels/unassign/route.js.map +7 -0
  104. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js +292 -0
  105. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js.map +7 -0
  106. package/dist/modules/customers/api/people/[id]/companies/context.js +66 -0
  107. package/dist/modules/customers/api/people/[id]/companies/context.js.map +7 -0
  108. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js +334 -0
  109. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js.map +7 -0
  110. package/dist/modules/customers/api/people/[id]/companies/route.js +205 -0
  111. package/dist/modules/customers/api/people/[id]/companies/route.js.map +7 -0
  112. package/dist/modules/customers/api/people/[id]/roles/route.js +22 -0
  113. package/dist/modules/customers/api/people/[id]/roles/route.js.map +7 -0
  114. package/dist/modules/customers/api/people/[id]/route.js +134 -21
  115. package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
  116. package/dist/modules/customers/api/people/route.js +122 -23
  117. package/dist/modules/customers/api/people/route.js.map +2 -2
  118. package/dist/modules/customers/api/todos/route.js +4 -0
  119. package/dist/modules/customers/api/todos/route.js.map +2 -2
  120. package/dist/modules/customers/api/utils.js +22 -0
  121. package/dist/modules/customers/api/utils.js.map +2 -2
  122. package/dist/modules/customers/backend/config/customers/page.js +2 -6
  123. package/dist/modules/customers/backend/config/customers/page.js.map +2 -2
  124. package/dist/modules/customers/backend/customers/companies/page.js +37 -26
  125. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  126. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +265 -262
  127. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +3 -3
  128. package/dist/modules/customers/backend/customers/deals/[id]/hooks/formatters.js +23 -0
  129. package/dist/modules/customers/backend/customers/deals/[id]/hooks/formatters.js.map +7 -0
  130. package/dist/modules/customers/backend/customers/deals/[id]/hooks/types.js +1 -0
  131. package/dist/modules/customers/backend/customers/deals/[id]/hooks/types.js.map +7 -0
  132. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js +43 -0
  133. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js.map +7 -0
  134. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.js +264 -0
  135. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.js.map +7 -0
  136. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.js +88 -0
  137. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.js.map +7 -0
  138. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js +41 -0
  139. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js.map +7 -0
  140. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js +66 -0
  141. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js.map +7 -0
  142. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealInjectedTabs.js +39 -0
  143. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealInjectedTabs.js.map +7 -0
  144. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealMutationContext.js +49 -0
  145. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealMutationContext.js.map +7 -0
  146. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.js +43 -0
  147. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.js.map +7 -0
  148. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useScheduleDialog.js +28 -0
  149. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useScheduleDialog.js.map +7 -0
  150. package/dist/modules/customers/backend/customers/deals/[id]/page.js +556 -503
  151. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +3 -3
  152. package/dist/modules/customers/backend/customers/deals/page.js +66 -21
  153. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  154. package/dist/modules/customers/backend/customers/people/page.js +36 -28
  155. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  156. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +318 -203
  157. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +3 -3
  158. package/dist/modules/customers/cli.js +105 -13
  159. package/dist/modules/customers/cli.js.map +2 -2
  160. package/dist/modules/customers/commands/activities.js +6 -0
  161. package/dist/modules/customers/commands/activities.js.map +2 -2
  162. package/dist/modules/customers/commands/deals.js +315 -107
  163. package/dist/modules/customers/commands/deals.js.map +2 -2
  164. package/dist/modules/customers/commands/dictionaries.js +166 -32
  165. package/dist/modules/customers/commands/dictionaries.js.map +2 -2
  166. package/dist/modules/customers/commands/dictionaryKindSettings.js +208 -0
  167. package/dist/modules/customers/commands/dictionaryKindSettings.js.map +7 -0
  168. package/dist/modules/customers/commands/entity-roles.js +415 -0
  169. package/dist/modules/customers/commands/entity-roles.js.map +7 -0
  170. package/dist/modules/customers/commands/index.js +4 -0
  171. package/dist/modules/customers/commands/index.js.map +2 -2
  172. package/dist/modules/customers/commands/interactions.js +108 -21
  173. package/dist/modules/customers/commands/interactions.js.map +2 -2
  174. package/dist/modules/customers/commands/labels.js +539 -0
  175. package/dist/modules/customers/commands/labels.js.map +7 -0
  176. package/dist/modules/customers/commands/people.js +560 -463
  177. package/dist/modules/customers/commands/people.js.map +3 -3
  178. package/dist/modules/customers/commands/personCompanyLinks.js +568 -0
  179. package/dist/modules/customers/commands/personCompanyLinks.js.map +7 -0
  180. package/dist/modules/customers/commands/shared.js +12 -4
  181. package/dist/modules/customers/commands/shared.js.map +2 -2
  182. package/dist/modules/customers/commands/todos.js +10 -1
  183. package/dist/modules/customers/commands/todos.js.map +2 -2
  184. package/dist/modules/customers/components/AddressEditor.js +1 -1
  185. package/dist/modules/customers/components/AddressEditor.js.map +2 -2
  186. package/dist/modules/customers/components/CustomersConfigurationSections.js +31 -0
  187. package/dist/modules/customers/components/CustomersConfigurationSections.js.map +7 -0
  188. package/dist/modules/customers/components/DictionarySettings.js +37 -2
  189. package/dist/modules/customers/components/DictionarySettings.js.map +2 -2
  190. package/dist/modules/customers/components/detail/ActiveDealCard.js +121 -0
  191. package/dist/modules/customers/components/detail/ActiveDealCard.js.map +7 -0
  192. package/dist/modules/customers/components/detail/ActivitiesSection.js +222 -331
  193. package/dist/modules/customers/components/detail/ActivitiesSection.js.map +3 -3
  194. package/dist/modules/customers/components/detail/ActivityAiActions.js +36 -0
  195. package/dist/modules/customers/components/detail/ActivityAiActions.js.map +7 -0
  196. package/dist/modules/customers/components/detail/ActivityCard.js +126 -0
  197. package/dist/modules/customers/components/detail/ActivityCard.js.map +7 -0
  198. package/dist/modules/customers/components/detail/ActivityHistorySection.js +340 -0
  199. package/dist/modules/customers/components/detail/ActivityHistorySection.js.map +7 -0
  200. package/dist/modules/customers/components/detail/ActivityLogTab.js +56 -0
  201. package/dist/modules/customers/components/detail/ActivityLogTab.js.map +7 -0
  202. package/dist/modules/customers/components/detail/ActivityTimeline.js +108 -0
  203. package/dist/modules/customers/components/detail/ActivityTimeline.js.map +7 -0
  204. package/dist/modules/customers/components/detail/ActivityTimelineFilters.js +139 -0
  205. package/dist/modules/customers/components/detail/ActivityTimelineFilters.js.map +7 -0
  206. package/dist/modules/customers/components/detail/ActivityTypeSelector.js +42 -0
  207. package/dist/modules/customers/components/detail/ActivityTypeSelector.js.map +7 -0
  208. package/dist/modules/customers/components/detail/AiActionChips.js +38 -0
  209. package/dist/modules/customers/components/detail/AiActionChips.js.map +7 -0
  210. package/dist/modules/customers/components/detail/AssignRoleDialog.js +534 -0
  211. package/dist/modules/customers/components/detail/AssignRoleDialog.js.map +7 -0
  212. package/dist/modules/customers/components/detail/ChangelogEntryRow.js +79 -0
  213. package/dist/modules/customers/components/detail/ChangelogEntryRow.js.map +7 -0
  214. package/dist/modules/customers/components/detail/ChangelogFilters.js +176 -0
  215. package/dist/modules/customers/components/detail/ChangelogFilters.js.map +7 -0
  216. package/dist/modules/customers/components/detail/ChangelogKpiCards.js +88 -0
  217. package/dist/modules/customers/components/detail/ChangelogKpiCards.js.map +7 -0
  218. package/dist/modules/customers/components/detail/ChangelogTab.js +470 -0
  219. package/dist/modules/customers/components/detail/ChangelogTab.js.map +7 -0
  220. package/dist/modules/customers/components/detail/ComingSoonPlaceholder.js +16 -0
  221. package/dist/modules/customers/components/detail/ComingSoonPlaceholder.js.map +7 -0
  222. package/dist/modules/customers/components/detail/CompanyCard.js +283 -0
  223. package/dist/modules/customers/components/detail/CompanyCard.js.map +7 -0
  224. package/dist/modules/customers/components/detail/CompanyDashboardTab.js +133 -0
  225. package/dist/modules/customers/components/detail/CompanyDashboardTab.js.map +7 -0
  226. package/dist/modules/customers/components/detail/CompanyDetailHeader.js +191 -0
  227. package/dist/modules/customers/components/detail/CompanyDetailHeader.js.map +7 -0
  228. package/dist/modules/customers/components/detail/CompanyDetailTabs.js +123 -0
  229. package/dist/modules/customers/components/detail/CompanyDetailTabs.js.map +7 -0
  230. package/dist/modules/customers/components/detail/CompanyKpiBar.js +174 -0
  231. package/dist/modules/customers/components/detail/CompanyKpiBar.js.map +7 -0
  232. package/dist/modules/customers/components/detail/CompanyPeopleSection.js +514 -230
  233. package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
  234. package/dist/modules/customers/components/detail/CompanyTagsDialog.js +22 -0
  235. package/dist/modules/customers/components/detail/CompanyTagsDialog.js.map +7 -0
  236. package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js +159 -0
  237. package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js.map +7 -0
  238. package/dist/modules/customers/components/detail/CreatePersonDialog.js +135 -0
  239. package/dist/modules/customers/components/detail/CreatePersonDialog.js.map +7 -0
  240. package/dist/modules/customers/components/detail/DealClosureActionBar.js +59 -0
  241. package/dist/modules/customers/components/detail/DealClosureActionBar.js.map +7 -0
  242. package/dist/modules/customers/components/detail/DealDetailHeader.js +237 -0
  243. package/dist/modules/customers/components/detail/DealDetailHeader.js.map +7 -0
  244. package/dist/modules/customers/components/detail/DealDetailTabs.js +109 -0
  245. package/dist/modules/customers/components/detail/DealDetailTabs.js.map +7 -0
  246. package/dist/modules/customers/components/detail/DealForm.js +219 -92
  247. package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
  248. package/dist/modules/customers/components/detail/DealLinkedEntitiesTab.js +295 -0
  249. package/dist/modules/customers/components/detail/DealLinkedEntitiesTab.js.map +7 -0
  250. package/dist/modules/customers/components/detail/DealLostSummaryDialog.js +107 -0
  251. package/dist/modules/customers/components/detail/DealLostSummaryDialog.js.map +7 -0
  252. package/dist/modules/customers/components/detail/DealWonPopup.js +113 -0
  253. package/dist/modules/customers/components/detail/DealWonPopup.js.map +7 -0
  254. package/dist/modules/customers/components/detail/DealsSection.js +206 -193
  255. package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
  256. package/dist/modules/customers/components/detail/DecisionMakersFooter.js +39 -0
  257. package/dist/modules/customers/components/detail/DecisionMakersFooter.js.map +7 -0
  258. package/dist/modules/customers/components/detail/EntityTagsDialog.js +1096 -0
  259. package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +7 -0
  260. package/dist/modules/customers/components/detail/InlineActivityComposer.js +197 -0
  261. package/dist/modules/customers/components/detail/InlineActivityComposer.js.map +7 -0
  262. package/dist/modules/customers/components/detail/ManageTagsDialog.js +1091 -0
  263. package/dist/modules/customers/components/detail/ManageTagsDialog.js.map +7 -0
  264. package/dist/modules/customers/components/detail/MiniWeekCalendar.js +272 -0
  265. package/dist/modules/customers/components/detail/MiniWeekCalendar.js.map +7 -0
  266. package/dist/modules/customers/components/detail/MobilePersonDetail.js +106 -0
  267. package/dist/modules/customers/components/detail/MobilePersonDetail.js.map +7 -0
  268. package/dist/modules/customers/components/detail/NextStepCard.js +72 -0
  269. package/dist/modules/customers/components/detail/NextStepCard.js.map +7 -0
  270. package/dist/modules/customers/components/detail/PersonCard.js +192 -0
  271. package/dist/modules/customers/components/detail/PersonCard.js.map +7 -0
  272. package/dist/modules/customers/components/detail/PersonCompaniesSection.js +345 -0
  273. package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +7 -0
  274. package/dist/modules/customers/components/detail/PersonDetailHeader.js +220 -0
  275. package/dist/modules/customers/components/detail/PersonDetailHeader.js.map +7 -0
  276. package/dist/modules/customers/components/detail/PersonDetailTabs.js +122 -0
  277. package/dist/modules/customers/components/detail/PersonDetailTabs.js.map +7 -0
  278. package/dist/modules/customers/components/detail/PersonTagsDialog.js +24 -0
  279. package/dist/modules/customers/components/detail/PersonTagsDialog.js.map +7 -0
  280. package/dist/modules/customers/components/detail/PipelineStepper.js +191 -0
  281. package/dist/modules/customers/components/detail/PipelineStepper.js.map +7 -0
  282. package/dist/modules/customers/components/detail/PlannedActivitiesSection.js +222 -0
  283. package/dist/modules/customers/components/detail/PlannedActivitiesSection.js.map +7 -0
  284. package/dist/modules/customers/components/detail/RelationshipHealthCard.js +49 -0
  285. package/dist/modules/customers/components/detail/RelationshipHealthCard.js.map +7 -0
  286. package/dist/modules/customers/components/detail/RoleAssignmentRow.js +189 -0
  287. package/dist/modules/customers/components/detail/RoleAssignmentRow.js.map +7 -0
  288. package/dist/modules/customers/components/detail/RolesSection.js +234 -0
  289. package/dist/modules/customers/components/detail/RolesSection.js.map +7 -0
  290. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +410 -0
  291. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +7 -0
  292. package/dist/modules/customers/components/detail/aiActionCatalog.js +41 -0
  293. package/dist/modules/customers/components/detail/aiActionCatalog.js.map +7 -0
  294. package/dist/modules/customers/components/detail/assignableStaff.js +48 -0
  295. package/dist/modules/customers/components/detail/assignableStaff.js.map +7 -0
  296. package/dist/modules/customers/components/detail/dashboard/ActiveDealWidget.js +48 -0
  297. package/dist/modules/customers/components/detail/dashboard/ActiveDealWidget.js.map +7 -0
  298. package/dist/modules/customers/components/detail/dashboard/OpenTasksWidget.js +86 -0
  299. package/dist/modules/customers/components/detail/dashboard/OpenTasksWidget.js.map +7 -0
  300. package/dist/modules/customers/components/detail/dashboard/RecentActivityWidget.js +53 -0
  301. package/dist/modules/customers/components/detail/dashboard/RecentActivityWidget.js.map +7 -0
  302. package/dist/modules/customers/components/detail/dashboard/RelationshipHealthWidget.js +30 -0
  303. package/dist/modules/customers/components/detail/dashboard/RelationshipHealthWidget.js.map +7 -0
  304. package/dist/modules/customers/components/detail/dashboard/UpcomingMeetingsWidget.js +43 -0
  305. package/dist/modules/customers/components/detail/dashboard/UpcomingMeetingsWidget.js.map +7 -0
  306. package/dist/modules/customers/components/detail/dashboard/helpers.js +71 -0
  307. package/dist/modules/customers/components/detail/dashboard/helpers.js.map +7 -0
  308. package/dist/modules/customers/components/detail/healthScoreUtils.js +69 -0
  309. package/dist/modules/customers/components/detail/healthScoreUtils.js.map +7 -0
  310. package/dist/modules/customers/components/detail/hooks/useCurrencyDictionary.js +5 -5
  311. package/dist/modules/customers/components/detail/hooks/useCurrencyDictionary.js.map +2 -2
  312. package/dist/modules/customers/components/detail/hooks/useCustomerDictionary.js +9 -8
  313. package/dist/modules/customers/components/detail/hooks/useCustomerDictionary.js.map +3 -3
  314. package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js +65 -0
  315. package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js.map +7 -0
  316. package/dist/modules/customers/components/detail/notesAdapter.js +70 -30
  317. package/dist/modules/customers/components/detail/notesAdapter.js.map +2 -2
  318. package/dist/modules/customers/components/detail/pipelineStageUtils.js +26 -0
  319. package/dist/modules/customers/components/detail/pipelineStageUtils.js.map +7 -0
  320. package/dist/modules/customers/components/detail/schedule/DateTimeFields.js +144 -0
  321. package/dist/modules/customers/components/detail/schedule/DateTimeFields.js.map +7 -0
  322. package/dist/modules/customers/components/detail/schedule/FooterFields.js +60 -0
  323. package/dist/modules/customers/components/detail/schedule/FooterFields.js.map +7 -0
  324. package/dist/modules/customers/components/detail/schedule/LinkedEntitiesField.js +216 -0
  325. package/dist/modules/customers/components/detail/schedule/LinkedEntitiesField.js.map +7 -0
  326. package/dist/modules/customers/components/detail/schedule/LocationField.js +34 -0
  327. package/dist/modules/customers/components/detail/schedule/LocationField.js.map +7 -0
  328. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js +226 -0
  329. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js.map +7 -0
  330. package/dist/modules/customers/components/detail/schedule/fieldConfig.js +69 -0
  331. package/dist/modules/customers/components/detail/schedule/fieldConfig.js.map +7 -0
  332. package/dist/modules/customers/components/detail/schedule/index.js +21 -0
  333. package/dist/modules/customers/components/detail/schedule/index.js.map +7 -0
  334. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js +172 -0
  335. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +7 -0
  336. package/dist/modules/customers/components/detail/utils.js +23 -0
  337. package/dist/modules/customers/components/detail/utils.js.map +2 -2
  338. package/dist/modules/customers/components/formConfig.js +144 -22
  339. package/dist/modules/customers/components/formConfig.js.map +2 -2
  340. package/dist/modules/customers/components/linking/LinkEntityDialog.js +661 -0
  341. package/dist/modules/customers/components/linking/LinkEntityDialog.js.map +7 -0
  342. package/dist/modules/customers/components/linking/adapters/companyAdapter.js +252 -0
  343. package/dist/modules/customers/components/linking/adapters/companyAdapter.js.map +7 -0
  344. package/dist/modules/customers/components/linking/adapters/dealAdapter.js +384 -0
  345. package/dist/modules/customers/components/linking/adapters/dealAdapter.js.map +7 -0
  346. package/dist/modules/customers/components/linking/adapters/personAdapter.js +324 -0
  347. package/dist/modules/customers/components/linking/adapters/personAdapter.js.map +7 -0
  348. package/dist/modules/customers/components/list/CollectionPreviewCell.js +53 -0
  349. package/dist/modules/customers/components/list/CollectionPreviewCell.js.map +7 -0
  350. package/dist/modules/customers/data/entities.js +407 -1
  351. package/dist/modules/customers/data/entities.js.map +2 -2
  352. package/dist/modules/customers/data/validators.js +139 -21
  353. package/dist/modules/customers/data/validators.js.map +2 -2
  354. package/dist/modules/customers/events.js +19 -1
  355. package/dist/modules/customers/events.js.map +2 -2
  356. package/dist/modules/customers/lib/customerRoleTypes.js +19 -0
  357. package/dist/modules/customers/lib/customerRoleTypes.js.map +7 -0
  358. package/dist/modules/customers/lib/dealClosureNotification.js +39 -0
  359. package/dist/modules/customers/lib/dealClosureNotification.js.map +7 -0
  360. package/dist/modules/customers/lib/dealStageTransitionTable.js +29 -0
  361. package/dist/modules/customers/lib/dealStageTransitionTable.js.map +7 -0
  362. package/dist/modules/customers/lib/dictionaries.js +25 -0
  363. package/dist/modules/customers/lib/dictionaries.js.map +2 -2
  364. package/dist/modules/customers/lib/interactionReadModel.js +10 -0
  365. package/dist/modules/customers/lib/interactionReadModel.js.map +2 -2
  366. package/dist/modules/customers/lib/personCompanies.js +235 -0
  367. package/dist/modules/customers/lib/personCompanies.js.map +7 -0
  368. package/dist/modules/customers/lib/personCompanyLinkTable.js +42 -0
  369. package/dist/modules/customers/lib/personCompanyLinkTable.js.map +7 -0
  370. package/dist/modules/customers/lib/roleTypeUsage.js +104 -0
  371. package/dist/modules/customers/lib/roleTypeUsage.js.map +7 -0
  372. package/dist/modules/customers/migrations/Migration20260406214502.js +18 -0
  373. package/dist/modules/customers/migrations/Migration20260406214502.js.map +7 -0
  374. package/dist/modules/customers/migrations/Migration20260408135736.js +17 -0
  375. package/dist/modules/customers/migrations/Migration20260408135736.js.map +7 -0
  376. package/dist/modules/customers/migrations/Migration20260408225345.js +21 -0
  377. package/dist/modules/customers/migrations/Migration20260408225345.js.map +7 -0
  378. package/dist/modules/customers/migrations/Migration20260411075533.js +27 -0
  379. package/dist/modules/customers/migrations/Migration20260411075533.js.map +7 -0
  380. package/dist/modules/customers/migrations/Migration20260411103551.js +13 -0
  381. package/dist/modules/customers/migrations/Migration20260411103551.js.map +7 -0
  382. package/dist/modules/customers/migrations/Migration20260411130944.js +26 -0
  383. package/dist/modules/customers/migrations/Migration20260411130944.js.map +7 -0
  384. package/dist/modules/customers/migrations/Migration20260415095203.js +13 -0
  385. package/dist/modules/customers/migrations/Migration20260415095203.js.map +7 -0
  386. package/dist/modules/customers/migrations/Migration20260415135056.js +20 -0
  387. package/dist/modules/customers/migrations/Migration20260415135056.js.map +7 -0
  388. package/dist/modules/customers/migrations/Migration20260417140000.js +15 -0
  389. package/dist/modules/customers/migrations/Migration20260417140000.js.map +7 -0
  390. package/dist/modules/customers/migrations/Migration20260417160000.js +17 -0
  391. package/dist/modules/customers/migrations/Migration20260417160000.js.map +7 -0
  392. package/dist/modules/customers/migrations/Migration20260417235407.js +13 -0
  393. package/dist/modules/customers/migrations/Migration20260417235407.js.map +7 -0
  394. package/dist/modules/customers/setup.js +16 -1
  395. package/dist/modules/customers/setup.js.map +2 -2
  396. package/dist/modules/customers/subscribers/deal-closure-notification.js +16 -0
  397. package/dist/modules/customers/subscribers/deal-closure-notification.js.map +7 -0
  398. package/dist/modules/customers/subscribers/deal-lost-notification.js +16 -0
  399. package/dist/modules/customers/subscribers/deal-lost-notification.js.map +7 -0
  400. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +2 -0
  401. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
  402. package/dist/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.js +154 -0
  403. package/dist/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.js.map +7 -0
  404. package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js +6 -2
  405. package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js.map +2 -2
  406. package/dist/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.js +154 -0
  407. package/dist/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.js.map +7 -0
  408. package/dist/modules/dictionaries/api/context.js +8 -1
  409. package/dist/modules/dictionaries/api/context.js.map +2 -2
  410. package/dist/modules/dictionaries/api/openapi.js +18 -1
  411. package/dist/modules/dictionaries/api/openapi.js.map +2 -2
  412. package/dist/modules/dictionaries/commands/entry-operations.js +388 -0
  413. package/dist/modules/dictionaries/commands/entry-operations.js.map +7 -0
  414. package/dist/modules/dictionaries/commands/factory.js +24 -3
  415. package/dist/modules/dictionaries/commands/factory.js.map +2 -2
  416. package/dist/modules/dictionaries/commands/index.js +1 -0
  417. package/dist/modules/dictionaries/commands/index.js.map +2 -2
  418. package/dist/modules/dictionaries/components/DictionaryTable.js +6 -3
  419. package/dist/modules/dictionaries/components/DictionaryTable.js.map +2 -2
  420. package/dist/modules/dictionaries/data/entities.js +11 -1
  421. package/dist/modules/dictionaries/data/entities.js.map +2 -2
  422. package/dist/modules/dictionaries/data/validators.js +28 -2
  423. package/dist/modules/dictionaries/data/validators.js.map +2 -2
  424. package/dist/modules/dictionaries/events.js +18 -0
  425. package/dist/modules/dictionaries/events.js.map +7 -0
  426. package/dist/modules/dictionaries/lib/clientEntries.js +43 -0
  427. package/dist/modules/dictionaries/lib/clientEntries.js.map +7 -0
  428. package/dist/modules/dictionaries/migrations/Migration20260410171544.js +45 -0
  429. package/dist/modules/dictionaries/migrations/Migration20260410171544.js.map +7 -0
  430. package/dist/modules/inbox_ops/api/proposals/[id]/route.js +4 -1
  431. package/dist/modules/inbox_ops/api/proposals/[id]/route.js.map +2 -2
  432. package/dist/modules/query_index/lib/engine.js +1 -1
  433. package/dist/modules/query_index/lib/engine.js.map +2 -2
  434. package/dist/modules/sales/components/documents/AddressesSection.js +82 -42
  435. package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
  436. package/dist/modules/sales/lib/dictionaries.js +16 -0
  437. package/dist/modules/sales/lib/dictionaries.js.map +2 -2
  438. package/dist/modules/sales/widgets/injection-table.js +5 -1
  439. package/dist/modules/sales/widgets/injection-table.js.map +2 -2
  440. package/generated/entities/action_log/index.ts +4 -0
  441. package/generated/entities/customer_company_billing/index.ts +10 -0
  442. package/generated/entities/customer_deal/index.ts +4 -0
  443. package/generated/entities/customer_deal_stage_transition/index.ts +14 -0
  444. package/generated/entities/customer_dictionary_kind_setting/index.ts +9 -0
  445. package/generated/entities/customer_entity/index.ts +4 -0
  446. package/generated/entities/customer_entity_role/index.ts +10 -0
  447. package/generated/entities/customer_interaction/index.ts +11 -0
  448. package/generated/entities/customer_label/index.ts +8 -0
  449. package/generated/entities/customer_label_assignment/index.ts +7 -0
  450. package/generated/entities/customer_person_company_link/index.ts +9 -0
  451. package/generated/entities/customer_person_company_role/index.ts +7 -0
  452. package/generated/entities/dictionary_entry/index.ts +2 -0
  453. package/generated/entities.ids.generated.ts +9 -1
  454. package/generated/entity-fields-registry.ts +116 -1
  455. package/package.json +3 -3
  456. package/src/modules/attachments/api/route.ts +48 -6
  457. package/src/modules/attachments/i18n/de.json +4 -0
  458. package/src/modules/attachments/i18n/en.json +4 -0
  459. package/src/modules/attachments/i18n/es.json +4 -0
  460. package/src/modules/attachments/i18n/pl.json +4 -0
  461. package/src/modules/audit_logs/api/audit-logs/actions/export/route.ts +260 -0
  462. package/src/modules/audit_logs/api/audit-logs/actions/route.ts +81 -6
  463. package/src/modules/audit_logs/cli.ts +79 -0
  464. package/src/modules/audit_logs/data/entities.ts +17 -0
  465. package/src/modules/audit_logs/data/validators.ts +9 -1
  466. package/src/modules/audit_logs/lib/changeRows.ts +47 -0
  467. package/src/modules/audit_logs/lib/display-helpers.tsx +4 -30
  468. package/src/modules/audit_logs/lib/projections.ts +110 -0
  469. package/src/modules/audit_logs/migrations/.snapshot-open-mercato.json +325 -2
  470. package/src/modules/audit_logs/migrations/Migration20260412160533.ts +21 -0
  471. package/src/modules/audit_logs/services/actionLogService.ts +455 -85
  472. package/src/modules/catalog/i18n/de.json +1 -0
  473. package/src/modules/catalog/i18n/en.json +1 -0
  474. package/src/modules/catalog/i18n/es.json +1 -0
  475. package/src/modules/catalog/i18n/pl.json +1 -0
  476. package/src/modules/customer_accounts/i18n/de.json +2 -0
  477. package/src/modules/customer_accounts/i18n/en.json +2 -0
  478. package/src/modules/customer_accounts/i18n/es.json +2 -0
  479. package/src/modules/customer_accounts/i18n/pl.json +2 -0
  480. package/src/modules/customers/acl.ts +2 -0
  481. package/src/modules/customers/api/activities/route.ts +4 -0
  482. package/src/modules/customers/api/assignable-staff/route.ts +250 -0
  483. package/src/modules/customers/api/companies/[id]/people/route.ts +244 -0
  484. package/src/modules/customers/api/companies/[id]/roles/route.ts +15 -0
  485. package/src/modules/customers/api/companies/[id]/route.ts +458 -40
  486. package/src/modules/customers/api/companies/route.ts +93 -15
  487. package/src/modules/customers/api/deals/[id]/companies/route.ts +203 -0
  488. package/src/modules/customers/api/deals/[id]/people/route.ts +182 -0
  489. package/src/modules/customers/api/deals/[id]/route.ts +554 -57
  490. package/src/modules/customers/api/deals/[id]/stats/route.ts +221 -0
  491. package/src/modules/customers/api/deals/route.ts +35 -46
  492. package/src/modules/customers/api/dictionaries/[kind]/[id]/route.ts +105 -3
  493. package/src/modules/customers/api/dictionaries/[kind]/route.ts +143 -44
  494. package/src/modules/customers/api/dictionaries/context.ts +45 -16
  495. package/src/modules/customers/api/dictionaries/kind-settings/route.ts +232 -0
  496. package/src/modules/customers/api/entity-roles-factory.ts +520 -0
  497. package/src/modules/customers/api/interactions/conflicts/route.ts +196 -0
  498. package/src/modules/customers/api/interactions/counts/route.ts +112 -0
  499. package/src/modules/customers/api/interactions/route.ts +95 -2
  500. package/src/modules/customers/api/labels/assign/route.ts +202 -0
  501. package/src/modules/customers/api/labels/auth.ts +19 -0
  502. package/src/modules/customers/api/labels/route.ts +310 -0
  503. package/src/modules/customers/api/labels/table-errors.ts +36 -0
  504. package/src/modules/customers/api/labels/unassign/route.ts +197 -0
  505. package/src/modules/customers/api/people/[id]/companies/[linkId]/route.ts +331 -0
  506. package/src/modules/customers/api/people/[id]/companies/context.ts +70 -0
  507. package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +384 -0
  508. package/src/modules/customers/api/people/[id]/companies/route.ts +215 -0
  509. package/src/modules/customers/api/people/[id]/roles/route.ts +15 -0
  510. package/src/modules/customers/api/people/[id]/route.ts +153 -26
  511. package/src/modules/customers/api/people/route.ts +134 -31
  512. package/src/modules/customers/api/todos/route.ts +4 -0
  513. package/src/modules/customers/api/utils.ts +36 -0
  514. package/src/modules/customers/backend/config/customers/page.tsx +2 -6
  515. package/src/modules/customers/backend/customers/companies/page.tsx +36 -26
  516. package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +277 -262
  517. package/src/modules/customers/backend/customers/deals/[id]/hooks/formatters.ts +19 -0
  518. package/src/modules/customers/backend/customers/deals/[id]/hooks/types.ts +104 -0
  519. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.ts +60 -0
  520. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.ts +362 -0
  521. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.ts +113 -0
  522. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealData.ts +52 -0
  523. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.ts +86 -0
  524. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealInjectedTabs.tsx +60 -0
  525. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealMutationContext.ts +76 -0
  526. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.ts +56 -0
  527. package/src/modules/customers/backend/customers/deals/[id]/hooks/useScheduleDialog.ts +38 -0
  528. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +587 -624
  529. package/src/modules/customers/backend/customers/deals/page.tsx +71 -28
  530. package/src/modules/customers/backend/customers/people/page.tsx +35 -29
  531. package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +343 -209
  532. package/src/modules/customers/cli.ts +107 -12
  533. package/src/modules/customers/commands/activities.ts +13 -0
  534. package/src/modules/customers/commands/deals.ts +386 -114
  535. package/src/modules/customers/commands/dictionaries.ts +175 -32
  536. package/src/modules/customers/commands/dictionaryKindSettings.ts +268 -0
  537. package/src/modules/customers/commands/entity-roles.ts +494 -0
  538. package/src/modules/customers/commands/index.ts +4 -0
  539. package/src/modules/customers/commands/interactions.ts +125 -21
  540. package/src/modules/customers/commands/labels.ts +626 -0
  541. package/src/modules/customers/commands/people.ts +373 -259
  542. package/src/modules/customers/commands/personCompanyLinks.ts +654 -0
  543. package/src/modules/customers/commands/shared.ts +16 -15
  544. package/src/modules/customers/commands/todos.ts +17 -1
  545. package/src/modules/customers/components/AddressEditor.tsx +1 -1
  546. package/src/modules/customers/components/CustomersConfigurationSections.tsx +36 -0
  547. package/src/modules/customers/components/DictionarySettings.tsx +43 -2
  548. package/src/modules/customers/components/detail/ActiveDealCard.tsx +175 -0
  549. package/src/modules/customers/components/detail/ActivitiesSection.tsx +267 -361
  550. package/src/modules/customers/components/detail/ActivityAiActions.tsx +49 -0
  551. package/src/modules/customers/components/detail/ActivityCard.tsx +154 -0
  552. package/src/modules/customers/components/detail/ActivityHistorySection.tsx +412 -0
  553. package/src/modules/customers/components/detail/ActivityLogTab.tsx +67 -0
  554. package/src/modules/customers/components/detail/ActivityTimeline.tsx +158 -0
  555. package/src/modules/customers/components/detail/ActivityTimelineFilters.tsx +163 -0
  556. package/src/modules/customers/components/detail/ActivityTypeSelector.tsx +53 -0
  557. package/src/modules/customers/components/detail/AiActionChips.tsx +48 -0
  558. package/src/modules/customers/components/detail/AssignRoleDialog.tsx +672 -0
  559. package/src/modules/customers/components/detail/ChangelogEntryRow.tsx +132 -0
  560. package/src/modules/customers/components/detail/ChangelogFilters.tsx +193 -0
  561. package/src/modules/customers/components/detail/ChangelogKpiCards.tsx +107 -0
  562. package/src/modules/customers/components/detail/ChangelogTab.tsx +629 -0
  563. package/src/modules/customers/components/detail/ComingSoonPlaceholder.tsx +21 -0
  564. package/src/modules/customers/components/detail/CompanyCard.tsx +419 -0
  565. package/src/modules/customers/components/detail/CompanyDashboardTab.tsx +161 -0
  566. package/src/modules/customers/components/detail/CompanyDetailHeader.tsx +243 -0
  567. package/src/modules/customers/components/detail/CompanyDetailTabs.tsx +172 -0
  568. package/src/modules/customers/components/detail/CompanyKpiBar.tsx +206 -0
  569. package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +582 -288
  570. package/src/modules/customers/components/detail/CompanyTagsDialog.tsx +23 -0
  571. package/src/modules/customers/components/detail/ConfirmDealLostDialog.tsx +210 -0
  572. package/src/modules/customers/components/detail/CreatePersonDialog.tsx +178 -0
  573. package/src/modules/customers/components/detail/DealClosureActionBar.tsx +63 -0
  574. package/src/modules/customers/components/detail/DealDetailHeader.tsx +335 -0
  575. package/src/modules/customers/components/detail/DealDetailTabs.tsx +154 -0
  576. package/src/modules/customers/components/detail/DealForm.tsx +253 -101
  577. package/src/modules/customers/components/detail/DealLinkedEntitiesTab.tsx +349 -0
  578. package/src/modules/customers/components/detail/DealLostSummaryDialog.tsx +156 -0
  579. package/src/modules/customers/components/detail/DealWonPopup.tsx +164 -0
  580. package/src/modules/customers/components/detail/DealsSection.tsx +276 -221
  581. package/src/modules/customers/components/detail/DecisionMakersFooter.tsx +56 -0
  582. package/src/modules/customers/components/detail/EntityTagsDialog.tsx +1372 -0
  583. package/src/modules/customers/components/detail/InlineActivityComposer.tsx +239 -0
  584. package/src/modules/customers/components/detail/ManageTagsDialog.tsx +1331 -0
  585. package/src/modules/customers/components/detail/MiniWeekCalendar.tsx +338 -0
  586. package/src/modules/customers/components/detail/MobilePersonDetail.tsx +124 -0
  587. package/src/modules/customers/components/detail/NextStepCard.tsx +104 -0
  588. package/src/modules/customers/components/detail/PersonCard.tsx +238 -0
  589. package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +426 -0
  590. package/src/modules/customers/components/detail/PersonDetailHeader.tsx +294 -0
  591. package/src/modules/customers/components/detail/PersonDetailTabs.tsx +172 -0
  592. package/src/modules/customers/components/detail/PersonTagsDialog.tsx +26 -0
  593. package/src/modules/customers/components/detail/PipelineStepper.tsx +245 -0
  594. package/src/modules/customers/components/detail/PlannedActivitiesSection.tsx +255 -0
  595. package/src/modules/customers/components/detail/RelationshipHealthCard.tsx +63 -0
  596. package/src/modules/customers/components/detail/RoleAssignmentRow.tsx +248 -0
  597. package/src/modules/customers/components/detail/RolesSection.tsx +311 -0
  598. package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +481 -0
  599. package/src/modules/customers/components/detail/aiActionCatalog.ts +77 -0
  600. package/src/modules/customers/components/detail/assignableStaff.ts +124 -0
  601. package/src/modules/customers/components/detail/dashboard/ActiveDealWidget.tsx +63 -0
  602. package/src/modules/customers/components/detail/dashboard/OpenTasksWidget.tsx +114 -0
  603. package/src/modules/customers/components/detail/dashboard/RecentActivityWidget.tsx +69 -0
  604. package/src/modules/customers/components/detail/dashboard/RelationshipHealthWidget.tsx +40 -0
  605. package/src/modules/customers/components/detail/dashboard/UpcomingMeetingsWidget.tsx +64 -0
  606. package/src/modules/customers/components/detail/dashboard/helpers.ts +78 -0
  607. package/src/modules/customers/components/detail/healthScoreUtils.ts +91 -0
  608. package/src/modules/customers/components/detail/hooks/useCurrencyDictionary.ts +8 -8
  609. package/src/modules/customers/components/detail/hooks/useCustomerDictionary.ts +10 -6
  610. package/src/modules/customers/components/detail/hooks/useInteractionMutations.ts +91 -0
  611. package/src/modules/customers/components/detail/notesAdapter.ts +91 -30
  612. package/src/modules/customers/components/detail/pipelineStageUtils.ts +29 -0
  613. package/src/modules/customers/components/detail/schedule/DateTimeFields.tsx +187 -0
  614. package/src/modules/customers/components/detail/schedule/FooterFields.tsx +79 -0
  615. package/src/modules/customers/components/detail/schedule/LinkedEntitiesField.tsx +277 -0
  616. package/src/modules/customers/components/detail/schedule/LocationField.tsx +42 -0
  617. package/src/modules/customers/components/detail/schedule/ParticipantsField.tsx +255 -0
  618. package/src/modules/customers/components/detail/schedule/fieldConfig.ts +70 -0
  619. package/src/modules/customers/components/detail/schedule/index.ts +9 -0
  620. package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +221 -0
  621. package/src/modules/customers/components/detail/types.ts +16 -0
  622. package/src/modules/customers/components/detail/utils.ts +25 -0
  623. package/src/modules/customers/components/formConfig.tsx +223 -28
  624. package/src/modules/customers/components/linking/LinkEntityDialog.tsx +920 -0
  625. package/src/modules/customers/components/linking/adapters/companyAdapter.tsx +398 -0
  626. package/src/modules/customers/components/linking/adapters/dealAdapter.tsx +578 -0
  627. package/src/modules/customers/components/linking/adapters/personAdapter.tsx +512 -0
  628. package/src/modules/customers/components/list/CollectionPreviewCell.tsx +66 -0
  629. package/src/modules/customers/data/entities.ts +353 -1
  630. package/src/modules/customers/data/validators.ts +170 -19
  631. package/src/modules/customers/events.ts +22 -0
  632. package/src/modules/customers/i18n/de.json +841 -2
  633. package/src/modules/customers/i18n/en.json +841 -2
  634. package/src/modules/customers/i18n/es.json +840 -1
  635. package/src/modules/customers/i18n/pl.json +841 -2
  636. package/src/modules/customers/lib/customerRoleTypes.ts +24 -0
  637. package/src/modules/customers/lib/dealClosureNotification.ts +64 -0
  638. package/src/modules/customers/lib/dealStageTransitionTable.ts +32 -0
  639. package/src/modules/customers/lib/dictionaries.ts +26 -10
  640. package/src/modules/customers/lib/interactionReadModel.ts +10 -0
  641. package/src/modules/customers/lib/personCompanies.ts +317 -0
  642. package/src/modules/customers/lib/personCompanyLinkTable.ts +58 -0
  643. package/src/modules/customers/lib/roleTypeUsage.ts +146 -0
  644. package/src/modules/customers/migrations/.snapshot-open-mercato.json +2747 -798
  645. package/src/modules/customers/migrations/Migration20260406214502.ts +19 -0
  646. package/src/modules/customers/migrations/Migration20260408135736.ts +15 -0
  647. package/src/modules/customers/migrations/Migration20260408225345.ts +23 -0
  648. package/src/modules/customers/migrations/Migration20260411075533.ts +30 -0
  649. package/src/modules/customers/migrations/Migration20260411103551.ts +13 -0
  650. package/src/modules/customers/migrations/Migration20260411130944.ts +30 -0
  651. package/src/modules/customers/migrations/Migration20260415095203.ts +13 -0
  652. package/src/modules/customers/migrations/Migration20260415135056.ts +22 -0
  653. package/src/modules/customers/migrations/Migration20260417140000.ts +15 -0
  654. package/src/modules/customers/migrations/Migration20260417160000.ts +17 -0
  655. package/src/modules/customers/migrations/Migration20260417235407.ts +13 -0
  656. package/src/modules/customers/setup.ts +15 -0
  657. package/src/modules/customers/subscribers/deal-closure-notification.ts +22 -0
  658. package/src/modules/customers/subscribers/deal-lost-notification.ts +22 -0
  659. package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +2 -0
  660. package/src/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.ts +162 -0
  661. package/src/modules/dictionaries/api/[dictionaryId]/entries/route.ts +6 -2
  662. package/src/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.ts +162 -0
  663. package/src/modules/dictionaries/api/context.ts +9 -0
  664. package/src/modules/dictionaries/api/openapi.ts +17 -0
  665. package/src/modules/dictionaries/commands/entry-operations.ts +457 -0
  666. package/src/modules/dictionaries/commands/factory.ts +31 -3
  667. package/src/modules/dictionaries/commands/index.ts +1 -0
  668. package/src/modules/dictionaries/components/DictionaryTable.tsx +15 -6
  669. package/src/modules/dictionaries/data/entities.ts +9 -0
  670. package/src/modules/dictionaries/data/validators.ts +34 -0
  671. package/src/modules/dictionaries/events.ts +20 -0
  672. package/src/modules/dictionaries/i18n/de.json +2 -0
  673. package/src/modules/dictionaries/i18n/en.json +2 -0
  674. package/src/modules/dictionaries/i18n/es.json +2 -0
  675. package/src/modules/dictionaries/i18n/pl.json +2 -0
  676. package/src/modules/dictionaries/lib/clientEntries.ts +66 -0
  677. package/src/modules/dictionaries/migrations/.snapshot-open-mercato.json +185 -3
  678. package/src/modules/dictionaries/migrations/Migration20260410171544.ts +49 -0
  679. package/src/modules/inbox_ops/api/proposals/[id]/route.ts +4 -1
  680. package/src/modules/query_index/lib/engine.ts +9 -1
  681. package/src/modules/sales/components/documents/AddressesSection.tsx +92 -42
  682. package/src/modules/sales/i18n/de.json +28 -0
  683. package/src/modules/sales/i18n/en.json +28 -0
  684. package/src/modules/sales/i18n/es.json +28 -0
  685. package/src/modules/sales/i18n/pl.json +28 -0
  686. package/src/modules/sales/lib/dictionaries.ts +18 -0
  687. package/src/modules/sales/widgets/injection-table.ts +4 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/customers/backend/customers/deals/page.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { usePathname, useRouter, useSearchParams } from 'next/navigation'\nimport { useQueryClient } from '@tanstack/react-query'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, type DataTableExportFormat, withDataTableNamespaces } from '@open-mercato/ui/backend/DataTable'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport type { AdvancedFilterState } from '@open-mercato/shared/lib/query/advanced-filter'\nimport { serializeAdvancedFilter } from '@open-mercato/shared/lib/query/advanced-filter'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildCrudExportUrl, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { E } from '#generated/entities.ids.generated'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport {\n DictionaryValue,\n type CustomerDictionaryKind,\n type CustomerDictionaryMap,\n} from '../../../lib/dictionaries'\nimport {\n ensureCustomerDictionary,\n invalidateCustomerDictionary,\n} from '../../../components/detail/hooks/useCustomerDictionary'\nimport {\n useCustomFieldDefs,\n} from '@open-mercato/ui/backend/utils/customFieldDefs'\nimport {\n mapCustomFieldKindToFilterType,\n normalizeCustomFieldFilterOptions,\n supportsCustomFieldColumn,\n} from '@open-mercato/ui/backend/utils/customFieldColumns'\n\ntype DealRow = {\n id: string\n title: string\n status?: string | null\n pipelineStage?: string | null\n pipelineStageId?: string | null\n pipelineId?: string | null\n valueAmount?: number | null\n valueCurrency?: string | null\n probability?: number | null\n expectedCloseAt?: string | null\n updatedAt?: string | null\n companies: { id: string; label: string }[]\n people: { id: string; label: string }[]\n} & Record<string, unknown>\n\ntype DealsResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n totalPages?: number\n}\n\ntype FilterOption = { value: string; label: string }\n\ntype DictionaryKey = Extract<CustomerDictionaryKind, 'deal-statuses' | 'pipeline-stages'>\n\ntype PersonLookupRecord = {\n id: string\n name: string | null\n email: string | null\n phone: string | null\n}\n\ntype CompanyLookupRecord = {\n id: string\n name: string | null\n domain: string | null\n email: string | null\n}\n\nfunction parsePersonLookupRecord(item: unknown): PersonLookupRecord | null {\n if (typeof item !== 'object' || item === null) return null\n const record = item as Record<string, unknown>\n const id = typeof record.id === 'string' ? record.id : null\n if (!id || !isUuid(id)) return null\n const name = typeof record.display_name === 'string' ? record.display_name : null\n const email = typeof record.primary_email === 'string' ? record.primary_email : null\n const phone = typeof record.primary_phone === 'string' ? record.primary_phone : null\n return { id, name, email, phone }\n}\n\nfunction parseCompanyLookupRecord(item: unknown): CompanyLookupRecord | null {\n if (typeof item !== 'object' || item === null) return null\n const record = item as Record<string, unknown>\n const id = typeof record.id === 'string' ? record.id : null\n if (!id || !isUuid(id)) return null\n const name = typeof record.display_name === 'string' ? record.display_name : null\n const domain = typeof record.primary_domain === 'string' ? record.primary_domain : null\n const email = typeof record.primary_email === 'string' ? record.primary_email : null\n return { id, name, domain, email }\n}\n\ntype OptionsState = {\n options: FilterOption[]\n idToLabel: Record<string, string>\n labelToId: Record<string, string>\n}\n\nconst EMPTY_OPTIONS_STATE: OptionsState = {\n options: [],\n idToLabel: {},\n labelToId: {},\n}\n\nconst PAGE_SIZE = 20\nconst UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i\n\nfunction isUuid(value: string | null | undefined): value is string {\n if (!value) return false\n return UUID_REGEX.test(value.trim())\n}\n\nfunction normalizeIdCandidates(raw: Array<string>): string[] {\n const set = new Set<string>()\n raw.forEach((candidate) => {\n candidate\n .split(',')\n .map((part) => part.trim())\n .filter((part) => part.length > 0)\n .forEach((part) => {\n if (isUuid(part)) set.add(part)\n })\n })\n return Array.from(set)\n}\n\nfunction extractIdsFromParams(params: URLSearchParams | null | undefined, key: string): string[] {\n if (!params) return []\n const values = params.getAll(key)\n return normalizeIdCandidates(values)\n}\n\nfunction ensureUniqueLabel(base: string, occupied: Set<string>): string {\n const trimmed = base.trim() || 'Unnamed'\n if (!occupied.has(trimmed)) {\n occupied.add(trimmed)\n return trimmed\n }\n let counter = 2\n let candidate = `${trimmed} \u2022 ${counter}`\n while (occupied.has(candidate)) {\n counter += 1\n candidate = `${trimmed} \u2022 ${counter}`\n }\n occupied.add(candidate)\n return candidate\n}\n\nasync function fetchPeopleLookup(query?: string): Promise<PersonLookupRecord[]> {\n const search = new URLSearchParams()\n search.set('page', '1')\n search.set('pageSize', '20')\n if (query && query.trim().length) search.set('search', query.trim())\n try {\n const call = await apiCall<{ items?: unknown[] }>(`/api/customers/people?${search.toString()}`)\n if (!call.ok) return []\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n return items\n .map((item) => parsePersonLookupRecord(item))\n .filter((record): record is PersonLookupRecord => record !== null)\n } catch {\n return []\n }\n}\n\nasync function fetchPeopleLookupByIds(ids: string[]): Promise<PersonLookupRecord[]> {\n const unique = Array.from(new Set(ids.filter((id) => isUuid(id))))\n if (!unique.length) return []\n const results = await Promise.all(\n unique.map(async (id) => {\n const search = new URLSearchParams()\n search.set('id', id)\n search.set('page', '1')\n search.set('pageSize', '1')\n try {\n const call = await apiCall<{ items?: unknown[] }>(`/api/customers/people?${search.toString()}`)\n if (!call.ok) return null\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const match = items\n .map((item) => parsePersonLookupRecord(item))\n .find((record) => record?.id === id)\n return match ?? null\n } catch {\n return null\n }\n }),\n )\n return results.filter((record): record is PersonLookupRecord => !!record)\n}\n\nasync function fetchCompaniesLookup(query?: string): Promise<CompanyLookupRecord[]> {\n const search = new URLSearchParams()\n search.set('page', '1')\n search.set('pageSize', '20')\n if (query && query.trim().length) search.set('search', query.trim())\n try {\n const call = await apiCall<{ items?: unknown[] }>(`/api/customers/companies?${search.toString()}`)\n if (!call.ok) return []\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n return items\n .map((item) => parseCompanyLookupRecord(item))\n .filter((record): record is CompanyLookupRecord => record !== null)\n } catch {\n return []\n }\n}\n\nasync function fetchCompaniesLookupByIds(ids: string[]): Promise<CompanyLookupRecord[]> {\n const unique = Array.from(new Set(ids.filter((id) => isUuid(id))))\n if (!unique.length) return []\n const results = await Promise.all(\n unique.map(async (id) => {\n const search = new URLSearchParams()\n search.set('id', id)\n search.set('page', '1')\n search.set('pageSize', '1')\n try {\n const call = await apiCall<{ items?: unknown[] }>(`/api/customers/companies?${search.toString()}`)\n if (!call.ok) return null\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const match = items\n .map((item) => parseCompanyLookupRecord(item))\n .find((record) => record?.id === id)\n return match ?? null\n } catch {\n return null\n }\n }),\n )\n return results.filter((record): record is CompanyLookupRecord => !!record)\n}\n\nfunction formatCurrency(amount: number | null | undefined, currency: string | null | undefined, fallback: string): string {\n if (typeof amount !== 'number' || Number.isNaN(amount)) return fallback\n try {\n if (currency && currency.trim().length) {\n const formatter = new Intl.NumberFormat(undefined, { style: 'currency', currency })\n return formatter.format(amount)\n }\n const formatter = new Intl.NumberFormat(undefined, { style: 'decimal', maximumFractionDigits: 2 })\n return formatter.format(amount)\n } catch {\n return currency ? `${amount} ${currency}` : String(amount)\n }\n}\n\nfunction formatDateValue(value: string | null | undefined, fallback: string): string {\n if (!value) return fallback\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return fallback\n return date.toLocaleDateString()\n}\n\nfunction arraysEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i += 1) {\n if (a[i] !== b[i]) return false\n }\n return true\n}\n\nexport default function CustomersDealsPage() {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const router = useRouter()\n const pathname = usePathname()\n const searchParams = useSearchParams()\n const scopeVersion = useOrganizationScopeVersion()\n const queryClient = useQueryClient()\n\n const [rows, setRows] = React.useState<DealRow[]>([])\n const [page, setPage] = React.useState(() => {\n const raw = Number(searchParams?.get('page') ?? '1')\n return Number.isFinite(raw) && raw > 0 ? raw : 1\n })\n const [pageSize, setPageSize] = React.useState(PAGE_SIZE)\n const [sorting, setSorting] = React.useState<import('@tanstack/react-table').SortingState>([])\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [search, setSearch] = React.useState(() => searchParams?.get('search')?.trim() ?? '')\n const [isLoading, setIsLoading] = React.useState(false)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [pendingDeleteId, setPendingDeleteId] = React.useState<string | null>(null)\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [advancedFilterState, setAdvancedFilterState] = React.useState<AdvancedFilterState>({ logic: 'and', conditions: [] })\n const [cacheStatus, setCacheStatus] = React.useState<'hit' | 'miss' | null>(null)\n\n const initialPersonIds = React.useMemo(\n () => extractIdsFromParams(searchParams, 'personId'),\n [searchParams],\n )\n const initialCompanyIds = React.useMemo(\n () => extractIdsFromParams(searchParams, 'companyId'),\n [searchParams],\n )\n\n const [selectedPersonIds, setSelectedPersonIds] = React.useState<string[]>(initialPersonIds)\n const [selectedCompanyIds, setSelectedCompanyIds] = React.useState<string[]>(initialCompanyIds)\n\n const [peopleState, setPeopleState] = React.useState<OptionsState>(EMPTY_OPTIONS_STATE)\n const [companiesState, setCompaniesState] = React.useState<OptionsState>(EMPTY_OPTIONS_STATE)\n const peopleCacheRef = React.useRef<Map<string, FilterOption[]>>(new Map())\n const companiesCacheRef = React.useRef<Map<string, FilterOption[]>>(new Map())\n\n const buildPersonLabel = React.useCallback((record: PersonLookupRecord): string => {\n const parts: string[] = []\n const name = record.name?.trim()\n if (name) parts.push(name)\n const email = record.email?.trim()\n if (email && !parts.includes(email)) parts.push(email)\n const phone = record.phone?.trim()\n if (!parts.length && phone) parts.push(phone)\n if (!parts.length) parts.push(t('customers.deals.list.unnamedPerson', 'Unnamed person'))\n return parts.join(' \u2022 ')\n }, [t])\n\n const buildCompanyLabel = React.useCallback((record: CompanyLookupRecord): string => {\n const parts: string[] = []\n const name = record.name?.trim()\n if (name) parts.push(name)\n const domain = record.domain?.trim()\n if (domain && !parts.includes(domain)) parts.push(domain)\n const email = record.email?.trim()\n if (!parts.length && email) parts.push(email)\n if (!parts.length) parts.push(t('customers.deals.list.unnamedCompany', 'Unnamed company'))\n return parts.join(' \u2022 ')\n }, [t])\n\n const ingestPeopleRecords = React.useCallback((records: PersonLookupRecord[]) => {\n if (!records.length) return [] as FilterOption[]\n const queryMap = new Map<string, FilterOption>()\n setPeopleState((prev) => {\n const idToLabel = { ...prev.idToLabel }\n const labelToId: Record<string, string> = {}\n const merged = new Map(prev.options.map((opt) => [opt.value, opt]))\n const occupied = new Set<string>()\n Object.entries(prev.labelToId).forEach(([label, id]) => {\n occupied.add(label)\n labelToId[label] = id\n })\n records.forEach((record) => {\n if (!isUuid(record.id)) return\n const base = buildPersonLabel(record)\n let previousLabel = idToLabel[record.id]\n if (previousLabel) {\n // remove previous label before reassigning\n delete labelToId[previousLabel]\n occupied.delete(previousLabel)\n }\n const label = ensureUniqueLabel(base, occupied)\n idToLabel[record.id] = label\n labelToId[label] = record.id\n const option = { value: record.id, label }\n merged.set(record.id, option)\n queryMap.set(record.id, option)\n })\n const nextOptions = Array.from(merged.values()).sort((a, b) => a.label.localeCompare(b.label))\n return { options: nextOptions, idToLabel, labelToId }\n })\n return Array.from(queryMap.values()).sort((a, b) => a.label.localeCompare(b.label))\n }, [buildPersonLabel])\n\n const ingestCompanyRecords = React.useCallback((records: CompanyLookupRecord[]) => {\n if (!records.length) return [] as FilterOption[]\n const queryMap = new Map<string, FilterOption>()\n setCompaniesState((prev) => {\n const idToLabel = { ...prev.idToLabel }\n const labelToId: Record<string, string> = {}\n const merged = new Map(prev.options.map((opt) => [opt.value, opt]))\n const occupied = new Set<string>()\n Object.entries(prev.labelToId).forEach(([label, id]) => {\n occupied.add(label)\n labelToId[label] = id\n })\n records.forEach((record) => {\n if (!isUuid(record.id)) return\n const base = buildCompanyLabel(record)\n let previousLabel = idToLabel[record.id]\n if (previousLabel) {\n delete labelToId[previousLabel]\n occupied.delete(previousLabel)\n }\n const label = ensureUniqueLabel(base, occupied)\n idToLabel[record.id] = label\n labelToId[label] = record.id\n const option = { value: record.id, label }\n merged.set(record.id, option)\n queryMap.set(record.id, option)\n })\n const nextOptions = Array.from(merged.values()).sort((a, b) => a.label.localeCompare(b.label))\n return { options: nextOptions, idToLabel, labelToId }\n })\n return Array.from(queryMap.values()).sort((a, b) => a.label.localeCompare(b.label))\n }, [buildCompanyLabel])\n\n const loadPeopleOptions = React.useCallback(async (query?: string) => {\n const normalizedQuery = (query || '').trim().toLowerCase()\n const cacheKey = `${scopeVersion}|${normalizedQuery}`\n const cached = peopleCacheRef.current.get(cacheKey)\n if (cached) return cached\n const records = await fetchPeopleLookup(query)\n const options = ingestPeopleRecords(records)\n peopleCacheRef.current.set(cacheKey, options)\n return options\n }, [scopeVersion, ingestPeopleRecords])\n\n const loadCompanyOptions = React.useCallback(async (query?: string) => {\n const normalizedQuery = (query || '').trim().toLowerCase()\n const cacheKey = `${scopeVersion}|${normalizedQuery}`\n const cached = companiesCacheRef.current.get(cacheKey)\n if (cached) return cached\n const records = await fetchCompaniesLookup(query)\n const options = ingestCompanyRecords(records)\n companiesCacheRef.current.set(cacheKey, options)\n return options\n }, [scopeVersion, ingestCompanyRecords])\n\n React.useEffect(() => {\n let cancelled = false\n if (!selectedPersonIds.length) return\n const missing = selectedPersonIds.filter((id) => !peopleState.idToLabel[id])\n if (!missing.length) return\n fetchPeopleLookupByIds(missing).then((records) => {\n if (cancelled) return\n ingestPeopleRecords(records)\n })\n return () => { cancelled = true }\n }, [selectedPersonIds, peopleState.idToLabel, ingestPeopleRecords])\n\n React.useEffect(() => {\n let cancelled = false\n if (!selectedCompanyIds.length) return\n const missing = selectedCompanyIds.filter((id) => !companiesState.idToLabel[id])\n if (!missing.length) return\n fetchCompaniesLookupByIds(missing).then((records) => {\n if (cancelled) return\n ingestCompanyRecords(records)\n })\n return () => { cancelled = true }\n }, [selectedCompanyIds, companiesState.idToLabel, ingestCompanyRecords])\n\n const [dictionaryMaps, setDictionaryMaps] = React.useState<Record<DictionaryKey, CustomerDictionaryMap>>({\n 'deal-statuses': {},\n 'pipeline-stages': {},\n })\n\n const [pipelineNames, setPipelineNames] = React.useState<Record<string, string>>({})\n\n const fetchDictionaryEntries = React.useCallback(\n async (kind: DictionaryKey) => {\n try {\n const data = await ensureCustomerDictionary(queryClient, kind, scopeVersion)\n setDictionaryMaps((prev) => ({ ...prev, [kind]: data.map }))\n } catch {\n setDictionaryMaps((prev) => ({ ...prev, [kind]: {} }))\n }\n },\n [queryClient, scopeVersion],\n )\n\n React.useEffect(() => {\n let cancelled = false\n async function loadDictionaries() {\n if (cancelled) return\n await Promise.all([fetchDictionaryEntries('deal-statuses'), fetchDictionaryEntries('pipeline-stages')])\n }\n loadDictionaries().catch(() => {})\n return () => { cancelled = true }\n }, [fetchDictionaryEntries, reloadToken])\n\n React.useEffect(() => {\n let cancelled = false\n async function loadPipelines() {\n try {\n const call = await apiCall<{ items?: Array<{ id: string; name: string }> }>('/api/customers/pipelines')\n if (cancelled || !call.ok) return\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const map: Record<string, string> = {}\n items.forEach((p) => { if (p.id && p.name) map[p.id] = p.name })\n setPipelineNames(map)\n } catch {}\n }\n loadPipelines().catch(() => {})\n return () => { cancelled = true }\n }, [reloadToken, scopeVersion])\n\n React.useEffect(() => {\n peopleCacheRef.current.clear()\n companiesCacheRef.current.clear()\n setPeopleState((prev) => {\n if (!prev.options.length && !Object.keys(prev.idToLabel).length) return prev\n return { ...EMPTY_OPTIONS_STATE }\n })\n setCompaniesState((prev) => {\n if (!prev.options.length && !Object.keys(prev.idToLabel).length) return prev\n return { ...EMPTY_OPTIONS_STATE }\n })\n }, [scopeVersion, reloadToken])\n\n const syncFilterLabels = React.useCallback((\n key: 'people' | 'companies',\n ids: string[],\n idToLabel: Record<string, string>,\n ) => {\n setFilterValues((prev) => {\n const current = Array.isArray(prev[key]) ? (prev[key] as string[]) : []\n if (!ids.length) {\n if (!current.length) return prev\n const next = { ...prev }\n delete next[key]\n return next\n }\n const labels: string[] = []\n ids.forEach((id) => {\n const label = idToLabel[id]\n if (label && !labels.includes(label)) labels.push(label)\n })\n if (labels.length < ids.length) return prev\n if (arraysEqual(current, labels)) return prev\n return { ...prev, [key]: labels }\n })\n }, [])\n\n React.useEffect(() => {\n syncFilterLabels('people', selectedPersonIds, peopleState.idToLabel)\n }, [selectedPersonIds, peopleState.idToLabel, syncFilterLabels])\n\n React.useEffect(() => {\n syncFilterLabels('companies', selectedCompanyIds, companiesState.idToLabel)\n }, [selectedCompanyIds, companiesState.idToLabel, syncFilterLabels])\n\n const handleSearchChange = React.useCallback((value: string) => {\n setSearch(value.trim())\n setPage(1)\n }, [])\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n const next: FilterValues = { ...values }\n const rawPeople = Array.isArray(values.people) ? (values.people as string[]) : []\n const nextPersonIds: string[] = []\n rawPeople.forEach((value) => {\n const trimmed = typeof value === 'string' ? value.trim() : ''\n if (!trimmed) return\n const mapped = peopleState.labelToId[trimmed]\n if (mapped && !nextPersonIds.includes(mapped)) nextPersonIds.push(mapped)\n })\n setSelectedPersonIds(nextPersonIds)\n if (nextPersonIds.length) {\n next.people = Array.from(new Set(rawPeople.map((value) => (typeof value === 'string' ? value.trim() : '')).filter((value) => value.length > 0)))\n } else {\n delete next.people\n }\n\n const rawCompanies = Array.isArray(values.companies) ? (values.companies as string[]) : []\n const nextCompanyIds: string[] = []\n rawCompanies.forEach((value) => {\n const trimmed = typeof value === 'string' ? value.trim() : ''\n if (!trimmed) return\n const mapped = companiesState.labelToId[trimmed]\n if (mapped && !nextCompanyIds.includes(mapped)) nextCompanyIds.push(mapped)\n })\n setSelectedCompanyIds(nextCompanyIds)\n if (nextCompanyIds.length) {\n next.companies = Array.from(new Set(rawCompanies.map((value) => (typeof value === 'string' ? value.trim() : '')).filter((value) => value.length > 0)))\n } else {\n delete next.companies\n }\n\n setFilterValues(next)\n setPage(1)\n }, [peopleState.labelToId, companiesState.labelToId])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({})\n setSelectedPersonIds([])\n setSelectedCompanyIds([])\n setPage(1)\n }, [])\n\n const queryParams = React.useMemo(() => {\n const params = new URLSearchParams()\n params.set('page', String(page))\n params.set('pageSize', String(pageSize))\n if (sorting.length > 0) {\n params.set('sort', sorting[0].id)\n params.set('order', sorting[0].desc ? 'desc' : 'asc')\n }\n if (search.trim().length) params.set('search', search.trim())\n if (selectedPersonIds.length) params.set('personId', selectedPersonIds.join(','))\n if (selectedCompanyIds.length) params.set('companyId', selectedCompanyIds.join(','))\n Object.entries(filterValues).forEach(([key, value]) => {\n if (key === 'people' || key === 'companies') return\n if (value == null) return\n if (Array.isArray(value)) {\n const normalized = value\n .map((item) => {\n if (item == null) return ''\n if (typeof item === 'string') return item.trim()\n return String(item).trim()\n })\n .filter((item) => item.length > 0)\n if (normalized.length) params.set(key, normalized.join(','))\n } else if (typeof value === 'object') {\n const obj = value as Record<string, unknown>\n const from = typeof obj.from === 'string' ? obj.from.trim() : ''\n const to = typeof obj.to === 'string' ? obj.to.trim() : ''\n if (from) params.set(`${key}[from]`, from)\n if (to) params.set(`${key}[to]`, to)\n } else {\n const stringValue = typeof value === 'string' ? value.trim() : String(value)\n if (stringValue) params.set(key, stringValue)\n }\n })\n const advancedParams = serializeAdvancedFilter(advancedFilterState)\n for (const [key, val] of Object.entries(advancedParams)) {\n params.set(key, val)\n }\n return params.toString()\n }, [advancedFilterState, filterValues, page, pageSize, search, selectedCompanyIds, selectedPersonIds, sorting])\n\n const currentParams = React.useMemo(\n () => Object.fromEntries(new URLSearchParams(queryParams)),\n [queryParams],\n )\n\n const exportConfig = React.useMemo(() => ({\n view: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('customers/deals', { ...currentParams, exportScope: 'view' }, format),\n },\n full: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('customers/deals', { ...currentParams, exportScope: 'full', all: 'true' }, format),\n },\n }), [currentParams])\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setIsLoading(true)\n setCacheStatus(null)\n try {\n const fallback: DealsResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<DealsResponse>(`/api/customers/deals?${queryParams}`, undefined, { fallback })\n if (!call.ok) {\n const message =\n typeof (call.result as { error?: string } | undefined)?.error === 'string'\n ? (call.result as { error?: string }).error!\n : t('customers.deals.list.error.load')\n flash(message, 'error')\n if (!cancelled) setCacheStatus(null)\n return\n }\n const payload = call.result ?? fallback\n if (cancelled) return\n setCacheStatus(call.cacheStatus ?? null)\n const items = Array.isArray(payload.items) ? payload.items : []\n const mapped = items\n .map((item) => mapDeal(item as Record<string, unknown>))\n .filter((row): row is DealRow => !!row)\n setRows(mapped)\n setTotal(typeof payload.total === 'number' ? payload.total : mapped.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : 1)\n } catch (err) {\n if (!cancelled) {\n setCacheStatus(null)\n const message = err instanceof Error ? err.message : t('customers.deals.list.error.load')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n load()\n return () => { cancelled = true }\n }, [queryParams, reloadToken, scopeVersion, t])\n\n React.useEffect(() => {\n if (totalPages > 0 && page > totalPages) {\n setPage(totalPages)\n }\n }, [page, totalPages])\n\n const queryRef = React.useRef(searchParams?.toString() ?? '')\n React.useEffect(() => {\n if (!pathname) return\n const params = new URLSearchParams()\n if (search.trim().length) params.set('search', search.trim())\n if (selectedPersonIds.length) selectedPersonIds.forEach((id) => params.append('personId', id))\n if (selectedCompanyIds.length) selectedCompanyIds.forEach((id) => params.append('companyId', id))\n if (page > 1) params.set('page', String(page))\n const next = params.toString()\n if (queryRef.current === next) return\n queryRef.current = next\n router.replace(next ? `${pathname}?${next}` : pathname, { scroll: false })\n }, [pathname, router, page, search, selectedPersonIds, selectedCompanyIds])\n\n const handleRefresh = React.useCallback(() => {\n peopleCacheRef.current.clear()\n companiesCacheRef.current.clear()\n void Promise.all([\n invalidateCustomerDictionary(queryClient, 'deal-statuses'),\n invalidateCustomerDictionary(queryClient, 'pipeline-stages'),\n ])\n setReloadToken((token) => token + 1)\n }, [queryClient])\n\n const handleDeleteDeal = React.useCallback(\n async (dealId: string) => {\n if (pendingDeleteId) return\n const confirmed = await confirm({\n title: t(\n 'customers.deals.list.deleteConfirm',\n 'Delete this deal? This action cannot be undone.',\n ),\n variant: 'destructive',\n })\n if (!confirmed) return\n setPendingDeleteId(dealId)\n try {\n await deleteCrud('customers/deals', {\n body: { id: dealId },\n errorMessage: t('customers.deals.list.deleteError', 'Failed to delete deal.'),\n })\n flash(t('customers.deals.list.deleteSuccess', 'Deal deleted.'), 'success')\n setRows((prev) => prev.filter((row) => row.id !== dealId))\n setTotal((prev) => Math.max(0, prev - 1))\n handleRefresh()\n } catch (err) {\n const message =\n err instanceof Error && err.message\n ? err.message\n : t('customers.deals.list.deleteError', 'Failed to delete deal.')\n flash(message, 'error')\n } finally {\n setPendingDeleteId(null)\n }\n },\n [confirm, handleRefresh, pendingDeleteId, t],\n )\n\n const handlePageSizeChange = React.useCallback((newSize: number) => {\n setPageSize(newSize)\n setPage(1)\n }, [])\n\n const handleBulkDelete = React.useCallback(async (selectedRows: DealRow[]) => {\n const confirmed = await confirm({\n title: t('customers.deals.list.bulkDelete.title', 'Delete {count} deals?', { count: selectedRows.length }),\n description: t('customers.deals.list.bulkDelete.description', 'This action cannot be undone.'),\n variant: 'destructive',\n })\n if (!confirmed) return false\n let deletedCount = 0\n for (const row of selectedRows) {\n try {\n await deleteCrud('customers/deals', {\n body: { id: row.id },\n errorMessage: t('customers.deals.list.deleteError', 'Failed to delete deal.'),\n })\n deletedCount++\n } catch {}\n }\n if (deletedCount > 0) {\n setRows((prev) => {\n const deletedIds = new Set(selectedRows.map((r) => r.id))\n return prev.filter((r) => !deletedIds.has(r.id))\n })\n setTotal((prev) => Math.max(0, prev - deletedCount))\n flash(t('customers.deals.list.bulkDelete.success', '{count} deals deleted', { count: deletedCount }), 'success')\n }\n return deletedCount > 0\n }, [confirm, t])\n\n const personOptions = peopleState.options\n const companyOptions = companiesState.options\n\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'people',\n label: t('customers.deals.list.filters.people'),\n type: 'tags',\n options: personOptions,\n loadOptions: loadPeopleOptions,\n placeholder: t('customers.deals.list.filters.peoplePlaceholder'),\n },\n {\n id: 'companies',\n label: t('customers.deals.list.filters.companies'),\n type: 'tags',\n options: companyOptions,\n loadOptions: loadCompanyOptions,\n placeholder: t('customers.deals.list.filters.companiesPlaceholder'),\n },\n ], [companyOptions, loadCompanyOptions, loadPeopleOptions, personOptions, t])\n\n const { data: customFieldDefs = [] } = useCustomFieldDefs([E.customers.customer_deal], {\n keyExtras: [scopeVersion, reloadToken],\n })\n\n const columns = React.useMemo<ColumnDef<DealRow>[]>(() => {\n const noValue = <span className=\"text-muted-foreground text-sm\">{t('customers.deals.list.noValue')}</span>\n const renderDictionaryCell = (kind: DictionaryKey, value: string | null | undefined) => (\n <DictionaryValue\n value={value}\n map={dictionaryMaps[kind]}\n fallback={value ? <span className=\"text-sm\">{value}</span> : noValue}\n className=\"text-sm\"\n iconWrapperClassName=\"inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-card\"\n iconClassName=\"h-4 w-4\"\n colorClassName=\"h-3 w-3 rounded-full\"\n />\n )\n const renderAssociationList = (\n items: { id: string; label: string }[],\n fallbackLabel: string,\n ) => {\n if (!items.length) return noValue\n return (\n <ul className=\"flex flex-wrap gap-1 text-sm\">\n {items.map((entry) => (\n <li key={entry.id} className=\"rounded border px-2 py-0.5 text-xs bg-muted\">\n {entry.label && entry.label.trim().length ? entry.label : fallbackLabel}\n </li>\n ))}\n </ul>\n )\n }\n\n const customColumns = customFieldDefs\n .filter((def) => supportsCustomFieldColumn(def))\n .map<ColumnDef<DealRow>>((def) => ({\n accessorKey: `cf_${def.key}`,\n header: def.label || def.key,\n meta: {\n columnChooserGroup: def.group?.title ?? 'Custom Fields',\n filterGroup: def.group?.title ?? 'Custom Fields',\n filterType: mapCustomFieldKindToFilterType(def.kind),\n filterOptions: normalizeCustomFieldFilterOptions(def.options),\n hidden: def.listVisible === false,\n },\n cell: ({ getValue }) => {\n const value = getValue()\n if (value == null) return noValue\n if (Array.isArray(value)) {\n const normalized = value\n .map((item) => {\n if (item == null) return ''\n if (typeof item === 'string') return item.trim()\n return String(item).trim()\n })\n .filter((item) => item.length > 0)\n if (!normalized.length) return noValue\n return <span className=\"text-sm\">{normalized.join(', ')}</span>\n }\n if (typeof value === 'boolean') {\n return (\n <span className=\"text-sm\">\n {value\n ? t('customers.deals.list.booleanYes', 'Yes')\n : t('customers.deals.list.booleanNo', 'No')}\n </span>\n )\n }\n const stringValue = typeof value === 'string' ? value.trim() : String(value)\n if (!stringValue) return noValue\n return <span className=\"text-sm\">{stringValue}</span>\n },\n }))\n\n return [\n {\n accessorKey: 'title',\n header: t('customers.deals.list.columns.title'),\n meta: { alwaysVisible: true, columnChooserGroup: 'Basic Info', filterKey: 'title' },\n cell: ({ row }) => <span className=\"font-medium text-sm\">{row.original.title}</span>,\n },\n {\n accessorKey: 'status',\n header: t('customers.deals.list.columns.status'),\n meta: { filterType: 'select' as const, columnChooserGroup: 'Basic Info', filterKey: 'status' },\n cell: ({ row }) => renderDictionaryCell('deal-statuses', row.original.status),\n },\n {\n accessorKey: 'pipelineStage',\n header: t('customers.deals.list.columns.pipelineStage'),\n meta: { columnChooserGroup: 'Pipeline', filterKey: 'pipeline_stage' },\n cell: ({ row }) => renderDictionaryCell('pipeline-stages', row.original.pipelineStage),\n },\n {\n accessorKey: 'pipelineId',\n header: t('customers.deals.list.columns.pipeline', 'Pipeline'),\n meta: { columnChooserGroup: 'Pipeline', filterKey: 'pipeline_id' },\n cell: ({ row }) => {\n const name = row.original.pipelineId ? pipelineNames[row.original.pipelineId] : null\n return name ? <span className=\"text-sm\">{name}</span> : noValue\n },\n },\n {\n accessorKey: 'valueAmount',\n header: t('customers.deals.list.columns.value'),\n meta: { filterType: 'number' as const, columnChooserGroup: 'Financial', filterKey: 'value_amount' },\n cell: ({ row }) => (\n <span className=\"text-sm font-medium\">\n {formatCurrency(row.original.valueAmount ?? null, row.original.valueCurrency ?? null, t('customers.deals.list.noValue'))}\n </span>\n ),\n },\n {\n accessorKey: 'probability',\n header: t('customers.deals.list.columns.probability'),\n meta: { filterType: 'number' as const, columnChooserGroup: 'Financial', filterKey: 'probability' },\n cell: ({ row }) => {\n const value = row.original.probability\n if (typeof value === 'number' && Number.isFinite(value)) {\n return <span className=\"text-sm\">{`${Math.min(Math.max(value, 0), 100)}%`}</span>\n }\n return noValue\n },\n },\n {\n accessorKey: 'expectedCloseAt',\n header: t('customers.deals.list.columns.expectedClose'),\n meta: { columnChooserGroup: 'Dates', filterKey: 'expected_close_at' },\n cell: ({ row }) => (\n <span className=\"text-sm\">\n {formatDateValue(row.original.expectedCloseAt ?? null, t('customers.deals.list.noValue'))}\n </span>\n ),\n },\n {\n accessorKey: 'companies',\n header: t('customers.deals.list.columns.companies'),\n meta: { columnChooserGroup: 'Associations', filterable: false },\n cell: ({ row }) => renderAssociationList(row.original.companies, t('customers.deals.list.unnamedCompany')),\n },\n {\n accessorKey: 'people',\n header: t('customers.deals.list.columns.people'),\n meta: { columnChooserGroup: 'Associations', filterable: false },\n cell: ({ row }) => renderAssociationList(row.original.people, t('customers.deals.list.unnamedPerson')),\n },\n {\n accessorKey: 'updatedAt',\n header: t('customers.deals.list.columns.updatedAt'),\n meta: { columnChooserGroup: 'Dates', filterKey: 'updated_at' },\n cell: ({ row }) => (\n <span className=\"text-sm\">\n {formatDateValue(row.original.updatedAt ?? null, t('customers.deals.list.noValue'))}\n </span>\n ),\n },\n ...customColumns,\n ]\n }, [customFieldDefs, dictionaryMaps, pipelineNames, t])\n\n return (\n <Page>\n <PageBody>\n <DataTable<DealRow>\n stickyFirstColumn\n stickyActionsColumn\n title={t('customers.deals.list.title')}\n actions={(\n <Button asChild>\n <Link href=\"/backend/customers/deals/create\">\n {t('customers.deals.list.actions.new', 'New deal')}\n </Link>\n </Button>\n )}\n columns={columns}\n columnChooser={{ auto: true }}\n data={rows}\n onRowClick={(row) => {\n router.push(`/backend/customers/deals/${row.id}`)\n }}\n rowActions={(row) => {\n const isDeleting = pendingDeleteId === row.id\n return (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('customers.deals.list.actions.edit', 'Edit'),\n onSelect: () => { router.push(`/backend/customers/deals/${row.id}`) },\n },\n {\n id: 'open-new-tab',\n label: t('customers.deals.list.actions.openInNewTab', 'Open in new tab'),\n onSelect: () => {\n if (typeof window !== 'undefined') {\n window.open(`/backend/customers/deals/${row.id}`, '_blank', 'noopener')\n }\n },\n },\n {\n id: 'delete',\n label: isDeleting\n ? t('customers.deals.list.actions.deleting', 'Deleting\u2026')\n : t('customers.deals.list.actions.delete', 'Delete'),\n destructive: true,\n onSelect: () => handleDeleteDeal(row.id),\n },\n ]}\n />\n )\n }}\n sortable\n sorting={sorting}\n onSortingChange={setSorting}\n bulkActions={[\n {\n id: 'delete',\n label: t('customers.deals.list.actions.delete', 'Delete'),\n destructive: true,\n onExecute: handleBulkDelete,\n },\n ]}\n searchValue={search}\n onSearchChange={handleSearchChange}\n searchPlaceholder={t('customers.deals.list.searchPlaceholder')}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n pagination={{\n page,\n pageSize,\n total,\n totalPages,\n onPageChange: (nextPage) => setPage(nextPage),\n pageSizeOptions: [10, 25, 50, 100],\n onPageSizeChange: handlePageSizeChange,\n cacheStatus,\n }}\n isLoading={isLoading}\n refreshButton={{\n label: t('customers.deals.list.refresh'),\n onRefresh: handleRefresh,\n }}\n exporter={exportConfig}\n entityId={E.customers.customer_deal}\n perspective={{ tableId: 'customers.deals.list' }}\n advancedFilter={{\n auto: true,\n value: advancedFilterState,\n onChange: setAdvancedFilterState,\n onApply: () => { setPage(1) },\n onClear: () => { setAdvancedFilterState({ logic: 'and', conditions: [] }); setPage(1) },\n }}\n virtualized\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n\nfunction mapDeal(item: Record<string, unknown>): DealRow | null {\n const id = typeof item.id === 'string' ? item.id : null\n if (!id) return null\n const title = typeof item.title === 'string' ? item.title : ''\n const status = typeof item.status === 'string' ? item.status : null\n const pipelineStage = typeof item.pipeline_stage === 'string' ? item.pipeline_stage : null\n const pipelineStageId = typeof item.pipeline_stage_id === 'string' ? item.pipeline_stage_id : null\n const pipelineId = typeof item.pipeline_id === 'string' ? item.pipeline_id : null\n const valueAmountRaw = item.value_amount\n const valueAmount =\n typeof valueAmountRaw === 'number'\n ? valueAmountRaw\n : typeof valueAmountRaw === 'string' && valueAmountRaw.trim()\n ? Number(valueAmountRaw)\n : null\n const valueCurrency =\n typeof item.value_currency === 'string' && item.value_currency.trim().length\n ? item.value_currency.trim().toUpperCase()\n : null\n const probabilityRaw = item.probability\n const probability =\n typeof probabilityRaw === 'number'\n ? probabilityRaw\n : typeof probabilityRaw === 'string' && probabilityRaw.trim().length\n ? Number(probabilityRaw)\n : null\n const expectedCloseAt = typeof item.expected_close_at === 'string' ? item.expected_close_at : null\n const updatedAt = typeof item.updated_at === 'string' ? item.updated_at : null\n const peopleRaw = Array.isArray(item.people) ? item.people : []\n const companiesRaw = Array.isArray(item.companies) ? item.companies : []\n const people = peopleRaw\n .map((entry) => {\n if (!entry || typeof entry !== 'object') return null\n const data = entry as Record<string, unknown>\n const pid = typeof data.id === 'string' ? data.id : null\n if (!pid) return null\n const label = typeof data.label === 'string' ? data.label : ''\n return { id: pid, label }\n })\n .filter((entry): entry is { id: string; label: string } => !!entry)\n const companies = companiesRaw\n .map((entry) => {\n if (!entry || typeof entry !== 'object') return null\n const data = entry as Record<string, unknown>\n const cid = typeof data.id === 'string' ? data.id : null\n if (!cid) return null\n const label = typeof data.label === 'string' ? data.label : ''\n return { id: cid, label }\n })\n .filter((entry): entry is { id: string; label: string } => !!entry)\n const customFields: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(item)) {\n if (key.startsWith('cf_')) customFields[key] = value\n }\n return withDataTableNamespaces({\n id,\n title,\n status,\n pipelineStage,\n pipelineStageId,\n pipelineId,\n valueAmount,\n valueCurrency,\n probability,\n expectedCloseAt,\n updatedAt,\n people,\n companies,\n ...customFields,\n }, item)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { usePathname, useRouter, useSearchParams } from 'next/navigation'\nimport { useQueryClient } from '@tanstack/react-query'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, type DataTableExportFormat, withDataTableNamespaces } from '@open-mercato/ui/backend/DataTable'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport type { AdvancedFilterState } from '@open-mercato/shared/lib/query/advanced-filter'\nimport { serializeAdvancedFilter } from '@open-mercato/shared/lib/query/advanced-filter'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildCrudExportUrl, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { E } from '#generated/entities.ids.generated'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport {\n DictionaryValue,\n type CustomerDictionaryKind,\n type CustomerDictionaryMap,\n} from '../../../lib/dictionaries'\nimport {\n ensureCustomerDictionary,\n invalidateCustomerDictionary,\n} from '../../../components/detail/hooks/useCustomerDictionary'\nimport {\n useCustomFieldDefs,\n} from '@open-mercato/ui/backend/utils/customFieldDefs'\nimport {\n mapCustomFieldKindToFilterType,\n normalizeCustomFieldFilterOptions,\n supportsCustomFieldColumn,\n} from '@open-mercato/ui/backend/utils/customFieldColumns'\nimport { CollectionPreviewCell, normalizeCollectionLabels } from '../../../components/list/CollectionPreviewCell'\n\ntype DealRow = {\n id: string\n title: string\n status?: string | null\n pipelineStage?: string | null\n pipelineStageId?: string | null\n pipelineId?: string | null\n valueAmount?: number | null\n valueCurrency?: string | null\n probability?: number | null\n expectedCloseAt?: string | null\n updatedAt?: string | null\n companies: { id: string; label: string }[]\n people: { id: string; label: string }[]\n} & Record<string, unknown>\n\ntype DealsResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n totalPages?: number\n}\n\ntype FilterOption = { value: string; label: string }\n\ntype DictionaryKey = Extract<CustomerDictionaryKind, 'deal-statuses' | 'pipeline-stages'>\n\ntype PersonLookupRecord = {\n id: string\n name: string | null\n email: string | null\n phone: string | null\n}\n\ntype CompanyLookupRecord = {\n id: string\n name: string | null\n domain: string | null\n email: string | null\n}\n\nfunction parsePersonLookupRecord(item: unknown): PersonLookupRecord | null {\n if (typeof item !== 'object' || item === null) return null\n const record = item as Record<string, unknown>\n const id = typeof record.id === 'string' ? record.id : null\n if (!id || !isUuid(id)) return null\n const name = typeof record.display_name === 'string' ? record.display_name : null\n const email = typeof record.primary_email === 'string' ? record.primary_email : null\n const phone = typeof record.primary_phone === 'string' ? record.primary_phone : null\n return { id, name, email, phone }\n}\n\nfunction parseCompanyLookupRecord(item: unknown): CompanyLookupRecord | null {\n if (typeof item !== 'object' || item === null) return null\n const record = item as Record<string, unknown>\n const id = typeof record.id === 'string' ? record.id : null\n if (!id || !isUuid(id)) return null\n const name = typeof record.display_name === 'string' ? record.display_name : null\n const domain = typeof record.primary_domain === 'string' ? record.primary_domain : null\n const email = typeof record.primary_email === 'string' ? record.primary_email : null\n return { id, name, domain, email }\n}\n\ntype OptionsState = {\n options: FilterOption[]\n idToLabel: Record<string, string>\n labelToId: Record<string, string>\n}\n\nconst EMPTY_OPTIONS_STATE: OptionsState = {\n options: [],\n idToLabel: {},\n labelToId: {},\n}\n\nconst PAGE_SIZE = 20\nconst UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i\n\nfunction isUuid(value: string | null | undefined): value is string {\n if (!value) return false\n return UUID_REGEX.test(value.trim())\n}\n\nfunction normalizeIdCandidates(raw: Array<string>): string[] {\n const set = new Set<string>()\n raw.forEach((candidate) => {\n candidate\n .split(',')\n .map((part) => part.trim())\n .filter((part) => part.length > 0)\n .forEach((part) => {\n if (isUuid(part)) set.add(part)\n })\n })\n return Array.from(set)\n}\n\nfunction extractIdsFromParams(params: URLSearchParams | null | undefined, key: string): string[] {\n if (!params) return []\n const values = params.getAll(key)\n return normalizeIdCandidates(values)\n}\n\nfunction ensureUniqueLabel(base: string, occupied: Set<string>): string {\n const trimmed = base.trim() || 'Unnamed'\n if (!occupied.has(trimmed)) {\n occupied.add(trimmed)\n return trimmed\n }\n let counter = 2\n let candidate = `${trimmed} \u2022 ${counter}`\n while (occupied.has(candidate)) {\n counter += 1\n candidate = `${trimmed} \u2022 ${counter}`\n }\n occupied.add(candidate)\n return candidate\n}\n\nasync function fetchPeopleLookup(query?: string): Promise<PersonLookupRecord[]> {\n const search = new URLSearchParams()\n search.set('page', '1')\n search.set('pageSize', '20')\n if (query && query.trim().length) search.set('search', query.trim())\n try {\n const call = await apiCall<{ items?: unknown[] }>(`/api/customers/people?${search.toString()}`)\n if (!call.ok) return []\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n return items\n .map((item) => parsePersonLookupRecord(item))\n .filter((record): record is PersonLookupRecord => record !== null)\n } catch {\n return []\n }\n}\n\nasync function fetchPeopleLookupByIds(ids: string[]): Promise<PersonLookupRecord[]> {\n const unique = Array.from(new Set(ids.filter((id) => isUuid(id))))\n if (!unique.length) return []\n const results = await Promise.all(\n unique.map(async (id) => {\n const search = new URLSearchParams()\n search.set('id', id)\n search.set('page', '1')\n search.set('pageSize', '1')\n try {\n const call = await apiCall<{ items?: unknown[] }>(`/api/customers/people?${search.toString()}`)\n if (!call.ok) return null\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const match = items\n .map((item) => parsePersonLookupRecord(item))\n .find((record) => record?.id === id)\n return match ?? null\n } catch {\n return null\n }\n }),\n )\n return results.filter((record): record is PersonLookupRecord => !!record)\n}\n\nasync function fetchCompaniesLookup(query?: string): Promise<CompanyLookupRecord[]> {\n const search = new URLSearchParams()\n search.set('page', '1')\n search.set('pageSize', '20')\n if (query && query.trim().length) search.set('search', query.trim())\n try {\n const call = await apiCall<{ items?: unknown[] }>(`/api/customers/companies?${search.toString()}`)\n if (!call.ok) return []\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n return items\n .map((item) => parseCompanyLookupRecord(item))\n .filter((record): record is CompanyLookupRecord => record !== null)\n } catch {\n return []\n }\n}\n\nasync function fetchCompaniesLookupByIds(ids: string[]): Promise<CompanyLookupRecord[]> {\n const unique = Array.from(new Set(ids.filter((id) => isUuid(id))))\n if (!unique.length) return []\n const results = await Promise.all(\n unique.map(async (id) => {\n const search = new URLSearchParams()\n search.set('id', id)\n search.set('page', '1')\n search.set('pageSize', '1')\n try {\n const call = await apiCall<{ items?: unknown[] }>(`/api/customers/companies?${search.toString()}`)\n if (!call.ok) return null\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const match = items\n .map((item) => parseCompanyLookupRecord(item))\n .find((record) => record?.id === id)\n return match ?? null\n } catch {\n return null\n }\n }),\n )\n return results.filter((record): record is CompanyLookupRecord => !!record)\n}\n\nfunction formatCurrency(amount: number | null | undefined, currency: string | null | undefined, fallback: string): string {\n if (typeof amount !== 'number' || Number.isNaN(amount)) return fallback\n try {\n if (currency && currency.trim().length) {\n const formatter = new Intl.NumberFormat(undefined, { style: 'currency', currency })\n return formatter.format(amount)\n }\n const formatter = new Intl.NumberFormat(undefined, { style: 'decimal', maximumFractionDigits: 2 })\n return formatter.format(amount)\n } catch {\n return currency ? `${amount} ${currency}` : String(amount)\n }\n}\n\nfunction formatDateValue(value: string | null | undefined, fallback: string): string {\n if (!value) return fallback\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return fallback\n return date.toLocaleDateString()\n}\n\nfunction arraysEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i += 1) {\n if (a[i] !== b[i]) return false\n }\n return true\n}\n\nexport default function CustomersDealsPage() {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const router = useRouter()\n const pathname = usePathname()\n const searchParams = useSearchParams()\n const scopeVersion = useOrganizationScopeVersion()\n const queryClient = useQueryClient()\n\n const [rows, setRows] = React.useState<DealRow[]>([])\n const [page, setPage] = React.useState(() => {\n const raw = Number(searchParams?.get('page') ?? '1')\n return Number.isFinite(raw) && raw > 0 ? raw : 1\n })\n const [pageSize, setPageSize] = React.useState(PAGE_SIZE)\n const [sorting, setSorting] = React.useState<import('@tanstack/react-table').SortingState>([])\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [search, setSearch] = React.useState(() => searchParams?.get('search')?.trim() ?? '')\n const [isLoading, setIsLoading] = React.useState(false)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [pendingDeleteId, setPendingDeleteId] = React.useState<string | null>(null)\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [advancedFilterState, setAdvancedFilterState] = React.useState<AdvancedFilterState>({ logic: 'and', conditions: [] })\n const [cacheStatus, setCacheStatus] = React.useState<'hit' | 'miss' | null>(null)\n\n const initialPersonIds = React.useMemo(\n () => extractIdsFromParams(searchParams, 'personId'),\n [searchParams],\n )\n const initialCompanyIds = React.useMemo(\n () => extractIdsFromParams(searchParams, 'companyId'),\n [searchParams],\n )\n\n const [selectedPersonIds, setSelectedPersonIds] = React.useState<string[]>(initialPersonIds)\n const [selectedCompanyIds, setSelectedCompanyIds] = React.useState<string[]>(initialCompanyIds)\n\n const [peopleState, setPeopleState] = React.useState<OptionsState>(EMPTY_OPTIONS_STATE)\n const [companiesState, setCompaniesState] = React.useState<OptionsState>(EMPTY_OPTIONS_STATE)\n const peopleCacheRef = React.useRef<Map<string, FilterOption[]>>(new Map())\n const companiesCacheRef = React.useRef<Map<string, FilterOption[]>>(new Map())\n\n const buildPersonLabel = React.useCallback((record: PersonLookupRecord): string => {\n const parts: string[] = []\n const name = record.name?.trim()\n if (name) parts.push(name)\n const email = record.email?.trim()\n if (email && !parts.includes(email)) parts.push(email)\n const phone = record.phone?.trim()\n if (!parts.length && phone) parts.push(phone)\n if (!parts.length) parts.push(t('customers.deals.list.unnamedPerson', 'Unnamed person'))\n return parts.join(' \u2022 ')\n }, [t])\n\n const buildCompanyLabel = React.useCallback((record: CompanyLookupRecord): string => {\n const parts: string[] = []\n const name = record.name?.trim()\n if (name) parts.push(name)\n const domain = record.domain?.trim()\n if (domain && !parts.includes(domain)) parts.push(domain)\n const email = record.email?.trim()\n if (!parts.length && email) parts.push(email)\n if (!parts.length) parts.push(t('customers.deals.list.unnamedCompany', 'Unnamed company'))\n return parts.join(' \u2022 ')\n }, [t])\n\n const ingestPeopleRecords = React.useCallback((records: PersonLookupRecord[]) => {\n if (!records.length) return [] as FilterOption[]\n const queryMap = new Map<string, FilterOption>()\n setPeopleState((prev) => {\n const idToLabel = { ...prev.idToLabel }\n const labelToId: Record<string, string> = {}\n const merged = new Map(prev.options.map((opt) => [opt.value, opt]))\n const occupied = new Set<string>()\n Object.entries(prev.labelToId).forEach(([label, id]) => {\n occupied.add(label)\n labelToId[label] = id\n })\n records.forEach((record) => {\n if (!isUuid(record.id)) return\n const base = buildPersonLabel(record)\n let previousLabel = idToLabel[record.id]\n if (previousLabel) {\n // remove previous label before reassigning\n delete labelToId[previousLabel]\n occupied.delete(previousLabel)\n }\n const label = ensureUniqueLabel(base, occupied)\n idToLabel[record.id] = label\n labelToId[label] = record.id\n const option = { value: record.id, label }\n merged.set(record.id, option)\n queryMap.set(record.id, option)\n })\n const nextOptions = Array.from(merged.values()).sort((a, b) => a.label.localeCompare(b.label))\n return { options: nextOptions, idToLabel, labelToId }\n })\n return Array.from(queryMap.values()).sort((a, b) => a.label.localeCompare(b.label))\n }, [buildPersonLabel])\n\n const ingestCompanyRecords = React.useCallback((records: CompanyLookupRecord[]) => {\n if (!records.length) return [] as FilterOption[]\n const queryMap = new Map<string, FilterOption>()\n setCompaniesState((prev) => {\n const idToLabel = { ...prev.idToLabel }\n const labelToId: Record<string, string> = {}\n const merged = new Map(prev.options.map((opt) => [opt.value, opt]))\n const occupied = new Set<string>()\n Object.entries(prev.labelToId).forEach(([label, id]) => {\n occupied.add(label)\n labelToId[label] = id\n })\n records.forEach((record) => {\n if (!isUuid(record.id)) return\n const base = buildCompanyLabel(record)\n let previousLabel = idToLabel[record.id]\n if (previousLabel) {\n delete labelToId[previousLabel]\n occupied.delete(previousLabel)\n }\n const label = ensureUniqueLabel(base, occupied)\n idToLabel[record.id] = label\n labelToId[label] = record.id\n const option = { value: record.id, label }\n merged.set(record.id, option)\n queryMap.set(record.id, option)\n })\n const nextOptions = Array.from(merged.values()).sort((a, b) => a.label.localeCompare(b.label))\n return { options: nextOptions, idToLabel, labelToId }\n })\n return Array.from(queryMap.values()).sort((a, b) => a.label.localeCompare(b.label))\n }, [buildCompanyLabel])\n\n const loadPeopleOptions = React.useCallback(async (query?: string) => {\n const normalizedQuery = (query || '').trim().toLowerCase()\n const cacheKey = `${scopeVersion}|${normalizedQuery}`\n const cached = peopleCacheRef.current.get(cacheKey)\n if (cached) return cached\n const records = await fetchPeopleLookup(query)\n const options = ingestPeopleRecords(records)\n peopleCacheRef.current.set(cacheKey, options)\n return options\n }, [scopeVersion, ingestPeopleRecords])\n\n const loadCompanyOptions = React.useCallback(async (query?: string) => {\n const normalizedQuery = (query || '').trim().toLowerCase()\n const cacheKey = `${scopeVersion}|${normalizedQuery}`\n const cached = companiesCacheRef.current.get(cacheKey)\n if (cached) return cached\n const records = await fetchCompaniesLookup(query)\n const options = ingestCompanyRecords(records)\n companiesCacheRef.current.set(cacheKey, options)\n return options\n }, [scopeVersion, ingestCompanyRecords])\n\n React.useEffect(() => {\n let cancelled = false\n if (!selectedPersonIds.length) return\n const missing = selectedPersonIds.filter((id) => !peopleState.idToLabel[id])\n if (!missing.length) return\n fetchPeopleLookupByIds(missing).then((records) => {\n if (cancelled) return\n ingestPeopleRecords(records)\n })\n return () => { cancelled = true }\n }, [selectedPersonIds, peopleState.idToLabel, ingestPeopleRecords])\n\n React.useEffect(() => {\n let cancelled = false\n if (!selectedCompanyIds.length) return\n const missing = selectedCompanyIds.filter((id) => !companiesState.idToLabel[id])\n if (!missing.length) return\n fetchCompaniesLookupByIds(missing).then((records) => {\n if (cancelled) return\n ingestCompanyRecords(records)\n })\n return () => { cancelled = true }\n }, [selectedCompanyIds, companiesState.idToLabel, ingestCompanyRecords])\n\n const [dictionaryMaps, setDictionaryMaps] = React.useState<Record<DictionaryKey, CustomerDictionaryMap>>({\n 'deal-statuses': {},\n 'pipeline-stages': {},\n })\n\n const [pipelineNames, setPipelineNames] = React.useState<Record<string, string>>({})\n\n const fetchDictionaryEntries = React.useCallback(\n async (kind: DictionaryKey) => {\n try {\n const data = await ensureCustomerDictionary(queryClient, kind, scopeVersion)\n setDictionaryMaps((prev) => ({ ...prev, [kind]: data.map }))\n } catch {\n setDictionaryMaps((prev) => ({ ...prev, [kind]: {} }))\n }\n },\n [queryClient, scopeVersion],\n )\n\n React.useEffect(() => {\n let cancelled = false\n async function loadDictionaries() {\n if (cancelled) return\n await Promise.all([fetchDictionaryEntries('deal-statuses'), fetchDictionaryEntries('pipeline-stages')])\n }\n loadDictionaries().catch(() => {})\n return () => { cancelled = true }\n }, [fetchDictionaryEntries, reloadToken])\n\n React.useEffect(() => {\n let cancelled = false\n async function loadPipelines() {\n try {\n const call = await apiCall<{ items?: Array<{ id: string; name: string }> }>('/api/customers/pipelines')\n if (cancelled || !call.ok) return\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const map: Record<string, string> = {}\n items.forEach((p) => { if (p.id && p.name) map[p.id] = p.name })\n setPipelineNames(map)\n } catch (err) {\n console.warn('[customers.deals.list] failed to load pipelines', err)\n }\n }\n loadPipelines().catch((err) => {\n console.warn('[customers.deals.list] loadPipelines threw', err)\n })\n return () => { cancelled = true }\n }, [reloadToken, scopeVersion])\n\n React.useEffect(() => {\n peopleCacheRef.current.clear()\n companiesCacheRef.current.clear()\n setPeopleState((prev) => {\n if (!prev.options.length && !Object.keys(prev.idToLabel).length) return prev\n return { ...EMPTY_OPTIONS_STATE }\n })\n setCompaniesState((prev) => {\n if (!prev.options.length && !Object.keys(prev.idToLabel).length) return prev\n return { ...EMPTY_OPTIONS_STATE }\n })\n }, [scopeVersion, reloadToken])\n\n const syncFilterLabels = React.useCallback((\n key: 'people' | 'companies',\n ids: string[],\n idToLabel: Record<string, string>,\n ) => {\n setFilterValues((prev) => {\n const current = Array.isArray(prev[key]) ? (prev[key] as string[]) : []\n if (!ids.length) {\n if (!current.length) return prev\n const next = { ...prev }\n delete next[key]\n return next\n }\n const labels: string[] = []\n ids.forEach((id) => {\n const label = idToLabel[id]\n if (label && !labels.includes(label)) labels.push(label)\n })\n if (labels.length < ids.length) return prev\n if (arraysEqual(current, labels)) return prev\n return { ...prev, [key]: labels }\n })\n }, [])\n\n React.useEffect(() => {\n syncFilterLabels('people', selectedPersonIds, peopleState.idToLabel)\n }, [selectedPersonIds, peopleState.idToLabel, syncFilterLabels])\n\n React.useEffect(() => {\n syncFilterLabels('companies', selectedCompanyIds, companiesState.idToLabel)\n }, [selectedCompanyIds, companiesState.idToLabel, syncFilterLabels])\n\n const handleSearchChange = React.useCallback((value: string) => {\n setSearch(value.trim())\n setPage(1)\n }, [])\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n const next: FilterValues = { ...values }\n const rawPeople = Array.isArray(values.people) ? (values.people as string[]) : []\n const nextPersonIds: string[] = []\n rawPeople.forEach((value) => {\n const trimmed = typeof value === 'string' ? value.trim() : ''\n if (!trimmed) return\n const mapped = peopleState.labelToId[trimmed]\n if (mapped && !nextPersonIds.includes(mapped)) nextPersonIds.push(mapped)\n })\n setSelectedPersonIds(nextPersonIds)\n if (nextPersonIds.length) {\n next.people = Array.from(new Set(rawPeople.map((value) => (typeof value === 'string' ? value.trim() : '')).filter((value) => value.length > 0)))\n } else {\n delete next.people\n }\n\n const rawCompanies = Array.isArray(values.companies) ? (values.companies as string[]) : []\n const nextCompanyIds: string[] = []\n rawCompanies.forEach((value) => {\n const trimmed = typeof value === 'string' ? value.trim() : ''\n if (!trimmed) return\n const mapped = companiesState.labelToId[trimmed]\n if (mapped && !nextCompanyIds.includes(mapped)) nextCompanyIds.push(mapped)\n })\n setSelectedCompanyIds(nextCompanyIds)\n if (nextCompanyIds.length) {\n next.companies = Array.from(new Set(rawCompanies.map((value) => (typeof value === 'string' ? value.trim() : '')).filter((value) => value.length > 0)))\n } else {\n delete next.companies\n }\n\n setFilterValues(next)\n setPage(1)\n }, [peopleState.labelToId, companiesState.labelToId])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({})\n setSelectedPersonIds([])\n setSelectedCompanyIds([])\n setPage(1)\n }, [])\n\n const queryParams = React.useMemo(() => {\n const params = new URLSearchParams()\n params.set('page', String(page))\n params.set('pageSize', String(pageSize))\n if (sorting.length > 0) {\n params.set('sort', sorting[0].id)\n params.set('order', sorting[0].desc ? 'desc' : 'asc')\n }\n if (search.trim().length) params.set('search', search.trim())\n if (selectedPersonIds.length) params.set('personId', selectedPersonIds.join(','))\n if (selectedCompanyIds.length) params.set('companyId', selectedCompanyIds.join(','))\n Object.entries(filterValues).forEach(([key, value]) => {\n if (key === 'people' || key === 'companies') return\n if (value == null) return\n if (Array.isArray(value)) {\n const normalized = value\n .map((item) => {\n if (item == null) return ''\n if (typeof item === 'string') return item.trim()\n return String(item).trim()\n })\n .filter((item) => item.length > 0)\n if (normalized.length) params.set(key, normalized.join(','))\n } else if (typeof value === 'object') {\n const obj = value as Record<string, unknown>\n const from = typeof obj.from === 'string' ? obj.from.trim() : ''\n const to = typeof obj.to === 'string' ? obj.to.trim() : ''\n if (from) params.set(`${key}[from]`, from)\n if (to) params.set(`${key}[to]`, to)\n } else {\n const stringValue = typeof value === 'string' ? value.trim() : String(value)\n if (stringValue) params.set(key, stringValue)\n }\n })\n const advancedParams = serializeAdvancedFilter(advancedFilterState)\n for (const [key, val] of Object.entries(advancedParams)) {\n params.set(key, val)\n }\n return params.toString()\n }, [advancedFilterState, filterValues, page, pageSize, search, selectedCompanyIds, selectedPersonIds, sorting])\n\n const currentParams = React.useMemo(\n () => Object.fromEntries(new URLSearchParams(queryParams)),\n [queryParams],\n )\n\n const exportConfig = React.useMemo(() => ({\n view: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('customers/deals', { ...currentParams, exportScope: 'view' }, format),\n },\n full: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('customers/deals', { ...currentParams, exportScope: 'full', all: 'true' }, format),\n },\n }), [currentParams])\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setIsLoading(true)\n setCacheStatus(null)\n try {\n const fallback: DealsResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<DealsResponse>(`/api/customers/deals?${queryParams}`, undefined, { fallback })\n if (!call.ok) {\n const message =\n typeof (call.result as { error?: string } | undefined)?.error === 'string'\n ? (call.result as { error?: string }).error!\n : t('customers.deals.list.error.load')\n flash(message, 'error')\n if (!cancelled) setCacheStatus(null)\n return\n }\n const payload = call.result ?? fallback\n if (cancelled) return\n setCacheStatus(call.cacheStatus ?? null)\n const items = Array.isArray(payload.items) ? payload.items : []\n const mapped = items\n .map((item) => mapDeal(item as Record<string, unknown>))\n .filter((row): row is DealRow => !!row)\n setRows(mapped)\n setTotal(typeof payload.total === 'number' ? payload.total : mapped.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : 1)\n } catch (err) {\n if (!cancelled) {\n setCacheStatus(null)\n const message = err instanceof Error ? err.message : t('customers.deals.list.error.load')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n load()\n return () => { cancelled = true }\n }, [queryParams, reloadToken, scopeVersion, t])\n\n React.useEffect(() => {\n if (totalPages > 0 && page > totalPages) {\n setPage(totalPages)\n }\n }, [page, totalPages])\n\n const queryRef = React.useRef(searchParams?.toString() ?? '')\n React.useEffect(() => {\n if (!pathname) return\n const params = new URLSearchParams()\n if (search.trim().length) params.set('search', search.trim())\n if (selectedPersonIds.length) selectedPersonIds.forEach((id) => params.append('personId', id))\n if (selectedCompanyIds.length) selectedCompanyIds.forEach((id) => params.append('companyId', id))\n if (page > 1) params.set('page', String(page))\n const next = params.toString()\n if (queryRef.current === next) return\n queryRef.current = next\n router.replace(next ? `${pathname}?${next}` : pathname, { scroll: false })\n }, [pathname, router, page, search, selectedPersonIds, selectedCompanyIds])\n\n const handleRefresh = React.useCallback(() => {\n peopleCacheRef.current.clear()\n companiesCacheRef.current.clear()\n void Promise.all([\n invalidateCustomerDictionary(queryClient, 'deal-statuses'),\n invalidateCustomerDictionary(queryClient, 'pipeline-stages'),\n ])\n setReloadToken((token) => token + 1)\n }, [queryClient])\n\n const handleDeleteDeal = React.useCallback(\n async (dealId: string) => {\n if (pendingDeleteId) return\n const confirmed = await confirm({\n title: t(\n 'customers.deals.list.deleteConfirm',\n 'Delete this deal? This action cannot be undone.',\n ),\n variant: 'destructive',\n })\n if (!confirmed) return\n setPendingDeleteId(dealId)\n try {\n await deleteCrud('customers/deals', {\n body: { id: dealId },\n errorMessage: t('customers.deals.list.deleteError', 'Failed to delete deal.'),\n })\n flash(t('customers.deals.list.deleteSuccess', 'Deal deleted.'), 'success')\n setRows((prev) => prev.filter((row) => row.id !== dealId))\n setTotal((prev) => Math.max(0, prev - 1))\n handleRefresh()\n } catch (err) {\n const message =\n err instanceof Error && err.message\n ? err.message\n : t('customers.deals.list.deleteError', 'Failed to delete deal.')\n flash(message, 'error')\n } finally {\n setPendingDeleteId(null)\n }\n },\n [confirm, handleRefresh, pendingDeleteId, t],\n )\n\n const handlePageSizeChange = React.useCallback((newSize: number) => {\n setPageSize(newSize)\n setPage(1)\n }, [])\n\n const handleBulkDelete = React.useCallback(async (selectedRows: DealRow[]) => {\n const confirmed = await confirm({\n title: t('customers.deals.list.bulkDelete.title', 'Delete {count} deals?', { count: selectedRows.length }),\n description: t('customers.deals.list.bulkDelete.description', 'This action cannot be undone.'),\n variant: 'destructive',\n })\n if (!confirmed) return false\n let deletedCount = 0\n const failedIds: string[] = []\n for (const row of selectedRows) {\n try {\n await deleteCrud('customers/deals', {\n body: { id: row.id },\n errorMessage: t('customers.deals.list.deleteError', 'Failed to delete deal.'),\n })\n deletedCount++\n } catch (err) {\n failedIds.push(row.id)\n console.warn('[customers.deals.list] bulk delete failed', row.id, err)\n }\n }\n if (deletedCount > 0) {\n setRows((prev) => {\n const succeeded = new Set(selectedRows.map((r) => r.id).filter((id) => !failedIds.includes(id)))\n return prev.filter((r) => !succeeded.has(r.id))\n })\n setTotal((prev) => Math.max(0, prev - deletedCount))\n if (failedIds.length === 0) {\n flash(t('customers.deals.list.bulkDelete.success', '{count} deals deleted', { count: deletedCount }), 'success')\n } else {\n flash(\n t('customers.deals.list.bulkDelete.partial', '{deleted} of {total} deals deleted; {failed} failed', {\n deleted: deletedCount,\n total: selectedRows.length,\n failed: failedIds.length,\n }),\n 'warning',\n )\n }\n } else if (failedIds.length > 0) {\n flash(t('customers.deals.list.bulkDelete.failed', 'Failed to delete {count} deals', { count: failedIds.length }), 'error')\n }\n return deletedCount > 0\n }, [confirm, t])\n\n const personOptions = peopleState.options\n const companyOptions = companiesState.options\n\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'people',\n label: t('customers.deals.list.filters.people'),\n type: 'tags',\n options: personOptions,\n loadOptions: loadPeopleOptions,\n placeholder: t('customers.deals.list.filters.peoplePlaceholder'),\n },\n {\n id: 'companies',\n label: t('customers.deals.list.filters.companies'),\n type: 'tags',\n options: companyOptions,\n loadOptions: loadCompanyOptions,\n placeholder: t('customers.deals.list.filters.companiesPlaceholder'),\n },\n ], [companyOptions, loadCompanyOptions, loadPeopleOptions, personOptions, t])\n\n const { data: customFieldDefs = [] } = useCustomFieldDefs([E.customers.customer_deal], {\n keyExtras: [scopeVersion, reloadToken],\n })\n\n const columns = React.useMemo<ColumnDef<DealRow>[]>(() => {\n const noValue = <span className=\"text-muted-foreground text-sm\">{t('customers.deals.list.noValue')}</span>\n const renderDictionaryCell = (kind: DictionaryKey, value: string | null | undefined) => (\n <DictionaryValue\n value={value}\n map={dictionaryMaps[kind]}\n fallback={value ? <span className=\"text-sm\">{value}</span> : noValue}\n className=\"text-sm\"\n iconWrapperClassName=\"inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-card\"\n iconClassName=\"h-4 w-4\"\n colorClassName=\"h-3 w-3 rounded-full\"\n />\n )\n const renderAssociationSummary = (\n items: { id: string; label: string }[],\n fallbackLabel: string,\n ) => {\n if (!items.length) return noValue\n const labels = normalizeCollectionLabels(\n items.map((entry) => (entry.label && entry.label.trim().length ? entry.label : fallbackLabel)),\n )\n if (!labels.length) return noValue\n return (\n <CollectionPreviewCell labels={labels} maxVisible={1} />\n )\n }\n\n const customColumns = customFieldDefs\n .filter((def) => supportsCustomFieldColumn(def))\n .map<ColumnDef<DealRow>>((def) => ({\n accessorKey: `cf_${def.key}`,\n header: def.label || def.key,\n meta: {\n columnChooserGroup: def.group?.title ?? 'Custom Fields',\n filterGroup: def.group?.title ?? 'Custom Fields',\n filterType: mapCustomFieldKindToFilterType(def.kind),\n filterOptions: normalizeCustomFieldFilterOptions(def.options),\n hidden: def.listVisible === false,\n maxWidth: '220px',\n },\n cell: ({ getValue }) => {\n const value = getValue()\n if (value == null) return noValue\n if (Array.isArray(value)) {\n const normalized = normalizeCollectionLabels(\n value\n .map((item) => {\n if (item == null) return ''\n if (typeof item === 'string') return item\n return String(item)\n }),\n )\n if (!normalized.length) return noValue\n return <CollectionPreviewCell labels={normalized} maxVisible={2} />\n }\n if (typeof value === 'boolean') {\n return (\n <span className=\"text-sm\">\n {value\n ? t('customers.deals.list.booleanYes', 'Yes')\n : t('customers.deals.list.booleanNo', 'No')}\n </span>\n )\n }\n const stringValue = typeof value === 'string' ? value.trim() : String(value)\n if (!stringValue) return noValue\n return <span className=\"text-sm\">{stringValue}</span>\n },\n }))\n\n return [\n {\n accessorKey: 'title',\n header: t('customers.deals.list.columns.title'),\n meta: {\n alwaysVisible: true,\n columnChooserGroup: 'Basic Info',\n filterKey: 'title',\n maxWidth: '280px',\n },\n cell: ({ row }) => <span className=\"font-medium text-sm\">{row.original.title}</span>,\n },\n {\n accessorKey: 'status',\n header: t('customers.deals.list.columns.status'),\n meta: { filterType: 'select' as const, columnChooserGroup: 'Basic Info', filterKey: 'status' },\n cell: ({ row }) => renderDictionaryCell('deal-statuses', row.original.status),\n },\n {\n accessorKey: 'pipelineStage',\n header: t('customers.deals.list.columns.pipelineStage'),\n meta: { columnChooserGroup: 'Pipeline', filterKey: 'pipeline_stage' },\n cell: ({ row }) => renderDictionaryCell('pipeline-stages', row.original.pipelineStage),\n },\n {\n accessorKey: 'pipelineId',\n header: t('customers.deals.list.columns.pipeline', 'Pipeline'),\n meta: { columnChooserGroup: 'Pipeline', filterKey: 'pipeline_id', maxWidth: '220px' },\n cell: ({ row }) => {\n const name = row.original.pipelineId ? pipelineNames[row.original.pipelineId] : null\n return name ? <span className=\"text-sm\">{name}</span> : noValue\n },\n },\n {\n accessorKey: 'valueAmount',\n header: t('customers.deals.list.columns.value'),\n meta: { filterType: 'number' as const, columnChooserGroup: 'Financial', filterKey: 'value_amount' },\n cell: ({ row }) => (\n <span className=\"text-sm font-medium\">\n {formatCurrency(row.original.valueAmount ?? null, row.original.valueCurrency ?? null, t('customers.deals.list.noValue'))}\n </span>\n ),\n },\n {\n accessorKey: 'probability',\n header: t('customers.deals.list.columns.probability'),\n meta: { filterType: 'number' as const, columnChooserGroup: 'Financial', filterKey: 'probability' },\n cell: ({ row }) => {\n const value = row.original.probability\n if (typeof value === 'number' && Number.isFinite(value)) {\n return <span className=\"text-sm\">{`${Math.min(Math.max(value, 0), 100)}%`}</span>\n }\n return noValue\n },\n },\n {\n accessorKey: 'expectedCloseAt',\n header: t('customers.deals.list.columns.expectedClose'),\n meta: { columnChooserGroup: 'Dates', filterKey: 'expected_close_at' },\n cell: ({ row }) => (\n <span className=\"text-sm\">\n {formatDateValue(row.original.expectedCloseAt ?? null, t('customers.deals.list.noValue'))}\n </span>\n ),\n },\n {\n accessorKey: 'companies',\n header: t('customers.deals.list.columns.companies'),\n meta: {\n columnChooserGroup: 'Associations',\n filterable: false,\n maxWidth: '220px',\n tooltipContent: (row: DealRow) =>\n normalizeCollectionLabels(\n row.companies.map((entry) => (entry.label && entry.label.trim().length ? entry.label : t('customers.deals.list.unnamedCompany'))),\n ).join(', '),\n },\n cell: ({ row }) => renderAssociationSummary(row.original.companies, t('customers.deals.list.unnamedCompany')),\n },\n {\n accessorKey: 'people',\n header: t('customers.deals.list.columns.people'),\n meta: {\n columnChooserGroup: 'Associations',\n filterable: false,\n maxWidth: '220px',\n tooltipContent: (row: DealRow) =>\n normalizeCollectionLabels(\n row.people.map((entry) => (entry.label && entry.label.trim().length ? entry.label : t('customers.deals.list.unnamedPerson'))),\n ).join(', '),\n },\n cell: ({ row }) => renderAssociationSummary(row.original.people, t('customers.deals.list.unnamedPerson')),\n },\n {\n accessorKey: 'updatedAt',\n header: t('customers.deals.list.columns.updatedAt'),\n meta: { columnChooserGroup: 'Dates', filterKey: 'updated_at' },\n cell: ({ row }) => (\n <span className=\"text-sm\">\n {formatDateValue(row.original.updatedAt ?? null, t('customers.deals.list.noValue'))}\n </span>\n ),\n },\n ...customColumns,\n ]\n }, [customFieldDefs, dictionaryMaps, pipelineNames, t])\n\n return (\n <Page>\n <PageBody>\n <DataTable<DealRow>\n stickyFirstColumn\n stickyActionsColumn\n title={t('customers.deals.list.title')}\n actions={(\n <Button asChild>\n <Link href=\"/backend/customers/deals/create\">\n {t('customers.deals.list.actions.new', 'New deal')}\n </Link>\n </Button>\n )}\n columns={columns}\n columnChooser={{ auto: true }}\n data={rows}\n onRowClick={(row) => {\n router.push(`/backend/customers/deals/${row.id}`)\n }}\n rowActions={(row) => {\n const isDeleting = pendingDeleteId === row.id\n return (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('customers.deals.list.actions.edit', 'Edit'),\n onSelect: () => { router.push(`/backend/customers/deals/${row.id}`) },\n },\n {\n id: 'open-new-tab',\n label: t('customers.deals.list.actions.openInNewTab', 'Open in new tab'),\n onSelect: () => {\n if (typeof window !== 'undefined') {\n window.open(`/backend/customers/deals/${row.id}`, '_blank', 'noopener')\n }\n },\n },\n {\n id: 'delete',\n label: isDeleting\n ? t('customers.deals.list.actions.deleting', 'Deleting\u2026')\n : t('customers.deals.list.actions.delete', 'Delete'),\n destructive: true,\n onSelect: () => handleDeleteDeal(row.id),\n },\n ]}\n />\n )\n }}\n sortable\n sorting={sorting}\n onSortingChange={setSorting}\n bulkActions={[\n {\n id: 'delete',\n label: t('customers.deals.list.actions.delete', 'Delete'),\n destructive: true,\n onExecute: handleBulkDelete,\n },\n ]}\n searchValue={search}\n onSearchChange={handleSearchChange}\n searchPlaceholder={t('customers.deals.list.searchPlaceholder')}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n pagination={{\n page,\n pageSize,\n total,\n totalPages,\n onPageChange: (nextPage) => setPage(nextPage),\n pageSizeOptions: [10, 25, 50, 100],\n onPageSizeChange: handlePageSizeChange,\n cacheStatus,\n }}\n isLoading={isLoading}\n refreshButton={{\n label: t('customers.deals.list.refresh'),\n onRefresh: handleRefresh,\n }}\n exporter={exportConfig}\n entityId={E.customers.customer_deal}\n perspective={{ tableId: 'customers.deals.list' }}\n advancedFilter={{\n auto: true,\n value: advancedFilterState,\n onChange: setAdvancedFilterState,\n onApply: () => { setPage(1) },\n onClear: () => { setAdvancedFilterState({ logic: 'and', conditions: [] }); setPage(1) },\n }}\n virtualized\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n\nfunction mapDeal(item: Record<string, unknown>): DealRow | null {\n const id = typeof item.id === 'string' ? item.id : null\n if (!id) return null\n const title = typeof item.title === 'string' ? item.title : ''\n const status = typeof item.status === 'string' ? item.status : null\n const pipelineStage = typeof item.pipeline_stage === 'string' ? item.pipeline_stage : null\n const pipelineStageId = typeof item.pipeline_stage_id === 'string' ? item.pipeline_stage_id : null\n const pipelineId = typeof item.pipeline_id === 'string' ? item.pipeline_id : null\n const valueAmountRaw = item.value_amount\n const valueAmount =\n typeof valueAmountRaw === 'number'\n ? valueAmountRaw\n : typeof valueAmountRaw === 'string' && valueAmountRaw.trim()\n ? Number(valueAmountRaw)\n : null\n const valueCurrency =\n typeof item.value_currency === 'string' && item.value_currency.trim().length\n ? item.value_currency.trim().toUpperCase()\n : null\n const probabilityRaw = item.probability\n const probability =\n typeof probabilityRaw === 'number'\n ? probabilityRaw\n : typeof probabilityRaw === 'string' && probabilityRaw.trim().length\n ? Number(probabilityRaw)\n : null\n const expectedCloseAt = typeof item.expected_close_at === 'string' ? item.expected_close_at : null\n const updatedAt = typeof item.updated_at === 'string' ? item.updated_at : null\n const peopleRaw = Array.isArray(item.people) ? item.people : []\n const companiesRaw = Array.isArray(item.companies) ? item.companies : []\n const people = peopleRaw\n .map((entry) => {\n if (!entry || typeof entry !== 'object') return null\n const data = entry as Record<string, unknown>\n const pid = typeof data.id === 'string' ? data.id : null\n if (!pid) return null\n const label = typeof data.label === 'string' ? data.label : ''\n return { id: pid, label }\n })\n .filter((entry): entry is { id: string; label: string } => !!entry)\n const companies = companiesRaw\n .map((entry) => {\n if (!entry || typeof entry !== 'object') return null\n const data = entry as Record<string, unknown>\n const cid = typeof data.id === 'string' ? data.id : null\n if (!cid) return null\n const label = typeof data.label === 'string' ? data.label : ''\n return { id: cid, label }\n })\n .filter((entry): entry is { id: string; label: string } => !!entry)\n const customFields: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(item)) {\n if (key.startsWith('cf_')) customFields[key] = value\n }\n return withDataTableNamespaces({\n id,\n title,\n status,\n pipelineStage,\n pipelineStageId,\n pipelineId,\n valueAmount,\n valueCurrency,\n probability,\n expectedCloseAt,\n updatedAt,\n people,\n companies,\n ...customFields,\n }, item)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["formatter"]
7
7
  }
@@ -17,6 +17,7 @@ import { useConfirmDialog } from "@open-mercato/ui/backend/confirm-dialog";
17
17
  import { serializeAdvancedFilter } from "@open-mercato/shared/lib/query/advanced-filter";
18
18
  import {
19
19
  DictionaryValue,
20
+ createEmptyCustomerDictionaryMaps,
20
21
  renderDictionaryColor,
21
22
  renderDictionaryIcon
22
23
  } from "../../../lib/dictionaries.js";
@@ -30,20 +31,8 @@ import {
30
31
  } from "@open-mercato/ui/backend/utils/customFieldColumns";
31
32
  import { useQueryClient } from "@tanstack/react-query";
32
33
  import { ensureCustomerDictionary } from "../../../components/detail/hooks/useCustomerDictionary.js";
34
+ import { CollectionPreviewCell, normalizeCollectionLabels } from "../../../components/list/CollectionPreviewCell.js";
33
35
  const NO_MATCH_TAG_SENTINEL = "__no_match__";
34
- function createEmptyDictionaryMaps() {
35
- return {
36
- statuses: {},
37
- sources: {},
38
- "lifecycle-stages": {},
39
- "address-types": {},
40
- "activity-types": {},
41
- "deal-statuses": {},
42
- "pipeline-stages": {},
43
- "job-titles": {},
44
- industries: {}
45
- };
46
- }
47
36
  function formatDate(value, fallback) {
48
37
  if (!value) return fallback;
49
38
  const date = new Date(value);
@@ -122,7 +111,7 @@ function CustomersPeoplePage() {
122
111
  const [isLoading, setIsLoading] = React.useState(true);
123
112
  const [reloadToken, setReloadToken] = React.useState(0);
124
113
  const [cacheStatus, setCacheStatus] = React.useState(null);
125
- const [dictionaryMaps, setDictionaryMaps] = React.useState(createEmptyDictionaryMaps());
114
+ const [dictionaryMaps, setDictionaryMaps] = React.useState(createEmptyCustomerDictionaryMaps());
126
115
  const [tagIdToLabel, setTagIdToLabel] = React.useState({});
127
116
  const scopeVersion = useOrganizationScopeVersion();
128
117
  const queryClient = useQueryClient();
@@ -207,7 +196,7 @@ function CustomersPeoplePage() {
207
196
  let cancelled = false;
208
197
  async function loadAll() {
209
198
  if (cancelled) return;
210
- setDictionaryMaps(createEmptyDictionaryMaps());
199
+ setDictionaryMaps(createEmptyCustomerDictionaryMaps());
211
200
  await Promise.all([
212
201
  fetchDictionaryEntries("statuses"),
213
202
  fetchDictionaryEntries("sources"),
@@ -428,6 +417,7 @@ function CustomersPeoplePage() {
428
417
  });
429
418
  if (!confirmed) return false;
430
419
  let deletedCount = 0;
420
+ const failedIds = [];
431
421
  for (const row of selectedRows) {
432
422
  try {
433
423
  await apiCallOrThrow(`/api/customers/people?id=${encodeURIComponent(row.id)}`, {
@@ -435,17 +425,32 @@ function CustomersPeoplePage() {
435
425
  headers: { "content-type": "application/json" }
436
426
  });
437
427
  deletedCount++;
438
- } catch {
428
+ } catch (err) {
429
+ failedIds.push(row.id);
430
+ console.warn("[customers.people.list] bulk delete failed", row.id, err);
439
431
  }
440
432
  }
441
433
  if (deletedCount > 0) {
442
434
  setRows((prev) => {
443
- const deletedIds = new Set(selectedRows.map((r) => r.id));
444
- return prev.filter((r) => !deletedIds.has(r.id));
435
+ const succeeded = new Set(selectedRows.map((r) => r.id).filter((id) => !failedIds.includes(id)));
436
+ return prev.filter((r) => !succeeded.has(r.id));
445
437
  });
446
438
  setTotal((prev) => Math.max(0, prev - deletedCount));
447
- flash(t("customers.people.list.bulkDelete.success", "{count} people deleted", { count: deletedCount }), "success");
439
+ if (failedIds.length === 0) {
440
+ flash(t("customers.people.list.bulkDelete.success", "{count} people deleted", { count: deletedCount }), "success");
441
+ } else {
442
+ flash(
443
+ t("customers.people.list.bulkDelete.partial", "{deleted} of {total} people deleted; {failed} failed", {
444
+ deleted: deletedCount,
445
+ total: selectedRows.length,
446
+ failed: failedIds.length
447
+ }),
448
+ "warning"
449
+ );
450
+ }
448
451
  setReloadToken((prev) => prev + 1);
452
+ } else if (failedIds.length > 0) {
453
+ flash(t("customers.people.list.bulkDelete.failed", "Failed to delete {count} people", { count: failedIds.length }), "error");
449
454
  }
450
455
  return deletedCount > 0;
451
456
  }, [confirm, t]);
@@ -489,13 +494,15 @@ function CustomersPeoplePage() {
489
494
  if (value == null) return noValue;
490
495
  if (Array.isArray(value)) {
491
496
  if (!value.length) return noValue;
492
- const normalized = value.map((item) => {
493
- if (item == null) return "";
494
- if (typeof item === "string") return item.trim();
495
- return String(item).trim();
496
- }).filter((item) => item.length > 0);
497
+ const normalized = normalizeCollectionLabels(
498
+ value.map((item) => {
499
+ if (item == null) return "";
500
+ if (typeof item === "string") return item;
501
+ return String(item);
502
+ })
503
+ );
497
504
  if (!normalized.length) return noValue;
498
- return /* @__PURE__ */ jsx("span", { className: "text-sm", children: normalized.join(", ") });
505
+ return /* @__PURE__ */ jsx(CollectionPreviewCell, { labels: normalized, maxVisible: 2 });
499
506
  }
500
507
  if (typeof value === "boolean") {
501
508
  return /* @__PURE__ */ jsx("span", { className: "text-sm", children: value ? t("customers.people.list.booleanYes", "Yes") : t("customers.people.list.booleanNo", "No") });
@@ -508,13 +515,13 @@ function CustomersPeoplePage() {
508
515
  {
509
516
  accessorKey: "name",
510
517
  header: t("customers.people.list.columns.name"),
511
- meta: { alwaysVisible: true, columnChooserGroup: "Basic Info", filterKey: "display_name" },
518
+ meta: { alwaysVisible: true, columnChooserGroup: "Basic Info", filterKey: "display_name", maxWidth: "240px" },
512
519
  cell: ({ row }) => /* @__PURE__ */ jsx(Link, { href: `/backend/customers/people-v2/${row.original.id}`, className: "font-medium hover:underline", children: row.original.name })
513
520
  },
514
521
  {
515
522
  accessorKey: "email",
516
523
  header: t("customers.people.list.columns.email"),
517
- meta: { columnChooserGroup: "Contact", filterKey: "primary_email" },
524
+ meta: { columnChooserGroup: "Contact", filterKey: "primary_email", maxWidth: "220px" },
518
525
  cell: ({ row }) => row.original.email || /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm", children: t("customers.people.list.noValue") })
519
526
  },
520
527
  {
@@ -631,7 +638,8 @@ function CustomersPeoplePage() {
631
638
  filterGroup: def.group?.title ?? "Custom Fields",
632
639
  filterType: mapCustomFieldKindToFilterType(def.kind),
633
640
  filterOptions: normalizeCustomFieldFilterOptions(def.options),
634
- hidden: def.listVisible === false
641
+ hidden: def.listVisible === false,
642
+ maxWidth: "220px"
635
643
  },
636
644
  cell: ({ getValue }) => renderCustomFieldCell(getValue())
637
645
  }));