@aglyn/plugins-commerce 1.0.0-beta.143

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 (417) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +10 -0
  3. package/package.json +57 -0
  4. package/src/index.d.ts +38 -0
  5. package/src/index.js +38 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/components/account.d.ts +31 -0
  8. package/src/lib/components/account.js +645 -0
  9. package/src/lib/components/account.js.map +1 -0
  10. package/src/lib/components/cart.d.ts +38 -0
  11. package/src/lib/components/cart.js +851 -0
  12. package/src/lib/components/cart.js.map +1 -0
  13. package/src/lib/components/commerce-console-page.d.ts +32 -0
  14. package/src/lib/components/commerce-console-page.js +296 -0
  15. package/src/lib/components/commerce-console-page.js.map +1 -0
  16. package/src/lib/components/commerce-console-sections.d.ts +34 -0
  17. package/src/lib/components/commerce-console-sections.js +62 -0
  18. package/src/lib/components/commerce-console-sections.js.map +1 -0
  19. package/src/lib/components/console/catalog-organization-card.component.d.ts +14 -0
  20. package/src/lib/components/console/catalog-organization-card.component.js +1087 -0
  21. package/src/lib/components/console/catalog-organization-card.component.js.map +1 -0
  22. package/src/lib/components/console/commerce-analytics-card.component.d.ts +27 -0
  23. package/src/lib/components/console/commerce-analytics-card.component.js +310 -0
  24. package/src/lib/components/console/commerce-analytics-card.component.js.map +1 -0
  25. package/src/lib/components/console/commerce-glance-card.component.d.ts +20 -0
  26. package/src/lib/components/console/commerce-glance-card.component.js +340 -0
  27. package/src/lib/components/console/commerce-glance-card.component.js.map +1 -0
  28. package/src/lib/components/console/commerce-stat-tile.component.d.ts +37 -0
  29. package/src/lib/components/console/commerce-stat-tile.component.js +72 -0
  30. package/src/lib/components/console/commerce-stat-tile.component.js.map +1 -0
  31. package/src/lib/components/console/discounts-card.component.d.ts +14 -0
  32. package/src/lib/components/console/discounts-card.component.js +443 -0
  33. package/src/lib/components/console/discounts-card.component.js.map +1 -0
  34. package/src/lib/components/console/entitlement-gate.component.d.ts +76 -0
  35. package/src/lib/components/console/entitlement-gate.component.js +115 -0
  36. package/src/lib/components/console/entitlement-gate.component.js.map +1 -0
  37. package/src/lib/components/console/gift-cards-card.component.d.ts +29 -0
  38. package/src/lib/components/console/gift-cards-card.component.js +379 -0
  39. package/src/lib/components/console/gift-cards-card.component.js.map +1 -0
  40. package/src/lib/components/console/host-coupons-card.component.d.ts +14 -0
  41. package/src/lib/components/console/host-coupons-card.component.js +252 -0
  42. package/src/lib/components/console/host-coupons-card.component.js.map +1 -0
  43. package/src/lib/components/console/host-orders-card.component.d.ts +13 -0
  44. package/src/lib/components/console/host-orders-card.component.js +861 -0
  45. package/src/lib/components/console/host-orders-card.component.js.map +1 -0
  46. package/src/lib/components/console/locations-card.component.d.ts +14 -0
  47. package/src/lib/components/console/locations-card.component.js +256 -0
  48. package/src/lib/components/console/locations-card.component.js.map +1 -0
  49. package/src/lib/components/console/member-posts-card.component.d.ts +8 -0
  50. package/src/lib/components/console/member-posts-card.component.js +283 -0
  51. package/src/lib/components/console/member-posts-card.component.js.map +1 -0
  52. package/src/lib/components/console/newest-site-users-card.component.d.ts +36 -0
  53. package/src/lib/components/console/newest-site-users-card.component.js +126 -0
  54. package/src/lib/components/console/newest-site-users-card.component.js.map +1 -0
  55. package/src/lib/components/console/order-detail-dialog.component.d.ts +28 -0
  56. package/src/lib/components/console/order-detail-dialog.component.js +976 -0
  57. package/src/lib/components/console/order-detail-dialog.component.js.map +1 -0
  58. package/src/lib/components/console/paid-media.d.ts +127 -0
  59. package/src/lib/components/console/paid-media.js +397 -0
  60. package/src/lib/components/console/paid-media.js.map +1 -0
  61. package/src/lib/components/console/payments-settings-card.component.d.ts +13 -0
  62. package/src/lib/components/console/payments-settings-card.component.js +295 -0
  63. package/src/lib/components/console/payments-settings-card.component.js.map +1 -0
  64. package/src/lib/components/console/pos-page.component.d.ts +13 -0
  65. package/src/lib/components/console/pos-page.component.js +916 -0
  66. package/src/lib/components/console/pos-page.component.js.map +1 -0
  67. package/src/lib/components/console/product-editor-dialog.component.d.ts +32 -0
  68. package/src/lib/components/console/product-editor-dialog.component.js +1374 -0
  69. package/src/lib/components/console/product-editor-dialog.component.js.map +1 -0
  70. package/src/lib/components/console/products-hub-card.component.d.ts +16 -0
  71. package/src/lib/components/console/products-hub-card.component.js +1280 -0
  72. package/src/lib/components/console/products-hub-card.component.js.map +1 -0
  73. package/src/lib/components/console/products-hub-zone.component.d.ts +50 -0
  74. package/src/lib/components/console/products-hub-zone.component.js +200 -0
  75. package/src/lib/components/console/products-hub-zone.component.js.map +1 -0
  76. package/src/lib/components/console/recovery-queue-card.component.d.ts +39 -0
  77. package/src/lib/components/console/recovery-queue-card.component.js +262 -0
  78. package/src/lib/components/console/recovery-queue-card.component.js.map +1 -0
  79. package/src/lib/components/console/registers-card.component.d.ts +21 -0
  80. package/src/lib/components/console/registers-card.component.js +296 -0
  81. package/src/lib/components/console/registers-card.component.js.map +1 -0
  82. package/src/lib/components/console/reservations-card.component.d.ts +14 -0
  83. package/src/lib/components/console/reservations-card.component.js +650 -0
  84. package/src/lib/components/console/reservations-card.component.js.map +1 -0
  85. package/src/lib/components/console/reviews-moderation-card.component.d.ts +8 -0
  86. package/src/lib/components/console/reviews-moderation-card.component.js +235 -0
  87. package/src/lib/components/console/reviews-moderation-card.component.js.map +1 -0
  88. package/src/lib/components/console/shipping-settings-card.component.d.ts +38 -0
  89. package/src/lib/components/console/shipping-settings-card.component.js +560 -0
  90. package/src/lib/components/console/shipping-settings-card.component.js.map +1 -0
  91. package/src/lib/components/console/stock-movements-card.component.d.ts +31 -0
  92. package/src/lib/components/console/stock-movements-card.component.js +333 -0
  93. package/src/lib/components/console/stock-movements-card.component.js.map +1 -0
  94. package/src/lib/components/console/store-settings-card.component.d.ts +14 -0
  95. package/src/lib/components/console/store-settings-card.component.js +300 -0
  96. package/src/lib/components/console/store-settings-card.component.js.map +1 -0
  97. package/src/lib/components/console/storefront-tax-summary-card.component.d.ts +73 -0
  98. package/src/lib/components/console/storefront-tax-summary-card.component.js +408 -0
  99. package/src/lib/components/console/storefront-tax-summary-card.component.js.map +1 -0
  100. package/src/lib/components/console/suppliers-card.component.d.ts +8 -0
  101. package/src/lib/components/console/suppliers-card.component.js +328 -0
  102. package/src/lib/components/console/suppliers-card.component.js.map +1 -0
  103. package/src/lib/components/console/tax-settings-card.component.d.ts +14 -0
  104. package/src/lib/components/console/tax-settings-card.component.js +473 -0
  105. package/src/lib/components/console/tax-settings-card.component.js.map +1 -0
  106. package/src/lib/components/gate.d.ts +39 -0
  107. package/src/lib/components/gate.js +202 -0
  108. package/src/lib/components/gate.js.map +1 -0
  109. package/src/lib/components/gated-video.d.ts +40 -0
  110. package/src/lib/components/gated-video.js +366 -0
  111. package/src/lib/components/gated-video.js.map +1 -0
  112. package/src/lib/components/member-feed.d.ts +32 -0
  113. package/src/lib/components/member-feed.js +198 -0
  114. package/src/lib/components/member-feed.js.map +1 -0
  115. package/src/lib/components/member-recovery.d.ts +35 -0
  116. package/src/lib/components/member-recovery.js +313 -0
  117. package/src/lib/components/member-recovery.js.map +1 -0
  118. package/src/lib/components/member-signin.d.ts +35 -0
  119. package/src/lib/components/member-signin.js +257 -0
  120. package/src/lib/components/member-signin.js.map +1 -0
  121. package/src/lib/components/member-signup.d.ts +34 -0
  122. package/src/lib/components/member-signup.js +287 -0
  123. package/src/lib/components/member-signup.js.map +1 -0
  124. package/src/lib/components/newsletter-signup.d.ts +39 -0
  125. package/src/lib/components/newsletter-signup.js +229 -0
  126. package/src/lib/components/newsletter-signup.js.map +1 -0
  127. package/src/lib/components/product-detail.d.ts +38 -0
  128. package/src/lib/components/product-detail.js +1022 -0
  129. package/src/lib/components/product-detail.js.map +1 -0
  130. package/src/lib/components/product-grid.d.ts +67 -0
  131. package/src/lib/components/product-grid.js +909 -0
  132. package/src/lib/components/product-grid.js.map +1 -0
  133. package/src/lib/components/product-reviews.d.ts +32 -0
  134. package/src/lib/components/product-reviews.js +349 -0
  135. package/src/lib/components/product-reviews.js.map +1 -0
  136. package/src/lib/components/related-products.d.ts +33 -0
  137. package/src/lib/components/related-products.js +232 -0
  138. package/src/lib/components/related-products.js.map +1 -0
  139. package/src/lib/components/reservation-widget.d.ts +33 -0
  140. package/src/lib/components/reservation-widget.js +418 -0
  141. package/src/lib/components/reservation-widget.js.map +1 -0
  142. package/src/lib/components/storefront-payment-element-fallback.d.ts +18 -0
  143. package/src/lib/components/storefront-payment-element-fallback.js +51 -0
  144. package/src/lib/components/storefront-payment-element-fallback.js.map +1 -0
  145. package/src/lib/components/storefront-payment-element.d.ts +78 -0
  146. package/src/lib/components/storefront-payment-element.js +156 -0
  147. package/src/lib/components/storefront-payment-element.js.map +1 -0
  148. package/src/lib/components/wishlist.d.ts +46 -0
  149. package/src/lib/components/wishlist.js +304 -0
  150. package/src/lib/components/wishlist.js.map +1 -0
  151. package/src/lib/constants/bundle-common.d.ts +18 -0
  152. package/src/lib/constants/bundle-common.js +18 -0
  153. package/src/lib/constants/bundle-common.js.map +1 -0
  154. package/src/lib/constants/product-filters.d.ts +35 -0
  155. package/src/lib/constants/product-filters.js +109 -0
  156. package/src/lib/constants/product-filters.js.map +1 -0
  157. package/src/lib/model/commerce-cart.d.ts +52 -0
  158. package/src/lib/model/commerce-cart.js +102 -0
  159. package/src/lib/model/commerce-cart.js.map +1 -0
  160. package/src/lib/model/commerce-connect-transfer.d.ts +243 -0
  161. package/src/lib/model/commerce-connect-transfer.js +231 -0
  162. package/src/lib/model/commerce-connect-transfer.js.map +1 -0
  163. package/src/lib/model/commerce-discounts.d.ts +164 -0
  164. package/src/lib/model/commerce-discounts.js +231 -0
  165. package/src/lib/model/commerce-discounts.js.map +1 -0
  166. package/src/lib/model/commerce-dispute.d.ts +124 -0
  167. package/src/lib/model/commerce-dispute.js +225 -0
  168. package/src/lib/model/commerce-dispute.js.map +1 -0
  169. package/src/lib/model/commerce-gift-cards.d.ts +107 -0
  170. package/src/lib/model/commerce-gift-cards.js +121 -0
  171. package/src/lib/model/commerce-gift-cards.js.map +1 -0
  172. package/src/lib/model/commerce-io.d.ts +36 -0
  173. package/src/lib/model/commerce-io.js +245 -0
  174. package/src/lib/model/commerce-io.js.map +1 -0
  175. package/src/lib/model/commerce-orders.d.ts +1040 -0
  176. package/src/lib/model/commerce-orders.js +1022 -0
  177. package/src/lib/model/commerce-orders.js.map +1 -0
  178. package/src/lib/model/commerce-promotions.d.ts +188 -0
  179. package/src/lib/model/commerce-promotions.js +199 -0
  180. package/src/lib/model/commerce-promotions.js.map +1 -0
  181. package/src/lib/model/commerce-reservations.d.ts +175 -0
  182. package/src/lib/model/commerce-reservations.js +157 -0
  183. package/src/lib/model/commerce-reservations.js.map +1 -0
  184. package/src/lib/model/commerce-shipping.d.ts +316 -0
  185. package/src/lib/model/commerce-shipping.js +484 -0
  186. package/src/lib/model/commerce-shipping.js.map +1 -0
  187. package/src/lib/model/commerce-stock-holds.d.ts +199 -0
  188. package/src/lib/model/commerce-stock-holds.js +190 -0
  189. package/src/lib/model/commerce-stock-holds.js.map +1 -0
  190. package/src/lib/model/commerce-subscription-status.d.ts +67 -0
  191. package/src/lib/model/commerce-subscription-status.js +76 -0
  192. package/src/lib/model/commerce-subscription-status.js.map +1 -0
  193. package/src/lib/model/commerce-tax-decision.d.ts +222 -0
  194. package/src/lib/model/commerce-tax-decision.js +165 -0
  195. package/src/lib/model/commerce-tax-decision.js.map +1 -0
  196. package/src/lib/model/commerce-tax.d.ts +176 -0
  197. package/src/lib/model/commerce-tax.js +92 -0
  198. package/src/lib/model/commerce-tax.js.map +1 -0
  199. package/src/lib/model/commerce.d.ts +551 -0
  200. package/src/lib/model/commerce.js +739 -0
  201. package/src/lib/model/commerce.js.map +1 -0
  202. package/src/lib/model/index.d.ts +40 -0
  203. package/src/lib/model/index.js +40 -0
  204. package/src/lib/model/index.js.map +1 -0
  205. package/src/lib/model/order-figures.d.ts +48 -0
  206. package/src/lib/model/order-figures.js +74 -0
  207. package/src/lib/model/order-figures.js.map +1 -0
  208. package/src/lib/model/plugin-permissions.d.ts +23 -0
  209. package/src/lib/model/plugin-permissions.js +34 -0
  210. package/src/lib/model/plugin-permissions.js.map +1 -0
  211. package/src/lib/model/purchase-analytics.d.ts +186 -0
  212. package/src/lib/model/purchase-analytics.js +216 -0
  213. package/src/lib/model/purchase-analytics.js.map +1 -0
  214. package/src/lib/plugin-config.d.ts +62 -0
  215. package/src/lib/plugin-config.js +78 -0
  216. package/src/lib/plugin-config.js.map +1 -0
  217. package/src/lib/plugin.d.ts +28 -0
  218. package/src/lib/plugin.js +147 -0
  219. package/src/lib/plugin.js.map +1 -0
  220. package/src/lib/server/billing-webhook.d.ts +26 -0
  221. package/src/lib/server/billing-webhook.js +4011 -0
  222. package/src/lib/server/billing-webhook.js.map +1 -0
  223. package/src/lib/server/cancel-order.d.ts +87 -0
  224. package/src/lib/server/cancel-order.js +368 -0
  225. package/src/lib/server/cancel-order.js.map +1 -0
  226. package/src/lib/server/cart-checkout.d.ts +25 -0
  227. package/src/lib/server/cart-checkout.js +976 -0
  228. package/src/lib/server/cart-checkout.js.map +1 -0
  229. package/src/lib/server/cart-cookie.d.ts +32 -0
  230. package/src/lib/server/cart-cookie.js +77 -0
  231. package/src/lib/server/cart-cookie.js.map +1 -0
  232. package/src/lib/server/cart.d.ts +34 -0
  233. package/src/lib/server/cart.js +181 -0
  234. package/src/lib/server/cart.js.map +1 -0
  235. package/src/lib/server/catalog.d.ts +127 -0
  236. package/src/lib/server/catalog.js +277 -0
  237. package/src/lib/server/catalog.js.map +1 -0
  238. package/src/lib/server/checkout.d.ts +36 -0
  239. package/src/lib/server/checkout.js +915 -0
  240. package/src/lib/server/checkout.js.map +1 -0
  241. package/src/lib/server/connect.d.ts +26 -0
  242. package/src/lib/server/connect.js +238 -0
  243. package/src/lib/server/connect.js.map +1 -0
  244. package/src/lib/server/contact-refund.d.ts +117 -0
  245. package/src/lib/server/contact-refund.js +196 -0
  246. package/src/lib/server/contact-refund.js.map +1 -0
  247. package/src/lib/server/download.d.ts +39 -0
  248. package/src/lib/server/download.js +206 -0
  249. package/src/lib/server/download.js.map +1 -0
  250. package/src/lib/server/draft-order.d.ts +26 -0
  251. package/src/lib/server/draft-order.js +706 -0
  252. package/src/lib/server/draft-order.js.map +1 -0
  253. package/src/lib/server/feed.d.ts +24 -0
  254. package/src/lib/server/feed.js +59 -0
  255. package/src/lib/server/feed.js.map +1 -0
  256. package/src/lib/server/fulfill-order.d.ts +97 -0
  257. package/src/lib/server/fulfill-order.js +235 -0
  258. package/src/lib/server/fulfill-order.js.map +1 -0
  259. package/src/lib/server/gate.d.ts +36 -0
  260. package/src/lib/server/gate.js +112 -0
  261. package/src/lib/server/gate.js.map +1 -0
  262. package/src/lib/server/gift-cards.d.ts +42 -0
  263. package/src/lib/server/gift-cards.js +219 -0
  264. package/src/lib/server/gift-cards.js.map +1 -0
  265. package/src/lib/server/low-stock.d.ts +49 -0
  266. package/src/lib/server/low-stock.js +60 -0
  267. package/src/lib/server/low-stock.js.map +1 -0
  268. package/src/lib/server/manual-tax-rate.d.ts +82 -0
  269. package/src/lib/server/manual-tax-rate.js +113 -0
  270. package/src/lib/server/manual-tax-rate.js.map +1 -0
  271. package/src/lib/server/member-feed.d.ts +24 -0
  272. package/src/lib/server/member-feed.js +72 -0
  273. package/src/lib/server/member-feed.js.map +1 -0
  274. package/src/lib/server/member-name-search.d.ts +37 -0
  275. package/src/lib/server/member-name-search.js +42 -0
  276. package/src/lib/server/member-name-search.js.map +1 -0
  277. package/src/lib/server/member-post.d.ts +23 -0
  278. package/src/lib/server/member-post.js +166 -0
  279. package/src/lib/server/member-post.js.map +1 -0
  280. package/src/lib/server/membership-account.d.ts +37 -0
  281. package/src/lib/server/membership-account.js +148 -0
  282. package/src/lib/server/membership-account.js.map +1 -0
  283. package/src/lib/server/membership-admin-password.d.ts +33 -0
  284. package/src/lib/server/membership-admin-password.js +202 -0
  285. package/src/lib/server/membership-admin-password.js.map +1 -0
  286. package/src/lib/server/membership-content.d.ts +23 -0
  287. package/src/lib/server/membership-content.js +105 -0
  288. package/src/lib/server/membership-content.js.map +1 -0
  289. package/src/lib/server/membership-login.d.ts +19 -0
  290. package/src/lib/server/membership-login.js +137 -0
  291. package/src/lib/server/membership-login.js.map +1 -0
  292. package/src/lib/server/membership-logout.d.ts +19 -0
  293. package/src/lib/server/membership-logout.js +35 -0
  294. package/src/lib/server/membership-logout.js.map +1 -0
  295. package/src/lib/server/membership-recover.d.ts +60 -0
  296. package/src/lib/server/membership-recover.js +244 -0
  297. package/src/lib/server/membership-recover.js.map +1 -0
  298. package/src/lib/server/membership-register.d.ts +22 -0
  299. package/src/lib/server/membership-register.js +241 -0
  300. package/src/lib/server/membership-register.js.map +1 -0
  301. package/src/lib/server/membership-reset.d.ts +26 -0
  302. package/src/lib/server/membership-reset.js +88 -0
  303. package/src/lib/server/membership-reset.js.map +1 -0
  304. package/src/lib/server/membership-wishlist.d.ts +23 -0
  305. package/src/lib/server/membership-wishlist.js +89 -0
  306. package/src/lib/server/membership-wishlist.js.map +1 -0
  307. package/src/lib/server/membership.d.ts +96 -0
  308. package/src/lib/server/membership.js +222 -0
  309. package/src/lib/server/membership.js.map +1 -0
  310. package/src/lib/server/native-checkout.d.ts +170 -0
  311. package/src/lib/server/native-checkout.js +193 -0
  312. package/src/lib/server/native-checkout.js.map +1 -0
  313. package/src/lib/server/newsletter.d.ts +23 -0
  314. package/src/lib/server/newsletter.js +323 -0
  315. package/src/lib/server/newsletter.js.map +1 -0
  316. package/src/lib/server/notify-restock.d.ts +22 -0
  317. package/src/lib/server/notify-restock.js +84 -0
  318. package/src/lib/server/notify-restock.js.map +1 -0
  319. package/src/lib/server/order-analytics.d.ts +134 -0
  320. package/src/lib/server/order-analytics.js +263 -0
  321. package/src/lib/server/order-analytics.js.map +1 -0
  322. package/src/lib/server/order-figures.d.ts +33 -0
  323. package/src/lib/server/order-figures.js +220 -0
  324. package/src/lib/server/order-figures.js.map +1 -0
  325. package/src/lib/server/paid-media-delivery.d.ts +173 -0
  326. package/src/lib/server/paid-media-delivery.js +212 -0
  327. package/src/lib/server/paid-media-delivery.js.map +1 -0
  328. package/src/lib/server/pos-order.d.ts +54 -0
  329. package/src/lib/server/pos-order.js +1137 -0
  330. package/src/lib/server/pos-order.js.map +1 -0
  331. package/src/lib/server/process-abandoned.d.ts +54 -0
  332. package/src/lib/server/process-abandoned.js +222 -0
  333. package/src/lib/server/process-abandoned.js.map +1 -0
  334. package/src/lib/server/process-restock.d.ts +42 -0
  335. package/src/lib/server/process-restock.js +219 -0
  336. package/src/lib/server/process-restock.js.map +1 -0
  337. package/src/lib/server/product-card.d.ts +29 -0
  338. package/src/lib/server/product-card.js +54 -0
  339. package/src/lib/server/product-card.js.map +1 -0
  340. package/src/lib/server/product.d.ts +70 -0
  341. package/src/lib/server/product.js +105 -0
  342. package/src/lib/server/product.js.map +1 -0
  343. package/src/lib/server/promotion-hold.d.ts +144 -0
  344. package/src/lib/server/promotion-hold.js +174 -0
  345. package/src/lib/server/promotion-hold.js.map +1 -0
  346. package/src/lib/server/reconcile-stock.d.ts +106 -0
  347. package/src/lib/server/reconcile-stock.js +349 -0
  348. package/src/lib/server/reconcile-stock.js.map +1 -0
  349. package/src/lib/server/refund.d.ts +45 -0
  350. package/src/lib/server/refund.js +607 -0
  351. package/src/lib/server/refund.js.map +1 -0
  352. package/src/lib/server/related.d.ts +24 -0
  353. package/src/lib/server/related.js +104 -0
  354. package/src/lib/server/related.js.map +1 -0
  355. package/src/lib/server/reservation-availability.d.ts +23 -0
  356. package/src/lib/server/reservation-availability.js +111 -0
  357. package/src/lib/server/reservation-availability.js.map +1 -0
  358. package/src/lib/server/reserve-stock.d.ts +156 -0
  359. package/src/lib/server/reserve-stock.js +146 -0
  360. package/src/lib/server/reserve-stock.js.map +1 -0
  361. package/src/lib/server/reserve.d.ts +25 -0
  362. package/src/lib/server/reserve.js +426 -0
  363. package/src/lib/server/reserve.js.map +1 -0
  364. package/src/lib/server/restock-flag.d.ts +202 -0
  365. package/src/lib/server/restock-flag.js +449 -0
  366. package/src/lib/server/restock-flag.js.map +1 -0
  367. package/src/lib/server/reviews.d.ts +51 -0
  368. package/src/lib/server/reviews.js +132 -0
  369. package/src/lib/server/reviews.js.map +1 -0
  370. package/src/lib/server/site-page-enricher.d.ts +42 -0
  371. package/src/lib/server/site-page-enricher.js +149 -0
  372. package/src/lib/server/site-page-enricher.js.map +1 -0
  373. package/src/lib/server/site-page-resolver.d.ts +26 -0
  374. package/src/lib/server/site-page-resolver.js +223 -0
  375. package/src/lib/server/site-page-resolver.js.map +1 -0
  376. package/src/lib/server/stock-hold.d.ts +127 -0
  377. package/src/lib/server/stock-hold.js +258 -0
  378. package/src/lib/server/stock-hold.js.map +1 -0
  379. package/src/lib/server/storefront-tax-record.d.ts +22 -0
  380. package/src/lib/server/storefront-tax-record.js +218 -0
  381. package/src/lib/server/storefront-tax-record.js.map +1 -0
  382. package/src/lib/server/storefront-tax.d.ts +197 -0
  383. package/src/lib/server/storefront-tax.js +245 -0
  384. package/src/lib/server/storefront-tax.js.map +1 -0
  385. package/src/lib/server/stream.d.ts +25 -0
  386. package/src/lib/server/stream.js +191 -0
  387. package/src/lib/server/stream.js.map +1 -0
  388. package/src/lib/server/subscription-portal.d.ts +24 -0
  389. package/src/lib/server/subscription-portal.js +91 -0
  390. package/src/lib/server/subscription-portal.js.map +1 -0
  391. package/src/lib/server/supplier-outbox.d.ts +190 -0
  392. package/src/lib/server/supplier-outbox.js +342 -0
  393. package/src/lib/server/supplier-outbox.js.map +1 -0
  394. package/src/lib/server/supplier-update.d.ts +23 -0
  395. package/src/lib/server/supplier-update.js +289 -0
  396. package/src/lib/server/supplier-update.js.map +1 -0
  397. package/src/lib/server/tax-profile.d.ts +29 -0
  398. package/src/lib/server/tax-profile.js +40 -0
  399. package/src/lib/server/tax-profile.js.map +1 -0
  400. package/src/lib/server.d.ts +32 -0
  401. package/src/lib/server.js +311 -0
  402. package/src/lib/server.js.map +1 -0
  403. package/src/lib/site.d.ts +27 -0
  404. package/src/lib/site.js +134 -0
  405. package/src/lib/site.js.map +1 -0
  406. package/src/lib/utils/escape-html.d.ts +41 -0
  407. package/src/lib/utils/escape-html.js +41 -0
  408. package/src/lib/utils/escape-html.js.map +1 -0
  409. package/src/lib/utils/generate-preset-id.d.ts +19 -0
  410. package/src/lib/utils/generate-preset-id.js +25 -0
  411. package/src/lib/utils/generate-preset-id.js.map +1 -0
  412. package/src/lib/utils/member-continue.d.ts +45 -0
  413. package/src/lib/utils/member-continue.js +49 -0
  414. package/src/lib/utils/member-continue.js.map +1 -0
  415. package/src/lib/utils/use-storefront-purchase-event.d.ts +60 -0
  416. package/src/lib/utils/use-storefront-purchase-event.js +142 -0
  417. package/src/lib/utils/use-storefront-purchase-event.js.map +1 -0
