@fluid-app/portal-sdk 0.1.230 → 0.1.232

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 (151) hide show
  1. package/dist/{AppDownloadScreen-BmYJ7Zgb.cjs → AppDownloadScreen-B0YwMqYM.cjs} +2 -2
  2. package/dist/{AppDownloadScreen-BmYJ7Zgb.cjs.map → AppDownloadScreen-B0YwMqYM.cjs.map} +1 -1
  3. package/dist/{AppDownloadScreen-zrhWlSE7.mjs → AppDownloadScreen-Dj5ZPsSb.mjs} +2 -2
  4. package/dist/{AppDownloadScreen-zrhWlSE7.mjs.map → AppDownloadScreen-Dj5ZPsSb.mjs.map} +1 -1
  5. package/dist/{AppNavigationContext-C1-hd9Rw.cjs → AppNavigationContext-BDs1cOuG.cjs} +1 -1
  6. package/dist/{AppNavigationContext-C1-hd9Rw.cjs.map → AppNavigationContext-BDs1cOuG.cjs.map} +1 -1
  7. package/dist/{AppNavigationContext-BcZZMtV6.mjs → AppNavigationContext-DNod9mf6.mjs} +1 -1
  8. package/dist/{AppNavigationContext-BcZZMtV6.mjs.map → AppNavigationContext-DNod9mf6.mjs.map} +1 -1
  9. package/dist/{ContactsScreen-BfS33bcq.cjs → ContactsScreen-9cZWC9PP.cjs} +6 -6
  10. package/dist/{ContactsScreen-DHHzJhO4.mjs → ContactsScreen-B4Ue9m5H.mjs} +9 -22
  11. package/dist/ContactsScreen-B4Ue9m5H.mjs.map +1 -0
  12. package/dist/{ContactsScreen-gq1fPZzb.cjs → ContactsScreen-BTQ_qfq3.cjs} +10 -23
  13. package/dist/ContactsScreen-BTQ_qfq3.cjs.map +1 -0
  14. package/dist/{CustomersScreen-D55HjYHC.mjs → CustomersScreen-CX3P2KpF.mjs} +1 -1
  15. package/dist/{CustomersScreen-D55HjYHC.mjs.map → CustomersScreen-CX3P2KpF.mjs.map} +1 -1
  16. package/dist/{CustomersScreen-DW3BuhBs.cjs → CustomersScreen-GROLIynQ.cjs} +1 -1
  17. package/dist/{CustomersScreen-DW3BuhBs.cjs.map → CustomersScreen-GROLIynQ.cjs.map} +1 -1
  18. package/dist/{FluidProvider-Bc56jo27.cjs → FluidProvider-BNL_Apw2.cjs} +27 -7
  19. package/dist/{FluidProvider-Bc56jo27.cjs.map → FluidProvider-BNL_Apw2.cjs.map} +1 -1
  20. package/dist/{FluidProvider-CLpYfVNX.mjs → FluidProvider-Dg-eouRw.mjs} +27 -7
  21. package/dist/FluidProvider-Dg-eouRw.mjs.map +1 -0
  22. package/dist/{InfiniteScrollSentinel-bVdxImf8.mjs → InfiniteScrollSentinel-CQD9JPVe.mjs} +1 -1
  23. package/dist/{InfiniteScrollSentinel-bVdxImf8.mjs.map → InfiniteScrollSentinel-CQD9JPVe.mjs.map} +1 -1
  24. package/dist/{InfiniteScrollSentinel-LcHXpBw-.cjs → InfiniteScrollSentinel-V1ubmA8z.cjs} +1 -1
  25. package/dist/{InfiniteScrollSentinel-LcHXpBw-.cjs.map → InfiniteScrollSentinel-V1ubmA8z.cjs.map} +1 -1
  26. package/dist/{MessagingScreen-araykPtU.cjs → MessagingScreen-BMoCh4MT.cjs} +6 -6
  27. package/dist/{MessagingScreen-BJnHF8Va.cjs → MessagingScreen-CxpLlTW_.cjs} +5 -5
  28. package/dist/{MessagingScreen-BJnHF8Va.cjs.map → MessagingScreen-CxpLlTW_.cjs.map} +1 -1
  29. package/dist/{MessagingScreen-DLmXcdxZ.mjs → MessagingScreen-Q17pdhUz.mjs} +3 -3
  30. package/dist/{MessagingScreen-DLmXcdxZ.mjs.map → MessagingScreen-Q17pdhUz.mjs.map} +1 -1
  31. package/dist/{MySiteScreen-DsR9VEwa.cjs → MySiteScreen-5-eNH2S6.cjs} +3 -3
  32. package/dist/{MySiteScreen-DwgWY0cl.cjs → MySiteScreen-B1yomsp6.cjs} +3 -3
  33. package/dist/{MySiteScreen-DwgWY0cl.cjs.map → MySiteScreen-B1yomsp6.cjs.map} +1 -1
  34. package/dist/{MySiteScreen-Q9xN2oxD.mjs → MySiteScreen-BBT8FN5s.mjs} +3 -3
  35. package/dist/{MySiteScreen-Q9xN2oxD.mjs.map → MySiteScreen-BBT8FN5s.mjs.map} +1 -1
  36. package/dist/OrdersScreen-Co2oatu4.cjs +9 -0
  37. package/dist/{OrdersScreen-YWHy3VBL.mjs → OrdersScreen-DkTGTQJZ.mjs} +5 -5
  38. package/dist/{OrdersScreen-YWHy3VBL.mjs.map → OrdersScreen-DkTGTQJZ.mjs.map} +1 -1
  39. package/dist/{OrdersScreen-BPrt9kNr.cjs → OrdersScreen-e5DdNpD-.cjs} +5 -5
  40. package/dist/{OrdersScreen-BPrt9kNr.cjs.map → OrdersScreen-e5DdNpD-.cjs.map} +1 -1
  41. package/dist/{PortalProductsApiProvider-BeCWFRtF.mjs → PortalProductsApiProvider-BIZg_c4Y.mjs} +2 -2
  42. package/dist/{PortalProductsApiProvider-BeCWFRtF.mjs.map → PortalProductsApiProvider-BIZg_c4Y.mjs.map} +1 -1
  43. package/dist/{PortalProductsApiProvider-Bb5B1Hv5.cjs → PortalProductsApiProvider-DL8nl7To.cjs} +2 -2
  44. package/dist/{PortalProductsApiProvider-Bb5B1Hv5.cjs.map → PortalProductsApiProvider-DL8nl7To.cjs.map} +1 -1
  45. package/dist/{ProfileScreen-KkzdoK5p.cjs → ProfileScreen-BSWw10cc.cjs} +6 -6
  46. package/dist/{ProfileScreen-B55RliPH.mjs → ProfileScreen-CHsIDbg8.mjs} +6 -6
  47. package/dist/{ProfileScreen-B55RliPH.mjs.map → ProfileScreen-CHsIDbg8.mjs.map} +1 -1
  48. package/dist/{ProfileScreen-CgieZEps.cjs → ProfileScreen-CVOS2By3.cjs} +6 -6
  49. package/dist/{ProfileScreen-CgieZEps.cjs.map → ProfileScreen-CVOS2By3.cjs.map} +1 -1
  50. package/dist/{ScreenHeaderContext-4WYXIqQ5.mjs → ScreenHeaderContext-Cemdo7bM.mjs} +1 -1
  51. package/dist/{ScreenHeaderContext-4WYXIqQ5.mjs.map → ScreenHeaderContext-Cemdo7bM.mjs.map} +1 -1
  52. package/dist/{ScreenHeaderContext-PbjwAMeB.cjs → ScreenHeaderContext-oIu5Bvhs.cjs} +1 -1
  53. package/dist/{ScreenHeaderContext-PbjwAMeB.cjs.map → ScreenHeaderContext-oIu5Bvhs.cjs.map} +1 -1
  54. package/dist/{SearchSort-BQ-nf9gJ.mjs → SearchSort-DN0gsmxk.mjs} +1 -1
  55. package/dist/{SearchSort-BQ-nf9gJ.mjs.map → SearchSort-DN0gsmxk.mjs.map} +1 -1
  56. package/dist/{SearchSort-Hwga1dIi.cjs → SearchSort-O89uV2dl.cjs} +1 -1
  57. package/dist/{SearchSort-Hwga1dIi.cjs.map → SearchSort-O89uV2dl.cjs.map} +1 -1
  58. package/dist/{ShareablesScreen-DjRtywMv.mjs → ShareablesScreen-DHKFnIOE.mjs} +1238 -282
  59. package/dist/ShareablesScreen-DHKFnIOE.mjs.map +1 -0
  60. package/dist/{ShareablesScreen-CTIe6EH0.cjs → ShareablesScreen-DQjgnn2x.cjs} +8 -8
  61. package/dist/{ShareablesScreen-o6frhZUM.cjs → ShareablesScreen-DfrTNnRw.cjs} +1238 -282
  62. package/dist/ShareablesScreen-DfrTNnRw.cjs.map +1 -0
  63. package/dist/{ShopScreen-Bgflgt7W.cjs → ShopScreen-CFR2O1jn.cjs} +7 -7
  64. package/dist/{ShopScreen-DEKy0nFN.mjs → ShopScreen-CLN8FFiL.mjs} +7 -7
  65. package/dist/{ShopScreen-DEKy0nFN.mjs.map → ShopScreen-CLN8FFiL.mjs.map} +1 -1
  66. package/dist/{ShopScreen-8VoJvVs7.cjs → ShopScreen-jk3Y3-x8.cjs} +7 -7
  67. package/dist/{ShopScreen-8VoJvVs7.cjs.map → ShopScreen-jk3Y3-x8.cjs.map} +1 -1
  68. package/dist/{SubscriptionsScreen-mUaEWHn5.mjs → SubscriptionsScreen-CVPj6hhP.mjs} +10 -10
  69. package/dist/{SubscriptionsScreen-mUaEWHn5.mjs.map → SubscriptionsScreen-CVPj6hhP.mjs.map} +1 -1
  70. package/dist/{SubscriptionsScreen-CISCXowf.cjs → SubscriptionsScreen-DOf7rlRP.cjs} +6 -6
  71. package/dist/{SubscriptionsScreen-BsOdTfJQ.cjs → SubscriptionsScreen-r2_drNFg.cjs} +11 -11
  72. package/dist/{SubscriptionsScreen-BsOdTfJQ.cjs.map → SubscriptionsScreen-r2_drNFg.cjs.map} +1 -1
  73. package/dist/ToDoWidget-BgyusdPn.cjs +8 -0
  74. package/dist/{ToDoWidget-CaDOZtAB.cjs → ToDoWidget-CQ_zTbhz.cjs} +114 -31
  75. package/dist/ToDoWidget-CQ_zTbhz.cjs.map +1 -0
  76. package/dist/{ToDoWidget-Bv258x8F.mjs → ToDoWidget-DYGt45vL.mjs} +116 -23
  77. package/dist/ToDoWidget-DYGt45vL.mjs.map +1 -0
  78. package/dist/{UpgradeScreen-4Z5_ALSr.cjs → UpgradeScreen-BJbdv9T9.cjs} +1 -1
  79. package/dist/{UpgradeScreen-CGiVn0KG.mjs → UpgradeScreen-DMxxZjj_.mjs} +1 -1
  80. package/dist/{UpgradeScreen-CGiVn0KG.mjs.map → UpgradeScreen-DMxxZjj_.mjs.map} +1 -1
  81. package/dist/{UpgradeScreen-BaclFXEh.cjs → UpgradeScreen-QhhBuHXE.cjs} +1 -1
  82. package/dist/{UpgradeScreen-BaclFXEh.cjs.map → UpgradeScreen-QhhBuHXE.cjs.map} +1 -1
  83. package/dist/{VideoWidget-BntlfHhP.cjs → VideoWidget-Bc6ZAAaA.cjs} +1 -1
  84. package/dist/{VideoWidget-BntlfHhP.cjs.map → VideoWidget-Bc6ZAAaA.cjs.map} +1 -1
  85. package/dist/{VideoWidget-DmHZ05vp.mjs → VideoWidget-lTyeZypJ.mjs} +1 -1
  86. package/dist/{VideoWidget-DmHZ05vp.mjs.map → VideoWidget-lTyeZypJ.mjs.map} +1 -1
  87. package/dist/{dist-FHf4OHgt.cjs → dist-BQZkLGL6.cjs} +1 -1
  88. package/dist/{dist-FHf4OHgt.cjs.map → dist-BQZkLGL6.cjs.map} +1 -1
  89. package/dist/{dist-BQCx-9SK.cjs → dist-DbRTQ2QF.cjs} +1 -1
  90. package/dist/{dist-BQCx-9SK.cjs.map → dist-DbRTQ2QF.cjs.map} +1 -1
  91. package/dist/{dist-q1wrtxfG.mjs → dist-PbA1vxAz.mjs} +1 -1
  92. package/dist/{dist-q1wrtxfG.mjs.map → dist-PbA1vxAz.mjs.map} +1 -1
  93. package/dist/{dist-5XPflEEG.cjs → dist-myuZC8sf.cjs} +2 -2
  94. package/dist/{dist-5XPflEEG.cjs.map → dist-myuZC8sf.cjs.map} +1 -1
  95. package/dist/{dist-CsNsoBdu.mjs → dist-o2cjwzIa.mjs} +2 -2
  96. package/dist/{dist-CsNsoBdu.mjs.map → dist-o2cjwzIa.mjs.map} +1 -1
  97. package/dist/{es-nxOxb57F.cjs → es-UfEBhcZD.cjs} +1 -1
  98. package/dist/{es-nxOxb57F.cjs.map → es-UfEBhcZD.cjs.map} +1 -1
  99. package/dist/{fluid-pay-api-adapter-COBmngde.cjs → fluid-pay-api-adapter-CLP8wfno.cjs} +1 -1
  100. package/dist/{fluid-pay-api-adapter-COBmngde.cjs.map → fluid-pay-api-adapter-CLP8wfno.cjs.map} +1 -1
  101. package/dist/{fluid-pay-api-adapter-Dv2K17WN.mjs → fluid-pay-api-adapter-Dfi0LtxL.mjs} +1 -1
  102. package/dist/{fluid-pay-api-adapter-Dv2K17WN.mjs.map → fluid-pay-api-adapter-Dfi0LtxL.mjs.map} +1 -1
  103. package/dist/{format-Dyb61f6F.cjs → format-CytB2M00.cjs} +1 -1
  104. package/dist/{format-Dyb61f6F.cjs.map → format-CytB2M00.cjs.map} +1 -1
  105. package/dist/index.cjs +49 -49
  106. package/dist/index.d.cts.map +1 -1
  107. package/dist/index.d.mts.map +1 -1
  108. package/dist/index.mjs +48 -48
  109. package/dist/{order-status-badge-CnQE7lFJ.mjs → order-status-badge-CL5XC2va.mjs} +3 -3
  110. package/dist/{order-status-badge-CnQE7lFJ.mjs.map → order-status-badge-CL5XC2va.mjs.map} +1 -1
  111. package/dist/{order-status-badge-NMygmn5d.cjs → order-status-badge-Cqkx76d8.cjs} +3 -3
  112. package/dist/{order-status-badge-NMygmn5d.cjs.map → order-status-badge-Cqkx76d8.cjs.map} +1 -1
  113. package/dist/parse-task-body-BxbA_DC6.cjs +29 -0
  114. package/dist/parse-task-body-BxbA_DC6.cjs.map +1 -0
  115. package/dist/parse-task-body-DEmYvdNM.mjs +24 -0
  116. package/dist/parse-task-body-DEmYvdNM.mjs.map +1 -0
  117. package/dist/{portal_tenant-GpShCvG9.cjs → portal_tenant-CNmiAf_A.cjs} +34 -1
  118. package/dist/portal_tenant-CNmiAf_A.cjs.map +1 -0
  119. package/dist/{portal_tenant-CFngP8OD.mjs → portal_tenant-Q3x7ALaZ.mjs} +23 -2
  120. package/dist/portal_tenant-Q3x7ALaZ.mjs.map +1 -0
  121. package/dist/{portal_tenant_content-WBAKi5Vl.mjs → portal_tenant_content-CEDc7an2.mjs} +2 -2
  122. package/dist/portal_tenant_content-CEDc7an2.mjs.map +1 -0
  123. package/dist/{portal_tenant_content-Bnr0IyhM.cjs → portal_tenant_content-D60b_KWd.cjs} +2 -2
  124. package/dist/portal_tenant_content-D60b_KWd.cjs.map +1 -0
  125. package/dist/{query-keys-CC2PXIfJ.cjs → query-keys-D3lK70Ea.cjs} +1 -1
  126. package/dist/{query-keys-BkMRwfNo.mjs.map → query-keys-D3lK70Ea.cjs.map} +1 -1
  127. package/dist/{query-keys-BkMRwfNo.mjs → query-keys-xJy_fapN.mjs} +1 -1
  128. package/dist/{query-keys-CC2PXIfJ.cjs.map → query-keys-xJy_fapN.mjs.map} +1 -1
  129. package/dist/{sortable.esm-BSpvRpWg.mjs → sortable.esm-C8G00cCP.mjs} +1 -1
  130. package/dist/{sortable.esm-BSpvRpWg.mjs.map → sortable.esm-C8G00cCP.mjs.map} +1 -1
  131. package/dist/{use-account-Ipii17ZX.mjs → use-account-CBMPhhs7.mjs} +2 -2
  132. package/dist/{use-account-Ipii17ZX.mjs.map → use-account-CBMPhhs7.mjs.map} +1 -1
  133. package/dist/{use-account-Bv_VAVxj.cjs → use-account-DcBCP06c.cjs} +2 -2
  134. package/dist/{use-account-Bv_VAVxj.cjs.map → use-account-DcBCP06c.cjs.map} +1 -1
  135. package/dist/{use-store-3holBUj4.mjs → use-store-By_7tzrN.mjs} +1 -1
  136. package/dist/{use-store-3holBUj4.mjs.map → use-store-By_7tzrN.mjs.map} +1 -1
  137. package/dist/{use-store-D2S1FywW.cjs → use-store-lOOUcpRT.cjs} +1 -1
  138. package/dist/{use-store-D2S1FywW.cjs.map → use-store-lOOUcpRT.cjs.map} +1 -1
  139. package/package.json +10 -10
  140. package/dist/ContactsScreen-DHHzJhO4.mjs.map +0 -1
  141. package/dist/ContactsScreen-gq1fPZzb.cjs.map +0 -1
  142. package/dist/FluidProvider-CLpYfVNX.mjs.map +0 -1
  143. package/dist/OrdersScreen-knd6gnEi.cjs +0 -9
  144. package/dist/ShareablesScreen-DjRtywMv.mjs.map +0 -1
  145. package/dist/ShareablesScreen-o6frhZUM.cjs.map +0 -1
  146. package/dist/ToDoWidget-Bv258x8F.mjs.map +0 -1
  147. package/dist/ToDoWidget-CaDOZtAB.cjs.map +0 -1
  148. package/dist/portal_tenant-CFngP8OD.mjs.map +0 -1
  149. package/dist/portal_tenant-GpShCvG9.cjs.map +0 -1
  150. package/dist/portal_tenant_content-Bnr0IyhM.cjs.map +0 -1
  151. package/dist/portal_tenant_content-WBAKi5Vl.mjs.map +0 -1
