@open-mercato/core 0.10.1-develop.7709.1.046124599c → 0.10.1-develop.7714.1.9dbb8200d8

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 (276) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities/asn/index.js +19 -0
  3. package/dist/generated/entities/asn/index.js.map +7 -0
  4. package/dist/generated/entities/putaway_task/index.js +25 -0
  5. package/dist/generated/entities/putaway_task/index.js.map +7 -0
  6. package/dist/generated/entities/receiving_line/index.js +21 -0
  7. package/dist/generated/entities/receiving_line/index.js.map +7 -0
  8. package/dist/generated/entities.ids.generated.js +4 -1
  9. package/dist/generated/entities.ids.generated.js.map +2 -2
  10. package/dist/generated/entity-fields-registry.js +34 -0
  11. package/dist/generated/entity-fields-registry.js.map +2 -2
  12. package/dist/modules/communication_channels/lib/sanitize-channel-html.js +22 -3
  13. package/dist/modules/communication_channels/lib/sanitize-channel-html.js.map +2 -2
  14. package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.js +40 -11
  15. package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.js.map +2 -2
  16. package/dist/modules/customers/components/calendar/CalendarEventEditor.js +13 -2
  17. package/dist/modules/customers/components/calendar/CalendarEventEditor.js.map +2 -2
  18. package/dist/modules/wms/acl.js +2 -0
  19. package/dist/modules/wms/acl.js.map +2 -2
  20. package/dist/modules/wms/api/asns/[id]/complete/route.js +61 -0
  21. package/dist/modules/wms/api/asns/[id]/complete/route.js.map +7 -0
  22. package/dist/modules/wms/api/asns/[id]/receive/route.js +68 -0
  23. package/dist/modules/wms/api/asns/[id]/receive/route.js.map +7 -0
  24. package/dist/modules/wms/api/asns/route.js +197 -0
  25. package/dist/modules/wms/api/asns/route.js.map +7 -0
  26. package/dist/modules/wms/api/inventory/helpers.js +42 -34
  27. package/dist/modules/wms/api/inventory/helpers.js.map +2 -2
  28. package/dist/modules/wms/api/inventory/receive/route.js +1 -1
  29. package/dist/modules/wms/api/inventory/receive/route.js.map +2 -2
  30. package/dist/modules/wms/api/listEnrichers.js +23 -0
  31. package/dist/modules/wms/api/listEnrichers.js.map +2 -2
  32. package/dist/modules/wms/api/putaway-tasks/[id]/assign/route.js +56 -0
  33. package/dist/modules/wms/api/putaway-tasks/[id]/assign/route.js.map +7 -0
  34. package/dist/modules/wms/api/putaway-tasks/[id]/cancel/route.js +56 -0
  35. package/dist/modules/wms/api/putaway-tasks/[id]/cancel/route.js.map +7 -0
  36. package/dist/modules/wms/api/putaway-tasks/[id]/complete/route.js +65 -0
  37. package/dist/modules/wms/api/putaway-tasks/[id]/complete/route.js.map +7 -0
  38. package/dist/modules/wms/api/putaway-tasks/[id]/start/route.js +56 -0
  39. package/dist/modules/wms/api/putaway-tasks/[id]/start/route.js.map +7 -0
  40. package/dist/modules/wms/api/putaway-tasks/create-from-balance/route.js +51 -0
  41. package/dist/modules/wms/api/putaway-tasks/create-from-balance/route.js.map +7 -0
  42. package/dist/modules/wms/api/putaway-tasks/route.js +192 -0
  43. package/dist/modules/wms/api/putaway-tasks/route.js.map +7 -0
  44. package/dist/modules/wms/api/receiving-lines/route.js +180 -0
  45. package/dist/modules/wms/api/receiving-lines/route.js.map +7 -0
  46. package/dist/modules/wms/api/scan/putaway/route.js +104 -0
  47. package/dist/modules/wms/api/scan/putaway/route.js.map +7 -0
  48. package/dist/modules/wms/api/scan/receive/route.js +109 -0
  49. package/dist/modules/wms/api/scan/receive/route.js.map +7 -0
  50. package/dist/modules/wms/api/scan/resolve-location/route.js +89 -0
  51. package/dist/modules/wms/api/scan/resolve-location/route.js.map +7 -0
  52. package/dist/modules/wms/api/scan/resolve-lot/route.js +89 -0
  53. package/dist/modules/wms/api/scan/resolve-lot/route.js.map +7 -0
  54. package/dist/modules/wms/backend/wms/asns/[id]/page.js +9 -0
  55. package/dist/modules/wms/backend/wms/asns/[id]/page.js.map +7 -0
  56. package/dist/modules/wms/backend/wms/asns/[id]/page.meta.js +18 -0
  57. package/dist/modules/wms/backend/wms/asns/[id]/page.meta.js.map +7 -0
  58. package/dist/modules/wms/backend/wms/asns/page.js +9 -0
  59. package/dist/modules/wms/backend/wms/asns/page.js.map +7 -0
  60. package/dist/modules/wms/backend/wms/asns/page.meta.js +18 -0
  61. package/dist/modules/wms/backend/wms/asns/page.meta.js.map +7 -0
  62. package/dist/modules/wms/backend/wms/putaway/page.js +9 -0
  63. package/dist/modules/wms/backend/wms/putaway/page.js.map +7 -0
  64. package/dist/modules/wms/backend/wms/putaway/page.meta.js +18 -0
  65. package/dist/modules/wms/backend/wms/putaway/page.meta.js.map +7 -0
  66. package/dist/modules/wms/backend/wms/receiving/page.js +8 -0
  67. package/dist/modules/wms/backend/wms/receiving/page.js.map +7 -0
  68. package/dist/modules/wms/backend/wms/receiving/page.meta.js +18 -0
  69. package/dist/modules/wms/backend/wms/receiving/page.meta.js.map +7 -0
  70. package/dist/modules/wms/ce.js +27 -0
  71. package/dist/modules/wms/ce.js.map +2 -2
  72. package/dist/modules/wms/commands/asn.js +1746 -0
  73. package/dist/modules/wms/commands/asn.js.map +7 -0
  74. package/dist/modules/wms/commands/index.js +2 -0
  75. package/dist/modules/wms/commands/index.js.map +2 -2
  76. package/dist/modules/wms/commands/inventory-actions.js +347 -243
  77. package/dist/modules/wms/commands/inventory-actions.js.map +2 -2
  78. package/dist/modules/wms/commands/putaway.js +945 -0
  79. package/dist/modules/wms/commands/putaway.js.map +7 -0
  80. package/dist/modules/wms/commands/shared.js +51 -0
  81. package/dist/modules/wms/commands/shared.js.map +2 -2
  82. package/dist/modules/wms/components/backend/AssignPutawayTaskDialog.js +278 -0
  83. package/dist/modules/wms/components/backend/AssignPutawayTaskDialog.js.map +7 -0
  84. package/dist/modules/wms/components/backend/CompletePutawayTaskDialog.js +327 -0
  85. package/dist/modules/wms/components/backend/CompletePutawayTaskDialog.js.map +7 -0
  86. package/dist/modules/wms/components/backend/CreateAsnDialog.js +404 -0
  87. package/dist/modules/wms/components/backend/CreateAsnDialog.js.map +7 -0
  88. package/dist/modules/wms/components/backend/InventoryOperationsSection.js +16 -3
  89. package/dist/modules/wms/components/backend/InventoryOperationsSection.js.map +2 -2
  90. package/dist/modules/wms/components/backend/ReceiveAsnLineDialog.js +476 -0
  91. package/dist/modules/wms/components/backend/ReceiveAsnLineDialog.js.map +7 -0
  92. package/dist/modules/wms/components/backend/ReceiveInventoryDialog.js +2 -2
  93. package/dist/modules/wms/components/backend/ReceiveInventoryDialog.js.map +2 -2
  94. package/dist/modules/wms/components/backend/WmsAsnDetailPage.js +524 -0
  95. package/dist/modules/wms/components/backend/WmsAsnDetailPage.js.map +7 -0
  96. package/dist/modules/wms/components/backend/WmsAsnsListPage.js +339 -0
  97. package/dist/modules/wms/components/backend/WmsAsnsListPage.js.map +7 -0
  98. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js +5 -6
  99. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js.map +2 -2
  100. package/dist/modules/wms/components/backend/WmsLotDetailPage.js +5 -6
  101. package/dist/modules/wms/components/backend/WmsLotDetailPage.js.map +2 -2
  102. package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js +14 -10
  103. package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js.map +2 -2
  104. package/dist/modules/wms/components/backend/WmsPutawayQueuePage.js +598 -0
  105. package/dist/modules/wms/components/backend/WmsPutawayQueuePage.js.map +7 -0
  106. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js +5 -6
  107. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js.map +2 -2
  108. package/dist/modules/wms/components/backend/asnCompleteOptimisticLock.js +32 -0
  109. package/dist/modules/wms/components/backend/asnCompleteOptimisticLock.js.map +7 -0
  110. package/dist/modules/wms/components/backend/asnReceivingLinesLoader.js +36 -0
  111. package/dist/modules/wms/components/backend/asnReceivingLinesLoader.js.map +7 -0
  112. package/dist/modules/wms/components/backend/inboundStatusUi.js +106 -0
  113. package/dist/modules/wms/components/backend/inboundStatusUi.js.map +7 -0
  114. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js +17 -0
  115. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js.map +2 -2
  116. package/dist/modules/wms/components/backend/putawayQueueOptimisticLock.js +14 -0
  117. package/dist/modules/wms/components/backend/putawayQueueOptimisticLock.js.map +7 -0
  118. package/dist/modules/wms/components/backend/useWmsInventoryMutationAccess.js +4 -0
  119. package/dist/modules/wms/components/backend/useWmsInventoryMutationAccess.js.map +2 -2
  120. package/dist/modules/wms/data/enrichers.js +117 -12
  121. package/dist/modules/wms/data/enrichers.js.map +2 -2
  122. package/dist/modules/wms/data/entities.js +150 -1
  123. package/dist/modules/wms/data/entities.js.map +2 -2
  124. package/dist/modules/wms/data/validators.js +214 -0
  125. package/dist/modules/wms/data/validators.js.map +2 -2
  126. package/dist/modules/wms/events.js +12 -1
  127. package/dist/modules/wms/events.js.map +2 -2
  128. package/dist/modules/wms/extension-points.js +3 -1
  129. package/dist/modules/wms/extension-points.js.map +2 -2
  130. package/dist/modules/wms/lib/asnReceiving.js +124 -0
  131. package/dist/modules/wms/lib/asnReceiving.js.map +7 -0
  132. package/dist/modules/wms/lib/asnVendor.js +52 -0
  133. package/dist/modules/wms/lib/asnVendor.js.map +7 -0
  134. package/dist/modules/wms/lib/flashMutationError.js +4 -0
  135. package/dist/modules/wms/lib/flashMutationError.js.map +2 -2
  136. package/dist/modules/wms/lib/inventoryDisplayUi.js +24 -0
  137. package/dist/modules/wms/lib/inventoryDisplayUi.js.map +2 -2
  138. package/dist/modules/wms/lib/inventoryPolicy.js +17 -0
  139. package/dist/modules/wms/lib/inventoryPolicy.js.map +2 -2
  140. package/dist/modules/wms/lib/loadOperationalDashboard.js +67 -1
  141. package/dist/modules/wms/lib/loadOperationalDashboard.js.map +2 -2
  142. package/dist/modules/wms/lib/putaway.js +141 -0
  143. package/dist/modules/wms/lib/putaway.js.map +7 -0
  144. package/dist/modules/wms/lib/roleFeatures.js +3 -1
  145. package/dist/modules/wms/lib/roleFeatures.js.map +2 -2
  146. package/dist/modules/wms/lib/salesOrderInventoryAutomation.js +99 -1
  147. package/dist/modules/wms/lib/salesOrderInventoryAutomation.js.map +2 -2
  148. package/dist/modules/wms/lib/scanResolve.js +147 -0
  149. package/dist/modules/wms/lib/scanResolve.js.map +7 -0
  150. package/dist/modules/wms/lib/wmsIntegrationToggles.js +1 -1
  151. package/dist/modules/wms/lib/wmsIntegrationToggles.js.map +2 -2
  152. package/dist/modules/wms/migrations/Migration20260812120000.js +43 -0
  153. package/dist/modules/wms/migrations/Migration20260812120000.js.map +7 -0
  154. package/dist/modules/wms/migrations/Migration20260812130000.js +30 -0
  155. package/dist/modules/wms/migrations/Migration20260812130000.js.map +7 -0
  156. package/dist/modules/wms/migrations/Migration20260822120000.js +17 -0
  157. package/dist/modules/wms/migrations/Migration20260822120000.js.map +7 -0
  158. package/dist/modules/wms/migrations/Migration20260822130000.js +17 -0
  159. package/dist/modules/wms/migrations/Migration20260822130000.js.map +7 -0
  160. package/dist/modules/wms/migrations/Migration20261029120000.js +13 -0
  161. package/dist/modules/wms/migrations/Migration20261029120000.js.map +7 -0
  162. package/dist/modules/wms/search.js +85 -0
  163. package/dist/modules/wms/search.js.map +2 -2
  164. package/dist/modules/wms/subscribers/asn-line-received-reevaluate-reservations.js +14 -0
  165. package/dist/modules/wms/subscribers/asn-line-received-reevaluate-reservations.js.map +7 -0
  166. package/dist/modules/wms/subscribers/invalidate-enricher-cache-asn.js +12 -0
  167. package/dist/modules/wms/subscribers/invalidate-enricher-cache-asn.js.map +7 -0
  168. package/dist/modules/wms/subscribers/procurement-goods-receipt-created.js +163 -0
  169. package/dist/modules/wms/subscribers/procurement-goods-receipt-created.js.map +7 -0
  170. package/dist/modules/wms/subscribers/putaway-completed-reevaluate-reservations.js +14 -0
  171. package/dist/modules/wms/subscribers/putaway-completed-reevaluate-reservations.js.map +7 -0
  172. package/dist/modules/wms/widgets/injection/sales-order-stock-context/widget.client.js +37 -8
  173. package/dist/modules/wms/widgets/injection/sales-order-stock-context/widget.client.js.map +2 -2
  174. package/generated/entities/asn/index.ts +8 -0
  175. package/generated/entities/putaway_task/index.ts +11 -0
  176. package/generated/entities/receiving_line/index.ts +9 -0
  177. package/generated/entities.ids.generated.ts +4 -1
  178. package/generated/entity-fields-registry.ts +34 -0
  179. package/package.json +7 -7
  180. package/src/modules/auth/i18n/de.json +2 -0
  181. package/src/modules/auth/i18n/en.json +2 -0
  182. package/src/modules/auth/i18n/es.json +2 -0
  183. package/src/modules/auth/i18n/ko.json +2 -0
  184. package/src/modules/auth/i18n/pl.json +2 -0
  185. package/src/modules/communication_channels/i18n/de.json +2 -0
  186. package/src/modules/communication_channels/i18n/en.json +2 -0
  187. package/src/modules/communication_channels/i18n/es.json +2 -0
  188. package/src/modules/communication_channels/i18n/ko.json +2 -0
  189. package/src/modules/communication_channels/i18n/pl.json +2 -0
  190. package/src/modules/communication_channels/lib/sanitize-channel-html.ts +23 -3
  191. package/src/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.tsx +44 -12
  192. package/src/modules/customers/components/calendar/CalendarEventEditor.tsx +16 -2
  193. package/src/modules/wms/acl.ts +2 -0
  194. package/src/modules/wms/api/asns/[id]/complete/route.ts +62 -0
  195. package/src/modules/wms/api/asns/[id]/receive/route.ts +74 -0
  196. package/src/modules/wms/api/asns/route.ts +200 -0
  197. package/src/modules/wms/api/inventory/helpers.ts +57 -34
  198. package/src/modules/wms/api/inventory/receive/route.ts +2 -1
  199. package/src/modules/wms/api/listEnrichers.ts +38 -0
  200. package/src/modules/wms/api/putaway-tasks/[id]/assign/route.ts +56 -0
  201. package/src/modules/wms/api/putaway-tasks/[id]/cancel/route.ts +56 -0
  202. package/src/modules/wms/api/putaway-tasks/[id]/complete/route.ts +66 -0
  203. package/src/modules/wms/api/putaway-tasks/[id]/start/route.ts +56 -0
  204. package/src/modules/wms/api/putaway-tasks/create-from-balance/route.ts +50 -0
  205. package/src/modules/wms/api/putaway-tasks/route.ts +199 -0
  206. package/src/modules/wms/api/receiving-lines/route.ts +180 -0
  207. package/src/modules/wms/api/scan/putaway/route.ts +108 -0
  208. package/src/modules/wms/api/scan/receive/route.ts +118 -0
  209. package/src/modules/wms/api/scan/resolve-location/route.ts +92 -0
  210. package/src/modules/wms/api/scan/resolve-lot/route.ts +92 -0
  211. package/src/modules/wms/backend/wms/asns/[id]/page.meta.ts +14 -0
  212. package/src/modules/wms/backend/wms/asns/[id]/page.tsx +5 -0
  213. package/src/modules/wms/backend/wms/asns/page.meta.ts +14 -0
  214. package/src/modules/wms/backend/wms/asns/page.tsx +5 -0
  215. package/src/modules/wms/backend/wms/putaway/page.meta.ts +14 -0
  216. package/src/modules/wms/backend/wms/putaway/page.tsx +5 -0
  217. package/src/modules/wms/backend/wms/receiving/page.meta.ts +14 -0
  218. package/src/modules/wms/backend/wms/receiving/page.tsx +5 -0
  219. package/src/modules/wms/ce.ts +27 -0
  220. package/src/modules/wms/commands/asn.ts +2122 -0
  221. package/src/modules/wms/commands/index.ts +2 -0
  222. package/src/modules/wms/commands/inventory-actions.ts +413 -243
  223. package/src/modules/wms/commands/putaway.ts +1169 -0
  224. package/src/modules/wms/commands/shared.ts +51 -0
  225. package/src/modules/wms/components/backend/AssignPutawayTaskDialog.tsx +328 -0
  226. package/src/modules/wms/components/backend/CompletePutawayTaskDialog.tsx +366 -0
  227. package/src/modules/wms/components/backend/CreateAsnDialog.tsx +427 -0
  228. package/src/modules/wms/components/backend/InventoryOperationsSection.tsx +20 -2
  229. package/src/modules/wms/components/backend/ReceiveAsnLineDialog.tsx +535 -0
  230. package/src/modules/wms/components/backend/ReceiveInventoryDialog.tsx +2 -2
  231. package/src/modules/wms/components/backend/WmsAsnDetailPage.tsx +647 -0
  232. package/src/modules/wms/components/backend/WmsAsnsListPage.tsx +407 -0
  233. package/src/modules/wms/components/backend/WmsLocationDetailPage.tsx +4 -5
  234. package/src/modules/wms/components/backend/WmsLotDetailPage.tsx +4 -5
  235. package/src/modules/wms/components/backend/WmsOperationalDashboardPage.tsx +12 -8
  236. package/src/modules/wms/components/backend/WmsPutawayQueuePage.tsx +677 -0
  237. package/src/modules/wms/components/backend/WmsSkuDetailPage.tsx +4 -5
  238. package/src/modules/wms/components/backend/asnCompleteOptimisticLock.ts +52 -0
  239. package/src/modules/wms/components/backend/asnReceivingLinesLoader.ts +83 -0
  240. package/src/modules/wms/components/backend/inboundStatusUi.ts +154 -0
  241. package/src/modules/wms/components/backend/inventoryMutationLoaders.ts +20 -0
  242. package/src/modules/wms/components/backend/putawayQueueOptimisticLock.ts +20 -0
  243. package/src/modules/wms/components/backend/useWmsInventoryMutationAccess.ts +4 -0
  244. package/src/modules/wms/data/enrichers.ts +175 -13
  245. package/src/modules/wms/data/entities.ts +155 -0
  246. package/src/modules/wms/data/validators.ts +256 -0
  247. package/src/modules/wms/events.ts +11 -0
  248. package/src/modules/wms/extension-points.ts +2 -0
  249. package/src/modules/wms/i18n/de.json +205 -3
  250. package/src/modules/wms/i18n/en.json +205 -3
  251. package/src/modules/wms/i18n/es.json +205 -3
  252. package/src/modules/wms/i18n/ko.json +205 -3
  253. package/src/modules/wms/i18n/pl.json +205 -3
  254. package/src/modules/wms/lib/asnReceiving.ts +226 -0
  255. package/src/modules/wms/lib/asnVendor.ts +80 -0
  256. package/src/modules/wms/lib/flashMutationError.ts +4 -0
  257. package/src/modules/wms/lib/inventoryDisplayUi.ts +46 -0
  258. package/src/modules/wms/lib/inventoryPolicy.ts +31 -1
  259. package/src/modules/wms/lib/loadOperationalDashboard.ts +89 -1
  260. package/src/modules/wms/lib/putaway.ts +210 -0
  261. package/src/modules/wms/lib/roleFeatures.ts +2 -0
  262. package/src/modules/wms/lib/salesOrderInventoryAutomation.ts +150 -1
  263. package/src/modules/wms/lib/scanResolve.ts +185 -0
  264. package/src/modules/wms/lib/wmsIntegrationToggles.ts +2 -1
  265. package/src/modules/wms/migrations/.snapshot-open-mercato.json +1000 -0
  266. package/src/modules/wms/migrations/Migration20260812120000.ts +43 -0
  267. package/src/modules/wms/migrations/Migration20260812130000.ts +28 -0
  268. package/src/modules/wms/migrations/Migration20260822120000.ts +17 -0
  269. package/src/modules/wms/migrations/Migration20260822130000.ts +15 -0
  270. package/src/modules/wms/migrations/Migration20261029120000.ts +11 -0
  271. package/src/modules/wms/search.ts +95 -0
  272. package/src/modules/wms/subscribers/asn-line-received-reevaluate-reservations.ts +21 -0
  273. package/src/modules/wms/subscribers/invalidate-enricher-cache-asn.ts +12 -0
  274. package/src/modules/wms/subscribers/procurement-goods-receipt-created.ts +238 -0
  275. package/src/modules/wms/subscribers/putaway-completed-reevaluate-reservations.ts +21 -0
  276. package/src/modules/wms/widgets/injection/sales-order-stock-context/widget.client.tsx +63 -13
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/wms/widgets/injection/sales-order-stock-context/widget.client.tsx"],
4
- "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { RefreshCw, ShieldOff } from 'lucide-react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport {\n StatusBadge,\n type StatusMap,\n} from '@open-mercato/ui/primitives/status-badge'\nimport { ComboboxInput } from '@open-mercato/ui/backend/inputs/ComboboxInput'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { raiseCrudError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport type { InjectionWidgetComponentProps } from '@open-mercato/shared/modules/widgets/injection'\nimport { useWmsInventoryMutationAccess } from '../../../components/backend/useWmsInventoryMutationAccess'\nimport { loadWarehouseOptions } from '../../../components/backend/wmsLookupLoaders'\nimport {\n resolveCatalogVariantLabel,\n resolveWarehouseLabel,\n} from '../../../components/backend/inventoryMutationLoaders'\nimport { ReleaseReservationDialog } from '../../../components/backend/ReleaseReservationDialog'\n\ntype ReservationStatus =\n | 'unreserved'\n | 'partially_reserved'\n | 'fully_reserved'\n\ntype SalesOrderWmsPayload = {\n assignedWarehouseId?: string | null\n assignedWarehouseName?: string | null\n isExplicitlyAssigned?: boolean\n stockSummary?: Array<{\n catalogVariantId?: string\n available?: string\n reserved?: string\n }>\n reservationSummary?: {\n status?: ReservationStatus\n reservationIds?: string[]\n }\n}\n\nexport type SalesOrderRecord = Record<string, unknown> & {\n id?: string\n status?: string | null\n _wms?: SalesOrderWmsPayload\n}\n\nconst reservationStatusMap: StatusMap<ReservationStatus> = {\n unreserved: 'neutral',\n partially_reserved: 'warning',\n fully_reserved: 'success',\n}\n\nfunction formatQuantity(value: unknown): string {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value.toString()\n }\n if (typeof value === 'string' && value.trim().length > 0) {\n return value\n }\n return '0'\n}\n\nfunction isCancelledOrder(data: SalesOrderRecord | undefined): boolean {\n const status = typeof data?.status === 'string' ? data.status.trim() : ''\n return status === 'canceled' || status === 'cancelled'\n}\n\nfunction resolveOrderId(data: SalesOrderRecord | undefined): string | null {\n return typeof data?.id === 'string' && data.id.length > 0 ? data.id : null\n}\n\nexport default function SalesOrderStockContextWidget(\n props: InjectionWidgetComponentProps<unknown, SalesOrderRecord>,\n) {\n const { data } = props\n const t = useT()\n const router = useRouter()\n const { organizationId, tenantId } = useOrganizationScopeDetail()\n const access = useWmsInventoryMutationAccess()\n const orderId = resolveOrderId(data)\n const wms = data?._wms\n const [selectedWarehouseId, setSelectedWarehouseId] = React.useState<string | null>(null)\n const [saving, setSaving] = React.useState(false)\n const [rerunning, setRerunning] = React.useState(false)\n const [variantLabels, setVariantLabels] = React.useState<Map<string, string>>(new Map())\n const [releaseReservationId, setReleaseReservationId] = React.useState<string | null>(null)\n\n const { runMutation, retryLastMutation } = useGuardedMutation({\n contextId: 'wms-sales-order-warehouse-assignment',\n })\n const mutationContext = React.useMemo(\n () => ({ retryLastMutation }),\n [retryLastMutation],\n )\n\n React.useEffect(() => {\n if (wms?.isExplicitlyAssigned && wms.assignedWarehouseId) {\n setSelectedWarehouseId(wms.assignedWarehouseId)\n return\n }\n setSelectedWarehouseId(null)\n }, [wms?.assignedWarehouseId, wms?.isExplicitlyAssigned])\n\n const stockSummary = React.useMemo(\n () => (Array.isArray(wms?.stockSummary) ? wms.stockSummary : []),\n [wms?.stockSummary],\n )\n\n React.useEffect(() => {\n const variantIds = stockSummary\n .map((item) => item.catalogVariantId)\n .filter((id): id is string => !!id)\n if (variantIds.length === 0) return\n void (async () => {\n const entries = await Promise.all(\n variantIds.map(async (id) => {\n const label = await resolveCatalogVariantLabel(id)\n return [id, label ?? id] as const\n }),\n )\n setVariantLabels(new Map(entries))\n })()\n }, [stockSummary])\n\n const canManageAssignment = access.canRelease\n const assignedLabel =\n wms?.assignedWarehouseName ||\n (wms?.isExplicitlyAssigned ? wms.assignedWarehouseId : null) ||\n t('wms.widgets.sales.stockContext.unassigned', 'Not assigned')\n\n const warehouseSeedOptions = React.useMemo(() => {\n if (!wms?.assignedWarehouseId) return []\n const label = wms.assignedWarehouseName?.trim() || wms.assignedWarehouseId\n return [{ value: wms.assignedWarehouseId, label }]\n }, [wms?.assignedWarehouseId, wms?.assignedWarehouseName])\n\n const resolveWarehouseComboboxLabel = React.useCallback(async (value: string) => {\n if (wms?.assignedWarehouseId === value && wms.assignedWarehouseName?.trim()) {\n return wms.assignedWarehouseName.trim()\n }\n const label = await resolveWarehouseLabel(value)\n return label ?? value\n }, [wms?.assignedWarehouseId, wms?.assignedWarehouseName])\n\n const persistAssignment = React.useCallback(\n async (warehouseId: string | null) => {\n if (!orderId || !organizationId || !tenantId) return\n setSaving(true)\n try {\n const mutationPayload = {\n organizationId,\n tenantId,\n warehouseId,\n }\n await runMutation({\n operation: async () => {\n if (warehouseId) {\n const response = await apiCall<{ ok?: boolean }>(\n `/api/wms/sales-orders/${orderId}/warehouse-assignment`,\n {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(mutationPayload),\n },\n )\n if (!response.ok) await raiseCrudError(response.response)\n } else {\n const response = await apiCall<{ ok?: boolean }>(\n `/api/wms/sales-orders/${orderId}/warehouse-assignment`,\n {\n method: 'DELETE',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n organizationId,\n tenantId,\n }),\n },\n )\n if (!response.ok) await raiseCrudError(response.response)\n }\n },\n context: mutationContext,\n mutationPayload,\n })\n\n router.refresh()\n flash(\n warehouseId\n ? t(\n 'wms.widgets.sales.stockContext.assignSuccess',\n 'Warehouse assignment saved.',\n )\n : t(\n 'wms.widgets.sales.stockContext.unassignSuccess',\n 'Warehouse assignment cleared.',\n ),\n 'success',\n )\n } catch {\n flash(\n t(\n 'wms.widgets.sales.stockContext.assignError',\n 'Could not update warehouse assignment.',\n ),\n 'error',\n )\n } finally {\n setSaving(false)\n }\n },\n [mutationContext, orderId, organizationId, router, runMutation, t, tenantId],\n )\n\n const handleRerunReservation = React.useCallback(async () => {\n if (!orderId || !organizationId || !tenantId) return\n setRerunning(true)\n try {\n const response = await apiCall<{ ok?: boolean }>(\n `/api/wms/sales-orders/${orderId}/re-run-reservation`,\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ organizationId, tenantId }),\n },\n )\n if (!response.ok) await raiseCrudError(response.response)\n router.refresh()\n flash(\n t(\n 'wms.widgets.sales.stockContext.rerunSuccess',\n 'Reservation re-run triggered. Stock context will refresh shortly.',\n ),\n 'success',\n )\n } catch {\n flash(\n t(\n 'wms.widgets.sales.stockContext.rerunError',\n 'Could not re-run reservation.',\n ),\n 'error',\n )\n } finally {\n setRerunning(false)\n }\n }, [orderId, organizationId, router, t, tenantId])\n\n if (!wms) return null\n\n const reservationStatus = wms.reservationSummary?.status ?? 'unreserved'\n const reservationIds = Array.isArray(wms.reservationSummary?.reservationIds)\n ? (wms.reservationSummary?.reservationIds ?? [])\n : []\n\n const releaseReservation = releaseReservationId\n ? { id: releaseReservationId }\n : null\n\n return (\n <div className=\"rounded-lg border bg-card px-4 py-3 space-y-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"space-y-1\">\n <p className=\"text-sm font-medium\">\n {t(\n 'wms.widgets.sales.stockContext.title',\n 'WMS stock context',\n )}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.description',\n 'Live reservation and availability summary for this sales order.',\n )}\n </p>\n </div>\n <StatusBadge\n variant={reservationStatusMap[reservationStatus]}\n dot\n >\n {t(\n `wms.widgets.sales.stockContext.status.${reservationStatus}`,\n reservationStatus,\n )}\n </StatusBadge>\n </div>\n\n <dl className=\"grid gap-3 text-sm sm:grid-cols-2\">\n <div className=\"space-y-2 sm:col-span-2\">\n <dt className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.assignedWarehouse',\n 'Assigned warehouse',\n )}\n </dt>\n <dd>\n {canManageAssignment && orderId ? (\n <ComboboxInput\n value={selectedWarehouseId ?? ''}\n onChange={(value) => {\n const nextValue = value.trim().length > 0 ? value : null\n setSelectedWarehouseId(nextValue)\n void persistAssignment(nextValue)\n }}\n seedOptions={warehouseSeedOptions}\n resolveLabel={resolveWarehouseComboboxLabel}\n loadSuggestions={async (query) => {\n const options = await loadWarehouseOptions(query)\n return options.map((option) => ({\n value: option.value,\n label: option.label,\n }))\n }}\n placeholder={t(\n 'wms.widgets.sales.stockContext.warehousePlaceholder',\n 'Select a warehouse',\n )}\n allowCustomValues={false}\n disabled={saving}\n />\n ) : (\n <span className=\"font-medium\">{assignedLabel}</span>\n )}\n </dd>\n {wms.isExplicitlyAssigned ? (\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.explicitAssignmentHint',\n 'Explicit assignment overrides reservation-derived warehouse context.',\n )}\n </p>\n ) : null}\n </div>\n <div className=\"space-y-1\">\n <dt className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.reservationCount',\n 'Reservation records',\n )}\n </dt>\n <dd className=\"font-medium\">{reservationIds.length}</dd>\n </div>\n </dl>\n\n {stockSummary.length > 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.linesTitle',\n 'Variant availability',\n )}\n </p>\n <div className=\"space-y-2\">\n {stockSummary.map((item) => {\n const id = item.catalogVariantId ?? 'unknown'\n const label = variantLabels.get(id) ?? id\n return (\n <div\n key={id}\n className=\"rounded-md border border-border/70 bg-background px-3 py-2\"\n >\n <p className=\"text-sm font-medium\">{label}</p>\n <div className=\"mt-1 flex flex-wrap gap-4 text-xs text-muted-foreground\">\n <span>\n {t(\n 'wms.widgets.sales.stockContext.available',\n 'Available',\n )}\n {': '}\n {formatQuantity(item.available)}\n </span>\n <span>\n {t(\n 'wms.widgets.sales.stockContext.reserved',\n 'Reserved',\n )}\n {': '}\n {formatQuantity(item.reserved)}\n </span>\n </div>\n </div>\n )\n })}\n </div>\n </div>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.empty',\n 'No WMS stock summary is available for this order yet.',\n )}\n </p>\n )}\n\n {access.canRelease && reservationIds.length > 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.reservationsTitle',\n 'Active reservations',\n )}\n </p>\n <div className=\"space-y-1\">\n {reservationIds.map((rid) => (\n <div\n key={rid}\n className=\"flex items-center justify-between gap-2 rounded-md border border-border/70 bg-background px-3 py-1.5\"\n >\n <span className=\"font-mono text-xs text-muted-foreground truncate\">{rid}</span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-6 shrink-0 px-2 text-xs text-status-error-fg hover:text-status-error-fg\"\n onClick={() => setReleaseReservationId(rid)}\n >\n <ShieldOff className=\"size-3 mr-1\" />\n {t('wms.widgets.sales.stockContext.releaseBtn', 'Release')}\n </Button>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n\n <div className=\"flex flex-wrap gap-2\">\n {reservationStatus !== 'fully_reserved' && access.canRelease && orderId && !isCancelledOrder(data) ? (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n disabled={rerunning}\n onClick={() => void handleRerunReservation()}\n >\n <RefreshCw className={`size-3 mr-1.5 ${rerunning ? 'animate-spin' : ''}`} />\n {t(\n 'wms.widgets.sales.stockContext.actions.rerunReservation',\n 'Re-run reservation',\n )}\n </Button>\n ) : null}\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link href=\"/backend/wms/inventory\">\n {t(\n 'wms.widgets.sales.stockContext.actions.inventory',\n 'Open inventory console',\n )}\n </Link>\n </Button>\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link href=\"/backend/wms/reservations\">\n {t(\n 'wms.widgets.sales.stockContext.actions.reservations',\n 'Open reservations',\n )}\n </Link>\n </Button>\n </div>\n\n {access.canRelease ? (\n <ReleaseReservationDialog\n open={releaseReservationId !== null}\n onOpenChange={(open) => {\n if (!open) setReleaseReservationId(null)\n }}\n access={access}\n reservation={releaseReservation}\n onSuccess={() => {\n setReleaseReservationId(null)\n router.refresh()\n }}\n />\n ) : null}\n </div>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { RefreshCw, ShieldOff } from 'lucide-react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport {\n StatusBadge,\n type StatusMap,\n} from '@open-mercato/ui/primitives/status-badge'\nimport { ComboboxInput } from '@open-mercato/ui/backend/inputs/ComboboxInput'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { raiseCrudError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport type { InjectionWidgetComponentProps } from '@open-mercato/shared/modules/widgets/injection'\nimport { useWmsInventoryMutationAccess } from '../../../components/backend/useWmsInventoryMutationAccess'\nimport { loadWarehouseOptions } from '../../../components/backend/wmsLookupLoaders'\nimport {\n resolveCatalogVariantLabel,\n resolveWarehouseLabel,\n} from '../../../components/backend/inventoryMutationLoaders'\nimport { ReleaseReservationDialog } from '../../../components/backend/ReleaseReservationDialog'\n\ntype ReservationStatus =\n | 'unreserved'\n | 'partially_reserved'\n | 'fully_reserved'\n\ntype SalesOrderWmsPayload = {\n assignedWarehouseId?: string | null\n assignedWarehouseName?: string | null\n isExplicitlyAssigned?: boolean\n stockSummary?: Array<{\n catalogVariantId?: string\n available?: string\n reserved?: string\n }>\n reservationSummary?: {\n status?: ReservationStatus\n reservationIds?: string[]\n reservations?: Array<{\n id?: string\n reservationLabel?: string\n catalogVariantId?: string\n warehouseId?: string | null\n warehouseName?: string | null\n quantity?: string\n variantName?: string | null\n variantSku?: string | null\n }>\n }\n}\n\nexport type SalesOrderRecord = Record<string, unknown> & {\n id?: string\n status?: string | null\n _wms?: SalesOrderWmsPayload\n}\n\nconst reservationStatusMap: StatusMap<ReservationStatus> = {\n unreserved: 'neutral',\n partially_reserved: 'warning',\n fully_reserved: 'success',\n}\n\nfunction formatQuantity(value: unknown): string {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value.toString()\n }\n if (typeof value === 'string' && value.trim().length > 0) {\n return value\n }\n return '0'\n}\n\nfunction isCancelledOrder(data: SalesOrderRecord | undefined): boolean {\n const status = typeof data?.status === 'string' ? data.status.trim() : ''\n return status === 'canceled' || status === 'cancelled'\n}\n\nfunction resolveOrderId(data: SalesOrderRecord | undefined): string | null {\n return typeof data?.id === 'string' && data.id.length > 0 ? data.id : null\n}\n\nexport default function SalesOrderStockContextWidget(\n props: InjectionWidgetComponentProps<unknown, SalesOrderRecord>,\n) {\n const { data } = props\n const t = useT()\n const router = useRouter()\n const { organizationId, tenantId } = useOrganizationScopeDetail()\n const access = useWmsInventoryMutationAccess()\n const orderId = resolveOrderId(data)\n const wms = data?._wms\n const [selectedWarehouseId, setSelectedWarehouseId] = React.useState<string | null>(null)\n const [saving, setSaving] = React.useState(false)\n const [rerunning, setRerunning] = React.useState(false)\n const [variantLabels, setVariantLabels] = React.useState<Map<string, string>>(new Map())\n const [releaseReservationId, setReleaseReservationId] = React.useState<string | null>(null)\n\n const { runMutation, retryLastMutation } = useGuardedMutation({\n contextId: 'wms-sales-order-warehouse-assignment',\n })\n const mutationContext = React.useMemo(\n () => ({ retryLastMutation }),\n [retryLastMutation],\n )\n\n React.useEffect(() => {\n if (wms?.isExplicitlyAssigned && wms.assignedWarehouseId) {\n setSelectedWarehouseId(wms.assignedWarehouseId)\n return\n }\n setSelectedWarehouseId(null)\n }, [wms?.assignedWarehouseId, wms?.isExplicitlyAssigned])\n\n const stockSummary = React.useMemo(\n () => (Array.isArray(wms?.stockSummary) ? wms.stockSummary : []),\n [wms?.stockSummary],\n )\n\n const activeReservations = React.useMemo(() => {\n const enriched = Array.isArray(wms?.reservationSummary?.reservations)\n ? (wms.reservationSummary?.reservations ?? [])\n : []\n const fromEnriched = enriched\n .map((item) => {\n const id = typeof item?.id === 'string' ? item.id : null\n if (!id) return null\n const reservationLabel =\n typeof item.reservationLabel === 'string' && item.reservationLabel.trim().length > 0\n ? item.reservationLabel.trim()\n : id\n return {\n id,\n reservationLabel,\n warehouse_name: item.warehouseName ?? null,\n variant_name: item.variantName ?? null,\n variant_sku: item.variantSku ?? null,\n quantity: item.quantity ?? null,\n }\n })\n .filter((item): item is NonNullable<typeof item> => item !== null)\n if (fromEnriched.length > 0) return fromEnriched\n\n const ids = Array.isArray(wms?.reservationSummary?.reservationIds)\n ? (wms.reservationSummary?.reservationIds ?? [])\n : []\n return ids\n .filter((id): id is string => typeof id === 'string' && id.length > 0)\n .map((id) => ({\n id,\n reservationLabel: id,\n warehouse_name: null,\n variant_name: null,\n variant_sku: null,\n quantity: null,\n }))\n }, [wms?.reservationSummary?.reservationIds, wms?.reservationSummary?.reservations])\n\n const releaseReservation = React.useMemo(() => {\n if (!releaseReservationId) return null\n const match = activeReservations.find((item) => item.id === releaseReservationId)\n return match ?? { id: releaseReservationId }\n }, [activeReservations, releaseReservationId])\n\n React.useEffect(() => {\n const variantIds = stockSummary\n .map((item) => item.catalogVariantId)\n .filter((id): id is string => !!id)\n if (variantIds.length === 0) return\n void (async () => {\n const entries = await Promise.all(\n variantIds.map(async (id) => {\n const label = await resolveCatalogVariantLabel(id)\n return [id, label ?? id] as const\n }),\n )\n setVariantLabels(new Map(entries))\n })()\n }, [stockSummary])\n\n const canManageAssignment = access.canRelease\n const assignedLabel =\n wms?.assignedWarehouseName ||\n (wms?.isExplicitlyAssigned ? wms.assignedWarehouseId : null) ||\n t('wms.widgets.sales.stockContext.unassigned', 'Not assigned')\n\n const warehouseSeedOptions = React.useMemo(() => {\n if (!wms?.assignedWarehouseId) return []\n const label = wms.assignedWarehouseName?.trim() || wms.assignedWarehouseId\n return [{ value: wms.assignedWarehouseId, label }]\n }, [wms?.assignedWarehouseId, wms?.assignedWarehouseName])\n\n const resolveWarehouseComboboxLabel = React.useCallback(async (value: string) => {\n if (wms?.assignedWarehouseId === value && wms.assignedWarehouseName?.trim()) {\n return wms.assignedWarehouseName.trim()\n }\n const label = await resolveWarehouseLabel(value)\n return label ?? value\n }, [wms?.assignedWarehouseId, wms?.assignedWarehouseName])\n\n const persistAssignment = React.useCallback(\n async (warehouseId: string | null) => {\n if (!orderId || !organizationId || !tenantId) return\n setSaving(true)\n try {\n const mutationPayload = {\n organizationId,\n tenantId,\n warehouseId,\n }\n await runMutation({\n operation: async () => {\n if (warehouseId) {\n const response = await apiCall<{ ok?: boolean }>(\n `/api/wms/sales-orders/${orderId}/warehouse-assignment`,\n {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(mutationPayload),\n },\n )\n if (!response.ok) await raiseCrudError(response.response)\n } else {\n const response = await apiCall<{ ok?: boolean }>(\n `/api/wms/sales-orders/${orderId}/warehouse-assignment`,\n {\n method: 'DELETE',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n organizationId,\n tenantId,\n }),\n },\n )\n if (!response.ok) await raiseCrudError(response.response)\n }\n },\n context: mutationContext,\n mutationPayload,\n })\n\n router.refresh()\n flash(\n warehouseId\n ? t(\n 'wms.widgets.sales.stockContext.assignSuccess',\n 'Warehouse assignment saved.',\n )\n : t(\n 'wms.widgets.sales.stockContext.unassignSuccess',\n 'Warehouse assignment cleared.',\n ),\n 'success',\n )\n } catch {\n flash(\n t(\n 'wms.widgets.sales.stockContext.assignError',\n 'Could not update warehouse assignment.',\n ),\n 'error',\n )\n } finally {\n setSaving(false)\n }\n },\n [mutationContext, orderId, organizationId, router, runMutation, t, tenantId],\n )\n\n const handleRerunReservation = React.useCallback(async () => {\n if (!orderId || !organizationId || !tenantId) return\n setRerunning(true)\n try {\n const response = await apiCall<{ ok?: boolean }>(\n `/api/wms/sales-orders/${orderId}/re-run-reservation`,\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ organizationId, tenantId }),\n },\n )\n if (!response.ok) await raiseCrudError(response.response)\n router.refresh()\n flash(\n t(\n 'wms.widgets.sales.stockContext.rerunSuccess',\n 'Reservation re-run triggered. Stock context will refresh shortly.',\n ),\n 'success',\n )\n } catch {\n flash(\n t(\n 'wms.widgets.sales.stockContext.rerunError',\n 'Could not re-run reservation.',\n ),\n 'error',\n )\n } finally {\n setRerunning(false)\n }\n }, [orderId, organizationId, router, t, tenantId])\n\n if (!wms) return null\n\n const reservationStatus = wms.reservationSummary?.status ?? 'unreserved'\n\n return (\n <div className=\"rounded-lg border bg-card px-4 py-3 space-y-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"space-y-1\">\n <p className=\"text-sm font-medium\">\n {t(\n 'wms.widgets.sales.stockContext.title',\n 'WMS stock context',\n )}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.description',\n 'Live reservation and availability summary for this sales order.',\n )}\n </p>\n </div>\n <StatusBadge\n variant={reservationStatusMap[reservationStatus]}\n dot\n >\n {t(\n `wms.widgets.sales.stockContext.status.${reservationStatus}`,\n reservationStatus,\n )}\n </StatusBadge>\n </div>\n\n <dl className=\"grid gap-3 text-sm sm:grid-cols-2\">\n <div className=\"space-y-2 sm:col-span-2\">\n <dt className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.assignedWarehouse',\n 'Assigned warehouse',\n )}\n </dt>\n <dd>\n {canManageAssignment && orderId ? (\n <ComboboxInput\n value={selectedWarehouseId ?? ''}\n onChange={(value) => {\n const nextValue = value.trim().length > 0 ? value : null\n setSelectedWarehouseId(nextValue)\n void persistAssignment(nextValue)\n }}\n seedOptions={warehouseSeedOptions}\n resolveLabel={resolveWarehouseComboboxLabel}\n loadSuggestions={async (query) => {\n const options = await loadWarehouseOptions(query)\n return options.map((option) => ({\n value: option.value,\n label: option.label,\n }))\n }}\n placeholder={t(\n 'wms.widgets.sales.stockContext.warehousePlaceholder',\n 'Select a warehouse',\n )}\n allowCustomValues={false}\n disabled={saving}\n />\n ) : (\n <span className=\"font-medium\">{assignedLabel}</span>\n )}\n </dd>\n {wms.isExplicitlyAssigned ? (\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.explicitAssignmentHint',\n 'Explicit assignment overrides reservation-derived warehouse context.',\n )}\n </p>\n ) : null}\n </div>\n <div className=\"space-y-1\">\n <dt className=\"text-xs text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.reservationCount',\n 'Reservation records',\n )}\n </dt>\n <dd className=\"font-medium\">{activeReservations.length}</dd>\n </div>\n </dl>\n\n {stockSummary.length > 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.linesTitle',\n 'Variant availability',\n )}\n </p>\n <div className=\"space-y-2\">\n {stockSummary.map((item) => {\n const id = item.catalogVariantId ?? 'unknown'\n const label = variantLabels.get(id) ?? id\n return (\n <div\n key={id}\n className=\"rounded-md border border-border/70 bg-background px-3 py-2\"\n >\n <p className=\"text-sm font-medium\">{label}</p>\n <div className=\"mt-1 flex flex-wrap gap-4 text-xs text-muted-foreground\">\n <span>\n {t(\n 'wms.widgets.sales.stockContext.available',\n 'Available',\n )}\n {': '}\n {formatQuantity(item.available)}\n </span>\n <span>\n {t(\n 'wms.widgets.sales.stockContext.reserved',\n 'Reserved',\n )}\n {': '}\n {formatQuantity(item.reserved)}\n </span>\n </div>\n </div>\n )\n })}\n </div>\n </div>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.empty',\n 'No WMS stock summary is available for this order yet.',\n )}\n </p>\n )}\n\n {access.canRelease && activeReservations.length > 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {t(\n 'wms.widgets.sales.stockContext.reservationsTitle',\n 'Active reservations',\n )}\n </p>\n <div className=\"space-y-1\">\n {activeReservations.map((reservation) => (\n <div\n key={reservation.id}\n className=\"flex items-center justify-between gap-2 rounded-md border border-border/70 bg-background px-3 py-1.5\"\n >\n <span className=\"text-xs text-foreground truncate\" title={reservation.reservationLabel}>\n {reservation.reservationLabel}\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-6 shrink-0 px-2 text-xs text-status-error-fg hover:text-status-error-fg\"\n onClick={() => setReleaseReservationId(reservation.id)}\n >\n <ShieldOff className=\"size-3 mr-1\" />\n {t('wms.widgets.sales.stockContext.releaseBtn', 'Release')}\n </Button>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n\n <div className=\"flex flex-wrap gap-2\">\n {reservationStatus !== 'fully_reserved' && access.canRelease && orderId && !isCancelledOrder(data) ? (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n disabled={rerunning}\n onClick={() => void handleRerunReservation()}\n >\n <RefreshCw className={`size-3 mr-1.5 ${rerunning ? 'animate-spin' : ''}`} />\n {t(\n 'wms.widgets.sales.stockContext.actions.rerunReservation',\n 'Re-run reservation',\n )}\n </Button>\n ) : null}\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link href=\"/backend/wms/inventory\">\n {t(\n 'wms.widgets.sales.stockContext.actions.inventory',\n 'Open inventory console',\n )}\n </Link>\n </Button>\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link href=\"/backend/wms/reservations\">\n {t(\n 'wms.widgets.sales.stockContext.actions.reservations',\n 'Open reservations',\n )}\n </Link>\n </Button>\n </div>\n\n {access.canRelease ? (\n <ReleaseReservationDialog\n open={releaseReservationId !== null}\n onOpenChange={(open) => {\n if (!open) setReleaseReservationId(null)\n }}\n access={access}\n reservation={releaseReservation}\n onSuccess={() => {\n setReleaseReservationId(null)\n router.refresh()\n }}\n />\n ) : null}\n </div>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,8 @@
1
+ export const warehouse = "warehouse";
2
+ export const vendor_id = "vendor_id";
3
+ export const status = "status";
4
+ export const expected_at = "expected_at";
5
+ export const reference_number = "reference_number";
6
+ export const source_key = "source_key";
7
+ export const notes = "notes";
8
+ export const lines = "lines";
@@ -0,0 +1,11 @@
1
+ export const warehouse = "warehouse";
2
+ export const source_location_id = "source_location_id";
3
+ export const target_location_id = "target_location_id";
4
+ export const catalog_variant_id = "catalog_variant_id";
5
+ export const lot_id = "lot_id";
6
+ export const serial_number = "serial_number";
7
+ export const quantity = "quantity";
8
+ export const status = "status";
9
+ export const assigned_to = "assigned_to";
10
+ export const priority = "priority";
11
+ export const putaway_key = "putaway_key";
@@ -0,0 +1,9 @@
1
+ export const asn = "asn";
2
+ export const catalog_variant_id = "catalog_variant_id";
3
+ export const expected_qty = "expected_qty";
4
+ export const received_qty = "received_qty";
5
+ export const lot_number = "lot_number";
6
+ export const serial_numbers = "serial_numbers";
7
+ export const qc_status = "qc_status";
8
+ export const target_staging_location_id = "target_staging_location_id";
9
+ export const rejection_reason = "rejection_reason";
@@ -202,7 +202,10 @@ export const M = {
202
202
  "inventory_balance": "wms:inventory_balance",
203
203
  "inventory_reservation": "wms:inventory_reservation",
204
204
  "sales_order_warehouse_assignment": "wms:sales_order_warehouse_assignment",
205
- "inventory_movement": "wms:inventory_movement"
205
+ "inventory_movement": "wms:inventory_movement",
206
+ "asn": "wms:asn",
207
+ "receiving_line": "wms:receiving_line",
208
+ "putaway_task": "wms:putaway_task"
206
209
  },