@@ -0,0 +1,1087 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ 'use client';
17
+ import { _ as _extends } from "@swc/helpers/_/_extends";
18
+ import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
19
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
20
+ import * as Aglyn from "@aglyn/aglyn";
21
+ import * as CommerceModel from "../../model/index.js";
22
+ import { CardDisplay, useConfirmationContext } from "@aglyn/shared-ui-jsx";
23
+ import { useSnackbar } from "@aglyn/shared-ui-snackstack";
24
+ import { Timestamp } from "@aglyn/shared-util-timestamp";
25
+ import { Alert, Autocomplete, Button, Chip, Dialog, DialogActions, DialogContent, DialogTitle, Divider, MenuItem, Stack, Switch, TextField, Typography } from "@mui/material";
26
+ import { collection, deleteDoc, doc, setDoc } from "firebase/firestore";
27
+ import { useCallback, useMemo, useState } from "react";
28
+ import { useFirestore, useUser } from "@aglyn/tenant-feature-instance";
29
+ import { ceilingedWindow, collectionCeiling, useFirestoreCollection, writeGuardedBySeed } from "@aglyn/tenant-feature-instance";
30
+ import { ListPagination } from "@aglyn/shared-ui-jsx/components/list-pagination.component";
31
+ import { TABLE_PAGE_SIZE_DEFAULT } from "@aglyn/shared-ui-jsx/const/table-pagination";
32
+ import { pluginDocsHelp } from "@aglyn/aglyn";
33
+ import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
34
+ /**
35
+ * How many category documents the card reads.
36
+ *
37
+ * A CEILING, not a page size — the walk below is a TREE and cannot be sliced
38
+ * by document without orphaning children from parents on another page.
39
+ */ const CATEGORY_CEILING = 250;
40
+ /** The same, for collections: the slug check needs every row to be correct. */ const COLLECTION_CEILING = 250;
41
+ /**
42
+ * The catalog the match counts are computed over.
43
+ *
44
+ * Neither a page size nor a promise: it is how much of the catalog this card
45
+ * is willing to read, and the counts below say "at least" once the probe finds
46
+ * a product past it.
47
+ */ const PRODUCT_CEILING = 500;
48
+ const RULE_FIELDS = [
49
+ {
50
+ value: 'tag',
51
+ label: 'Tag'
52
+ },
53
+ {
54
+ value: 'categoryId',
55
+ label: 'Category'
56
+ },
57
+ {
58
+ value: 'priceUsd',
59
+ label: 'Price'
60
+ },
61
+ {
62
+ value: 'name',
63
+ label: 'Name'
64
+ },
65
+ {
66
+ value: 'type',
67
+ label: 'Type'
68
+ }
69
+ ];
70
+ const RULE_OPS = [
71
+ {
72
+ value: 'eq',
73
+ label: 'is'
74
+ },
75
+ {
76
+ value: 'neq',
77
+ label: 'is not'
78
+ },
79
+ {
80
+ value: 'lt',
81
+ label: 'below'
82
+ },
83
+ {
84
+ value: 'gt',
85
+ label: 'above'
86
+ },
87
+ {
88
+ value: 'contains',
89
+ label: 'contains'
90
+ }
91
+ ];
92
+ /**
93
+ * Categories & collections manager (AGL-280): category tree (parentId)
94
+ * at `hosts/{hostId}/productCategories`, manual + smart collections at
95
+ * `hosts/{hostId}/collections` with a live matched-product preview from
96
+ * the same `matchesCollection` matcher the storefront uses.
97
+ */ export function CatalogOrganizationCard(props) {
98
+ var _CommerceModel_validateCollection, _ref, _ref1, _ref2, _ref3, _ref4;
99
+ const { hostId } = props;
100
+ const firestore = useFirestore();
101
+ const { enqueueSnackbar } = useSnackbar();
102
+ const { confirm } = useConfirmationContext();
103
+ const { data: user } = useUser();
104
+ const { data: categoryDocs, status: categoriesStatus, /**
105
+ * The category rows are unconfirmed by the server (AGL-1358). Two writes
106
+ * are seeded from them: the editor carries `parentId` off the row whether
107
+ * or not the author touched it, and the delete REPARENTS every child of
108
+ * the deleted category — a set computed entirely from this cached read,
109
+ * so a stale snapshot can miss children that should have been moved.
110
+ * (The reparent write itself is narrow since AGL-1374; what remains
111
+ * cache-dependent is WHICH rows it runs on.)
112
+ */ fromCache: categoriesFromCache } = useFirestoreCollection(/*
113
+ * ORDERED AND CEILINGED, deliberately not paged by the query (AGL-2501).
114
+ *
115
+ * `limit(250)` alone is answered in DOCUMENT-ID order and the ids are
116
+ * `createResourceUid()`, so the window was a pseudo-random sample. Naming
117
+ * the order does not change WHICH 250 come back; what it changes is that
118
+ * the obvious next edit is caught — `orderBy('name')` would HIDE every
119
+ * category saved without one, and `orderBy('order')` is worse still, since
120
+ * the walk below already treats a missing `order` as 0.
121
+ *
122
+ * The QUERY is not paged because this is a TREE. The walk puts parents
123
+ * before children and collects orphans by scanning the whole set, so a
124
+ * page boundary would separate a child from the parent that positions it
125
+ * and re-label as an orphan every category whose parent is on another
126
+ * page. The parent PICKER in the dialog reads the same rows for the same
127
+ * reason.
128
+ */ ()=>collectionCeiling(collection(firestore, 'hosts', hostId, 'productCategories'), CATEGORY_CEILING), [
129
+ firestore,
130
+ hostId
131
+ ], {
132
+ idField: '$id'
133
+ });
134
+ const { rows: readCategories, truncated: categoriesTruncated } = ceilingedWindow(categoryDocs, CATEGORY_CEILING);
135
+ const { data: collectionDocs, status: collectionsStatus, /**
136
+ * The collection rows are unconfirmed by the server (AGL-1358). The
137
+ * editor copies a whole stored row and the save posts all of it — the
138
+ * transport is the AGL-978 route rather than a client `setDoc`, but the
139
+ * shape is identical, and so is the damage: `productIds` is the manual
140
+ * membership, so a cached seed drops every product added since that
141
+ * snapshot and the storefront blocks pointing at the collection go empty.
142
+ */ fromCache: collectionsFromCache } = useFirestoreCollection(/*
143
+ * ORDERED AND CEILINGED, deliberately not paged (AGL-2501).
144
+ *
145
+ * The slug check below tests a draft against these rows — two catalog
146
+ * collections answering `/collections/{slug}` is a storefront route that
147
+ * resolves to whichever the server reaches first — so a ten-row server
148
+ * page would compare a new collection against a tenth of the catalog and
149
+ * create the collision the check exists to prevent.
150
+ *
151
+ * The rows are also filtered after reading: content collections (AGL-81)
152
+ * share this subcollection and are classified out below, so a page of ten
153
+ * documents arrives holding anywhere from zero to ten catalog collections.
154
+ */ ()=>collectionCeiling(collection(firestore, 'hosts', hostId, 'collections'), COLLECTION_CEILING), [
155
+ firestore,
156
+ hostId
157
+ ], {
158
+ idField: '$id'
159
+ });
160
+ const { rows: readCollections, truncated: collectionsTruncated } = ceilingedWindow(collectionDocs, COLLECTION_CEILING);
161
+ const { data: productDocs } = useFirestoreCollection(/*
162
+ * The catalog behind the MATCH COUNTS, ceilinged with a probe (AGL-2501).
163
+ *
164
+ * `collectionCount` and the smart-collection preview both count this array
165
+ * and print the result as a number of products. It was a bare `limit(500)`,
166
+ * so on a three-thousand-product catalog "Matches 47 products" meant "47 of
167
+ * the five hundred I read" — a count that is a window length, on the
168
+ * control that decides what a collection contains.
169
+ *
170
+ * It stays a window, because the honest alternative is reading the whole
171
+ * catalog on every mount of this card. What changes is that the probe makes
172
+ * the shortfall a FACT, and the counts say "at least" when it bit rather
173
+ * than stating a total they cannot know.
174
+ */ ()=>collectionCeiling(collection(firestore, 'hosts', hostId, 'products'), PRODUCT_CEILING), [
175
+ firestore,
176
+ hostId
177
+ ], {
178
+ idField: '$id'
179
+ });
180
+ const { rows: readProducts, truncated: productsTruncated } = ceilingedWindow(productDocs, PRODUCT_CEILING);
181
+ const products = useMemo(()=>[
182
+ ...readProducts
183
+ ].filter((product)=>!product.deletedAt).map((product)=>_extends({}, CommerceModel.liftLegacyProduct(product), {
184
+ $id: product.$id
185
+ })), // eslint-disable-next-line react-hooks/exhaustive-deps
186
+ [
187
+ productDocs
188
+ ]);
189
+ // Content collections (AGL-81) live in the same `hosts/{hostId}/collections`
190
+ // subcollection. This used to keep them out by requiring a non-empty
191
+ // `name`, which held only because the Content page happens to write
192
+ // `displayName` — a content doc that ever acquired a `name` (an import, a
193
+ // hand edit) would land in this list, and its Delete reached the
194
+ // recursiveDelete route (AGL-947). The shared classifier is the real
195
+ // check (AGL-954); the route re-checks it, and AGL-1324 now refuses any
196
+ // collection with entries besides.
197
+ const commerceCollections = useMemo(()=>readCollections.filter(Aglyn.isHostCollectionKind('catalog')), // eslint-disable-next-line react-hooks/exhaustive-deps
198
+ [
199
+ collectionDocs
200
+ ]);
201
+ // Categories ordered as a walked tree: parents before children.
202
+ const categories = useMemo(()=>{
203
+ const rows = [
204
+ ...readCategories
205
+ ];
206
+ rows.sort((a, b)=>{
207
+ var _a_order, _b_order;
208
+ return ((_a_order = a.order) != null ? _a_order : 0) - ((_b_order = b.order) != null ? _b_order : 0) || a.name.localeCompare(b.name);
209
+ });
210
+ const byParent = new Map();
211
+ for (const row of rows){
212
+ var _row_parentId, _byParent_get;
213
+ const key = (_row_parentId = row.parentId) != null ? _row_parentId : null;
214
+ byParent.set(key, [
215
+ ...(_byParent_get = byParent.get(key)) != null ? _byParent_get : [],
216
+ row
217
+ ]);
218
+ }
219
+ const walked = [];
220
+ const walk = (parentId, depth)=>{
221
+ var _byParent_get;
222
+ for (const row of (_byParent_get = byParent.get(parentId)) != null ? _byParent_get : []){
223
+ walked.push(_extends({}, row, {
224
+ depth
225
+ }));
226
+ if (depth < 4) walk(row.$id, depth + 1);
227
+ }
228
+ };
229
+ walk(null, 0);
230
+ // Orphans (parent deleted) still show, at the root.
231
+ for (const row of rows){
232
+ if (!walked.some((item)=>item.$id === row.$id)) {
233
+ walked.push(_extends({}, row, {
234
+ depth: 0
235
+ }));
236
+ }
237
+ }
238
+ return walked;
239
+ // eslint-disable-next-line react-hooks/exhaustive-deps
240
+ }, [
241
+ categoryDocs
242
+ ]);
243
+ /*
244
+ * Both pages are SLICES: the rows are already in hand, and the tree walk,
245
+ * the parent picker and the slug check all need every one of them.
246
+ */ const [categoryPage, setCategoryPage] = useState(0);
247
+ const [categoryPageSize, setCategoryPageSize] = useState(TABLE_PAGE_SIZE_DEFAULT);
248
+ const visibleCategories = useMemo(()=>categories.slice(categoryPage * categoryPageSize, categoryPage * categoryPageSize + categoryPageSize), [
249
+ categories,
250
+ categoryPage,
251
+ categoryPageSize
252
+ ]);
253
+ const [collectionPage, setCollectionPage] = useState(0);
254
+ const [collectionPageSize, setCollectionPageSize] = useState(TABLE_PAGE_SIZE_DEFAULT);
255
+ const visibleCollections = useMemo(()=>commerceCollections.slice(collectionPage * collectionPageSize, collectionPage * collectionPageSize + collectionPageSize), [
256
+ commerceCollections,
257
+ collectionPage,
258
+ collectionPageSize
259
+ ]);
260
+ const [categoryDraft, setCategoryDraft] = useState(null);
261
+ const [collectionDraft, setCollectionDraft] = useState(null);
262
+ const handleCategorySave = useCallback(async ()=>{
263
+ var _categoryDraft_id;
264
+ if (!(categoryDraft == null ? void 0 : categoryDraft.name.trim())) return;
265
+ const id = (_categoryDraft_id = categoryDraft.id) != null ? _categoryDraft_id : Aglyn.createResourceUid();
266
+ /**
267
+ * Refuse an EDIT whose seed the server never confirmed (AGL-1358).
268
+ *
269
+ * The payload is narrower than most sites in this issue, but `parentId`
270
+ * is carried off the seeded row on every save whether or not the author
271
+ * opened the parent picker — so renaming a category against a cached read
272
+ * can move it, and the whole subtree under it, back to a parent someone
273
+ * had already reorganised away from.
274
+ *
275
+ * Only the edit path. A NEW category is built from blanks at a fresh uid
276
+ * and can overwrite nothing, and the first snapshot of any listener is
277
+ * `fromCache: true`, so guarding a create would refuse a save that was
278
+ * never unsafe.
279
+ *
280
+ * The guard WRAPS the write — an early return is a shape you can keep
281
+ * while losing the protection.
282
+ */ const verdict = await writeGuardedBySeed({
283
+ subject: 'category',
284
+ unreadable: Boolean(categoryDraft.id) && categoriesStatus === 'error',
285
+ fromCache: Boolean(categoryDraft.id) && categoriesFromCache
286
+ }, async ()=>{
287
+ /**
288
+ * `merge: true`, because this payload is NARROWER than the document
289
+ * (AGL-1372). A replacing write deletes every stored key the form
290
+ * does not send, and this form sends four:
291
+ *
292
+ * - `order` — the tree position. Both sorts read it (the walk above,
293
+ * and `queryPublicCatalog`'s facet chips), and nothing in this card
294
+ * can set it, so it is not the form's to send: a rename dropped it
295
+ * and the category fell back to `?? 0`, reordering the storefront's
296
+ * filter chips.
297
+ * - `createdAt` — written at creation by the seeder, never by this
298
+ * card, so a rename erased it too.
299
+ *
300
+ * Carrying `order` in the payload would have fixed the field we
301
+ * happened to notice and left `createdAt`, plus whatever the document
302
+ * grows next. Merging fixes the shape. Nothing here needs delete
303
+ * semantics — `parentId` clears to an explicit `null`, which merges.
304
+ */ await setDoc(doc(firestore, 'hosts', hostId, 'productCategories', id), {
305
+ name: categoryDraft.name.trim().slice(0, 80),
306
+ slug: CommerceModel.commerceSlug(categoryDraft.name),
307
+ parentId: categoryDraft.parentId || null,
308
+ updatedAt: Timestamp.now()
309
+ }, {
310
+ merge: true
311
+ });
312
+ });
313
+ // Before `setCategoryDraft(null)`, so a refusal keeps the dialog open
314
+ // with what was typed.
315
+ if (!verdict.ok) {
316
+ return void enqueueSnackbar(verdict.message, {
317
+ variant: 'warning',
318
+ persist: false
319
+ });
320
+ }
321
+ setCategoryDraft(null);
322
+ enqueueSnackbar('Category saved', {
323
+ variant: 'success',
324
+ persist: false
325
+ });
326
+ }, [
327
+ categoryDraft,
328
+ firestore,
329
+ hostId,
330
+ enqueueSnackbar,
331
+ categoriesStatus,
332
+ categoriesFromCache
333
+ ]);
334
+ const handleCategoryDelete = useCallback((category)=>async ()=>{
335
+ const confirmed = await confirm({
336
+ title: 'Delete this category?',
337
+ description: `Products keep their other categories; children of ` + `"${category.name}" move to the top level.`,
338
+ confirmationText: 'Delete',
339
+ confirmationButtonProps: {
340
+ color: 'error'
341
+ }
342
+ }).then(()=>true).catch(()=>false);
343
+ if (!confirmed) return;
344
+ /**
345
+ * Refuse the whole sequence when the rows it reads were never confirmed
346
+ * by the server (AGL-1358).
347
+ *
348
+ * The reparent is this issue's shape at its least visible: the author
349
+ * opened no editor, so there is nothing on screen to look stale, and
350
+ * `children` is read straight out of the cache. The write itself is
351
+ * now narrow (see below), so a stale row can no longer be copied back
352
+ * over a child — but WHICH rows are children is still a cached answer.
353
+ *
354
+ * The guard encloses the DELETE as well, for the reason the site
355
+ * details rename did: `children` is computed from the same seed, so a
356
+ * cached read can miss children entirely, and deleting the parent
357
+ * without reparenting them leaves them pointing at a category that no
358
+ * longer exists. Half of this sequence is worse than none of it.
359
+ */ const verdict = await writeGuardedBySeed({
360
+ subject: 'categories',
361
+ unreadable: categoriesStatus === 'error',
362
+ fromCache: categoriesFromCache
363
+ }, async ()=>{
364
+ // Reparent children to root, then remove.
365
+ const children = (categoryDocs != null ? categoryDocs : []).filter((row)=>row.parentId === category.$id);
366
+ /**
367
+ * Write only the field the reparent changes (AGL-1374).
368
+ *
369
+ * `{...child}` spread the listener row, and that row carries a
370
+ * SYNTHETIC `$id` — `idField: '$id'` stamps the document id onto
371
+ * the in-memory object, where nothing persists it. Spreading it
372
+ * into the payload persisted it: every delete-with-children added
373
+ * a real `$id` key to each child, permanently, and a child
374
+ * reparented twice could end up carrying one that no longer
375
+ * matched its own document id. Nothing reads it, so nothing broke
376
+ * — it is the listener's bookkeeping leaking into storage, and
377
+ * once there no reader can tell it from a real field.
378
+ *
379
+ * `{ parentId: null }` with `{ merge: true }` is what the reparent
380
+ * actually means, and it is the stronger fix than stripping `$id`
381
+ * off a full spread: the old write had no options argument, so it
382
+ * was also a whole-document REPLACE of a cached row — the AGL-1358
383
+ * hazard in miniature (and AGL-1372's, one collection over). A
384
+ * narrow merge cannot carry a synthetic key it never names, and
385
+ * cannot rewrite a field the delete has no business touching.
386
+ *
387
+ * `null` is a value, not a deletion, so it merges: the child ends
388
+ * up at the top level, which is what the confirmation promised.
389
+ */ for (const child of children){
390
+ await setDoc(doc(firestore, 'hosts', hostId, 'productCategories', child.$id), {
391
+ parentId: null
392
+ }, {
393
+ merge: true
394
+ });
395
+ }
396
+ await deleteDoc(doc(firestore, 'hosts', hostId, 'productCategories', category.$id));
397
+ });
398
+ // This path had no report of its own. A delete that silently does
399
+ // nothing after the user confirmed it reads as a delete that worked.
400
+ if (!verdict.ok) {
401
+ enqueueSnackbar(verdict.message, {
402
+ variant: 'warning',
403
+ persist: false
404
+ });
405
+ }
406
+ }, [
407
+ confirm,
408
+ categoryDocs,
409
+ firestore,
410
+ hostId,
411
+ enqueueSnackbar,
412
+ categoriesStatus,
413
+ categoriesFromCache
414
+ ]);
415
+ const draftSlug = collectionDraft ? collectionDraft.slug || CommerceModel.commerceSlug(collectionDraft.name) : '';
416
+ // The slug is the collection's public address at /collections/{slug} and
417
+ // nothing enforced uniqueness (AGL-957) — a second one at the same slug
418
+ // made the first unreachable with no error anywhere. Checked against the
419
+ // catalog collections only; content collections have their own namespace.
420
+ const slugTaken = collectionDraft !== null && Aglyn.isCollectionSlugTaken(draftSlug, 'catalog', commerceCollections, collectionDraft.id);
421
+ const collectionError = collectionDraft ? collectionDraft.name ? (_CommerceModel_validateCollection = CommerceModel.validateCollection(_extends({}, collectionDraft, {
422
+ slug: draftSlug
423
+ }))) != null ? _CommerceModel_validateCollection : slugTaken ? `Another collection already serves /collections/${draftSlug}` : null : null : null;
424
+ const previewMatches = useMemo(()=>{
425
+ if (!collectionDraft) return [];
426
+ const candidate = _extends({}, collectionDraft, {
427
+ slug: collectionDraft.slug || CommerceModel.commerceSlug(collectionDraft.name)
428
+ });
429
+ return products.filter((product)=>CommerceModel.matchesCollection(product, candidate, product.$id));
430
+ }, [
431
+ collectionDraft,
432
+ products
433
+ ]);
434
+ const handleCollectionSave = useCallback(async ()=>{
435
+ if (!(collectionDraft == null ? void 0 : collectionDraft.name.trim()) || collectionError) return;
436
+ const { id: draftId } = collectionDraft, data = _object_without_properties_loose(collectionDraft, [
437
+ "id"
438
+ ]);
439
+ // Both create and rename go through the route (AGL-978): this save writes
440
+ // the whole document including `slug`, which is the collection's public
441
+ // address and is claimed transactionally there. Rules deny a client
442
+ // create, and freeze `slug`/`kind` on update.
443
+ /**
444
+ * Refuse an UPDATE whose seed the server never confirmed (AGL-1358).
445
+ *
446
+ * The transport is the route rather than a client `setDoc`, but the shape
447
+ * is the one this issue is about: `data` is the whole stored row copied
448
+ * out of the listener, and the route writes what it is sent. `productIds`
449
+ * is the manual membership, so a cached seed drops every product added
450
+ * since that snapshot and the storefront blocks pointing at the
451
+ * collection go empty; `rules` and `matchAll` do the same for a smart
452
+ * collection. That the write leaves the browser over HTTP changes who
453
+ * performs it, not what it destroys.
454
+ *
455
+ * Only the update path. A CREATE is built from blanks, and the route
456
+ * claims a fresh slug transactionally, so it can overwrite nothing.
457
+ *
458
+ * The guard WRAPS the request — an early return is a shape you can keep
459
+ * while losing the protection.
460
+ */ let verdict;
461
+ try {
462
+ verdict = await writeGuardedBySeed({
463
+ subject: 'collection',
464
+ unreadable: Boolean(draftId) && collectionsStatus === 'error',
465
+ fromCache: Boolean(draftId) && collectionsFromCache
466
+ }, async ()=>{
467
+ const response = await authorizedFetch(user, '/api/hosts/collections', {
468
+ method: 'POST',
469
+ headers: {
470
+ 'Content-Type': 'application/json'
471
+ },
472
+ body: JSON.stringify(_extends({
473
+ hostId,
474
+ action: draftId ? 'update' : 'create',
475
+ kind: 'catalog'
476
+ }, draftId ? {
477
+ id: draftId
478
+ } : {}, {
479
+ data: _extends({}, data, {
480
+ name: collectionDraft.name.trim().slice(0, 80),
481
+ slug: draftSlug
482
+ })
483
+ }))
484
+ });
485
+ const result = await response.json().catch(()=>({}));
486
+ if (!response.ok) {
487
+ var _ref;
488
+ throw new Error((_ref = result == null ? void 0 : result.error) != null ? _ref : 'Collection save failed');
489
+ }
490
+ });
491
+ } catch (error) {
492
+ var _ref;
493
+ return void enqueueSnackbar((_ref = error == null ? void 0 : error.message) != null ? _ref : 'Collection save failed', {
494
+ variant: 'error'
495
+ });
496
+ }
497
+ // Before `setCollectionDraft(null)`, so a refusal keeps the dialog open
498
+ // with the membership that was picked.
499
+ if (!verdict.ok) {
500
+ return void enqueueSnackbar(verdict.message, {
501
+ variant: 'warning',
502
+ persist: false
503
+ });
504
+ }
505
+ setCollectionDraft(null);
506
+ enqueueSnackbar('Collection saved', {
507
+ variant: 'success',
508
+ persist: false
509
+ });
510
+ }, [
511
+ collectionDraft,
512
+ collectionError,
513
+ draftSlug,
514
+ user,
515
+ hostId,
516
+ enqueueSnackbar,
517
+ collectionsStatus,
518
+ collectionsFromCache
519
+ ]);
520
+ const handleCollectionDelete = useCallback((row)=>async ()=>{
521
+ const confirmed = await confirm({
522
+ title: 'Delete this collection?',
523
+ // NOT a cascade any more (AGL-1324/AGL-1336): the route REFUSES a
524
+ // collection anything still depends on. Promising to take the
525
+ // entries with it was the opposite of what happens, and the two
526
+ // blockers are the whole point of the feature — say them before the
527
+ // button is armed, not in a 409 afterwards.
528
+ description: `Storefront blocks pointing at "${row.name}" go empty. The delete ` + 'is refused while the collection still has entries, or while a ' + 'screen uses it as a list or entry template — empty it and detach ' + 'those screens first. It also takes the site admin role.',
529
+ confirmationText: 'Delete',
530
+ confirmationButtonProps: {
531
+ color: 'error'
532
+ }
533
+ }).then(()=>true).catch(()=>false);
534
+ if (!confirmed) return;
535
+ // A collection owns an `entries` subcollection (the Content page's
536
+ // published entries) and Firestore doesn't cascade, so deleting the
537
+ // doc from here stranded them — still editor-writable through the
538
+ // host catch-all rule, just unreachable. recursiveDelete is
539
+ // Admin-SDK-only, hence the route (AGL-947). Since AGL-1324 the route
540
+ // also refuses rather than cascading; the 409's message names the
541
+ // blockers and is surfaced by the catch below.
542
+ try {
543
+ const response = await authorizedFetch(user, '/api/resources/erase', {
544
+ method: 'POST',
545
+ headers: {
546
+ 'Content-Type': 'application/json'
547
+ },
548
+ body: JSON.stringify({
549
+ scope: 'hosts',
550
+ scopeId: hostId,
551
+ kind: 'collections',
552
+ id: row.$id,
553
+ // The route re-checks this server-side (AGL-954): a stale client
554
+ // must not be able to recursiveDelete a content collection's
555
+ // entries through the catalog card.
556
+ collectionKind: 'catalog'
557
+ })
558
+ });
559
+ const result = await response.json().catch(()=>({}));
560
+ if (!response.ok) {
561
+ var _ref;
562
+ throw new Error((_ref = result == null ? void 0 : result.error) != null ? _ref : 'Collection delete failed');
563
+ }
564
+ } catch (error) {
565
+ var _ref1;
566
+ return void enqueueSnackbar((_ref1 = error == null ? void 0 : error.message) != null ? _ref1 : 'Collection delete failed', {
567
+ variant: 'error'
568
+ });
569
+ }
570
+ enqueueSnackbar('Collection deleted', {
571
+ variant: 'success',
572
+ persist: false
573
+ });
574
+ }, [
575
+ confirm,
576
+ user,
577
+ hostId,
578
+ enqueueSnackbar
579
+ ]);
580
+ /**
581
+ * How many products a collection holds — over the CATALOG WINDOW.
582
+ *
583
+ * Rendered with "at least" when the probe found a product past the ceiling,
584
+ * because past that point this is a lower bound and printing it as a total
585
+ * is the count-that-is-a-window-length defect. The number itself is honest
586
+ * either way; only the claim around it changes.
587
+ */ const collectionCount = (row)=>products.filter((product)=>CommerceModel.matchesCollection(product, row, product.$id)).length;
588
+ /*
589
+ * "at least", or nothing at all.
590
+ *
591
+ * Every count on this card is computed over `products`, which is the catalog
592
+ * WINDOW rather than the catalog. While the probe finds a product past the
593
+ * ceiling those counts are lower bounds, and printing one as a total is the
594
+ * count-that-is-a-window-length defect this ceiling exists to make visible.
595
+ *
596
+ * Keyed on the probe rather than on `products.length >= PRODUCT_CEILING`,
597
+ * because a catalog of exactly the ceiling is complete: nothing is missing,
598
+ * and a comparison would put "at least" on a number that is exact.
599
+ */ const countPrefix = productsTruncated ? 'at least ' : '';
600
+ const updateRule = (index, patch)=>{
601
+ var _collectionDraft_rules;
602
+ if (!collectionDraft) return;
603
+ const rules = [
604
+ ...(_collectionDraft_rules = collectionDraft.rules) != null ? _collectionDraft_rules : []
605
+ ];
606
+ if (patch === null) rules.splice(index, 1);
607
+ else rules[index] = _extends({
608
+ field: 'tag',
609
+ op: 'eq',
610
+ value: ''
611
+ }, rules[index], patch);
612
+ setCollectionDraft(_extends({}, collectionDraft, {
613
+ rules
614
+ }));
615
+ };
616
+ return /*#__PURE__*/ _jsxs(CardDisplay, {
617
+ header: 'Categories & collections',
618
+ help: pluginDocsHelp('catalog', {
619
+ anchor: '#categories-and-tags'
620
+ }),
621
+ contentGutterX: true,
622
+ contentGutterY: true,
623
+ children: [
624
+ /*#__PURE__*/ _jsxs(Stack, {
625
+ spacing: 1,
626
+ children: [
627
+ /*#__PURE__*/ _jsx(Typography, {
628
+ variant: "subtitle2",
629
+ children: 'Categories'
630
+ }),
631
+ categories.length === 0 ? /*#__PURE__*/ _jsx(Typography, {
632
+ variant: "body2",
633
+ color: "text.secondary",
634
+ children: 'Group products into a browsable tree (e.g. Brakes → Pads).'
635
+ }) : visibleCategories.map((category)=>/*#__PURE__*/ _jsxs(Stack, {
636
+ direction: "row",
637
+ spacing: 1,
638
+ sx: {
639
+ alignItems: 'center',
640
+ pl: category.depth * 2
641
+ },
642
+ children: [
643
+ /*#__PURE__*/ _jsxs(Typography, {
644
+ variant: "body2",
645
+ sx: {
646
+ flex: 1
647
+ },
648
+ noWrap: true,
649
+ children: [
650
+ category.name,
651
+ /*#__PURE__*/ _jsx(Typography, {
652
+ component: "span",
653
+ variant: "caption",
654
+ color: "text.secondary",
655
+ children: ` /${category.slug}`
656
+ })
657
+ ]
658
+ }),
659
+ /*#__PURE__*/ _jsx(Button, {
660
+ size: "small",
661
+ onClick: ()=>{
662
+ var _category_parentId;
663
+ return setCategoryDraft({
664
+ id: category.$id,
665
+ name: category.name,
666
+ parentId: (_category_parentId = category.parentId) != null ? _category_parentId : ''
667
+ });
668
+ },
669
+ children: 'Edit'
670
+ }),
671
+ /*#__PURE__*/ _jsx(Button, {
672
+ size: "small",
673
+ color: "error",
674
+ onClick: handleCategoryDelete(category),
675
+ children: 'Delete'
676
+ })
677
+ ]
678
+ }, category.$id)),
679
+ categories.length === 0 ? null : /*#__PURE__*/ _jsx(ListPagination, {
680
+ page: categoryPage,
681
+ pageSize: categoryPageSize,
682
+ rowCount: visibleCategories.length,
683
+ // The categories the card HOLDS — a client slice of rows already
684
+ // read, so the total is known exactly.
685
+ count: categories.length,
686
+ onPageChange: setCategoryPage,
687
+ onPageSizeChange: setCategoryPageSize
688
+ }),
689
+ categoriesTruncated ? /*#__PURE__*/ _jsx(Alert, {
690
+ severity: "info",
691
+ children: `Showing ${CATEGORY_CEILING} categories, ordered by id. This ` + 'catalog has more — a category whose parent is past that ' + 'boundary is drawn at the top level here rather than under it.'
692
+ }) : null,
693
+ /*#__PURE__*/ _jsx(Button, {
694
+ size: "small",
695
+ sx: {
696
+ alignSelf: 'flex-start'
697
+ },
698
+ onClick: ()=>setCategoryDraft({
699
+ id: null,
700
+ name: '',
701
+ parentId: ''
702
+ }),
703
+ children: 'Add category'
704
+ }),
705
+ /*#__PURE__*/ _jsx(Divider, {
706
+ sx: {
707
+ my: 1
708
+ }
709
+ }),
710
+ /*#__PURE__*/ _jsx(Typography, {
711
+ variant: "subtitle2",
712
+ children: 'Collections'
713
+ }),
714
+ visibleCollections.map((row)=>{
715
+ var _row_mode;
716
+ return /*#__PURE__*/ _jsxs(Stack, {
717
+ direction: "row",
718
+ spacing: 1,
719
+ sx: {
720
+ alignItems: 'center'
721
+ },
722
+ children: [
723
+ /*#__PURE__*/ _jsxs(Typography, {
724
+ variant: "body2",
725
+ sx: {
726
+ flex: 1
727
+ },
728
+ noWrap: true,
729
+ children: [
730
+ row.name,
731
+ /*#__PURE__*/ _jsx(Typography, {
732
+ component: "span",
733
+ variant: "caption",
734
+ color: "text.secondary",
735
+ children: ` · ${(_row_mode = row.mode) != null ? _row_mode : 'manual'} · ${countPrefix}${collectionCount(row)} products`
736
+ })
737
+ ]
738
+ }),
739
+ /*#__PURE__*/ _jsx(Button, {
740
+ size: "small",
741
+ onClick: ()=>{
742
+ var _row_slug, _row_mode, _row_productIds, _row_rules;
743
+ return setCollectionDraft({
744
+ id: row.$id,
745
+ name: row.name,
746
+ slug: (_row_slug = row.slug) != null ? _row_slug : '',
747
+ mode: (_row_mode = row.mode) != null ? _row_mode : 'manual',
748
+ productIds: (_row_productIds = row.productIds) != null ? _row_productIds : [],
749
+ rules: (_row_rules = row.rules) != null ? _row_rules : [],
750
+ matchAll: row.matchAll !== false
751
+ });
752
+ },
753
+ children: 'Edit'
754
+ }),
755
+ /*#__PURE__*/ _jsx(Button, {
756
+ size: "small",
757
+ color: "error",
758
+ onClick: handleCollectionDelete(row),
759
+ children: 'Delete'
760
+ })
761
+ ]
762
+ }, row.$id);
763
+ }),
764
+ commerceCollections.length === 0 ? null : /*#__PURE__*/ _jsx(ListPagination, {
765
+ page: collectionPage,
766
+ pageSize: collectionPageSize,
767
+ rowCount: visibleCollections.length,
768
+ // The CATALOG collections, which is what this list is. Not the
769
+ // window's length: content collections share the subcollection
770
+ // and are classified out before this count is taken.
771
+ count: commerceCollections.length,
772
+ onPageChange: setCollectionPage,
773
+ onPageSizeChange: setCollectionPageSize
774
+ }),
775
+ collectionsTruncated ? /*#__PURE__*/ _jsx(Alert, {
776
+ severity: "info",
777
+ children: `Showing ${COLLECTION_CEILING} collections, ordered by id. This ` + 'site has more — the slug check below only covers the ones ' + 'listed here, so an address may already be taken by one that ' + 'is not.'
778
+ }) : null,
779
+ /*#__PURE__*/ _jsx(Button, {
780
+ size: "small",
781
+ sx: {
782
+ alignSelf: 'flex-start'
783
+ },
784
+ onClick: ()=>setCollectionDraft({
785
+ id: null,
786
+ name: '',
787
+ slug: '',
788
+ mode: 'manual',
789
+ productIds: [],
790
+ rules: [],
791
+ matchAll: true
792
+ }),
793
+ children: 'Add collection'
794
+ })
795
+ ]
796
+ }),
797
+ /*#__PURE__*/ _jsxs(Dialog, {
798
+ open: Boolean(categoryDraft),
799
+ onClose: ()=>setCategoryDraft(null),
800
+ maxWidth: "xs",
801
+ fullWidth: true,
802
+ children: [
803
+ /*#__PURE__*/ _jsx(DialogTitle, {
804
+ children: (categoryDraft == null ? void 0 : categoryDraft.id) ? 'Edit category' : 'New category'
805
+ }),
806
+ /*#__PURE__*/ _jsxs(DialogContent, {
807
+ sx: {
808
+ display: 'flex',
809
+ flexDirection: 'column',
810
+ gap: 2
811
+ },
812
+ children: [
813
+ /*#__PURE__*/ _jsx(TextField, {
814
+ label: "Name",
815
+ value: (_ref = categoryDraft == null ? void 0 : categoryDraft.name) != null ? _ref : '',
816
+ onChange: (event)=>setCategoryDraft((prev)=>prev ? _extends({}, prev, {
817
+ name: event.target.value
818
+ }) : prev),
819
+ size: "small",
820
+ autoFocus: true,
821
+ sx: {
822
+ mt: 1
823
+ }
824
+ }),
825
+ /*#__PURE__*/ _jsxs(TextField, {
826
+ label: "Parent category",
827
+ value: (_ref1 = categoryDraft == null ? void 0 : categoryDraft.parentId) != null ? _ref1 : '',
828
+ onChange: (event)=>setCategoryDraft((prev)=>prev ? _extends({}, prev, {
829
+ parentId: event.target.value
830
+ }) : prev),
831
+ size: "small",
832
+ select: true,
833
+ children: [
834
+ /*#__PURE__*/ _jsx(MenuItem, {
835
+ value: "",
836
+ children: 'None (top level)'
837
+ }),
838
+ categories.filter((category)=>category.$id !== (categoryDraft == null ? void 0 : categoryDraft.id)).map((category)=>/*#__PURE__*/ _jsx(MenuItem, {
839
+ value: category.$id,
840
+ children: `${'— '.repeat(category.depth)}${category.name}`
841
+ }, category.$id))
842
+ ]
843
+ })
844
+ ]
845
+ }),
846
+ /*#__PURE__*/ _jsxs(DialogActions, {
847
+ children: [
848
+ /*#__PURE__*/ _jsx(Button, {
849
+ onClick: ()=>setCategoryDraft(null),
850
+ children: 'Cancel'
851
+ }),
852
+ /*#__PURE__*/ _jsx(Button, {
853
+ variant: "contained",
854
+ color: "primary",
855
+ disabled: !(categoryDraft == null ? void 0 : categoryDraft.name.trim()),
856
+ onClick: handleCategorySave,
857
+ children: 'Save'
858
+ })
859
+ ]
860
+ })
861
+ ]
862
+ }),
863
+ /*#__PURE__*/ _jsxs(Dialog, {
864
+ open: Boolean(collectionDraft),
865
+ onClose: ()=>setCollectionDraft(null),
866
+ maxWidth: "sm",
867
+ fullWidth: true,
868
+ children: [
869
+ /*#__PURE__*/ _jsx(DialogTitle, {
870
+ children: (collectionDraft == null ? void 0 : collectionDraft.id) ? 'Edit collection' : 'New collection'
871
+ }),
872
+ /*#__PURE__*/ _jsxs(DialogContent, {
873
+ sx: {
874
+ display: 'flex',
875
+ flexDirection: 'column',
876
+ gap: 2
877
+ },
878
+ children: [
879
+ /*#__PURE__*/ _jsx(TextField, {
880
+ label: "Name",
881
+ value: (_ref2 = collectionDraft == null ? void 0 : collectionDraft.name) != null ? _ref2 : '',
882
+ onChange: (event)=>setCollectionDraft((prev)=>prev ? _extends({}, prev, {
883
+ name: event.target.value
884
+ }) : prev),
885
+ size: "small",
886
+ autoFocus: true,
887
+ sx: {
888
+ mt: 1
889
+ },
890
+ error: slugTaken,
891
+ helperText: (collectionDraft == null ? void 0 : collectionDraft.name) ? `/collections/${draftSlug}` : undefined
892
+ }),
893
+ /*#__PURE__*/ _jsxs(TextField, {
894
+ label: "Mode",
895
+ value: (_ref3 = collectionDraft == null ? void 0 : collectionDraft.mode) != null ? _ref3 : 'manual',
896
+ onChange: (event)=>setCollectionDraft((prev)=>prev ? _extends({}, prev, {
897
+ mode: event.target.value
898
+ }) : prev),
899
+ size: "small",
900
+ select: true,
901
+ children: [
902
+ /*#__PURE__*/ _jsx(MenuItem, {
903
+ value: "manual",
904
+ children: 'Manual — pick products'
905
+ }),
906
+ /*#__PURE__*/ _jsx(MenuItem, {
907
+ value: "smart",
908
+ children: 'Smart — rule based'
909
+ })
910
+ ]
911
+ }),
912
+ (collectionDraft == null ? void 0 : collectionDraft.mode) === 'manual' ? /*#__PURE__*/ _jsx(Autocomplete, {
913
+ multiple: true,
914
+ options: products,
915
+ getOptionLabel: (product)=>product.name,
916
+ isOptionEqualToValue: (option, value)=>option.$id === value.$id,
917
+ value: products.filter((product)=>{
918
+ var _collectionDraft_productIds;
919
+ return ((_collectionDraft_productIds = collectionDraft.productIds) != null ? _collectionDraft_productIds : []).includes(product.$id);
920
+ }),
921
+ onChange: (_event, picked)=>setCollectionDraft((prev)=>prev ? _extends({}, prev, {
922
+ productIds: picked.map((item)=>item.$id)
923
+ }) : prev),
924
+ renderInput: (params)=>/*#__PURE__*/ _jsx(TextField, _extends({}, params, {
925
+ label: "Products",
926
+ size: "small"
927
+ }))
928
+ }) : /*#__PURE__*/ _jsxs(_Fragment, {
929
+ children: [
930
+ /*#__PURE__*/ _jsxs(Stack, {
931
+ direction: "row",
932
+ spacing: 1,
933
+ sx: {
934
+ alignItems: 'center'
935
+ },
936
+ children: [
937
+ /*#__PURE__*/ _jsx(Typography, {
938
+ variant: "body2",
939
+ children: 'Match'
940
+ }),
941
+ /*#__PURE__*/ _jsx(Switch, {
942
+ size: "small",
943
+ checked: (collectionDraft == null ? void 0 : collectionDraft.matchAll) !== false,
944
+ onChange: (event)=>setCollectionDraft((prev)=>prev ? _extends({}, prev, {
945
+ matchAll: event.target.checked
946
+ }) : prev)
947
+ }),
948
+ /*#__PURE__*/ _jsx(Typography, {
949
+ variant: "body2",
950
+ children: (collectionDraft == null ? void 0 : collectionDraft.matchAll) !== false ? 'all rules' : 'any rule'
951
+ })
952
+ ]
953
+ }),
954
+ ((_ref4 = collectionDraft == null ? void 0 : collectionDraft.rules) != null ? _ref4 : []).map((rule, index)=>/*#__PURE__*/ _jsxs(Stack, {
955
+ direction: "row",
956
+ spacing: 1,
957
+ children: [
958
+ /*#__PURE__*/ _jsx(TextField, {
959
+ value: rule.field,
960
+ onChange: (event)=>updateRule(index, {
961
+ field: event.target.value
962
+ }),
963
+ size: "small",
964
+ select: true,
965
+ sx: {
966
+ width: 130
967
+ },
968
+ children: RULE_FIELDS.map((field)=>/*#__PURE__*/ _jsx(MenuItem, {
969
+ value: field.value,
970
+ children: field.label
971
+ }, field.value))
972
+ }),
973
+ /*#__PURE__*/ _jsx(TextField, {
974
+ value: rule.op,
975
+ onChange: (event)=>updateRule(index, {
976
+ op: event.target.value
977
+ }),
978
+ size: "small",
979
+ select: true,
980
+ sx: {
981
+ width: 110
982
+ },
983
+ children: RULE_OPS.map((op)=>/*#__PURE__*/ _jsx(MenuItem, {
984
+ value: op.value,
985
+ children: op.label
986
+ }, op.value))
987
+ }),
988
+ rule.field === 'categoryId' ? /*#__PURE__*/ _jsx(TextField, {
989
+ value: rule.value,
990
+ onChange: (event)=>updateRule(index, {
991
+ value: event.target.value
992
+ }),
993
+ size: "small",
994
+ select: true,
995
+ sx: {
996
+ flex: 1
997
+ },
998
+ children: categories.map((category)=>/*#__PURE__*/ _jsx(MenuItem, {
999
+ value: category.$id,
1000
+ children: category.name
1001
+ }, category.$id))
1002
+ }) : /*#__PURE__*/ _jsx(TextField, {
1003
+ value: rule.value,
1004
+ onChange: (event)=>updateRule(index, {
1005
+ value: rule.field === 'priceUsd' ? Number(event.target.value) : event.target.value
1006
+ }),
1007
+ size: "small",
1008
+ sx: {
1009
+ flex: 1
1010
+ },
1011
+ placeholder: rule.field === 'type' ? 'physical' : 'Value'
1012
+ }),
1013
+ /*#__PURE__*/ _jsx(Button, {
1014
+ size: "small",
1015
+ color: "error",
1016
+ onClick: ()=>updateRule(index, null),
1017
+ children: '✕'
1018
+ })
1019
+ ]
1020
+ }, index)),
1021
+ /*#__PURE__*/ _jsx(Button, {
1022
+ size: "small",
1023
+ sx: {
1024
+ alignSelf: 'flex-start'
1025
+ },
1026
+ onClick: ()=>{
1027
+ var _ref;
1028
+ var _collectionDraft_rules;
1029
+ return updateRule((_ref = collectionDraft == null ? void 0 : (_collectionDraft_rules = collectionDraft.rules) == null ? void 0 : _collectionDraft_rules.length) != null ? _ref : 0, {});
1030
+ },
1031
+ children: 'Add rule'
1032
+ })
1033
+ ]
1034
+ }),
1035
+ collectionError ? /*#__PURE__*/ _jsx(Alert, {
1036
+ severity: "warning",
1037
+ children: collectionError
1038
+ }) : null,
1039
+ collectionDraft ? /*#__PURE__*/ _jsxs(Stack, {
1040
+ direction: "row",
1041
+ spacing: 0.5,
1042
+ sx: {
1043
+ flexWrap: 'wrap'
1044
+ },
1045
+ children: [
1046
+ /*#__PURE__*/ _jsx(Typography, {
1047
+ variant: "caption",
1048
+ color: "text.secondary",
1049
+ children: `Matches ${countPrefix}${previewMatches.length} products: `
1050
+ }),
1051
+ previewMatches.slice(0, 6).map((product)=>/*#__PURE__*/ _jsx(Chip, {
1052
+ label: product.name,
1053
+ size: "small"
1054
+ }, product.$id)),
1055
+ previewMatches.length > 6 ? /*#__PURE__*/ _jsx(Typography, {
1056
+ variant: "caption",
1057
+ color: "text.secondary",
1058
+ children: `+${previewMatches.length - 6} more`
1059
+ }) : null
1060
+ ]
1061
+ }) : null
1062
+ ]
1063
+ }),
1064
+ /*#__PURE__*/ _jsxs(DialogActions, {
1065
+ children: [
1066
+ /*#__PURE__*/ _jsx(Button, {
1067
+ onClick: ()=>setCollectionDraft(null),
1068
+ children: 'Cancel'
1069
+ }),
1070
+ /*#__PURE__*/ _jsx(Button, {
1071
+ variant: "contained",
1072
+ color: "primary",
1073
+ disabled: !(collectionDraft == null ? void 0 : collectionDraft.name.trim()) || Boolean(collectionError),
1074
+ onClick: handleCollectionSave,
1075
+ children: 'Save'
1076
+ })
1077
+ ]
1078
+ })
1079
+ ]
1080
+ })
1081
+ ]
1082
+ });
1083
+ }
1084
+ CatalogOrganizationCard.displayName = 'CatalogOrganizationCard';
1085
+ export default CatalogOrganizationCard;
1086
+
1087
+ //# sourceMappingURL=catalog-organization-card.component.js.map