@@ -1,17 +1,18 @@
1
1
  const require_chunk = require("./chunk-9hOWP6kD.cjs");
2
- const require_portal_tenant_content = require("./portal_tenant_content-Bnr0IyhM.cjs");
2
+ const require_portal_tenant = require("./portal_tenant-CNmiAf_A.cjs");
3
+ const require_portal_tenant_content = require("./portal_tenant_content-D60b_KWd.cjs");
3
4
  const require_PortalTenantClientProvider = require("./PortalTenantClientProvider-BT5Y4YyL.cjs");
4
5
  const require_src = require("./src-DpFIi-nj.cjs");
5
- const require_ScreenHeaderContext = require("./ScreenHeaderContext-PbjwAMeB.cjs");
6
- const require_use_account = require("./use-account-Bv_VAVxj.cjs");
7
- const require_use_store = require("./use-store-D2S1FywW.cjs");
8
- const require_AppNavigationContext = require("./AppNavigationContext-C1-hd9Rw.cjs");
9
- const require_dist$3 = require("./dist-BQCx-9SK.cjs");
10
- const require_es = require("./es-nxOxb57F.cjs");
11
- const require_SearchSort = require("./SearchSort-Hwga1dIi.cjs");
12
- const require_dist$4 = require("./dist-5XPflEEG.cjs");
13
- const require_dist$5 = require("./dist-FHf4OHgt.cjs");
14
- const require_PortalProductsApiProvider = require("./PortalProductsApiProvider-Bb5B1Hv5.cjs");
6
+ const require_ScreenHeaderContext = require("./ScreenHeaderContext-oIu5Bvhs.cjs");
7
+ const require_use_account = require("./use-account-DcBCP06c.cjs");
8
+ const require_use_store = require("./use-store-lOOUcpRT.cjs");
9
+ const require_AppNavigationContext = require("./AppNavigationContext-BDs1cOuG.cjs");
10
+ const require_dist$3 = require("./dist-DbRTQ2QF.cjs");
11
+ const require_es = require("./es-UfEBhcZD.cjs");
12
+ const require_SearchSort = require("./SearchSort-O89uV2dl.cjs");
13
+ const require_dist$4 = require("./dist-myuZC8sf.cjs");
14
+ const require_dist$5 = require("./dist-BQZkLGL6.cjs");
15
+ const require_PortalProductsApiProvider = require("./PortalProductsApiProvider-DL8nl7To.cjs");
15
16
  let react = require("react");
16
17
  react = require_chunk.__toESM(react);
17
18
  let _tanstack_react_query = require("@tanstack/react-query");
@@ -724,7 +725,7 @@ function useInfiniteListSentinel({ hasNextPage, isFetchingNextPage, fetchNextPag
724
725
  }
725
726
  //#endregion
726
727
  //#region ../../shareables/ui/src/components/screens/ProductsScreen.tsx
727
- const PAGE_SIZE$5 = 24;
728
+ const PAGE_SIZE$6 = 24;
728
729
  const SORT_OPTIONS$1 = [
729
730
  {
730
731
  label: "Newest",
@@ -776,11 +777,11 @@ function ProductsScreen({ countryCode, fetchProducts: fetchPortalProducts, onNav
776
777
  queryKey: [
777
778
  "portal-product-catalog",
778
779
  debouncedSearch || "",
779
- PAGE_SIZE$5,
780
+ PAGE_SIZE$6,
780
781
  effectiveSort
781
782
  ],
782
783
  queryFn: async ({ pageParam }) => {
783
- return fetchPortalProducts(debouncedSearch, pageParam, PAGE_SIZE$5, effectiveSort);
784
+ return fetchPortalProducts(debouncedSearch, pageParam, PAGE_SIZE$6, effectiveSort);
784
785
  },
785
786
  getNextPageParam: (lastPage) => lastPage.meta?.pagination?.next_cursor ?? void 0,
786
787
  initialPageParam: void 0,
@@ -796,7 +797,7 @@ function ProductsScreen({ countryCode, fetchProducts: fetchPortalProducts, onNav
796
797
  if (!client) throw new Error("Unreachable: client is null");
797
798
  return (await listProducts(client, {
798
799
  page: pageParam,
799
- per_page: PAGE_SIZE$5,
800
+ per_page: PAGE_SIZE$6,
800
801
  search_query: debouncedSearch || void 0,
801
802
  sorting: {
802
803
  id: "title",
@@ -807,7 +808,7 @@ function ProductsScreen({ countryCode, fetchProducts: fetchPortalProducts, onNav
807
808
  published_stores: ["rep"]
808
809
  })).products;
809
810
  },
810
- getNextPageParam: (lastPage, allPages) => lastPage.length === PAGE_SIZE$5 ? allPages.length + 1 : void 0,
811
+ getNextPageParam: (lastPage, allPages) => lastPage.length === PAGE_SIZE$6 ? allPages.length + 1 : void 0,
811
812
  initialPageParam: 1,
812
813
  enabled: !fetchPortalProducts && !!client
813
814
  });
@@ -1669,7 +1670,7 @@ function OwnerFilterTabs({ value, onValueChange, myLabel = "Mine" }) {
1669
1670
  }
1670
1671
  //#endregion
1671
1672
  //#region ../../shareables/ui/src/components/screens/MediaListingScreen.tsx
1672
- const PAGE_SIZE$4 = 24;
1673
+ const PAGE_SIZE$5 = 24;
1673
1674
  function getMediaKindLabel(kind) {
1674
1675
  switch (kind) {
1675
1676
  case "video": return "Video";
@@ -1769,7 +1770,7 @@ function MediaListingScreen(_props) {
1769
1770
  "filter[ownership]": ownerFilter,
1770
1771
  "filter[content_format]": bffKind,
1771
1772
  "page[cursor]": pageParam,
1772
- "page[limit]": PAGE_SIZE$4,
1773
+ "page[limit]": PAGE_SIZE$5,
1773
1774
  sort: bffSort
1774
1775
  });
1775
1776
  },
@@ -2164,8 +2165,6 @@ zod.z.object({
2164
2165
  timestamp: zod.z.string()
2165
2166
  })
2166
2167
  });
2167
- //#endregion
2168
- //#region ../../file-picker/core/src/schemas/file-picker-config.ts
2169
2168
  const filePickerConfigSchema = zod.z.object({
2170
2169
  accept: zod.z.array(zod.z.string()).optional(),
2171
2170
  maxFiles: zod.z.number().min(1).optional().default(1),
@@ -2178,6 +2177,9 @@ const filePickerConfigSchema = zod.z.object({
2178
2177
  "computer",
2179
2178
  "dam",
2180
2179
  "media",
2180
+ "pages",
2181
+ "products",
2182
+ "enrollment_packs",
2181
2183
  "url",
2182
2184
  "unsplash",
2183
2185
  "google-drive",
@@ -2185,7 +2187,8 @@ const filePickerConfigSchema = zod.z.object({
2185
2187
  "facebook",
2186
2188
  "tiktok",
2187
2189
  "dropbox"
2188
- ])).optional()
2190
+ ])).optional(),
2191
+ unifiedSelection: zod.z.boolean().optional().default(false)
2189
2192
  });
2190
2193
  const DAM_TYPE_FILTER_OPTIONS = [
2191
2194
  {
@@ -2910,7 +2913,7 @@ const FilePickerContext = (0, react.createContext)(null);
2910
2913
  function FilePickerProvider({ children, value }) {
2911
2914
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilePickerContext.Provider, {
2912
2915
  value,
2913
- children
2916
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilePickerSelectionProvider, { children })
2914
2917
  });
2915
2918
  }
2916
2919
  function useFilePickerContext() {
@@ -2918,6 +2921,37 @@ function useFilePickerContext() {
2918
2921
  if (!ctx) throw new Error("useFilePickerContext must be used within a FilePickerProvider");
2919
2922
  return ctx;
2920
2923
  }
2924
+ const FilePickerSelectionReadContext = (0, react.createContext)(null);
2925
+ const FilePickerSelectionWriteContext = (0, react.createContext)(null);
2926
+ function FilePickerSelectionProvider({ children }) {
2927
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilePickerSelectionReadContext.Provider, {
2928
+ value: null,
2929
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilePickerSelectionWriteContext.Provider, {
2930
+ value: null,
2931
+ children
2932
+ })
2933
+ });
2934
+ }
2935
+ function FilePickerSelectionScope({ state, api, children }) {
2936
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilePickerSelectionReadContext.Provider, {
2937
+ value: state,
2938
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilePickerSelectionWriteContext.Provider, {
2939
+ value: api,
2940
+ children
2941
+ })
2942
+ });
2943
+ }
2944
+ /**
2945
+ * Returns the unified selection state when the active picker has unified
2946
+ * selection enabled, otherwise null. Tabs use this as the signal to switch
2947
+ * between unified and per-method behavior.
2948
+ */
2949
+ function useFilePickerSelection() {
2950
+ return {
2951
+ state: (0, react.useContext)(FilePickerSelectionReadContext),
2952
+ api: (0, react.useContext)(FilePickerSelectionWriteContext)
2953
+ };
2954
+ }
2921
2955
  //#endregion
2922
2956
  //#region ../../file-picker/ui/src/utils/brand-icons.tsx
