@open-mercato/core 0.6.8-develop.7099.1.7ba2771d06 → 0.7.0

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 (941) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/helpers/integration/api.js +1 -13
  3. package/dist/helpers/integration/api.js.map +2 -2
  4. package/dist/helpers/integration/communicationChannelsFixtures.js +0 -19
  5. package/dist/helpers/integration/communicationChannelsFixtures.js.map +2 -2
  6. package/dist/modules/api_keys/api/keys/route.js +1 -1
  7. package/dist/modules/api_keys/api/keys/route.js.map +2 -2
  8. package/dist/modules/api_keys/backend/api-keys/page.js +1 -3
  9. package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
  10. package/dist/modules/attachments/api/route.js +2 -2
  11. package/dist/modules/attachments/api/route.js.map +2 -2
  12. package/dist/modules/attachments/components/AttachmentLibrary.js +0 -2
  13. package/dist/modules/attachments/components/AttachmentLibrary.js.map +2 -2
  14. package/dist/modules/attachments/di.js +1 -11
  15. package/dist/modules/attachments/di.js.map +2 -2
  16. package/dist/modules/attachments/index.js.map +1 -1
  17. package/dist/modules/attachments/lib/scoped-upload-service.js +2 -15
  18. package/dist/modules/attachments/lib/scoped-upload-service.js.map +2 -2
  19. package/dist/modules/attachments/lib/upload-limits.js +2 -6
  20. package/dist/modules/attachments/lib/upload-limits.js.map +2 -2
  21. package/dist/modules/audit_logs/backend/audit-logs/page.js +0 -6
  22. package/dist/modules/audit_logs/backend/audit-logs/page.js.map +2 -2
  23. package/dist/modules/audit_logs/lib/display-helpers.js +11 -19
  24. package/dist/modules/audit_logs/lib/display-helpers.js.map +2 -2
  25. package/dist/modules/audit_logs/services/actionLogService.js +12 -57
  26. package/dist/modules/audit_logs/services/actionLogService.js.map +3 -3
  27. package/dist/modules/auth/acl.js +5 -30
  28. package/dist/modules/auth/acl.js.map +2 -2
  29. package/dist/modules/auth/api/feature-check.js +2 -8
  30. package/dist/modules/auth/api/feature-check.js.map +2 -2
  31. package/dist/modules/auth/api/login.js +20 -4
  32. package/dist/modules/auth/api/login.js.map +2 -2
  33. package/dist/modules/auth/api/roles/acl/route.js +33 -28
  34. package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
  35. package/dist/modules/auth/api/routeError.js +11 -0
  36. package/dist/modules/auth/api/routeError.js.map +7 -0
  37. package/dist/modules/auth/api/session/refresh.js +1 -25
  38. package/dist/modules/auth/api/session/refresh.js.map +2 -2
  39. package/dist/modules/auth/api/users/acl/route.js +73 -102
  40. package/dist/modules/auth/api/users/acl/route.js.map +2 -2
  41. package/dist/modules/auth/backend/roles/[id]/edit/page.meta.js +1 -5
  42. package/dist/modules/auth/backend/roles/[id]/edit/page.meta.js.map +2 -2
  43. package/dist/modules/auth/backend/roles/page.js +1 -3
  44. package/dist/modules/auth/backend/roles/page.js.map +2 -2
  45. package/dist/modules/auth/backend/users/[id]/edit/page.meta.js +1 -5
  46. package/dist/modules/auth/backend/users/[id]/edit/page.meta.js.map +2 -2
  47. package/dist/modules/auth/backend/users/page.js +1 -2
  48. package/dist/modules/auth/backend/users/page.js.map +2 -2
  49. package/dist/modules/auth/components/AclEditor.js +30 -39
  50. package/dist/modules/auth/components/AclEditor.js.map +2 -2
  51. package/dist/modules/auth/data/entities.js.map +2 -2
  52. package/dist/modules/auth/data/validators.js +1 -5
  53. package/dist/modules/auth/data/validators.js.map +2 -2
  54. package/dist/modules/auth/di.js +9 -35
  55. package/dist/modules/auth/di.js.map +2 -2
  56. package/dist/modules/auth/frontend/reset/[token]/page.js +0 -46
  57. package/dist/modules/auth/frontend/reset/[token]/page.js.map +2 -2
  58. package/dist/modules/auth/lib/grantChecks.js.map +2 -2
  59. package/dist/modules/auth/services/authService.js +2 -16
  60. package/dist/modules/auth/services/authService.js.map +2 -2
  61. package/dist/modules/auth/services/rbacService.js +24 -67
  62. package/dist/modules/auth/services/rbacService.js.map +3 -3
  63. package/dist/modules/business_rules/backend/logs/page.js +1 -3
  64. package/dist/modules/business_rules/backend/logs/page.js.map +2 -2
  65. package/dist/modules/business_rules/backend/rules/[id]/page.meta.js +6 -1
  66. package/dist/modules/business_rules/backend/rules/[id]/page.meta.js.map +2 -2
  67. package/dist/modules/business_rules/backend/rules/create/page.meta.js +5 -1
  68. package/dist/modules/business_rules/backend/rules/create/page.meta.js.map +2 -2
  69. package/dist/modules/business_rules/backend/rules/page.js +1 -3
  70. package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
  71. package/dist/modules/business_rules/backend/sets/[id]/page.meta.js +6 -1
  72. package/dist/modules/business_rules/backend/sets/[id]/page.meta.js.map +2 -2
  73. package/dist/modules/business_rules/backend/sets/create/page.meta.js +5 -1
  74. package/dist/modules/business_rules/backend/sets/create/page.meta.js.map +2 -2
  75. package/dist/modules/business_rules/backend/sets/page.js +1 -3
  76. package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
  77. package/dist/modules/business_rules/lib/expression-evaluator.js +9 -9
  78. package/dist/modules/business_rules/lib/expression-evaluator.js.map +2 -2
  79. package/dist/modules/business_rules/lib/rule-evaluator.js +9 -10
  80. package/dist/modules/business_rules/lib/rule-evaluator.js.map +2 -2
  81. package/dist/modules/catalog/ai-agents.js +1 -1
  82. package/dist/modules/catalog/ai-agents.js.map +1 -1
  83. package/dist/modules/catalog/ai-tools/merchandising-pack.js +2 -2
  84. package/dist/modules/catalog/ai-tools/merchandising-pack.js.map +2 -2
  85. package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js +2 -5
  86. package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js.map +2 -2
  87. package/dist/modules/catalog/components/categories/CategoriesDataTable.js +0 -2
  88. package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
  89. package/dist/modules/catalog/components/products/ProductsDataTable.js +1 -7
  90. package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
  91. package/dist/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.js +0 -2
  92. package/dist/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.js.map +2 -2
  93. package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js +1 -9
  94. package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js.map +2 -2
  95. package/dist/modules/communication_channels/api/post/test-seed/route.js +10 -95
  96. package/dist/modules/communication_channels/api/post/test-seed/route.js.map +2 -2
  97. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js +0 -3
  98. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js.map +2 -2
  99. package/dist/modules/communication_channels/commands/ingest-inbound-message.js +1 -14
  100. package/dist/modules/communication_channels/commands/ingest-inbound-message.js.map +2 -2
  101. package/dist/modules/communication_channels/di.js +1 -7
  102. package/dist/modules/communication_channels/di.js.map +2 -2
  103. package/dist/modules/communication_channels/lib/email-capabilities.js +1 -4
  104. package/dist/modules/communication_channels/lib/email-capabilities.js.map +2 -2
  105. package/dist/modules/communication_channels/lib/test-seed.js +2 -41
  106. package/dist/modules/communication_channels/lib/test-seed.js.map +2 -2
  107. package/dist/modules/configs/lib/system-status.js +0 -9
  108. package/dist/modules/configs/lib/system-status.js.map +2 -2
  109. package/dist/modules/currencies/backend/currencies/page.js +1 -3
  110. package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
  111. package/dist/modules/currencies/backend/exchange-rates/page.js +1 -3
  112. package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
  113. package/dist/modules/customer_accounts/api/admin/domain-mappings.js +0 -9
  114. package/dist/modules/customer_accounts/api/admin/domain-mappings.js.map +2 -2
  115. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +1 -3
  116. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
  117. package/dist/modules/customer_accounts/backend/customer_accounts/settings/CustomerAccountsSettingsPageClient.js +84 -0
  118. package/dist/modules/customer_accounts/backend/customer_accounts/settings/CustomerAccountsSettingsPageClient.js.map +7 -0
  119. package/dist/modules/customer_accounts/backend/customer_accounts/settings/page.js +7 -81
  120. package/dist/modules/customer_accounts/backend/customer_accounts/settings/page.js.map +2 -2
  121. package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js +523 -0
  122. package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js.map +7 -0
  123. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/PortalUserDetailPageClient.js +731 -0
  124. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/PortalUserDetailPageClient.js.map +7 -0
  125. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +7 -727
  126. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
  127. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +7 -521
  128. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
  129. package/dist/modules/customer_accounts/extension-points.js +1 -1
  130. package/dist/modules/customer_accounts/extension-points.js.map +2 -2
  131. package/dist/modules/customer_accounts/lib/portalUrl.js +69 -0
  132. package/dist/modules/customer_accounts/lib/portalUrl.js.map +7 -0
  133. package/dist/modules/customer_accounts/services/domainMappingService.js +0 -10
  134. package/dist/modules/customer_accounts/services/domainMappingService.js.map +2 -2
  135. package/dist/modules/customers/ai-tools/companies-pack.js +1 -4
  136. package/dist/modules/customers/ai-tools/companies-pack.js.map +2 -2
  137. package/dist/modules/customers/ai-tools/deal-analyzer-pack.js +2 -13
  138. package/dist/modules/customers/ai-tools/deal-analyzer-pack.js.map +2 -2
  139. package/dist/modules/customers/ai-tools/deals-pack.js +6 -52
  140. package/dist/modules/customers/ai-tools/deals-pack.js.map +2 -2
  141. package/dist/modules/customers/ai-tools/people-pack.js +1 -4
  142. package/dist/modules/customers/ai-tools/people-pack.js.map +2 -2
  143. package/dist/modules/customers/api/activities/route.js +6 -48
  144. package/dist/modules/customers/api/activities/route.js.map +2 -2
  145. package/dist/modules/customers/api/companies/[id]/people/route.js +64 -20
  146. package/dist/modules/customers/api/companies/[id]/people/route.js.map +2 -2
  147. package/dist/modules/customers/api/companies/[id]/route.js +94 -17
  148. package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
  149. package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js +5 -8
  150. package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js.map +2 -2
  151. package/dist/modules/customers/api/deals/[id]/companies/route.js +1 -1
  152. package/dist/modules/customers/api/deals/[id]/companies/route.js.map +2 -2
  153. package/dist/modules/customers/api/deals/[id]/people/route.js +1 -1
  154. package/dist/modules/customers/api/deals/[id]/people/route.js.map +2 -2
  155. package/dist/modules/customers/api/deals/[id]/route.js +25 -8
  156. package/dist/modules/customers/api/deals/[id]/route.js.map +2 -2
  157. package/dist/modules/customers/api/deals/[id]/stats/route.js +22 -3
  158. package/dist/modules/customers/api/deals/[id]/stats/route.js.map +2 -2
  159. package/dist/modules/customers/api/deals/aggregate/route.js +4 -11
  160. package/dist/modules/customers/api/deals/aggregate/route.js.map +2 -2
  161. package/dist/modules/customers/api/deals/map/route.js +1 -2
  162. package/dist/modules/customers/api/deals/map/route.js.map +2 -2
  163. package/dist/modules/customers/api/deals/route.js +1 -38
  164. package/dist/modules/customers/api/deals/route.js.map +2 -2
  165. package/dist/modules/customers/api/entity-roles-factory.js +4 -4
  166. package/dist/modules/customers/api/entity-roles-factory.js.map +2 -2
  167. package/dist/modules/customers/api/interactions/route.js +1 -3
  168. package/dist/modules/customers/api/interactions/route.js.map +2 -2
  169. package/dist/modules/customers/api/interactions/tasks/route.js +4 -27
  170. package/dist/modules/customers/api/interactions/tasks/route.js.map +2 -2
  171. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js +3 -4
  172. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js.map +2 -2
  173. package/dist/modules/customers/api/people/[id]/companies/context.js +1 -1
  174. package/dist/modules/customers/api/people/[id]/companies/context.js.map +2 -2
  175. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js +1 -1
  176. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js.map +2 -2
  177. package/dist/modules/customers/api/people/[id]/route.js +10 -11
  178. package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
  179. package/dist/modules/customers/api/people/check-phone/route.js +9 -51
  180. package/dist/modules/customers/api/people/check-phone/route.js.map +2 -2
  181. package/dist/modules/customers/api/todos/route.js +5 -30
  182. package/dist/modules/customers/api/todos/route.js.map +2 -2
  183. package/dist/modules/customers/backend/customers/companies/page.js +4 -6
  184. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  185. package/dist/modules/customers/backend/customers/deals/[id]/page.js +1 -6
  186. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
  187. package/dist/modules/customers/backend/customers/deals/page.js +4 -7
  188. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  189. package/dist/modules/customers/backend/customers/deals/pipeline/components/Lane.js +13 -4
  190. package/dist/modules/customers/backend/customers/deals/pipeline/components/Lane.js.map +2 -2
  191. package/dist/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.js +14 -85
  192. package/dist/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.js.map +2 -2
  193. package/dist/modules/customers/backend/customers/people/page.js +4 -6
  194. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  195. package/dist/modules/customers/backend/hooks/useEmailDuplicateCheck.js +3 -9
  196. package/dist/modules/customers/backend/hooks/useEmailDuplicateCheck.js.map +2 -2
  197. package/dist/modules/customers/commands/deals.js +34 -21
  198. package/dist/modules/customers/commands/deals.js.map +2 -2
  199. package/dist/modules/customers/commands/interactions.js.map +1 -1
  200. package/dist/modules/customers/commands/personCompanyLinks.js +2 -131
  201. package/dist/modules/customers/commands/personCompanyLinks.js.map +2 -2
  202. package/dist/modules/customers/components/CustomerTodosTable.js +0 -1
  203. package/dist/modules/customers/components/CustomerTodosTable.js.map +2 -2
  204. package/dist/modules/customers/components/DealsKpiStrip.js +6 -7
  205. package/dist/modules/customers/components/DealsKpiStrip.js.map +2 -2
  206. package/dist/modules/customers/components/calendar/AgendaList.js +2 -2
  207. package/dist/modules/customers/components/calendar/AgendaList.js.map +2 -2
  208. package/dist/modules/customers/components/calendar/CalendarEventEditor.js +1 -1
  209. package/dist/modules/customers/components/calendar/CalendarEventEditor.js.map +2 -2
  210. package/dist/modules/customers/components/calendar/CalendarScreen.js +1 -1
  211. package/dist/modules/customers/components/calendar/CalendarScreen.js.map +2 -2
  212. package/dist/modules/customers/components/calendar/CalendarSettingsModal.js +1 -1
  213. package/dist/modules/customers/components/calendar/CalendarSettingsModal.js.map +2 -2
  214. package/dist/modules/customers/components/calendar/EventBlock.js +1 -1
  215. package/dist/modules/customers/components/calendar/EventBlock.js.map +2 -2
  216. package/dist/modules/customers/components/calendar/EventPeekPopover.js +2 -3
  217. package/dist/modules/customers/components/calendar/EventPeekPopover.js.map +2 -2
  218. package/dist/modules/customers/components/calendar/editor/PeopleField.js +5 -40
  219. package/dist/modules/customers/components/calendar/editor/PeopleField.js.map +2 -2
  220. package/dist/modules/customers/components/calendar/editor/hooks.js +1 -2
  221. package/dist/modules/customers/components/calendar/editor/hooks.js.map +2 -2
  222. package/dist/modules/customers/components/calendar/types.js +1 -1
  223. package/dist/modules/customers/components/calendar/types.js.map +2 -2
  224. package/dist/modules/customers/components/detail/AssignRoleDialog.js +33 -28
  225. package/dist/modules/customers/components/detail/AssignRoleDialog.js.map +2 -2
  226. package/dist/modules/customers/components/detail/CompanyKpiBar.js +4 -5
  227. package/dist/modules/customers/components/detail/CompanyKpiBar.js.map +2 -2
  228. package/dist/modules/customers/components/detail/CompanyPeopleSection.js +1 -3
  229. package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
  230. package/dist/modules/customers/components/detail/DealForm.js +7 -19
  231. package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
  232. package/dist/modules/customers/components/detail/DealsSection.js +5 -6
  233. package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
  234. package/dist/modules/customers/components/detail/EntityTagsDialog.js +11 -35
  235. package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +2 -2
  236. package/dist/modules/customers/components/detail/PersonCompaniesSection.js +1 -3
  237. package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +2 -2
  238. package/dist/modules/customers/components/detail/hooks/usePersonTasks.js +13 -19
  239. package/dist/modules/customers/components/detail/hooks/usePersonTasks.js.map +2 -2
  240. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js +4 -4
  241. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js.map +2 -2
  242. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js +3 -3
  243. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +2 -2
  244. package/dist/modules/customers/components/detail/utils.js +5 -5
  245. package/dist/modules/customers/components/detail/utils.js.map +2 -2
  246. package/dist/modules/customers/data/entities.js.map +1 -1
  247. package/dist/modules/customers/data/validators.js +3 -32
  248. package/dist/modules/customers/data/validators.js.map +2 -2
  249. package/dist/modules/customers/events.js +0 -5
  250. package/dist/modules/customers/events.js.map +2 -2
  251. package/dist/modules/customers/lib/calendar/conflicts.js +2 -8
  252. package/dist/modules/customers/lib/calendar/conflicts.js.map +2 -2
  253. package/dist/modules/customers/lib/calendar/editorPayload.js +2 -3
  254. package/dist/modules/customers/lib/calendar/editorPayload.js.map +2 -2
  255. package/dist/modules/customers/lib/calendar/mapItem.js +3 -8
  256. package/dist/modules/customers/lib/calendar/mapItem.js.map +2 -2
  257. package/dist/modules/customers/lib/dealStatus.js +0 -30
  258. package/dist/modules/customers/lib/dealStatus.js.map +2 -2
  259. package/dist/modules/customers/lib/findPeopleByAddresses.js +0 -1
  260. package/dist/modules/customers/lib/findPeopleByAddresses.js.map +2 -2
  261. package/dist/modules/customers/lib/personCompanies.js +2 -100
  262. package/dist/modules/customers/lib/personCompanies.js.map +2 -2
  263. package/dist/modules/customers/lib/todoCompatibility.js +0 -12
  264. package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
  265. package/dist/modules/dashboards/lib/widgetScope.js +1 -6
  266. package/dist/modules/dashboards/lib/widgetScope.js.map +2 -2
  267. package/dist/modules/data_sync/backend/data-sync/page.js +1 -3
  268. package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
  269. package/dist/modules/data_sync/lib/sync-engine.js +6 -72
  270. package/dist/modules/data_sync/lib/sync-engine.js.map +2 -2
  271. package/dist/modules/data_sync/workers/sync-export.js +1 -5
  272. package/dist/modules/data_sync/workers/sync-export.js.map +2 -2
  273. package/dist/modules/data_sync/workers/sync-import.js +1 -5
  274. package/dist/modules/data_sync/workers/sync-import.js.map +2 -2
  275. package/dist/modules/devices/api/admin/devices/[id]/route.js +32 -5
  276. package/dist/modules/devices/api/admin/devices/[id]/route.js.map +2 -2
  277. package/dist/modules/devices/api/admin/devices/route.js +1 -14
  278. package/dist/modules/devices/api/admin/devices/route.js.map +2 -2
  279. package/dist/modules/devices/api/deviceList.js +12 -99
  280. package/dist/modules/devices/api/deviceList.js.map +2 -2
  281. package/dist/modules/devices/api/openapi.js +1 -3
  282. package/dist/modules/devices/api/openapi.js.map +2 -2
  283. package/dist/modules/devices/api/route.js +1 -9
  284. package/dist/modules/devices/api/route.js.map +2 -2
  285. package/dist/modules/devices/backend/devices/[id]/page.js +8 -8
  286. package/dist/modules/devices/backend/devices/[id]/page.js.map +2 -2
  287. package/dist/modules/devices/backend/devices/page.js +13 -15
  288. package/dist/modules/devices/backend/devices/page.js.map +2 -2
  289. package/dist/modules/directory/backend/directory/organizations/page.js +1 -2
  290. package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
  291. package/dist/modules/directory/backend/directory/tenants/page.js +1 -2
  292. package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
  293. package/dist/modules/directory/di.js +0 -9
  294. package/dist/modules/directory/di.js.map +2 -2
  295. package/dist/modules/directory/utils/organizationScope.js.map +2 -2
  296. package/dist/modules/entities/api/records.js +2 -4
  297. package/dist/modules/entities/api/records.js.map +2 -2
  298. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +1 -3
  299. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
  300. package/dist/modules/eudr/api/plots/route.js +1 -5
  301. package/dist/modules/eudr/api/plots/route.js.map +2 -2
  302. package/dist/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.js +3 -1
  303. package/dist/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.js.map +2 -2
  304. package/dist/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.js +1 -0
  305. package/dist/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.js.map +2 -2
  306. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js +0 -3
  307. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js.map +2 -2
  308. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.meta.js +4 -1
  309. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.meta.js.map +2 -2
  310. package/dist/modules/eudr/backend/eudr/page.meta.js +2 -2
  311. package/dist/modules/eudr/backend/eudr/page.meta.js.map +2 -2
  312. package/dist/modules/eudr/backend/eudr/plots/[id]/page.js +8 -2
  313. package/dist/modules/eudr/backend/eudr/plots/[id]/page.js.map +2 -2
  314. package/dist/modules/eudr/backend/eudr/plots/[id]/page.meta.js +3 -1
  315. package/dist/modules/eudr/backend/eudr/plots/[id]/page.meta.js.map +2 -2
  316. package/dist/modules/eudr/backend/eudr/plots/create/page.js +8 -2
  317. package/dist/modules/eudr/backend/eudr/plots/create/page.js.map +2 -2
  318. package/dist/modules/eudr/backend/eudr/plots/create/page.meta.js +1 -0
  319. package/dist/modules/eudr/backend/eudr/plots/create/page.meta.js.map +2 -2
  320. package/dist/modules/eudr/backend/eudr/plots/page.js +0 -3
  321. package/dist/modules/eudr/backend/eudr/plots/page.js.map +2 -2
  322. package/dist/modules/eudr/backend/eudr/plots/page.meta.js +4 -1
  323. package/dist/modules/eudr/backend/eudr/plots/page.meta.js.map +2 -2
  324. package/dist/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.js +3 -1
  325. package/dist/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.js.map +2 -2
  326. package/dist/modules/eudr/backend/eudr/product-mappings/create/page.meta.js +1 -0
  327. package/dist/modules/eudr/backend/eudr/product-mappings/create/page.meta.js.map +2 -2
  328. package/dist/modules/eudr/backend/eudr/product-mappings/page.js +0 -3
  329. package/dist/modules/eudr/backend/eudr/product-mappings/page.js.map +2 -2
  330. package/dist/modules/eudr/backend/eudr/product-mappings/page.meta.js +4 -1
  331. package/dist/modules/eudr/backend/eudr/product-mappings/page.meta.js.map +2 -2
  332. package/dist/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.js +3 -1
  333. package/dist/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.js.map +2 -2
  334. package/dist/modules/eudr/backend/eudr/risk-assessments/create/page.meta.js +1 -0
  335. package/dist/modules/eudr/backend/eudr/risk-assessments/create/page.meta.js.map +2 -2
  336. package/dist/modules/eudr/backend/eudr/risk-assessments/page.js +0 -3
  337. package/dist/modules/eudr/backend/eudr/risk-assessments/page.js.map +2 -2
  338. package/dist/modules/eudr/backend/eudr/risk-assessments/page.meta.js +4 -1
  339. package/dist/modules/eudr/backend/eudr/risk-assessments/page.meta.js.map +2 -2
  340. package/dist/modules/eudr/backend/eudr/statements/[id]/page.js +2 -0
  341. package/dist/modules/eudr/backend/eudr/statements/[id]/page.js.map +2 -2
  342. package/dist/modules/eudr/backend/eudr/statements/[id]/page.meta.js +3 -1
  343. package/dist/modules/eudr/backend/eudr/statements/[id]/page.meta.js.map +2 -2
  344. package/dist/modules/eudr/backend/eudr/statements/create/page.meta.js +1 -0
  345. package/dist/modules/eudr/backend/eudr/statements/create/page.meta.js.map +2 -2
  346. package/dist/modules/eudr/backend/eudr/statements/page.js +30 -28
  347. package/dist/modules/eudr/backend/eudr/statements/page.js.map +2 -2
  348. package/dist/modules/eudr/backend/eudr/statements/page.meta.js +4 -1
  349. package/dist/modules/eudr/backend/eudr/statements/page.meta.js.map +2 -2
  350. package/dist/modules/eudr/commands/statements.js +8 -3
  351. package/dist/modules/eudr/commands/statements.js.map +2 -2
  352. package/dist/modules/eudr/components/crudErrorI18n.js +21 -1
  353. package/dist/modules/eudr/components/crudErrorI18n.js.map +2 -2
  354. package/dist/modules/eudr/components/formConfig.js +6 -2
  355. package/dist/modules/eudr/components/formConfig.js.map +2 -2
  356. package/dist/modules/eudr/data/validators.js +1 -4
  357. package/dist/modules/eudr/data/validators.js.map +2 -2
  358. package/dist/modules/eudr/lib/statement-lifecycle.js +9 -1
  359. package/dist/modules/eudr/lib/statement-lifecycle.js.map +2 -2
  360. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +0 -1
  361. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
  362. package/dist/modules/feature_toggles/components/OverridesTable.js +0 -1
  363. package/dist/modules/feature_toggles/components/OverridesTable.js.map +2 -2
  364. package/dist/modules/feature_toggles/defaults.json +8 -0
  365. package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js +0 -3
  366. package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js.map +2 -2
  367. package/dist/modules/inbox_ops/backend/inbox-ops/page.js +0 -3
  368. package/dist/modules/inbox_ops/backend/inbox-ops/page.js.map +2 -2
  369. package/dist/modules/inbox_ops/lib/htmlToPlainText.js +12 -1
  370. package/dist/modules/inbox_ops/lib/htmlToPlainText.js.map +2 -2
  371. package/dist/modules/integrations/api/[id]/credentials/route.js +1 -6
  372. package/dist/modules/integrations/api/[id]/credentials/route.js.map +2 -2
  373. package/dist/modules/integrations/backend/integrations/[id]/page.js +29 -38
  374. package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
  375. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +9 -36
  376. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
  377. package/dist/modules/integrations/data/validators.js +3 -11
  378. package/dist/modules/integrations/data/validators.js.map +2 -2
  379. package/dist/modules/integrations/lib/credentials-masking.js +2 -6
  380. package/dist/modules/integrations/lib/credentials-masking.js.map +2 -2
  381. package/dist/modules/messages/api/[id]/route.js +1 -29
  382. package/dist/modules/messages/api/[id]/route.js.map +2 -2
  383. package/dist/modules/messages/api/openapi.js +2 -17
  384. package/dist/modules/messages/api/openapi.js.map +2 -2
  385. package/dist/modules/messages/api/route.js +2 -17
  386. package/dist/modules/messages/api/route.js.map +2 -2
  387. package/dist/modules/messages/components/MessagesInboxPageClient.js +14 -7
  388. package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
  389. package/dist/modules/messages/components/inboxFilters.js +0 -15
  390. package/dist/modules/messages/components/inboxFilters.js.map +2 -2
  391. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js +1 -11
  392. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js.map +2 -2
  393. package/dist/modules/messages/components/message-detail/panels/MessageHeader.js +1 -3
  394. package/dist/modules/messages/components/message-detail/panels/MessageHeader.js.map +2 -2
  395. package/dist/modules/messages/components/message-detail/panels/thread-panel.js +1 -2
  396. package/dist/modules/messages/components/message-detail/panels/thread-panel.js.map +2 -2
  397. package/dist/modules/messages/components/messageListLabels.js +2 -14
  398. package/dist/modules/messages/components/messageListLabels.js.map +2 -2
  399. package/dist/modules/messages/data/validators.js +4 -18
  400. package/dist/modules/messages/data/validators.js.map +2 -2
  401. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js +6 -4
  402. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js.map +2 -2
  403. package/dist/modules/payment_gateways/backend/payment-gateways/page.js +1 -3
  404. package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +2 -2
  405. package/dist/modules/payment_gateways/lib/webhook-processor.js +0 -7
  406. package/dist/modules/payment_gateways/lib/webhook-processor.js.map +2 -2
  407. package/dist/modules/planner/backend/planner/availability-rulesets/page.js +0 -3
  408. package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
  409. package/dist/modules/push_notifications/backend/push_notifications/page.js +1 -3
  410. package/dist/modules/push_notifications/backend/push_notifications/page.js.map +2 -2
  411. package/dist/modules/push_notifications/backend/push_notifications/send/page.js +1 -1
  412. package/dist/modules/push_notifications/backend/push_notifications/send/page.js.map +2 -2
  413. package/dist/modules/query_index/lib/engine.js +51 -150
  414. package/dist/modules/query_index/lib/engine.js.map +2 -2
  415. package/dist/modules/query_index/lib/search-tokens.js +3 -79
  416. package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
  417. package/dist/modules/resources/backend/resources/resource-types/page.js +1 -3
  418. package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
  419. package/dist/modules/resources/backend/resources/resources/page.js +1 -3
  420. package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
  421. package/dist/modules/sales/backend/sales/channels/offers/page.js +0 -3
  422. package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
  423. package/dist/modules/sales/backend/sales/channels/page.js +0 -3
  424. package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
  425. package/dist/modules/sales/backend/sales/documents/[id]/page.js +8 -10
  426. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  427. package/dist/modules/sales/commands/documents.js +1 -79
  428. package/dist/modules/sales/commands/documents.js.map +2 -2
  429. package/dist/modules/sales/components/PriceWithCurrency.js +5 -7
  430. package/dist/modules/sales/components/PriceWithCurrency.js.map +2 -2
  431. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +0 -3
  432. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
  433. package/dist/modules/sales/components/documents/AdjustmentsSection.js +6 -8
  434. package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
  435. package/dist/modules/sales/components/documents/ItemsSection.js +22 -51
  436. package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
  437. package/dist/modules/sales/components/documents/LineItemDialog.js +19 -84
  438. package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
  439. package/dist/modules/sales/components/documents/PaymentsSection.js +9 -23
  440. package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
  441. package/dist/modules/sales/components/documents/ReturnsSection.js +6 -8
  442. package/dist/modules/sales/components/documents/ReturnsSection.js.map +2 -2
  443. package/dist/modules/sales/components/documents/SalesDocumentsTable.js +14 -68
  444. package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
  445. package/dist/modules/sales/components/documents/SalesOrderDraftLines.js +5 -6
  446. package/dist/modules/sales/components/documents/SalesOrderDraftLines.js.map +2 -2
  447. package/dist/modules/sales/components/documents/ShipmentDialog.js +4 -5
  448. package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
  449. package/dist/modules/sales/components/documents/ShipmentsSection.js +6 -8
  450. package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
  451. package/dist/modules/sales/components/documents/lineItemUtils.js +2 -2
  452. package/dist/modules/sales/components/documents/lineItemUtils.js.map +2 -2
  453. package/dist/modules/sales/data/entities.js +2 -8
  454. package/dist/modules/sales/data/entities.js.map +2 -2
  455. package/dist/modules/sales/extension-points.js +0 -1
  456. package/dist/modules/sales/extension-points.js.map +2 -2
  457. package/dist/modules/sales/setup.js +0 -2
  458. package/dist/modules/sales/setup.js.map +2 -2
  459. package/dist/modules/sales/widgets/injection/document-history/widget.client.js +44 -2
  460. package/dist/modules/sales/widgets/injection/document-history/widget.client.js.map +2 -2
  461. package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js +2 -10
  462. package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js.map +2 -2
  463. package/dist/modules/sales/widgets/injection-table.js +7 -4
  464. package/dist/modules/sales/widgets/injection-table.js.map +2 -2
  465. package/dist/modules/staff/backend/staff/leave-requests/page.js +0 -3
  466. package/dist/modules/staff/backend/staff/leave-requests/page.js.map +2 -2
  467. package/dist/modules/staff/backend/staff/my-leave-requests/page.js +0 -3
  468. package/dist/modules/staff/backend/staff/my-leave-requests/page.js.map +2 -2
  469. package/dist/modules/staff/backend/staff/team-members/page.js +0 -3
  470. package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
  471. package/dist/modules/staff/backend/staff/team-roles/page.js +0 -3
  472. package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
  473. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +0 -3
  474. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
  475. package/dist/modules/staff/backend/staff/teams/page.js +0 -3
  476. package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
  477. package/dist/modules/staff/backend/staff/timesheets/page.js +18 -29
  478. package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
  479. package/dist/modules/staff/backend/staff/timesheets/projects/page.js +0 -3
  480. package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
  481. package/dist/modules/sync_excel/lib/adapters/customers.js +0 -1
  482. package/dist/modules/sync_excel/lib/adapters/customers.js.map +2 -2
  483. package/dist/modules/warranty_claims/api/assignees/route.js +3 -3
  484. package/dist/modules/warranty_claims/api/assignees/route.js.map +2 -2
  485. package/dist/modules/warranty_claims/api/portal/attachments/route.js +2 -2
  486. package/dist/modules/warranty_claims/api/portal/attachments/route.js.map +2 -2
  487. package/dist/modules/warranty_claims/api/portal/claims/route.js +9 -12
  488. package/dist/modules/warranty_claims/api/portal/claims/route.js.map +2 -2
  489. package/dist/modules/warranty_claims/backend/page.js +0 -3
  490. package/dist/modules/warranty_claims/backend/page.js.map +2 -2
  491. package/dist/modules/warranty_claims/backend/warranty_claims/registrations/page.js +0 -3
  492. package/dist/modules/warranty_claims/backend/warranty_claims/registrations/page.js.map +2 -2
  493. package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js +0 -3
  494. package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js.map +2 -2
  495. package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.js +0 -3
  496. package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.js.map +2 -2
  497. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js +0 -3
  498. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js.map +2 -2
  499. package/dist/modules/wms/api/warehouses/route.js +9 -13
  500. package/dist/modules/wms/api/warehouses/route.js.map +2 -2
  501. package/dist/modules/wms/api/zones/route.js +2 -15
  502. package/dist/modules/wms/api/zones/route.js.map +2 -2
  503. package/dist/modules/wms/commands/configuration.js +9 -121
  504. package/dist/modules/wms/commands/configuration.js.map +2 -2
  505. package/dist/modules/wms/commands/inventory-actions.js +0 -3
  506. package/dist/modules/wms/commands/inventory-actions.js.map +2 -2
  507. package/dist/modules/wms/commands/shared.js +1 -9
  508. package/dist/modules/wms/commands/shared.js.map +2 -2
  509. package/dist/modules/wms/components/backend/WmsConfigurationPage.js +111 -76
  510. package/dist/modules/wms/components/backend/WmsConfigurationPage.js.map +3 -3
  511. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js +0 -1
  512. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js.map +2 -2
  513. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js +20 -16
  514. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js.map +2 -2
  515. package/dist/modules/wms/components/backend/WmsLotDetailPage.js +10 -6
  516. package/dist/modules/wms/components/backend/WmsLotDetailPage.js.map +2 -2
  517. package/dist/modules/wms/components/backend/WmsLotsListPage.js +0 -1
  518. package/dist/modules/wms/components/backend/WmsLotsListPage.js.map +2 -2
  519. package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js +11 -7
  520. package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js.map +2 -2
  521. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js +10 -6
  522. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js.map +2 -2
  523. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js +20 -27
  524. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js.map +2 -2
  525. package/dist/modules/workflows/backend/definitions/page.js +1 -3
  526. package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
  527. package/dist/modules/workflows/backend/events/page.js +1 -3
  528. package/dist/modules/workflows/backend/events/page.js.map +2 -2
  529. package/dist/modules/workflows/backend/instances/page.js +1 -3
  530. package/dist/modules/workflows/backend/instances/page.js.map +2 -2
  531. package/dist/modules/workflows/backend/tasks/page.js +1 -3
  532. package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
  533. package/dist/modules/workflows/lib/activity-executor.js +0 -4
  534. package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
  535. package/package.json +10 -9
  536. package/src/helpers/integration/api.ts +1 -33
  537. package/src/helpers/integration/communicationChannelsFixtures.ts +1 -69
  538. package/src/modules/api_keys/api/keys/route.ts +1 -3
  539. package/src/modules/api_keys/backend/api-keys/page.tsx +1 -4
  540. package/src/modules/attachments/AGENTS.md +0 -15
  541. package/src/modules/attachments/api/route.ts +2 -2
  542. package/src/modules/attachments/components/AttachmentLibrary.tsx +0 -3
  543. package/src/modules/attachments/di.ts +0 -16
  544. package/src/modules/attachments/i18n/de.json +0 -5
  545. package/src/modules/attachments/i18n/en.json +0 -5
  546. package/src/modules/attachments/i18n/es.json +0 -5
  547. package/src/modules/attachments/i18n/ko.json +0 -5
  548. package/src/modules/attachments/i18n/pl.json +0 -5
  549. package/src/modules/attachments/index.ts +0 -10
  550. package/src/modules/attachments/lib/scoped-upload-service.ts +0 -46
  551. package/src/modules/attachments/lib/upload-limits.ts +2 -6
  552. package/src/modules/audit_logs/backend/audit-logs/page.tsx +0 -8
  553. package/src/modules/audit_logs/lib/display-helpers.tsx +32 -42
  554. package/src/modules/audit_logs/services/actionLogService.ts +11 -74
  555. package/src/modules/auth/acl.ts +6 -30
  556. package/src/modules/auth/api/feature-check.ts +3 -10
  557. package/src/modules/auth/api/login.ts +24 -9
  558. package/src/modules/auth/api/roles/acl/route.ts +39 -42
  559. package/src/modules/auth/api/routeError.ts +30 -0
  560. package/src/modules/auth/api/session/refresh.ts +1 -32
  561. package/src/modules/auth/api/users/acl/route.ts +101 -185
  562. package/src/modules/auth/backend/roles/[id]/edit/page.meta.ts +2 -5
  563. package/src/modules/auth/backend/roles/page.tsx +2 -4
  564. package/src/modules/auth/backend/users/[id]/edit/page.meta.ts +2 -5
  565. package/src/modules/auth/backend/users/page.tsx +2 -3
  566. package/src/modules/auth/components/AclEditor.tsx +33 -63
  567. package/src/modules/auth/data/entities.ts +1 -4
  568. package/src/modules/auth/data/validators.ts +0 -5
  569. package/src/modules/auth/di.ts +16 -46
  570. package/src/modules/auth/frontend/reset/[token]/page.tsx +0 -74
  571. package/src/modules/auth/i18n/de.json +0 -389
  572. package/src/modules/auth/i18n/en.json +0 -389
  573. package/src/modules/auth/i18n/es.json +0 -389
  574. package/src/modules/auth/i18n/ko.json +0 -389
  575. package/src/modules/auth/i18n/pl.json +2 -391
  576. package/src/modules/auth/lib/grantChecks.ts +0 -6
  577. package/src/modules/auth/services/authService.ts +2 -18
  578. package/src/modules/auth/services/rbacService.ts +24 -110
  579. package/src/modules/business_rules/backend/logs/page.tsx +1 -4
  580. package/src/modules/business_rules/backend/rules/[id]/page.meta.ts +5 -0
  581. package/src/modules/business_rules/backend/rules/create/page.meta.ts +5 -1
  582. package/src/modules/business_rules/backend/rules/page.tsx +1 -4
  583. package/src/modules/business_rules/backend/sets/[id]/page.meta.ts +5 -0
  584. package/src/modules/business_rules/backend/sets/create/page.meta.ts +5 -1
  585. package/src/modules/business_rules/backend/sets/page.tsx +1 -4
  586. package/src/modules/business_rules/lib/expression-evaluator.ts +9 -9
  587. package/src/modules/business_rules/lib/rule-evaluator.ts +9 -10
  588. package/src/modules/catalog/ai-agents.ts +1 -1
  589. package/src/modules/catalog/ai-tools/merchandising-pack.ts +2 -2
  590. package/src/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.tsx +5 -12
  591. package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +0 -3
  592. package/src/modules/catalog/components/products/ProductsDataTable.tsx +0 -7
  593. package/src/modules/catalog/i18n/de.json +0 -1
  594. package/src/modules/catalog/i18n/en.json +0 -1
  595. package/src/modules/catalog/i18n/es.json +0 -1
  596. package/src/modules/catalog/i18n/ko.json +0 -1
  597. package/src/modules/catalog/i18n/pl.json +0 -1
  598. package/src/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.tsx +0 -4
  599. package/src/modules/communication_channels/api/post/channels/[id]/test-send/route.ts +1 -17
  600. package/src/modules/communication_channels/api/post/test-seed/route.ts +16 -155
  601. package/src/modules/communication_channels/backend/communication_channels/channels/page.tsx +0 -4
  602. package/src/modules/communication_channels/commands/ingest-inbound-message.ts +1 -38
  603. package/src/modules/communication_channels/di.ts +0 -7
  604. package/src/modules/communication_channels/lib/adapter.ts +0 -14
  605. package/src/modules/communication_channels/lib/email-capabilities.ts +0 -4
  606. package/src/modules/communication_channels/lib/test-seed.ts +4 -64
  607. package/src/modules/configs/i18n/de.json +0 -2
  608. package/src/modules/configs/i18n/en.json +0 -2
  609. package/src/modules/configs/i18n/es.json +0 -2
  610. package/src/modules/configs/i18n/ko.json +0 -2
  611. package/src/modules/configs/i18n/pl.json +0 -2
  612. package/src/modules/configs/lib/system-status.ts +0 -9
  613. package/src/modules/currencies/backend/currencies/page.tsx +1 -4
  614. package/src/modules/currencies/backend/exchange-rates/page.tsx +1 -4
  615. package/src/modules/customer_accounts/api/admin/domain-mappings.ts +0 -7
  616. package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +1 -4
  617. package/src/modules/customer_accounts/backend/customer_accounts/settings/CustomerAccountsSettingsPageClient.tsx +138 -0
  618. package/src/modules/customer_accounts/backend/customer_accounts/settings/page.tsx +8 -132
  619. package/src/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.tsx +598 -0
  620. package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/PortalUserDetailPageClient.tsx +838 -0
  621. package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +6 -838
  622. package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +6 -590
  623. package/src/modules/customer_accounts/extension-points.ts +1 -1
  624. package/src/modules/customer_accounts/lib/portalUrl.ts +112 -0
  625. package/src/modules/customer_accounts/services/domainMappingService.ts +0 -10
  626. package/src/modules/customers/ai-tools/companies-pack.ts +1 -4
  627. package/src/modules/customers/ai-tools/deal-analyzer-pack.ts +2 -17
  628. package/src/modules/customers/ai-tools/deals-pack.ts +1 -66
  629. package/src/modules/customers/ai-tools/people-pack.ts +1 -4
  630. package/src/modules/customers/api/activities/route.ts +0 -45
  631. package/src/modules/customers/api/companies/[id]/people/route.ts +73 -24
  632. package/src/modules/customers/api/companies/[id]/route.ts +107 -24
  633. package/src/modules/customers/api/dashboard/widgets/customer-todos/route.ts +8 -16
  634. package/src/modules/customers/api/deals/[id]/companies/route.ts +1 -4
  635. package/src/modules/customers/api/deals/[id]/people/route.ts +1 -4
  636. package/src/modules/customers/api/deals/[id]/route.ts +28 -17
  637. package/src/modules/customers/api/deals/[id]/stats/route.ts +25 -10
  638. package/src/modules/customers/api/deals/aggregate/route.ts +4 -14
  639. package/src/modules/customers/api/deals/map/route.ts +0 -1
  640. package/src/modules/customers/api/deals/route.ts +1 -50
  641. package/src/modules/customers/api/entity-roles-factory.ts +4 -8
  642. package/src/modules/customers/api/interactions/route.ts +2 -8
  643. package/src/modules/customers/api/interactions/tasks/route.ts +1 -24
  644. package/src/modules/customers/api/people/[id]/companies/[linkId]/route.ts +4 -12
  645. package/src/modules/customers/api/people/[id]/companies/context.ts +1 -4
  646. package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +1 -4
  647. package/src/modules/customers/api/people/[id]/route.ts +11 -16
  648. package/src/modules/customers/api/people/check-phone/route.ts +10 -75
  649. package/src/modules/customers/api/todos/route.ts +2 -27
  650. package/src/modules/customers/backend/customers/companies/page.tsx +4 -7
  651. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +2 -7
  652. package/src/modules/customers/backend/customers/deals/page.tsx +4 -10
  653. package/src/modules/customers/backend/customers/deals/pipeline/components/Lane.tsx +14 -5
  654. package/src/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.tsx +27 -109
  655. package/src/modules/customers/backend/customers/people/page.tsx +4 -7
  656. package/src/modules/customers/backend/hooks/useEmailDuplicateCheck.ts +4 -12
  657. package/src/modules/customers/commands/deals.ts +59 -34
  658. package/src/modules/customers/commands/interactions.ts +1 -1
  659. package/src/modules/customers/commands/personCompanyLinks.ts +8 -224
  660. package/src/modules/customers/components/CustomerTodosTable.tsx +0 -2
  661. package/src/modules/customers/components/DealsKpiStrip.tsx +7 -7
  662. package/src/modules/customers/components/calendar/AgendaList.tsx +3 -3
  663. package/src/modules/customers/components/calendar/CalendarEventEditor.tsx +1 -1
  664. package/src/modules/customers/components/calendar/CalendarScreen.tsx +1 -1
  665. package/src/modules/customers/components/calendar/CalendarSettingsModal.tsx +1 -1
  666. package/src/modules/customers/components/calendar/EventBlock.tsx +2 -2
  667. package/src/modules/customers/components/calendar/EventPeekPopover.tsx +2 -4
  668. package/src/modules/customers/components/calendar/editor/PeopleField.tsx +5 -61
  669. package/src/modules/customers/components/calendar/editor/hooks.ts +1 -7
  670. package/src/modules/customers/components/calendar/types.ts +2 -2
  671. package/src/modules/customers/components/detail/AssignRoleDialog.tsx +12 -7
  672. package/src/modules/customers/components/detail/CompanyKpiBar.tsx +4 -5
  673. package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +1 -8
  674. package/src/modules/customers/components/detail/DealForm.tsx +2 -22
  675. package/src/modules/customers/components/detail/DealsSection.tsx +5 -11
  676. package/src/modules/customers/components/detail/EntityTagsDialog.tsx +12 -58
  677. package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +1 -8
  678. package/src/modules/customers/components/detail/hooks/usePersonTasks.ts +14 -23
  679. package/src/modules/customers/components/detail/schedule/ParticipantsField.tsx +5 -5
  680. package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +5 -5
  681. package/src/modules/customers/components/detail/types.ts +1 -1
  682. package/src/modules/customers/components/detail/utils.ts +5 -15
  683. package/src/modules/customers/data/entities.ts +1 -1
  684. package/src/modules/customers/data/validators.ts +9 -50
  685. package/src/modules/customers/events.ts +0 -5
  686. package/src/modules/customers/i18n/de.json +1 -9
  687. package/src/modules/customers/i18n/en.json +1 -9
  688. package/src/modules/customers/i18n/es.json +1 -9
  689. package/src/modules/customers/i18n/ko.json +1 -9
  690. package/src/modules/customers/i18n/pl.json +1 -9
  691. package/src/modules/customers/lib/calendar/conflicts.ts +2 -10
  692. package/src/modules/customers/lib/calendar/editorPayload.ts +3 -4
  693. package/src/modules/customers/lib/calendar/mapItem.ts +3 -8
  694. package/src/modules/customers/lib/dealStatus.ts +0 -42
  695. package/src/modules/customers/lib/findPeopleByAddresses.ts +6 -8
  696. package/src/modules/customers/lib/personCompanies.ts +1 -136
  697. package/src/modules/customers/lib/todoCompatibility.ts +1 -19
  698. package/src/modules/dashboards/i18n/es.json +4 -4
  699. package/src/modules/dashboards/i18n/pl.json +7 -7
  700. package/src/modules/dashboards/lib/widgetScope.ts +0 -6
  701. package/src/modules/data_sync/AGENTS.md +1 -1
  702. package/src/modules/data_sync/backend/data-sync/page.tsx +1 -4
  703. package/src/modules/data_sync/lib/adapter.ts +0 -36
  704. package/src/modules/data_sync/lib/sync-engine.ts +5 -113
  705. package/src/modules/data_sync/workers/sync-export.ts +0 -4
  706. package/src/modules/data_sync/workers/sync-import.ts +0 -4
  707. package/src/modules/devices/AGENTS.md +0 -8
  708. package/src/modules/devices/api/admin/devices/[id]/route.ts +34 -5
  709. package/src/modules/devices/api/admin/devices/route.ts +1 -14
  710. package/src/modules/devices/api/deviceList.ts +11 -135
  711. package/src/modules/devices/api/openapi.ts +1 -9
  712. package/src/modules/devices/api/route.ts +1 -9
  713. package/src/modules/devices/backend/devices/[id]/page.tsx +15 -15
  714. package/src/modules/devices/backend/devices/page.tsx +21 -24
  715. package/src/modules/directory/backend/directory/organizations/page.tsx +1 -3
  716. package/src/modules/directory/backend/directory/tenants/page.tsx +1 -3
  717. package/src/modules/directory/di.ts +2 -14
  718. package/src/modules/directory/utils/organizationScope.ts +15 -4
  719. package/src/modules/entities/api/records.ts +0 -2
  720. package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +1 -4
  721. package/src/modules/eudr/api/plots/route.ts +0 -4
  722. package/src/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.ts +2 -0
  723. package/src/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.ts +1 -0
  724. package/src/modules/eudr/backend/eudr/evidence-submissions/page.meta.ts +4 -1
  725. package/src/modules/eudr/backend/eudr/evidence-submissions/page.tsx +0 -4
  726. package/src/modules/eudr/backend/eudr/page.meta.ts +2 -2
  727. package/src/modules/eudr/backend/eudr/plots/[id]/page.meta.ts +2 -0
  728. package/src/modules/eudr/backend/eudr/plots/[id]/page.tsx +8 -2
  729. package/src/modules/eudr/backend/eudr/plots/create/page.meta.ts +1 -0
  730. package/src/modules/eudr/backend/eudr/plots/create/page.tsx +8 -2
  731. package/src/modules/eudr/backend/eudr/plots/page.meta.ts +4 -1
  732. package/src/modules/eudr/backend/eudr/plots/page.tsx +0 -4
  733. package/src/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.ts +2 -0
  734. package/src/modules/eudr/backend/eudr/product-mappings/create/page.meta.ts +1 -0
  735. package/src/modules/eudr/backend/eudr/product-mappings/page.meta.ts +4 -1
  736. package/src/modules/eudr/backend/eudr/product-mappings/page.tsx +0 -4
  737. package/src/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.ts +2 -0
  738. package/src/modules/eudr/backend/eudr/risk-assessments/create/page.meta.ts +1 -0
  739. package/src/modules/eudr/backend/eudr/risk-assessments/page.meta.ts +4 -1
  740. package/src/modules/eudr/backend/eudr/risk-assessments/page.tsx +0 -4
  741. package/src/modules/eudr/backend/eudr/statements/[id]/page.meta.ts +2 -0
  742. package/src/modules/eudr/backend/eudr/statements/[id]/page.tsx +2 -0
  743. package/src/modules/eudr/backend/eudr/statements/create/page.meta.ts +1 -0
  744. package/src/modules/eudr/backend/eudr/statements/page.meta.ts +4 -1
  745. package/src/modules/eudr/backend/eudr/statements/page.tsx +32 -30
  746. package/src/modules/eudr/commands/statements.ts +7 -2
  747. package/src/modules/eudr/components/crudErrorI18n.ts +31 -0
  748. package/src/modules/eudr/components/formConfig.tsx +9 -1
  749. package/src/modules/eudr/data/validators.ts +1 -16
  750. package/src/modules/eudr/i18n/de.json +3 -2
  751. package/src/modules/eudr/i18n/en.json +3 -2
  752. package/src/modules/eudr/i18n/es.json +3 -2
  753. package/src/modules/eudr/i18n/ko.json +3 -2
  754. package/src/modules/eudr/i18n/pl.json +3 -2
  755. package/src/modules/eudr/lib/statement-lifecycle.ts +8 -0
  756. package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +1 -2
  757. package/src/modules/feature_toggles/components/OverridesTable.tsx +1 -2
  758. package/src/modules/feature_toggles/defaults.json +8 -0
  759. package/src/modules/inbox_ops/backend/inbox-ops/log/page.tsx +0 -4
  760. package/src/modules/inbox_ops/backend/inbox-ops/page.tsx +0 -4
  761. package/src/modules/inbox_ops/lib/htmlToPlainText.ts +17 -1
  762. package/src/modules/integrations/api/[id]/credentials/route.ts +4 -6
  763. package/src/modules/integrations/backend/integrations/[id]/page.tsx +31 -61
  764. package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +9 -44
  765. package/src/modules/integrations/data/validators.ts +2 -12
  766. package/src/modules/integrations/i18n/de.json +0 -1
  767. package/src/modules/integrations/i18n/en.json +0 -1
  768. package/src/modules/integrations/i18n/es.json +0 -1
  769. package/src/modules/integrations/i18n/ko.json +0 -1
  770. package/src/modules/integrations/i18n/pl.json +0 -1
  771. package/src/modules/integrations/lib/credentials-masking.ts +6 -10
  772. package/src/modules/messages/api/[id]/route.ts +1 -55
  773. package/src/modules/messages/api/openapi.ts +0 -20
  774. package/src/modules/messages/api/route.ts +2 -31
  775. package/src/modules/messages/components/MessagesInboxPageClient.tsx +16 -9
  776. package/src/modules/messages/components/inboxFilters.ts +0 -36
  777. package/src/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.ts +1 -14
  778. package/src/modules/messages/components/message-detail/panels/MessageHeader.tsx +1 -3
  779. package/src/modules/messages/components/message-detail/panels/thread-panel.tsx +1 -2
  780. package/src/modules/messages/components/message-detail/types.ts +0 -3
  781. package/src/modules/messages/components/messageListLabels.ts +3 -52
  782. package/src/modules/messages/data/validators.ts +4 -43
  783. package/src/modules/payment_gateways/api/webhook/[provider]/route.ts +6 -4
  784. package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +1 -4
  785. package/src/modules/payment_gateways/lib/webhook-processor.ts +0 -11
  786. package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +0 -4
  787. package/src/modules/push_notifications/backend/push_notifications/page.tsx +1 -4
  788. package/src/modules/push_notifications/backend/push_notifications/send/page.tsx +4 -4
  789. package/src/modules/query_index/lib/engine.ts +61 -249
  790. package/src/modules/query_index/lib/search-tokens.ts +3 -135
  791. package/src/modules/resources/backend/resources/resource-types/page.tsx +1 -4
  792. package/src/modules/resources/backend/resources/resources/page.tsx +1 -4
  793. package/src/modules/sales/backend/sales/channels/offers/page.tsx +0 -4
  794. package/src/modules/sales/backend/sales/channels/page.tsx +0 -4
  795. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +8 -14
  796. package/src/modules/sales/commands/documents.ts +0 -93
  797. package/src/modules/sales/components/PriceWithCurrency.tsx +5 -17
  798. package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +0 -4
  799. package/src/modules/sales/components/documents/AdjustmentsSection.tsx +5 -6
  800. package/src/modules/sales/components/documents/ItemsSection.tsx +18 -56
  801. package/src/modules/sales/components/documents/LineItemDialog.tsx +21 -138
  802. package/src/modules/sales/components/documents/PaymentsSection.tsx +9 -20
  803. package/src/modules/sales/components/documents/ReturnsSection.tsx +5 -6
  804. package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +14 -106
  805. package/src/modules/sales/components/documents/SalesOrderDraftLines.tsx +5 -6
  806. package/src/modules/sales/components/documents/ShipmentDialog.tsx +4 -5
  807. package/src/modules/sales/components/documents/ShipmentsSection.tsx +5 -6
  808. package/src/modules/sales/components/documents/lineItemUtils.ts +2 -7
  809. package/src/modules/sales/data/entities.ts +0 -6
  810. package/src/modules/sales/extension-points.ts +0 -1
  811. package/src/modules/sales/i18n/de.json +37 -8
  812. package/src/modules/sales/i18n/en.json +37 -8
  813. package/src/modules/sales/i18n/es.json +37 -8
  814. package/src/modules/sales/i18n/ko.json +37 -8
  815. package/src/modules/sales/i18n/pl.json +37 -8
  816. package/src/modules/sales/migrations/.snapshot-open-mercato.json +0 -60
  817. package/src/modules/sales/setup.ts +0 -2
  818. package/src/modules/sales/widgets/injection/document-history/widget.client.tsx +42 -2
  819. package/src/modules/sales/widgets/injection/payment-gateway-status-column/widget.ts +1 -9
  820. package/src/modules/sales/widgets/injection-table.ts +7 -4
  821. package/src/modules/staff/backend/staff/leave-requests/page.tsx +0 -4
  822. package/src/modules/staff/backend/staff/my-leave-requests/page.tsx +0 -4
  823. package/src/modules/staff/backend/staff/team-members/page.tsx +0 -6
  824. package/src/modules/staff/backend/staff/team-roles/page.tsx +0 -4
  825. package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +0 -4
  826. package/src/modules/staff/backend/staff/teams/page.tsx +0 -4
  827. package/src/modules/staff/backend/staff/timesheets/page.tsx +1 -12
  828. package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +0 -4
  829. package/src/modules/sync_excel/lib/adapters/customers.ts +0 -5
  830. package/src/modules/warranty_claims/api/assignees/route.ts +3 -3
  831. package/src/modules/warranty_claims/api/portal/attachments/route.ts +2 -2
  832. package/src/modules/warranty_claims/api/portal/claims/route.ts +9 -12
  833. package/src/modules/warranty_claims/backend/page.tsx +0 -4
  834. package/src/modules/warranty_claims/backend/warranty_claims/registrations/page.tsx +0 -4
  835. package/src/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.tsx +0 -4
  836. package/src/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.tsx +0 -4
  837. package/src/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.tsx +0 -4
  838. package/src/modules/wms/api/warehouses/route.ts +9 -13
  839. package/src/modules/wms/api/zones/route.ts +0 -16
  840. package/src/modules/wms/commands/configuration.ts +10 -159
  841. package/src/modules/wms/commands/inventory-actions.ts +0 -3
  842. package/src/modules/wms/commands/shared.ts +0 -17
  843. package/src/modules/wms/components/backend/WmsConfigurationPage.tsx +141 -95
  844. package/src/modules/wms/components/backend/WmsInventoryConsolePage.tsx +0 -2
  845. package/src/modules/wms/components/backend/WmsLocationDetailPage.tsx +30 -26
  846. package/src/modules/wms/components/backend/WmsLotDetailPage.tsx +21 -17
  847. package/src/modules/wms/components/backend/WmsLotsListPage.tsx +0 -2
  848. package/src/modules/wms/components/backend/WmsOperationalDashboardPage.tsx +17 -13
  849. package/src/modules/wms/components/backend/WmsSkuDetailPage.tsx +16 -12
  850. package/src/modules/wms/components/backend/inventoryMutationLoaders.ts +20 -36
  851. package/src/modules/wms/i18n/de.json +0 -2
  852. package/src/modules/wms/i18n/en.json +0 -2
  853. package/src/modules/wms/i18n/es.json +0 -2
  854. package/src/modules/wms/i18n/ko.json +0 -2
  855. package/src/modules/wms/i18n/pl.json +0 -2
  856. package/src/modules/workflows/backend/definitions/page.tsx +1 -4
  857. package/src/modules/workflows/backend/events/page.tsx +1 -4
  858. package/src/modules/workflows/backend/instances/page.tsx +1 -4
  859. package/src/modules/workflows/backend/tasks/page.tsx +1 -4
  860. package/src/modules/workflows/lib/activity-executor.ts +0 -9
  861. package/dist/modules/api_keys/di.js +0 -9
  862. package/dist/modules/api_keys/di.js.map +0 -7
  863. package/dist/modules/api_keys/services/principalService.js +0 -31
  864. package/dist/modules/api_keys/services/principalService.js.map +0 -7
  865. package/dist/modules/attachments/lib/attachment-service.js +0 -313
  866. package/dist/modules/attachments/lib/attachment-service.js.map +0 -7
  867. package/dist/modules/auth/api/reset/validate.js +0 -55
  868. package/dist/modules/auth/api/reset/validate.js.map +0 -7
  869. package/dist/modules/auth/commands/acl.js +0 -254
  870. package/dist/modules/auth/commands/acl.js.map +0 -7
  871. package/dist/modules/auth/services/principalService.js +0 -200
  872. package/dist/modules/auth/services/principalService.js.map +0 -7
  873. package/dist/modules/auth/services/roleOrganizationScope.js +0 -41
  874. package/dist/modules/auth/services/roleOrganizationScope.js.map +0 -7
  875. package/dist/modules/communication_channels/lib/outbound-recipient.js +0 -33
  876. package/dist/modules/communication_channels/lib/outbound-recipient.js.map +0 -7
  877. package/dist/modules/communication_channels/lib/resolve-channel-type.js +0 -51
  878. package/dist/modules/communication_channels/lib/resolve-channel-type.js.map +0 -7
  879. package/dist/modules/customers/backend/customers/deals/pipeline/components/toneClasses.js +0 -18
  880. package/dist/modules/customers/backend/customers/deals/pipeline/components/toneClasses.js.map +0 -7
  881. package/dist/modules/customers/lib/calendar/participantIdentity.js +0 -9
  882. package/dist/modules/customers/lib/calendar/participantIdentity.js.map +0 -7
  883. package/dist/modules/customers/lib/closureStage.js +0 -45
  884. package/dist/modules/customers/lib/closureStage.js.map +0 -7
  885. package/dist/modules/customers/lib/detailReadAccess.js +0 -12
  886. package/dist/modules/customers/lib/detailReadAccess.js.map +0 -7
  887. package/dist/modules/data_sync/lib/abandoned-run.js +0 -19
  888. package/dist/modules/data_sync/lib/abandoned-run.js.map +0 -7
  889. package/dist/modules/devices/api/deviceSerialization.js +0 -46
  890. package/dist/modules/devices/api/deviceSerialization.js.map +0 -7
  891. package/dist/modules/directory/services/organizationHierarchyService.js +0 -29
  892. package/dist/modules/directory/services/organizationHierarchyService.js.map +0 -7
  893. package/dist/modules/directory/services/organizationScopeService.js +0 -56
  894. package/dist/modules/directory/services/organizationScopeService.js.map +0 -7
  895. package/dist/modules/integrations/backend/integrations/credential-secret-fields.js +0 -55
  896. package/dist/modules/integrations/backend/integrations/credential-secret-fields.js.map +0 -7
  897. package/dist/modules/messages/lib/channel-sender-identity.js +0 -26
  898. package/dist/modules/messages/lib/channel-sender-identity.js.map +0 -7
  899. package/dist/modules/messages/lib/composeSourceChannelType.js +0 -41
  900. package/dist/modules/messages/lib/composeSourceChannelType.js.map +0 -7
  901. package/dist/modules/query_index/lib/search-entity-policy.js +0 -14
  902. package/dist/modules/query_index/lib/search-entity-policy.js.map +0 -7
  903. package/dist/modules/sales/components/documents/lineItemShipmentLock.js +0 -54
  904. package/dist/modules/sales/components/documents/lineItemShipmentLock.js.map +0 -7
  905. package/dist/modules/sales/lib/salesChannelsToggleSeed.js +0 -33
  906. package/dist/modules/sales/lib/salesChannelsToggleSeed.js.map +0 -7
  907. package/dist/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.js +0 -32
  908. package/dist/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.js.map +0 -7
  909. package/dist/modules/wms/api/warehouseSearch.js +0 -21
  910. package/dist/modules/wms/api/warehouseSearch.js.map +0 -7
  911. package/dist/modules/wms/components/backend/WarehouseEditDialog.js +0 -158
  912. package/dist/modules/wms/components/backend/WarehouseEditDialog.js.map +0 -7
  913. package/dist/modules/wms/components/backend/warehouseFormOptions.js +0 -66
  914. package/dist/modules/wms/components/backend/warehouseFormOptions.js.map +0 -7
  915. package/src/modules/api_keys/di.ts +0 -7
  916. package/src/modules/api_keys/services/principalService.ts +0 -33
  917. package/src/modules/attachments/lib/attachment-service.ts +0 -468
  918. package/src/modules/auth/api/reset/validate.ts +0 -57
  919. package/src/modules/auth/commands/acl.ts +0 -495
  920. package/src/modules/auth/services/principalService.ts +0 -266
  921. package/src/modules/auth/services/roleOrganizationScope.ts +0 -70
  922. package/src/modules/communication_channels/lib/outbound-recipient.ts +0 -71
  923. package/src/modules/communication_channels/lib/resolve-channel-type.ts +0 -99
  924. package/src/modules/customers/backend/customers/deals/pipeline/components/toneClasses.ts +0 -21
  925. package/src/modules/customers/lib/calendar/participantIdentity.ts +0 -17
  926. package/src/modules/customers/lib/closureStage.ts +0 -76
  927. package/src/modules/customers/lib/detailReadAccess.ts +0 -35
  928. package/src/modules/data_sync/lib/abandoned-run.ts +0 -56
  929. package/src/modules/devices/api/deviceSerialization.ts +0 -50
  930. package/src/modules/directory/services/organizationHierarchyService.ts +0 -34
  931. package/src/modules/directory/services/organizationScopeService.ts +0 -85
  932. package/src/modules/integrations/backend/integrations/credential-secret-fields.ts +0 -84
  933. package/src/modules/messages/lib/channel-sender-identity.ts +0 -55
  934. package/src/modules/messages/lib/composeSourceChannelType.ts +0 -95
  935. package/src/modules/query_index/lib/search-entity-policy.ts +0 -46
  936. package/src/modules/sales/components/documents/lineItemShipmentLock.ts +0 -74
  937. package/src/modules/sales/lib/salesChannelsToggleSeed.ts +0 -42
  938. package/src/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.ts +0 -87
  939. package/src/modules/wms/api/warehouseSearch.ts +0 -23
  940. package/src/modules/wms/components/backend/WarehouseEditDialog.tsx +0 -216
  941. package/src/modules/wms/components/backend/warehouseFormOptions.ts +0 -72
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.tsx"],
4
- "sourcesContent": ["\"use client\"\n\n/**\n * MerchandisingAssistantSheet \u2014 Step 4.9 (Spec \u00A710 D18).\n *\n * Embeds `<AiChat agent=\"catalog.merchandising_assistant\" pageContext={...} />`\n * in a right-side sheet (built on the shared Dialog primitive because\n * `packages/ui` does not ship a dedicated Sheet/Drawer primitive in\n * Phase 2). The trigger is a button rendered in the products-list page\n * header.\n *\n * Phase 2 is strictly read-only: the sheet shows proposals (structured\n * output), but the mutation tools (`catalog.update_product`,\n * `catalog.bulk_update_products`, `catalog.apply_attribute_extraction`,\n * `catalog.update_product_media_descriptions`) are intentionally NOT in\n * the agent whitelist. Phase 5.14 introduces those via the pending-action\n * contract.\n *\n * pageContext follows spec \u00A710.1 exactly:\n *\n * {\n * view: 'catalog.products.list',\n * recordType: null,\n * recordId: string, // \"\" or comma-separated UUIDs\n * extra: {\n * filter: { categoryId, priceRange, tags, status },\n * totalMatching: number,\n * selectedCount: number,\n * }\n * }\n */\n\nimport * as React from 'react'\nimport { Boxes, ChevronDown, FileText, Package, PanelRightOpen, PenLine, Tags, TrendingUp } from 'lucide-react'\nimport { AiChat, type AiChatSuggestion, type AiChatContextItem } from '@open-mercato/ui/ai/AiChat'\nimport { AiIcon } from '@open-mercato/ui/ai/AiIcon'\nimport { useAiDock } from '@open-mercato/ui/ai/AiDock'\nimport { useAiChatSessions } from '@open-mercato/ui/ai/AiChatSessions'\nimport { ChatPaneTabs } from '@open-mercato/ui/ai/ChatPaneTabs'\n// Side-effect import: registers the `catalog.stats-card` UI part on the\n// global registry the first time this client bundle loads. Tools that\n// emit `{ uiPart: { componentId: 'catalog.stats-card' } }` envelopes\n// (catalog.show_stats today; user-defined tools tomorrow) automatically\n// resolve to the card without dispatcher changes.\nimport '../../../components/CatalogStatsCard'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { ButtonGroup } from '@open-mercato/ui/primitives/button-group'\nimport { IconButton } from '@open-mercato/ui/primitives/icon-button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '@open-mercato/ui/primitives/dialog'\nimport { Popover, PopoverContent, PopoverTrigger } from '@open-mercato/ui/primitives/popover'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { cn } from '@open-mercato/shared/lib/utils'\n\nexport interface MerchandisingPageContextFilter {\n categoryId: string | null\n priceRange: { min?: number; max?: number } | null\n tags: string[]\n status: string | null\n}\n\nexport interface MerchandisingPageContext {\n view: 'catalog.products.list'\n entityType?: 'catalog.products.list'\n recordType: null\n recordId: string\n extra: {\n filter: MerchandisingPageContextFilter\n totalMatching: number\n /** `totalMatching` is a floor, not an exact count (server-capped list count). */\n totalMatchingIsCapped?: boolean\n selectedCount: number\n }\n}\n\nexport interface MerchandisingAssistantSheetProps {\n /** Selection-aware page context, built by the products list host. */\n pageContext: MerchandisingPageContext\n /** When false (feature-gated by the host), the sheet renders nothing. */\n enabled?: boolean\n className?: string\n}\n\nexport const MERCHANDISING_AGENT_ID = 'catalog.merchandising_assistant'\n\nfunction useMerchandisingSuggestions(\n hasSelection: boolean,\n selectedCount: number,\n): AiChatSuggestion[] {\n const t = useT()\n return React.useMemo(() => {\n if (hasSelection) {\n return [\n {\n label: t(\n 'catalog.merchandising_assistant.suggestions.draftDescriptions',\n 'Draft product descriptions for selected items',\n ),\n prompt: `Draft compelling product descriptions for my ${selectedCount} selected products`,\n icon: <PenLine className=\"size-4\" />,\n },\n {\n label: t(\n 'catalog.merchandising_assistant.suggestions.extractAttributes',\n 'Extract attributes from descriptions',\n ),\n prompt: `Extract structured attributes from the descriptions of my ${selectedCount} selected products`,\n icon: <Tags className=\"size-4\" />,\n },\n {\n label: t(\n 'catalog.merchandising_assistant.suggestions.titleVariants',\n 'Generate title variants for SEO',\n ),\n prompt: `Generate SEO-optimized title variants for my ${selectedCount} selected products`,\n icon: <FileText className=\"size-4\" />,\n },\n {\n label: t(\n 'catalog.merchandising_assistant.suggestions.priceAdjustments',\n 'Suggest price adjustments',\n ),\n prompt: `Analyze and suggest price adjustments for my ${selectedCount} selected products`,\n icon: <TrendingUp className=\"size-4\" />,\n },\n ]\n }\n return [\n {\n label: t(\n 'catalog.merchandising_assistant.suggestions.showStats',\n 'Show catalog overview',\n ),\n // Triggers the `catalog.show_stats` tool, which returns the inline\n // catalog-stats UI part (live counts of products, active products,\n // categories, tags). Demo entry-point for the dynamic UI-part path.\n prompt: 'Show me a quick catalog overview using the stats card.',\n icon: <Boxes className=\"size-4\" />,\n },\n {\n label: t(\n 'catalog.merchandising_assistant.suggestions.browseProducts',\n 'Show me an overview of my product catalog',\n ),\n prompt: 'Give me an overview of my product catalog \u2014 categories, total products, and pricing ranges',\n icon: <Package className=\"size-4\" />,\n },\n {\n label: t(\n 'catalog.merchandising_assistant.suggestions.findMissingDescriptions',\n 'Find products with missing descriptions',\n ),\n prompt: 'Find products that are missing descriptions or have very short descriptions',\n icon: <PenLine className=\"size-4\" />,\n },\n {\n label: t(\n 'catalog.merchandising_assistant.suggestions.analyzeAttributes',\n 'Analyze attribute coverage',\n ),\n prompt: 'Analyze which products have incomplete attribute data',\n icon: <Tags className=\"size-4\" />,\n },\n {\n label: t(\n 'catalog.merchandising_assistant.suggestions.pricingOverview',\n 'Show pricing distribution',\n ),\n prompt: 'Show me the pricing distribution across categories',\n icon: <TrendingUp className=\"size-4\" />,\n },\n ]\n }, [hasSelection, selectedCount, t])\n}\n\nfunction useContextItems(pageContext: MerchandisingPageContext): AiChatContextItem[] {\n const t = useT()\n return React.useMemo(() => {\n const items: AiChatContextItem[] = []\n const { selectedCount, totalMatching, totalMatchingIsCapped, filter } = pageContext.extra\n if (selectedCount > 0) {\n items.push({\n label: t(\n 'catalog.merchandising_assistant.context.selectedProducts',\n '{count} products selected',\n ).replace('{count}', String(selectedCount)),\n })\n } else if (totalMatching > 0) {\n items.push({\n label: totalMatchingIsCapped\n ? t(\n 'catalog.merchandising_assistant.context.matchingProductsCapped',\n '{count}+ products in view',\n ).replace('{count}', String(totalMatching))\n : t(\n 'catalog.merchandising_assistant.context.matchingProducts',\n '{count} products in view',\n ).replace('{count}', String(totalMatching)),\n })\n }\n if (filter.categoryId) {\n items.push({\n label: t('catalog.merchandising_assistant.context.filteredByCategory', 'Filtered by category'),\n detail: filter.categoryId,\n })\n }\n if (filter.status) {\n items.push({ label: filter.status })\n }\n if (filter.tags.length > 0) {\n items.push({\n label: t('catalog.merchandising_assistant.context.tags', '{count} tags').replace(\n '{count}',\n String(filter.tags.length),\n ),\n })\n }\n return items\n }, [pageContext, t])\n}\n\ninterface MerchandisingAgentDescriptor {\n id: string\n label: string\n description: string\n icon: React.ReactNode\n}\n\ninterface AgentsResponse {\n agents?: Array<{\n id?: string | null\n }>\n}\n\ninterface MerchandisingAgentsState {\n agents: MerchandisingAgentDescriptor[]\n loaded: boolean\n}\n\nfunction useMerchandisingAgents(): MerchandisingAgentsState {\n const t = useT()\n const [accessibleAgentIds, setAccessibleAgentIds] = React.useState<Set<string> | null>(null)\n const declaredAgents = React.useMemo(\n () => [\n {\n id: MERCHANDISING_AGENT_ID,\n label: t(\n 'catalog.merchandising_assistant.agents.merchandising.label',\n 'Merchandising Assistant',\n ),\n description: t(\n 'catalog.merchandising_assistant.agents.merchandising.description',\n 'Draft copy, normalize attributes, and propose price changes for the current selection.',\n ),\n icon: <AiIcon className=\"size-4\" />,\n },\n ],\n [t],\n )\n\n React.useEffect(() => {\n let cancelled = false\n apiCall<AgentsResponse>('/api/ai_assistant/ai/agents', {\n credentials: 'same-origin',\n headers: { 'x-om-forbidden-redirect': '0', 'x-om-unauthorized-redirect': '0' },\n })\n .then((call) => {\n if (cancelled) return\n if (!call.ok || !call.result || !Array.isArray(call.result.agents)) {\n setAccessibleAgentIds(new Set())\n return\n }\n setAccessibleAgentIds(\n new Set(\n call.result.agents\n .map((agent) => agent?.id)\n .filter((id): id is string => typeof id === 'string' && id.length > 0),\n ),\n )\n })\n .catch(() => {\n if (!cancelled) setAccessibleAgentIds(new Set())\n })\n return () => {\n cancelled = true\n }\n }, [])\n\n return React.useMemo(\n () => ({\n agents:\n accessibleAgentIds === null\n ? []\n : declaredAgents.filter((agent) => accessibleAgentIds.has(agent.id)),\n loaded: accessibleAgentIds !== null,\n }),\n [accessibleAgentIds, declaredAgents],\n )\n}\n\nexport function MerchandisingAssistantSheet({\n pageContext,\n enabled = true,\n className,\n}: MerchandisingAssistantSheetProps): React.ReactElement | null {\n const t = useT()\n const dock = useAiDock()\n const [open, setOpen] = React.useState(false)\n const [popoverOpen, setPopoverOpen] = React.useState(false)\n const [activeAgent, setActiveAgent] = React.useState<string>(MERCHANDISING_AGENT_ID)\n const [lastAgent, setLastAgent] = React.useState<string | null>(null)\n\n const selectedCount = pageContext.extra.selectedCount\n const hasSelection = selectedCount > 0\n const suggestions = useMerchandisingSuggestions(hasSelection, selectedCount)\n const contextItems = useContextItems(pageContext)\n const { agents, loaded: agentsLoaded } = useMerchandisingAgents()\n\n if (!enabled || !agentsLoaded || agents.length === 0) return null\n\n const openAgent = (agentId: string) => {\n setActiveAgent(agentId)\n setLastAgent(agentId)\n setPopoverOpen(false)\n if (dock.state.assistant?.agent === agentId) {\n dock.dock(dock.state.assistant)\n setOpen(false)\n return\n }\n setOpen(true)\n }\n\n const handleSelectAgent = (agentId: string) => {\n openAgent(agentId)\n }\n\n const handleMainTriggerClick = () => {\n if (agents.length === 1) {\n openAgent(agents[0].id)\n return\n }\n if (lastAgent && agents.some((a) => a.id === lastAgent)) {\n openAgent(lastAgent)\n return\n }\n setPopoverOpen(true)\n }\n\n const handleDock = () => {\n const agent = agents.find((a) => a.id === activeAgent) ?? agents[0]\n if (!agent) return\n dock.dock({\n agent: agent.id,\n label: agent.label,\n description: t('catalog.merchandising_assistant.dock.subtitle', 'Catalog'),\n pageContext: pageContext as unknown as Record<string, unknown>,\n placeholder: t(\n 'catalog.merchandising_assistant.sheet.composerPlaceholder',\n 'Ask for descriptions, attributes, titles, or price ideas...',\n ),\n suggestions,\n contextItems,\n welcomeTitle: t(\n 'catalog.merchandising_assistant.sheet.welcomeTitle',\n 'Merchandising Assistant',\n ),\n welcomeDescription: hasSelection\n ? t(\n 'catalog.merchandising_assistant.sheet.welcomeDescriptionSelection',\n 'Ready to work with your {count} selected products. Try one of these:',\n ).replace('{count}', String(selectedCount))\n : t(\n 'catalog.merchandising_assistant.sheet.welcomeDescriptionAll',\n 'Select products for targeted actions, or explore your catalog:',\n ),\n })\n setOpen(false)\n }\n\n const triggerLabel = t(\n 'catalog.merchandising_assistant.trigger.ariaLabel',\n 'Open AI merchandising assistant',\n )\n const labelText = t('catalog.merchandising_assistant.trigger.label', 'AI')\n const moreAgentsLabel = t(\n 'catalog.merchandising_assistant.trigger.moreAgentsAriaLabel',\n 'Choose an AI assistant',\n )\n\n return (\n <>\n <ButtonGroup className={className}>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleMainTriggerClick}\n data-ai-merchandising-trigger=\"\"\n aria-label={triggerLabel}\n title={triggerLabel}\n className=\"relative\"\n >\n <AiIcon className=\"size-4\" />\n <span>{labelText}</span>\n {hasSelection ? (\n <span\n className=\"absolute -top-1 -right-1 inline-flex h-4 min-w-4 items-center justify-center rounded-full bg-primary px-1 text-[10px] font-medium leading-none text-primary-foreground\"\n data-ai-merchandising-selected-count={selectedCount}\n >\n {selectedCount}\n </span>\n ) : null}\n </Button>\n {agents.length > 1 ? (\n <Popover open={popoverOpen} onOpenChange={setPopoverOpen}>\n <PopoverTrigger asChild>\n <IconButton\n type=\"button\"\n variant=\"outline\"\n aria-label={moreAgentsLabel}\n title={moreAgentsLabel}\n data-ai-merchandising-picker=\"\"\n >\n <ChevronDown className=\"size-4\" aria-hidden />\n </IconButton>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"w-72 p-1\">\n <div className=\"px-3 pt-2 pb-1 text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n {t('catalog.merchandising_assistant.popover.heading', 'AI assistants')}\n </div>\n <div className=\"flex flex-col gap-0.5\">\n {agents.map((agent) => (\n <Button\n key={agent.id}\n type=\"button\"\n variant=\"ghost\"\n onClick={() => handleSelectAgent(agent.id)}\n data-ai-merchandising-agent-option={agent.id}\n className=\"h-auto w-full items-start justify-start gap-2 whitespace-normal rounded-sm px-2 py-2 text-left text-sm font-normal\"\n >\n <span className=\"mt-0.5 inline-flex size-6 items-center justify-center rounded-full bg-secondary text-secondary-foreground\">\n {agent.icon}\n </span>\n <span className=\"flex-1 min-w-0\">\n <span className=\"block font-medium leading-tight\">{agent.label}</span>\n <span className=\"block text-xs text-muted-foreground leading-snug\">\n {agent.description}\n </span>\n </span>\n </Button>\n ))}\n </div>\n </PopoverContent>\n </Popover>\n ) : null}\n </ButtonGroup>\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogContent\n className={cn(\n // Mobile: full-screen sheet. Desktop (\u2265sm): right-anchored side sheet.\n // The Dialog primitive applies a centering transform at the\n // sm breakpoint; each piece (`top`, `left`, transform, inset)\n // must be overridden at the same breakpoint or the panel\n // renders half off the viewport.\n 'top-0 left-0 right-0 bottom-0 translate-x-0 translate-y-0 max-w-none w-screen h-svh max-h-svh rounded-none',\n 'sm:top-0 sm:bottom-0 sm:right-0 sm:left-auto sm:translate-x-0 sm:translate-y-0',\n 'sm:max-w-xl sm:w-[36rem] sm:rounded-l-2xl sm:h-screen sm:max-h-screen',\n 'flex flex-col gap-3 p-4 z-[70]',\n )}\n data-ai-merchandising-sheet=\"\"\n >\n <DialogHeader>\n <div className=\"flex items-center gap-3 pr-8\">\n {/* Dock button lives on the LEFT \u2014 the Dialog primitive\n auto-renders an X close button absolutely positioned in\n the top-right corner, so anything we drop in the header's\n right side visually collides with it. Mobile hides the\n dock entirely (the side panel is desktop-only). */}\n <IconButton\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n aria-label={t('catalog.merchandising_assistant.sheet.dock', 'Dock to side')}\n title={t('catalog.merchandising_assistant.sheet.dock', 'Dock to side')}\n onClick={handleDock}\n data-ai-merchandising-dock=\"\"\n className=\"hidden lg:inline-flex shrink-0\"\n >\n <PanelRightOpen className=\"size-4\" aria-hidden />\n </IconButton>\n <DialogTitle className=\"flex-1 min-w-0 truncate\">\n {t('catalog.merchandising_assistant.sheet.title', 'Catalog merchandising assistant')}\n </DialogTitle>\n {hasSelection ? (\n <span\n className=\"shrink-0 inline-flex items-center rounded-full border border-border bg-secondary px-2 py-0.5 text-xs text-secondary-foreground\"\n data-ai-merchandising-selection-pill=\"\"\n data-ai-merchandising-selected-count={selectedCount}\n >\n {t(\n 'catalog.merchandising_assistant.sheet.selectionPill',\n 'Acting on {count} products',\n ).replace('{count}', String(selectedCount))}\n </span>\n ) : null}\n </div>\n <DialogDescription>\n {hasSelection\n ? t(\n 'catalog.merchandising_assistant.sheet.descriptionWithSelection',\n 'Working with {count} selected products. Ask for descriptions, attribute extraction, title suggestions, or pricing analysis.',\n ).replace('{count}', String(selectedCount))\n : t(\n 'catalog.merchandising_assistant.sheet.description',\n 'Your AI merchandising copilot. Select products from the list for targeted actions, or explore your full catalog.',\n )}\n </DialogDescription>\n </DialogHeader>\n <MerchandisingChatBody\n activeAgent={activeAgent}\n pageContext={pageContext}\n suggestions={suggestions}\n contextItems={contextItems}\n hasSelection={hasSelection}\n selectedCount={selectedCount}\n />\n </DialogContent>\n </Dialog>\n </>\n )\n}\n\ninterface MerchandisingChatBodyProps {\n activeAgent: string\n pageContext: MerchandisingPageContext\n suggestions: AiChatSuggestion[]\n contextItems: AiChatContextItem[]\n hasSelection: boolean\n selectedCount: number\n}\n\nfunction MerchandisingChatBody({\n activeAgent,\n pageContext,\n suggestions,\n contextItems,\n hasSelection,\n selectedCount,\n}: MerchandisingChatBodyProps) {\n const t = useT()\n const sessions = useAiChatSessions()\n const session = sessions.getActiveSession(activeAgent)\n\n React.useEffect(() => {\n if (!session) sessions.ensureSession(activeAgent)\n }, [activeAgent, session, sessions])\n\n return (\n <>\n <ChatPaneTabs agentId={activeAgent} className=\"border-b\" />\n <div className=\"min-h-0 flex-1\" data-ai-merchandising-chat-container=\"\">\n {session ? (\n <AiChat\n key={session.id}\n agent={activeAgent}\n conversationId={session.conversationId}\n pageContext={pageContext as unknown as Record<string, unknown>}\n className=\"h-full\"\n placeholder={t(\n 'catalog.merchandising_assistant.sheet.composerPlaceholder',\n 'Ask for descriptions, attributes, titles, or price ideas...',\n )}\n suggestions={suggestions}\n contextItems={contextItems}\n welcomeTitle={t(\n 'catalog.merchandising_assistant.sheet.welcomeTitle',\n 'Merchandising Assistant',\n )}\n welcomeDescription={\n hasSelection\n ? t(\n 'catalog.merchandising_assistant.sheet.welcomeDescriptionSelection',\n 'Ready to work with your {count} selected products. Try one of these:',\n ).replace('{count}', String(selectedCount))\n : t(\n 'catalog.merchandising_assistant.sheet.welcomeDescriptionAll',\n 'Select products for targeted actions, or explore your catalog:',\n )\n }\n />\n ) : null}\n </div>\n </>\n )\n}\n\nexport default MerchandisingAssistantSheet\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\n/**\n * MerchandisingAssistantSheet \u2014 Step 4.9 (Spec \u00A710 D18).\n *\n * Embeds `<AiChat agent=\"catalog.merchandising_assistant\" pageContext={...} />`\n * in a right-side sheet (built on the shared Dialog primitive because\n * `packages/ui` does not ship a dedicated Sheet/Drawer primitive in\n * Phase 2). The trigger is a button rendered in the products-list page\n * header.\n *\n * Phase 2 is strictly read-only: the sheet shows proposals (structured\n * output), but the mutation tools (`catalog.update_product`,\n * `catalog.bulk_update_products`, `catalog.apply_attribute_extraction`,\n * `catalog.update_product_media_descriptions`) are intentionally NOT in\n * the agent whitelist. Phase 5.14 introduces those via the pending-action\n * contract.\n *\n * pageContext follows spec \u00A710.1 exactly:\n *\n * {\n * view: 'catalog.products.list',\n * recordType: null,\n * recordId: string, // \"\" or comma-separated UUIDs\n * extra: {\n * filter: { categoryId, priceRange, tags, status },\n * totalMatching: number,\n * selectedCount: number,\n * }\n * }\n */\n\nimport * as React from 'react'\nimport { Boxes, ChevronDown, FileText, Package, PanelRightOpen, PenLine, Tags, TrendingUp } from 'lucide-react'\nimport { AiChat, type AiChatSuggestion, type AiChatContextItem } from '@open-mercato/ui/ai/AiChat'\nimport { AiIcon } from '@open-mercato/ui/ai/AiIcon'\nimport { useAiDock } from '@open-mercato/ui/ai/AiDock'\nimport { useAiChatSessions } from '@open-mercato/ui/ai/AiChatSessions'\nimport { ChatPaneTabs } from '@open-mercato/ui/ai/ChatPaneTabs'\n// Side-effect import: registers the `catalog.stats-card` UI part on the\n// global registry the first time this client bundle loads. Tools that\n// emit `{ uiPart: { componentId: 'catalog.stats-card' } }` envelopes\n// (catalog.show_stats today; user-defined tools tomorrow) automatically\n// resolve to the card without dispatcher changes.\nimport '../../../components/CatalogStatsCard'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { ButtonGroup } from '@open-mercato/ui/primitives/button-group'\nimport { IconButton } from '@open-mercato/ui/primitives/icon-button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '@open-mercato/ui/primitives/dialog'\nimport { Popover, PopoverContent, PopoverTrigger } from '@open-mercato/ui/primitives/popover'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { cn } from '@open-mercato/shared/lib/utils'\n\nexport interface MerchandisingPageContextFilter {\n categoryId: string | null\n priceRange: { min?: number; max?: number } | null\n tags: string[]\n status: string | null\n}\n\nexport interface MerchandisingPageContext {\n view: 'catalog.products.list'\n entityType?: 'catalog.products.list'\n recordType: null\n recordId: string\n extra: {\n filter: MerchandisingPageContextFilter\n totalMatching: number\n selectedCount: number\n }\n}\n\nexport interface MerchandisingAssistantSheetProps {\n /** Selection-aware page context, built by the products list host. */\n pageContext: MerchandisingPageContext\n /** When false (feature-gated by the host), the sheet renders nothing. */\n enabled?: boolean\n className?: string\n}\n\nexport const MERCHANDISING_AGENT_ID = 'catalog.merchandising_assistant'\n\nfunction useMerchandisingSuggestions(\n hasSelection: boolean,\n selectedCount: number,\n): AiChatSuggestion[] {\n const t = useT()\n return React.useMemo(() => {\n if (hasSelection) {\n return [\n {\n label: t(\n 'catalog.merchandising_assistant.suggestions.draftDescriptions',\n 'Draft product descriptions for selected items',\n ),\n prompt: `Draft compelling product descriptions for my ${selectedCount} selected products`,\n icon: <PenLine className=\"size-4\" />,\n },\n {\n label: t(\n 'catalog.merchandising_assistant.suggestions.extractAttributes',\n 'Extract attributes from descriptions',\n ),\n prompt: `Extract structured attributes from the descriptions of my ${selectedCount} selected products`,\n icon: <Tags className=\"size-4\" />,\n },\n {\n label: t(\n 'catalog.merchandising_assistant.suggestions.titleVariants',\n 'Generate title variants for SEO',\n ),\n prompt: `Generate SEO-optimized title variants for my ${selectedCount} selected products`,\n icon: <FileText className=\"size-4\" />,\n },\n {\n label: t(\n 'catalog.merchandising_assistant.suggestions.priceAdjustments',\n 'Suggest price adjustments',\n ),\n prompt: `Analyze and suggest price adjustments for my ${selectedCount} selected products`,\n icon: <TrendingUp className=\"size-4\" />,\n },\n ]\n }\n return [\n {\n label: t(\n 'catalog.merchandising_assistant.suggestions.showStats',\n 'Show catalog overview',\n ),\n // Triggers the `catalog.show_stats` tool, which returns the inline\n // catalog-stats UI part (live counts of products, active products,\n // categories, tags). Demo entry-point for the dynamic UI-part path.\n prompt: 'Show me a quick catalog overview using the stats card.',\n icon: <Boxes className=\"size-4\" />,\n },\n {\n label: t(\n 'catalog.merchandising_assistant.suggestions.browseProducts',\n 'Show me an overview of my product catalog',\n ),\n prompt: 'Give me an overview of my product catalog \u2014 categories, total products, and pricing ranges',\n icon: <Package className=\"size-4\" />,\n },\n {\n label: t(\n 'catalog.merchandising_assistant.suggestions.findMissingDescriptions',\n 'Find products with missing descriptions',\n ),\n prompt: 'Find products that are missing descriptions or have very short descriptions',\n icon: <PenLine className=\"size-4\" />,\n },\n {\n label: t(\n 'catalog.merchandising_assistant.suggestions.analyzeAttributes',\n 'Analyze attribute coverage',\n ),\n prompt: 'Analyze which products have incomplete attribute data',\n icon: <Tags className=\"size-4\" />,\n },\n {\n label: t(\n 'catalog.merchandising_assistant.suggestions.pricingOverview',\n 'Show pricing distribution',\n ),\n prompt: 'Show me the pricing distribution across categories',\n icon: <TrendingUp className=\"size-4\" />,\n },\n ]\n }, [hasSelection, selectedCount, t])\n}\n\nfunction useContextItems(pageContext: MerchandisingPageContext): AiChatContextItem[] {\n const t = useT()\n return React.useMemo(() => {\n const items: AiChatContextItem[] = []\n const { selectedCount, totalMatching, filter } = pageContext.extra\n if (selectedCount > 0) {\n items.push({\n label: t(\n 'catalog.merchandising_assistant.context.selectedProducts',\n '{count} products selected',\n ).replace('{count}', String(selectedCount)),\n })\n } else if (totalMatching > 0) {\n items.push({\n label: t(\n 'catalog.merchandising_assistant.context.matchingProducts',\n '{count} products in view',\n ).replace('{count}', String(totalMatching)),\n })\n }\n if (filter.categoryId) {\n items.push({\n label: t('catalog.merchandising_assistant.context.filteredByCategory', 'Filtered by category'),\n detail: filter.categoryId,\n })\n }\n if (filter.status) {\n items.push({ label: filter.status })\n }\n if (filter.tags.length > 0) {\n items.push({\n label: t('catalog.merchandising_assistant.context.tags', '{count} tags').replace(\n '{count}',\n String(filter.tags.length),\n ),\n })\n }\n return items\n }, [pageContext, t])\n}\n\ninterface MerchandisingAgentDescriptor {\n id: string\n label: string\n description: string\n icon: React.ReactNode\n}\n\ninterface AgentsResponse {\n agents?: Array<{\n id?: string | null\n }>\n}\n\ninterface MerchandisingAgentsState {\n agents: MerchandisingAgentDescriptor[]\n loaded: boolean\n}\n\nfunction useMerchandisingAgents(): MerchandisingAgentsState {\n const t = useT()\n const [accessibleAgentIds, setAccessibleAgentIds] = React.useState<Set<string> | null>(null)\n const declaredAgents = React.useMemo(\n () => [\n {\n id: MERCHANDISING_AGENT_ID,\n label: t(\n 'catalog.merchandising_assistant.agents.merchandising.label',\n 'Merchandising Assistant',\n ),\n description: t(\n 'catalog.merchandising_assistant.agents.merchandising.description',\n 'Draft copy, normalize attributes, and propose price changes for the current selection.',\n ),\n icon: <AiIcon className=\"size-4\" />,\n },\n ],\n [t],\n )\n\n React.useEffect(() => {\n let cancelled = false\n apiCall<AgentsResponse>('/api/ai_assistant/ai/agents', {\n credentials: 'same-origin',\n headers: { 'x-om-forbidden-redirect': '0', 'x-om-unauthorized-redirect': '0' },\n })\n .then((call) => {\n if (cancelled) return\n if (!call.ok || !call.result || !Array.isArray(call.result.agents)) {\n setAccessibleAgentIds(new Set())\n return\n }\n setAccessibleAgentIds(\n new Set(\n call.result.agents\n .map((agent) => agent?.id)\n .filter((id): id is string => typeof id === 'string' && id.length > 0),\n ),\n )\n })\n .catch(() => {\n if (!cancelled) setAccessibleAgentIds(new Set())\n })\n return () => {\n cancelled = true\n }\n }, [])\n\n return React.useMemo(\n () => ({\n agents:\n accessibleAgentIds === null\n ? []\n : declaredAgents.filter((agent) => accessibleAgentIds.has(agent.id)),\n loaded: accessibleAgentIds !== null,\n }),\n [accessibleAgentIds, declaredAgents],\n )\n}\n\nexport function MerchandisingAssistantSheet({\n pageContext,\n enabled = true,\n className,\n}: MerchandisingAssistantSheetProps): React.ReactElement | null {\n const t = useT()\n const dock = useAiDock()\n const [open, setOpen] = React.useState(false)\n const [popoverOpen, setPopoverOpen] = React.useState(false)\n const [activeAgent, setActiveAgent] = React.useState<string>(MERCHANDISING_AGENT_ID)\n const [lastAgent, setLastAgent] = React.useState<string | null>(null)\n\n const selectedCount = pageContext.extra.selectedCount\n const hasSelection = selectedCount > 0\n const suggestions = useMerchandisingSuggestions(hasSelection, selectedCount)\n const contextItems = useContextItems(pageContext)\n const { agents, loaded: agentsLoaded } = useMerchandisingAgents()\n\n if (!enabled || !agentsLoaded || agents.length === 0) return null\n\n const openAgent = (agentId: string) => {\n setActiveAgent(agentId)\n setLastAgent(agentId)\n setPopoverOpen(false)\n if (dock.state.assistant?.agent === agentId) {\n dock.dock(dock.state.assistant)\n setOpen(false)\n return\n }\n setOpen(true)\n }\n\n const handleSelectAgent = (agentId: string) => {\n openAgent(agentId)\n }\n\n const handleMainTriggerClick = () => {\n if (agents.length === 1) {\n openAgent(agents[0].id)\n return\n }\n if (lastAgent && agents.some((a) => a.id === lastAgent)) {\n openAgent(lastAgent)\n return\n }\n setPopoverOpen(true)\n }\n\n const handleDock = () => {\n const agent = agents.find((a) => a.id === activeAgent) ?? agents[0]\n if (!agent) return\n dock.dock({\n agent: agent.id,\n label: agent.label,\n description: t('catalog.merchandising_assistant.dock.subtitle', 'Catalog'),\n pageContext: pageContext as unknown as Record<string, unknown>,\n placeholder: t(\n 'catalog.merchandising_assistant.sheet.composerPlaceholder',\n 'Ask for descriptions, attributes, titles, or price ideas...',\n ),\n suggestions,\n contextItems,\n welcomeTitle: t(\n 'catalog.merchandising_assistant.sheet.welcomeTitle',\n 'Merchandising Assistant',\n ),\n welcomeDescription: hasSelection\n ? t(\n 'catalog.merchandising_assistant.sheet.welcomeDescriptionSelection',\n 'Ready to work with your {count} selected products. Try one of these:',\n ).replace('{count}', String(selectedCount))\n : t(\n 'catalog.merchandising_assistant.sheet.welcomeDescriptionAll',\n 'Select products for targeted actions, or explore your catalog:',\n ),\n })\n setOpen(false)\n }\n\n const triggerLabel = t(\n 'catalog.merchandising_assistant.trigger.ariaLabel',\n 'Open AI merchandising assistant',\n )\n const labelText = t('catalog.merchandising_assistant.trigger.label', 'AI')\n const moreAgentsLabel = t(\n 'catalog.merchandising_assistant.trigger.moreAgentsAriaLabel',\n 'Choose an AI assistant',\n )\n\n return (\n <>\n <ButtonGroup className={className}>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleMainTriggerClick}\n data-ai-merchandising-trigger=\"\"\n aria-label={triggerLabel}\n title={triggerLabel}\n className=\"relative\"\n >\n <AiIcon className=\"size-4\" />\n <span>{labelText}</span>\n {hasSelection ? (\n <span\n className=\"absolute -top-1 -right-1 inline-flex h-4 min-w-4 items-center justify-center rounded-full bg-primary px-1 text-[10px] font-medium leading-none text-primary-foreground\"\n data-ai-merchandising-selected-count={selectedCount}\n >\n {selectedCount}\n </span>\n ) : null}\n </Button>\n {agents.length > 1 ? (\n <Popover open={popoverOpen} onOpenChange={setPopoverOpen}>\n <PopoverTrigger asChild>\n <IconButton\n type=\"button\"\n variant=\"outline\"\n aria-label={moreAgentsLabel}\n title={moreAgentsLabel}\n data-ai-merchandising-picker=\"\"\n >\n <ChevronDown className=\"size-4\" aria-hidden />\n </IconButton>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"w-72 p-1\">\n <div className=\"px-3 pt-2 pb-1 text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n {t('catalog.merchandising_assistant.popover.heading', 'AI assistants')}\n </div>\n <div className=\"flex flex-col gap-0.5\">\n {agents.map((agent) => (\n <Button\n key={agent.id}\n type=\"button\"\n variant=\"ghost\"\n onClick={() => handleSelectAgent(agent.id)}\n data-ai-merchandising-agent-option={agent.id}\n className=\"h-auto w-full items-start justify-start gap-2 whitespace-normal rounded-sm px-2 py-2 text-left text-sm font-normal\"\n >\n <span className=\"mt-0.5 inline-flex size-6 items-center justify-center rounded-full bg-secondary text-secondary-foreground\">\n {agent.icon}\n </span>\n <span className=\"flex-1 min-w-0\">\n <span className=\"block font-medium leading-tight\">{agent.label}</span>\n <span className=\"block text-xs text-muted-foreground leading-snug\">\n {agent.description}\n </span>\n </span>\n </Button>\n ))}\n </div>\n </PopoverContent>\n </Popover>\n ) : null}\n </ButtonGroup>\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogContent\n className={cn(\n // Mobile: full-screen sheet. Desktop (\u2265sm): right-anchored side sheet.\n // The Dialog primitive applies a centering transform at the\n // sm breakpoint; each piece (`top`, `left`, transform, inset)\n // must be overridden at the same breakpoint or the panel\n // renders half off the viewport.\n 'top-0 left-0 right-0 bottom-0 translate-x-0 translate-y-0 max-w-none w-screen h-svh max-h-svh rounded-none',\n 'sm:top-0 sm:bottom-0 sm:right-0 sm:left-auto sm:translate-x-0 sm:translate-y-0',\n 'sm:max-w-xl sm:w-[36rem] sm:rounded-l-2xl sm:h-screen sm:max-h-screen',\n 'flex flex-col gap-3 p-4 z-[70]',\n )}\n data-ai-merchandising-sheet=\"\"\n >\n <DialogHeader>\n <div className=\"flex items-center gap-3 pr-8\">\n {/* Dock button lives on the LEFT \u2014 the Dialog primitive\n auto-renders an X close button absolutely positioned in\n the top-right corner, so anything we drop in the header's\n right side visually collides with it. Mobile hides the\n dock entirely (the side panel is desktop-only). */}\n <IconButton\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n aria-label={t('catalog.merchandising_assistant.sheet.dock', 'Dock to side')}\n title={t('catalog.merchandising_assistant.sheet.dock', 'Dock to side')}\n onClick={handleDock}\n data-ai-merchandising-dock=\"\"\n className=\"hidden lg:inline-flex shrink-0\"\n >\n <PanelRightOpen className=\"size-4\" aria-hidden />\n </IconButton>\n <DialogTitle className=\"flex-1 min-w-0 truncate\">\n {t('catalog.merchandising_assistant.sheet.title', 'Catalog merchandising assistant')}\n </DialogTitle>\n {hasSelection ? (\n <span\n className=\"shrink-0 inline-flex items-center rounded-full border border-border bg-secondary px-2 py-0.5 text-xs text-secondary-foreground\"\n data-ai-merchandising-selection-pill=\"\"\n data-ai-merchandising-selected-count={selectedCount}\n >\n {t(\n 'catalog.merchandising_assistant.sheet.selectionPill',\n 'Acting on {count} products',\n ).replace('{count}', String(selectedCount))}\n </span>\n ) : null}\n </div>\n <DialogDescription>\n {hasSelection\n ? t(\n 'catalog.merchandising_assistant.sheet.descriptionWithSelection',\n 'Working with {count} selected products. Ask for descriptions, attribute extraction, title suggestions, or pricing analysis.',\n ).replace('{count}', String(selectedCount))\n : t(\n 'catalog.merchandising_assistant.sheet.description',\n 'Your AI merchandising copilot. Select products from the list for targeted actions, or explore your full catalog.',\n )}\n </DialogDescription>\n </DialogHeader>\n <MerchandisingChatBody\n activeAgent={activeAgent}\n pageContext={pageContext}\n suggestions={suggestions}\n contextItems={contextItems}\n hasSelection={hasSelection}\n selectedCount={selectedCount}\n />\n </DialogContent>\n </Dialog>\n </>\n )\n}\n\ninterface MerchandisingChatBodyProps {\n activeAgent: string\n pageContext: MerchandisingPageContext\n suggestions: AiChatSuggestion[]\n contextItems: AiChatContextItem[]\n hasSelection: boolean\n selectedCount: number\n}\n\nfunction MerchandisingChatBody({\n activeAgent,\n pageContext,\n suggestions,\n contextItems,\n hasSelection,\n selectedCount,\n}: MerchandisingChatBodyProps) {\n const t = useT()\n const sessions = useAiChatSessions()\n const session = sessions.getActiveSession(activeAgent)\n\n React.useEffect(() => {\n if (!session) sessions.ensureSession(activeAgent)\n }, [activeAgent, session, sessions])\n\n return (\n <>\n <ChatPaneTabs agentId={activeAgent} className=\"border-b\" />\n <div className=\"min-h-0 flex-1\" data-ai-merchandising-chat-container=\"\">\n {session ? (\n <AiChat\n key={session.id}\n agent={activeAgent}\n conversationId={session.conversationId}\n pageContext={pageContext as unknown as Record<string, unknown>}\n className=\"h-full\"\n placeholder={t(\n 'catalog.merchandising_assistant.sheet.composerPlaceholder',\n 'Ask for descriptions, attributes, titles, or price ideas...',\n )}\n suggestions={suggestions}\n contextItems={contextItems}\n welcomeTitle={t(\n 'catalog.merchandising_assistant.sheet.welcomeTitle',\n 'Merchandising Assistant',\n )}\n welcomeDescription={\n hasSelection\n ? t(\n 'catalog.merchandising_assistant.sheet.welcomeDescriptionSelection',\n 'Ready to work with your {count} selected products. Try one of these:',\n ).replace('{count}', String(selectedCount))\n : t(\n 'catalog.merchandising_assistant.sheet.welcomeDescriptionAll',\n 'Select products for targeted actions, or explore your catalog:',\n )\n }\n />\n ) : null}\n </div>\n </>\n )\n}\n\nexport default MerchandisingAssistantSheet\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -82,7 +82,6 @@ function CategoriesDataTable() {
82
82
  const rows = data?.items ?? [];
83
83
  const total = data?.total ?? 0;
84
84
  const totalPages = data?.totalPages ?? 0;
85
- const totalIsCapped = data?.totalIsCapped === true;
86
85
  const columns = React.useMemo(() => [
87
86
  {
88
87
  accessorKey: "name",
@@ -206,7 +205,6 @@ function CategoriesDataTable() {
206
205
  pageSize: PAGE_SIZE,
207
206
  total,
208
207
  totalPages,
209
- totalIsCapped,
210
208
  onPageChange: setPage
211
209
  },
212
210
  isLoading
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/catalog/components/categories/CategoriesDataTable.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { extensionPoints } from '@open-mercato/core/modules/catalog/extension-points'\nimport Link from 'next/link'\nimport { useQuery, useQueryClient } from '@tanstack/react-query'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { ListEmptyState } from '@open-mercato/ui/backend/filters/ListEmptyState'\nimport type { FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { BooleanIcon } from '@open-mercato/ui/backend/ValueIcons'\nimport { apiCall, apiCallOrThrow, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\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 { formatCategoryTreeLabel } from '../../lib/categoryTree'\n\ntype CategoryRow = {\n id: string\n name: string\n slug: string | null\n description: string | null\n parentId: string | null\n parentName: string | null\n depth: number\n treePath: string\n pathLabel: string\n childCount: number\n descendantCount: number\n isActive: boolean\n}\n\ntype CategoriesResponse = {\n items: CategoryRow[]\n total: number\n page: number\n pageSize: number\n totalPages: number\n totalIsCapped?: boolean\n}\n\nconst PAGE_SIZE = 50\nconst TREE_BASE_INDENT = 18\nconst TREE_STEP_INDENT = 14\n\nfunction computeIndent(depth: number): number {\n if (depth <= 0) return 0\n return TREE_BASE_INDENT + (depth - 1) * TREE_STEP_INDENT\n}\n\nexport default function CategoriesDataTable() {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const queryClient = useQueryClient()\n const scopeVersion = useOrganizationScopeVersion()\n const [page, setPage] = React.useState(1)\n const [status, setStatus] = React.useState<'all' | 'active' | 'inactive'>('all')\n const [search, setSearch] = React.useState('')\n const [canManage, setCanManage] = React.useState(false)\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n try {\n const call = await apiCall<{ granted?: string[]; ok?: boolean }>('/api/auth/feature-check', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ features: ['catalog.categories.manage'] }),\n })\n if (!cancelled) {\n const granted = Array.isArray(call.result?.granted) ? call.result.granted : []\n setCanManage(call.result?.ok === true || granted.includes('catalog.categories.manage'))\n }\n } catch {\n if (!cancelled) setCanManage(false)\n }\n }\n load()\n return () => {\n cancelled = true\n }\n }, [])\n\n const queryParams = React.useMemo(() => {\n const params = new URLSearchParams()\n params.set('view', 'manage')\n params.set('page', String(page))\n params.set('pageSize', String(PAGE_SIZE))\n params.set('status', status)\n if (search) params.set('search', search)\n return params.toString()\n }, [page, status, search])\n\n const { data, isLoading } = useQuery<CategoriesResponse>({\n queryKey: ['catalog-categories', queryParams, scopeVersion],\n queryFn: async () => {\n const payload = await readApiResultOrThrow<CategoriesResponse>(\n `/api/catalog/categories?${queryParams}`,\n undefined,\n { errorMessage: t('catalog.categories.list.error.load', 'Failed to load categories') },\n )\n return {\n items: Array.isArray(payload.items) ? payload.items : [],\n total: typeof payload.total === 'number' ? payload.total : 0,\n page: typeof payload.page === 'number' ? payload.page : 1,\n pageSize: typeof payload.pageSize === 'number' ? payload.pageSize : PAGE_SIZE,\n totalPages: typeof payload.totalPages === 'number' ? payload.totalPages : 1,\n }\n },\n })\n\n const rows = data?.items ?? []\n const total = data?.total ?? 0\n const totalPages = data?.totalPages ?? 0\n const totalIsCapped = data?.totalIsCapped === true\n\n const columns = React.useMemo<ColumnDef<CategoryRow>[]>(() => [\n {\n accessorKey: 'name',\n header: t('catalog.categories.list.columns.category', 'Category'),\n meta: { priority: 1 },\n cell: ({ row }) => {\n const depth = row.original.depth ?? 0\n return (\n <div className=\"flex items-center text-sm font-medium leading-none text-foreground\">\n <span style={{ marginLeft: computeIndent(depth), whiteSpace: 'pre' }}>\n {formatCategoryTreeLabel(row.original.name, depth)}\n </span>\n </div>\n )\n },\n },\n {\n accessorKey: 'pathLabel',\n header: t('catalog.categories.list.columns.path', 'Path'),\n meta: { priority: 3 },\n cell: ({ getValue }) => {\n const value = getValue<string>()\n return <span className=\"text-xs text-muted-foreground\">{value || '\u2014'}</span>\n },\n },\n {\n accessorKey: 'parentName',\n header: t('catalog.categories.list.columns.parent', 'Parent'),\n meta: { priority: 4 },\n cell: ({ getValue }) => getValue<string>() || t('catalog.categories.list.none', '\u2014'),\n },\n {\n accessorKey: 'childCount',\n header: t('catalog.categories.list.columns.children', 'Children'),\n meta: { priority: 5 },\n },\n {\n accessorKey: 'isActive',\n header: t('catalog.categories.list.columns.active', 'Active'),\n enableSorting: false,\n meta: { priority: 2 },\n cell: ({ getValue }) => <BooleanIcon value={Boolean(getValue())} />,\n },\n ], [t])\n\n const handleDelete = React.useCallback(async (category: CategoryRow) => {\n const confirmLabel = t(\n 'catalog.categories.list.confirmDelete',\n 'Archive category \"{{name}}\"?',\n { name: category.name },\n )\n const confirmed = await confirm({\n title: confirmLabel,\n variant: 'destructive',\n })\n if (!confirmed) return\n try {\n // optimistic-lock-exempt: delete-only mutation \u2014 no field-level lost-update\n await apiCallOrThrow(\n `/api/catalog/categories?id=${encodeURIComponent(category.id)}`,\n { method: 'DELETE' },\n { errorMessage: t('catalog.categories.list.error.delete', 'Failed to delete category') },\n )\n await queryClient.invalidateQueries({ queryKey: ['catalog-categories'] })\n flash(t('catalog.categories.flash.deleted', 'Category archived'), 'success')\n } catch (err: unknown) {\n const fallback = t('catalog.categories.list.error.delete', 'Failed to delete category')\n const message = err instanceof Error ? err.message : fallback\n flash(message, 'error')\n }\n }, [confirm, queryClient, t])\n\n return (\n <>\n <DataTable\n title={t('catalog.categories.list.title', 'Categories')}\n actions={canManage ? (\n <Button asChild>\n <Link href=\"/backend/catalog/categories/create\">\n {t('catalog.categories.list.actions.create', 'Create')}\n </Link>\n </Button>\n ) : undefined}\n columns={columns}\n data={rows}\n emptyState={(\n <ListEmptyState\n entityName={t('catalog.categories.list.title', 'Categories')}\n createHref={canManage ? '/backend/catalog/categories/create' : undefined}\n createLabel={canManage ? t('catalog.categories.list.actions.create', 'Create') : undefined}\n />\n )}\n searchValue={search}\n searchPlaceholder={t('catalog.categories.list.searchPlaceholder', 'Search categories')}\n onSearchChange={(value) => { setSearch(value); setPage(1) }}\n filters={[\n {\n id: 'status',\n label: t('catalog.categories.list.filters.status', 'Status'),\n type: 'select',\n options: [\n { value: 'all', label: t('catalog.categories.list.filters.all', 'All') },\n { value: 'active', label: t('catalog.categories.list.filters.active', 'Active') },\n { value: 'inactive', label: t('catalog.categories.list.filters.inactive', 'Inactive') },\n ],\n },\n ]}\n filterValues={status === 'all' ? {} : { status }}\n onFiltersApply={(values: FilterValues) => {\n const nextStatus = (values.status as 'all' | 'active' | 'inactive' | undefined) ?? 'all'\n setStatus(nextStatus)\n setPage(1)\n }}\n onFiltersClear={() => {\n setStatus('all')\n setPage(1)\n }}\n sortable={false}\n perspective={{ tableId: extensionPoints.hosts.categoriesTable.tableId }}\n rowActions={(row) => (\n canManage ? (\n <RowActions\n items={[\n { id: 'edit', label: t('catalog.categories.list.actions.edit', 'Edit'), href: `/backend/catalog/categories/${row.id}/edit` },\n { id: 'delete', label: t('catalog.categories.list.actions.delete', 'Delete'), destructive: true, onSelect: () => handleDelete(row) },\n ]}\n />\n ) : null\n )}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n totalIsCapped,\n onPageChange: setPage,\n }}\n isLoading={isLoading}\n />\n {ConfirmDialogElement}\n </>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { extensionPoints } from '@open-mercato/core/modules/catalog/extension-points'\nimport Link from 'next/link'\nimport { useQuery, useQueryClient } from '@tanstack/react-query'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { ListEmptyState } from '@open-mercato/ui/backend/filters/ListEmptyState'\nimport type { FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { BooleanIcon } from '@open-mercato/ui/backend/ValueIcons'\nimport { apiCall, apiCallOrThrow, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\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 { formatCategoryTreeLabel } from '../../lib/categoryTree'\n\ntype CategoryRow = {\n id: string\n name: string\n slug: string | null\n description: string | null\n parentId: string | null\n parentName: string | null\n depth: number\n treePath: string\n pathLabel: string\n childCount: number\n descendantCount: number\n isActive: boolean\n}\n\ntype CategoriesResponse = {\n items: CategoryRow[]\n total: number\n page: number\n pageSize: number\n totalPages: number\n}\n\nconst PAGE_SIZE = 50\nconst TREE_BASE_INDENT = 18\nconst TREE_STEP_INDENT = 14\n\nfunction computeIndent(depth: number): number {\n if (depth <= 0) return 0\n return TREE_BASE_INDENT + (depth - 1) * TREE_STEP_INDENT\n}\n\nexport default function CategoriesDataTable() {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const queryClient = useQueryClient()\n const scopeVersion = useOrganizationScopeVersion()\n const [page, setPage] = React.useState(1)\n const [status, setStatus] = React.useState<'all' | 'active' | 'inactive'>('all')\n const [search, setSearch] = React.useState('')\n const [canManage, setCanManage] = React.useState(false)\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n try {\n const call = await apiCall<{ granted?: string[]; ok?: boolean }>('/api/auth/feature-check', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ features: ['catalog.categories.manage'] }),\n })\n if (!cancelled) {\n const granted = Array.isArray(call.result?.granted) ? call.result.granted : []\n setCanManage(call.result?.ok === true || granted.includes('catalog.categories.manage'))\n }\n } catch {\n if (!cancelled) setCanManage(false)\n }\n }\n load()\n return () => {\n cancelled = true\n }\n }, [])\n\n const queryParams = React.useMemo(() => {\n const params = new URLSearchParams()\n params.set('view', 'manage')\n params.set('page', String(page))\n params.set('pageSize', String(PAGE_SIZE))\n params.set('status', status)\n if (search) params.set('search', search)\n return params.toString()\n }, [page, status, search])\n\n const { data, isLoading } = useQuery<CategoriesResponse>({\n queryKey: ['catalog-categories', queryParams, scopeVersion],\n queryFn: async () => {\n const payload = await readApiResultOrThrow<CategoriesResponse>(\n `/api/catalog/categories?${queryParams}`,\n undefined,\n { errorMessage: t('catalog.categories.list.error.load', 'Failed to load categories') },\n )\n return {\n items: Array.isArray(payload.items) ? payload.items : [],\n total: typeof payload.total === 'number' ? payload.total : 0,\n page: typeof payload.page === 'number' ? payload.page : 1,\n pageSize: typeof payload.pageSize === 'number' ? payload.pageSize : PAGE_SIZE,\n totalPages: typeof payload.totalPages === 'number' ? payload.totalPages : 1,\n }\n },\n })\n\n const rows = data?.items ?? []\n const total = data?.total ?? 0\n const totalPages = data?.totalPages ?? 0\n\n const columns = React.useMemo<ColumnDef<CategoryRow>[]>(() => [\n {\n accessorKey: 'name',\n header: t('catalog.categories.list.columns.category', 'Category'),\n meta: { priority: 1 },\n cell: ({ row }) => {\n const depth = row.original.depth ?? 0\n return (\n <div className=\"flex items-center text-sm font-medium leading-none text-foreground\">\n <span style={{ marginLeft: computeIndent(depth), whiteSpace: 'pre' }}>\n {formatCategoryTreeLabel(row.original.name, depth)}\n </span>\n </div>\n )\n },\n },\n {\n accessorKey: 'pathLabel',\n header: t('catalog.categories.list.columns.path', 'Path'),\n meta: { priority: 3 },\n cell: ({ getValue }) => {\n const value = getValue<string>()\n return <span className=\"text-xs text-muted-foreground\">{value || '\u2014'}</span>\n },\n },\n {\n accessorKey: 'parentName',\n header: t('catalog.categories.list.columns.parent', 'Parent'),\n meta: { priority: 4 },\n cell: ({ getValue }) => getValue<string>() || t('catalog.categories.list.none', '\u2014'),\n },\n {\n accessorKey: 'childCount',\n header: t('catalog.categories.list.columns.children', 'Children'),\n meta: { priority: 5 },\n },\n {\n accessorKey: 'isActive',\n header: t('catalog.categories.list.columns.active', 'Active'),\n enableSorting: false,\n meta: { priority: 2 },\n cell: ({ getValue }) => <BooleanIcon value={Boolean(getValue())} />,\n },\n ], [t])\n\n const handleDelete = React.useCallback(async (category: CategoryRow) => {\n const confirmLabel = t(\n 'catalog.categories.list.confirmDelete',\n 'Archive category \"{{name}}\"?',\n { name: category.name },\n )\n const confirmed = await confirm({\n title: confirmLabel,\n variant: 'destructive',\n })\n if (!confirmed) return\n try {\n // optimistic-lock-exempt: delete-only mutation \u2014 no field-level lost-update\n await apiCallOrThrow(\n `/api/catalog/categories?id=${encodeURIComponent(category.id)}`,\n { method: 'DELETE' },\n { errorMessage: t('catalog.categories.list.error.delete', 'Failed to delete category') },\n )\n await queryClient.invalidateQueries({ queryKey: ['catalog-categories'] })\n flash(t('catalog.categories.flash.deleted', 'Category archived'), 'success')\n } catch (err: unknown) {\n const fallback = t('catalog.categories.list.error.delete', 'Failed to delete category')\n const message = err instanceof Error ? err.message : fallback\n flash(message, 'error')\n }\n }, [confirm, queryClient, t])\n\n return (\n <>\n <DataTable\n title={t('catalog.categories.list.title', 'Categories')}\n actions={canManage ? (\n <Button asChild>\n <Link href=\"/backend/catalog/categories/create\">\n {t('catalog.categories.list.actions.create', 'Create')}\n </Link>\n </Button>\n ) : undefined}\n columns={columns}\n data={rows}\n emptyState={(\n <ListEmptyState\n entityName={t('catalog.categories.list.title', 'Categories')}\n createHref={canManage ? '/backend/catalog/categories/create' : undefined}\n createLabel={canManage ? t('catalog.categories.list.actions.create', 'Create') : undefined}\n />\n )}\n searchValue={search}\n searchPlaceholder={t('catalog.categories.list.searchPlaceholder', 'Search categories')}\n onSearchChange={(value) => { setSearch(value); setPage(1) }}\n filters={[\n {\n id: 'status',\n label: t('catalog.categories.list.filters.status', 'Status'),\n type: 'select',\n options: [\n { value: 'all', label: t('catalog.categories.list.filters.all', 'All') },\n { value: 'active', label: t('catalog.categories.list.filters.active', 'Active') },\n { value: 'inactive', label: t('catalog.categories.list.filters.inactive', 'Inactive') },\n ],\n },\n ]}\n filterValues={status === 'all' ? {} : { status }}\n onFiltersApply={(values: FilterValues) => {\n const nextStatus = (values.status as 'all' | 'active' | 'inactive' | undefined) ?? 'all'\n setStatus(nextStatus)\n setPage(1)\n }}\n onFiltersClear={() => {\n setStatus('all')\n setPage(1)\n }}\n sortable={false}\n perspective={{ tableId: extensionPoints.hosts.categoriesTable.tableId }}\n rowActions={(row) => (\n canManage ? (\n <RowActions\n items={[\n { id: 'edit', label: t('catalog.categories.list.actions.edit', 'Edit'), href: `/backend/catalog/categories/${row.id}/edit` },\n { id: 'delete', label: t('catalog.categories.list.actions.delete', 'Delete'), destructive: true, onSelect: () => handleDelete(row) },\n ]}\n />\n ) : null\n )}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n onPageChange: setPage,\n }}\n isLoading={isLoading}\n />\n {ConfirmDialogElement}\n </>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -74,7 +74,6 @@ function ProductsDataTable({
74
74
  const [page, setPage] = React.useState(1);
75
75
  const [total, setTotal] = React.useState(0);
76
76
  const [totalPages, setTotalPages] = React.useState(1);
77
- const [totalIsCapped, setTotalIsCapped] = React.useState(false);
78
77
  const [cacheStatus, setCacheStatus] = React.useState(null);
79
78
  const [sorting, setSorting] = React.useState([{ id: "title", desc: false }]);
80
79
  const [search, setSearch] = React.useState("");
@@ -446,7 +445,6 @@ function ProductsDataTable({
446
445
  setRows(normalized);
447
446
  setTotal(typeof payload.total === "number" ? payload.total : normalized.length);
448
447
  setTotalPages(typeof payload.totalPages === "number" ? payload.totalPages : 1);
449
- setTotalIsCapped(payload.totalIsCapped === true);
450
448
  } catch (error) {
451
449
  if (!cancelled) {
452
450
  setCacheStatus(null);
@@ -541,17 +539,13 @@ function ProductsDataTable({
541
539
  // a selection-aware pageContext per spec §10.1 without taking a
542
540
  // dependency on the host page.
543
541
  total,
544
- totalMatching: total,
545
- // `total` is a floor when the server capped the count, so the
546
- // merchandising widget must not present it as an exact match count.
547
- totalIsCapped
542
+ totalMatching: total
548
543
  },
549
544
  pagination: {
550
545
  page,
551
546
  pageSize: PAGE_SIZE,
552
547
  total,
553
548
  totalPages,
554
- totalIsCapped,
555
549
  onPageChange: setPage,
556
550
  cacheStatus
557
551
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/catalog/components/products/ProductsDataTable.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { extensionPoints } from '@open-mercato/core/modules/catalog/extension-points'\nimport Link from 'next/link'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport type { SortingState } from '@tanstack/react-table'\nimport { DataTable, type DataTableExportFormat } from '@open-mercato/ui/backend/DataTable'\nimport { ListEmptyState } from '@open-mercato/ui/backend/filters/ListEmptyState'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { apiCall, readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { deleteCrud, buildCrudExportUrl } from '@open-mercato/ui/backend/utils/crud'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { useCustomFieldDefs } from '@open-mercato/ui/backend/utils/customFieldDefs'\nimport { applyCustomFieldVisibility } from '@open-mercato/ui/backend/utils/customFieldColumns'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport type { FilterOption } from '@open-mercato/ui/backend/FilterOverlay'\nimport { BooleanIcon } from '@open-mercato/ui/backend/ValueIcons'\nimport { markdownToPlainText } from '@open-mercato/ui/backend/markdown/markdownToPlainText'\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 { useAppEvent } from '@open-mercato/ui/backend/injection/useAppEvent'\nimport { E } from '#generated/entities.ids.generated'\nimport { ProductImageCell } from './ProductImageCell'\n\ntype PricingScope = {\n variant_id?: string | null\n offer_id?: string | null\n channel_id?: string | null\n user_id?: string | null\n user_group_id?: string | null\n customer_id?: string | null\n customer_group_id?: string | null\n}\n\ntype PricingInfo = {\n kind?: string | null\n price_kind_id?: string | null\n price_kind_code?: string | null\n currency_code?: string | null\n unit_price_net?: string | null\n unit_price_gross?: string | null\n min_quantity?: number | null\n max_quantity?: number | null\n tax_rate?: string | null\n scope?: PricingScope | null\n} | null\n\ntype OfferInfo = {\n id: string\n channelId: string\n channelName?: string | null\n channelCode?: string | null\n title: string\n description?: string | null\n isActive: boolean\n}\n\nexport type ProductRow = {\n id: string\n title: string\n subtitle?: string | null\n description?: string | null\n sku?: string | null\n handle?: string | null\n product_type?: string | null\n status_entry_id?: string | null\n primary_currency_code?: string | null\n default_unit?: string | null\n default_media_id?: string | null\n default_media_url?: string | null\n is_configurable?: boolean\n is_active?: boolean\n metadata?: Record<string, unknown> | null\n custom_fieldset_code?: string | null\n created_at?: string\n updated_at?: string\n offers?: OfferInfo[]\n pricing?: PricingInfo\n} & Record<string, unknown>\n\ntype ProductsResponse = {\n items?: ProductRow[]\n total?: number\n totalPages?: number\n totalIsCapped?: boolean\n}\n\nconst PAGE_SIZE = 25\nconst ENTITY_ID = E.catalog.catalog_product\n\nfunction formatDate(value?: string): string {\n if (!value) return '\u2014'\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return '\u2014'\n return date.toLocaleDateString()\n}\n\nfunction renderOffers(offers: OfferInfo[] | undefined): React.ReactNode {\n if (!offers || offers.length === 0) return <span className=\"text-xs text-muted-foreground\">\u2014</span>\n const visible = offers.slice(0, 3)\n return (\n <div className=\"flex flex-wrap gap-1\">\n {visible.map((offer) => {\n const label =\n typeof offer.channelName === 'string' && offer.channelName.trim().length\n ? offer.channelName.trim()\n : typeof offer.title === 'string' && offer.title.trim().length\n ? offer.title.trim()\n : offer.channelId\n const badgeTitle =\n typeof offer.channelCode === 'string' && offer.channelCode.trim().length ? offer.channelCode : undefined\n return (\n <span\n key={offer.id}\n className={`inline-flex items-center rounded-full border px-2 py-0.5 text-xs ${\n offer.isActive ? 'bg-secondary/80 text-secondary-foreground' : 'bg-muted text-muted-foreground'\n }`}\n title={badgeTitle}\n >\n {label}\n </span>\n )\n })}\n {offers.length > visible.length ? (\n <span className=\"text-xs text-muted-foreground\">+{offers.length - visible.length}</span>\n ) : null}\n </div>\n )\n}\n\nfunction renderPrice(pricing: PricingInfo | undefined, currency?: string | null, fallback = '\u2014'): React.ReactNode {\n if (!pricing) return <span className=\"text-xs text-muted-foreground\">{fallback}</span>\n const unit = pricing.unit_price_net ?? pricing.unit_price_gross\n if (unit == null) return <span className=\"text-xs text-muted-foreground\">{fallback}</span>\n const formatted = `${currency ?? pricing.currency_code ?? ''} ${unit}`\n const kind = pricing.kind ?? 'list'\n return (\n <div className=\"flex flex-col\">\n <span className=\"font-medium\">{formatted.trim()}</span>\n <span className=\"text-xs text-muted-foreground\">{kind}</span>\n </div>\n )\n}\n\nexport type ProductsDataTableSnapshot = {\n search: string\n filterValues: FilterValues\n total: number\n}\n\nexport type ProductsDataTableProps = {\n /**\n * Extra actions rendered alongside the built-in Create button in the\n * DataTable header. Used by the Step 4.9 AI merchandising sheet\n * trigger without coupling DataTable to the AI module.\n */\n extraActions?: React.ReactNode\n /**\n * Optional callback invoked whenever the table's search / filter /\n * total-matching snapshot changes. Used by the Step 4.9 AI merchandising\n * sheet to form a selection-aware pageContext per spec \u00A710.1.\n */\n onSnapshotChange?: (snapshot: ProductsDataTableSnapshot) => void\n}\n\nexport default function ProductsDataTable({\n extraActions,\n onSnapshotChange,\n}: ProductsDataTableProps = {}) {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const scopeVersion = useOrganizationScopeVersion()\n const [rows, setRows] = React.useState<ProductRow[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [totalIsCapped, setTotalIsCapped] = React.useState(false)\n const [cacheStatus, setCacheStatus] = React.useState<'hit' | 'miss' | null>(null)\n const [sorting, setSorting] = React.useState<SortingState>([{ id: 'title', desc: false }])\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [isLoading, setIsLoading] = React.useState(false)\n const [reloadToken, setReloadToken] = React.useState(0)\n // Step 5.18 (spec \u00A710 line 836, D18 demo): refresh the list when a\n // catalog.product.* event arrives via the DOM event bridge. Confirmed\n // AI bulk mutations (one `ai.action.confirmed` + one\n // `catalog.product.updated` per record) and direct API writes both\n // surface here so the table reflects the new state without a manual\n // reload.\n useAppEvent('catalog.product.*', () => {\n setReloadToken((token) => token + 1)\n })\n const [customFieldsetFilter, setCustomFieldsetFilter] = React.useState<string | null>(null)\n const { data: customFieldDefs = [] } = useCustomFieldDefs(ENTITY_ID, {\n keyExtras: [scopeVersion, reloadToken],\n })\n const [channelOptionsCache, setChannelOptionsCache] = React.useState<Record<string, FilterOption>>({})\n const [categoryOptionsCache, setCategoryOptionsCache] = React.useState<Record<string, FilterOption>>({})\n const [tagOptionsCache, setTagOptionsCache] = React.useState<Record<string, FilterOption>>({})\n\n const registerOptions = React.useCallback(\n (\n setter: React.Dispatch<React.SetStateAction<Record<string, FilterOption>>>,\n options: FilterOption[]\n ) => {\n setter((prev) => {\n const next = { ...prev }\n options.forEach((opt) => {\n if (opt.value) next[opt.value] = opt\n })\n return next\n })\n },\n []\n )\n\n const registerChannelOptions = React.useCallback(\n (options: FilterOption[]) => registerOptions(setChannelOptionsCache, options),\n [registerOptions]\n )\n const registerCategoryOptions = React.useCallback(\n (options: FilterOption[]) => registerOptions(setCategoryOptionsCache, options),\n [registerOptions]\n )\n const registerTagOptions = React.useCallback(\n (options: FilterOption[]) => registerOptions(setTagOptionsCache, options),\n [registerOptions]\n )\n\n const channelOptions = React.useMemo(() => Object.values(channelOptionsCache), [channelOptionsCache])\n const categoryOptions = React.useMemo(() => Object.values(categoryOptionsCache), [categoryOptionsCache])\n const tagOptions = React.useMemo(() => Object.values(tagOptionsCache), [tagOptionsCache])\n\n const loadChannelOptions = React.useCallback(\n async (term?: string): Promise<FilterOption[]> => {\n try {\n const params = new URLSearchParams({ pageSize: '100', isActive: 'true' })\n if (term && term.trim().length) params.set('search', term.trim())\n const payload = await readApiResultOrThrow<{ items?: Array<{ id?: string; name?: string; code?: string }> }>(\n `/api/sales/channels?${params.toString()}`,\n undefined,\n { errorMessage: t('catalog.products.filters.channelsLoadError', 'Failed to load channels') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options = items\n .map((entry) => {\n const value = typeof entry.id === 'string' ? entry.id : null\n if (!value) return null\n const label =\n typeof entry.name === 'string'\n ? entry.name\n : typeof entry.code === 'string'\n ? entry.code\n : value\n return { value, label, description: typeof entry.code === 'string' ? entry.code : undefined }\n })\n .filter((option) => !!option) as FilterOption[]\n registerChannelOptions(options)\n return options\n } catch {\n return []\n }\n },\n [registerChannelOptions, t],\n )\n\n const loadCategoryOptions = React.useCallback(\n async (term?: string): Promise<FilterOption[]> => {\n try {\n const params = new URLSearchParams({ pageSize: '200', view: 'manage' })\n if (term && term.trim().length) params.set('search', term.trim())\n const payload = await readApiResultOrThrow<{ items?: Array<{ id?: string; name?: string; parentName?: string | null }> }>(\n `/api/catalog/categories?${params.toString()}`,\n undefined,\n { errorMessage: t('catalog.products.filters.categoriesLoadError', 'Failed to load categories') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options = items\n .map((entry) => {\n const value = typeof entry.id === 'string' ? entry.id : null\n if (!value) return null\n const label = typeof entry.name === 'string' && entry.name.trim().length ? entry.name : value\n const description =\n typeof entry.parentName === 'string' && entry.parentName.trim().length ? entry.parentName : null\n return { value, label, description }\n })\n .filter((option) => !!option) as FilterOption[]\n registerCategoryOptions(options)\n return options\n } catch {\n return []\n }\n },\n [registerCategoryOptions, t],\n )\n\n const loadTagOptions = React.useCallback(\n async (term?: string): Promise<FilterOption[]> => {\n try {\n const params = new URLSearchParams({ pageSize: '100' })\n if (term && term.trim().length) params.set('search', term.trim())\n const payload = await readApiResultOrThrow<{ items?: Array<{ id?: string; label?: string }> }>(\n `/api/catalog/tags?${params.toString()}`,\n undefined,\n { errorMessage: t('catalog.products.filters.tagsLoadError', 'Failed to load tags') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options = items\n .map((entry) => {\n const value = typeof entry.id === 'string' ? entry.id : null\n if (!value) return null\n const label = typeof entry.label === 'string' && entry.label.trim().length ? entry.label : value\n return { value, label }\n })\n .filter((option) => !!option) as FilterOption[]\n registerTagOptions(options)\n return options\n } catch {\n return []\n }\n },\n [registerTagOptions, t],\n )\n\n const productTypeOptions = React.useMemo<FilterOption[]>(() => [\n { value: 'simple', label: t('catalog.products.types.simple', 'Simple') },\n { value: 'configurable', label: t('catalog.products.types.configurable', 'Configurable') },\n { value: 'virtual', label: t('catalog.products.types.virtual', 'Virtual') },\n { value: 'downloadable', label: t('catalog.products.types.downloadable', 'Downloadable') },\n {\n value: 'bundle',\n label: `${t('catalog.products.types.bundle', 'Bundle')} (${t('common.comingSoon', 'Coming soon')})`,\n },\n {\n value: 'grouped',\n label: `${t('catalog.products.types.grouped', 'Grouped')} (${t('common.comingSoon', 'Coming soon')})`,\n },\n ], [t])\n\n const productTypeLabelMap = React.useMemo(() => {\n const map = new Map<string, string>()\n productTypeOptions.forEach((opt) => map.set(opt.value, opt.label))\n return map\n }, [productTypeOptions])\n\n const filters = React.useMemo<FilterDef[]>(() => [\n { id: 'status', label: t('catalog.products.filters.status'), type: 'text' },\n { id: 'isActive', label: t('catalog.products.filters.active'), type: 'checkbox' },\n { id: 'configurable', label: t('catalog.products.filters.configurable'), type: 'checkbox' },\n { id: 'productType', label: t('catalog.products.filters.productType', 'Type'), type: 'select', options: productTypeOptions },\n {\n id: 'channelIds',\n label: t('catalog.products.filters.channels'),\n type: 'tags',\n loadOptions: loadChannelOptions,\n options: channelOptions,\n formatValue: (val) => channelOptionsCache[val]?.label ?? val,\n formatDescription: (val) => channelOptionsCache[val]?.description ?? null,\n },\n {\n id: 'categoryIds',\n label: t('catalog.products.filters.categories', 'Categories'),\n type: 'tags',\n loadOptions: loadCategoryOptions,\n options: categoryOptions,\n formatValue: (val) => categoryOptionsCache[val]?.label ?? val,\n formatDescription: (val) => categoryOptionsCache[val]?.description ?? null,\n },\n {\n id: 'tagIds',\n label: t('catalog.products.filters.tags', 'Tags'),\n type: 'tags',\n loadOptions: loadTagOptions,\n options: tagOptions,\n formatValue: (val) => tagOptionsCache[val]?.label ?? val,\n },\n ], [\n categoryOptions,\n categoryOptionsCache,\n channelOptions,\n channelOptionsCache,\n loadCategoryOptions,\n loadChannelOptions,\n loadTagOptions,\n productTypeOptions,\n tagOptions,\n tagOptionsCache,\n t,\n ])\n\n const columns = React.useMemo<ColumnDef<ProductRow>[]>(() => {\n const base: ColumnDef<ProductRow>[] = [\n {\n id: 'media',\n header: '',\n size: 80,\n cell: ({ row }) => (\n <ProductImageCell\n mediaId={row.original.default_media_id}\n mediaUrl={row.original.default_media_url}\n title={row.original.title}\n cropType=\"contain\"\n />\n ),\n meta: { sticky: true },\n },\n {\n accessorKey: 'title',\n header: t('catalog.products.table.title', 'Title'),\n cell: ({ row }) => (\n <div className=\"flex flex-col\">\n <span className=\"font-medium\">{row.original.title || '\u2014'}</span>\n {row.original.subtitle ? (\n <span className=\"text-xs text-muted-foreground\">{row.original.subtitle}</span>\n ) : null}\n {row.original.handle ? (\n <span className=\"text-xs text-muted-foreground\">/{row.original.handle}</span>\n ) : null}\n {row.original.description ? (\n <span className=\"text-xs text-muted-foreground\">{markdownToPlainText(row.original.description)}</span>\n ) : null}\n </div>\n ),\n meta: { sticky: true },\n },\n {\n accessorKey: 'sku',\n header: t('catalog.products.table.sku', 'SKU'),\n cell: ({ getValue }) => {\n const value = getValue()\n return value ? <span className=\"font-mono text-xs\">{String(value)}</span> : <span className=\"text-xs text-muted-foreground\">\u2014</span>\n },\n },\n {\n accessorKey: 'product_type',\n header: t('catalog.products.table.type'),\n cell: ({ row }) => {\n const type = typeof row.original.product_type === 'string' ? row.original.product_type : 'simple'\n const label = productTypeLabelMap.get(type) ?? type\n return <span className=\"text-xs text-muted-foreground\">{label}</span>\n },\n },\n {\n accessorKey: 'is_configurable',\n header: t('catalog.products.table.configurable'),\n cell: ({ row }) => <BooleanIcon value={!!row.original.is_configurable} />,\n },\n {\n accessorKey: 'is_active',\n header: t('catalog.products.table.active'),\n cell: ({ row }) => <BooleanIcon value={!!row.original.is_active} />,\n },\n {\n accessorKey: 'pricing',\n header: t('catalog.products.table.price'),\n cell: ({ row }) => renderPrice(row.original.pricing, row.original.primary_currency_code),\n },\n {\n accessorKey: 'offers',\n header: t('catalog.products.table.channels'),\n cell: ({ row }) => renderOffers(row.original.offers),\n },\n {\n accessorKey: 'updated_at',\n header: t('catalog.products.table.updatedAt'),\n cell: ({ row }) => <span className=\"text-xs text-muted-foreground\">{formatDate(row.original.updated_at)}</span>,\n },\n ]\n return applyCustomFieldVisibility(base, customFieldDefs)\n }, [customFieldDefs, productTypeLabelMap, t])\n\n const handleSearchChange = React.useCallback((value: string) => {\n setSearch(value)\n setPage(1)\n }, [])\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n setFilterValues(values)\n setPage(1)\n }, [])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({})\n setPage(1)\n }, [])\n\n const handleCustomFieldsetFilterChange = React.useCallback(\n (value: string | null) => {\n if (value === customFieldsetFilter) return\n setCustomFieldsetFilter(value)\n setFilterValues((prev) => {\n const entries = Object.entries(prev)\n if (!entries.some(([key]) => key.startsWith('cf_'))) return prev\n const next: FilterValues = {}\n entries.forEach(([key, val]) => {\n if (!key.startsWith('cf_')) next[key] = val\n })\n return next\n })\n setPage(1)\n },\n [customFieldsetFilter],\n )\n\n const handleRefresh = React.useCallback(() => {\n setReloadToken((token) => token + 1)\n }, [])\n\n const queryParams = React.useMemo(() => {\n const params = new URLSearchParams()\n params.set('page', String(page))\n params.set('pageSize', String(PAGE_SIZE))\n if (search.trim()) params.set('search', search.trim())\n const sort = sorting[0]\n if (sort?.id) {\n params.set('sortField', sort.id)\n params.set('sortDir', sort.desc ? 'desc' : 'asc')\n }\n const status = filterValues.status\n if (typeof status === 'string' && status.trim()) {\n params.set('status', status.trim())\n }\n if (filterValues.isActive === true) params.set('isActive', 'true')\n if (filterValues.isActive === false) params.set('isActive', 'false')\n if (filterValues.configurable === true) params.set('configurable', 'true')\n if (filterValues.configurable === false) params.set('configurable', 'false')\n if (typeof filterValues.productType === 'string' && filterValues.productType.trim()) {\n params.set('productType', filterValues.productType.trim())\n }\n if (Array.isArray(filterValues.channelIds) && filterValues.channelIds.length) {\n const values = filterValues.channelIds\n .map((value) => (typeof value === 'string' ? value : null))\n .filter((value): value is string => !!value)\n if (values.length) params.set('channelIds', values.join(','))\n }\n if (Array.isArray(filterValues.categoryIds) && filterValues.categoryIds.length) {\n const values = filterValues.categoryIds\n .map((value) => (typeof value === 'string' ? value : null))\n .filter((value): value is string => !!value)\n if (values.length) params.set('categoryIds', values.join(','))\n }\n if (Array.isArray(filterValues.tagIds) && filterValues.tagIds.length) {\n const values = filterValues.tagIds\n .map((value) => (typeof value === 'string' ? value : null))\n .filter((value): value is string => !!value)\n if (values.length) params.set('tagIds', values.join(','))\n }\n Object.entries(filterValues).forEach(([key, value]) => {\n if (!key.startsWith('cf_') || value == null) return\n if (Array.isArray(value)) {\n const entries = value\n .map((entry) => (typeof entry === 'string' ? entry.trim() : String(entry || '').trim()))\n .filter((entry) => entry.length > 0)\n if (entries.length) params.set(key, entries.join(','))\n } else if (typeof value === 'object' && value !== null && ('from' in (value as Record<string, unknown>) || 'to' in (value as Record<string, unknown>))) {\n const range = value as { from?: string; to?: string }\n if (typeof range.from === 'string' && range.from.trim().length) {\n params.set(`${key}:from`, range.from.trim())\n }\n if (typeof range.to === 'string' && range.to.trim().length) {\n params.set(`${key}:to`, range.to.trim())\n }\n } else if (typeof value === 'string' && value.trim()) {\n params.set(key, value.trim())\n }\n })\n if (typeof customFieldsetFilter === 'string' && customFieldsetFilter.trim().length > 0) {\n params.set('customFieldset', customFieldsetFilter.trim())\n }\n return params.toString()\n }, [customFieldsetFilter, filterValues, page, search, sorting])\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setIsLoading(true)\n setCacheStatus(null)\n try {\n const fallback: ProductsResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<ProductsResponse>(\n `/api/catalog/products?${queryParams}`,\n undefined,\n { fallback },\n )\n if (!call.ok) {\n const message = t('catalog.products.list.error.load', 'Failed to load products')\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 normalized = items.filter((item): item is ProductRow => typeof item?.id === 'string')\n setRows(normalized)\n setTotal(typeof payload.total === 'number' ? payload.total : normalized.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : 1)\n setTotalIsCapped(payload.totalIsCapped === true)\n } catch (error) {\n if (!cancelled) {\n setCacheStatus(null)\n const message =\n error instanceof Error\n ? error.message\n : t('catalog.products.list.error.load', 'Failed to load products')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n load()\n return () => {\n cancelled = true\n }\n }, [queryParams, reloadToken, scopeVersion, t])\n\n const handleDelete = React.useCallback(async (row: ProductRow) => {\n const confirmed = await confirm({\n title: t('catalog.products.list.deleteConfirm', 'Delete this product?'),\n variant: 'destructive',\n })\n if (!confirmed) return\n try {\n const headers = buildOptimisticLockHeader(typeof row.updated_at === 'string' ? row.updated_at : null)\n await withScopedApiRequestHeaders(headers, () => (\n deleteCrud('catalog/products', row.id, {\n errorMessage: t('catalog.products.list.error.delete', 'Failed to delete product'),\n })\n ))\n flash(t('catalog.products.flash.deleted', 'Product deleted'), 'success')\n setReloadToken((token) => token + 1)\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : t('catalog.products.list.error.delete', 'Failed to delete product')\n flash(message, 'error')\n }\n }, [confirm, t])\n\n React.useEffect(() => {\n if (!onSnapshotChange) return\n onSnapshotChange({ search, filterValues, total })\n }, [onSnapshotChange, search, filterValues, total])\n\n const currentParams = React.useMemo(() => Object.fromEntries(new URLSearchParams(queryParams)), [queryParams])\n\n const exportConfig = React.useMemo(() => ({\n view: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('catalog/products', { ...currentParams, exportScope: 'view' }, format),\n },\n full: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('catalog/products', { ...currentParams, exportScope: 'full', all: 'true' }, format),\n },\n }), [currentParams])\n\n return (\n <>\n <DataTable<ProductRow>\n title={t('catalog.products.page.title', 'Products & services')}\n entityId={ENTITY_ID}\n customFieldFilterKeyExtras={[scopeVersion, reloadToken]}\n refreshButton={{\n label: t('catalog.products.actions.refresh', 'Refresh'),\n onRefresh: handleRefresh,\n isRefreshing: isLoading,\n }}\n actions={(\n <div className=\"flex items-center gap-2\">\n {extraActions}\n <Button asChild>\n <Link href=\"/backend/catalog/products/create\">\n {t('catalog.products.actions.create', 'Create')}\n </Link>\n </Button>\n </div>\n )}\n columns={columns}\n data={rows}\n emptyState={(\n <ListEmptyState\n entityName={t('catalog.products.page.title', 'Products & services')}\n createHref=\"/backend/catalog/products/create\"\n createLabel={t('catalog.products.actions.create', 'Create')}\n />\n )}\n searchValue={search}\n onSearchChange={handleSearchChange}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n onCustomFieldFilterFieldsetChange={handleCustomFieldsetFilterChange}\n sorting={sorting}\n onSortingChange={setSorting}\n injectionSpotId={extensionPoints.hosts.productsTable.baseSpotId}\n injectionContext={{\n search,\n filters: filterValues,\n customFieldset: customFieldsetFilter,\n page,\n sorting,\n scopeVersion,\n // Step 5.15: surface `total` so the merchandising AI widget\n // (rendered in `data-table:catalog.products:header`) can build\n // a selection-aware pageContext per spec \u00A710.1 without taking a\n // dependency on the host page.\n total,\n totalMatching: total,\n // `total` is a floor when the server capped the count, so the\n // merchandising widget must not present it as an exact match count.\n totalIsCapped,\n }}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n totalIsCapped,\n onPageChange: setPage,\n cacheStatus,\n }}\n exporter={exportConfig}\n isLoading={isLoading}\n perspective={{ tableId: extensionPoints.hosts.productsTable.tableId }}\n stickyActionsColumn\n rowActions={(row) => (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('catalog.products.table.actions.edit', 'Edit'),\n href: `/backend/catalog/products/${row.id}`,\n },\n {\n id: 'delete',\n label: t('catalog.products.table.actions.delete', 'Delete'),\n destructive: true,\n onSelect: () => {\n void handleDelete(row)\n },\n },\n ]}\n />\n )}\n />\n {ConfirmDialogElement}\n </>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { extensionPoints } from '@open-mercato/core/modules/catalog/extension-points'\nimport Link from 'next/link'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport type { SortingState } from '@tanstack/react-table'\nimport { DataTable, type DataTableExportFormat } from '@open-mercato/ui/backend/DataTable'\nimport { ListEmptyState } from '@open-mercato/ui/backend/filters/ListEmptyState'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { apiCall, readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { deleteCrud, buildCrudExportUrl } from '@open-mercato/ui/backend/utils/crud'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { useCustomFieldDefs } from '@open-mercato/ui/backend/utils/customFieldDefs'\nimport { applyCustomFieldVisibility } from '@open-mercato/ui/backend/utils/customFieldColumns'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport type { FilterOption } from '@open-mercato/ui/backend/FilterOverlay'\nimport { BooleanIcon } from '@open-mercato/ui/backend/ValueIcons'\nimport { markdownToPlainText } from '@open-mercato/ui/backend/markdown/markdownToPlainText'\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 { useAppEvent } from '@open-mercato/ui/backend/injection/useAppEvent'\nimport { E } from '#generated/entities.ids.generated'\nimport { ProductImageCell } from './ProductImageCell'\n\ntype PricingScope = {\n variant_id?: string | null\n offer_id?: string | null\n channel_id?: string | null\n user_id?: string | null\n user_group_id?: string | null\n customer_id?: string | null\n customer_group_id?: string | null\n}\n\ntype PricingInfo = {\n kind?: string | null\n price_kind_id?: string | null\n price_kind_code?: string | null\n currency_code?: string | null\n unit_price_net?: string | null\n unit_price_gross?: string | null\n min_quantity?: number | null\n max_quantity?: number | null\n tax_rate?: string | null\n scope?: PricingScope | null\n} | null\n\ntype OfferInfo = {\n id: string\n channelId: string\n channelName?: string | null\n channelCode?: string | null\n title: string\n description?: string | null\n isActive: boolean\n}\n\nexport type ProductRow = {\n id: string\n title: string\n subtitle?: string | null\n description?: string | null\n sku?: string | null\n handle?: string | null\n product_type?: string | null\n status_entry_id?: string | null\n primary_currency_code?: string | null\n default_unit?: string | null\n default_media_id?: string | null\n default_media_url?: string | null\n is_configurable?: boolean\n is_active?: boolean\n metadata?: Record<string, unknown> | null\n custom_fieldset_code?: string | null\n created_at?: string\n updated_at?: string\n offers?: OfferInfo[]\n pricing?: PricingInfo\n} & Record<string, unknown>\n\ntype ProductsResponse = {\n items?: ProductRow[]\n total?: number\n totalPages?: number\n}\n\nconst PAGE_SIZE = 25\nconst ENTITY_ID = E.catalog.catalog_product\n\nfunction formatDate(value?: string): string {\n if (!value) return '\u2014'\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return '\u2014'\n return date.toLocaleDateString()\n}\n\nfunction renderOffers(offers: OfferInfo[] | undefined): React.ReactNode {\n if (!offers || offers.length === 0) return <span className=\"text-xs text-muted-foreground\">\u2014</span>\n const visible = offers.slice(0, 3)\n return (\n <div className=\"flex flex-wrap gap-1\">\n {visible.map((offer) => {\n const label =\n typeof offer.channelName === 'string' && offer.channelName.trim().length\n ? offer.channelName.trim()\n : typeof offer.title === 'string' && offer.title.trim().length\n ? offer.title.trim()\n : offer.channelId\n const badgeTitle =\n typeof offer.channelCode === 'string' && offer.channelCode.trim().length ? offer.channelCode : undefined\n return (\n <span\n key={offer.id}\n className={`inline-flex items-center rounded-full border px-2 py-0.5 text-xs ${\n offer.isActive ? 'bg-secondary/80 text-secondary-foreground' : 'bg-muted text-muted-foreground'\n }`}\n title={badgeTitle}\n >\n {label}\n </span>\n )\n })}\n {offers.length > visible.length ? (\n <span className=\"text-xs text-muted-foreground\">+{offers.length - visible.length}</span>\n ) : null}\n </div>\n )\n}\n\nfunction renderPrice(pricing: PricingInfo | undefined, currency?: string | null, fallback = '\u2014'): React.ReactNode {\n if (!pricing) return <span className=\"text-xs text-muted-foreground\">{fallback}</span>\n const unit = pricing.unit_price_net ?? pricing.unit_price_gross\n if (unit == null) return <span className=\"text-xs text-muted-foreground\">{fallback}</span>\n const formatted = `${currency ?? pricing.currency_code ?? ''} ${unit}`\n const kind = pricing.kind ?? 'list'\n return (\n <div className=\"flex flex-col\">\n <span className=\"font-medium\">{formatted.trim()}</span>\n <span className=\"text-xs text-muted-foreground\">{kind}</span>\n </div>\n )\n}\n\nexport type ProductsDataTableSnapshot = {\n search: string\n filterValues: FilterValues\n total: number\n}\n\nexport type ProductsDataTableProps = {\n /**\n * Extra actions rendered alongside the built-in Create button in the\n * DataTable header. Used by the Step 4.9 AI merchandising sheet\n * trigger without coupling DataTable to the AI module.\n */\n extraActions?: React.ReactNode\n /**\n * Optional callback invoked whenever the table's search / filter /\n * total-matching snapshot changes. Used by the Step 4.9 AI merchandising\n * sheet to form a selection-aware pageContext per spec \u00A710.1.\n */\n onSnapshotChange?: (snapshot: ProductsDataTableSnapshot) => void\n}\n\nexport default function ProductsDataTable({\n extraActions,\n onSnapshotChange,\n}: ProductsDataTableProps = {}) {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const scopeVersion = useOrganizationScopeVersion()\n const [rows, setRows] = React.useState<ProductRow[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [cacheStatus, setCacheStatus] = React.useState<'hit' | 'miss' | null>(null)\n const [sorting, setSorting] = React.useState<SortingState>([{ id: 'title', desc: false }])\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [isLoading, setIsLoading] = React.useState(false)\n const [reloadToken, setReloadToken] = React.useState(0)\n // Step 5.18 (spec \u00A710 line 836, D18 demo): refresh the list when a\n // catalog.product.* event arrives via the DOM event bridge. Confirmed\n // AI bulk mutations (one `ai.action.confirmed` + one\n // `catalog.product.updated` per record) and direct API writes both\n // surface here so the table reflects the new state without a manual\n // reload.\n useAppEvent('catalog.product.*', () => {\n setReloadToken((token) => token + 1)\n })\n const [customFieldsetFilter, setCustomFieldsetFilter] = React.useState<string | null>(null)\n const { data: customFieldDefs = [] } = useCustomFieldDefs(ENTITY_ID, {\n keyExtras: [scopeVersion, reloadToken],\n })\n const [channelOptionsCache, setChannelOptionsCache] = React.useState<Record<string, FilterOption>>({})\n const [categoryOptionsCache, setCategoryOptionsCache] = React.useState<Record<string, FilterOption>>({})\n const [tagOptionsCache, setTagOptionsCache] = React.useState<Record<string, FilterOption>>({})\n\n const registerOptions = React.useCallback(\n (\n setter: React.Dispatch<React.SetStateAction<Record<string, FilterOption>>>,\n options: FilterOption[]\n ) => {\n setter((prev) => {\n const next = { ...prev }\n options.forEach((opt) => {\n if (opt.value) next[opt.value] = opt\n })\n return next\n })\n },\n []\n )\n\n const registerChannelOptions = React.useCallback(\n (options: FilterOption[]) => registerOptions(setChannelOptionsCache, options),\n [registerOptions]\n )\n const registerCategoryOptions = React.useCallback(\n (options: FilterOption[]) => registerOptions(setCategoryOptionsCache, options),\n [registerOptions]\n )\n const registerTagOptions = React.useCallback(\n (options: FilterOption[]) => registerOptions(setTagOptionsCache, options),\n [registerOptions]\n )\n\n const channelOptions = React.useMemo(() => Object.values(channelOptionsCache), [channelOptionsCache])\n const categoryOptions = React.useMemo(() => Object.values(categoryOptionsCache), [categoryOptionsCache])\n const tagOptions = React.useMemo(() => Object.values(tagOptionsCache), [tagOptionsCache])\n\n const loadChannelOptions = React.useCallback(\n async (term?: string): Promise<FilterOption[]> => {\n try {\n const params = new URLSearchParams({ pageSize: '100', isActive: 'true' })\n if (term && term.trim().length) params.set('search', term.trim())\n const payload = await readApiResultOrThrow<{ items?: Array<{ id?: string; name?: string; code?: string }> }>(\n `/api/sales/channels?${params.toString()}`,\n undefined,\n { errorMessage: t('catalog.products.filters.channelsLoadError', 'Failed to load channels') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options = items\n .map((entry) => {\n const value = typeof entry.id === 'string' ? entry.id : null\n if (!value) return null\n const label =\n typeof entry.name === 'string'\n ? entry.name\n : typeof entry.code === 'string'\n ? entry.code\n : value\n return { value, label, description: typeof entry.code === 'string' ? entry.code : undefined }\n })\n .filter((option) => !!option) as FilterOption[]\n registerChannelOptions(options)\n return options\n } catch {\n return []\n }\n },\n [registerChannelOptions, t],\n )\n\n const loadCategoryOptions = React.useCallback(\n async (term?: string): Promise<FilterOption[]> => {\n try {\n const params = new URLSearchParams({ pageSize: '200', view: 'manage' })\n if (term && term.trim().length) params.set('search', term.trim())\n const payload = await readApiResultOrThrow<{ items?: Array<{ id?: string; name?: string; parentName?: string | null }> }>(\n `/api/catalog/categories?${params.toString()}`,\n undefined,\n { errorMessage: t('catalog.products.filters.categoriesLoadError', 'Failed to load categories') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options = items\n .map((entry) => {\n const value = typeof entry.id === 'string' ? entry.id : null\n if (!value) return null\n const label = typeof entry.name === 'string' && entry.name.trim().length ? entry.name : value\n const description =\n typeof entry.parentName === 'string' && entry.parentName.trim().length ? entry.parentName : null\n return { value, label, description }\n })\n .filter((option) => !!option) as FilterOption[]\n registerCategoryOptions(options)\n return options\n } catch {\n return []\n }\n },\n [registerCategoryOptions, t],\n )\n\n const loadTagOptions = React.useCallback(\n async (term?: string): Promise<FilterOption[]> => {\n try {\n const params = new URLSearchParams({ pageSize: '100' })\n if (term && term.trim().length) params.set('search', term.trim())\n const payload = await readApiResultOrThrow<{ items?: Array<{ id?: string; label?: string }> }>(\n `/api/catalog/tags?${params.toString()}`,\n undefined,\n { errorMessage: t('catalog.products.filters.tagsLoadError', 'Failed to load tags') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options = items\n .map((entry) => {\n const value = typeof entry.id === 'string' ? entry.id : null\n if (!value) return null\n const label = typeof entry.label === 'string' && entry.label.trim().length ? entry.label : value\n return { value, label }\n })\n .filter((option) => !!option) as FilterOption[]\n registerTagOptions(options)\n return options\n } catch {\n return []\n }\n },\n [registerTagOptions, t],\n )\n\n const productTypeOptions = React.useMemo<FilterOption[]>(() => [\n { value: 'simple', label: t('catalog.products.types.simple', 'Simple') },\n { value: 'configurable', label: t('catalog.products.types.configurable', 'Configurable') },\n { value: 'virtual', label: t('catalog.products.types.virtual', 'Virtual') },\n { value: 'downloadable', label: t('catalog.products.types.downloadable', 'Downloadable') },\n {\n value: 'bundle',\n label: `${t('catalog.products.types.bundle', 'Bundle')} (${t('common.comingSoon', 'Coming soon')})`,\n },\n {\n value: 'grouped',\n label: `${t('catalog.products.types.grouped', 'Grouped')} (${t('common.comingSoon', 'Coming soon')})`,\n },\n ], [t])\n\n const productTypeLabelMap = React.useMemo(() => {\n const map = new Map<string, string>()\n productTypeOptions.forEach((opt) => map.set(opt.value, opt.label))\n return map\n }, [productTypeOptions])\n\n const filters = React.useMemo<FilterDef[]>(() => [\n { id: 'status', label: t('catalog.products.filters.status'), type: 'text' },\n { id: 'isActive', label: t('catalog.products.filters.active'), type: 'checkbox' },\n { id: 'configurable', label: t('catalog.products.filters.configurable'), type: 'checkbox' },\n { id: 'productType', label: t('catalog.products.filters.productType', 'Type'), type: 'select', options: productTypeOptions },\n {\n id: 'channelIds',\n label: t('catalog.products.filters.channels'),\n type: 'tags',\n loadOptions: loadChannelOptions,\n options: channelOptions,\n formatValue: (val) => channelOptionsCache[val]?.label ?? val,\n formatDescription: (val) => channelOptionsCache[val]?.description ?? null,\n },\n {\n id: 'categoryIds',\n label: t('catalog.products.filters.categories', 'Categories'),\n type: 'tags',\n loadOptions: loadCategoryOptions,\n options: categoryOptions,\n formatValue: (val) => categoryOptionsCache[val]?.label ?? val,\n formatDescription: (val) => categoryOptionsCache[val]?.description ?? null,\n },\n {\n id: 'tagIds',\n label: t('catalog.products.filters.tags', 'Tags'),\n type: 'tags',\n loadOptions: loadTagOptions,\n options: tagOptions,\n formatValue: (val) => tagOptionsCache[val]?.label ?? val,\n },\n ], [\n categoryOptions,\n categoryOptionsCache,\n channelOptions,\n channelOptionsCache,\n loadCategoryOptions,\n loadChannelOptions,\n loadTagOptions,\n productTypeOptions,\n tagOptions,\n tagOptionsCache,\n t,\n ])\n\n const columns = React.useMemo<ColumnDef<ProductRow>[]>(() => {\n const base: ColumnDef<ProductRow>[] = [\n {\n id: 'media',\n header: '',\n size: 80,\n cell: ({ row }) => (\n <ProductImageCell\n mediaId={row.original.default_media_id}\n mediaUrl={row.original.default_media_url}\n title={row.original.title}\n cropType=\"contain\"\n />\n ),\n meta: { sticky: true },\n },\n {\n accessorKey: 'title',\n header: t('catalog.products.table.title', 'Title'),\n cell: ({ row }) => (\n <div className=\"flex flex-col\">\n <span className=\"font-medium\">{row.original.title || '\u2014'}</span>\n {row.original.subtitle ? (\n <span className=\"text-xs text-muted-foreground\">{row.original.subtitle}</span>\n ) : null}\n {row.original.handle ? (\n <span className=\"text-xs text-muted-foreground\">/{row.original.handle}</span>\n ) : null}\n {row.original.description ? (\n <span className=\"text-xs text-muted-foreground\">{markdownToPlainText(row.original.description)}</span>\n ) : null}\n </div>\n ),\n meta: { sticky: true },\n },\n {\n accessorKey: 'sku',\n header: t('catalog.products.table.sku', 'SKU'),\n cell: ({ getValue }) => {\n const value = getValue()\n return value ? <span className=\"font-mono text-xs\">{String(value)}</span> : <span className=\"text-xs text-muted-foreground\">\u2014</span>\n },\n },\n {\n accessorKey: 'product_type',\n header: t('catalog.products.table.type'),\n cell: ({ row }) => {\n const type = typeof row.original.product_type === 'string' ? row.original.product_type : 'simple'\n const label = productTypeLabelMap.get(type) ?? type\n return <span className=\"text-xs text-muted-foreground\">{label}</span>\n },\n },\n {\n accessorKey: 'is_configurable',\n header: t('catalog.products.table.configurable'),\n cell: ({ row }) => <BooleanIcon value={!!row.original.is_configurable} />,\n },\n {\n accessorKey: 'is_active',\n header: t('catalog.products.table.active'),\n cell: ({ row }) => <BooleanIcon value={!!row.original.is_active} />,\n },\n {\n accessorKey: 'pricing',\n header: t('catalog.products.table.price'),\n cell: ({ row }) => renderPrice(row.original.pricing, row.original.primary_currency_code),\n },\n {\n accessorKey: 'offers',\n header: t('catalog.products.table.channels'),\n cell: ({ row }) => renderOffers(row.original.offers),\n },\n {\n accessorKey: 'updated_at',\n header: t('catalog.products.table.updatedAt'),\n cell: ({ row }) => <span className=\"text-xs text-muted-foreground\">{formatDate(row.original.updated_at)}</span>,\n },\n ]\n return applyCustomFieldVisibility(base, customFieldDefs)\n }, [customFieldDefs, productTypeLabelMap, t])\n\n const handleSearchChange = React.useCallback((value: string) => {\n setSearch(value)\n setPage(1)\n }, [])\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n setFilterValues(values)\n setPage(1)\n }, [])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({})\n setPage(1)\n }, [])\n\n const handleCustomFieldsetFilterChange = React.useCallback(\n (value: string | null) => {\n if (value === customFieldsetFilter) return\n setCustomFieldsetFilter(value)\n setFilterValues((prev) => {\n const entries = Object.entries(prev)\n if (!entries.some(([key]) => key.startsWith('cf_'))) return prev\n const next: FilterValues = {}\n entries.forEach(([key, val]) => {\n if (!key.startsWith('cf_')) next[key] = val\n })\n return next\n })\n setPage(1)\n },\n [customFieldsetFilter],\n )\n\n const handleRefresh = React.useCallback(() => {\n setReloadToken((token) => token + 1)\n }, [])\n\n const queryParams = React.useMemo(() => {\n const params = new URLSearchParams()\n params.set('page', String(page))\n params.set('pageSize', String(PAGE_SIZE))\n if (search.trim()) params.set('search', search.trim())\n const sort = sorting[0]\n if (sort?.id) {\n params.set('sortField', sort.id)\n params.set('sortDir', sort.desc ? 'desc' : 'asc')\n }\n const status = filterValues.status\n if (typeof status === 'string' && status.trim()) {\n params.set('status', status.trim())\n }\n if (filterValues.isActive === true) params.set('isActive', 'true')\n if (filterValues.isActive === false) params.set('isActive', 'false')\n if (filterValues.configurable === true) params.set('configurable', 'true')\n if (filterValues.configurable === false) params.set('configurable', 'false')\n if (typeof filterValues.productType === 'string' && filterValues.productType.trim()) {\n params.set('productType', filterValues.productType.trim())\n }\n if (Array.isArray(filterValues.channelIds) && filterValues.channelIds.length) {\n const values = filterValues.channelIds\n .map((value) => (typeof value === 'string' ? value : null))\n .filter((value): value is string => !!value)\n if (values.length) params.set('channelIds', values.join(','))\n }\n if (Array.isArray(filterValues.categoryIds) && filterValues.categoryIds.length) {\n const values = filterValues.categoryIds\n .map((value) => (typeof value === 'string' ? value : null))\n .filter((value): value is string => !!value)\n if (values.length) params.set('categoryIds', values.join(','))\n }\n if (Array.isArray(filterValues.tagIds) && filterValues.tagIds.length) {\n const values = filterValues.tagIds\n .map((value) => (typeof value === 'string' ? value : null))\n .filter((value): value is string => !!value)\n if (values.length) params.set('tagIds', values.join(','))\n }\n Object.entries(filterValues).forEach(([key, value]) => {\n if (!key.startsWith('cf_') || value == null) return\n if (Array.isArray(value)) {\n const entries = value\n .map((entry) => (typeof entry === 'string' ? entry.trim() : String(entry || '').trim()))\n .filter((entry) => entry.length > 0)\n if (entries.length) params.set(key, entries.join(','))\n } else if (typeof value === 'object' && value !== null && ('from' in (value as Record<string, unknown>) || 'to' in (value as Record<string, unknown>))) {\n const range = value as { from?: string; to?: string }\n if (typeof range.from === 'string' && range.from.trim().length) {\n params.set(`${key}:from`, range.from.trim())\n }\n if (typeof range.to === 'string' && range.to.trim().length) {\n params.set(`${key}:to`, range.to.trim())\n }\n } else if (typeof value === 'string' && value.trim()) {\n params.set(key, value.trim())\n }\n })\n if (typeof customFieldsetFilter === 'string' && customFieldsetFilter.trim().length > 0) {\n params.set('customFieldset', customFieldsetFilter.trim())\n }\n return params.toString()\n }, [customFieldsetFilter, filterValues, page, search, sorting])\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setIsLoading(true)\n setCacheStatus(null)\n try {\n const fallback: ProductsResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<ProductsResponse>(\n `/api/catalog/products?${queryParams}`,\n undefined,\n { fallback },\n )\n if (!call.ok) {\n const message = t('catalog.products.list.error.load', 'Failed to load products')\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 normalized = items.filter((item): item is ProductRow => typeof item?.id === 'string')\n setRows(normalized)\n setTotal(typeof payload.total === 'number' ? payload.total : normalized.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : 1)\n } catch (error) {\n if (!cancelled) {\n setCacheStatus(null)\n const message =\n error instanceof Error\n ? error.message\n : t('catalog.products.list.error.load', 'Failed to load products')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n load()\n return () => {\n cancelled = true\n }\n }, [queryParams, reloadToken, scopeVersion, t])\n\n const handleDelete = React.useCallback(async (row: ProductRow) => {\n const confirmed = await confirm({\n title: t('catalog.products.list.deleteConfirm', 'Delete this product?'),\n variant: 'destructive',\n })\n if (!confirmed) return\n try {\n const headers = buildOptimisticLockHeader(typeof row.updated_at === 'string' ? row.updated_at : null)\n await withScopedApiRequestHeaders(headers, () => (\n deleteCrud('catalog/products', row.id, {\n errorMessage: t('catalog.products.list.error.delete', 'Failed to delete product'),\n })\n ))\n flash(t('catalog.products.flash.deleted', 'Product deleted'), 'success')\n setReloadToken((token) => token + 1)\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : t('catalog.products.list.error.delete', 'Failed to delete product')\n flash(message, 'error')\n }\n }, [confirm, t])\n\n React.useEffect(() => {\n if (!onSnapshotChange) return\n onSnapshotChange({ search, filterValues, total })\n }, [onSnapshotChange, search, filterValues, total])\n\n const currentParams = React.useMemo(() => Object.fromEntries(new URLSearchParams(queryParams)), [queryParams])\n\n const exportConfig = React.useMemo(() => ({\n view: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('catalog/products', { ...currentParams, exportScope: 'view' }, format),\n },\n full: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('catalog/products', { ...currentParams, exportScope: 'full', all: 'true' }, format),\n },\n }), [currentParams])\n\n return (\n <>\n <DataTable<ProductRow>\n title={t('catalog.products.page.title', 'Products & services')}\n entityId={ENTITY_ID}\n customFieldFilterKeyExtras={[scopeVersion, reloadToken]}\n refreshButton={{\n label: t('catalog.products.actions.refresh', 'Refresh'),\n onRefresh: handleRefresh,\n isRefreshing: isLoading,\n }}\n actions={(\n <div className=\"flex items-center gap-2\">\n {extraActions}\n <Button asChild>\n <Link href=\"/backend/catalog/products/create\">\n {t('catalog.products.actions.create', 'Create')}\n </Link>\n </Button>\n </div>\n )}\n columns={columns}\n data={rows}\n emptyState={(\n <ListEmptyState\n entityName={t('catalog.products.page.title', 'Products & services')}\n createHref=\"/backend/catalog/products/create\"\n createLabel={t('catalog.products.actions.create', 'Create')}\n />\n )}\n searchValue={search}\n onSearchChange={handleSearchChange}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n onCustomFieldFilterFieldsetChange={handleCustomFieldsetFilterChange}\n sorting={sorting}\n onSortingChange={setSorting}\n injectionSpotId={extensionPoints.hosts.productsTable.baseSpotId}\n injectionContext={{\n search,\n filters: filterValues,\n customFieldset: customFieldsetFilter,\n page,\n sorting,\n scopeVersion,\n // Step 5.15: surface `total` so the merchandising AI widget\n // (rendered in `data-table:catalog.products:header`) can build\n // a selection-aware pageContext per spec \u00A710.1 without taking a\n // dependency on the host page.\n total,\n totalMatching: total,\n }}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n onPageChange: setPage,\n cacheStatus,\n }}\n exporter={exportConfig}\n isLoading={isLoading}\n perspective={{ tableId: extensionPoints.hosts.productsTable.tableId }}\n stickyActionsColumn\n rowActions={(row) => (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('catalog.products.table.actions.edit', 'Edit'),\n href: `/backend/catalog/products/${row.id}`,\n },\n {\n id: 'delete',\n label: t('catalog.products.table.actions.delete', 'Delete'),\n destructive: true,\n onSelect: () => {\n void handleDelete(row)\n },\n },\n ]}\n />\n )}\n />\n {ConfirmDialogElement}\n </>\n )\n}\n"],
5
+ "mappings": ";AAqG6C,SAijBzC,UAjjByC,KA0BrC,YA1BqC;AAnG7C,YAAY,WAAW;AACvB,SAAS,uBAAuB;AAChC,OAAO,UAAU;AAGjB,SAAS,iBAA6C;AACtD,SAAS,sBAAsB;AAC/B,SAAS,cAAc;AACvB,SAAS,kBAAkB;AAC3B,SAAS,SAAS,sBAAsB,mCAAmC;AAC3E,SAAS,aAAa;AACtB,SAAS,YAAY,0BAA0B;AAC/C,SAAS,iCAAiC;AAC1C,SAAS,0BAA0B;AACnC,SAAS,kCAAkC;AAG3C,SAAS,mBAAmB;AAC5B,SAAS,2BAA2B;AACpC,SAAS,mCAAmC;AAC5C,SAAS,YAAY;AACrB,SAAS,wBAAwB;AACjC,SAAS,mBAAmB;AAC5B,SAAS,SAAS;AAClB,SAAS,wBAAwB;AAgEjC,MAAM,YAAY;AAClB,MAAM,YAAY,EAAE,QAAQ;AAE5B,SAAS,WAAW,OAAwB;AAC1C,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,OAAO,IAAI,KAAK,KAAK;AAC3B,MAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,EAAG,QAAO;AACzC,SAAO,KAAK,mBAAmB;AACjC;AAEA,SAAS,aAAa,QAAkD;AACtE,MAAI,CAAC,UAAU,OAAO,WAAW,EAAG,QAAO,oBAAC,UAAK,WAAU,iCAAgC,oBAAC;AAC5F,QAAM,UAAU,OAAO,MAAM,GAAG,CAAC;AACjC,SACE,qBAAC,SAAI,WAAU,wBACZ;AAAA,YAAQ,IAAI,CAAC,UAAU;AACtB,YAAM,QACJ,OAAO,MAAM,gBAAgB,YAAY,MAAM,YAAY,KAAK,EAAE,SAC9D,MAAM,YAAY,KAAK,IACvB,OAAO,MAAM,UAAU,YAAY,MAAM,MAAM,KAAK,EAAE,SACpD,MAAM,MAAM,KAAK,IACjB,MAAM;AACd,YAAM,aACJ,OAAO,MAAM,gBAAgB,YAAY,MAAM,YAAY,KAAK,EAAE,SAAS,MAAM,cAAc;AACjG,aACE;AAAA,QAAC;AAAA;AAAA,UAEC,WAAW,oEACT,MAAM,WAAW,8CAA8C,gCACjE;AAAA,UACA,OAAO;AAAA,UAEN;AAAA;AAAA,QANI,MAAM;AAAA,MAOb;AAAA,IAEJ,CAAC;AAAA,IACA,OAAO,SAAS,QAAQ,SACvB,qBAAC,UAAK,WAAU,iCAAgC;AAAA;AAAA,MAAE,OAAO,SAAS,QAAQ;AAAA,OAAO,IAC/E;AAAA,KACN;AAEJ;AAEA,SAAS,YAAY,SAAkC,UAA0B,WAAW,UAAsB;AAChH,MAAI,CAAC,QAAS,QAAO,oBAAC,UAAK,WAAU,iCAAiC,oBAAS;AAC/E,QAAM,OAAO,QAAQ,kBAAkB,QAAQ;AAC/C,MAAI,QAAQ,KAAM,QAAO,oBAAC,UAAK,WAAU,iCAAiC,oBAAS;AACnF,QAAM,YAAY,GAAG,YAAY,QAAQ,iBAAiB,EAAE,IAAI,IAAI;AACpE,QAAM,OAAO,QAAQ,QAAQ;AAC7B,SACE,qBAAC,SAAI,WAAU,iBACb;AAAA,wBAAC,UAAK,WAAU,eAAe,oBAAU,KAAK,GAAE;AAAA,IAChD,oBAAC,UAAK,WAAU,iCAAiC,gBAAK;AAAA,KACxD;AAEJ;AAuBe,SAAR,kBAAmC;AAAA,EACxC;AAAA,EACA;AACF,IAA4B,CAAC,GAAG;AAC9B,QAAM,IAAI,KAAK;AACf,QAAM,EAAE,SAAS,qBAAqB,IAAI,iBAAiB;AAC3D,QAAM,eAAe,4BAA4B;AACjD,QAAM,CAAC,MAAM,OAAO,IAAI,MAAM,SAAuB,CAAC,CAAC;AACvD,QAAM,CAAC,MAAM,OAAO,IAAI,MAAM,SAAS,CAAC;AACxC,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAAS,CAAC;AAC1C,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAS,CAAC;AACpD,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAAgC,IAAI;AAChF,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAAuB,CAAC,EAAE,IAAI,SAAS,MAAM,MAAM,CAAC,CAAC;AACzF,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAS,EAAE;AAC7C,QAAM,CAAC,cAAc,eAAe,IAAI,MAAM,SAAuB,CAAC,CAAC;AACvE,QAAM,CAAC,WAAW,YAAY,IAAI,MAAM,SAAS,KAAK;AACtD,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAAS,CAAC;AAOtD,cAAY,qBAAqB,MAAM;AACrC,mBAAe,CAAC,UAAU,QAAQ,CAAC;AAAA,EACrC,CAAC;AACD,QAAM,CAAC,sBAAsB,uBAAuB,IAAI,MAAM,SAAwB,IAAI;AAC1F,QAAM,EAAE,MAAM,kBAAkB,CAAC,EAAE,IAAI,mBAAmB,WAAW;AAAA,IACnE,WAAW,CAAC,cAAc,WAAW;AAAA,EACvC,CAAC;AACD,QAAM,CAAC,qBAAqB,sBAAsB,IAAI,MAAM,SAAuC,CAAC,CAAC;AACrG,QAAM,CAAC,sBAAsB,uBAAuB,IAAI,MAAM,SAAuC,CAAC,CAAC;AACvG,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,MAAM,SAAuC,CAAC,CAAC;AAE7F,QAAM,kBAAkB,MAAM;AAAA,IAC5B,CACE,QACA,YACG;AACH,aAAO,CAAC,SAAS;AACf,cAAM,OAAO,EAAE,GAAG,KAAK;AACvB,gBAAQ,QAAQ,CAAC,QAAQ;AACvB,cAAI,IAAI,MAAO,MAAK,IAAI,KAAK,IAAI;AAAA,QACnC,CAAC;AACD,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,yBAAyB,MAAM;AAAA,IACnC,CAAC,YAA4B,gBAAgB,wBAAwB,OAAO;AAAA,IAC5E,CAAC,eAAe;AAAA,EAClB;AACA,QAAM,0BAA0B,MAAM;AAAA,IACpC,CAAC,YAA4B,gBAAgB,yBAAyB,OAAO;AAAA,IAC7E,CAAC,eAAe;AAAA,EAClB;AACA,QAAM,qBAAqB,MAAM;AAAA,IAC/B,CAAC,YAA4B,gBAAgB,oBAAoB,OAAO;AAAA,IACxE,CAAC,eAAe;AAAA,EAClB;AAEA,QAAM,iBAAiB,MAAM,QAAQ,MAAM,OAAO,OAAO,mBAAmB,GAAG,CAAC,mBAAmB,CAAC;AACpG,QAAM,kBAAkB,MAAM,QAAQ,MAAM,OAAO,OAAO,oBAAoB,GAAG,CAAC,oBAAoB,CAAC;AACvG,QAAM,aAAa,MAAM,QAAQ,MAAM,OAAO,OAAO,eAAe,GAAG,CAAC,eAAe,CAAC;AAExF,QAAM,qBAAqB,MAAM;AAAA,IAC/B,OAAO,SAA2C;AAChD,UAAI;AACF,cAAM,SAAS,IAAI,gBAAgB,EAAE,UAAU,OAAO,UAAU,OAAO,CAAC;AACxE,YAAI,QAAQ,KAAK,KAAK,EAAE,OAAQ,QAAO,IAAI,UAAU,KAAK,KAAK,CAAC;AAChE,cAAM,UAAU,MAAM;AAAA,UACpB,uBAAuB,OAAO,SAAS,CAAC;AAAA,UACxC;AAAA,UACA,EAAE,cAAc,EAAE,8CAA8C,yBAAyB,EAAE;AAAA,QAC7F;AACA,cAAM,QAAQ,MAAM,QAAQ,SAAS,KAAK,IAAI,QAAQ,QAAQ,CAAC;AAC/D,cAAM,UAAU,MACb,IAAI,CAAC,UAAU;AACd,gBAAM,QAAQ,OAAO,MAAM,OAAO,WAAW,MAAM,KAAK;AACxD,cAAI,CAAC,MAAO,QAAO;AACnB,gBAAM,QACJ,OAAO,MAAM,SAAS,WAClB,MAAM,OACN,OAAO,MAAM,SAAS,WACpB,MAAM,OACN;AACR,iBAAO,EAAE,OAAO,OAAO,aAAa,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO,OAAU;AAAA,QAC9F,CAAC,EACA,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM;AAC9B,+BAAuB,OAAO;AAC9B,eAAO;AAAA,MACT,QAAQ;AACN,eAAO,CAAC;AAAA,MACV;AAAA,IACF;AAAA,IACA,CAAC,wBAAwB,CAAC;AAAA,EAC5B;AAEA,QAAM,sBAAsB,MAAM;AAAA,IAChC,OAAO,SAA2C;AAChD,UAAI;AACF,cAAM,SAAS,IAAI,gBAAgB,EAAE,UAAU,OAAO,MAAM,SAAS,CAAC;AACtE,YAAI,QAAQ,KAAK,KAAK,EAAE,OAAQ,QAAO,IAAI,UAAU,KAAK,KAAK,CAAC;AAChE,cAAM,UAAU,MAAM;AAAA,UACpB,2BAA2B,OAAO,SAAS,CAAC;AAAA,UAC5C;AAAA,UACA,EAAE,cAAc,EAAE,gDAAgD,2BAA2B,EAAE;AAAA,QACjG;AACA,cAAM,QAAQ,MAAM,QAAQ,SAAS,KAAK,IAAI,QAAQ,QAAQ,CAAC;AAC/D,cAAM,UAAU,MACb,IAAI,CAAC,UAAU;AACd,gBAAM,QAAQ,OAAO,MAAM,OAAO,WAAW,MAAM,KAAK;AACxD,cAAI,CAAC,MAAO,QAAO;AACnB,gBAAM,QAAQ,OAAO,MAAM,SAAS,YAAY,MAAM,KAAK,KAAK,EAAE,SAAS,MAAM,OAAO;AACxF,gBAAM,cACJ,OAAO,MAAM,eAAe,YAAY,MAAM,WAAW,KAAK,EAAE,SAAS,MAAM,aAAa;AAC9F,iBAAO,EAAE,OAAO,OAAO,YAAY;AAAA,QACrC,CAAC,EACA,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM;AAC9B,gCAAwB,OAAO;AAC/B,eAAO;AAAA,MACT,QAAQ;AACN,eAAO,CAAC;AAAA,MACV;AAAA,IACF;AAAA,IACA,CAAC,yBAAyB,CAAC;AAAA,EAC7B;AAEA,QAAM,iBAAiB,MAAM;AAAA,IAC3B,OAAO,SAA2C;AAChD,UAAI;AACF,cAAM,SAAS,IAAI,gBAAgB,EAAE,UAAU,MAAM,CAAC;AACtD,YAAI,QAAQ,KAAK,KAAK,EAAE,OAAQ,QAAO,IAAI,UAAU,KAAK,KAAK,CAAC;AAChE,cAAM,UAAU,MAAM;AAAA,UACpB,qBAAqB,OAAO,SAAS,CAAC;AAAA,UACtC;AAAA,UACA,EAAE,cAAc,EAAE,0CAA0C,qBAAqB,EAAE;AAAA,QACrF;AACA,cAAM,QAAQ,MAAM,QAAQ,SAAS,KAAK,IAAI,QAAQ,QAAQ,CAAC;AAC/D,cAAM,UAAU,MACb,IAAI,CAAC,UAAU;AACd,gBAAM,QAAQ,OAAO,MAAM,OAAO,WAAW,MAAM,KAAK;AACxD,cAAI,CAAC,MAAO,QAAO;AACnB,gBAAM,QAAQ,OAAO,MAAM,UAAU,YAAY,MAAM,MAAM,KAAK,EAAE,SAAS,MAAM,QAAQ;AAC3F,iBAAO,EAAE,OAAO,MAAM;AAAA,QACxB,CAAC,EACA,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM;AAC9B,2BAAmB,OAAO;AAC1B,eAAO;AAAA,MACT,QAAQ;AACN,eAAO,CAAC;AAAA,MACV;AAAA,IACF;AAAA,IACA,CAAC,oBAAoB,CAAC;AAAA,EACxB;AAEA,QAAM,qBAAqB,MAAM,QAAwB,MAAM;AAAA,IAC7D,EAAE,OAAO,UAAU,OAAO,EAAE,iCAAiC,QAAQ,EAAE;AAAA,IACvE,EAAE,OAAO,gBAAgB,OAAO,EAAE,uCAAuC,cAAc,EAAE;AAAA,IACzF,EAAE,OAAO,WAAW,OAAO,EAAE,kCAAkC,SAAS,EAAE;AAAA,IAC1E,EAAE,OAAO,gBAAgB,OAAO,EAAE,uCAAuC,cAAc,EAAE;AAAA,IACzF;AAAA,MACE,OAAO;AAAA,MACP,OAAO,GAAG,EAAE,iCAAiC,QAAQ,CAAC,KAAK,EAAE,qBAAqB,aAAa,CAAC;AAAA,IAClG;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,OAAO,GAAG,EAAE,kCAAkC,SAAS,CAAC,KAAK,EAAE,qBAAqB,aAAa,CAAC;AAAA,IACpG;AAAA,EACF,GAAG,CAAC,CAAC,CAAC;AAEN,QAAM,sBAAsB,MAAM,QAAQ,MAAM;AAC9C,UAAM,MAAM,oBAAI,IAAoB;AACpC,uBAAmB,QAAQ,CAAC,QAAQ,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,CAAC;AACjE,WAAO;AAAA,EACT,GAAG,CAAC,kBAAkB,CAAC;AAEvB,QAAM,UAAU,MAAM,QAAqB,MAAM;AAAA,IAC/C,EAAE,IAAI,UAAU,OAAO,EAAE,iCAAiC,GAAG,MAAM,OAAO;AAAA,IAC1E,EAAE,IAAI,YAAY,OAAO,EAAE,iCAAiC,GAAG,MAAM,WAAW;AAAA,IAChF,EAAE,IAAI,gBAAgB,OAAO,EAAE,uCAAuC,GAAG,MAAM,WAAW;AAAA,IAC1F,EAAE,IAAI,eAAe,OAAO,EAAE,wCAAwC,MAAM,GAAG,MAAM,UAAU,SAAS,mBAAmB;AAAA,IAC3H;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,mCAAmC;AAAA,MAC5C,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,MACT,aAAa,CAAC,QAAQ,oBAAoB,GAAG,GAAG,SAAS;AAAA,MACzD,mBAAmB,CAAC,QAAQ,oBAAoB,GAAG,GAAG,eAAe;AAAA,IACvE;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,uCAAuC,YAAY;AAAA,MAC5D,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,MACT,aAAa,CAAC,QAAQ,qBAAqB,GAAG,GAAG,SAAS;AAAA,MAC1D,mBAAmB,CAAC,QAAQ,qBAAqB,GAAG,GAAG,eAAe;AAAA,IACxE;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,iCAAiC,MAAM;AAAA,MAChD,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,MACT,aAAa,CAAC,QAAQ,gBAAgB,GAAG,GAAG,SAAS;AAAA,IACvD;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,UAAU,MAAM,QAAiC,MAAM;AAC3D,UAAM,OAAgC;AAAA,MACpC;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,MAAM,CAAC,EAAE,IAAI,MACX;AAAA,UAAC;AAAA;AAAA,YACC,SAAS,IAAI,SAAS;AAAA,YACtB,UAAU,IAAI,SAAS;AAAA,YACvB,OAAO,IAAI,SAAS;AAAA,YACpB,UAAS;AAAA;AAAA,QACX;AAAA,QAEF,MAAM,EAAE,QAAQ,KAAK;AAAA,MACvB;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,gCAAgC,OAAO;AAAA,QACjD,MAAM,CAAC,EAAE,IAAI,MACX,qBAAC,SAAI,WAAU,iBACb;AAAA,8BAAC,UAAK,WAAU,eAAe,cAAI,SAAS,SAAS,UAAI;AAAA,UACxD,IAAI,SAAS,WACZ,oBAAC,UAAK,WAAU,iCAAiC,cAAI,SAAS,UAAS,IACrE;AAAA,UACH,IAAI,SAAS,SACZ,qBAAC,UAAK,WAAU,iCAAgC;AAAA;AAAA,YAAE,IAAI,SAAS;AAAA,aAAO,IACpE;AAAA,UACH,IAAI,SAAS,cACZ,oBAAC,UAAK,WAAU,iCAAiC,8BAAoB,IAAI,SAAS,WAAW,GAAE,IAC7F;AAAA,WACN;AAAA,QAEF,MAAM,EAAE,QAAQ,KAAK;AAAA,MACvB;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,8BAA8B,KAAK;AAAA,QAC7C,MAAM,CAAC,EAAE,SAAS,MAAM;AACtB,gBAAM,QAAQ,SAAS;AACvB,iBAAO,QAAQ,oBAAC,UAAK,WAAU,qBAAqB,iBAAO,KAAK,GAAE,IAAU,oBAAC,UAAK,WAAU,iCAAgC,oBAAC;AAAA,QAC/H;AAAA,MACF;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,6BAA6B;AAAA,QACvC,MAAM,CAAC,EAAE,IAAI,MAAM;AACjB,gBAAM,OAAO,OAAO,IAAI,SAAS,iBAAiB,WAAW,IAAI,SAAS,eAAe;AACzF,gBAAM,QAAQ,oBAAoB,IAAI,IAAI,KAAK;AAC/C,iBAAO,oBAAC,UAAK,WAAU,iCAAiC,iBAAM;AAAA,QAChE;AAAA,MACF;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,qCAAqC;AAAA,QAC/C,MAAM,CAAC,EAAE,IAAI,MAAM,oBAAC,eAAY,OAAO,CAAC,CAAC,IAAI,SAAS,iBAAiB;AAAA,MACzE;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,+BAA+B;AAAA,QACzC,MAAM,CAAC,EAAE,IAAI,MAAM,oBAAC,eAAY,OAAO,CAAC,CAAC,IAAI,SAAS,WAAW;AAAA,MACnE;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,8BAA8B;AAAA,QACxC,MAAM,CAAC,EAAE,IAAI,MAAM,YAAY,IAAI,SAAS,SAAS,IAAI,SAAS,qBAAqB;AAAA,MACzF;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,iCAAiC;AAAA,QAC3C,MAAM,CAAC,EAAE,IAAI,MAAM,aAAa,IAAI,SAAS,MAAM;AAAA,MACrD;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,kCAAkC;AAAA,QAC5C,MAAM,CAAC,EAAE,IAAI,MAAM,oBAAC,UAAK,WAAU,iCAAiC,qBAAW,IAAI,SAAS,UAAU,GAAE;AAAA,MAC1G;AAAA,IACF;AACA,WAAO,2BAA2B,MAAM,eAAe;AAAA,EACzD,GAAG,CAAC,iBAAiB,qBAAqB,CAAC,CAAC;AAE5C,QAAM,qBAAqB,MAAM,YAAY,CAAC,UAAkB;AAC9D,cAAU,KAAK;AACf,YAAQ,CAAC;AAAA,EACX,GAAG,CAAC,CAAC;AAEL,QAAM,qBAAqB,MAAM,YAAY,CAAC,WAAyB;AACrE,oBAAgB,MAAM;AACtB,YAAQ,CAAC;AAAA,EACX,GAAG,CAAC,CAAC;AAEL,QAAM,qBAAqB,MAAM,YAAY,MAAM;AACjD,oBAAgB,CAAC,CAAC;AAClB,YAAQ,CAAC;AAAA,EACX,GAAG,CAAC,CAAC;AAEL,QAAM,mCAAmC,MAAM;AAAA,IAC7C,CAAC,UAAyB;AACxB,UAAI,UAAU,qBAAsB;AACpC,8BAAwB,KAAK;AAC7B,sBAAgB,CAAC,SAAS;AACxB,cAAM,UAAU,OAAO,QAAQ,IAAI;AACnC,YAAI,CAAC,QAAQ,KAAK,CAAC,CAAC,GAAG,MAAM,IAAI,WAAW,KAAK,CAAC,EAAG,QAAO;AAC5D,cAAM,OAAqB,CAAC;AAC5B,gBAAQ,QAAQ,CAAC,CAAC,KAAK,GAAG,MAAM;AAC9B,cAAI,CAAC,IAAI,WAAW,KAAK,EAAG,MAAK,GAAG,IAAI;AAAA,QAC1C,CAAC;AACD,eAAO;AAAA,MACT,CAAC;AACD,cAAQ,CAAC;AAAA,IACX;AAAA,IACA,CAAC,oBAAoB;AAAA,EACvB;AAEA,QAAM,gBAAgB,MAAM,YAAY,MAAM;AAC5C,mBAAe,CAAC,UAAU,QAAQ,CAAC;AAAA,EACrC,GAAG,CAAC,CAAC;AAEL,QAAM,cAAc,MAAM,QAAQ,MAAM;AACtC,UAAM,SAAS,IAAI,gBAAgB;AACnC,WAAO,IAAI,QAAQ,OAAO,IAAI,CAAC;AAC/B,WAAO,IAAI,YAAY,OAAO,SAAS,CAAC;AACxC,QAAI,OAAO,KAAK,EAAG,QAAO,IAAI,UAAU,OAAO,KAAK,CAAC;AACrD,UAAM,OAAO,QAAQ,CAAC;AACtB,QAAI,MAAM,IAAI;AACZ,aAAO,IAAI,aAAa,KAAK,EAAE;AAC/B,aAAO,IAAI,WAAW,KAAK,OAAO,SAAS,KAAK;AAAA,IAClD;AACA,UAAM,SAAS,aAAa;AAC5B,QAAI,OAAO,WAAW,YAAY,OAAO,KAAK,GAAG;AAC/C,aAAO,IAAI,UAAU,OAAO,KAAK,CAAC;AAAA,IACpC;AACA,QAAI,aAAa,aAAa,KAAM,QAAO,IAAI,YAAY,MAAM;AACjE,QAAI,aAAa,aAAa,MAAO,QAAO,IAAI,YAAY,OAAO;AACnE,QAAI,aAAa,iBAAiB,KAAM,QAAO,IAAI,gBAAgB,MAAM;AACzE,QAAI,aAAa,iBAAiB,MAAO,QAAO,IAAI,gBAAgB,OAAO;AAC3E,QAAI,OAAO,aAAa,gBAAgB,YAAY,aAAa,YAAY,KAAK,GAAG;AACnF,aAAO,IAAI,eAAe,aAAa,YAAY,KAAK,CAAC;AAAA,IAC3D;AACA,QAAI,MAAM,QAAQ,aAAa,UAAU,KAAK,aAAa,WAAW,QAAQ;AAC5E,YAAM,SAAS,aAAa,WACzB,IAAI,CAAC,UAAW,OAAO,UAAU,WAAW,QAAQ,IAAK,EACzD,OAAO,CAAC,UAA2B,CAAC,CAAC,KAAK;AAC7C,UAAI,OAAO,OAAQ,QAAO,IAAI,cAAc,OAAO,KAAK,GAAG,CAAC;AAAA,IAC9D;AACA,QAAI,MAAM,QAAQ,aAAa,WAAW,KAAK,aAAa,YAAY,QAAQ;AAC9E,YAAM,SAAS,aAAa,YACzB,IAAI,CAAC,UAAW,OAAO,UAAU,WAAW,QAAQ,IAAK,EACzD,OAAO,CAAC,UAA2B,CAAC,CAAC,KAAK;AAC7C,UAAI,OAAO,OAAQ,QAAO,IAAI,eAAe,OAAO,KAAK,GAAG,CAAC;AAAA,IAC/D;AACA,QAAI,MAAM,QAAQ,aAAa,MAAM,KAAK,aAAa,OAAO,QAAQ;AACpE,YAAM,SAAS,aAAa,OACzB,IAAI,CAAC,UAAW,OAAO,UAAU,WAAW,QAAQ,IAAK,EACzD,OAAO,CAAC,UAA2B,CAAC,CAAC,KAAK;AAC7C,UAAI,OAAO,OAAQ,QAAO,IAAI,UAAU,OAAO,KAAK,GAAG,CAAC;AAAA,IAC1D;AACA,WAAO,QAAQ,YAAY,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACrD,UAAI,CAAC,IAAI,WAAW,KAAK,KAAK,SAAS,KAAM;AAC7C,UAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,cAAM,UAAU,MACb,IAAI,CAAC,UAAW,OAAO,UAAU,WAAW,MAAM,KAAK,IAAI,OAAO,SAAS,EAAE,EAAE,KAAK,CAAE,EACtF,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC;AACrC,YAAI,QAAQ,OAAQ,QAAO,IAAI,KAAK,QAAQ,KAAK,GAAG,CAAC;AAAA,MACvD,WAAW,OAAO,UAAU,YAAY,UAAU,SAAS,UAAW,SAAqC,QAAS,QAAoC;AACtJ,cAAM,QAAQ;AACd,YAAI,OAAO,MAAM,SAAS,YAAY,MAAM,KAAK,KAAK,EAAE,QAAQ;AAC9D,iBAAO,IAAI,GAAG,GAAG,SAAS,MAAM,KAAK,KAAK,CAAC;AAAA,QAC7C;AACA,YAAI,OAAO,MAAM,OAAO,YAAY,MAAM,GAAG,KAAK,EAAE,QAAQ;AAC1D,iBAAO,IAAI,GAAG,GAAG,OAAO,MAAM,GAAG,KAAK,CAAC;AAAA,QACzC;AAAA,MACF,WAAW,OAAO,UAAU,YAAY,MAAM,KAAK,GAAG;AACpD,eAAO,IAAI,KAAK,MAAM,KAAK,CAAC;AAAA,MAC9B;AAAA,IACF,CAAC;AACD,QAAI,OAAO,yBAAyB,YAAY,qBAAqB,KAAK,EAAE,SAAS,GAAG;AACtF,aAAO,IAAI,kBAAkB,qBAAqB,KAAK,CAAC;AAAA,IAC1D;AACA,WAAO,OAAO,SAAS;AAAA,EACzB,GAAG,CAAC,sBAAsB,cAAc,MAAM,QAAQ,OAAO,CAAC;AAE9D,QAAM,UAAU,MAAM;AACpB,QAAI,YAAY;AAChB,mBAAe,OAAO;AACpB,mBAAa,IAAI;AACjB,qBAAe,IAAI;AACnB,UAAI;AACF,cAAM,WAA6B,EAAE,OAAO,CAAC,GAAG,OAAO,GAAG,YAAY,EAAE;AACxE,cAAM,OAAO,MAAM;AAAA,UACjB,yBAAyB,WAAW;AAAA,UACpC;AAAA,UACA,EAAE,SAAS;AAAA,QACb;AACA,YAAI,CAAC,KAAK,IAAI;AACZ,gBAAM,UAAU,EAAE,oCAAoC,yBAAyB;AAC/E,gBAAM,SAAS,OAAO;AACtB,cAAI,CAAC,UAAW,gBAAe,IAAI;AACnC;AAAA,QACF;AACA,cAAM,UAAU,KAAK,UAAU;AAC/B,YAAI,UAAW;AACf,uBAAe,KAAK,eAAe,IAAI;AACvC,cAAM,QAAQ,MAAM,QAAQ,QAAQ,KAAK,IAAI,QAAQ,QAAQ,CAAC;AAC9D,cAAM,aAAa,MAAM,OAAO,CAAC,SAA6B,OAAO,MAAM,OAAO,QAAQ;AAC1F,gBAAQ,UAAU;AAClB,iBAAS,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ,WAAW,MAAM;AAC9E,sBAAc,OAAO,QAAQ,eAAe,WAAW,QAAQ,aAAa,CAAC;AAAA,MAC/E,SAAS,OAAO;AACd,YAAI,CAAC,WAAW;AACd,yBAAe,IAAI;AACnB,gBAAM,UACJ,iBAAiB,QACb,MAAM,UACN,EAAE,oCAAoC,yBAAyB;AACrE,gBAAM,SAAS,OAAO;AAAA,QACxB;AAAA,MACF,UAAE;AACA,YAAI,CAAC,UAAW,cAAa,KAAK;AAAA,MACpC;AAAA,IACF;AACA,SAAK;AACL,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,aAAa,aAAa,cAAc,CAAC,CAAC;AAE9C,QAAM,eAAe,MAAM,YAAY,OAAO,QAAoB;AAChE,UAAM,YAAY,MAAM,QAAQ;AAAA,MAC9B,OAAO,EAAE,uCAAuC,sBAAsB;AAAA,MACtE,SAAS;AAAA,IACX,CAAC;AACD,QAAI,CAAC,UAAW;AAChB,QAAI;AACF,YAAM,UAAU,0BAA0B,OAAO,IAAI,eAAe,WAAW,IAAI,aAAa,IAAI;AACpG,YAAM,4BAA4B,SAAS,MACzC,WAAW,oBAAoB,IAAI,IAAI;AAAA,QACrC,cAAc,EAAE,sCAAsC,0BAA0B;AAAA,MAClF,CAAC,CACF;AACD,YAAM,EAAE,kCAAkC,iBAAiB,GAAG,SAAS;AACvE,qBAAe,CAAC,UAAU,QAAQ,CAAC;AAAA,IACrC,SAAS,OAAO;AACd,YAAM,UACJ,iBAAiB,QACb,MAAM,UACN,EAAE,sCAAsC,0BAA0B;AACxE,YAAM,SAAS,OAAO;AAAA,IACxB;AAAA,EACF,GAAG,CAAC,SAAS,CAAC,CAAC;AAEf,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,iBAAkB;AACvB,qBAAiB,EAAE,QAAQ,cAAc,MAAM,CAAC;AAAA,EAClD,GAAG,CAAC,kBAAkB,QAAQ,cAAc,KAAK,CAAC;AAElD,QAAM,gBAAgB,MAAM,QAAQ,MAAM,OAAO,YAAY,IAAI,gBAAgB,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC;AAE7G,QAAM,eAAe,MAAM,QAAQ,OAAO;AAAA,IACxC,MAAM;AAAA,MACJ,QAAQ,CAAC,WACP,mBAAmB,oBAAoB,EAAE,GAAG,eAAe,aAAa,OAAO,GAAG,MAAM;AAAA,IAC5F;AAAA,IACA,MAAM;AAAA,MACJ,QAAQ,CAAC,WACP,mBAAmB,oBAAoB,EAAE,GAAG,eAAe,aAAa,QAAQ,KAAK,OAAO,GAAG,MAAM;AAAA,IACzG;AAAA,EACF,IAAI,CAAC,aAAa,CAAC;AAEnB,SACE,iCACE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,+BAA+B,qBAAqB;AAAA,QAC7D,UAAU;AAAA,QACV,4BAA4B,CAAC,cAAc,WAAW;AAAA,QACtD,eAAe;AAAA,UACb,OAAO,EAAE,oCAAoC,SAAS;AAAA,UACtD,WAAW;AAAA,UACX,cAAc;AAAA,QAChB;AAAA,QACA,SACE,qBAAC,SAAI,WAAU,2BACZ;AAAA;AAAA,UACD,oBAAC,UAAO,SAAO,MACb,8BAAC,QAAK,MAAK,oCACR,YAAE,mCAAmC,QAAQ,GAChD,GACF;AAAA,WACF;AAAA,QAEF;AAAA,QACA,MAAM;AAAA,QACN,YACE;AAAA,UAAC;AAAA;AAAA,YACC,YAAY,EAAE,+BAA+B,qBAAqB;AAAA,YAClE,YAAW;AAAA,YACX,aAAa,EAAE,mCAAmC,QAAQ;AAAA;AAAA,QAC5D;AAAA,QAEF,aAAa;AAAA,QACb,gBAAgB;AAAA,QAChB;AAAA,QACA;AAAA,QACA,gBAAgB;AAAA,QAChB,gBAAgB;AAAA,QAChB,mCAAmC;AAAA,QACnC;AAAA,QACA,iBAAiB;AAAA,QACjB,iBAAiB,gBAAgB,MAAM,cAAc;AAAA,QACrD,kBAAkB;AAAA,UAChB;AAAA,UACA,SAAS;AAAA,UACT,gBAAgB;AAAA,UAChB;AAAA,UACA;AAAA,UACA;AAAA;AAAA;AAAA;AAAA;AAAA,UAKA;AAAA,UACA,eAAe;AAAA,QACjB;AAAA,QACA,YAAY;AAAA,UACV;AAAA,UACA,UAAU;AAAA,UACV;AAAA,UACA;AAAA,UACA,cAAc;AAAA,UACd;AAAA,QACF;AAAA,QACA,UAAU;AAAA,QACV;AAAA,QACA,aAAa,EAAE,SAAS,gBAAgB,MAAM,cAAc,QAAQ;AAAA,QACpE,qBAAmB;AAAA,QACnB,YAAY,CAAC,QACX;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL;AAAA,gBACE,IAAI;AAAA,gBACJ,OAAO,EAAE,uCAAuC,MAAM;AAAA,gBACtD,MAAM,6BAA6B,IAAI,EAAE;AAAA,cAC3C;AAAA,cACA;AAAA,gBACE,IAAI;AAAA,gBACJ,OAAO,EAAE,yCAAyC,QAAQ;AAAA,gBAC1D,aAAa;AAAA,gBACb,UAAU,MAAM;AACd,uBAAK,aAAa,GAAG;AAAA,gBACvB;AAAA,cACF;AAAA,YACF;AAAA;AAAA,QACF;AAAA;AAAA,IAEJ;AAAA,IACC;AAAA,KACH;AAEJ;",
6
6
  "names": []
7
7
  }
@@ -29,7 +29,6 @@ function normalizeFilters(context) {
29
29
  }
30
30
  function computeCatalogMerchandisingPageContext(context) {
31
31
  const totalMatching = readNumber(context?.totalMatching ?? context?.total);
32
- const totalMatchingIsCapped = context?.totalIsCapped === true;
33
32
  const selectedRowIds = Array.isArray(context?.selectedRowIds) ? context.selectedRowIds : [];
34
33
  const selectedCount = selectedRowIds.length > 0 ? selectedRowIds.length : readNumber(context?.selectedCount);
35
34
  return {
@@ -40,7 +39,6 @@ function computeCatalogMerchandisingPageContext(context) {
40
39
  extra: {
41
40
  filter: normalizeFilters(context),
42
41
  totalMatching,
43
- totalMatchingIsCapped,
44
42
  selectedCount
45
43
  }
46
44
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.tsx"],
4
- "sourcesContent": ["\"use client\"\n\n/**\n * Step 5.15 \u2014 Catalog merchandising AiChat injection widget.\n *\n * Reuses the Step 4.9 `MerchandisingAssistantSheet` component but loads\n * it through the widget-injection system instead of being imported\n * directly from the products list page. `pageContext` follows spec \u00A710.1\n * exactly and is derived from the DataTable's injection context (filter\n * snapshot + total-matching count). Selection data is not exposed by the\n * shared DataTable today (Phase 2 contract); `selectedCount` ships as 0\n * until the host lifts selection into injection context.\n */\n\nimport * as React from 'react'\nimport MerchandisingAssistantSheet, {\n type MerchandisingPageContext,\n type MerchandisingPageContextFilter,\n} from '../../../backend/catalog/products/MerchandisingAssistantSheet'\n\ninterface HostInjectionContext {\n search?: string\n filters?: {\n categoryIds?: unknown\n tagIds?: unknown\n status?: unknown\n }\n customFieldset?: string | null\n page?: number\n sorting?: unknown\n scopeVersion?: unknown\n total?: number | string\n totalMatching?: number | string\n /** `totalMatching` is a floor, not an exact count (server-capped list count). */\n totalIsCapped?: boolean\n /** Selected row IDs from DataTable (auto-enriched when bulk actions are present). */\n selectedRowIds?: string[]\n selectedCount?: number\n}\n\ninterface MerchandisingAssistantTriggerProps {\n context?: HostInjectionContext\n}\n\nfunction readString(value: unknown): string | null {\n return typeof value === 'string' && value.length > 0 ? value : null\n}\n\nfunction readNumber(value: unknown): number {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string') {\n const parsed = Number.parseInt(value, 10)\n if (Number.isFinite(parsed)) return parsed\n }\n return 0\n}\n\nfunction normalizeFilters(context: HostInjectionContext | undefined): MerchandisingPageContextFilter {\n const rawCategories = context?.filters?.categoryIds\n const categoryIds = Array.isArray(rawCategories) ? rawCategories : []\n const firstCategoryId = categoryIds\n .map(readString)\n .find((value): value is string => value !== null && value.length > 0) ?? null\n\n const rawTags = context?.filters?.tagIds\n const tags = Array.isArray(rawTags)\n ? rawTags.map(readString).filter((value): value is string => value !== null)\n : []\n\n const status = readString(context?.filters?.status)\n\n return {\n categoryId: firstCategoryId,\n priceRange: null,\n tags,\n status,\n }\n}\n\n/**\n * Exposed for unit tests so the page-context derivation is exercisable\n * without mounting the widget.\n */\nexport function computeCatalogMerchandisingPageContext(\n context: HostInjectionContext | undefined,\n): MerchandisingPageContext {\n const totalMatching = readNumber(context?.totalMatching ?? context?.total)\n const totalMatchingIsCapped = context?.totalIsCapped === true\n const selectedRowIds = Array.isArray(context?.selectedRowIds) ? context.selectedRowIds : []\n const selectedCount = selectedRowIds.length > 0 ? selectedRowIds.length : readNumber(context?.selectedCount)\n return {\n view: 'catalog.products.list',\n entityType: 'catalog.products.list',\n recordType: null,\n recordId: selectedRowIds.join(','),\n extra: {\n filter: normalizeFilters(context),\n totalMatching,\n totalMatchingIsCapped,\n selectedCount,\n },\n }\n}\n\nexport default function MerchandisingAssistantTriggerWidget({\n context,\n}: MerchandisingAssistantTriggerProps) {\n const pageContext = React.useMemo(\n () => computeCatalogMerchandisingPageContext(context),\n [context],\n )\n return <MerchandisingAssistantSheet pageContext={pageContext} />\n}\n"],
5
- "mappings": ";AA+GS;AAjGT,YAAY,WAAW;AACvB,OAAO,iCAGA;AA0BP,SAAS,WAAW,OAA+B;AACjD,SAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ;AACjE;AAEA,SAAS,WAAW,OAAwB;AAC1C,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,EAAG,QAAO;AAChE,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,SAAS,OAAO,SAAS,OAAO,EAAE;AACxC,QAAI,OAAO,SAAS,MAAM,EAAG,QAAO;AAAA,EACtC;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,SAA2E;AACnG,QAAM,gBAAgB,SAAS,SAAS;AACxC,QAAM,cAAc,MAAM,QAAQ,aAAa,IAAI,gBAAgB,CAAC;AACpE,QAAM,kBAAkB,YACrB,IAAI,UAAU,EACd,KAAK,CAAC,UAA2B,UAAU,QAAQ,MAAM,SAAS,CAAC,KAAK;AAE3E,QAAM,UAAU,SAAS,SAAS;AAClC,QAAM,OAAO,MAAM,QAAQ,OAAO,IAC9B,QAAQ,IAAI,UAAU,EAAE,OAAO,CAAC,UAA2B,UAAU,IAAI,IACzE,CAAC;AAEL,QAAM,SAAS,WAAW,SAAS,SAAS,MAAM;AAElD,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AACF;AAMO,SAAS,uCACd,SAC0B;AAC1B,QAAM,gBAAgB,WAAW,SAAS,iBAAiB,SAAS,KAAK;AACzE,QAAM,wBAAwB,SAAS,kBAAkB;AACzD,QAAM,iBAAiB,MAAM,QAAQ,SAAS,cAAc,IAAI,QAAQ,iBAAiB,CAAC;AAC1F,QAAM,gBAAgB,eAAe,SAAS,IAAI,eAAe,SAAS,WAAW,SAAS,aAAa;AAC3G,SAAO;AAAA,IACL,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,UAAU,eAAe,KAAK,GAAG;AAAA,IACjC,OAAO;AAAA,MACL,QAAQ,iBAAiB,OAAO;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEe,SAAR,oCAAqD;AAAA,EAC1D;AACF,GAAuC;AACrC,QAAM,cAAc,MAAM;AAAA,IACxB,MAAM,uCAAuC,OAAO;AAAA,IACpD,CAAC,OAAO;AAAA,EACV;AACA,SAAO,oBAAC,+BAA4B,aAA0B;AAChE;",
4
+ "sourcesContent": ["\"use client\"\n\n/**\n * Step 5.15 \u2014 Catalog merchandising AiChat injection widget.\n *\n * Reuses the Step 4.9 `MerchandisingAssistantSheet` component but loads\n * it through the widget-injection system instead of being imported\n * directly from the products list page. `pageContext` follows spec \u00A710.1\n * exactly and is derived from the DataTable's injection context (filter\n * snapshot + total-matching count). Selection data is not exposed by the\n * shared DataTable today (Phase 2 contract); `selectedCount` ships as 0\n * until the host lifts selection into injection context.\n */\n\nimport * as React from 'react'\nimport MerchandisingAssistantSheet, {\n type MerchandisingPageContext,\n type MerchandisingPageContextFilter,\n} from '../../../backend/catalog/products/MerchandisingAssistantSheet'\n\ninterface HostInjectionContext {\n search?: string\n filters?: {\n categoryIds?: unknown\n tagIds?: unknown\n status?: unknown\n }\n customFieldset?: string | null\n page?: number\n sorting?: unknown\n scopeVersion?: unknown\n total?: number | string\n totalMatching?: number | string\n /** Selected row IDs from DataTable (auto-enriched when bulk actions are present). */\n selectedRowIds?: string[]\n selectedCount?: number\n}\n\ninterface MerchandisingAssistantTriggerProps {\n context?: HostInjectionContext\n}\n\nfunction readString(value: unknown): string | null {\n return typeof value === 'string' && value.length > 0 ? value : null\n}\n\nfunction readNumber(value: unknown): number {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string') {\n const parsed = Number.parseInt(value, 10)\n if (Number.isFinite(parsed)) return parsed\n }\n return 0\n}\n\nfunction normalizeFilters(context: HostInjectionContext | undefined): MerchandisingPageContextFilter {\n const rawCategories = context?.filters?.categoryIds\n const categoryIds = Array.isArray(rawCategories) ? rawCategories : []\n const firstCategoryId = categoryIds\n .map(readString)\n .find((value): value is string => value !== null && value.length > 0) ?? null\n\n const rawTags = context?.filters?.tagIds\n const tags = Array.isArray(rawTags)\n ? rawTags.map(readString).filter((value): value is string => value !== null)\n : []\n\n const status = readString(context?.filters?.status)\n\n return {\n categoryId: firstCategoryId,\n priceRange: null,\n tags,\n status,\n }\n}\n\n/**\n * Exposed for unit tests so the page-context derivation is exercisable\n * without mounting the widget.\n */\nexport function computeCatalogMerchandisingPageContext(\n context: HostInjectionContext | undefined,\n): MerchandisingPageContext {\n const totalMatching = readNumber(context?.totalMatching ?? context?.total)\n const selectedRowIds = Array.isArray(context?.selectedRowIds) ? context.selectedRowIds : []\n const selectedCount = selectedRowIds.length > 0 ? selectedRowIds.length : readNumber(context?.selectedCount)\n return {\n view: 'catalog.products.list',\n entityType: 'catalog.products.list',\n recordType: null,\n recordId: selectedRowIds.join(','),\n extra: {\n filter: normalizeFilters(context),\n totalMatching,\n selectedCount,\n },\n }\n}\n\nexport default function MerchandisingAssistantTriggerWidget({\n context,\n}: MerchandisingAssistantTriggerProps) {\n const pageContext = React.useMemo(\n () => computeCatalogMerchandisingPageContext(context),\n [context],\n )\n return <MerchandisingAssistantSheet pageContext={pageContext} />\n}\n"],
5
+ "mappings": ";AA2GS;AA7FT,YAAY,WAAW;AACvB,OAAO,iCAGA;AAwBP,SAAS,WAAW,OAA+B;AACjD,SAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ;AACjE;AAEA,SAAS,WAAW,OAAwB;AAC1C,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,EAAG,QAAO;AAChE,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,SAAS,OAAO,SAAS,OAAO,EAAE;AACxC,QAAI,OAAO,SAAS,MAAM,EAAG,QAAO;AAAA,EACtC;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,SAA2E;AACnG,QAAM,gBAAgB,SAAS,SAAS;AACxC,QAAM,cAAc,MAAM,QAAQ,aAAa,IAAI,gBAAgB,CAAC;AACpE,QAAM,kBAAkB,YACrB,IAAI,UAAU,EACd,KAAK,CAAC,UAA2B,UAAU,QAAQ,MAAM,SAAS,CAAC,KAAK;AAE3E,QAAM,UAAU,SAAS,SAAS;AAClC,QAAM,OAAO,MAAM,QAAQ,OAAO,IAC9B,QAAQ,IAAI,UAAU,EAAE,OAAO,CAAC,UAA2B,UAAU,IAAI,IACzE,CAAC;AAEL,QAAM,SAAS,WAAW,SAAS,SAAS,MAAM;AAElD,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AACF;AAMO,SAAS,uCACd,SAC0B;AAC1B,QAAM,gBAAgB,WAAW,SAAS,iBAAiB,SAAS,KAAK;AACzE,QAAM,iBAAiB,MAAM,QAAQ,SAAS,cAAc,IAAI,QAAQ,iBAAiB,CAAC;AAC1F,QAAM,gBAAgB,eAAe,SAAS,IAAI,eAAe,SAAS,WAAW,SAAS,aAAa;AAC3G,SAAO;AAAA,IACL,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,UAAU,eAAe,KAAK,GAAG;AAAA,IACjC,OAAO;AAAA,MACL,QAAQ,iBAAiB,OAAO;AAAA,MAChC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEe,SAAR,oCAAqD;AAAA,EAC1D;AACF,GAAuC;AACrC,QAAM,cAAc,MAAM;AAAA,IACxB,MAAM,uCAAuC,OAAO;AAAA,IACpD,CAAC,OAAO;AAAA,EACV;AACA,SAAO,oBAAC,+BAA4B,aAA0B;AAChE;",
6
6
  "names": []
7
7
  }