@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
@@ -0,0 +1,481 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { Users, Phone, Check, Mail, Calendar, AlertTriangle, X } from 'lucide-react'
5
+ import { cn } from '@open-mercato/shared/lib/utils'
6
+ import { useT } from '@open-mercato/shared/lib/i18n/context'
7
+ import { apiCallOrThrow, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'
8
+ import { flash } from '@open-mercato/ui/backend/FlashMessages'
9
+ import { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'
10
+ import { Alert, AlertDescription, AlertTitle } from '@open-mercato/ui/primitives/alert'
11
+ import { Button } from '@open-mercato/ui/primitives/button'
12
+ import { IconButton } from '@open-mercato/ui/primitives/icon-button'
13
+ import { Dialog, DialogContent, DialogTitle } from '@open-mercato/ui/primitives/dialog'
14
+ import { VisuallyHidden } from '@radix-ui/react-visually-hidden'
15
+ import { SwitchableMarkdownInput } from '@open-mercato/ui/backend/inputs'
16
+ import { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'
17
+ import {
18
+ useScheduleFormState,
19
+ FIELD_VISIBILITY,
20
+ getFieldLabel,
21
+ DateTimeFields,
22
+ ParticipantsField,
23
+ LocationField,
24
+ FooterFields,
25
+ LinkedEntitiesField,
26
+ } from './schedule'
27
+ import type { ActivityType, ScheduleActivityEditData } from './schedule'
28
+
29
+ const TYPE_TABS: Array<{ type: ActivityType; icon: React.ComponentType<{ className?: string }>; labelKey: string; fallback: string }> = [
30
+ { type: 'meeting', icon: Users, labelKey: 'customers.schedule.types.meeting', fallback: 'Meeting' },
31
+ { type: 'call', icon: Phone, labelKey: 'customers.schedule.types.call', fallback: 'Call' },
32
+ { type: 'task', icon: Check, labelKey: 'customers.schedule.types.task', fallback: 'Task' },
33
+ { type: 'email', icon: Mail, labelKey: 'customers.schedule.types.email', fallback: 'Email' },
34
+ ]
35
+
36
+ interface ScheduleActivityDialogProps {
37
+ open: boolean
38
+ onClose: () => void
39
+ entityId: string
40
+ dealId?: string | null
41
+ entityName?: string
42
+ companyName?: string | null
43
+ entityType: 'company' | 'person' | 'deal'
44
+ onActivityCreated?: () => void
45
+ /** When provided, dialog opens in edit mode with pre-filled data */
46
+ editData?: ScheduleActivityEditData | null
47
+ }
48
+
49
+ export function ScheduleActivityDialog({
50
+ open,
51
+ onClose,
52
+ entityId,
53
+ dealId = null,
54
+ entityName,
55
+ companyName,
56
+ entityType,
57
+ onActivityCreated,
58
+ editData,
59
+ }: ScheduleActivityDialogProps) {
60
+ const t = useT()
61
+ const state = useScheduleFormState({ open, editData: editData ?? null })
62
+ const visibleFields = FIELD_VISIBILITY[state.activityType]
63
+ const { confirm, ConfirmDialogElement } = useConfirmDialog()
64
+
65
+ const formSnapshot = React.useMemo(() => JSON.stringify({
66
+ activityType: state.activityType,
67
+ title: state.title,
68
+ date: state.date,
69
+ startTime: state.startTime,
70
+ duration: state.duration,
71
+ allDay: state.allDay,
72
+ description: state.description,
73
+ location: state.location,
74
+ reminderMinutes: state.reminderMinutes,
75
+ visibility: state.visibility,
76
+ participants: state.participants,
77
+ linkedEntities: state.linkedEntities,
78
+ recurrenceEnabled: state.recurrenceEnabled,
79
+ recurrenceDays: state.recurrenceDays,
80
+ recurrenceEndType: state.recurrenceEndType,
81
+ recurrenceCount: state.recurrenceCount,
82
+ recurrenceEndDate: state.recurrenceEndDate,
83
+ guestPermissions: state.guestPermissions,
84
+ }), [
85
+ state.activityType, state.title, state.date, state.startTime, state.duration, state.allDay,
86
+ state.description, state.location, state.reminderMinutes, state.visibility, state.participants,
87
+ state.linkedEntities, state.recurrenceEnabled, state.recurrenceDays, state.recurrenceEndType,
88
+ state.recurrenceCount, state.recurrenceEndDate, state.guestPermissions,
89
+ ])
90
+ const initialSnapshotRef = React.useRef<string | null>(null)
91
+ const snapshotOpenKeyRef = React.useRef<string | null>(null)
92
+ const snapshotSettleCountRef = React.useRef(0)
93
+ const openKey = open ? `${editData?.id ?? 'new'}` : null
94
+ React.useEffect(() => {
95
+ if (!open) {
96
+ initialSnapshotRef.current = null
97
+ snapshotOpenKeyRef.current = null
98
+ snapshotSettleCountRef.current = 0
99
+ return
100
+ }
101
+ if (snapshotOpenKeyRef.current !== openKey) {
102
+ snapshotOpenKeyRef.current = openKey
103
+ snapshotSettleCountRef.current = 0
104
+ initialSnapshotRef.current = null
105
+ }
106
+ if (snapshotSettleCountRef.current < 2) {
107
+ initialSnapshotRef.current = formSnapshot
108
+ snapshotSettleCountRef.current += 1
109
+ }
110
+ }, [open, openKey, formSnapshot])
111
+
112
+ const isDirty = React.useCallback(() => {
113
+ if (initialSnapshotRef.current == null) return false
114
+ return initialSnapshotRef.current !== formSnapshot
115
+ }, [formSnapshot])
116
+
117
+ const guardedClose = React.useCallback(async () => {
118
+ if (!isDirty()) {
119
+ onClose()
120
+ return
121
+ }
122
+ const ok = await confirm({
123
+ title: t('customers.schedule.discardConfirm.title', 'Discard unsaved changes?'),
124
+ description: t(
125
+ 'customers.schedule.discardConfirm.description',
126
+ 'You have unsaved edits in this activity. Save them first or continue to discard them.',
127
+ ),
128
+ confirmText: t('customers.schedule.discardConfirm.confirm', 'Discard'),
129
+ cancelText: t('customers.schedule.discardConfirm.cancel', 'Keep editing'),
130
+ variant: 'destructive',
131
+ })
132
+ if (ok) onClose()
133
+ }, [confirm, isDirty, onClose, t])
134
+
135
+ const mutationContextId = React.useMemo(
136
+ () => `customer-activity:${entityType}:${entityId}`,
137
+ [entityId, entityType],
138
+ )
139
+ const { runMutation, retryLastMutation } = useGuardedMutation<{
140
+ formId: string
141
+ resourceKind: string
142
+ resourceId: string
143
+ entityType: 'company' | 'person' | 'deal'
144
+ retryLastMutation: () => Promise<boolean>
145
+ }>({
146
+ contextId: mutationContextId,
147
+ blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),
148
+ })
149
+ const mutationContext = React.useMemo(
150
+ () => ({
151
+ formId: mutationContextId,
152
+ resourceKind:
153
+ entityType === 'company'
154
+ ? 'customers.company'
155
+ : entityType === 'person'
156
+ ? 'customers.person'
157
+ : 'customers.deal',
158
+ resourceId: entityId,
159
+ entityType,
160
+ retryLastMutation,
161
+ }),
162
+ [entityId, entityType, mutationContextId, retryLastMutation],
163
+ )
164
+ const runGuardedMutation = React.useCallback(
165
+ async <T,>(operation: () => Promise<T>, mutationPayload: Record<string, unknown>) =>
166
+ runMutation({
167
+ operation,
168
+ mutationPayload,
169
+ context: mutationContext,
170
+ }),
171
+ [mutationContext, runMutation],
172
+ )
173
+
174
+ // Conflict detection -- debounced check when date/time/duration changes
175
+ React.useEffect(() => {
176
+ if (!open || state.allDay || !state.date || !state.startTime) {
177
+ state.setConflict(null)
178
+ return
179
+ }
180
+ const timer = setTimeout(async () => {
181
+ try {
182
+ const localStart = new Date(`${state.date}T${state.startTime}:00`)
183
+ const params = new URLSearchParams({
184
+ date: state.date,
185
+ startTime: state.startTime,
186
+ duration: String(state.duration),
187
+ })
188
+ if (editData?.id) {
189
+ params.set('excludeId', editData.id)
190
+ }
191
+ if (!Number.isNaN(localStart.getTime())) {
192
+ params.set('timezoneOffsetMinutes', String(-localStart.getTimezoneOffset()))
193
+ }
194
+ const data = await readApiResultOrThrow<{
195
+ hasConflicts: boolean
196
+ conflicts: Array<{ id: string; title: string | null; startTime: string; endTime: string; type: string }>
197
+ }>(`/api/customers/interactions/conflicts?${params.toString()}`)
198
+ if (data?.hasConflicts && Array.isArray(data.conflicts) && data.conflicts.length > 0) {
199
+ const descriptions = data.conflicts
200
+ .map((c) => `${c.startTime}–${c.endTime}: ${c.title ?? c.type}`)
201
+ .join(', ')
202
+ state.setConflict(
203
+ t('customers.schedule.conflict.description', 'Overlaps with: {{items}}', { items: descriptions }),
204
+ )
205
+ } else {
206
+ state.setConflict(null)
207
+ }
208
+ } catch {
209
+ state.setConflict(null)
210
+ }
211
+ }, 500)
212
+ return () => clearTimeout(timer)
213
+ }, [editData?.id, open, state.date, state.startTime, state.duration, state.allDay, t]) // eslint-disable-line react-hooks/exhaustive-deps
214
+
215
+ const handleSave = React.useCallback(async () => {
216
+ if (!state.title.trim()) return
217
+ state.setSaving(true)
218
+ try {
219
+ const scheduledAt = state.allDay
220
+ ? new Date(`${state.date}T00:00:00`).toISOString()
221
+ : new Date(`${state.date}T${state.startTime}:00`).toISOString()
222
+
223
+ const recurrenceRule = state.recurrenceEnabled
224
+ ? buildRecurrenceRule(state.recurrenceDays, state.recurrenceEndType, state.recurrenceCount, state.recurrenceEndDate)
225
+ : null
226
+
227
+ const isEditing = Boolean(editData?.id)
228
+ const payload = {
229
+ ...(isEditing ? { id: editData!.id } : {}),
230
+ entityId,
231
+ dealId,
232
+ interactionType: state.activityType,
233
+ title: state.title.trim(),
234
+ body: state.description.trim() || null,
235
+ status: 'planned',
236
+ scheduledAt,
237
+ durationMinutes: visibleFields.has('duration') && !state.allDay ? state.duration : null,
238
+ location: visibleFields.has('location') ? (state.location.trim() || null) : null,
239
+ allDay: visibleFields.has('allDay') ? state.allDay : null,
240
+ recurrenceRule: visibleFields.has('recurrence') ? recurrenceRule : null,
241
+ recurrenceEnd: visibleFields.has('recurrence') && state.recurrenceEndType === 'date' && state.recurrenceEndDate
242
+ ? new Date(state.recurrenceEndDate).toISOString()
243
+ : null,
244
+ participants: visibleFields.has('participants') && state.participants.length > 0
245
+ ? state.participants.map((p) => ({ userId: p.userId, name: p.name, email: p.email, status: p.status ?? 'pending' }))
246
+ : null,
247
+ guestPermissions: visibleFields.has('participants') && state.participants.length > 0 ? state.guestPermissions : null,
248
+ linkedEntities: state.linkedEntities.length > 0
249
+ ? state.linkedEntities.map((e) => ({ id: e.id, type: e.type, label: e.label }))
250
+ : null,
251
+ reminderMinutes: visibleFields.has('reminder') ? state.reminderMinutes : null,
252
+ visibility: visibleFields.has('visibility') ? state.visibility : null,
253
+ }
254
+ await runGuardedMutation(
255
+ () =>
256
+ apiCallOrThrow('/api/customers/interactions', {
257
+ method: isEditing ? 'PUT' : 'POST',
258
+ headers: { 'content-type': 'application/json' },
259
+ body: JSON.stringify(payload),
260
+ }),
261
+ {
262
+ operation: isEditing ? 'updateActivity' : 'createActivity',
263
+ interactionId: editData?.id ?? null,
264
+ interactionType: state.activityType,
265
+ },
266
+ )
267
+ flash(t('customers.schedule.saved', 'Activity scheduled'), 'success')
268
+ onClose()
269
+ // Delay data reload so the dialog can unmount cleanly and Radix restores body scroll
270
+ requestAnimationFrame(() => { onActivityCreated?.() })
271
+ } catch {
272
+ flash(t('customers.schedule.error', 'Failed to schedule activity'), 'error')
273
+ } finally {
274
+ state.setSaving(false)
275
+ }
276
+ }, [state.activityType, state.allDay, state.date, state.description, dealId, state.duration, editData, entityId, state.guestPermissions, state.linkedEntities, state.location, onActivityCreated, onClose, state.participants, state.recurrenceCount, state.recurrenceDays, state.recurrenceEnabled, state.recurrenceEndDate, state.recurrenceEndType, state.reminderMinutes, runGuardedMutation, state.startTime, t, state.title, state.visibility, visibleFields]) // eslint-disable-line react-hooks/exhaustive-deps
277
+
278
+ const handleKeyDown = React.useCallback((e: React.KeyboardEvent) => {
279
+ if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {
280
+ e.preventDefault()
281
+ handleSave()
282
+ }
283
+ }, [handleSave])
284
+
285
+ return (
286
+ <Dialog open={open} onOpenChange={(o) => { if (!o) void guardedClose() }}>
287
+ {ConfirmDialogElement}
288
+ <DialogContent className="flex max-h-[90vh] flex-col overflow-hidden border-border p-0 shadow-xl sm:max-w-[680px] sm:rounded-xl [&>[data-dialog-close]]:hidden" onKeyDown={handleKeyDown} aria-describedby={undefined}>
289
+ <VisuallyHidden>
290
+ <DialogTitle>{editData ? t('customers.schedule.editTitle', 'Edit activity') : t('customers.schedule.title', 'Schedule activity')}</DialogTitle>
291
+ </VisuallyHidden>
292
+
293
+ {/* Header */}
294
+ <div className="flex shrink-0 items-start justify-between gap-3 border-b border-border bg-background px-6 py-5">
295
+ <div className="flex flex-col gap-1.5">
296
+ <h2 className="text-lg font-bold leading-tight text-foreground">
297
+ {editData ? t('customers.schedule.editTitle', 'Edit activity') : t('customers.schedule.title', 'Schedule activity')}
298
+ </h2>
299
+ {entityName && (
300
+ <div className="flex items-center gap-1.5">
301
+ <span className="inline-block size-3.5 rounded-full bg-status-success-icon shrink-0" />
302
+ <span className="text-xs text-muted-foreground">
303
+ {t('customers.schedule.context', 'On timeline: {{name}}', { name: entityName })}
304
+ {companyName && ` · ${companyName}`}
305
+ </span>
306
+ </div>
307
+ )}
308
+ </div>
309
+ <IconButton type="button" variant="ghost" size="sm" onClick={() => { void guardedClose() }} className="flex size-9 shrink-0 items-center justify-center rounded-md border border-border bg-background" aria-label={t('customers.schedule.cancel', 'Cancel')}>
310
+ <X className="size-4 text-muted-foreground" />
311
+ </IconButton>
312
+ </div>
313
+
314
+ <div className="flex-1 overflow-y-auto">
315
+ <div className="flex flex-col gap-4 bg-background p-6">
316
+
317
+ {/* Conflict warning */}
318
+ {state.conflict && (
319
+ <Alert variant="warning" className="rounded-lg">
320
+ <AlertTriangle className="size-5" />
321
+ <AlertTitle>
322
+ {t('customers.schedule.conflict.title', 'Calendar conflict')}
323
+ </AlertTitle>
324
+ <AlertDescription>{state.conflict}</AlertDescription>
325
+ </Alert>
326
+ )}
327
+
328
+ {/* Type tabs */}
329
+ <div className="flex gap-0.5 rounded-md border border-border bg-muted p-1">
330
+ {TYPE_TABS.map(({ type, icon: Icon, labelKey, fallback }) => {
331
+ const isActive = state.activityType === type
332
+ return (
333
+ <Button
334
+ key={type}
335
+ type="button"
336
+ variant="ghost"
337
+ size="sm"
338
+ onClick={() => state.setActivityType(type)}
339
+ className={cn(
340
+ 'h-auto flex items-center gap-2 rounded-md px-3.5 py-2 text-sm transition-colors',
341
+ isActive
342
+ ? 'bg-background font-semibold text-foreground shadow-sm'
343
+ : 'bg-transparent font-normal text-muted-foreground',
344
+ )}
345
+ >
346
+ <Icon className="size-3.5" />
347
+ {t(labelKey, fallback)}
348
+ </Button>
349
+ )
350
+ })}
351
+ </div>
352
+
353
+ {/* Title */}
354
+ <div className="flex flex-col gap-1.5">
355
+ <label className="text-overline font-semibold text-muted-foreground tracking-wider">
356
+ {getFieldLabel(state.activityType, 'title', t, 'customers.schedule.titleLabel', 'Title')}
357
+ </label>
358
+ <input
359
+ type="text"
360
+ value={state.title}
361
+ onChange={(e) => state.setTitle(e.target.value)}
362
+ placeholder={t('customers.schedule.titlePlaceholder', 'Activity title...')}
363
+ className="w-full rounded-md border border-border bg-background px-3 py-2.5 text-sm text-foreground outline-none focus:border-foreground"
364
+ autoFocus
365
+ />
366
+ </div>
367
+
368
+ {/* Date/Time/Duration */}
369
+ <DateTimeFields
370
+ visible={visibleFields}
371
+ activityType={state.activityType}
372
+ date={state.date}
373
+ setDate={state.setDate}
374
+ startTime={state.startTime}
375
+ setStartTime={state.setStartTime}
376
+ duration={state.duration}
377
+ setDuration={state.setDuration}
378
+ allDay={state.allDay}
379
+ setAllDay={state.setAllDay}
380
+ recurrenceEnabled={state.recurrenceEnabled}
381
+ setRecurrenceEnabled={state.setRecurrenceEnabled}
382
+ recurrenceDays={state.recurrenceDays}
383
+ toggleRecurrenceDay={state.toggleRecurrenceDay}
384
+ recurrenceEndType={state.recurrenceEndType}
385
+ setRecurrenceEndType={state.setRecurrenceEndType}
386
+ recurrenceCount={state.recurrenceCount}
387
+ setRecurrenceCount={state.setRecurrenceCount}
388
+ recurrenceEndDate={state.recurrenceEndDate}
389
+ setRecurrenceEndDate={state.setRecurrenceEndDate}
390
+ />
391
+
392
+ {/* Participants */}
393
+ <ParticipantsField
394
+ visible={visibleFields}
395
+ activityType={state.activityType}
396
+ participants={state.participants}
397
+ setParticipants={state.setParticipants}
398
+ removeParticipant={state.removeParticipant}
399
+ guestPermissions={state.guestPermissions}
400
+ setGuestPermissions={state.setGuestPermissions}
401
+ />
402
+
403
+ {/* Location */}
404
+ <LocationField
405
+ visible={visibleFields}
406
+ activityType={state.activityType}
407
+ location={state.location}
408
+ setLocation={state.setLocation}
409
+ />
410
+
411
+ {/* Linked Entities */}
412
+ <LinkedEntitiesField
413
+ visible={visibleFields}
414
+ activityType={state.activityType}
415
+ linkedEntities={state.linkedEntities}
416
+ setLinkedEntities={state.setLinkedEntities}
417
+ />
418
+
419
+ {/* Description */}
420
+ <div>
421
+ <label className="text-overline font-semibold uppercase text-muted-foreground tracking-wider">
422
+ {getFieldLabel(state.activityType, 'description', t, 'customers.schedule.description', 'Description')}
423
+ </label>
424
+ <div className="mt-[8px]">
425
+ <SwitchableMarkdownInput
426
+ value={state.description}
427
+ onChange={state.setDescription}
428
+ isMarkdownEnabled={state.markdownEnabled}
429
+ height={120}
430
+ placeholder={t('customers.schedule.descriptionPlaceholder', 'Add details...')}
431
+ />
432
+ </div>
433
+ </div>
434
+
435
+ {/* Reminder + Visibility */}
436
+ <FooterFields
437
+ visible={visibleFields}
438
+ activityType={state.activityType}
439
+ reminderMinutes={state.reminderMinutes}
440
+ setReminderMinutes={state.setReminderMinutes}
441
+ visibility={state.visibility}
442
+ setVisibility={state.setVisibility}
443
+ />
444
+
445
+ </div>
446
+ </div>
447
+
448
+ {/* Footer */}
449
+ <div className="flex shrink-0 items-center justify-end gap-2.5 border-t border-border bg-muted/50 px-6 py-4">
450
+ <Button type="button" variant="outline" onClick={() => { void guardedClose() }} className="rounded-md border border-input bg-background px-5 py-3 text-sm font-semibold text-foreground">
451
+ {t('customers.schedule.cancel', 'Cancel')}
452
+ </Button>
453
+ <Button type="button" onClick={handleSave} disabled={state.saving || !state.title.trim()} className="flex items-center gap-2 rounded-md bg-primary px-5 py-3 text-sm font-semibold text-primary-foreground disabled:opacity-50">
454
+ <Calendar className="size-3.5" />
455
+ {state.saving
456
+ ? t('customers.schedule.saving', 'Saving...')
457
+ : editData
458
+ ? t('customers.schedule.update', 'Update activity')
459
+ : t('customers.schedule.save', 'Save activity')}
460
+ </Button>
461
+ </div>
462
+ </DialogContent>
463
+ </Dialog>
464
+ )
465
+ }
466
+
467
+ export type { ScheduleActivityEditData }
468
+
469
+ function buildRecurrenceRule(
470
+ days: boolean[],
471
+ endType: 'never' | 'count' | 'date',
472
+ count: number,
473
+ endDate: string,
474
+ ): string {
475
+ const dayNames = ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU']
476
+ const selectedDays = days.map((active, i) => (active ? dayNames[i] : null)).filter(Boolean)
477
+ let rule = `FREQ=WEEKLY;BYDAY=${selectedDays.join(',')}`
478
+ if (endType === 'count') rule += `;COUNT=${count}`
479
+ if (endType === 'date' && endDate) rule += `;UNTIL=${endDate.replace(/-/g, '')}T235959Z`
480
+ return rule
481
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Shared catalog of "coming soon" AI action chips used by both
3
+ * ActivityAiActions (outline button chips on activity cards) and
4
+ * AiActionChips (inline pipe-separated chips on timeline rows).
5
+ *
6
+ * Each presentation surface can subset / reorder the catalog.
7
+ * Action handlers are intentionally absent — the UI is disabled
8
+ * until the AI assistant wiring lands.
9
+ */
10
+
11
+ import type { ComponentType, SVGProps } from 'react'
12
+ import { BarChart3, FileText, ListTodo, Mail, NotebookPen, Play, Reply, Sparkles, Users } from 'lucide-react'
13
+
14
+ export type AiActionKey =
15
+ | 'ai'
16
+ | 'summarize'
17
+ | 'replay'
18
+ | 'transcription'
19
+ | 'actionItems'
20
+ | 'showEmail'
21
+ | 'reply'
22
+ | 'sentiment'
23
+ | 'notes'
24
+ | 'attendees'
25
+ | 'leadScore'
26
+ | 'expand'
27
+ | 'bulletize'
28
+ | 'translate'
29
+
30
+ export type AiActionDefinition = {
31
+ key: AiActionKey
32
+ i18nKey: string
33
+ fallback: string
34
+ icon: ComponentType<SVGProps<SVGSVGElement>>
35
+ }
36
+
37
+ export const AI_ACTION_DEFINITIONS: Record<AiActionKey, AiActionDefinition> = {
38
+ ai: { key: 'ai', i18nKey: 'customers.ai.actions.ai', fallback: 'AI', icon: Sparkles },
39
+ summarize: { key: 'summarize', i18nKey: 'customers.ai.actions.summarize', fallback: 'Summarize', icon: FileText },
40
+ replay: { key: 'replay', i18nKey: 'customers.ai.actions.replay', fallback: 'Replay', icon: Play },
41
+ transcription: { key: 'transcription', i18nKey: 'customers.ai.actions.transcription', fallback: 'Transcription', icon: NotebookPen },
42
+ actionItems: { key: 'actionItems', i18nKey: 'customers.ai.actions.actionItems', fallback: 'Action items', icon: ListTodo },
43
+ showEmail: { key: 'showEmail', i18nKey: 'customers.ai.actions.showEmail', fallback: 'Show email', icon: Mail },
44
+ reply: { key: 'reply', i18nKey: 'customers.ai.actions.reply', fallback: 'Reply', icon: Reply },
45
+ sentiment: { key: 'sentiment', i18nKey: 'customers.ai.actions.sentiment', fallback: 'Sentiment', icon: BarChart3 },
46
+ notes: { key: 'notes', i18nKey: 'customers.ai.actions.notes', fallback: 'Notes', icon: NotebookPen },
47
+ attendees: { key: 'attendees', i18nKey: 'customers.ai.actions.attendees', fallback: 'Attendees', icon: Users },
48
+ leadScore: { key: 'leadScore', i18nKey: 'customers.ai.actions.leadScore', fallback: 'Lead score', icon: BarChart3 },
49
+ expand: { key: 'expand', i18nKey: 'customers.ai.actions.expand', fallback: 'Expand', icon: Sparkles },
50
+ bulletize: { key: 'bulletize', i18nKey: 'customers.ai.actions.bulletize', fallback: 'Bulletize', icon: ListTodo },
51
+ translate: { key: 'translate', i18nKey: 'customers.ai.actions.translate', fallback: 'Translate', icon: Sparkles },
52
+ }
53
+
54
+ /** Per-activity-type action keys in card (outline chip) layout. */
55
+ export const AI_CARD_ACTIONS_BY_TYPE: Record<string, AiActionKey[]> = {
56
+ call: ['ai', 'summarize', 'replay', 'transcription', 'actionItems'],
57
+ email: ['ai', 'summarize', 'showEmail', 'reply', 'sentiment'],
58
+ meeting: ['ai', 'summarize', 'notes', 'attendees'],
59
+ note: ['ai', 'summarize'],
60
+ }
61
+
62
+ /** Per-activity-type action keys in timeline (inline) layout. */
63
+ export const AI_TIMELINE_ACTIONS_BY_TYPE: Record<string, AiActionKey[]> = {
64
+ call: ['summarize', 'replay', 'transcription', 'actionItems'],
65
+ email: ['summarize', 'showEmail', 'reply', 'sentiment'],
66
+ meeting: ['summarize', 'replay', 'actionItems', 'leadScore'],
67
+ note: ['expand', 'bulletize', 'translate'],
68
+ }
69
+
70
+ export function resolveAiActions(
71
+ activityType: string,
72
+ table: Record<string, AiActionKey[]>,
73
+ ): AiActionDefinition[] {
74
+ const fallbackKeys = table.note ?? []
75
+ const keys = table[activityType] ?? fallbackKeys
76
+ return keys.map((key) => AI_ACTION_DEFINITIONS[key]).filter(Boolean)
77
+ }
@@ -0,0 +1,124 @@
1
+ import { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'
2
+
3
+ export type AssignableStaffMember = {
4
+ teamMemberId: string
5
+ userId: string
6
+ displayName: string
7
+ email: string | null
8
+ teamName: string | null
9
+ }
10
+
11
+ type AssignableStaffResponse = {
12
+ items?: Array<Record<string, unknown>>
13
+ total?: number
14
+ page?: number
15
+ pageSize?: number
16
+ }
17
+
18
+ export type AssignableStaffMembersPage = {
19
+ items: AssignableStaffMember[]
20
+ total: number
21
+ page: number
22
+ pageSize: number
23
+ }
24
+
25
+ export async function fetchAssignableStaffMembersPage(
26
+ query: string,
27
+ options?: { page?: number; pageSize?: number; signal?: AbortSignal },
28
+ ): Promise<AssignableStaffMembersPage> {
29
+ const params = new URLSearchParams()
30
+ params.set('page', String(options?.page ?? 1))
31
+ params.set('pageSize', String(options?.pageSize ?? 24))
32
+ const normalizedQuery = query.trim()
33
+ if (normalizedQuery.length > 0) {
34
+ params.set('search', normalizedQuery)
35
+ }
36
+
37
+ const data = await readApiResultOrThrow<AssignableStaffResponse>(
38
+ `/api/customers/assignable-staff?${params.toString()}`,
39
+ options?.signal ? { signal: options.signal } : undefined,
40
+ )
41
+
42
+ const rawItems = Array.isArray(data?.items) ? data.items : []
43
+ const deduped = new Map<string, AssignableStaffMember>()
44
+
45
+ for (const item of rawItems) {
46
+ const userId =
47
+ typeof item?.userId === 'string'
48
+ ? item.userId
49
+ : typeof item?.user_id === 'string'
50
+ ? item.user_id
51
+ : null
52
+ if (!userId || deduped.has(userId)) continue
53
+
54
+ const user =
55
+ item?.user && typeof item.user === 'object'
56
+ ? (item.user as Record<string, unknown>)
57
+ : null
58
+ const team =
59
+ item?.team && typeof item.team === 'object'
60
+ ? (item.team as Record<string, unknown>)
61
+ : null
62
+
63
+ const displayName =
64
+ typeof item?.displayName === 'string' && item.displayName.trim().length > 0
65
+ ? item.displayName.trim()
66
+ : typeof item?.display_name === 'string' && item.display_name.trim().length > 0
67
+ ? item.display_name.trim()
68
+ : null
69
+ const email =
70
+ user && typeof user.email === 'string' && user.email.trim().length > 0
71
+ ? user.email.trim()
72
+ : typeof item?.email === 'string' && item.email.trim().length > 0
73
+ ? item.email.trim()
74
+ : null
75
+ const teamName =
76
+ typeof item?.teamName === 'string' && item.teamName.trim().length > 0
77
+ ? item.teamName.trim()
78
+ : typeof item?.team_name === 'string' && item.team_name.trim().length > 0
79
+ ? item.team_name.trim()
80
+ : team && typeof team.name === 'string' && team.name.trim().length > 0
81
+ ? team.name.trim()
82
+ : null
83
+ const teamMemberId =
84
+ typeof item?.teamMemberId === 'string'
85
+ ? item.teamMemberId
86
+ : typeof item?.team_member_id === 'string'
87
+ ? item.team_member_id
88
+ : typeof item?.id === 'string'
89
+ ? item.id
90
+ : userId
91
+
92
+ deduped.set(userId, {
93
+ teamMemberId,
94
+ userId,
95
+ displayName: displayName ?? email ?? userId,
96
+ email,
97
+ teamName,
98
+ })
99
+ }
100
+
101
+ return {
102
+ items: Array.from(deduped.values()),
103
+ total:
104
+ typeof data?.total === 'number' && Number.isFinite(data.total)
105
+ ? data.total
106
+ : deduped.size,
107
+ page:
108
+ typeof data?.page === 'number' && Number.isFinite(data.page)
109
+ ? data.page
110
+ : options?.page ?? 1,
111
+ pageSize:
112
+ typeof data?.pageSize === 'number' && Number.isFinite(data.pageSize)
113
+ ? data.pageSize
114
+ : options?.pageSize ?? 24,
115
+ }
116
+ }
117
+
118
+ export async function fetchAssignableStaffMembers(
119
+ query: string,
120
+ options?: { pageSize?: number; signal?: AbortSignal },
121
+ ): Promise<AssignableStaffMember[]> {
122
+ const result = await fetchAssignableStaffMembersPage(query, options)
123
+ return result.items
124
+ }