2923
2957
  function GoogleIcon({ className }) {
@@ -4008,6 +4042,9 @@ const FilePickerSidebar = ({ currentStep, activeMethod, onMethodChange, methods
4008
4042
  children: methods.filter((method) => [
4009
4043
  "dam",
4010
4044
  "media",
4045
+ "pages",
4046
+ "products",
4047
+ "enrollment_packs",
4011
4048
  "upload",
4012
4049
  "url",
4013
4050
  "unsplash"
@@ -4447,9 +4484,19 @@ const MediaTab = ({ config, onSelectionChange, onMediaDataChange, selectedMediaI
4447
4484
  upload_status: "ready"
4448
4485
  };
4449
4486
  }, []);
4487
+ const { state: unifiedState, api: unifiedApi } = useFilePickerSelection();
4488
+ const isUnified = unifiedState !== null && unifiedApi !== null;
4450
4489
  const handleMediaClick = (0, react.useCallback)((_e, id, _index) => {
4451
4490
  const mediaId = parseInt(id.replace(/^media_/, ""), 10);
4452
4491
  if (Number.isNaN(mediaId)) return;
4492
+ if (isUnified) {
4493
+ const media = allMediaItems.find((m) => m.id === mediaId);
4494
+ if (!media) return;
4495
+ const result = convertToFilePickerResult(media);
4496
+ if (unifiedApi.isSelected(result.asset_code)) unifiedApi.remove(result.asset_code);
4497
+ else unifiedApi.add(result);
4498
+ return;
4499
+ }
4453
4500
  const isSelected = selectedMediaIds.includes(mediaId);
4454
4501
  let newSelectedIds;
4455
4502
  if (isSelected) newSelectedIds = selectedMediaIds.filter((id) => id !== mediaId);
@@ -4461,6 +4508,8 @@ const MediaTab = ({ config, onSelectionChange, onMediaDataChange, selectedMediaI
4461
4508
  const filePickerResults = newSelectedIds.map((id) => idToMedia.get(id)).filter((m) => m != null).map(convertToFilePickerResult);
4462
4509
  onMediaDataChange?.(filePickerResults);
4463
4510
  }, [
4511
+ isUnified,
4512
+ unifiedApi,
4464
4513
  selectedMediaIds,
4465
4514
  config.maxFiles,
4466
4515
  allMediaItems,
@@ -4469,8 +4518,12 @@ const MediaTab = ({ config, onSelectionChange, onMediaDataChange, selectedMediaI
4469
4518
  onMediaDataChange
4470
4519
  ]);
4471
4520
  react.default.useEffect(() => {
4472
- onSelectionChange?.(selectedMediaIds.length);
4473
- }, [selectedMediaIds.length, onSelectionChange]);
4521
+ if (!isUnified) onSelectionChange?.(selectedMediaIds.length);
4522
+ }, [
4523
+ isUnified,
4524
+ selectedMediaIds.length,
4525
+ onSelectionChange
4526
+ ]);
4474
4527
  const sortedMediaItems = (0, react.useMemo)(() => {
4475
4528
  if (!sortOption || !allMediaItems.length) return allMediaItems;
4476
4529
  const option = SORT_OPTIONS.find((o) => o.id === sortOption);
@@ -4509,9 +4562,17 @@ const MediaTab = ({ config, onSelectionChange, onMediaDataChange, selectedMediaI
4509
4562
  const libraryItems = (0, react.useMemo)(() => {
4510
4563
  return sortedMediaItems.map((media) => {
4511
4564
  const id = `media_${media.id}`;
4512
- const indexInSelection = selectedMediaIds.indexOf(media.id);
4513
- const isSelected = indexInSelection >= 0;
4514
- const selectionIndex = isSelected ? indexInSelection + 1 : 0;
4565
+ let isSelected;
4566
+ let selectionIndex;
4567
+ if (isUnified) {
4568
+ const idx = unifiedState.items.findIndex((r) => r.asset_code === id);
4569
+ isSelected = idx >= 0;
4570
+ selectionIndex = isSelected ? idx + 1 : 0;
4571
+ } else {
4572
+ const indexInSelection = selectedMediaIds.indexOf(media.id);
4573
+ isSelected = indexInSelection >= 0;
4574
+ selectionIndex = isSelected ? indexInSelection + 1 : 0;
4575
+ }
4515
4576
  return {
4516
4577
  id,
4517
4578
  name: media.title ?? "",
@@ -4521,7 +4582,12 @@ const MediaTab = ({ config, onSelectionChange, onMediaDataChange, selectedMediaI
4521
4582
  raw: media
4522
4583
  };
4523
4584
  });
4524
- }, [sortedMediaItems, selectedMediaIds]);
4585
+ }, [
4586
+ sortedMediaItems,
4587
+ selectedMediaIds,
4588
+ isUnified,
4589
+ unifiedState
4590
+ ]);
4525
4591
  const handleMediaDoubleClick = (0, react.useCallback)((_e, _id, index) => {
4526
4592
  const media = sortedMediaItems[index];
4527
4593
  if (media) onPreviewMediaChange?.(media);
@@ -4644,6 +4710,330 @@ const MediaTab = ({ config, onSelectionChange, onMediaDataChange, selectedMediaI
4644
4710
  });
4645
4711
  };
4646
4712
  //#endregion
4713
+ //#region ../../file-picker/ui/src/components/ContentBrowserTab.tsx
4714
+ const PAGE_SIZE$4 = 30;
4715
+ function ContentBrowserTab({ contentKind, assetCodePrefix, labelPlural, source, getId, getLabel, getImageUrl, getSubtitle, fallbackIcon: FallbackIcon, config, selectedIds, onSelectedIdsChange, onSelectedDataChange, onSelectionCountChange, thumbnailSize = 100, viewMode = "grid", showNamesOnMedia = true }) {
4716
+ const supportsSearch = source.supportsSearch !== false;
4717
+ const [searchQuery, setSearchQuery] = (0, react.useState)("");
4718
+ const [debouncedQuery, setDebouncedQuery] = (0, react.useState)("");
4719
+ const [items, setItems] = (0, react.useState)([]);
4720
+ const [cursor, setCursor] = (0, react.useState)(null);
4721
+ const [loadingMore, setLoadingMore] = (0, react.useState)(false);
4722
+ (0, react.useEffect)(() => {
4723
+ const t = setTimeout(() => setDebouncedQuery(searchQuery), 250);
4724
+ return () => clearTimeout(t);
4725
+ }, [searchQuery]);
4726
+ const { data: firstPage, isLoading, error } = (0, _tanstack_react_query.useQuery)({
4727
+ queryKey: (0, react.useMemo)(() => [
4728
+ contentKind,
4729
+ "list",
4730
+ debouncedQuery
4731
+ ], [contentKind, debouncedQuery]),
4732
+ queryFn: () => source.list({
4733
+ search: debouncedQuery,
4734
+ cursor: null,
4735
+ limit: PAGE_SIZE$4
4736
+ }),
4737
+ staleTime: 300 * 1e3
4738
+ });
4739
+ (0, react.useEffect)(() => {
4740
+ if (!firstPage) return;
4741
+ setItems(firstPage.items);
4742
+ setCursor(firstPage.nextCursor);
4743
+ }, [firstPage]);
4744
+ const debouncedQueryRef = (0, react.useRef)(debouncedQuery);
4745
+ (0, react.useEffect)(() => {
4746
+ debouncedQueryRef.current = debouncedQuery;
4747
+ }, [debouncedQuery]);
4748
+ const { toast } = useFilePickerContext();
4749
+ const loadMore = (0, react.useCallback)(async () => {
4750
+ if (!cursor) return;
4751
+ const requestQuery = debouncedQuery;
4752
+ try {
4753
+ setLoadingMore(true);
4754
+ const next = await source.list({
4755
+ search: requestQuery,
4756
+ cursor,
4757
+ limit: PAGE_SIZE$4
4758
+ });
4759
+ if (requestQuery !== debouncedQueryRef.current) return;
4760
+ setItems((prev) => {
4761
+ const ids = new Set(prev.map(getId));
4762
+ const merged = [...prev];
4763
+ for (const it of next.items) if (!ids.has(getId(it))) merged.push(it);
4764
+ return merged;
4765
+ });
4766
+ setCursor(next.nextCursor);
4767
+ } catch (err) {
4768
+ toast.error(`Failed to load more ${labelPlural}`, err);
4769
+ } finally {
4770
+ setLoadingMore(false);
4771
+ }
4772
+ }, [
4773
+ cursor,
4774
+ debouncedQuery,
4775
+ source,
4776
+ getId,
4777
+ labelPlural,
4778
+ toast
4779
+ ]);
4780
+ const { state: unifiedState, api: unifiedApi } = useFilePickerSelection();
4781
+ const isUnified = unifiedState !== null && unifiedApi !== null;
4782
+ const toResult = (0, react.useCallback)((item) => {
4783
+ const id = getId(item);
4784
+ const label = getLabel(item);
4785
+ const image = getImageUrl(item) ?? "";
4786
+ return {
4787
+ asset_id: id,
4788
+ asset_code: `${assetCodePrefix}${id}`,
4789
+ file_path: image,
4790
+ file_url: image,
4791
+ ...image ? { thumbnail_url: image } : {},
4792
+ metadata: {
4793
+ file_name: label,
4794
+ mime_type: ""
4795
+ },
4796
+ upload_status: "ready"
4797
+ };
4798
+ }, [
4799
+ assetCodePrefix,
4800
+ getId,
4801
+ getLabel,
4802
+ getImageUrl
4803
+ ]);
4804
+ const isSelected = (0, react.useCallback)((id) => {
4805
+ if (isUnified) return unifiedState.items.some((r) => r.asset_code === `${assetCodePrefix}${id}`);
4806
+ return selectedIds.includes(id);
4807
+ }, [
4808
+ isUnified,
4809
+ unifiedState,
4810
+ assetCodePrefix,
4811
+ selectedIds
4812
+ ]);
4813
+ const selectionIndex = (0, react.useCallback)((id) => {
4814
+ if (isUnified) {
4815
+ const code = `${assetCodePrefix}${id}`;
4816
+ return unifiedState.items.findIndex((r) => r.asset_code === code) + 1;
4817
+ }
4818
+ return selectedIds.indexOf(id) + 1;
4819
+ }, [
4820
+ isUnified,
4821
+ unifiedState,
4822
+ assetCodePrefix,
4823
+ selectedIds
4824
+ ]);
4825
+ const handleClick = (0, react.useCallback)((_e, gridId) => {
4826
+ const numericId = Number.parseInt(gridId.startsWith(assetCodePrefix) ? gridId.slice(assetCodePrefix.length) : gridId, 10);
4827
+ if (Number.isNaN(numericId)) return;
4828
+ const item = items.find((it) => getId(it) === numericId);
4829
+ if (!item) return;
4830
+ const result = toResult(item);
4831
+ if (isUnified) {
4832
+ if (unifiedApi.isSelected(result.asset_code)) unifiedApi.remove(result.asset_code);
4833
+ else unifiedApi.add(result);
4834
+ return;
4835
+ }
4836
+ const already = selectedIds.includes(numericId);
4837
+ let nextIds;
4838
+ if (already) nextIds = selectedIds.filter((x) => x !== numericId);
4839
+ else if (config.maxFiles === 1) nextIds = [numericId];
4840
+ else if (config.maxFiles !== void 0 && selectedIds.length >= config.maxFiles) return;
4841
+ else nextIds = [...selectedIds, numericId];
4842
+ onSelectedIdsChange(nextIds);
4843
+ const idToItem = new Map(items.map((it) => [getId(it), it]));
4844
+ onSelectedDataChange(nextIds.map((id) => idToItem.get(id)).filter((it) => it != null).map(toResult));
4845
+ }, [
4846
+ items,
4847
+ assetCodePrefix,
4848
+ isUnified,
4849
+ unifiedApi,
4850
+ selectedIds,
4851
+ config.maxFiles,
4852
+ onSelectedIdsChange,
4853
+ onSelectedDataChange,
4854
+ toResult,
4855
+ getId
4856
+ ]);
4857
+ (0, react.useEffect)(() => {
4858
+ if (!isUnified) onSelectionCountChange?.(selectedIds.length);
4859
+ }, [
4860
+ isUnified,
4861
+ selectedIds.length,
4862
+ onSelectionCountChange
4863
+ ]);
4864
+ const renderThumbnail = (0, react.useCallback)((item) => {
4865
+ const url = getImageUrl(item);
4866
+ if (url) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
4867
+ src: url,
4868
+ alt: getLabel(item),
4869
+ width: 200,
4870
+ height: 150,
4871
+ className: "h-full w-full object-cover"
4872
+ });
4873
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4874
+ className: "flex h-full w-full items-center justify-center bg-gray-100",
4875
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FallbackIcon, { className: "h-8 w-8 text-gray-400" })
4876
+ });
4877
+ }, [
4878
+ FallbackIcon,
4879
+ getImageUrl,
4880
+ getLabel
4881
+ ]);
4882
+ const libraryItems = (0, react.useMemo)(() => items.map((item) => {
4883
+ const id = getId(item);
4884
+ const idx = selectionIndex(id);
4885
+ return {
4886
+ id: `${assetCodePrefix}${id}`,
4887
+ name: getLabel(item),
4888
+ subtitle: getSubtitle?.(item) ?? void 0,
4889
+ isSelected: isSelected(id),
4890
+ selectionIndex: idx,
4891
+ raw: item
4892
+ };
4893
+ }), [
4894
+ items,
4895
+ assetCodePrefix,
4896
+ isSelected,
4897
+ selectionIndex,
4898
+ getId,
4899
+ getLabel,
4900
+ getSubtitle
4901
+ ]);
4902
+ if (error) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4903
+ className: "flex flex-col items-center justify-center py-12",
4904
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
4905
+ className: "text-sm text-red-600",
4906
+ children: ["Failed to load ", labelPlural]
4907
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4908
+ className: "mt-1 text-xs text-gray-500",
4909
+ children: "Please try again later"
4910
+ })]
4911
+ });
4912
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4913
+ className: "space-y-4",
4914
+ children: [supportsSearch && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4915
+ className: "relative",
4916
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Input, {
4917
+ type: "text",
4918
+ placeholder: `Search ${labelPlural}...`,
4919
+ value: searchQuery,
4920
+ onChange: (e) => setSearchQuery(e.target.value),
4921
+ className: "h-9"
4922
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4923
+ className: "absolute top-1/2 right-3 -translate-y-1/2",
4924
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.SearchIcon, { className: "h-4 w-4 text-gray-400" })
4925
+ })]
4926
+ }), isLoading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4927
+ className: "flex items-center justify-center py-12",
4928
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4929
+ className: "text-center",
4930
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.LoaderIcon, { className: "mx-auto mb-2 h-8 w-8 animate-spin text-blue-600" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
4931
+ className: "text-sm text-gray-500",
4932
+ children: [
4933
+ "Loading ",
4934
+ labelPlural,
4935
+ "..."
4936
+ ]
4937
+ })]
4938
+ })
4939
+ }) : libraryItems.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4940
+ className: "flex flex-col items-center justify-center py-12",
4941
+ children: [
4942
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4943
+ className: "mb-4 rounded-full bg-gray-100 p-3",
4944
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FallbackIcon, { className: "h-6 w-6 text-gray-400" })
4945
+ }),
4946
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("h3", {
4947
+ className: "mb-1 text-sm font-medium text-gray-900",
4948
+ children: [
4949
+ "No ",
4950
+ labelPlural,
4951
+ " found"
4952
+ ]
4953
+ }),
4954
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4955
+ className: "text-xs text-gray-500",
4956
+ children: debouncedQuery ? "Try adjusting your search terms" : `No ${labelPlural} available`
4957
+ })
4958
+ ]
4959
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4960
+ className: "space-y-4",
4961
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(LibraryAssetGrid, {
4962
+ items: libraryItems,
4963
+ viewMode,
4964
+ thumbnailSize,
4965
+ showNamesOnMedia,
4966
+ renderThumbnail,
4967
+ onClick: handleClick
4968
+ }), cursor && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4969
+ className: "flex justify-center",
4970
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
4971
+ variant: "secondary",
4972
+ size: "sm",
4973
+ onClick: loadMore,
4974
+ disabled: loadingMore,
4975
+ children: loadingMore ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.LoaderIcon, { className: "mr-2 h-3 w-3 animate-spin" }), "Loading..."] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronDownIcon, { className: "mr-2 h-3 w-3" }), "Load more"] })
4976
+ })
4977
+ })]
4978
+ })]
4979
+ });
4980
+ }
4981
+ //#endregion
4982
+ //#region ../../file-picker/ui/src/components/PagesTab.tsx
4983
+ const PagesTab = (props) => {
4984
+ const { shareablesClient } = useFilePickerContext();
4985
+ const source = shareablesClient?.pages;
4986
+ if (!source) return null;
4987
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ContentBrowserTab, {
4988
+ contentKind: "pages",
4989
+ assetCodePrefix: "page_",
4990
+ labelPlural: "pages",
4991
+ source,
4992
+ getId: (p) => p.id,
4993
+ getLabel: (p) => p.title || `Page #${p.id}`,
4994
+ getImageUrl: (p) => p.image_url ?? null,
4995
+ fallbackIcon: lucide_react.FileTextIcon,
4996
+ ...props
4997
+ });
4998
+ };
4999
+ //#endregion
5000
+ //#region ../../file-picker/ui/src/components/ProductsTab.tsx
5001
+ const ProductsTab = (props) => {
5002
+ const { shareablesClient } = useFilePickerContext();
5003
+ const source = shareablesClient?.products;
5004
+ if (!source) return null;
5005
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ContentBrowserTab, {
5006
+ contentKind: "products",
5007
+ assetCodePrefix: "product_",
5008
+ labelPlural: "products",
5009
+ source,
5010
+ getId: (p) => p.id,
5011
+ getLabel: (p) => p.name || `Product #${p.id}`,
5012
+ getImageUrl: (p) => p.image_url ?? null,
5013
+ getSubtitle: (p) => p.price ? `$${p.price}` : void 0,
5014
+ fallbackIcon: lucide_react.PackageIcon,
5015
+ ...props
5016
+ });
5017
+ };
5018
+ //#endregion
5019
+ //#region ../../file-picker/ui/src/components/EnrollmentPacksTab.tsx
5020
+ const EnrollmentPacksTab = (props) => {
5021
+ const { shareablesClient } = useFilePickerContext();
5022
+ const source = shareablesClient?.enrollment_packs;
5023
+ if (!source) return null;
5024
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ContentBrowserTab, {
5025
+ contentKind: "enrollment_packs",
5026
+ assetCodePrefix: "enrollment_pack_",
5027
+ labelPlural: "enrollment packs",
5028
+ source,
5029
+ getId: (p) => p.id,
5030
+ getLabel: (p) => p.title || `Enrollment Pack #${p.id}`,
5031
+ getImageUrl: (p) => p.image_url ?? null,
5032
+ fallbackIcon: lucide_react.GraduationCapIcon,
5033
+ ...props
5034
+ });
5035
+ };
5036
+ //#endregion
4647
5037
  //#region ../../file-picker/ui/src/hooks/use-unsplash-picker.ts