207
210
  "availability": {
208
211
  "availability_policy": "availability:availability_policy"
@@ -63,6 +63,16 @@ export const entityFieldsRegistry: Record<string, Record<string, string>> = {
63
63
  "updated_at": "updated_at",
64
64
  "deleted_at": "deleted_at"
65
65
  },
66
+ "asn": {
67
+ "warehouse": "warehouse",
68
+ "vendor_id": "vendor_id",
69
+ "status": "status",
70
+ "expected_at": "expected_at",
71
+ "reference_number": "reference_number",
72
+ "source_key": "source_key",
73
+ "notes": "notes",
74
+ "lines": "lines"
75
+ },
66
76
  "attachment": {
67
77
  "id": "id",
68
78
  "entity_id": "entity_id",
@@ -2565,6 +2575,30 @@ export const entityFieldsRegistry: Record<string, Record<string, string>> = {
2565
2575
  "next_retry_at": "next_retry_at",
2566
2576
  "updated_at": "updated_at"
2567
2577
  },
2578
+ "putaway_task": {
2579
+ "warehouse": "warehouse",
2580
+ "source_location_id": "source_location_id",
2581
+ "target_location_id": "target_location_id",
2582
+ "catalog_variant_id": "catalog_variant_id",
2583
+ "lot_id": "lot_id",
2584
+ "serial_number": "serial_number",
2585
+ "quantity": "quantity",
2586
+ "status": "status",
2587
+ "assigned_to": "assigned_to",
2588
+ "priority": "priority",
2589
+ "putaway_key": "putaway_key"
2590
+ },
2591
+ "receiving_line": {
2592
+ "asn": "asn",
2593
+ "catalog_variant_id": "catalog_variant_id",
2594
+ "expected_qty": "expected_qty",
2595
+ "received_qty": "received_qty",
2596
+ "lot_number": "lot_number",
2597
+ "serial_numbers": "serial_numbers",
2598
+ "qc_status": "qc_status",
2599
+ "target_staging_location_id": "target_staging_location_id",
2600
+ "rejection_reason": "rejection_reason"
2601
+ },
2568
2602
  "resources_resource": {
2569
2603
  "id": "id",
2570
2604
  "tenant_id": "tenant_id",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/core",
3
- "version": "0.10.1-develop.7709.1.046124599c",
3
+ "version": "0.10.1-develop.7714.1.9dbb8200d8",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -265,16 +265,16 @@
265
265
  "zod": "^4.4.3"
266
266
  },
267
267
  "peerDependencies": {
268
- "@open-mercato/ai-assistant": "0.10.1-develop.7709.1.046124599c",
269
- "@open-mercato/shared": "0.10.1-develop.7709.1.046124599c",
270
- "@open-mercato/ui": "0.10.1-develop.7709.1.046124599c",
268
+ "@open-mercato/ai-assistant": "0.10.1-develop.7714.1.9dbb8200d8",
269
+ "@open-mercato/shared": "0.10.1-develop.7714.1.9dbb8200d8",
270
+ "@open-mercato/ui": "0.10.1-develop.7714.1.9dbb8200d8",
271
271
  "react": "^19.0.0",
272
272
  "react-dom": "^19.0.0"
273
273
  },
274
274
  "devDependencies": {
275
- "@open-mercato/ai-assistant": "0.10.1-develop.7709.1.046124599c",
276
- "@open-mercato/shared": "0.10.1-develop.7709.1.046124599c",
277
- "@open-mercato/ui": "0.10.1-develop.7709.1.046124599c",
275
+ "@open-mercato/ai-assistant": "0.10.1-develop.7714.1.9dbb8200d8",
276
+ "@open-mercato/shared": "0.10.1-develop.7714.1.9dbb8200d8",
277
+ "@open-mercato/ui": "0.10.1-develop.7714.1.9dbb8200d8",
278
278
  "@testing-library/dom": "^10.4.1",
279
279
  "@testing-library/jest-dom": "^7.0.1",
280
280
  "@testing-library/react": "^16.3.3",
@@ -378,8 +378,10 @@
378
378
  "auth.acl.features.wms.adjust_inventory": "Adjust and move inventory",
379
379
  "auth.acl.features.wms.cycle_count": "Run cycle counts",
380
380
  "auth.acl.features.wms.import": "Import inventory from CSV",
381
+ "auth.acl.features.wms.manage_asn": "Manage ASNs and receiving lines",
381
382
  "auth.acl.features.wms.manage_inventory": "Manage inventory profiles and stock state",
382
383
  "auth.acl.features.wms.manage_locations": "Manage warehouse locations",
384
+ "auth.acl.features.wms.manage_putaway": "Manage putaway tasks",
383
385
  "auth.acl.features.wms.manage_reservations": "Manage inventory reservations",
384
386
  "auth.acl.features.wms.manage_warehouses": "Manage warehouses",
385
387
  "auth.acl.features.wms.manage_zones": "Manage warehouse zones",
@@ -378,8 +378,10 @@
378
378
  "auth.acl.features.wms.adjust_inventory": "Adjust and move inventory",
379
379
  "auth.acl.features.wms.cycle_count": "Run cycle counts",
380
380
  "auth.acl.features.wms.import": "Import inventory from CSV",
381
+ "auth.acl.features.wms.manage_asn": "Manage ASNs and receiving lines",
381
382
  "auth.acl.features.wms.manage_inventory": "Manage inventory profiles and stock state",
382
383
  "auth.acl.features.wms.manage_locations": "Manage warehouse locations",
384
+ "auth.acl.features.wms.manage_putaway": "Manage putaway tasks",
383
385
  "auth.acl.features.wms.manage_reservations": "Manage inventory reservations",
384
386
  "auth.acl.features.wms.manage_warehouses": "Manage warehouses",
385
387
  "auth.acl.features.wms.manage_zones": "Manage warehouse zones",
@@ -378,8 +378,10 @@
378
378
  "auth.acl.features.wms.adjust_inventory": "Adjust and move inventory",
379
379
  "auth.acl.features.wms.cycle_count": "Run cycle counts",
380
380
  "auth.acl.features.wms.import": "Import inventory from CSV",
381
+ "auth.acl.features.wms.manage_asn": "Manage ASNs and receiving lines",
381
382
  "auth.acl.features.wms.manage_inventory": "Manage inventory profiles and stock state",
382
383
  "auth.acl.features.wms.manage_locations": "Manage warehouse locations",
384
+ "auth.acl.features.wms.manage_putaway": "Manage putaway tasks",
383
385
  "auth.acl.features.wms.manage_reservations": "Manage inventory reservations",
384
386
  "auth.acl.features.wms.manage_warehouses": "Manage warehouses",
385
387
  "auth.acl.features.wms.manage_zones": "Manage warehouse zones",
@@ -378,8 +378,10 @@
378
378
  "auth.acl.features.wms.adjust_inventory": "Adjust and move inventory",
379
379
  "auth.acl.features.wms.cycle_count": "Run cycle counts",
380
380
  "auth.acl.features.wms.import": "Import inventory from CSV",
381
+ "auth.acl.features.wms.manage_asn": "Manage ASNs and receiving lines",
381
382
  "auth.acl.features.wms.manage_inventory": "Manage inventory profiles and stock state",
382
383
  "auth.acl.features.wms.manage_locations": "Manage warehouse locations",
384
+ "auth.acl.features.wms.manage_putaway": "Manage putaway tasks",
383
385
  "auth.acl.features.wms.manage_reservations": "Manage inventory reservations",
384
386
  "auth.acl.features.wms.manage_warehouses": "Manage warehouses",
385
387
  "auth.acl.features.wms.manage_zones": "Manage warehouse zones",
@@ -378,8 +378,10 @@
378
378
  "auth.acl.features.wms.adjust_inventory": "Koryguj i przemieszczaj zapasy",
379
379
  "auth.acl.features.wms.cycle_count": "Przeprowadzaj inwentaryzacje cykliczne",
380
380
  "auth.acl.features.wms.import": "Importuj zapasy z pliku CSV",
381
+ "auth.acl.features.wms.manage_asn": "Zarządzaj ASN i liniami przyjęć",
381
382
  "auth.acl.features.wms.manage_inventory": "Zarządzaj profilami zapasów i stanami magazynowymi",
382
383
  "auth.acl.features.wms.manage_locations": "Zarządzaj lokalizacjami magazynowymi",
384
+ "auth.acl.features.wms.manage_putaway": "Zarządzaj zadaniami odkładania",
383
385
  "auth.acl.features.wms.manage_reservations": "Zarządzaj rezerwacjami zapasów",
384
386
  "auth.acl.features.wms.manage_warehouses": "Zarządzaj magazynami",
385
387
  "auth.acl.features.wms.manage_zones": "Zarządzaj strefami magazynowymi",
@@ -5,6 +5,8 @@
5
5
  "communication_channels.channel.providers.whatsapp": "WhatsApp",
6
6
  "communication_channels.channelPayload.aria": "Kanalinhalt",
7
7
  "communication_channels.channelPayload.email.aria": "E-Mail-Inhalt",
8
+ "communication_channels.channelPayload.email.loadRemoteImages": "Externe Bilder laden",
9
+ "communication_channels.channelPayload.email.remoteImagesBlocked": "Externe Bilder werden zum Schutz Ihrer Privatsphäre blockiert. Wenn Sie sie laden, erfährt der Absender möglicherweise, dass Sie diese Nachricht geöffnet haben.",
8
10
  "communication_channels.channelPayload.types.email/mime": "E-Mail (MIME)",
9
11
  "communication_channels.columns.displayName": "Kanal",
10
12
  "communication_channels.columns.identifier": "Externe ID",
@@ -5,6 +5,8 @@
5
5
  "communication_channels.channel.providers.whatsapp": "WhatsApp",
6
6
  "communication_channels.channelPayload.aria": "Channel payload",
7
7
  "communication_channels.channelPayload.email.aria": "Email payload",
8
+ "communication_channels.channelPayload.email.loadRemoteImages": "Load remote images",
9
+ "communication_channels.channelPayload.email.remoteImagesBlocked": "Remote images are blocked to protect your privacy. Loading them may let the sender know you opened this message.",
8
10
  "communication_channels.channelPayload.types.email/mime": "Email (MIME)",
9
11
  "communication_channels.columns.displayName": "Channel",
10
12
  "communication_channels.columns.identifier": "External ID",
@@ -5,6 +5,8 @@
5
5
  "communication_channels.channel.providers.whatsapp": "WhatsApp",
6
6
  "communication_channels.channelPayload.aria": "Contenido del canal",
7
7
  "communication_channels.channelPayload.email.aria": "Contenido del correo",
8
+ "communication_channels.channelPayload.email.loadRemoteImages": "Cargar imágenes remotas",
9
+ "communication_channels.channelPayload.email.remoteImagesBlocked": "Las imágenes remotas están bloqueadas para proteger su privacidad. Al cargarlas, el remitente podría saber que ha abierto este mensaje.",
8
10
  "communication_channels.channelPayload.types.email/mime": "Correo (MIME)",
9
11
  "communication_channels.columns.displayName": "Canal",
10
12
  "communication_channels.columns.identifier": "ID externo",
@@ -5,6 +5,8 @@
5
5
  "communication_channels.channel.providers.whatsapp": "WhatsApp",
6
6
  "communication_channels.channelPayload.aria": "채널 페이로드",
7
7
  "communication_channels.channelPayload.email.aria": "이메일 페이로드",
8
+ "communication_channels.channelPayload.email.loadRemoteImages": "원격 이미지 불러오기",
9
+ "communication_channels.channelPayload.email.remoteImagesBlocked": "개인정보 보호를 위해 원격 이미지가 차단되었습니다. 이미지를 불러오면 발신자가 이 메시지를 열었다는 사실을 알 수 있습니다.",
8
10
  "communication_channels.channelPayload.types.email/mime": "이메일 (MIME)",
9
11
  "communication_channels.columns.displayName": "채널",
10
12
  "communication_channels.columns.identifier": "외부 ID",
@@ -5,6 +5,8 @@
5
5
  "communication_channels.channel.providers.whatsapp": "WhatsApp",
6
6
  "communication_channels.channelPayload.aria": "Treść kanału",
7
7
  "communication_channels.channelPayload.email.aria": "Treść e-maila",
8
+ "communication_channels.channelPayload.email.loadRemoteImages": "Wczytaj zdalne obrazy",
9
+ "communication_channels.channelPayload.email.remoteImagesBlocked": "Zdalne obrazy są blokowane, aby chronić Twoją prywatność. Ich wczytanie może ujawnić nadawcy, że ta wiadomość została otwarta.",
8
10
  "communication_channels.channelPayload.types.email/mime": "E-mail (MIME)",
9
11
  "communication_channels.columns.displayName": "Kanał",
10
12
  "communication_channels.columns.identifier": "Identyfikator zewn.",
@@ -14,6 +14,7 @@ import sanitizeHtml from 'sanitize-html'
14
14
  *
15
15
  * Allowlist is tuned for email + chat HTML:
16
16
  * - Preserves typical email layout primitives (table-based layouts, inline images, basic typography).
17
+ * - Defers network images until the reader explicitly opts in for that message.
17
18
  * - Strips `<script>`, `<style>`, `<iframe>`, all event-handler attributes (`on*`).
18
19
  * - Blocks `javascript:` and `data:` URLs except `data:image/*;base64,…` (inline base64 images, common in email).
19
20
  */
@@ -55,7 +56,7 @@ const ALLOWED_TAGS = [
55
56
 
56
57
  const ALLOWED_SCHEMES = ['http', 'https', 'mailto', 'tel']
57
58
  const ALLOWED_SCHEMES_BY_TAG = {
58
- img: ['http', 'https', 'data'],
59
+ img: ['data'],
59
60
  }
60
61
 
61
62
  /**
@@ -72,13 +73,32 @@ const SANITIZE_OPTIONS: sanitizeHtml.IOptions = {
72
73
  allowedTags: ALLOWED_TAGS,
73
74
  allowedAttributes: {
74
75
  a: ['href', 'title', 'class'],
75
- img: ['src', 'alt', 'title', 'class', 'width', 'height'],
76
+ img: ['src', 'alt', 'title', 'class', 'width', 'height', 'data-channel-remote-src'],
76
77
  '*': ['class', 'style', 'colspan', 'rowspan', 'width', 'height'],
77
78
  },
78
79
  allowedSchemes: ALLOWED_SCHEMES,
79
80
  allowedSchemesByTag: ALLOWED_SCHEMES_BY_TAG,
80
81
  allowedSchemesAppliedToAttributes: ['href', 'src'],
81
82
  allowProtocolRelative: false,
83
+ transformTags: {
84
+ img: (tagName, attributes) => {
85
+ const { src } = attributes
86
+ const safeAttributes = { ...attributes }
87
+ delete safeAttributes.src
88
+ delete safeAttributes['data-channel-remote-src']
89
+ if (!src) return { tagName, attribs: safeAttributes }
90
+ if (/^data:/i.test(src)) return { tagName, attribs: { ...safeAttributes, src } }
91
+ try {
92
+ const remoteUrl = new URL(src.startsWith('//') ? `https:${src}` : src)
93
+ if (remoteUrl.protocol === 'http:' || remoteUrl.protocol === 'https:') {
94
+ safeAttributes['data-channel-remote-src'] = remoteUrl.href
95
+ }
96
+ } catch {
97
+ return { tagName, attribs: safeAttributes }
98
+ }
99
+ return { tagName, attribs: safeAttributes }
100
+ },
101
+ },
82
102
  // disable inline scripts in style attributes
83
103
  allowedStyles: {
84
104
  '*': {
@@ -107,7 +127,7 @@ const SANITIZE_OPTIONS: sanitizeHtml.IOptions = {
107
127
  exclusiveFilter: (frame) => {
108
128
  if (frame.tag === 'img' && frame.attribs?.src) {
109
129
  const src = frame.attribs.src
110
- if (src.startsWith('data:') && !/^data:image\/(?:png|jpe?g|gif|webp);base64,/i.test(src)) {
130
+ if (/^data:/i.test(src) && !/^data:image\/(?:png|jpe?g|gif|webp);base64,/i.test(src)) {
111
131
  return true
112
132
  }
113
133
  }
@@ -3,6 +3,8 @@
3
3
  import * as React from 'react'
4
4
  import type { InjectionWidgetComponentProps } from '@open-mercato/shared/modules/widgets/injection'
5
5
  import { useT } from '@open-mercato/shared/lib/i18n/context'
6
+ import { Alert } from '@open-mercato/ui/primitives/alert'
7
+ import { Button } from '@open-mercato/ui/primitives/button'
6
8
 
7
9
  type ChannelPayloadEnrichment = {
8
10
  channelContentType: string | null
@@ -19,6 +21,47 @@ type MessageWithPayload = Record<string, unknown> & {
19
21
  _channelPayload?: ChannelPayloadEnrichment | null
20
22
  }
21
23
 
24
+ function EmailPayload({ html }: { html: string }) {
25
+ const t = useT()
26
+ const bodyRef = React.useRef<HTMLDivElement>(null)
27
+ const [remoteImagesAllowed, setRemoteImagesAllowed] = React.useState(false)
28
+ const hasRemoteImages = html.includes('data-channel-remote-src=')
29
+
30
+ React.useEffect(() => {
31
+ if (!remoteImagesAllowed) return
32
+ for (const image of bodyRef.current?.querySelectorAll<HTMLImageElement>('img[data-channel-remote-src]') ?? []) {
33
+ const source = image.getAttribute('data-channel-remote-src')
34
+ if (source && /^https?:\/\//i.test(source)) {
35
+ image.referrerPolicy = 'no-referrer'
36
+ image.src = source.replace(/[<>"']/g, (character) => `%${character.charCodeAt(0).toString(16)}`)
37
+ }
38
+ }
39
+ }, [remoteImagesAllowed])
40
+
41
+ return (
42
+ <section
43
+ className="rounded-md border border-border bg-card p-4 text-sm"
44
+ aria-label={t('communication_channels.channelPayload.email.aria')}
45
+ >
46
+ {hasRemoteImages && !remoteImagesAllowed ? (
47
+ <Alert
48
+ status="information"
49
+ style="lighter"
50
+ className="mb-4"
51
+ action={(
52
+ <Button type="button" variant="outline" size="sm" onClick={() => setRemoteImagesAllowed(true)}>
53
+ {t('communication_channels.channelPayload.email.loadRemoteImages')}
54
+ </Button>
55
+ )}
56
+ >
57
+ {t('communication_channels.channelPayload.email.remoteImagesBlocked')}
58
+ </Alert>
59
+ ) : null}
60
+ <div ref={bodyRef} dangerouslySetInnerHTML={{ __html: html }} />
61
+ </section>
62
+ )
63
+ }
64
+
22
65
  export default function ChannelPayloadRendererWidget({
23
66
  data,
24
67
  }: InjectionWidgetComponentProps<Record<string, unknown>, MessageWithPayload>) {
@@ -28,19 +71,8 @@ export default function ChannelPayloadRendererWidget({
28
71
 
29
72
  const { channelContentType, channelPayload, sanitizedHtml } = payload
30
73
 
31
- // Email / HTML — render the HTML the server already sanitized.
32
74
  if (channelContentType.startsWith('email/') && typeof sanitizedHtml === 'string') {
33
- return (
34
- <section
35
- className="rounded-md border bg-card p-4 text-sm"
36
- aria-label={t(
37
- 'communication_channels.channelPayload.email.aria',
38
- 'Channel payload — email',
39
- )}
40
- >
41
- <div dangerouslySetInnerHTML={{ __html: sanitizedHtml }} />
42
- </section>
43
- )
75
+ return <EmailPayload key={`${data?.id ?? ''}:${sanitizedHtml}`} html={sanitizedHtml} />
44
76
  }
45
77
 
46
78
  // Provider-specific payloads (Slack Block Kit, WhatsApp interactive) —
@@ -9,6 +9,7 @@ import { extractOptimisticLockConflict } from '@open-mercato/ui/backend/utils/op
9
9
  import { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'
10
10
  import { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'
11
11
  import { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'
12
+ import { useCurrentOrganization } from '@open-mercato/ui/backend/BackendChromeProvider'
12
13
  import { flash } from '@open-mercato/ui/backend/FlashMessages'
13
14
  import { CrudForm, type CrudFormGroup, type CrudFormGroupComponentProps } from '@open-mercato/ui/backend/CrudForm'
14
15
  import { useInjectionWidgets } from '@open-mercato/ui/backend/injection/InjectionSpot'
@@ -206,7 +207,6 @@ const EditorBody = React.memo(function EditorBody({
206
207
  )
207
208
  const capabilities = React.useMemo(() => ({ resourcesEnabled, staffEnabled }), [resourcesEnabled, staffEnabled])
208
209
 
209
- useEditorLabelResolution(open, form, update)
210
210
  // Probe against the owner the interaction will actually be SAVED with so the
211
211
  // editor warning matches the grid's post-save conflict rings: tasks own via
212
212
  // their assignee, other kinds stay ownerless on create / keep the existing
@@ -329,6 +329,7 @@ export function CalendarEventEditor({
329
329
  onSaved,
330
330
  }: CalendarEventEditorProps) {
331
331
  const t = useT()
332
+ const activeOrgId = useCurrentOrganization()?.id ?? null
332
333
  const [saving, setSaving] = React.useState(false)
333
334
  const { confirm, ConfirmDialogElement } = useConfirmDialog()
334
335
  const dirtyRef = React.useRef(false)
@@ -388,12 +389,24 @@ export function CalendarEventEditor({
388
389
  wasOpenRef.current = open
389
390
  }, [open])
390
391
  const formKey = `${mode}:${item?.id ?? 'new'}:${openSeq}:${autoSelectedCreateType?.key ?? 'default'}`
392
+ const labelScopeKey = JSON.stringify([formKey, activeOrgId, item?.entityId, item?.dealId, item?.ownerUserId])
393
+ const [resolvedLabels, setResolvedLabels] = React.useState<{
394
+ scopeKey: string
395
+ values: Partial<EditorFormState>
396
+ } | null>(null)
397
+ const updateInitialLabels = React.useCallback((patch: Partial<EditorFormState>) => {
398
+ setResolvedLabels((previous) => ({
399
+ scopeKey: labelScopeKey,
400
+ values: { ...(previous?.scopeKey === labelScopeKey ? previous.values : {}), ...patch },
401
+ }))
402
+ }, [labelScopeKey])
391
403
 
392
404
  const initialValues = React.useMemo<Record<string, unknown>>(() => {
393
405
  if (isEdit && item) {
394
406
  return {
395
407
  ...parseItemToFormState(item),
396
408
  ...customFieldInitialValues(item),
409
+ ...(resolvedLabels?.scopeKey === labelScopeKey ? resolvedLabels.values : {}),
397
410
  id: item.id,
398
411
  updatedAt: item.updatedAt ?? undefined,
399
412
  }
@@ -406,7 +419,8 @@ export function CalendarEventEditor({
406
419
  category: autoSelectedCreateType.key,
407
420
  }
408
421
  // eslint-disable-next-line react-hooks/exhaustive-deps -- openSeq re-seeds defaults per dialog open
409
- }, [isEdit, item, defaultDate, defaultRange, openSeq, autoSelectedCreateType])
422
+ }, [isEdit, item, defaultDate, defaultRange, openSeq, autoSelectedCreateType, labelScopeKey, resolvedLabels])
423
+ useEditorLabelResolution(open, formStateOfValues(initialValues), updateInitialLabels)
410
424
  const initialTypeKey = String(initialValues.category ?? initialValues.kind ?? 'meeting')
411
425
  React.useEffect(() => { setSelectedTypeKey(initialTypeKey) }, [initialTypeKey, formKey])
412
426
  const selectedDefinition = selectedEventType(catalog.items, selectedTypeKey)
@@ -7,6 +7,8 @@ export const features = [
7
7
  { id: 'wms.manage_reservations', title: 'Manage inventory reservations', module: 'wms' },
8
8
  { id: 'wms.adjust_inventory', title: 'Adjust and move inventory', module: 'wms' },
9
9
  { id: 'wms.receive_inventory', title: 'Receive inbound inventory', module: 'wms' },
10
+ { id: 'wms.manage_asn', title: 'Manage ASNs and receiving lines', module: 'wms' },
11
+ { id: 'wms.manage_putaway', title: 'Manage putaway tasks', module: 'wms' },
10
12
  { id: 'wms.cycle_count', title: 'Run cycle counts', module: 'wms' },
11
13
  { id: 'wms.import', title: 'Import inventory from CSV', module: 'wms' },
12
14
  ]