4648
5038
  const useUnsplashPicker = (options) => {
4649
5039
  const { controlledSearchQuery, onControlledSearchQueryChange } = options ?? {};
@@ -6014,7 +6404,7 @@ const ComputerUpload = ({ config, onFilesSelected, enableShareableOption = false
6014
6404
  };
6015
6405
  //#endregion
6016
6406
  //#region ../../file-picker/ui/src/components/FilePickerContent.tsx
6017
- const FilePickerContent = ({ activeMethod, config, damTypeFilter, sortOption, onFilesSelected, onSingleFileSelected, enableShareableOption, shareableEnabled, onShareableChange, damLibraryRef, onDamConfirmAndMaybeCreate, selectedMediaIds, onMediaIdsChange, onMediaSelectionChange, onMediaDataChange, onDamSelectionChange, onDamSearchingChange, skipCropper = false, damSearchQuery = "", onDamSearchChange, mediaSearchQuery, onMediaSearchChange, unsplashSearchQuery, onUnsplashSearchChange, onUnsplashSearchingChange, onUnsplashUploadingChange, thumbnailSize = 100, viewMode = "grid", showNamesOnMedia = true, onDamFoldersChange, previewContainer, previewMedia, onPreviewMediaChange, previewAsset, onPreviewAssetChange, uploadSelectionCount }) => {
6407
+ const FilePickerContent = ({ activeMethod, config, damTypeFilter, sortOption, onFilesSelected, onSingleFileSelected, enableShareableOption, shareableEnabled, onShareableChange, damLibraryRef, onDamConfirmAndMaybeCreate, selectedMediaIds, onMediaIdsChange, onMediaSelectionChange, onMediaDataChange, selectedPageIds, onPageIdsChange, onPageSelectionChange, onPageDataChange, selectedProductIds, onProductIdsChange, onProductSelectionChange, onProductDataChange, selectedEnrollmentPackIds, onEnrollmentPackIdsChange, onEnrollmentPackSelectionChange, onEnrollmentPackDataChange, onDamSelectionChange, onDamSearchingChange, skipCropper = false, damSearchQuery = "", onDamSearchChange, mediaSearchQuery, onMediaSearchChange, unsplashSearchQuery, onUnsplashSearchChange, onUnsplashSearchingChange, onUnsplashUploadingChange, thumbnailSize = 100, viewMode = "grid", showNamesOnMedia = true, onDamFoldersChange, previewContainer, previewMedia, onPreviewMediaChange, previewAsset, onPreviewAssetChange, uploadSelectionCount }) => {
6018
6408
  const damConfig = react.default.useMemo(() => ({
6019
6409
  ...config,
6020
6410
  fileTypeFilter: damTypeFilter ? [damTypeFilter] : config.fileTypeFilter
@@ -6078,6 +6468,36 @@ const FilePickerContent = ({ activeMethod, config, damTypeFilter, sortOption, on
6078
6468
  previewMedia,
6079
6469
  onPreviewMediaChange
6080
6470
  }),
6471
+ activeMethod === "pages" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PagesTab, {
6472
+ config,
6473
+ selectedIds: selectedPageIds ?? [],
6474
+ onSelectedIdsChange: onPageIdsChange ?? (() => {}),
6475
+ onSelectedDataChange: onPageDataChange ?? (() => {}),
6476
+ onSelectionCountChange: onPageSelectionChange,
6477
+ thumbnailSize,
6478
+ viewMode,
6479
+ showNamesOnMedia
6480
+ }),
6481
+ activeMethod === "products" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProductsTab, {
6482
+ config,
6483
+ selectedIds: selectedProductIds ?? [],
6484
+ onSelectedIdsChange: onProductIdsChange ?? (() => {}),
6485
+ onSelectedDataChange: onProductDataChange ?? (() => {}),
6486
+ onSelectionCountChange: onProductSelectionChange,
6487
+ thumbnailSize,
6488
+ viewMode,
6489
+ showNamesOnMedia
6490
+ }),
6491
+ activeMethod === "enrollment_packs" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EnrollmentPacksTab, {
6492
+ config,
6493
+ selectedIds: selectedEnrollmentPackIds ?? [],
6494
+ onSelectedIdsChange: onEnrollmentPackIdsChange ?? (() => {}),
6495
+ onSelectedDataChange: onEnrollmentPackDataChange ?? (() => {}),
6496
+ onSelectionCountChange: onEnrollmentPackSelectionChange,
6497
+ thumbnailSize,
6498
+ viewMode,
6499
+ showNamesOnMedia
6500
+ }),
6081
6501
  activeMethod === "unsplash" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnsplashPicker, {
6082
6502
  config,
6083
6503
  onFileSelected: onSingleFileSelected,
@@ -6530,6 +6950,16 @@ const FilePicker = ({ config: configInput = {}, onFilesSelected, onClose, open,
6530
6950
  const [damFolders, setDamFolders] = (0, react.useState)([]);
6531
6951
  const [selectedMediaIds, setSelectedMediaIds] = (0, react.useState)([]);
6532
6952
  const [selectedMediaData, setSelectedMediaData] = (0, react.useState)([]);
6953
+ const [selectedPageIds, setSelectedPageIds] = (0, react.useState)([]);
6954
+ const [selectedPageData, setSelectedPageData] = (0, react.useState)([]);
6955
+ const [pageSelectionCount, setPageSelectionCount] = (0, react.useState)(0);
6956
+ const [selectedProductIds, setSelectedProductIds] = (0, react.useState)([]);
6957
+ const [selectedProductData, setSelectedProductData] = (0, react.useState)([]);
6958
+ const [productSelectionCount, setProductSelectionCount] = (0, react.useState)(0);
6959
+ const [selectedEnrollmentPackIds, setSelectedEnrollmentPackIds] = (0, react.useState)([]);
6960
+ const [selectedEnrollmentPackData, setSelectedEnrollmentPackData] = (0, react.useState)([]);
6961
+ const [enrollmentPackSelectionCount, setEnrollmentPackSelectionCount] = (0, react.useState)(0);
6962
+ const [unifiedItems, setUnifiedItems] = (0, react.useState)([]);
6533
6963
  const damLibraryRef = (0, react.useRef)(null);
6534
6964
  const [previewContainer, setPreviewContainer] = (0, react.useState)(null);
6535
6965
  const [previewAsset, setPreviewAsset] = (0, react.useState)(null);
@@ -6550,26 +6980,47 @@ const FilePicker = ({ config: configInput = {}, onFilesSelected, onClose, open,
6550
6980
  setMediaSelectionCount(0);
6551
6981
  setSelectedMediaIds([]);
6552
6982
  setSelectedMediaData([]);
6983
+ setSelectedPageIds([]);
6984
+ setSelectedPageData([]);
6985
+ setPageSelectionCount(0);
6986
+ setSelectedProductIds([]);
6987
+ setSelectedProductData([]);
6988
+ setProductSelectionCount(0);
6989
+ setSelectedEnrollmentPackIds([]);
6990
+ setSelectedEnrollmentPackData([]);
6991
+ setEnrollmentPackSelectionCount(0);
6992
+ setUnifiedItems([]);
6553
6993
  setDamFilters(defaultFilters);
6554
6994
  setSortOption(void 0);
6555
6995
  damLibraryRef.current?.clearSelection?.();
6556
6996
  setPreviewAsset(null);
6557
6997
  }, [defaultTab]);
6558
6998
  const handleMethodChange = (0, react.useCallback)((newMethod) => {
6559
- setSelectedResults([]);
6560
- setDamSelectionCount(0);
6561
- setDamSelectedFiles([]);
6562
- setDamVariantCounts({});
6563
- setDamSearchQuery("");
6564
- setUnsplashSearchQuery("");
6565
- setUnsplashSearching(false);
6566
- setIsUnsplashUploading(false);
6567
- setMediaSelectionCount(0);
6568
- setSelectedMediaIds([]);
6569
- setSelectedMediaData([]);
6570
- damLibraryRef.current?.clearSelection?.();
6999
+ if (!config.unifiedSelection) {
7000
+ setSelectedResults([]);
7001
+ setDamSelectionCount(0);
7002
+ setDamSelectedFiles([]);
7003
+ setDamVariantCounts({});
7004
+ setDamSearchQuery("");
7005
+ setUnsplashSearchQuery("");
7006
+ setUnsplashSearching(false);
7007
+ setIsUnsplashUploading(false);
7008
+ setMediaSelectionCount(0);
7009
+ setSelectedMediaIds([]);
7010
+ setSelectedMediaData([]);
7011
+ setSelectedPageIds([]);
7012
+ setSelectedPageData([]);
7013
+ setPageSelectionCount(0);
7014
+ setSelectedProductIds([]);
7015
+ setSelectedProductData([]);
7016
+ setProductSelectionCount(0);
7017
+ setSelectedEnrollmentPackIds([]);
7018
+ setSelectedEnrollmentPackData([]);
7019
+ setEnrollmentPackSelectionCount(0);
7020
+ damLibraryRef.current?.clearSelection?.();
7021
+ }
6571
7022
  setActiveMethod(newMethod);
6572
- }, []);
7023
+ }, [config.unifiedSelection]);
6573
7024
  const handleFilesSelected = (0, react.useCallback)((results) => {
6574
7025
  const validResults = results.filter((result) => result.upload_status !== "error");
6575
7026
  if (config.maxFiles === 1) setSelectedResults(validResults.slice(0, 1));
@@ -6612,8 +7063,9 @@ const FilePicker = ({ config: configInput = {}, onFilesSelected, onClose, open,
6612
7063
  onFilesSelected(results);
6613
7064
  onClose?.();
6614
7065
  }, [onFilesSelected, onClose]);
7066
+ const { shareablesClient, toast } = useFilePickerContext();
6615
7067
  const methods = (0, react.useMemo)(() => {
6616
- const allMethods = [
7068
+ const filteredBySource = [
6617
7069
  {
6618
7070
  id: "dam",
6619
7071
  label: "Library",
@@ -6626,6 +7078,24 @@ const FilePicker = ({ config: configInput = {}, onFilesSelected, onClose, open,
6626
7078
  icon: lucide_react.ImagesIcon,
6627
7079
  description: "Choose from existing media"
6628
7080
  }] : [],
7081
+ {
7082
+ id: "pages",
7083
+ label: "Pages",
7084
+ icon: lucide_react.FileTextIcon,
7085
+ description: "Choose from existing pages"
7086
+ },
7087
+ {
7088
+ id: "products",
7089
+ label: "Products",
7090
+ icon: lucide_react.PackageIcon,
7091
+ description: "Choose from existing products"
7092
+ },
7093
+ {
7094
+ id: "enrollment_packs",
7095
+ label: "Enrollment Packs",
7096
+ icon: lucide_react.GraduationCapIcon,
7097
+ description: "Choose from existing enrollment packs"
7098
+ },
6629
7099
  {
6630
7100
  id: "upload",
6631
7101
  label: "Local Files",
@@ -6674,11 +7144,275 @@ const FilePicker = ({ config: configInput = {}, onFilesSelected, onClose, open,
6674
7144
  icon: DropboxIcon,
6675
7145
  description: "Import from Dropbox"
6676
7146
  }
6677
- ];
6678
- if (config.allowedMethods && config.allowedMethods.length > 0) return allMethods.filter((method) => config.allowedMethods.includes(method.id));
6679
- return allMethods;
6680
- }, [showMediaTab, config.allowedMethods]);
7147
+ ].filter((m) => {
7148
+ if (m.id === "pages") return shareablesClient?.pages != null;
7149
+ if (m.id === "products") return shareablesClient?.products != null;
7150
+ if (m.id === "enrollment_packs") return shareablesClient?.enrollment_packs != null;
7151
+ return true;
7152
+ });
7153
+ if (config.allowedMethods && config.allowedMethods.length > 0) return filteredBySource.filter((method) => config.allowedMethods.includes(method.id));
7154
+ return filteredBySource;
7155
+ }, [
7156
+ showMediaTab,
7157
+ config.allowedMethods,
7158
+ shareablesClient
7159
+ ]);
6681
7160
  const showPreview = previewAsset !== null;
7161
+ const unifiedSelectionState = (0, react.useMemo)(() => ({ items: unifiedItems }), [unifiedItems]);
7162
+ const unifiedItemsRef = (0, react.useRef)(unifiedItems);
7163
+ (0, react.useEffect)(() => {
7164
+ unifiedItemsRef.current = unifiedItems;
7165
+ }, [unifiedItems]);
7166
+ const unifiedApi = (0, react.useMemo)(() => ({
7167
+ add: (item) => {
7168
+ const current = unifiedItemsRef.current;
7169
+ if (current.some((r) => r.asset_code === item.asset_code)) return;
7170
+ if (config.maxFiles && current.length >= config.maxFiles) {
7171
+ toast.error(`You can select up to ${config.maxFiles} items at a time.`);
7172
+ return;
7173
+ }
7174
+ setUnifiedItems((prev) => {
7175
+ if (prev.some((r) => r.asset_code === item.asset_code)) return prev;
7176
+ if (config.maxFiles && prev.length >= config.maxFiles) return prev;
7177
+ return [...prev, item];
7178
+ });
7179
+ },
7180
+ remove: (assetCode) => {
7181
+ setUnifiedItems((prev) => prev.filter((r) => r.asset_code !== assetCode));
7182
+ },
7183
+ clear: () => setUnifiedItems([]),
7184
+ isSelected: (assetCode) => unifiedItemsRef.current.some((r) => r.asset_code === assetCode),
7185
+ selectionIndex: (assetCode) => unifiedItemsRef.current.findIndex((r) => r.asset_code === assetCode) + 1
7186
+ }), [config.maxFiles, toast]);
7187
+ const body = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7188
+ className: "flex flex-1 overflow-y-auto",
7189
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilePickerSidebar, {
7190
+ currentStep: "select",
7191
+ activeMethod,
7192
+ onMethodChange: handleMethodChange,
7193
+ methods
7194
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7195
+ className: "flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden",
7196
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilePickerHeader, {
7197
+ currentStep: "select",
7198
+ activeMethod,
7199
+ methods,
7200
+ onClose: () => {
7201
+ resetPicker();
7202
+ onClose?.();
7203
+ },
7204
+ damSearchQuery: activeMethod === "dam" ? damSearchQuery : mediaSearchQuery,
7205
+ onDamSearchChange: activeMethod === "dam" ? setDamSearchQuery : setMediaSearchQuery,
7206
+ damSearching,
7207
+ thumbnailSize,
7208
+ onThumbnailSizeChange: handleThumbnailSizeChange,
7209
+ viewMode,
7210
+ onViewModeChange: handleViewModeChange,
7211
+ showNamesOnMedia,
7212
+ onShowNamesOnMediaChange: setShowNamesOnMedia,
7213
+ hasSelectedFiles: damSelectionCount > 0,
7214
+ damFolders,
7215
+ onAddToNewFolder: () => damLibraryRef.current?.openAddFolderModal(),
7216
+ onAddToExistingFolder: (folderPath) => damLibraryRef.current?.addToExistingFolder?.(folderPath),
7217
+ filters: damFilters,
7218
+ onFiltersChange: setDamFilters,
7219
+ onFiltersClear: () => setDamFilters(defaultFilters),
7220
+ sortOption,
7221
+ onSortChange: setSortOption,
7222
+ unsplashSearchQuery,
7223
+ onUnsplashSearchChange: setUnsplashSearchQuery,
7224
+ unsplashSearching,
7225
+ isUnsplashUploading
7226
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7227
+ className: "flex min-h-0 min-w-0 flex-1 overflow-hidden",
7228
+ children: [
7229
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7230
+ className: "min-h-0 min-w-0 flex-1 overflow-y-auto",
7231
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilePickerContent, {
7232
+ activeMethod,
7233
+ config,
7234
+ damTypeFilter: damFilters.type ? damFilters.type : void 0,
7235
+ sortOption,
7236
+ onFilesSelected: handleFilesSelected,
7237
+ onUploadConfirmAndMaybeCreate: handleUploadConfirm,
7238
+ onSingleFileSelected: handleSingleFileSelected,
7239
+ damLibraryRef,
7240
+ onDamConfirmAndMaybeCreate: handleDamConfirm,
7241
+ selectedMediaIds,
7242
+ onMediaIdsChange: setSelectedMediaIds,
7243
+ onMediaSelectionChange: handleMediaSelectionChange,
7244
+ onMediaDataChange: handleMediaDataChange,
7245
+ selectedPageIds,
7246
+ onPageIdsChange: setSelectedPageIds,
7247
+ onPageSelectionChange: setPageSelectionCount,
7248
+ onPageDataChange: setSelectedPageData,
7249
+ selectedProductIds,
7250
+ onProductIdsChange: setSelectedProductIds,
7251
+ onProductSelectionChange: setProductSelectionCount,
7252
+ onProductDataChange: setSelectedProductData,
7253
+ selectedEnrollmentPackIds,
7254
+ onEnrollmentPackIdsChange: setSelectedEnrollmentPackIds,
7255
+ onEnrollmentPackSelectionChange: setEnrollmentPackSelectionCount,
7256
+ onEnrollmentPackDataChange: setSelectedEnrollmentPackData,
7257
+ onDamSelectionChange: handleDamSelectionChange,
7258
+ onDamSearchingChange: setDamSearching,
7259
+ skipCropper,
7260
+ damSearchQuery,
7261
+ onDamSearchChange: setDamSearchQuery,
7262
+ mediaSearchQuery,
7263
+ onMediaSearchChange: setMediaSearchQuery,
7264
+ unsplashSearchQuery,
7265
+ onUnsplashSearchChange: setUnsplashSearchQuery,
7266
+ onUnsplashSearchingChange: setUnsplashSearching,
7267
+ onUnsplashUploadingChange: setIsUnsplashUploading,
7268
+ thumbnailSize,
7269
+ viewMode,
7270
+ showNamesOnMedia,
7271
+ onDamFoldersChange: setDamFolders,
7272
+ previewContainer,
7273
+ previewAsset,
7274
+ onPreviewAssetChange: setPreviewAsset,
7275
+ uploadSelectionCount: activeMethod === "upload" || activeMethod === "url" || activeMethod === "unsplash" ? selectedResults.length : void 0
7276
+ })
7277
+ }),
7278
+ activeMethod === "dam" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionPanel, {
7279
+ selectedFiles: damSelectedFiles,
7280
+ onRemoveFile: (assetCode) => {
7281
+ damLibraryRef.current?.deselectAssetByCode?.(assetCode);
7282
+ },
7283
+ onClear: () => {
7284
+ damLibraryRef.current?.clearSelection();
7285
+ setDamSelectionCount(0);
7286
+ setDamSelectedFiles([]);
7287
+ setDamVariantCounts({});
7288
+ },
7289
+ onConfirm: () => {
7290
+ damLibraryRef.current?.confirmAndClose();
7291
+ },
7292
+ isVisible: damSelectionCount > 0,
7293
+ hasVariants: (assetCode) => (damVariantCounts[assetCode] ?? 0) > 1,
7294
+ getAssetWithVariants: (assetCode) => damLibraryRef.current?.getAssetWithVariants?.(assetCode) ?? null,
7295
+ onVariantChange: (assetCode, variantId) => {
7296
+ damLibraryRef.current?.setVariantForAsset?.(assetCode, variantId);
7297
+ }
7298
+ }),
7299
+ !config.unifiedSelection && activeMethod === "media" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionPanel, {
7300
+ selectedFiles: selectedMediaData,
7301
+ onRemoveFile: (assetCode) => {
7302
+ const id = parseInt(assetCode.replace(/^media_/, ""), 10);
7303
+ if (!Number.isNaN(id)) {
7304
+ setSelectedMediaIds((prev) => prev.filter((mediaId) => mediaId !== id));
7305
+ setSelectedMediaData((prev) => prev.filter((r) => r.asset_code !== assetCode));
7306
+ }
7307
+ },
7308
+ onClear: () => {
7309
+ setSelectedMediaIds([]);
7310
+ setSelectedMediaData([]);
7311
+ setMediaSelectionCount(0);
7312
+ },
7313
+ onConfirm: () => {
7314
+ onFilesSelected(selectedMediaData);
7315
+ onClose?.();
7316
+ },
7317
+ isVisible: mediaSelectionCount > 0,
7318
+ hasVariants: () => false
7319
+ }),
7320
+ !config.unifiedSelection && activeMethod === "pages" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionPanel, {
7321
+ selectedFiles: selectedPageData,
7322
+ onRemoveFile: (assetCode) => {
7323
+ const id = parseInt(assetCode.replace(/^page_/, ""), 10);
7324
+ if (!Number.isNaN(id)) {
7325
+ setSelectedPageIds((prev) => prev.filter((pageId) => pageId !== id));
7326
+ setSelectedPageData((prev) => prev.filter((r) => r.asset_code !== assetCode));
7327
+ }
7328
+ },
7329
+ onClear: () => {
7330
+ setSelectedPageIds([]);
7331
+ setSelectedPageData([]);
7332
+ setPageSelectionCount(0);
7333
+ },
7334
+ onConfirm: () => {
7335
+ onFilesSelected(selectedPageData);
7336
+ onClose?.();
7337
+ },
7338
+ isVisible: pageSelectionCount > 0,
7339
+ hasVariants: () => false
7340
+ }),
7341
+ !config.unifiedSelection && activeMethod === "products" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionPanel, {
7342
+ selectedFiles: selectedProductData,
7343
+ onRemoveFile: (assetCode) => {
7344
+ const id = parseInt(assetCode.replace(/^product_/, ""), 10);
7345
+ if (!Number.isNaN(id)) {
7346
+ setSelectedProductIds((prev) => prev.filter((productId) => productId !== id));
7347
+ setSelectedProductData((prev) => prev.filter((r) => r.asset_code !== assetCode));
7348
+ }
7349
+ },
7350
+ onClear: () => {
7351
+ setSelectedProductIds([]);
7352
+ setSelectedProductData([]);
7353
+ setProductSelectionCount(0);
7354
+ },
7355
+ onConfirm: () => {
7356
+ onFilesSelected(selectedProductData);
7357
+ onClose?.();
7358
+ },
7359
+ isVisible: productSelectionCount > 0,
7360
+ hasVariants: () => false
7361
+ }),
7362
+ !config.unifiedSelection && activeMethod === "enrollment_packs" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionPanel, {
7363
+ selectedFiles: selectedEnrollmentPackData,
7364
+ onRemoveFile: (assetCode) => {
7365
+ const id = parseInt(assetCode.replace(/^enrollment_pack_/, ""), 10);
7366
+ if (!Number.isNaN(id)) {
7367
+ setSelectedEnrollmentPackIds((prev) => prev.filter((packId) => packId !== id));
7368
+ setSelectedEnrollmentPackData((prev) => prev.filter((r) => r.asset_code !== assetCode));
7369
+ }
7370
+ },
7371
+ onClear: () => {
7372
+ setSelectedEnrollmentPackIds([]);
7373
+ setSelectedEnrollmentPackData([]);
7374
+ setEnrollmentPackSelectionCount(0);
7375
+ },
7376
+ onConfirm: () => {
7377
+ onFilesSelected(selectedEnrollmentPackData);
7378
+ onClose?.();
7379
+ },
7380
+ isVisible: enrollmentPackSelectionCount > 0,
7381
+ hasVariants: () => false
7382
+ }),
7383
+ !config.unifiedSelection && (activeMethod === "upload" || activeMethod === "url" || activeMethod === "unsplash") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionPanel, {
7384
+ selectedFiles: selectedResults,
7385
+ onRemoveFile: (assetCode) => {
7386
+ setSelectedResults((prev) => prev.filter((r) => r.asset_code !== assetCode));
7387
+ },
7388
+ onClear: () => {
7389
+ setSelectedResults([]);
7390
+ },
7391
+ onConfirm: () => {
7392
+ handleUploadConfirm(selectedResults);
7393
+ },
7394
+ isVisible: selectedResults.length > 0,
7395
+ hasVariants: () => false
7396
+ }),
7397
+ config.unifiedSelection && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionPanel, {
7398
+ selectedFiles: unifiedItems,
7399
+ onRemoveFile: (assetCode) => {
7400
+ setUnifiedItems((prev) => prev.filter((r) => r.asset_code !== assetCode));
7401
+ },
7402
+ onClear: () => {
7403
+ setUnifiedItems([]);
7404
+ },
7405
+ onConfirm: () => {
7406
+ onFilesSelected(unifiedItems);
7407
+ onClose?.();
7408
+ },
7409
+ isVisible: unifiedItems.length > 0,
7410
+ hasVariants: () => false
7411
+ })
7412
+ ]
7413
+ })]
7414
+ })]
7415
+ });
6682
7416
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [typeof document !== "undefined" && (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6683
7417
  ref: setPreviewContainer,
6684
7418
  className: "fixed inset-0",
@@ -6700,145 +7434,11 @@ const FilePicker = ({ config: configInput = {}, onFilesSelected, onClose, open,
6700
7434
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DialogTitle, {
6701
7435
  className: "sr-only",
6702
7436
  children: "File Picker"
6703
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6704
- className: "flex flex-1 overflow-y-auto",
6705
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilePickerSidebar, {
6706
- currentStep: "select",
6707
- activeMethod,
6708
- onMethodChange: handleMethodChange,
6709
- methods
6710
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6711
- className: "flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden",
6712
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilePickerHeader, {
6713
- currentStep: "select",
6714
- activeMethod,
6715
- methods,
6716
- onClose: () => {
6717
- resetPicker();
6718
- onClose?.();
6719
- },
6720
- damSearchQuery: activeMethod === "dam" ? damSearchQuery : mediaSearchQuery,
6721
- onDamSearchChange: activeMethod === "dam" ? setDamSearchQuery : setMediaSearchQuery,
6722
- damSearching,
6723
- thumbnailSize,
6724
- onThumbnailSizeChange: handleThumbnailSizeChange,
6725
- viewMode,
6726
- onViewModeChange: handleViewModeChange,
6727
- showNamesOnMedia,
6728
- onShowNamesOnMediaChange: setShowNamesOnMedia,
6729
- hasSelectedFiles: damSelectionCount > 0,
6730
- damFolders,
6731
- onAddToNewFolder: () => damLibraryRef.current?.openAddFolderModal(),
6732
- onAddToExistingFolder: (folderPath) => damLibraryRef.current?.addToExistingFolder?.(folderPath),
6733
- filters: damFilters,
6734
- onFiltersChange: setDamFilters,
6735
- onFiltersClear: () => setDamFilters(defaultFilters),
6736
- sortOption,
6737
- onSortChange: setSortOption,
6738
- unsplashSearchQuery,
6739
- onUnsplashSearchChange: setUnsplashSearchQuery,
6740
- unsplashSearching,
6741
- isUnsplashUploading
6742
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6743
- className: "flex min-h-0 min-w-0 flex-1 overflow-hidden",
6744
- children: [
6745
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6746
- className: "min-h-0 min-w-0 flex-1 overflow-y-auto",
6747
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilePickerContent, {
6748
- activeMethod,
6749
- config,
6750
- damTypeFilter: damFilters.type ? damFilters.type : void 0,
6751
- sortOption,
6752
- onFilesSelected: handleFilesSelected,
6753
- onUploadConfirmAndMaybeCreate: handleUploadConfirm,
6754
- onSingleFileSelected: handleSingleFileSelected,
6755
- damLibraryRef,
6756
- onDamConfirmAndMaybeCreate: handleDamConfirm,
6757
- selectedMediaIds,
6758
- onMediaIdsChange: setSelectedMediaIds,
6759
- onMediaSelectionChange: handleMediaSelectionChange,
6760
- onMediaDataChange: handleMediaDataChange,
6761
- onDamSelectionChange: handleDamSelectionChange,
6762
- onDamSearchingChange: setDamSearching,
6763
- skipCropper,
6764
- damSearchQuery,
6765
- onDamSearchChange: setDamSearchQuery,
6766
- mediaSearchQuery,
6767
- onMediaSearchChange: setMediaSearchQuery,
6768
- unsplashSearchQuery,
6769
- onUnsplashSearchChange: setUnsplashSearchQuery,
6770
- onUnsplashSearchingChange: setUnsplashSearching,
6771
- onUnsplashUploadingChange: setIsUnsplashUploading,
6772
- thumbnailSize,
6773
- viewMode,
6774
- showNamesOnMedia,
6775
- onDamFoldersChange: setDamFolders,
6776
- previewContainer,
6777
- previewAsset,
6778
- onPreviewAssetChange: setPreviewAsset,
6779
- uploadSelectionCount: activeMethod === "upload" || activeMethod === "url" || activeMethod === "unsplash" ? selectedResults.length : void 0
6780
- })
6781
- }),
6782
- activeMethod === "dam" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionPanel, {
6783
- selectedFiles: damSelectedFiles,
6784
- onRemoveFile: (assetCode) => {
6785
- damLibraryRef.current?.deselectAssetByCode?.(assetCode);
6786
- },
6787
- onClear: () => {
6788
- damLibraryRef.current?.clearSelection();
6789
- setDamSelectionCount(0);
6790
- setDamSelectedFiles([]);
6791
- setDamVariantCounts({});
6792
- },
6793
- onConfirm: () => {
6794
- damLibraryRef.current?.confirmAndClose();
6795
- },
6796
- isVisible: damSelectionCount > 0,
6797
- hasVariants: (assetCode) => (damVariantCounts[assetCode] ?? 0) > 1,
6798
- getAssetWithVariants: (assetCode) => damLibraryRef.current?.getAssetWithVariants?.(assetCode) ?? null,
6799
- onVariantChange: (assetCode, variantId) => {
6800
- damLibraryRef.current?.setVariantForAsset?.(assetCode, variantId);
6801
- }
6802
- }),
6803
- activeMethod === "media" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionPanel, {
6804
- selectedFiles: selectedMediaData,
6805
- onRemoveFile: (assetCode) => {
6806
- const id = parseInt(assetCode.replace(/^media_/, ""), 10);
6807
- if (!Number.isNaN(id)) {
6808
- setSelectedMediaIds((prev) => prev.filter((mediaId) => mediaId !== id));
6809
- setSelectedMediaData((prev) => prev.filter((r) => r.asset_code !== assetCode));
6810
- }
6811
- },
6812
- onClear: () => {
6813
- setSelectedMediaIds([]);
6814
- setSelectedMediaData([]);
6815
- setMediaSelectionCount(0);
6816
- },
6817
- onConfirm: () => {
6818
- onFilesSelected(selectedMediaData);
6819
- onClose?.();
6820
- },
6821
- isVisible: mediaSelectionCount > 0,
6822
- hasVariants: () => false
6823
- }),
6824
- (activeMethod === "upload" || activeMethod === "url" || activeMethod === "unsplash") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionPanel, {
6825
- selectedFiles: selectedResults,
6826
- onRemoveFile: (assetCode) => {
6827
- setSelectedResults((prev) => prev.filter((r) => r.asset_code !== assetCode));
6828
- },
6829
- onClear: () => {
6830
- setSelectedResults([]);
6831
- },
6832
- onConfirm: () => {
6833
- handleUploadConfirm(selectedResults);
6834
- },
6835
- isVisible: selectedResults.length > 0,
6836
- hasVariants: () => false
6837
- })
6838
- ]
6839
- })]
6840
- })]
6841
- })]
7437
+ }), config.unifiedSelection ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilePickerSelectionScope, {
7438
+ state: unifiedSelectionState,
7439
+ api: unifiedApi,
7440
+ children: body
7441
+ }) : body]
6842
7442
  })
6843
7443
  })] });
6844
7444
  };
@@ -9674,13 +10274,14 @@ function PlaylistDetailScreen({ playlistId, onNavigate }) {
9674
10274
  }) })
9675
10275
  ]
9676
10276
  }) }), [displayTitle, navigate]));
9677
- const selectedPlaylistItem = playlist?.items?.[selectedPlaylistItemIndex];
10277
+ const taggedProducts = playlist?.items?.filter((item) => item.relateable_type === "Product" || item.relateable_type === "EnrollmentPack").map((item) => item.relateable).filter((p) => !!p) || [];
10278
+ const playableItems = playlist?.items?.filter((item) => item.relateable_type === "Medium" || item.relateable_type === "Page") ?? [];
10279
+ const selectedPlaylistItem = playableItems[selectedPlaylistItemIndex] ?? playableItems[0];
9678
10280
  const displayImage = selectedPlaylistItem?.image_url ?? selectedPlaylistItem?.relateable?.image_url ?? selectedPlaylistItem?.relateable?.compressed_image_url ?? DEFAULT_IMAGE$2;
9679
10281
  const displayDescription = playlist?.description || playlist?.search_engine_optimizer?.description || "";
9680
10282
  const selectedKind = selectedPlaylistItem?.kind ?? selectedPlaylistItem?.relateable?.kind;
9681
10283
  const displayVideo = selectedKind === "video" ? selectedPlaylistItem?.video_url ?? selectedPlaylistItem?.relateable?.video_url ?? void 0 : void 0;
9682
10284
  const isVideo = selectedKind === "video" && !!displayVideo;
9683
- const taggedProducts = playlist?.items?.filter((item) => item.relateable_type === "Product").map((item) => item.relateable).filter((p) => !!p) || [];
9684
10285
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ShareableDetailLayout, {
9685
10286
  isLoading,
9686
10287
  notFound: !playlist,
@@ -9712,7 +10313,7 @@ function PlaylistDetailScreen({ playlistId, onNavigate }) {
9712
10313
  products: taggedProducts,
9713
10314
  onProductClick: (productId) => onNavigate?.("product", String(productId))
9714
10315
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PlaylistItemsList, {
9715
- items: playlist?.items || [],
10316
+ items: playableItems,
9716
10317
  onSelectItem: setSelectedPlaylistItemIndex,
9717
10318
  selectedItemIndex: selectedPlaylistItemIndex,
9718
10319
  onNavigateToItem: (itemId, relateableType) => {
@@ -10236,19 +10837,42 @@ function SortableTable({ items, setItems, onDeleteItem, isDeletePending, enableR
10236
10837
  //#endregion
10237
10838
  //#region ../../shareables/ui/src/components/playlists/form/PlaylistItemsSection.tsx
10238
10839
  const REORDER_DEBOUNCE_MS = 500;
10239
- const PLAYLIST_CONTENT_TYPES = new Set([
10240
- "Medium",
10241
- "Page",
10242
- "Product",
10243
- "EnrollmentPack"
10244
- ]);
10840
+ const CONTENT_TYPES = [
10841
+ {
10842
+ prefix: "media_",
10843
+ relateableType: "Medium",
10844
+ section: "primary"
10845
+ },
10846
+ {
10847
+ prefix: "page_",
10848
+ relateableType: "Page",
10849
+ section: "primary"
10850
+ },
10851
+ {
10852
+ prefix: "product_",
10853
+ relateableType: "Product",
10854
+ section: "tagged"
10855
+ },
10856
+ {
10857
+ prefix: "enrollment_pack_",
10858
+ relateableType: "EnrollmentPack",
10859
+ section: "tagged"
10860
+ }
10861
+ ];
10862
+ const PRIMARY_CONTENT_TYPES = new Set(CONTENT_TYPES.filter((c) => c.section === "primary").map((c) => c.relateableType));
10863
+ const TAGGED_CONTENT_TYPES = new Set(CONTENT_TYPES.filter((c) => c.section === "tagged").map((c) => c.relateableType));
10864
+ new Set(CONTENT_TYPES.map((c) => c.relateableType));
10865
+ function deriveRelateableType(assetCode) {
10866
+ for (const entry of CONTENT_TYPES) if (assetCode.startsWith(entry.prefix)) return entry.relateableType;
10867
+ return null;
10868
+ }
10245
10869
  function computeOrderedItems(items) {
10246
10870
  const required = [];
10247
10871
  const optional = [];
10248
10872
  items.forEach((item) => {
10249
10873
  const type = item.relateable_type;
10250
- if (type === "Medium" || type === "Page") required.push(item);
10251
- else if (type === "Product" || type === "EnrollmentPack") optional.push(item);
10874
+ if (type && PRIMARY_CONTENT_TYPES.has(type)) required.push(item);
10875
+ else if (type && TAGGED_CONTENT_TYPES.has(type)) optional.push(item);
10252
10876
  });
10253
10877
  const result = [];
10254
10878
  required.forEach((item, index) => {
@@ -10265,22 +10889,36 @@ function computeOrderedItems(items) {
10265
10889
  });
10266
10890
  return result;
10267
10891
  }
10892
+ const SECTIONS = {
10893
+ primary: {
10894
+ heading: "Playlist Items",
10895
+ description: "Manage the media and pages in your playlist. At least one is required.",
10896
+ allowedMethods: ["media", "pages"],
10897
+ allowedRelateableTypes: PRIMARY_CONTENT_TYPES
10898
+ },
10899
+ tagged: {
10900
+ heading: "Tagged Products",
10901
+ description: "Manage the products and enrollments in your playlist. These items will show as recommended items in the cart.",
10902
+ allowedMethods: ["products", "enrollment_packs"],
10903
+ allowedRelateableTypes: TAGGED_CONTENT_TYPES
10904
+ }
10905
+ };
10268
10906
  function PlaylistItemsSection({ playlistId }) {
10269
- const { showToast, filePickerApi } = useShareablesUI();
10907
+ const { showToast, filePickerApi, pickerSources } = useShareablesUI();
10270
10908
  const api = useShareablesApi();
10271
- const [filePickerOpen, setFilePickerOpen] = (0, react.useState)(false);
10909
+ const [openSection, setOpenSection] = (0, react.useState)(null);
10272
10910
  const { items: contextItems, updateItems, addItem, removeItem } = usePlaylistItems();
10273
10911
  const tableItems = contextItems;
10274
- const { contentItems, tailItems } = (0, react.useMemo)(() => {
10275
- const content = [];
10276
- const tail = [];
10912
+ const { primaryItems, taggedItems } = (0, react.useMemo)(() => {
10913
+ const primary = [];
10914
+ const tagged = [];
10277
10915
  tableItems.forEach((item) => {
10278
- if (item.relateable_type && PLAYLIST_CONTENT_TYPES.has(item.relateable_type)) content.push(item);
10279
- else tail.push(item);
10916
+ if (item.relateable_type && PRIMARY_CONTENT_TYPES.has(item.relateable_type)) primary.push(item);
10917
+ else if (item.relateable_type && TAGGED_CONTENT_TYPES.has(item.relateable_type)) tagged.push(item);
10280
10918
  });
10281
10919
  return {
10282
- contentItems: content,
10283
- tailItems: tail
10920
+ primaryItems: primary,
10921
+ taggedItems: tagged
10284
10922
  };
10285
10923
  }, [tableItems]);
10286
10924
  const addItemMutation = useAddItemToPlaylistMutation({ onError: (error) => {
@@ -10312,8 +10950,8 @@ function PlaylistItemsSection({ playlistId }) {
10312
10950
  if (reorderTimerRef.current) clearTimeout(reorderTimerRef.current);
10313
10951
  }, []);
10314
10952
  const canPersistReorder = !!api.playlists.reorderPlaylistItems;
10315
- const mergeAndOrder = (0, react.useCallback)((reorderedContent) => {
10316
- const ordered = computeOrderedItems([...reorderedContent, ...tailItems]);
10953
+ const mergeAndOrder = (0, react.useCallback)((reordered, whichSection) => {
10954
+ const ordered = computeOrderedItems(whichSection === "primary" ? [...reordered, ...taggedItems] : [...primaryItems, ...reordered]);
10317
10955
  if (playlistId && canPersistReorder && reorderTimerRef.current === null && reorderRollbackRef.current === null) reorderRollbackRef.current = tableItems;
10318
10956
  updateItems(ordered);
10319
10957
  if (!playlistId || !canPersistReorder) return;
@@ -10344,7 +10982,8 @@ function PlaylistItemsSection({ playlistId }) {
10344
10982
  });
10345
10983
  }, REORDER_DEBOUNCE_MS);
10346
10984
  }, [
10347
- tailItems,
10985
+ primaryItems,
10986
+ taggedItems,
10348
10987
  tableItems,
10349
10988
  updateItems,
10350
10989
  playlistId,
@@ -10359,22 +10998,23 @@ function PlaylistItemsSection({ playlistId }) {
10359
10998
  itemIds: [itemId]
10360
10999
  });
10361
11000
  };
10362
- const handleFilePickerResults = async (results) => {
10363
- setFilePickerOpen(false);
10364
- const mediaResults = results.filter((r) => r.asset_code.startsWith("media_"));
10365
- if (mediaResults.length === 0) {
11001
+ const buildResultsHandler = (0, react.useCallback)((section) => async (results) => {
11002
+ setOpenSection(null);
11003
+ if (results.length === 0) {
10366
11004
  showToast({
10367
- title: "No media items selected",
11005
+ title: "No items selected",
10368
11006
  type: "warning"
10369
11007
  });
10370
11008
  return;
10371
11009
  }
10372
11010
  let nextOrder = tableItems.length + 1;
10373
- for (const result of mediaResults) {
10374
- const label = result.metadata?.file_name?.replace(/\.[^/.]+$/, "") || `Medium #${result.asset_id}`;
11011
+ for (const result of results) {
11012
+ const relateableType = deriveRelateableType(result.asset_code);
11013
+ if (!relateableType) continue;
11014
+ if (!section.allowedRelateableTypes.has(relateableType)) continue;
10375
11015
  const relateableId = result.asset_id;
10376
- const relateableType = "Medium";
10377
- if (tableItems.some((existingItem) => existingItem.relateable_type === relateableType && existingItem.relateable?.id === relateableId)) {
11016
+ const label = result.metadata?.file_name || `${relateableType} #${relateableId}`;
11017
+ if (tableItems.some((existing) => existing.relateable_type === relateableType && existing.relateable?.id === relateableId)) {
10378
11018
  showToast({
10379
11019
  title: "This item is already in the playlist",
10380
11020
  type: "error"
@@ -10409,7 +11049,13 @@ function PlaylistItemsSection({ playlistId }) {
10409
11049
  } catch {}
10410
11050
  else addItem(newItem);
10411
11051
  }
10412
- };
11052
+ }, [
11053
+ tableItems,
11054
+ playlistId,
11055
+ addItemMutation,
11056
+ addItem,
11057
+ showToast
11058
+ ]);
10413
11059
  const filePickerContextValue = (0, react.useMemo)(() => {
10414
11060
  if (!filePickerApi) return null;
10415
11061
  return {
@@ -10425,16 +11071,75 @@ function PlaylistItemsSection({ playlistId }) {
10425
11071
  loading: () => "",
10426
11072
  dismiss: () => {}
10427
11073
  },
10428
- shareablesClient: { media: { list: (filters) => api.media.getMedia(filters ?? {}) } }
11074
+ shareablesClient: {
11075
+ media: { list: (filters) => api.media.getMedia(filters ?? {}) },
11076
+ ...pickerSources?.pages ? { pages: pickerSources.pages } : {},
11077
+ ...pickerSources?.products ? { products: pickerSources.products } : {},
11078
+ ...pickerSources?.enrollment_packs ? { enrollment_packs: pickerSources.enrollment_packs } : {}
11079
+ }
10429
11080
  };
10430
11081
  }, [
10431
11082
  filePickerApi,
10432
11083
  showToast,
10433
- api
11084
+ api,
11085
+ pickerSources
10434
11086
  ]);
11087
+ const pickerAvailable = !!filePickerApi && !!filePickerContextValue;
10435
11088
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11089
+ className: "space-y-8",
11090
+ children: [
11091
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PlaylistItemsSubsection, {
11092
+ section: SECTIONS.primary,
11093
+ items: primaryItems,
11094
+ onAdd: () => setOpenSection("primary"),
11095
+ onReorder: (reordered) => mergeAndOrder(reordered, "primary"),
11096
+ onDeleteItem: handleDeleteItem,
11097
+ isPending: addItemMutation.isPending,
11098
+ isDeletePending: removeItemMutation.isPending,
11099
+ disableAdd: !pickerAvailable
11100
+ }),
11101
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PlaylistItemsSubsection, {
11102
+ section: SECTIONS.tagged,
11103
+ items: taggedItems,
11104
+ onAdd: () => setOpenSection("tagged"),
11105
+ onReorder: (reordered) => mergeAndOrder(reordered, "tagged"),
11106
+ onDeleteItem: handleDeleteItem,
11107
+ isPending: addItemMutation.isPending,
11108
+ isDeletePending: removeItemMutation.isPending,
11109
+ disableAdd: !pickerAvailable
11110
+ }),
11111
+ pickerAvailable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilePickerApiProvider, {
11112
+ api: filePickerApi,
11113
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(FilePickerProvider, {
11114
+ value: filePickerContextValue,
11115
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilePicker, {
11116
+ open: openSection === "primary",
11117
+ onClose: () => setOpenSection(null),
11118
+ onFilesSelected: (selected) => void buildResultsHandler(SECTIONS.primary)(selected),
11119
+ config: {
11120
+ maxFiles: 50,
11121
+ allowedMethods: SECTIONS.primary.allowedMethods,
11122
+ unifiedSelection: true
11123
+ }
11124
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilePicker, {
11125
+ open: openSection === "tagged",
11126
+ onClose: () => setOpenSection(null),
11127
+ onFilesSelected: (selected) => void buildResultsHandler(SECTIONS.tagged)(selected),
11128
+ config: {
11129
+ maxFiles: 50,
11130
+ allowedMethods: SECTIONS.tagged.allowedMethods,
11131
+ unifiedSelection: true
11132
+ }
11133
+ })]
11134
+ })
11135
+ })
11136
+ ]
11137
+ });
11138
+ }
11139
+ function PlaylistItemsSubsection({ section, items, onAdd, onReorder, onDeleteItem, isPending, isDeletePending, disableAdd = false }) {
11140
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10436
11141
  className: "border-border bg-card rounded-lg border p-4",
10437
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11142
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10438
11143
  className: "space-y-4",
10439
11144
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10440
11145
  className: "flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between",
@@ -10442,49 +11147,31 @@ function PlaylistItemsSection({ playlistId }) {
10442
11147
  className: "min-w-0",
10443
11148
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
10444
11149
  className: "text-md text-foreground font-semibold",
10445
- children: "Content"
10446
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
11150
+ children: section.heading
11151
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
10447
11152
  className: "text-muted-foreground text-sm",
10448
- children: [
10449
- "Use ",
10450
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: "Add content" }),
10451
- " to open the file picker and choose media from your library. Drag rows to reorder."
10452
- ]
11153
+ children: section.description
10453
11154
  })]
10454
11155
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10455
11156
  className: "flex shrink-0 flex-wrap items-center justify-end gap-2",
10456
11157
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
10457
11158
  type: "button",
10458
- disabled: addItemMutation.isPending || !filePickerApi,
11159
+ disabled: isPending || disableAdd,
10459
11160
  variant: "default",
10460
11161
  size: "sm",
10461
11162
  className: "flex min-w-25 items-center gap-2",
10462
- onClick: () => setFilePickerOpen(true),
10463
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Plus, { className: "h-4 w-4" }), "Add content"]
11163
+ onClick: onAdd,
11164
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Plus, { className: "h-4 w-4" }), "Add Item"]
10464
11165
  })
10465
11166
  })]
10466
11167
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SortableTable, {
10467
- items: contentItems,
10468
- setItems: (reordered) => mergeAndOrder(reordered),
10469
- onDeleteItem: handleDeleteItem,
10470
- isDeletePending: removeItemMutation.isPending,
11168
+ items,
11169
+ setItems: (reordered) => onReorder(reordered),
11170
+ onDeleteItem,
11171
+ isDeletePending,
10471
11172
  enableReordering: true
10472
11173
  })]
10473
- }), filePickerContextValue && filePickerApi && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilePickerApiProvider, {
10474
- api: filePickerApi,
10475
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilePickerProvider, {
10476
- value: filePickerContextValue,
10477
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilePicker, {
10478
- open: filePickerOpen,
10479
- onFilesSelected: (selected) => void handleFilePickerResults(selected),
10480
- onClose: () => setFilePickerOpen(false),
10481
- config: {
10482
- maxFiles: 50,
10483
- allowedMethods: ["media"]
10484
- }
10485
- })
10486
- })
10487
- })]
11174
+ })
10488
11175
  });
10489
11176
  }
10490
11177
  //#endregion
@@ -11395,22 +12082,25 @@ function createRawMediaAdapter(client) {
11395
12082
  },
11396
12083
  createMedia: async (body) => {
11397
12084
  const response = await require_portal_tenant_content.media_create(client, { media: body });
12085
+ if (!response.media) throw new Error("Media create response missing media");
11398
12086
  return {
11399
- media: mapMedia(response.media ?? {}),
12087
+ media: mapMedia(response.media),
11400
12088
  meta: mapMediaMeta(response.meta)
11401
12089
  };
11402
12090
  },
11403
12091
  getMedia: async (id) => {
11404
12092
  const response = await require_portal_tenant_content.media_show(client, id);
12093
+ if (!response.media) throw new Error("Media show response missing media");
11405
12094
  return {
11406
- media: mapMedia(response.media ?? {}),
12095
+ media: mapMedia(response.media),
11407
12096
  meta: mapMediaMeta(response.meta)
11408
12097
  };
11409
12098
  },
11410
12099
  updateMedia: async (id, body) => {
11411
12100
  const response = await require_portal_tenant_content.media_update(client, id, { media: body });
12101
+ if (!response.media) throw new Error("Media update response missing media");
11412
12102
  return {
11413
- media: mapMedia(response.media ?? {}),
12103
+ media: mapMedia(response.media),
11414
12104
  meta: mapMediaMeta(response.meta)
11415
12105
  };
11416
12106
  },
@@ -11674,15 +12364,12 @@ function mapPlaylist(raw) {
11674
12364
  }
11675
12365
  function mapPlaylistItem(raw) {
11676
12366
  return {
11677
- id: raw.id ?? 0,
11678
- media_id: raw.media_id ?? 0,
11679
- position: raw.position ?? null,
11680
- title: raw.title,
11681
- image_url: raw.image_url ?? null,
11682
- media_type: raw.media_type,
11683
- video_url: raw.video_url ?? null,
11684
- duration: raw.duration ?? null,
11685
- created_at: raw.created_at ?? ""
12367
+ id: raw.id,
12368
+ content_type: raw.content_type,
12369
+ content_id: raw.content_id,
12370
+ position: raw.position,
12371
+ created_at: raw.created_at,
12372
+ content: raw.content
11686
12373
  };
11687
12374
  }
11688
12375
  function mapPlaylistsMeta(raw) {
@@ -11751,8 +12438,10 @@ function createRawPlaylistsAdapter(client) {
11751
12438
  },
11752
12439
  addPlaylistItem: async (playlistId, body) => {
11753
12440
  const response = await require_portal_tenant_content.playlists_items_add(client, playlistId, { item: body });
12441
+ const rawItem = response.playlist_item;
12442
+ if (!rawItem) throw new Error("Playlist item add response missing playlist_item");
11754
12443
  return {
11755
- playlist_item: mapPlaylistItem(response.playlist_item ?? {}),
12444
+ playlist_item: mapPlaylistItem(rawItem),
11756
12445
  meta: mapPlaylistsMeta(response.meta)
11757
12446
  };
11758
12447
  },
@@ -11762,9 +12451,157 @@ function createRawPlaylistsAdapter(client) {
11762
12451
  playlist_item: { id: response.playlist_item?.id ?? 0 },
11763
12452
  meta: mapPlaylistsMeta(response.meta)
11764
12453
  };
12454
+ },
12455
+ reorderPlaylistItems: async (playlistId, body) => {
12456
+ const response = await require_portal_tenant_content.playlists_items_reorder(client, playlistId, body);
12457
+ return {
12458
+ playlist_id: response.playlist_id ?? playlistId,
12459
+ meta: mapPlaylistsMeta(response.meta)
12460
+ };
11765
12461
  }
11766
12462
  };
11767
12463
  }
12464
+ const CONTENT_TYPE_TO_RELATEABLE = {
12465
+ media: "Medium",
12466
+ page: "Page",
12467
+ product: "Product",
12468
+ enrollment_pack: "EnrollmentPack"
12469
+ };
12470
+ const RELATEABLE_TO_CONTENT_TYPE = {
12471
+ Medium: "media",
12472
+ Media: "media",
12473
+ media: "media",
12474
+ Page: "page",
12475
+ page: "page",
12476
+ Product: "product",
12477
+ product: "product",
12478
+ EnrollmentPack: "enrollment_pack",
12479
+ enrollment_pack: "enrollment_pack"
12480
+ };
12481
+ function firstImageUrl(images) {
12482
+ return images?.[0]?.url ?? null;
12483
+ }
12484
+ function toShareablePlaylistItem(item) {
12485
+ const relateableType = CONTENT_TYPE_TO_RELATEABLE[item.content_type];
12486
+ const base = {
12487
+ id: item.id,
12488
+ order: item.position ?? void 0,
12489
+ relateable_type: relateableType,
12490
+ relateable: { id: item.content_id }
12491
+ };
12492
+ switch (item.content_type) {
12493
+ case "media": {
12494
+ const c = item.content;
12495
+ const isVideo = c.content_format === "video";
12496
+ const isPdf = c.content_format === "pdf";
12497
+ base.title = c.title ?? "Untitled";
12498
+ base.image_url = isVideo || isPdf ? c.thumbnail_url ?? null : c.url ?? c.thumbnail_url ?? null;
12499
+ base.kind = mediaKindFromType(c.content_format ?? "");
12500
+ base.video_url = isVideo ? c.url ?? null : null;
12501
+ base.duration = null;
12502
+ base.media_format = c.content_format ?? null;
12503
+ base.relateable = {
12504
+ id: c.id,
12505
+ title: c.title,
12506
+ image_url: base.image_url,
12507
+ media_format: c.content_format ?? null,
12508
+ video_url: base.video_url,
12509
+ kind: base.kind,
12510
+ description: {
12511
+ id: null,
12512
+ name: null,
12513
+ body: c.description ?? null,
12514
+ record_type: null,
12515
+ record_id: null,
12516
+ created_at: c.created_at ?? null,
12517
+ updated_at: c.updated_at ?? null,
12518
+ locale: null
12519
+ }
12520
+ };
12521
+ break;
12522
+ }
12523
+ case "page": {
12524
+ const c = item.content;
12525
+ base.title = c.title ?? "Untitled";
12526
+ base.image_url = c.image_url ?? null;
12527
+ base.relateable = {
12528
+ id: c.id,
12529
+ title: c.title,
12530
+ slug: c.slug ?? null,
12531
+ image_url: c.image_url ?? null,
12532
+ status: c.status,
12533
+ description: {
12534
+ id: null,
12535
+ name: null,
12536
+ body: c.description ?? null,
12537
+ record_type: null,
12538
+ record_id: null,
12539
+ created_at: null,
12540
+ updated_at: null,
12541
+ locale: null
12542
+ }
12543
+ };
12544
+ break;
12545
+ }
12546
+ case "product": {
12547
+ const c = item.content;
12548
+ const image = firstImageUrl(c.images);
12549
+ base.title = c.name;
12550
+ base.image_url = image;
12551
+ base.relateable = {
12552
+ id: c.id,
12553
+ title: c.name,
12554
+ slug: c.slug ?? null,
12555
+ price: c.price ?? null,
12556
+ display_price: c.price ?? null,
12557
+ image_url: image,
12558
+ status: c.status ?? null,
12559
+ description: {
12560
+ id: null,
12561
+ name: null,
12562
+ body: c.description ?? null,
12563
+ record_type: null,
12564
+ record_id: null,
12565
+ created_at: c.created_at ?? null,
12566
+ updated_at: null,
12567
+ locale: null
12568
+ },
12569
+ images: (c.images ?? []).map((img) => ({ image_url: img.url ?? null }))
12570
+ };
12571
+ break;
12572
+ }
12573
+ case "enrollment_pack": {
12574
+ const c = item.content;
12575
+ const image = firstImageUrl(c.images);
12576
+ base.title = c.title;
12577
+ base.image_url = image;
12578
+ base.relateable = {
12579
+ id: c.id,
12580
+ title: c.title,
12581
+ slug: c.slug ?? null,
12582
+ canonical_url: c.url ?? null,
12583
+ image_url: image,
12584
+ description: {
12585
+ id: null,
12586
+ name: null,
12587
+ body: c.description ?? null,
12588
+ record_type: null,
12589
+ record_id: null,
12590
+ created_at: null,
12591
+ updated_at: null,
12592
+ locale: null
12593
+ },
12594
+ images: (c.images ?? []).map((img) => ({ image_url: img.url ?? null }))
12595
+ };
12596
+ break;
12597
+ }
12598
+ default: {
12599
+ const _exhaustive = item.content_type;
12600
+ throw new Error(`Unhandled playlist item content_type: ${String(_exhaustive)}`);
12601
+ }
12602
+ }
12603
+ return base;
12604
+ }
11768
12605
  function toBffPlaylist(bff, items) {
11769
12606
  return {
11770
12607
  id: bff.id,
@@ -11825,18 +12662,7 @@ function createPlaylistsAdapter(client) {
11825
12662
  cursor = page.meta.pagination?.next_cursor ?? void 0;
11826
12663
  if (!cursor) break;
11827
12664
  }
11828
- const items = allItems.map((item) => ({
11829
- id: item.id,
11830
- order: item.position ?? void 0,
11831
- relateable_type: "Medium",
11832
- relateable: { id: item.media_id },
11833
- title: item.title ?? "Untitled",
11834
- image_url: item.image_url ?? null,
11835
- kind: mediaKindFromType(item.media_type ?? ""),
11836
- video_url: item.video_url ?? null,
11837
- duration: item.duration ?? null,
11838
- media_format: item.media_type ?? null
11839
- }));
12665
+ const items = allItems.map(toShareablePlaylistItem);
11840
12666
  return {
11841
12667
  playlist: toBffPlaylist(response.playlist, items),
11842
12668
  meta: {
@@ -11872,10 +12698,15 @@ function createPlaylistsAdapter(client) {
11872
12698
  };
11873
12699
  },
11874
12700
  addItemToPlaylist: async (id, data) => {
11875
- await Promise.all(data.items.map((item) => portAdapter.addPlaylistItem(id, {
11876
- media_id: item.relateable_id,
11877
- position: typeof item.order === "number" ? item.order : Number(item.order)
11878
- })));
12701
+ for (const item of data.items) {
12702
+ const contentType = RELATEABLE_TO_CONTENT_TYPE[item.relateable_type];
12703
+ if (!contentType) throw new Error(`Unsupported relateable_type for playlist item: "${item.relateable_type}"`);
12704
+ await portAdapter.addPlaylistItem(id, {
12705
+ content_type: contentType,
12706
+ content_id: item.relateable_id,
12707
+ position: typeof item.order === "number" ? item.order : Number(item.order)
12708
+ });
12709
+ }
11879
12710
  return {
11880
12711
  id,
11881
12712
  title: "",
@@ -11905,7 +12736,7 @@ function createPlaylistsAdapter(client) {
11905
12736
  };
11906
12737
  },
11907
12738
  reorderPlaylistItems: async (playlistId, data) => {
11908
- await require_portal_tenant_content.playlists_items_reorder(client, playlistId, { items: data.items });
12739
+ await portAdapter.reorderPlaylistItems(playlistId, { items: data.items });
11909
12740
  }
11910
12741
  };
11911
12742
  }
@@ -12033,6 +12864,53 @@ function createRawPagesAdapter(client) {
12033
12864
  }
12034
12865
  };
12035
12866
  }
12867
+ function mapEnrollmentPack(raw) {
12868
+ return {
12869
+ id: raw.id ?? 0,
12870
+ title: raw.title ?? "",
12871
+ slug: raw.slug ?? null,
12872
+ description: raw.description ?? null,
12873
+ url: raw.url ?? null,
12874
+ images: (raw.images ?? []).map((img) => ({
12875
+ url: img.url ?? null,
12876
+ alt: img.alt ?? null
12877
+ }))
12878
+ };
12879
+ }
12880
+ function mapEnrollmentPacksMeta(raw) {
12881
+ return {
12882
+ request_id: raw?.request_id ?? null,
12883
+ timestamp: raw?.timestamp ?? "",
12884
+ pagination: raw?.pagination ? {
12885
+ cursor: raw.pagination.cursor ?? null,
12886
+ limit: raw.pagination.limit,
12887
+ next_cursor: raw.pagination.next_cursor ?? null,
12888
+ prev_cursor: raw.pagination.prev_cursor ?? null
12889
+ } : void 0
12890
+ };
12891
+ }
12892
+ function createRawEnrollmentPacksAdapter(client) {
12893
+ return {
12894
+ listEnrollmentPacks: async (params) => {
12895
+ const response = await require_portal_tenant.enrollment_packs_list(client, {
12896
+ "page[cursor]": params?.cursor,
12897
+ "page[limit]": params?.limit
12898
+ });
12899
+ return {
12900
+ enrollment_packs: (response.enrollment_packs ?? []).filter((p) => typeof p.id === "number").map(mapEnrollmentPack),
12901
+ meta: mapEnrollmentPacksMeta(response.meta)
12902
+ };
12903
+ },
12904
+ getEnrollmentPack: async (id) => {
12905
+ const response = await require_portal_tenant.enrollment_packs_show(client, id);
12906
+ if (!response.enrollment_pack) throw new Error(`EnrollmentPack ${id} not found`);
12907
+ return {
12908
+ enrollment_pack: mapEnrollmentPack(response.enrollment_pack),
12909
+ meta: mapEnrollmentPacksMeta(response.meta)
12910
+ };
12911
+ }
12912
+ };
12913
+ }
12036
12914
  function mapDamAsset(raw) {
12037
12915
  return {
12038
12916
  id: raw.id ?? 0,
@@ -12275,6 +13153,23 @@ function createPortalContentPlaylistsAdapter(client) {
12275
13153
  return createRawPlaylistsAdapter(client);
12276
13154
  }
12277
13155
  /**
13156
+ * Creates a ContentPagesApi (the port-level pages adapter) for screens that
13157
+ * need to list/show pages outside of ShareablesApiProvider — e.g. the
13158
+ * playlist editor's content picker. Mirrors createPortalContentPlaylistsAdapter.
13159
+ */
13160
+ function createPortalContentPagesAdapter(client) {
13161
+ return createRawPagesAdapter(client);
13162
+ }
13163
+ /**
13164
+ * Creates a ContentEnrollmentPacksApi adapter for screens that need to
13165
+ * list/show enrollment packs outside of ShareablesApiProvider — e.g. the
13166
+ * playlist editor's content picker. Backed by the portal-tenant
13167
+ * `/api/enrollment_packs` endpoint.
13168
+ */
13169
+ function createPortalContentEnrollmentPacksAdapter(client) {
13170
+ return createRawEnrollmentPacksAdapter(client);
13171
+ }
13172
+ /**
12278
13173
  * Toggles a favorite entry on a given shareable (Medium / Playlist /
12279
13174
  * Product / etc.) via the portal-tenant BFF's /favorites/toggle endpoint.
12280
13175
  * Returns the new is_favorited state reported by the backend.
@@ -12307,15 +13202,21 @@ function PortalContentApiProvider({ children }) {
12307
13202
  const productsApi = require_PortalProductsApiProvider.usePortalProductsApi();
12308
13203
  const contentApi = (0, react.useMemo)(() => createPortalContentDomainApiAdapter(client, productsApi), [client, productsApi]);
12309
13204
  const playlistsAdapter = (0, react.useMemo)(() => createPortalContentPlaylistsAdapter(client), [client]);
13205
+ const pagesAdapter = (0, react.useMemo)(() => createPortalContentPagesAdapter(client), [client]);
13206
+ const enrollmentPacksAdapter = (0, react.useMemo)(() => createPortalContentEnrollmentPacksAdapter(client), [client]);
12310
13207
  const mediaProductsAdapter = (0, react.useMemo)(() => createPortalTenantMediaProductsAdapter(client), [client]);
12311
13208
  const filePickerApi = (0, react.useMemo)(() => createFilePickerApiAdapter(client), [client]);
12312
13209
  const ctx = (0, react.useMemo)(() => ({
12313
13210
  productsApi,
12314
13211
  playlistsAdapter,
13212
+ pagesAdapter,
13213
+ enrollmentPacksAdapter,
12315
13214
  mediaProductsAdapter
12316
13215
  }), [
12317
13216
  productsApi,
12318
13217
  playlistsAdapter,
13218
+ pagesAdapter,
13219
+ enrollmentPacksAdapter,
12319
13220
  mediaProductsAdapter
12320
13221
  ]);
12321
13222
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ContentContext.Provider, {
@@ -12460,6 +13361,59 @@ function ShareablesScreenContent() {
12460
13361
  };
12461
13362
  },
12462
13363
  readOnly: isCustomer,
13364
+ pickerSources: isCustomer ? void 0 : {
13365
+ pages: { list: async ({ search, cursor, limit }) => {
13366
+ const response = await shareablesCtx.pagesAdapter.listPages({
13367
+ cursor: cursor ?? void 0,
13368
+ limit,
13369
+ "filter[title]": search && search.trim().length > 0 ? search : void 0
13370
+ });
13371
+ return {
13372
+ items: response.pages.map((p) => ({
13373
+ id: p.id,
13374
+ title: p.title ?? `Page #${p.id}`,
13375
+ image_url: p.image_url ?? null
13376
+ })),
13377
+ nextCursor: response.meta.pagination?.next_cursor ?? null
13378
+ };
13379
+ } },
13380
+ products: { list: async ({ search, cursor, limit }) => {
13381
+ const trimmedSearch = search?.trim() ?? "";
13382
+ const result = trimmedSearch.length > 0 ? await portalProductsApi.searchProducts(trimmedSearch, {
13383
+ cursor: cursor ?? void 0,
13384
+ limit
13385
+ }) : await portalProductsApi.listProducts({
13386
+ cursor: cursor ?? void 0,
13387
+ limit
13388
+ });
13389
+ return {
13390
+ items: (result.products ?? []).map((p) => p.id != null ? {
13391
+ id: p.id,
13392
+ name: p.name ?? "Untitled",
13393
+ image_url: p.images?.[0]?.url ?? null,
13394
+ price: p.price ?? null
13395
+ } : null).filter((p) => p !== null),
13396
+ nextCursor: result.meta?.pagination?.next_cursor ?? null
13397
+ };
13398
+ } },
13399
+ enrollment_packs: {
13400
+ supportsSearch: false,
13401
+ list: async ({ cursor, limit }) => {
13402
+ const response = await shareablesCtx.enrollmentPacksAdapter.listEnrollmentPacks({
13403
+ cursor: cursor ?? void 0,
13404
+ limit
13405
+ });
13406
+ return {
13407
+ items: response.enrollment_packs.map((pack) => ({
13408
+ id: pack.id,
13409
+ title: pack.title || `Enrollment Pack #${pack.id}`,
13410
+ image_url: pack.images[0]?.url ?? null
13411
+ })),
13412
+ nextCursor: response.meta.pagination?.next_cursor ?? null
13413
+ };
13414
+ }
13415
+ }
13416
+ },
12463
13417
  uploadThumbnail: isCustomer ? void 0 : async (blob, filename) => {
12464
13418
  const formData = new FormData();
12465
13419
  formData.append("asset[name]", filename);
@@ -12475,6 +13429,8 @@ function ShareablesScreenContent() {
12475
13429
  filePickerApi,
12476
13430
  isCustomer,
12477
13431
  shareablesCtx.playlistsAdapter,
13432
+ shareablesCtx.pagesAdapter,
13433
+ shareablesCtx.enrollmentPacksAdapter,
12478
13434
  shareablesCtx.mediaProductsAdapter,
12479
13435
  portalProductsApi,
12480
13436
  client,
@@ -12517,4 +13473,4 @@ Object.defineProperty(exports, "shareablesScreenPropertySchema", {
12517
13473
  }
12518
13474
  });
12519
13475
 
12520
- //# sourceMappingURL=ShareablesScreen-o6frhZUM.cjs.map
13476
+ //# sourceMappingURL=ShareablesScreen-DfrTNnRw.cjs.map