@payloadcms/ui 3.80.0-internal.21e9c47 → 3.80.0-internal.52ab774

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 (321) hide show
  1. package/dist/elements/ClipboardAction/mergeFormStateFromClipboard.d.ts.map +1 -1
  2. package/dist/elements/ClipboardAction/mergeFormStateFromClipboard.js +53 -3
  3. package/dist/elements/ClipboardAction/mergeFormStateFromClipboard.js.map +1 -1
  4. package/dist/elements/ClipboardAction/mergeFormStateFromClipboard.spec.js +541 -0
  5. package/dist/elements/ClipboardAction/mergeFormStateFromClipboard.spec.js.map +1 -0
  6. package/dist/elements/Combobox/index.d.ts.map +1 -1
  7. package/dist/elements/Combobox/index.js +1 -0
  8. package/dist/elements/Combobox/index.js.map +1 -1
  9. package/dist/elements/Hierarchy/ColumnBrowser/Column/index.d.ts.map +1 -0
  10. package/dist/elements/{HierarchyColumnBrowser → Hierarchy/ColumnBrowser}/Column/index.js +5 -5
  11. package/dist/elements/Hierarchy/ColumnBrowser/Column/index.js.map +1 -0
  12. package/dist/elements/{HierarchyColumnBrowser → Hierarchy/ColumnBrowser}/Column/index.scss +1 -1
  13. package/dist/elements/Hierarchy/ColumnBrowser/ColumnItem/index.d.ts.map +1 -0
  14. package/dist/elements/{HierarchyColumnBrowser → Hierarchy/ColumnBrowser}/ColumnItem/index.js +3 -3
  15. package/dist/elements/Hierarchy/ColumnBrowser/ColumnItem/index.js.map +1 -0
  16. package/dist/elements/{HierarchyColumnBrowser → Hierarchy/ColumnBrowser}/ColumnItem/index.scss +1 -1
  17. package/dist/elements/{HierarchyColumnBrowser → Hierarchy/ColumnBrowser}/index.d.ts +1 -1
  18. package/dist/elements/Hierarchy/ColumnBrowser/index.d.ts.map +1 -0
  19. package/dist/elements/{HierarchyColumnBrowser → Hierarchy/ColumnBrowser}/index.js +13 -10
  20. package/dist/elements/Hierarchy/ColumnBrowser/index.js.map +1 -0
  21. package/dist/elements/{HierarchyColumnBrowser → Hierarchy/ColumnBrowser}/types.d.ts +3 -0
  22. package/dist/elements/Hierarchy/ColumnBrowser/types.d.ts.map +1 -0
  23. package/dist/elements/Hierarchy/ColumnBrowser/types.js.map +1 -0
  24. package/dist/elements/Hierarchy/DocHeaderButton/index.d.ts.map +1 -0
  25. package/dist/elements/{HierarchyButton → Hierarchy/DocHeaderButton}/index.js +6 -6
  26. package/dist/elements/Hierarchy/DocHeaderButton/index.js.map +1 -0
  27. package/dist/elements/Hierarchy/DocHeaderButton/index.server.d.ts.map +1 -0
  28. package/dist/elements/{HierarchyButton → Hierarchy/DocHeaderButton}/index.server.js +3 -3
  29. package/dist/elements/Hierarchy/DocHeaderButton/index.server.js.map +1 -0
  30. package/dist/elements/Hierarchy/Drawer/fetchAncestorPath.d.ts.map +1 -0
  31. package/dist/elements/Hierarchy/Drawer/fetchAncestorPath.js.map +1 -0
  32. package/dist/elements/{HierarchyDrawer → Hierarchy}/Drawer/index.d.ts +3 -3
  33. package/dist/elements/Hierarchy/Drawer/index.d.ts.map +1 -0
  34. package/dist/elements/{HierarchyDrawer → Hierarchy}/Drawer/index.js +4 -2
  35. package/dist/elements/Hierarchy/Drawer/index.js.map +1 -0
  36. package/dist/elements/{HierarchyDrawer → Hierarchy/Drawer}/types.d.ts +4 -1
  37. package/dist/elements/Hierarchy/Drawer/types.d.ts.map +1 -0
  38. package/dist/elements/Hierarchy/Drawer/types.js.map +1 -0
  39. package/dist/elements/{HierarchyDrawer/index.d.ts → Hierarchy/Drawer/useHierarchyDrawer.d.ts} +1 -1
  40. package/dist/elements/Hierarchy/Drawer/useHierarchyDrawer.d.ts.map +1 -0
  41. package/dist/elements/{HierarchyDrawer/index.js → Hierarchy/Drawer/useHierarchyDrawer.js} +10 -8
  42. package/dist/elements/Hierarchy/Drawer/useHierarchyDrawer.js.map +1 -0
  43. package/dist/elements/Hierarchy/Field/SelectedHierarchies.d.ts.map +1 -0
  44. package/dist/elements/{HierarchyField → Hierarchy/Field}/SelectedHierarchies.js +7 -16
  45. package/dist/elements/Hierarchy/Field/SelectedHierarchies.js.map +1 -0
  46. package/dist/elements/{HierarchyField → Hierarchy/Field}/SelectedHierarchies.scss +1 -1
  47. package/dist/elements/Hierarchy/Field/index.client.d.ts.map +1 -0
  48. package/dist/elements/{HierarchyField → Hierarchy/Field}/index.client.js +17 -29
  49. package/dist/elements/Hierarchy/Field/index.client.js.map +1 -0
  50. package/dist/elements/{HierarchyField → Hierarchy/Field}/index.scss +1 -1
  51. package/dist/elements/Hierarchy/Field/index.server.d.ts.map +1 -0
  52. package/dist/elements/{HierarchyField → Hierarchy/Field}/index.server.js +2 -2
  53. package/dist/elements/Hierarchy/Field/index.server.js.map +1 -0
  54. package/dist/elements/Hierarchy/HydrateProvider/index.d.ts +4 -0
  55. package/dist/elements/Hierarchy/HydrateProvider/index.d.ts.map +1 -0
  56. package/dist/elements/Hierarchy/HydrateProvider/index.js +70 -0
  57. package/dist/elements/Hierarchy/HydrateProvider/index.js.map +1 -0
  58. package/dist/elements/{MoveMany → Hierarchy/MoveMany}/index.d.ts +3 -3
  59. package/dist/elements/Hierarchy/MoveMany/index.d.ts.map +1 -0
  60. package/dist/elements/{MoveMany → Hierarchy/MoveMany}/index.js +10 -10
  61. package/dist/elements/Hierarchy/MoveMany/index.js.map +1 -0
  62. package/dist/elements/{MoveMany → Hierarchy/MoveMany}/index.scss +1 -1
  63. package/dist/elements/Hierarchy/Search/HierarchySearchInput.d.ts.map +1 -0
  64. package/dist/elements/{HierarchySearch → Hierarchy/Search}/HierarchySearchInput.js +5 -5
  65. package/dist/elements/Hierarchy/Search/HierarchySearchInput.js.map +1 -0
  66. package/dist/elements/Hierarchy/Search/HierarchySearchResultItem.d.ts.map +1 -0
  67. package/dist/elements/Hierarchy/Search/HierarchySearchResultItem.js.map +1 -0
  68. package/dist/elements/Hierarchy/Search/HierarchySearchResults.d.ts.map +1 -0
  69. package/dist/elements/{HierarchySearch → Hierarchy/Search}/HierarchySearchResults.js +2 -2
  70. package/dist/elements/Hierarchy/Search/HierarchySearchResults.js.map +1 -0
  71. package/dist/elements/Hierarchy/Search/index.d.ts.map +1 -0
  72. package/dist/elements/{HierarchySearch → Hierarchy/Search}/index.js +2 -2
  73. package/dist/elements/Hierarchy/Search/index.js.map +1 -0
  74. package/dist/elements/{HierarchySearch → Hierarchy/Search}/index.scss +1 -1
  75. package/dist/elements/Hierarchy/Search/types.d.ts.map +1 -0
  76. package/dist/elements/Hierarchy/Search/types.js.map +1 -0
  77. package/dist/elements/Hierarchy/Search/useHierarchySearch.d.ts.map +1 -0
  78. package/dist/elements/{HierarchySearch → Hierarchy/Search}/useHierarchySearch.js +2 -2
  79. package/dist/elements/Hierarchy/Search/useHierarchySearch.js.map +1 -0
  80. package/dist/elements/{HierarchyTree → Hierarchy/Tree}/HierarchySidebarTab.d.ts +1 -0
  81. package/dist/elements/Hierarchy/Tree/HierarchySidebarTab.d.ts.map +1 -0
  82. package/dist/elements/Hierarchy/Tree/HierarchySidebarTab.js +194 -0
  83. package/dist/elements/Hierarchy/Tree/HierarchySidebarTab.js.map +1 -0
  84. package/dist/elements/Hierarchy/Tree/HierarchySidebarTab.server.d.ts.map +1 -0
  85. package/dist/elements/{HierarchyTree → Hierarchy/Tree}/HierarchySidebarTab.server.js +20 -10
  86. package/dist/elements/Hierarchy/Tree/HierarchySidebarTab.server.js.map +1 -0
  87. package/dist/elements/Hierarchy/Tree/LoadMore/LoadMoreButton.d.ts.map +1 -0
  88. package/dist/elements/{Tree → Hierarchy/Tree}/LoadMore/LoadMoreButton.js +1 -1
  89. package/dist/elements/Hierarchy/Tree/LoadMore/LoadMoreButton.js.map +1 -0
  90. package/dist/elements/Hierarchy/Tree/LoadMore/index.d.ts.map +1 -0
  91. package/dist/elements/{Tree → Hierarchy/Tree}/LoadMore/index.js +1 -1
  92. package/dist/elements/Hierarchy/Tree/LoadMore/index.js.map +1 -0
  93. package/dist/elements/Hierarchy/Tree/TreeConnector.d.ts.map +1 -0
  94. package/dist/elements/Hierarchy/Tree/TreeConnector.js.map +1 -0
  95. package/dist/elements/Hierarchy/Tree/TreeFocusContext.d.ts.map +1 -0
  96. package/dist/elements/Hierarchy/Tree/TreeFocusContext.js.map +1 -0
  97. package/dist/elements/Hierarchy/Tree/TreeNode/index.d.ts +5 -0
  98. package/dist/elements/Hierarchy/Tree/TreeNode/index.d.ts.map +1 -0
  99. package/dist/elements/{Tree → Hierarchy/Tree}/TreeNode/index.js +11 -4
  100. package/dist/elements/Hierarchy/Tree/TreeNode/index.js.map +1 -0
  101. package/dist/elements/{Tree → Hierarchy/Tree}/TreeNode/index.scss +1 -1
  102. package/dist/elements/{HierarchyTree → Hierarchy/Tree}/index.d.ts +1 -0
  103. package/dist/elements/Hierarchy/Tree/index.d.ts.map +1 -0
  104. package/dist/elements/Hierarchy/Tree/index.js +305 -0
  105. package/dist/elements/Hierarchy/Tree/index.js.map +1 -0
  106. package/dist/elements/{Tree → Hierarchy/Tree}/index.scss +2 -5
  107. package/dist/elements/{Tree → Hierarchy/Tree}/types.d.ts +31 -22
  108. package/dist/elements/Hierarchy/Tree/types.d.ts.map +1 -0
  109. package/dist/elements/Hierarchy/Tree/types.js.map +1 -0
  110. package/dist/elements/Hierarchy/Tree/useChildren.d.ts +32 -0
  111. package/dist/elements/Hierarchy/Tree/useChildren.d.ts.map +1 -0
  112. package/dist/elements/{Tree → Hierarchy/Tree}/useChildren.js +52 -32
  113. package/dist/elements/Hierarchy/Tree/useChildren.js.map +1 -0
  114. package/dist/elements/Link/index.d.ts.map +1 -1
  115. package/dist/elements/LoadMoreRow/index.js +1 -1
  116. package/dist/elements/LoadMoreRow/index.js.map +1 -1
  117. package/dist/elements/PublishButton/index.d.ts.map +1 -1
  118. package/dist/elements/PublishButton/index.js +3 -1
  119. package/dist/elements/PublishButton/index.js.map +1 -1
  120. package/dist/elements/RelationshipTable/index.d.ts.map +1 -1
  121. package/dist/elements/RelationshipTable/index.js +14 -9
  122. package/dist/elements/RelationshipTable/index.js.map +1 -1
  123. package/dist/elements/Table/DefaultCell/fields/Hierarchy/index.js +1 -1
  124. package/dist/elements/Table/DefaultCell/fields/Hierarchy/index.js.map +1 -1
  125. package/dist/elements/Toasts/fieldErrors.d.ts +4 -0
  126. package/dist/elements/Toasts/fieldErrors.d.ts.map +1 -1
  127. package/dist/elements/Toasts/fieldErrors.js +4 -2
  128. package/dist/elements/Toasts/fieldErrors.js.map +1 -1
  129. package/dist/elements/Toasts/fieldErrors.spec.js +46 -0
  130. package/dist/elements/Toasts/fieldErrors.spec.js.map +1 -0
  131. package/dist/elements/WhereBuilder/Condition/Relationship/index.d.ts.map +1 -1
  132. package/dist/elements/WhereBuilder/Condition/Relationship/index.js +8 -6
  133. package/dist/elements/WhereBuilder/Condition/Relationship/index.js.map +1 -1
  134. package/dist/elements/WhereBuilder/field-types.d.ts.map +1 -1
  135. package/dist/elements/WhereBuilder/field-types.js +2 -5
  136. package/dist/elements/WhereBuilder/field-types.js.map +1 -1
  137. package/dist/exports/client/{DatePicker-CL2EGBVQ.js → DatePicker-T2DMDMM5.js} +2 -2
  138. package/dist/exports/client/chunk-WDZJLNNB.js +29 -0
  139. package/dist/exports/client/{chunk-SH42NW5R.js.map → chunk-WDZJLNNB.js.map} +4 -4
  140. package/dist/exports/client/index.d.ts +11 -15
  141. package/dist/exports/client/index.d.ts.map +1 -1
  142. package/dist/exports/client/index.js +26 -26
  143. package/dist/exports/client/index.js.map +4 -4
  144. package/dist/exports/rsc/index.d.ts +3 -3
  145. package/dist/exports/rsc/index.d.ts.map +1 -1
  146. package/dist/exports/rsc/index.js +3 -3
  147. package/dist/exports/rsc/index.js.map +1 -1
  148. package/dist/forms/Form/mergeServerFormState.d.ts.map +1 -1
  149. package/dist/forms/Form/mergeServerFormState.js +101 -24
  150. package/dist/forms/Form/mergeServerFormState.js.map +1 -1
  151. package/dist/icons/TableView/index.d.ts +3 -0
  152. package/dist/icons/TableView/index.d.ts.map +1 -0
  153. package/dist/icons/TableView/index.js +16 -0
  154. package/dist/icons/TableView/index.js.map +1 -0
  155. package/dist/providers/Hierarchy/index.d.ts.map +1 -1
  156. package/dist/providers/Hierarchy/index.js +29 -8
  157. package/dist/providers/Hierarchy/index.js.map +1 -1
  158. package/dist/providers/Hierarchy/types.d.ts +10 -5
  159. package/dist/providers/Hierarchy/types.d.ts.map +1 -1
  160. package/dist/providers/Hierarchy/types.js.map +1 -1
  161. package/dist/providers/SidebarTabs/index.d.ts +19 -0
  162. package/dist/providers/SidebarTabs/index.d.ts.map +1 -0
  163. package/dist/providers/SidebarTabs/index.js +24 -0
  164. package/dist/providers/SidebarTabs/index.js.map +1 -0
  165. package/dist/styles.css +1 -1
  166. package/dist/views/Edit/index.d.ts.map +1 -1
  167. package/dist/views/Edit/index.js +12 -3
  168. package/dist/views/Edit/index.js.map +1 -1
  169. package/dist/views/HierarchyList/DocumentListSelection/index.d.ts.map +1 -1
  170. package/dist/views/HierarchyList/DocumentListSelection/index.js +147 -86
  171. package/dist/views/HierarchyList/DocumentListSelection/index.js.map +1 -1
  172. package/dist/views/HierarchyList/HierarchyListHeader/index.js +7 -6
  173. package/dist/views/HierarchyList/HierarchyListHeader/index.js.map +1 -1
  174. package/dist/views/HierarchyList/HierarchyTable/index.d.ts +7 -3
  175. package/dist/views/HierarchyList/HierarchyTable/index.d.ts.map +1 -1
  176. package/dist/views/HierarchyList/HierarchyTable/index.js +19 -18
  177. package/dist/views/HierarchyList/HierarchyTable/index.js.map +1 -1
  178. package/dist/views/HierarchyList/index.d.ts.map +1 -1
  179. package/dist/views/HierarchyList/index.js +3 -1
  180. package/dist/views/HierarchyList/index.js.map +1 -1
  181. package/package.json +4 -4
  182. package/dist/elements/HierarchyButton/index.d.ts.map +0 -1
  183. package/dist/elements/HierarchyButton/index.js.map +0 -1
  184. package/dist/elements/HierarchyButton/index.server.d.ts.map +0 -1
  185. package/dist/elements/HierarchyButton/index.server.js.map +0 -1
  186. package/dist/elements/HierarchyColumnBrowser/Column/index.d.ts.map +0 -1
  187. package/dist/elements/HierarchyColumnBrowser/Column/index.js.map +0 -1
  188. package/dist/elements/HierarchyColumnBrowser/ColumnItem/index.d.ts.map +0 -1
  189. package/dist/elements/HierarchyColumnBrowser/ColumnItem/index.js.map +0 -1
  190. package/dist/elements/HierarchyColumnBrowser/index.d.ts.map +0 -1
  191. package/dist/elements/HierarchyColumnBrowser/index.js.map +0 -1
  192. package/dist/elements/HierarchyColumnBrowser/types.d.ts.map +0 -1
  193. package/dist/elements/HierarchyColumnBrowser/types.js.map +0 -1
  194. package/dist/elements/HierarchyDrawer/Drawer/index.d.ts.map +0 -1
  195. package/dist/elements/HierarchyDrawer/Drawer/index.js.map +0 -1
  196. package/dist/elements/HierarchyDrawer/fetchAncestorPath.d.ts.map +0 -1
  197. package/dist/elements/HierarchyDrawer/fetchAncestorPath.js.map +0 -1
  198. package/dist/elements/HierarchyDrawer/index.d.ts.map +0 -1
  199. package/dist/elements/HierarchyDrawer/index.js.map +0 -1
  200. package/dist/elements/HierarchyDrawer/types.d.ts.map +0 -1
  201. package/dist/elements/HierarchyDrawer/types.js.map +0 -1
  202. package/dist/elements/HierarchyField/SelectedHierarchies.d.ts.map +0 -1
  203. package/dist/elements/HierarchyField/SelectedHierarchies.js.map +0 -1
  204. package/dist/elements/HierarchyField/index.client.d.ts.map +0 -1
  205. package/dist/elements/HierarchyField/index.client.js.map +0 -1
  206. package/dist/elements/HierarchyField/index.server.d.ts.map +0 -1
  207. package/dist/elements/HierarchyField/index.server.js.map +0 -1
  208. package/dist/elements/HierarchySearch/HierarchySearchInput.d.ts.map +0 -1
  209. package/dist/elements/HierarchySearch/HierarchySearchInput.js.map +0 -1
  210. package/dist/elements/HierarchySearch/HierarchySearchResultItem.d.ts.map +0 -1
  211. package/dist/elements/HierarchySearch/HierarchySearchResultItem.js.map +0 -1
  212. package/dist/elements/HierarchySearch/HierarchySearchResults.d.ts.map +0 -1
  213. package/dist/elements/HierarchySearch/HierarchySearchResults.js.map +0 -1
  214. package/dist/elements/HierarchySearch/index.d.ts.map +0 -1
  215. package/dist/elements/HierarchySearch/index.js.map +0 -1
  216. package/dist/elements/HierarchySearch/types.d.ts.map +0 -1
  217. package/dist/elements/HierarchySearch/types.js.map +0 -1
  218. package/dist/elements/HierarchySearch/useHierarchySearch.d.ts.map +0 -1
  219. package/dist/elements/HierarchySearch/useHierarchySearch.js.map +0 -1
  220. package/dist/elements/HierarchyTree/HierarchySidebarTab.d.ts.map +0 -1
  221. package/dist/elements/HierarchyTree/HierarchySidebarTab.js +0 -156
  222. package/dist/elements/HierarchyTree/HierarchySidebarTab.js.map +0 -1
  223. package/dist/elements/HierarchyTree/HierarchySidebarTab.server.d.ts.map +0 -1
  224. package/dist/elements/HierarchyTree/HierarchySidebarTab.server.js.map +0 -1
  225. package/dist/elements/HierarchyTree/LoadMore/LoadMoreButton.d.ts.map +0 -1
  226. package/dist/elements/HierarchyTree/LoadMore/LoadMoreButton.js +0 -36
  227. package/dist/elements/HierarchyTree/LoadMore/LoadMoreButton.js.map +0 -1
  228. package/dist/elements/HierarchyTree/LoadMore/index.d.ts.map +0 -1
  229. package/dist/elements/HierarchyTree/LoadMore/index.js +0 -29
  230. package/dist/elements/HierarchyTree/LoadMore/index.js.map +0 -1
  231. package/dist/elements/HierarchyTree/LoadMore/index.scss +0 -26
  232. package/dist/elements/HierarchyTree/TreeConnector.d.ts.map +0 -1
  233. package/dist/elements/HierarchyTree/TreeConnector.js.map +0 -1
  234. package/dist/elements/HierarchyTree/TreeFocusContext.d.ts.map +0 -1
  235. package/dist/elements/HierarchyTree/TreeFocusContext.js.map +0 -1
  236. package/dist/elements/HierarchyTree/TreeNode/index.d.ts +0 -5
  237. package/dist/elements/HierarchyTree/TreeNode/index.d.ts.map +0 -1
  238. package/dist/elements/HierarchyTree/TreeNode/index.js +0 -201
  239. package/dist/elements/HierarchyTree/TreeNode/index.js.map +0 -1
  240. package/dist/elements/HierarchyTree/TreeNode/index.scss +0 -99
  241. package/dist/elements/HierarchyTree/index.d.ts.map +0 -1
  242. package/dist/elements/HierarchyTree/index.js +0 -64
  243. package/dist/elements/HierarchyTree/index.js.map +0 -1
  244. package/dist/elements/HierarchyTree/index.scss +0 -42
  245. package/dist/elements/HierarchyTree/types.d.ts +0 -55
  246. package/dist/elements/HierarchyTree/types.d.ts.map +0 -1
  247. package/dist/elements/HierarchyTree/types.js.map +0 -1
  248. package/dist/elements/HierarchyTree/useChildren.d.ts +0 -26
  249. package/dist/elements/HierarchyTree/useChildren.d.ts.map +0 -1
  250. package/dist/elements/HierarchyTree/useChildren.js +0 -150
  251. package/dist/elements/HierarchyTree/useChildren.js.map +0 -1
  252. package/dist/elements/HierarchyTree/useTreeState.d.ts +0 -9
  253. package/dist/elements/HierarchyTree/useTreeState.d.ts.map +0 -1
  254. package/dist/elements/HierarchyTree/useTreeState.js +0 -50
  255. package/dist/elements/HierarchyTree/useTreeState.js.map +0 -1
  256. package/dist/elements/HydrateHierarchyProvider/index.d.ts +0 -4
  257. package/dist/elements/HydrateHierarchyProvider/index.d.ts.map +0 -1
  258. package/dist/elements/HydrateHierarchyProvider/index.js +0 -67
  259. package/dist/elements/HydrateHierarchyProvider/index.js.map +0 -1
  260. package/dist/elements/MoveMany/index.d.ts.map +0 -1
  261. package/dist/elements/MoveMany/index.js.map +0 -1
  262. package/dist/elements/Tree/LoadMore/LoadMoreButton.d.ts +0 -8
  263. package/dist/elements/Tree/LoadMore/LoadMoreButton.d.ts.map +0 -1
  264. package/dist/elements/Tree/LoadMore/LoadMoreButton.js.map +0 -1
  265. package/dist/elements/Tree/LoadMore/index.d.ts +0 -12
  266. package/dist/elements/Tree/LoadMore/index.d.ts.map +0 -1
  267. package/dist/elements/Tree/LoadMore/index.js.map +0 -1
  268. package/dist/elements/Tree/TreeConnector.d.ts +0 -7
  269. package/dist/elements/Tree/TreeConnector.d.ts.map +0 -1
  270. package/dist/elements/Tree/TreeConnector.js +0 -23
  271. package/dist/elements/Tree/TreeConnector.js.map +0 -1
  272. package/dist/elements/Tree/TreeFocusContext.d.ts +0 -28
  273. package/dist/elements/Tree/TreeFocusContext.d.ts.map +0 -1
  274. package/dist/elements/Tree/TreeFocusContext.js +0 -140
  275. package/dist/elements/Tree/TreeFocusContext.js.map +0 -1
  276. package/dist/elements/Tree/TreeNode/index.d.ts +0 -5
  277. package/dist/elements/Tree/TreeNode/index.d.ts.map +0 -1
  278. package/dist/elements/Tree/TreeNode/index.js.map +0 -1
  279. package/dist/elements/Tree/index.d.ts +0 -5
  280. package/dist/elements/Tree/index.d.ts.map +0 -1
  281. package/dist/elements/Tree/index.js +0 -258
  282. package/dist/elements/Tree/index.js.map +0 -1
  283. package/dist/elements/Tree/types.d.ts.map +0 -1
  284. package/dist/elements/Tree/types.js +0 -2
  285. package/dist/elements/Tree/types.js.map +0 -1
  286. package/dist/elements/Tree/useChildren.d.ts +0 -25
  287. package/dist/elements/Tree/useChildren.d.ts.map +0 -1
  288. package/dist/elements/Tree/useChildren.js.map +0 -1
  289. package/dist/exports/client/chunk-SH42NW5R.js +0 -29
  290. /package/dist/elements/{HierarchyColumnBrowser → Hierarchy/ColumnBrowser}/Column/index.d.ts +0 -0
  291. /package/dist/elements/{HierarchyColumnBrowser → Hierarchy/ColumnBrowser}/ColumnItem/index.d.ts +0 -0
  292. /package/dist/elements/{HierarchyColumnBrowser → Hierarchy/ColumnBrowser}/index.scss +0 -0
  293. /package/dist/elements/{HierarchyColumnBrowser → Hierarchy/ColumnBrowser}/types.js +0 -0
  294. /package/dist/elements/{HierarchyButton → Hierarchy/DocHeaderButton}/index.d.ts +0 -0
  295. /package/dist/elements/{HierarchyButton → Hierarchy/DocHeaderButton}/index.scss +0 -0
  296. /package/dist/elements/{HierarchyButton → Hierarchy/DocHeaderButton}/index.server.d.ts +0 -0
  297. /package/dist/elements/{HierarchyDrawer → Hierarchy/Drawer}/fetchAncestorPath.d.ts +0 -0
  298. /package/dist/elements/{HierarchyDrawer → Hierarchy/Drawer}/fetchAncestorPath.js +0 -0
  299. /package/dist/elements/{HierarchyDrawer → Hierarchy}/Drawer/index.scss +0 -0
  300. /package/dist/elements/{HierarchyDrawer → Hierarchy/Drawer}/types.js +0 -0
  301. /package/dist/elements/{HierarchyField → Hierarchy/Field}/SelectedHierarchies.d.ts +0 -0
  302. /package/dist/elements/{HierarchyField → Hierarchy/Field}/index.client.d.ts +0 -0
  303. /package/dist/elements/{HierarchyField → Hierarchy/Field}/index.server.d.ts +0 -0
  304. /package/dist/elements/{HierarchySearch → Hierarchy/Search}/HierarchySearchInput.d.ts +0 -0
  305. /package/dist/elements/{HierarchySearch → Hierarchy/Search}/HierarchySearchResultItem.d.ts +0 -0
  306. /package/dist/elements/{HierarchySearch → Hierarchy/Search}/HierarchySearchResultItem.js +0 -0
  307. /package/dist/elements/{HierarchySearch → Hierarchy/Search}/HierarchySearchResults.d.ts +0 -0
  308. /package/dist/elements/{HierarchySearch → Hierarchy/Search}/index.d.ts +0 -0
  309. /package/dist/elements/{HierarchySearch → Hierarchy/Search}/types.d.ts +0 -0
  310. /package/dist/elements/{HierarchySearch → Hierarchy/Search}/types.js +0 -0
  311. /package/dist/elements/{HierarchySearch → Hierarchy/Search}/useHierarchySearch.d.ts +0 -0
  312. /package/dist/elements/{HierarchyTree → Hierarchy/Tree}/HierarchySidebarTab.server.d.ts +0 -0
  313. /package/dist/elements/{HierarchyTree → Hierarchy/Tree}/LoadMore/LoadMoreButton.d.ts +0 -0
  314. /package/dist/elements/{HierarchyTree → Hierarchy/Tree}/LoadMore/index.d.ts +0 -0
  315. /package/dist/elements/{Tree → Hierarchy/Tree}/LoadMore/index.scss +0 -0
  316. /package/dist/elements/{HierarchyTree → Hierarchy/Tree}/TreeConnector.d.ts +0 -0
  317. /package/dist/elements/{HierarchyTree → Hierarchy/Tree}/TreeConnector.js +0 -0
  318. /package/dist/elements/{HierarchyTree → Hierarchy/Tree}/TreeFocusContext.d.ts +0 -0
  319. /package/dist/elements/{HierarchyTree → Hierarchy/Tree}/TreeFocusContext.js +0 -0
  320. /package/dist/elements/{HierarchyTree → Hierarchy/Tree}/types.js +0 -0
  321. /package/dist/exports/client/{DatePicker-CL2EGBVQ.js.map → DatePicker-T2DMDMM5.js.map} +0 -0
@@ -1,8 +1,8 @@
1
1
  export { FieldDiffContainer } from '../../elements/FieldDiffContainer/index.js';
2
2
  export { FieldDiffLabel } from '../../elements/FieldDiffLabel/index.js';
3
- export { HierarchyButton } from '../../elements/HierarchyButton/index.server.js';
4
- export { HierarchyField } from '../../elements/HierarchyField/index.server.js';
5
- export { HierarchySidebarTabServer } from '../../elements/HierarchyTree/HierarchySidebarTab.server.js';
3
+ export { HierarchyButton } from '../../elements/Hierarchy/DocHeaderButton/index.server.js';
4
+ export { HierarchyField } from '../../elements/Hierarchy/Field/index.server.js';
5
+ export { HierarchySidebarTabServer } from '../../elements/Hierarchy/Tree/HierarchySidebarTab.server.js';
6
6
  export { escapeDiffHTML, getHTMLDiffComponents, unescapeDiffHTML, } from '../../elements/HTMLDiff/index.js';
7
7
  export { _internal_renderFieldHandler } from '../../forms/fieldSchemasToFormState/serverFunctions/renderFieldServerFn.js';
8
8
  export { File } from '../../graphics/File/index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/exports/rsc/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,4CAA4C,CAAA;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAA;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,gDAAgD,CAAA;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,+CAA+C,CAAA;AAC9E,OAAO,EAAE,yBAAyB,EAAE,MAAM,4DAA4D,CAAA;AACtG,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,kCAAkC,CAAA;AACzC,OAAO,EAAE,4BAA4B,EAAE,MAAM,4EAA4E,CAAA;AACzH,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AACtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAA;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAA;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAA;AAChE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAA;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAA;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAA;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/exports/rsc/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,4CAA4C,CAAA;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAA;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,0DAA0D,CAAA;AAC1F,OAAO,EAAE,cAAc,EAAE,MAAM,gDAAgD,CAAA;AAC/E,OAAO,EAAE,yBAAyB,EAAE,MAAM,6DAA6D,CAAA;AACvG,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,kCAAkC,CAAA;AACzC,OAAO,EAAE,4BAA4B,EAAE,MAAM,4EAA4E,CAAA;AACzH,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AACtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAA;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAA;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAA;AAChE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAA;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAA;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAA;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA"}
@@ -1,8 +1,8 @@
1
1
  export { FieldDiffContainer } from '../../elements/FieldDiffContainer/index.js';
2
2
  export { FieldDiffLabel } from '../../elements/FieldDiffLabel/index.js';
3
- export { HierarchyButton } from '../../elements/HierarchyButton/index.server.js';
4
- export { HierarchyField } from '../../elements/HierarchyField/index.server.js';
5
- export { HierarchySidebarTabServer } from '../../elements/HierarchyTree/HierarchySidebarTab.server.js';
3
+ export { HierarchyButton } from '../../elements/Hierarchy/DocHeaderButton/index.server.js';
4
+ export { HierarchyField } from '../../elements/Hierarchy/Field/index.server.js';
5
+ export { HierarchySidebarTabServer } from '../../elements/Hierarchy/Tree/HierarchySidebarTab.server.js';
6
6
  export { escapeDiffHTML, getHTMLDiffComponents, unescapeDiffHTML } from '../../elements/HTMLDiff/index.js';
7
7
  export { _internal_renderFieldHandler } from '../../forms/fieldSchemasToFormState/serverFunctions/renderFieldServerFn.js';
8
8
  export { File } from '../../graphics/File/index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["FieldDiffContainer","FieldDiffLabel","HierarchyButton","HierarchyField","HierarchySidebarTabServer","escapeDiffHTML","getHTMLDiffComponents","unescapeDiffHTML","_internal_renderFieldHandler","File","CheckIcon","copyDataFromLocaleHandler","getColumns","handleLivePreview","handlePreview","renderFilters","renderTable","resolveFilterOptions","upsertPreferences","CollectionCards"],"sources":["../../../src/exports/rsc/index.ts"],"sourcesContent":["export { FieldDiffContainer } from '../../elements/FieldDiffContainer/index.js'\nexport { FieldDiffLabel } from '../../elements/FieldDiffLabel/index.js'\nexport { HierarchyButton } from '../../elements/HierarchyButton/index.server.js'\nexport { HierarchyField } from '../../elements/HierarchyField/index.server.js'\nexport { HierarchySidebarTabServer } from '../../elements/HierarchyTree/HierarchySidebarTab.server.js'\nexport {\n escapeDiffHTML,\n getHTMLDiffComponents,\n unescapeDiffHTML,\n} from '../../elements/HTMLDiff/index.js'\nexport { _internal_renderFieldHandler } from '../../forms/fieldSchemasToFormState/serverFunctions/renderFieldServerFn.js'\nexport { File } from '../../graphics/File/index.js'\nexport { CheckIcon } from '../../icons/Check/index.js'\nexport { copyDataFromLocaleHandler } from '../../utilities/copyDataFromLocale.js'\nexport { getColumns } from '../../utilities/getColumns.js'\nexport { handleLivePreview } from '../../utilities/handleLivePreview.js'\nexport { handlePreview } from '../../utilities/handlePreview.js'\nexport { renderFilters, renderTable } from '../../utilities/renderTable.js'\nexport { resolveFilterOptions } from '../../utilities/resolveFilterOptions.js'\nexport { upsertPreferences } from '../../utilities/upsertPreferences.js'\nexport { CollectionCards } from '../../widgets/CollectionCards/index.js'\n"],"mappings":"AAAA,SAASA,kBAAkB,QAAQ;AACnC,SAASC,cAAc,QAAQ;AAC/B,SAASC,eAAe,QAAQ;AAChC,SAASC,cAAc,QAAQ;AAC/B,SAASC,yBAAyB,QAAQ;AAC1C,SACEC,cAAc,EACdC,qBAAqB,EACrBC,gBAAgB,QACX;AACP,SAASC,4BAA4B,QAAQ;AAC7C,SAASC,IAAI,QAAQ;AACrB,SAASC,SAAS,QAAQ;AAC1B,SAASC,yBAAyB,QAAQ;AAC1C,SAASC,UAAU,QAAQ;AAC3B,SAASC,iBAAiB,QAAQ;AAClC,SAASC,aAAa,QAAQ;AAC9B,SAASC,aAAa,EAAEC,WAAW,QAAQ;AAC3C,SAASC,oBAAoB,QAAQ;AACrC,SAASC,iBAAiB,QAAQ;AAClC,SAASC,eAAe,QAAQ","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["FieldDiffContainer","FieldDiffLabel","HierarchyButton","HierarchyField","HierarchySidebarTabServer","escapeDiffHTML","getHTMLDiffComponents","unescapeDiffHTML","_internal_renderFieldHandler","File","CheckIcon","copyDataFromLocaleHandler","getColumns","handleLivePreview","handlePreview","renderFilters","renderTable","resolveFilterOptions","upsertPreferences","CollectionCards"],"sources":["../../../src/exports/rsc/index.ts"],"sourcesContent":["export { FieldDiffContainer } from '../../elements/FieldDiffContainer/index.js'\nexport { FieldDiffLabel } from '../../elements/FieldDiffLabel/index.js'\nexport { HierarchyButton } from '../../elements/Hierarchy/DocHeaderButton/index.server.js'\nexport { HierarchyField } from '../../elements/Hierarchy/Field/index.server.js'\nexport { HierarchySidebarTabServer } from '../../elements/Hierarchy/Tree/HierarchySidebarTab.server.js'\nexport {\n escapeDiffHTML,\n getHTMLDiffComponents,\n unescapeDiffHTML,\n} from '../../elements/HTMLDiff/index.js'\nexport { _internal_renderFieldHandler } from '../../forms/fieldSchemasToFormState/serverFunctions/renderFieldServerFn.js'\nexport { File } from '../../graphics/File/index.js'\nexport { CheckIcon } from '../../icons/Check/index.js'\nexport { copyDataFromLocaleHandler } from '../../utilities/copyDataFromLocale.js'\nexport { getColumns } from '../../utilities/getColumns.js'\nexport { handleLivePreview } from '../../utilities/handleLivePreview.js'\nexport { handlePreview } from '../../utilities/handlePreview.js'\nexport { renderFilters, renderTable } from '../../utilities/renderTable.js'\nexport { resolveFilterOptions } from '../../utilities/resolveFilterOptions.js'\nexport { upsertPreferences } from '../../utilities/upsertPreferences.js'\nexport { CollectionCards } from '../../widgets/CollectionCards/index.js'\n"],"mappings":"AAAA,SAASA,kBAAkB,QAAQ;AACnC,SAASC,cAAc,QAAQ;AAC/B,SAASC,eAAe,QAAQ;AAChC,SAASC,cAAc,QAAQ;AAC/B,SAASC,yBAAyB,QAAQ;AAC1C,SACEC,cAAc,EACdC,qBAAqB,EACrBC,gBAAgB,QACX;AACP,SAASC,4BAA4B,QAAQ;AAC7C,SAASC,IAAI,QAAQ;AACrB,SAASC,SAAS,QAAQ;AAC1B,SAASC,yBAAyB,QAAQ;AAC1C,SAASC,UAAU,QAAQ;AAC3B,SAASC,iBAAiB,QAAQ;AAClC,SAASC,aAAa,QAAQ;AAC9B,SAASC,aAAa,EAAEC,WAAW,QAAQ;AAC3C,SAASC,oBAAoB,QAAQ;AACrC,SAASC,iBAAiB,QAAQ;AAClC,SAASC,eAAe,QAAQ","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"mergeServerFormState.d.ts","sourceRoot":"","sources":["../../../src/forms/Form/mergeServerFormState.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAIxC;;;GAGG;AACH,MAAM,MAAM,YAAY,GACpB;IACE;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B,GACD,OAAO,CAAA;AAEX,KAAK,IAAI,GAAG;IACV,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,YAAY,CAAC,EAAE,SAAS,CAAA;IACxB,aAAa,EAAE,SAAS,CAAA;CACzB,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,mDAI9B,IAAI,KAAG,SA8GT,CAAA"}
1
+ {"version":3,"file":"mergeServerFormState.d.ts","sourceRoot":"","sources":["../../../src/forms/Form/mergeServerFormState.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAIxC;;;GAGG;AACH,MAAM,MAAM,YAAY,GACpB;IACE;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B,GACD,OAAO,CAAA;AAEX,KAAK,IAAI,GAAG;IACV,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,YAAY,CAAC,EAAE,SAAS,CAAA;IACxB,aAAa,EAAE,SAAS,CAAA;CACzB,CAAA;AA6CD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,mDAI9B,IAAI,KAAG,SAwJT,CAAA"}
@@ -1,6 +1,41 @@
1
1
  'use client';
2
2
 
3
3
  import { dequal } from 'dequal/lite'; // lite: no need for Map and Set support
4
+ /**
5
+ * Parses an array field path to extract the array path, row index, and field path.
6
+ * Handles nested arrays by finding the deepest numeric index.
7
+ *
8
+ * @param path - The field path to parse (e.g., 'array.1.text' or 'blocks.0.items.1.title')
9
+ * @returns Object with arrayPath, rowIndex, and fieldPath, or null if not an array field
10
+ *
11
+ * @example
12
+ * parseArrayFieldPath('array.1.text')
13
+ * // Returns: { arrayPath: 'array', rowIndex: 1, fieldPath: 'text' }
14
+ *
15
+ * @example
16
+ * parseArrayFieldPath('blocks.0.items.1.title')
17
+ * // Returns: { arrayPath: 'blocks.0.items', rowIndex: 1, fieldPath: 'title' }
18
+ */
19
+ function parseArrayFieldPath(path) {
20
+ const segments = path.split('.');
21
+ // Find the last numeric index (indicates array row)
22
+ let lastNumericIndex = -1;
23
+ for (let i = segments.length - 1; i >= 0; i--) {
24
+ if (/^\d+$/.test(segments[i])) {
25
+ lastNumericIndex = i;
26
+ break;
27
+ }
28
+ }
29
+ // Not an array field if no numeric index or nothing after it
30
+ if (lastNumericIndex === -1 || lastNumericIndex === segments.length - 1) {
31
+ return null;
32
+ }
33
+ return {
34
+ arrayPath: segments.slice(0, lastNumericIndex).join('.'),
35
+ fieldPath: segments.slice(lastNumericIndex + 1).join('.'),
36
+ rowIndex: parseInt(segments[lastNumericIndex], 10)
37
+ };
38
+ }
4
39
  /**
5
40
  * This function receives form state from the server and intelligently merges it into the client state.
6
41
  * The server contains extra properties that the client may not have, e.g. custom components and error states.
@@ -31,9 +66,32 @@ export const mergeServerFormState = ({
31
66
  * a. accept all values when explicitly requested, e.g. on submit
32
67
  * b. only accept values for unmodified fields, e.g. on autosave
33
68
  */
34
- const shouldAcceptValue = incomingField.addedByServer || acceptValues === true || typeof acceptValues === 'object' && acceptValues !== null &&
69
+ let shouldAcceptValue = incomingField.addedByServer || acceptValues === true || typeof acceptValues === 'object' && acceptValues !== null &&
35
70
  // Note: Must be explicitly `false`, allow `null` or `undefined` to mean true
36
71
  acceptValues.overrideLocalChanges === false && !currentState[path]?.isModified;
72
+ /**
73
+ * For array row fields, verify the row IDs match at the given index before accepting
74
+ * server values. If rows were reordered or deleted while the request was in-flight,
75
+ * the same index may refer to different rows, and accepting the server value would
76
+ * overwrite the wrong row's data.
77
+ *
78
+ * This guard only applies during autosave. On explicit save (acceptValues === true),
79
+ * the server response is authoritative and this check is bypassed.
80
+ */
81
+ if (shouldAcceptValue && !incomingField.addedByServer && acceptValues !== true) {
82
+ const parsed = parseArrayFieldPath(path);
83
+ if (parsed) {
84
+ const {
85
+ arrayPath,
86
+ rowIndex
87
+ } = parsed;
88
+ const clientRowId = currentState[arrayPath]?.rows?.[rowIndex]?.id;
89
+ const serverRowId = incomingState[arrayPath]?.rows?.[rowIndex]?.id;
90
+ if (clientRowId === undefined || serverRowId && clientRowId !== serverRowId) {
91
+ shouldAcceptValue = false;
92
+ }
93
+ }
94
+ }
37
95
  let sanitizedIncomingField = incomingField;
38
96
  if (!shouldAcceptValue) {
39
97
  /**
@@ -60,32 +118,51 @@ export const mergeServerFormState = ({
60
118
  * For example, the server response could come back with a row which has been deleted on the client
61
119
  * Loop over the incoming rows, if it exists in client side form state, merge in any new properties from the server
62
120
  * Note: read `currentState` and not `newState` here, as the `rows` property have already been merged above
121
+ *
122
+ * On explicit save (acceptValues === true), the server is authoritative - accept server row order.
123
+ * On autosave (acceptValues !== true), the client is source of truth - use ID-based matching.
63
124
  */
64
125
  if (Array.isArray(incomingField.rows) && path in currentState) {
65
- newState[path].rows = [...(currentState[path]?.rows || [])]; // shallow copy to avoid mutating the original array
66
- incomingField.rows.forEach(row => {
67
- const indexInCurrentState = currentState[path].rows?.findIndex(existingRow => existingRow.id === row.id);
68
- if (indexInCurrentState > -1) {
69
- newState[path].rows[indexInCurrentState] = {
70
- ...currentState[path].rows[indexInCurrentState],
71
- ...row
72
- };
73
- } else if (row.addedByServer) {
74
- /**
75
- * Note: This is a known limitation of computed array and block rows
76
- * If a new row was added by the server, we append it to the _end_ of this array
77
- * This is because the client is the source of truth, and it has arrays ordered in a certain position
78
- * For example, the user may have re-ordered rows client-side while a long running request is processing
79
- * This means that we _cannot_ slice a new row into the second position on the server, for example
80
- * By the time it gets back to the client, its index is stale
81
- */
82
- const newRow = {
83
- ...row
84
- };
85
- delete newRow.addedByServer;
86
- newState[path].rows.push(newRow);
126
+ if (acceptValues === true) {
127
+ // Explicit save: server is authoritative, use index-based merging
128
+ newState[path].rows = incomingField.rows.map((serverRow, index) => ({
129
+ ...(currentState[path]?.rows?.[index] || {}),
130
+ ...serverRow
131
+ }));
132
+ } else {
133
+ // Autosave: client is source of truth, use ID-based matching
134
+ newState[path].rows = [...(currentState[path]?.rows || [])]; // shallow copy to avoid mutating the original array
135
+ incomingField.rows.forEach(row => {
136
+ const indexInCurrentState = currentState[path].rows?.findIndex(existingRow => existingRow.id === row.id);
137
+ if (indexInCurrentState > -1) {
138
+ newState[path].rows[indexInCurrentState] = {
139
+ ...currentState[path].rows[indexInCurrentState],
140
+ ...row
141
+ };
142
+ } else if (row.addedByServer) {
143
+ /**
144
+ * Note: This is a known limitation of computed array and block rows
145
+ * If a new row was added by the server, we append it to the _end_ of this array
146
+ * This is because the client is the source of truth, and it has arrays ordered in a certain position
147
+ * For example, the user may have re-ordered rows client-side while a long running request is processing
148
+ * This means that we _cannot_ slice a new row into the second position on the server, for example
149
+ * By the time it gets back to the client, its index is stale
150
+ */
151
+ const newRow = {
152
+ ...row
153
+ };
154
+ delete newRow.addedByServer;
155
+ newState[path].rows.push(newRow);
156
+ }
157
+ });
158
+ /**
159
+ * Sync the value field to match the actual row count after merging.
160
+ * Client is source of truth for row count when rows were added/removed during the request.
161
+ */
162
+ if ('value' in incomingField && newState[path].rows.length !== incomingField.value) {
163
+ newState[path].value = newState[path].rows.length;
87
164
  }
88
- });
165
+ }
89
166
  }
90
167
  // If `valid` is `undefined`, mark it as `true`
91
168
  if (incomingField.valid !== false) {
@@ -1 +1 @@
1
- {"version":3,"file":"mergeServerFormState.js","names":["dequal","mergeServerFormState","acceptValues","currentState","incomingState","newState","path","incomingField","Object","entries","addedByServer","shouldAcceptValue","overrideLocalChanges","isModified","sanitizedIncomingField","initialValue","value","rest","errorPaths","Array","isArray","rows","forEach","row","indexInCurrentState","findIndex","existingRow","id","newRow","push","valid","passesCondition","blocksFilterOptions"],"sources":["../../../src/forms/Form/mergeServerFormState.ts"],"sourcesContent":["'use client'\nimport type { FormState } from 'payload'\n\nimport { dequal } from 'dequal/lite' // lite: no need for Map and Set support\n\n/**\n * If true, will accept all values from the server, overriding any current values in local state.\n * Can also provide an options object for more granular control.\n */\nexport type AcceptValues =\n | {\n /**\n * When `false`, will accept the values from the server _UNLESS_ the value has been modified locally since the request was made.\n * This is useful for autosave, for example, where hooks may have modified the field's value on the server while you were still making changes.\n * @default undefined\n */\n overrideLocalChanges?: boolean\n }\n | boolean\n\ntype Args = {\n acceptValues?: AcceptValues\n currentState?: FormState\n incomingState: FormState\n}\n\n/**\n * This function receives form state from the server and intelligently merges it into the client state.\n * The server contains extra properties that the client may not have, e.g. custom components and error states.\n * We typically do not want to merge properties that rely on user input, however, such as values, unless explicitly requested.\n * Doing this would cause the client to lose any local changes to those fields.\n *\n * Note: Local state is the source of truth, not the new server state that is getting merged in. This is critical for array row\n * manipulation specifically, where the user may have added, removed, or reordered rows while a request was pending and is now stale.\n *\n * This function applies some defaults, as well as cleans up the server response in preparation for the client.\n * e.g. it will set `valid` and `passesCondition` to true if undefined, and remove `addedByServer` from the response.\n */\nexport const mergeServerFormState = ({\n acceptValues,\n currentState = {},\n incomingState,\n}: Args): FormState => {\n const newState = { ...currentState }\n\n for (const [path, incomingField] of Object.entries(incomingState || {})) {\n if (!(path in currentState) && !incomingField.addedByServer) {\n continue\n }\n\n /**\n * If it's a new field added by the server, always accept the value.\n * Otherwise:\n * a. accept all values when explicitly requested, e.g. on submit\n * b. only accept values for unmodified fields, e.g. on autosave\n */\n const shouldAcceptValue =\n incomingField.addedByServer ||\n acceptValues === true ||\n (typeof acceptValues === 'object' &&\n acceptValues !== null &&\n // Note: Must be explicitly `false`, allow `null` or `undefined` to mean true\n acceptValues.overrideLocalChanges === false &&\n !currentState[path]?.isModified)\n\n let sanitizedIncomingField = incomingField\n\n if (!shouldAcceptValue) {\n /**\n * Note: do not delete properties off `incomingField` as this will mutate the original object\n * Instead, omit them from the destructured object by excluding specific keys\n * This will also ensure we don't set `undefined` into the result unnecessarily\n */\n const { initialValue, value, ...rest } = incomingField\n sanitizedIncomingField = rest\n }\n\n newState[path] = {\n ...currentState[path],\n ...sanitizedIncomingField,\n }\n\n if (\n currentState[path] &&\n 'errorPaths' in currentState[path] &&\n !('errorPaths' in incomingField)\n ) {\n newState[path].errorPaths = []\n }\n\n /**\n * Deeply merge the rows array to ensure changes to local state are not lost while the request was pending\n * For example, the server response could come back with a row which has been deleted on the client\n * Loop over the incoming rows, if it exists in client side form state, merge in any new properties from the server\n * Note: read `currentState` and not `newState` here, as the `rows` property have already been merged above\n */\n if (Array.isArray(incomingField.rows) && path in currentState) {\n newState[path].rows = [...(currentState[path]?.rows || [])] // shallow copy to avoid mutating the original array\n\n incomingField.rows.forEach((row) => {\n const indexInCurrentState = currentState[path].rows?.findIndex(\n (existingRow) => existingRow.id === row.id,\n )\n\n if (indexInCurrentState > -1) {\n newState[path].rows[indexInCurrentState] = {\n ...currentState[path].rows[indexInCurrentState],\n ...row,\n }\n } else if (row.addedByServer) {\n /**\n * Note: This is a known limitation of computed array and block rows\n * If a new row was added by the server, we append it to the _end_ of this array\n * This is because the client is the source of truth, and it has arrays ordered in a certain position\n * For example, the user may have re-ordered rows client-side while a long running request is processing\n * This means that we _cannot_ slice a new row into the second position on the server, for example\n * By the time it gets back to the client, its index is stale\n */\n const newRow = { ...row }\n delete newRow.addedByServer\n newState[path].rows.push(newRow)\n }\n })\n }\n\n // If `valid` is `undefined`, mark it as `true`\n if (incomingField.valid !== false) {\n newState[path].valid = true\n }\n\n // If `passesCondition` is `undefined`, mark it as `true`\n if (incomingField.passesCondition !== false) {\n newState[path].passesCondition = true\n }\n\n /**\n * Undefined values for blocksFilterOptions coming back should be treated as \"all blocks allowed\" and\n * should always be merged in.\n * Without this, an undefined value coming back will incorrectly be ignored, and the previous filter will remain.\n */\n if (!incomingField.blocksFilterOptions) {\n delete newState[path].blocksFilterOptions\n }\n\n // Strip away the `addedByServer` property from the client\n // This will prevent it from being passed back to the server\n delete newState[path].addedByServer\n }\n\n // Return the original object reference if the state is unchanged\n // This will avoid unnecessary re-renders and dependency updates\n return dequal(newState, currentState) ? currentState : newState\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"mergeServerFormState.js","names":["dequal","parseArrayFieldPath","path","segments","split","lastNumericIndex","i","length","test","arrayPath","slice","join","fieldPath","rowIndex","parseInt","mergeServerFormState","acceptValues","currentState","incomingState","newState","incomingField","Object","entries","addedByServer","shouldAcceptValue","overrideLocalChanges","isModified","parsed","clientRowId","rows","id","serverRowId","undefined","sanitizedIncomingField","initialValue","value","rest","errorPaths","Array","isArray","map","serverRow","index","forEach","row","indexInCurrentState","findIndex","existingRow","newRow","push","valid","passesCondition","blocksFilterOptions"],"sources":["../../../src/forms/Form/mergeServerFormState.ts"],"sourcesContent":["'use client'\nimport type { FormState } from 'payload'\n\nimport { dequal } from 'dequal/lite' // lite: no need for Map and Set support\n\n/**\n * If true, will accept all values from the server, overriding any current values in local state.\n * Can also provide an options object for more granular control.\n */\nexport type AcceptValues =\n | {\n /**\n * When `false`, will accept the values from the server _UNLESS_ the value has been modified locally since the request was made.\n * This is useful for autosave, for example, where hooks may have modified the field's value on the server while you were still making changes.\n * @default undefined\n */\n overrideLocalChanges?: boolean\n }\n | boolean\n\ntype Args = {\n acceptValues?: AcceptValues\n currentState?: FormState\n incomingState: FormState\n}\n\n/**\n * Parses an array field path to extract the array path, row index, and field path.\n * Handles nested arrays by finding the deepest numeric index.\n *\n * @param path - The field path to parse (e.g., 'array.1.text' or 'blocks.0.items.1.title')\n * @returns Object with arrayPath, rowIndex, and fieldPath, or null if not an array field\n *\n * @example\n * parseArrayFieldPath('array.1.text')\n * // Returns: { arrayPath: 'array', rowIndex: 1, fieldPath: 'text' }\n *\n * @example\n * parseArrayFieldPath('blocks.0.items.1.title')\n * // Returns: { arrayPath: 'blocks.0.items', rowIndex: 1, fieldPath: 'title' }\n */\nfunction parseArrayFieldPath(path: string): {\n arrayPath: string\n fieldPath: string\n rowIndex: number\n} | null {\n const segments = path.split('.')\n\n // Find the last numeric index (indicates array row)\n let lastNumericIndex = -1\n for (let i = segments.length - 1; i >= 0; i--) {\n if (/^\\d+$/.test(segments[i])) {\n lastNumericIndex = i\n break\n }\n }\n\n // Not an array field if no numeric index or nothing after it\n if (lastNumericIndex === -1 || lastNumericIndex === segments.length - 1) {\n return null\n }\n\n return {\n arrayPath: segments.slice(0, lastNumericIndex).join('.'),\n fieldPath: segments.slice(lastNumericIndex + 1).join('.'),\n rowIndex: parseInt(segments[lastNumericIndex], 10),\n }\n}\n\n/**\n * This function receives form state from the server and intelligently merges it into the client state.\n * The server contains extra properties that the client may not have, e.g. custom components and error states.\n * We typically do not want to merge properties that rely on user input, however, such as values, unless explicitly requested.\n * Doing this would cause the client to lose any local changes to those fields.\n *\n * Note: Local state is the source of truth, not the new server state that is getting merged in. This is critical for array row\n * manipulation specifically, where the user may have added, removed, or reordered rows while a request was pending and is now stale.\n *\n * This function applies some defaults, as well as cleans up the server response in preparation for the client.\n * e.g. it will set `valid` and `passesCondition` to true if undefined, and remove `addedByServer` from the response.\n */\nexport const mergeServerFormState = ({\n acceptValues,\n currentState = {},\n incomingState,\n}: Args): FormState => {\n const newState = { ...currentState }\n\n for (const [path, incomingField] of Object.entries(incomingState || {})) {\n if (!(path in currentState) && !incomingField.addedByServer) {\n continue\n }\n\n /**\n * If it's a new field added by the server, always accept the value.\n * Otherwise:\n * a. accept all values when explicitly requested, e.g. on submit\n * b. only accept values for unmodified fields, e.g. on autosave\n */\n let shouldAcceptValue =\n incomingField.addedByServer ||\n acceptValues === true ||\n (typeof acceptValues === 'object' &&\n acceptValues !== null &&\n // Note: Must be explicitly `false`, allow `null` or `undefined` to mean true\n acceptValues.overrideLocalChanges === false &&\n !currentState[path]?.isModified)\n\n /**\n * For array row fields, verify the row IDs match at the given index before accepting\n * server values. If rows were reordered or deleted while the request was in-flight,\n * the same index may refer to different rows, and accepting the server value would\n * overwrite the wrong row's data.\n *\n * This guard only applies during autosave. On explicit save (acceptValues === true),\n * the server response is authoritative and this check is bypassed.\n */\n if (shouldAcceptValue && !incomingField.addedByServer && acceptValues !== true) {\n const parsed = parseArrayFieldPath(path)\n if (parsed) {\n const { arrayPath, rowIndex } = parsed\n const clientRowId = currentState[arrayPath]?.rows?.[rowIndex]?.id\n const serverRowId = incomingState[arrayPath]?.rows?.[rowIndex]?.id\n\n if (clientRowId === undefined || (serverRowId && clientRowId !== serverRowId)) {\n shouldAcceptValue = false\n }\n }\n }\n\n let sanitizedIncomingField = incomingField\n\n if (!shouldAcceptValue) {\n /**\n * Note: do not delete properties off `incomingField` as this will mutate the original object\n * Instead, omit them from the destructured object by excluding specific keys\n * This will also ensure we don't set `undefined` into the result unnecessarily\n */\n const { initialValue, value, ...rest } = incomingField\n sanitizedIncomingField = rest\n }\n\n newState[path] = {\n ...currentState[path],\n ...sanitizedIncomingField,\n }\n\n if (\n currentState[path] &&\n 'errorPaths' in currentState[path] &&\n !('errorPaths' in incomingField)\n ) {\n newState[path].errorPaths = []\n }\n\n /**\n * Deeply merge the rows array to ensure changes to local state are not lost while the request was pending\n * For example, the server response could come back with a row which has been deleted on the client\n * Loop over the incoming rows, if it exists in client side form state, merge in any new properties from the server\n * Note: read `currentState` and not `newState` here, as the `rows` property have already been merged above\n *\n * On explicit save (acceptValues === true), the server is authoritative - accept server row order.\n * On autosave (acceptValues !== true), the client is source of truth - use ID-based matching.\n */\n if (Array.isArray(incomingField.rows) && path in currentState) {\n if (acceptValues === true) {\n // Explicit save: server is authoritative, use index-based merging\n newState[path].rows = incomingField.rows.map((serverRow, index) => ({\n ...(currentState[path]?.rows?.[index] || {}),\n ...serverRow,\n }))\n } else {\n // Autosave: client is source of truth, use ID-based matching\n newState[path].rows = [...(currentState[path]?.rows || [])] // shallow copy to avoid mutating the original array\n\n incomingField.rows.forEach((row) => {\n const indexInCurrentState = currentState[path].rows?.findIndex(\n (existingRow) => existingRow.id === row.id,\n )\n\n if (indexInCurrentState > -1) {\n newState[path].rows[indexInCurrentState] = {\n ...currentState[path].rows[indexInCurrentState],\n ...row,\n }\n } else if (row.addedByServer) {\n /**\n * Note: This is a known limitation of computed array and block rows\n * If a new row was added by the server, we append it to the _end_ of this array\n * This is because the client is the source of truth, and it has arrays ordered in a certain position\n * For example, the user may have re-ordered rows client-side while a long running request is processing\n * This means that we _cannot_ slice a new row into the second position on the server, for example\n * By the time it gets back to the client, its index is stale\n */\n const newRow = { ...row }\n delete newRow.addedByServer\n newState[path].rows.push(newRow)\n }\n })\n\n /**\n * Sync the value field to match the actual row count after merging.\n * Client is source of truth for row count when rows were added/removed during the request.\n */\n if ('value' in incomingField && newState[path].rows.length !== incomingField.value) {\n newState[path].value = newState[path].rows.length\n }\n }\n }\n\n // If `valid` is `undefined`, mark it as `true`\n if (incomingField.valid !== false) {\n newState[path].valid = true\n }\n\n // If `passesCondition` is `undefined`, mark it as `true`\n if (incomingField.passesCondition !== false) {\n newState[path].passesCondition = true\n }\n\n /**\n * Undefined values for blocksFilterOptions coming back should be treated as \"all blocks allowed\" and\n * should always be merged in.\n * Without this, an undefined value coming back will incorrectly be ignored, and the previous filter will remain.\n */\n if (!incomingField.blocksFilterOptions) {\n delete newState[path].blocksFilterOptions\n }\n\n // Strip away the `addedByServer` property from the client\n // This will prevent it from being passed back to the server\n delete newState[path].addedByServer\n }\n\n // Return the original object reference if the state is unchanged\n // This will avoid unnecessary re-renders and dependency updates\n return dequal(newState, currentState) ? currentState : newState\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ export declare const TableViewIcon: () => React.JSX.Element;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/icons/TableView/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,eAAO,MAAM,aAAa,yBAazB,CAAA"}
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ export const TableViewIcon = () => {
4
+ return /*#__PURE__*/_jsx("svg", {
5
+ className: "icon icon--table-view",
6
+ fill: "currentColor",
7
+ height: "20",
8
+ viewBox: "0 0 16 16",
9
+ width: "20",
10
+ xmlns: "http://www.w3.org/2000/svg",
11
+ children: /*#__PURE__*/_jsx("path", {
12
+ d: "M2 10.4078H5.27273V13H2.90874C2.30955 12.9998 2 12.6052 2 12.3207V10.4078ZM5.27273 9.29666H2V6.70334H5.27273V9.29666ZM14 9.29666H6.36364V6.70334H14V9.29666ZM14 12.3207C14 12.6052 13.6905 12.9998 13.0913 13H6.36364V10.4078H14V12.3207ZM2 3.67925C2 3.39484 2.30955 3.00016 2.90874 3H5.27273V5.59223H2V3.67925ZM14 5.59223H6.36364V3H13.0913C13.6905 3.00016 14 3.39484 14 3.67925V5.59223Z"
13
+ })
14
+ });
15
+ };
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["React","TableViewIcon","_jsx","className","fill","height","viewBox","width","xmlns","d"],"sources":["../../../src/icons/TableView/index.tsx"],"sourcesContent":["import React from 'react'\n\nexport const TableViewIcon = () => {\n return (\n <svg\n className=\"icon icon--table-view\"\n fill=\"currentColor\"\n height=\"20\"\n viewBox=\"0 0 16 16\"\n width=\"20\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M2 10.4078H5.27273V13H2.90874C2.30955 12.9998 2 12.6052 2 12.3207V10.4078ZM5.27273 9.29666H2V6.70334H5.27273V9.29666ZM14 9.29666H6.36364V6.70334H14V9.29666ZM14 12.3207C14 12.6052 13.6905 12.9998 13.0913 13H6.36364V10.4078H14V12.3207ZM2 3.67925C2 3.39484 2.30955 3.00016 2.90874 3H5.27273V5.59223H2V3.67925ZM14 5.59223H6.36364V3H13.0913C13.6905 3.00016 14 3.39484 14 3.67925V5.59223Z\" />\n </svg>\n )\n}\n"],"mappings":";AAAA,OAAOA,KAAA,MAAW;AAElB,OAAO,MAAMC,aAAA,GAAgBA,CAAA;EAC3B,oBACEC,IAAA,CAAC;IACCC,SAAA,EAAU;IACVC,IAAA,EAAK;IACLC,MAAA,EAAO;IACPC,OAAA,EAAQ;IACRC,KAAA,EAAM;IACNC,KAAA,EAAM;cAEN,aAAAN,IAAA,CAAC;MAAKO,CAAA,EAAE;;;AAGd","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/Hierarchy/index.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAoD,MAAM,OAAO,CAAA;AAExE,OAAO,KAAK,EAEV,qBAAqB,EAGrB,sBAAsB,EAEvB,MAAM,YAAY,CAAA;AAQnB,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAuY9D,CAAA;AAED,eAAO,MAAM,YAAY,QAAO,qBAM/B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/Hierarchy/index.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAoD,MAAM,OAAO,CAAA;AAExE,OAAO,KAAK,EAEV,qBAAqB,EAGrB,sBAAsB,EAEvB,MAAM,YAAY,CAAA;AAQnB,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CA0Z9D,CAAA;AAED,eAAO,MAAM,YAAY,QAAO,qBAM/B,CAAA"}
@@ -25,6 +25,7 @@ export const HierarchyProvider = ({
25
25
  serverURL
26
26
  }
27
27
  } = useConfig();
28
+ const [baseFilter, setBaseFilter] = useState(null);
28
29
  const [collectionSlug, setCollectionSlug] = useState(null);
29
30
  const [viewCollectionSlug, setViewCollectionSlug] = useState(null);
30
31
  const [parent, setParent] = useState(null);
@@ -38,7 +39,7 @@ export const HierarchyProvider = ({
38
39
  const [selectedFiltersByCollection, setSelectedFiltersByCollection] = useState(() => new Map());
39
40
  const [isLoadingMore, setIsLoadingMore] = useState(false);
40
41
  const [loadingNodeId, setLoadingNodeId] = useState(null);
41
- const [treeRefreshKey, setTreeRefreshKey] = useState(0);
42
+ const [treeRefreshKeys, setTreeRefreshKeys] = useState(() => new Map());
42
43
  const getNodeChildren = useCallback(parentId => {
43
44
  if (!collectionSlug) {
44
45
  return [];
@@ -58,6 +59,7 @@ export const HierarchyProvider = ({
58
59
  const hydrate = useCallback(data => {
59
60
  const {
60
61
  allowedCollections: newAllowedCollections,
62
+ baseFilter: newBaseFilter,
61
63
  collectionSlug: slug,
62
64
  expandedNodes: newExpandedNodes,
63
65
  parent: newParent,
@@ -70,6 +72,9 @@ export const HierarchyProvider = ({
70
72
  viewCollectionSlug: newViewCollectionSlug
71
73
  } = data;
72
74
  setCollectionSlug(slug);
75
+ if (newBaseFilter !== undefined) {
76
+ setBaseFilter(newBaseFilter ?? null);
77
+ }
73
78
  if (newViewCollectionSlug) {
74
79
  setViewCollectionSlug(newViewCollectionSlug);
75
80
  }
@@ -95,18 +100,24 @@ export const HierarchyProvider = ({
95
100
  setTreeCache(prev => {
96
101
  const newCache = new Map(prev);
97
102
  const existingEntry = newCache.get(slug);
98
- if (existingEntry) {
103
+ // If baseFilter is provided, replace cache entirely (tenant changed)
104
+ // Otherwise merge to support incremental loading
105
+ if (newBaseFilter !== undefined || !existingEntry) {
106
+ newCache.set(slug, {
107
+ ...treeData,
108
+ baseFilter: newBaseFilter ?? null
109
+ });
110
+ } else {
99
111
  const existingDocIds = new Set(existingEntry.docs.map(doc_0 => doc_0.id));
100
112
  const newDocs = treeData.docs.filter(doc_1 => !existingDocIds.has(doc_1.id));
101
113
  newCache.set(slug, {
114
+ baseFilter: existingEntry.baseFilter,
102
115
  docs: [...existingEntry.docs, ...newDocs],
103
116
  loadedParents: {
104
117
  ...existingEntry.loadedParents,
105
118
  ...treeData.loadedParents
106
119
  }
107
120
  });
108
- } else {
109
- newCache.set(slug, treeData);
110
121
  }
111
122
  return newCache;
112
123
  });
@@ -277,6 +288,7 @@ export const HierarchyProvider = ({
277
288
  }
278
289
  }, [api, collectionSlug, isLoadingMore, parentFieldName, serverURL, treeCache, treeLimit, useAsTitle]);
279
290
  const reset = useCallback(() => {
291
+ setBaseFilter(null);
280
292
  setCollectionSlug(null);
281
293
  setViewCollectionSlug(null);
282
294
  setParent(null);
@@ -290,14 +302,23 @@ export const HierarchyProvider = ({
290
302
  setIsLoadingMore(false);
291
303
  setLoadingNodeId(null);
292
304
  }, []);
293
- const refreshTree = useCallback(() => {
294
- setTreeCache(new Map());
295
- setTreeRefreshKey(prev_5 => prev_5 + 1);
305
+ const refreshTree = useCallback(slug_4 => {
306
+ setTreeCache(prev_5 => {
307
+ const next = new Map(prev_5);
308
+ next.delete(slug_4);
309
+ return next;
310
+ });
311
+ setTreeRefreshKeys(prev_6 => {
312
+ const next_0 = new Map(prev_6);
313
+ next_0.set(slug_4, (next_0.get(slug_4) ?? 0) + 1);
314
+ return next_0;
315
+ });
296
316
  }, []);
297
317
  const expandedNodes = collectionSlug && expandedNodesByCollection.has(collectionSlug) ? expandedNodesByCollection.get(collectionSlug) : new Set();
298
318
  const selectedFilters = collectionSlug && selectedFiltersByCollection.has(collectionSlug) ? selectedFiltersByCollection.get(collectionSlug) : [];
299
319
  const value = {
300
320
  allowedCollections,
321
+ baseFilter,
301
322
  collectionSlug,
302
323
  expandedNodes,
303
324
  getExpandedNodesForCollection,
@@ -317,7 +338,7 @@ export const HierarchyProvider = ({
317
338
  toggleNode,
318
339
  toggleNodeForCollection,
319
340
  treeLimit,
320
- treeRefreshKey,
341
+ treeRefreshKeys,
321
342
  typeFieldName,
322
343
  useAsTitle,
323
344
  viewCollectionSlug
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["useRouter","DEFAULT_HIERARCHY_TREE_LIMIT","formatAdminURL","PREFERENCE_KEYS","qs","React","createContext","use","useCallback","useState","useDebouncedCallback","useConfig","usePreferences","HierarchyContext","undefined","HierarchyProvider","children","setPreference","router","config","routes","admin","adminRoute","api","serverURL","collectionSlug","setCollectionSlug","viewCollectionSlug","setViewCollectionSlug","parent","setParent","parentFieldName","setParentFieldName","treeLimit","setTreeLimit","typeFieldName","setTypeFieldName","useAsTitle","setUseAsTitle","allowedCollections","setAllowedCollections","treeCache","setTreeCache","Map","expandedNodesByCollection","setExpandedNodesByCollection","selectedFiltersByCollection","setSelectedFiltersByCollection","isLoadingMore","setIsLoadingMore","loadingNodeId","setLoadingNodeId","treeRefreshKey","setTreeRefreshKey","getNodeChildren","parentId","cache","get","docs","filter","doc","docParentId","String","hydrate","data","newAllowedCollections","slug","expandedNodes","newExpandedNodes","newParent","newParentFieldName","selectedFilters","newSelectedFilters","treeData","newTreeLimit","newTypeFieldName","newUseAsTitle","newViewCollectionSlug","prev","newCache","existingEntry","existingDocIds","Set","map","id","newDocs","has","set","loadedParents","length","newMap","existingExpanded","mergedExpanded","savePreferencesDebounced","preferenceKey","HIERARCHY_TREE","currentExpanded","currentFilters","Array","from","expanded","filters","toggleNodeForCollection","newExpanded","delete","add","toggleNode","getExpandedNodesForCollection","getTreeDataForCollection","setSelectedFilters","selectParent","url","path","push","refresh","loadMoreChildren","parentKey","parentMeta","hasMore","currentChildren","nextPage","Math","floor","where","or","exists","equals","queryString","stringify","limit","page","sort","addQueryPrefix","apiRoute","response","fetch","credentials","ok","Error","json","uniqueNewDocs","hasNextPage","totalDocs","reset","refreshTree","value","_jsx","useHierarchy","context"],"sources":["../../../src/providers/Hierarchy/index.tsx"],"sourcesContent":["'use client'\n\nimport type { TypeWithID } from 'payload'\n\nimport { useRouter } from 'next/navigation.js'\nimport { DEFAULT_HIERARCHY_TREE_LIMIT, formatAdminURL, PREFERENCE_KEYS } from 'payload/shared'\nimport * as qs from 'qs-esm'\nimport React, { createContext, use, useCallback, useState } from 'react'\n\nimport type {\n AllowedCollection,\n HierarchyContextValue,\n HierarchyDocument,\n HierarchyHydrateData,\n HierarchyProviderProps,\n HierarchyTreeCacheEntry,\n} from './types.js'\n\nimport { useDebouncedCallback } from '../../hooks/useDebouncedCallback.js'\nimport { useConfig } from '../Config/index.js'\nimport { usePreferences } from '../Preferences/index.js'\n\nconst HierarchyContext = createContext<HierarchyContextValue | undefined>(undefined)\n\nexport const HierarchyProvider: React.FC<HierarchyProviderProps> = ({ children }) => {\n const { setPreference } = usePreferences()\n const router = useRouter()\n const {\n config: {\n routes: { admin: adminRoute, api },\n serverURL,\n },\n } = useConfig()\n\n const [collectionSlug, setCollectionSlug] = useState<null | string>(null)\n const [viewCollectionSlug, setViewCollectionSlug] = useState<null | string>(null)\n const [parent, setParent] = useState<null | (Record<string, unknown> & TypeWithID)>(null)\n const [parentFieldName, setParentFieldName] = useState<string>('')\n const [treeLimit, setTreeLimit] = useState<number>(DEFAULT_HIERARCHY_TREE_LIMIT)\n const [typeFieldName, setTypeFieldName] = useState<null | string>(null)\n const [useAsTitle, setUseAsTitle] = useState<null | string>(null)\n const [allowedCollections, setAllowedCollections] = useState<AllowedCollection[] | null>(null)\n\n const [treeCache, setTreeCache] = useState<Map<string, HierarchyTreeCacheEntry>>(() => new Map())\n const [expandedNodesByCollection, setExpandedNodesByCollection] = useState<\n Map<string, Set<number | string>>\n >(() => new Map())\n const [selectedFiltersByCollection, setSelectedFiltersByCollection] = useState<\n Map<string, string[]>\n >(() => new Map())\n const [isLoadingMore, setIsLoadingMore] = useState<boolean>(false)\n const [loadingNodeId, setLoadingNodeId] = useState<null | number | string>(null)\n const [treeRefreshKey, setTreeRefreshKey] = useState<number>(0)\n\n const getNodeChildren = useCallback(\n (parentId: null | number | string): HierarchyDocument[] => {\n if (!collectionSlug) {\n return []\n }\n\n const cache = treeCache.get(collectionSlug)\n if (!cache) {\n return []\n }\n\n return cache.docs.filter((doc) => {\n const docParentId = doc[parentFieldName]\n if (parentId === null) {\n return docParentId === null || docParentId === undefined\n }\n return docParentId !== null && String(docParentId) === String(parentId)\n })\n },\n [collectionSlug, parentFieldName, treeCache],\n )\n\n const hydrate = useCallback((data: HierarchyHydrateData) => {\n const {\n allowedCollections: newAllowedCollections,\n collectionSlug: slug,\n expandedNodes: newExpandedNodes,\n parent: newParent,\n parentFieldName: newParentFieldName,\n selectedFilters: newSelectedFilters,\n treeData,\n treeLimit: newTreeLimit,\n typeFieldName: newTypeFieldName,\n useAsTitle: newUseAsTitle,\n viewCollectionSlug: newViewCollectionSlug,\n } = data\n\n setCollectionSlug(slug)\n\n if (newViewCollectionSlug) {\n setViewCollectionSlug(newViewCollectionSlug)\n }\n\n if (newAllowedCollections) {\n setAllowedCollections(newAllowedCollections)\n }\n\n if (newParentFieldName) {\n setParentFieldName(newParentFieldName)\n }\n\n if (newTreeLimit !== undefined) {\n setTreeLimit(newTreeLimit)\n }\n\n if (newTypeFieldName !== undefined) {\n setTypeFieldName(newTypeFieldName)\n }\n\n if (newParent !== undefined) {\n setParent(newParent)\n }\n\n if (newUseAsTitle !== undefined) {\n setUseAsTitle(newUseAsTitle)\n }\n\n if (treeData) {\n setTreeCache((prev) => {\n const newCache = new Map(prev)\n const existingEntry = newCache.get(slug)\n\n if (existingEntry) {\n const existingDocIds = new Set(existingEntry.docs.map((doc) => doc.id))\n const newDocs = treeData.docs.filter((doc) => !existingDocIds.has(doc.id))\n\n newCache.set(slug, {\n docs: [...existingEntry.docs, ...newDocs],\n loadedParents: {\n ...existingEntry.loadedParents,\n ...treeData.loadedParents,\n },\n })\n } else {\n newCache.set(slug, treeData)\n }\n\n return newCache\n })\n }\n\n if (newExpandedNodes && newExpandedNodes.length > 0) {\n setExpandedNodesByCollection((prev) => {\n const newMap = new Map(prev)\n const existingExpanded = newMap.get(slug) || new Set()\n const mergedExpanded = new Set([...existingExpanded, ...newExpandedNodes])\n newMap.set(slug, mergedExpanded)\n return newMap\n })\n }\n\n if (newSelectedFilters) {\n setSelectedFiltersByCollection((prev) => {\n const newMap = new Map(prev)\n newMap.set(slug, newSelectedFilters)\n return newMap\n })\n }\n }, [])\n\n const savePreferencesDebounced = useDebouncedCallback(\n async (slug: string, data: { expanded?: Set<number | string>; filters?: string[] }) => {\n const preferenceKey = `${PREFERENCE_KEYS.HIERARCHY_TREE}-${slug}`\n const currentExpanded = expandedNodesByCollection.get(slug) || new Set()\n const currentFilters = selectedFiltersByCollection.get(slug) || []\n\n await setPreference(preferenceKey, {\n expandedNodes: Array.from(data.expanded ?? currentExpanded),\n selectedFilters: data.filters ?? currentFilters,\n })\n },\n 500,\n )\n\n const toggleNodeForCollection = useCallback(\n (slug: string, id: number | string) => {\n setExpandedNodesByCollection((prev) => {\n const newMap = new Map(prev)\n const currentExpanded = newMap.get(slug) || new Set()\n const newExpanded = new Set(currentExpanded)\n\n if (newExpanded.has(id)) {\n newExpanded.delete(id)\n } else {\n newExpanded.add(id)\n }\n\n newMap.set(slug, newExpanded)\n savePreferencesDebounced(slug, { expanded: newExpanded })\n return newMap\n })\n },\n [savePreferencesDebounced],\n )\n\n const toggleNode = useCallback(\n (id: number | string) => {\n if (!collectionSlug) {\n return\n }\n toggleNodeForCollection(collectionSlug, id)\n },\n [collectionSlug, toggleNodeForCollection],\n )\n\n const getExpandedNodesForCollection = useCallback(\n (slug: string): Set<number | string> => {\n return expandedNodesByCollection.get(slug) || new Set()\n },\n [expandedNodesByCollection],\n )\n\n const getTreeDataForCollection = useCallback(\n (slug: string) => {\n return treeCache.get(slug) || null\n },\n [treeCache],\n )\n\n const setSelectedFilters = useCallback(\n (filters: string[]) => {\n if (!collectionSlug) {\n return\n }\n\n setSelectedFiltersByCollection((prev) => {\n const newMap = new Map(prev)\n newMap.set(collectionSlug, filters)\n savePreferencesDebounced(collectionSlug, { filters })\n return newMap\n })\n },\n [collectionSlug, savePreferencesDebounced],\n )\n\n const selectParent = useCallback(\n (id: null | number | string) => {\n if (!collectionSlug) {\n return\n }\n\n const url = formatAdminURL({\n adminRoute,\n path: `/collections/${collectionSlug}${id !== null ? `?parent=${id}` : ''}`,\n })\n router.push(url)\n router.refresh()\n },\n [adminRoute, collectionSlug, router],\n )\n\n const loadMoreChildren = useCallback(\n async (parentId: null | number | string): Promise<void> => {\n if (!collectionSlug || isLoadingMore) {\n return\n }\n\n const cache = treeCache.get(collectionSlug)\n if (!cache) {\n return\n }\n\n const parentKey = parentId === null ? 'root' : String(parentId)\n const parentMeta = cache.loadedParents[parentKey]\n if (!parentMeta || !parentMeta.hasMore) {\n return\n }\n\n setIsLoadingMore(true)\n setLoadingNodeId(parentId)\n\n try {\n const currentChildren = cache.docs.filter((doc) => {\n const docParentId = doc[parentFieldName]\n if (parentId === null) {\n return docParentId === null || docParentId === undefined\n }\n return docParentId !== null && String(docParentId) === String(parentId)\n })\n\n const nextPage = Math.floor(currentChildren.length / treeLimit) + 1\n\n const where =\n parentId === null\n ? {\n or: [\n { [parentFieldName]: { exists: false } },\n { [parentFieldName]: { equals: null } },\n ],\n }\n : { [parentFieldName]: { equals: parentId } }\n\n const queryString = qs.stringify(\n { limit: treeLimit, page: nextPage, sort: useAsTitle ?? 'id', where },\n { addQueryPrefix: true },\n )\n const url = formatAdminURL({\n apiRoute: api,\n path: `/${collectionSlug}${queryString}`,\n serverURL,\n })\n const response = await fetch(url, {\n credentials: 'include',\n })\n\n if (!response.ok) {\n throw new Error('Failed to fetch more children')\n }\n\n const data = await response.json()\n const newDocs = data.docs || []\n\n setTreeCache((prev) => {\n const newCache = new Map(prev)\n const existingEntry = newCache.get(collectionSlug)\n\n if (existingEntry) {\n const existingDocIds = new Set(existingEntry.docs.map((doc) => doc.id))\n const uniqueNewDocs = newDocs.filter((doc) => !existingDocIds.has(doc.id))\n\n newCache.set(collectionSlug, {\n docs: [...existingEntry.docs, ...uniqueNewDocs],\n loadedParents: {\n ...existingEntry.loadedParents,\n [parentKey]: {\n hasMore: data.hasNextPage || false,\n totalDocs: data.totalDocs || 0,\n },\n },\n })\n }\n\n return newCache\n })\n } catch {\n // Failed to load more children - silently fail\n } finally {\n setIsLoadingMore(false)\n setLoadingNodeId(null)\n }\n },\n [\n api,\n collectionSlug,\n isLoadingMore,\n parentFieldName,\n serverURL,\n treeCache,\n treeLimit,\n useAsTitle,\n ],\n )\n\n const reset = useCallback(() => {\n setCollectionSlug(null)\n setViewCollectionSlug(null)\n setParent(null)\n setParentFieldName('')\n setTreeLimit(DEFAULT_HIERARCHY_TREE_LIMIT)\n setTypeFieldName(null)\n setUseAsTitle(null)\n setTreeCache(new Map())\n setExpandedNodesByCollection(new Map())\n setSelectedFiltersByCollection(new Map())\n setIsLoadingMore(false)\n setLoadingNodeId(null)\n }, [])\n\n const refreshTree = useCallback(() => {\n setTreeCache(new Map())\n setTreeRefreshKey((prev) => prev + 1)\n }, [])\n\n const expandedNodes =\n collectionSlug && expandedNodesByCollection.has(collectionSlug)\n ? expandedNodesByCollection.get(collectionSlug)\n : new Set<number | string>()\n\n const selectedFilters =\n collectionSlug && selectedFiltersByCollection.has(collectionSlug)\n ? selectedFiltersByCollection.get(collectionSlug)\n : []\n\n const value: HierarchyContextValue = {\n allowedCollections,\n collectionSlug,\n expandedNodes,\n getExpandedNodesForCollection,\n getNodeChildren,\n getTreeDataForCollection,\n hydrate,\n isLoadingMore,\n loadingNodeId,\n loadMoreChildren,\n parent,\n parentFieldName,\n refreshTree,\n reset,\n selectedFilters,\n selectParent,\n setSelectedFilters,\n toggleNode,\n toggleNodeForCollection,\n treeLimit,\n treeRefreshKey,\n typeFieldName,\n useAsTitle,\n viewCollectionSlug,\n }\n\n return <HierarchyContext value={value}>{children}</HierarchyContext>\n}\n\nexport const useHierarchy = (): HierarchyContextValue => {\n const context = use(HierarchyContext)\n if (!context) {\n throw new Error('useHierarchy must be used within HierarchyProvider')\n }\n return context\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["useRouter","DEFAULT_HIERARCHY_TREE_LIMIT","formatAdminURL","PREFERENCE_KEYS","qs","React","createContext","use","useCallback","useState","useDebouncedCallback","useConfig","usePreferences","HierarchyContext","undefined","HierarchyProvider","children","setPreference","router","config","routes","admin","adminRoute","api","serverURL","baseFilter","setBaseFilter","collectionSlug","setCollectionSlug","viewCollectionSlug","setViewCollectionSlug","parent","setParent","parentFieldName","setParentFieldName","treeLimit","setTreeLimit","typeFieldName","setTypeFieldName","useAsTitle","setUseAsTitle","allowedCollections","setAllowedCollections","treeCache","setTreeCache","Map","expandedNodesByCollection","setExpandedNodesByCollection","selectedFiltersByCollection","setSelectedFiltersByCollection","isLoadingMore","setIsLoadingMore","loadingNodeId","setLoadingNodeId","treeRefreshKeys","setTreeRefreshKeys","getNodeChildren","parentId","cache","get","docs","filter","doc","docParentId","String","hydrate","data","newAllowedCollections","newBaseFilter","slug","expandedNodes","newExpandedNodes","newParent","newParentFieldName","selectedFilters","newSelectedFilters","treeData","newTreeLimit","newTypeFieldName","newUseAsTitle","newViewCollectionSlug","prev","newCache","existingEntry","set","existingDocIds","Set","map","id","newDocs","has","loadedParents","length","newMap","existingExpanded","mergedExpanded","savePreferencesDebounced","preferenceKey","HIERARCHY_TREE","currentExpanded","currentFilters","Array","from","expanded","filters","toggleNodeForCollection","newExpanded","delete","add","toggleNode","getExpandedNodesForCollection","getTreeDataForCollection","setSelectedFilters","selectParent","url","path","push","refresh","loadMoreChildren","parentKey","parentMeta","hasMore","currentChildren","nextPage","Math","floor","where","or","exists","equals","queryString","stringify","limit","page","sort","addQueryPrefix","apiRoute","response","fetch","credentials","ok","Error","json","uniqueNewDocs","hasNextPage","totalDocs","reset","refreshTree","next","value","_jsx","useHierarchy","context"],"sources":["../../../src/providers/Hierarchy/index.tsx"],"sourcesContent":["'use client'\n\nimport type { TypeWithID, Where } from 'payload'\n\nimport { useRouter } from 'next/navigation.js'\nimport { DEFAULT_HIERARCHY_TREE_LIMIT, formatAdminURL, PREFERENCE_KEYS } from 'payload/shared'\nimport * as qs from 'qs-esm'\nimport React, { createContext, use, useCallback, useState } from 'react'\n\nimport type {\n AllowedCollection,\n HierarchyContextValue,\n HierarchyDocument,\n HierarchyHydrateData,\n HierarchyProviderProps,\n HierarchyTreeCacheEntry,\n} from './types.js'\n\nimport { useDebouncedCallback } from '../../hooks/useDebouncedCallback.js'\nimport { useConfig } from '../Config/index.js'\nimport { usePreferences } from '../Preferences/index.js'\n\nconst HierarchyContext = createContext<HierarchyContextValue | undefined>(undefined)\n\nexport const HierarchyProvider: React.FC<HierarchyProviderProps> = ({ children }) => {\n const { setPreference } = usePreferences()\n const router = useRouter()\n const {\n config: {\n routes: { admin: adminRoute, api },\n serverURL,\n },\n } = useConfig()\n\n const [baseFilter, setBaseFilter] = useState<null | Where>(null)\n const [collectionSlug, setCollectionSlug] = useState<null | string>(null)\n const [viewCollectionSlug, setViewCollectionSlug] = useState<null | string>(null)\n const [parent, setParent] = useState<null | (Record<string, unknown> & TypeWithID)>(null)\n const [parentFieldName, setParentFieldName] = useState<string>('')\n const [treeLimit, setTreeLimit] = useState<number>(DEFAULT_HIERARCHY_TREE_LIMIT)\n const [typeFieldName, setTypeFieldName] = useState<null | string>(null)\n const [useAsTitle, setUseAsTitle] = useState<null | string>(null)\n const [allowedCollections, setAllowedCollections] = useState<AllowedCollection[] | null>(null)\n\n const [treeCache, setTreeCache] = useState<Map<string, HierarchyTreeCacheEntry>>(() => new Map())\n const [expandedNodesByCollection, setExpandedNodesByCollection] = useState<\n Map<string, Set<number | string>>\n >(() => new Map())\n const [selectedFiltersByCollection, setSelectedFiltersByCollection] = useState<\n Map<string, string[]>\n >(() => new Map())\n const [isLoadingMore, setIsLoadingMore] = useState<boolean>(false)\n const [loadingNodeId, setLoadingNodeId] = useState<null | number | string>(null)\n const [treeRefreshKeys, setTreeRefreshKeys] = useState<Map<string, number>>(() => new Map())\n\n const getNodeChildren = useCallback(\n (parentId: null | number | string): HierarchyDocument[] => {\n if (!collectionSlug) {\n return []\n }\n\n const cache = treeCache.get(collectionSlug)\n if (!cache) {\n return []\n }\n\n return cache.docs.filter((doc) => {\n const docParentId = doc[parentFieldName]\n if (parentId === null) {\n return docParentId === null || docParentId === undefined\n }\n return docParentId !== null && String(docParentId) === String(parentId)\n })\n },\n [collectionSlug, parentFieldName, treeCache],\n )\n\n const hydrate = useCallback((data: HierarchyHydrateData) => {\n const {\n allowedCollections: newAllowedCollections,\n baseFilter: newBaseFilter,\n collectionSlug: slug,\n expandedNodes: newExpandedNodes,\n parent: newParent,\n parentFieldName: newParentFieldName,\n selectedFilters: newSelectedFilters,\n treeData,\n treeLimit: newTreeLimit,\n typeFieldName: newTypeFieldName,\n useAsTitle: newUseAsTitle,\n viewCollectionSlug: newViewCollectionSlug,\n } = data\n\n setCollectionSlug(slug)\n\n if (newBaseFilter !== undefined) {\n setBaseFilter(newBaseFilter ?? null)\n }\n\n if (newViewCollectionSlug) {\n setViewCollectionSlug(newViewCollectionSlug)\n }\n\n if (newAllowedCollections) {\n setAllowedCollections(newAllowedCollections)\n }\n\n if (newParentFieldName) {\n setParentFieldName(newParentFieldName)\n }\n\n if (newTreeLimit !== undefined) {\n setTreeLimit(newTreeLimit)\n }\n\n if (newTypeFieldName !== undefined) {\n setTypeFieldName(newTypeFieldName)\n }\n\n if (newParent !== undefined) {\n setParent(newParent)\n }\n\n if (newUseAsTitle !== undefined) {\n setUseAsTitle(newUseAsTitle)\n }\n\n if (treeData) {\n setTreeCache((prev) => {\n const newCache = new Map(prev)\n const existingEntry = newCache.get(slug)\n\n // If baseFilter is provided, replace cache entirely (tenant changed)\n // Otherwise merge to support incremental loading\n if (newBaseFilter !== undefined || !existingEntry) {\n newCache.set(slug, { ...treeData, baseFilter: newBaseFilter ?? null })\n } else {\n const existingDocIds = new Set(existingEntry.docs.map((doc) => doc.id))\n const newDocs = treeData.docs.filter((doc) => !existingDocIds.has(doc.id))\n\n newCache.set(slug, {\n baseFilter: existingEntry.baseFilter,\n docs: [...existingEntry.docs, ...newDocs],\n loadedParents: {\n ...existingEntry.loadedParents,\n ...treeData.loadedParents,\n },\n })\n }\n\n return newCache\n })\n }\n\n if (newExpandedNodes && newExpandedNodes.length > 0) {\n setExpandedNodesByCollection((prev) => {\n const newMap = new Map(prev)\n const existingExpanded = newMap.get(slug) || new Set()\n const mergedExpanded = new Set([...existingExpanded, ...newExpandedNodes])\n newMap.set(slug, mergedExpanded)\n return newMap\n })\n }\n\n if (newSelectedFilters) {\n setSelectedFiltersByCollection((prev) => {\n const newMap = new Map(prev)\n newMap.set(slug, newSelectedFilters)\n return newMap\n })\n }\n }, [])\n\n const savePreferencesDebounced = useDebouncedCallback(\n async (slug: string, data: { expanded?: Set<number | string>; filters?: string[] }) => {\n const preferenceKey = `${PREFERENCE_KEYS.HIERARCHY_TREE}-${slug}`\n const currentExpanded = expandedNodesByCollection.get(slug) || new Set()\n const currentFilters = selectedFiltersByCollection.get(slug) || []\n\n await setPreference(preferenceKey, {\n expandedNodes: Array.from(data.expanded ?? currentExpanded),\n selectedFilters: data.filters ?? currentFilters,\n })\n },\n 500,\n )\n\n const toggleNodeForCollection = useCallback(\n (slug: string, id: number | string) => {\n setExpandedNodesByCollection((prev) => {\n const newMap = new Map(prev)\n const currentExpanded = newMap.get(slug) || new Set()\n const newExpanded = new Set(currentExpanded)\n\n if (newExpanded.has(id)) {\n newExpanded.delete(id)\n } else {\n newExpanded.add(id)\n }\n\n newMap.set(slug, newExpanded)\n savePreferencesDebounced(slug, { expanded: newExpanded })\n return newMap\n })\n },\n [savePreferencesDebounced],\n )\n\n const toggleNode = useCallback(\n (id: number | string) => {\n if (!collectionSlug) {\n return\n }\n toggleNodeForCollection(collectionSlug, id)\n },\n [collectionSlug, toggleNodeForCollection],\n )\n\n const getExpandedNodesForCollection = useCallback(\n (slug: string): Set<number | string> => {\n return expandedNodesByCollection.get(slug) || new Set()\n },\n [expandedNodesByCollection],\n )\n\n const getTreeDataForCollection = useCallback(\n (slug: string) => {\n return treeCache.get(slug) || null\n },\n [treeCache],\n )\n\n const setSelectedFilters = useCallback(\n (filters: string[]) => {\n if (!collectionSlug) {\n return\n }\n\n setSelectedFiltersByCollection((prev) => {\n const newMap = new Map(prev)\n newMap.set(collectionSlug, filters)\n savePreferencesDebounced(collectionSlug, { filters })\n return newMap\n })\n },\n [collectionSlug, savePreferencesDebounced],\n )\n\n const selectParent = useCallback(\n (id: null | number | string) => {\n if (!collectionSlug) {\n return\n }\n\n const url = formatAdminURL({\n adminRoute,\n path: `/collections/${collectionSlug}${id !== null ? `?parent=${id}` : ''}`,\n })\n router.push(url)\n router.refresh()\n },\n [adminRoute, collectionSlug, router],\n )\n\n const loadMoreChildren = useCallback(\n async (parentId: null | number | string): Promise<void> => {\n if (!collectionSlug || isLoadingMore) {\n return\n }\n\n const cache = treeCache.get(collectionSlug)\n if (!cache) {\n return\n }\n\n const parentKey = parentId === null ? 'root' : String(parentId)\n const parentMeta = cache.loadedParents[parentKey]\n if (!parentMeta || !parentMeta.hasMore) {\n return\n }\n\n setIsLoadingMore(true)\n setLoadingNodeId(parentId)\n\n try {\n const currentChildren = cache.docs.filter((doc) => {\n const docParentId = doc[parentFieldName]\n if (parentId === null) {\n return docParentId === null || docParentId === undefined\n }\n return docParentId !== null && String(docParentId) === String(parentId)\n })\n\n const nextPage = Math.floor(currentChildren.length / treeLimit) + 1\n\n const where =\n parentId === null\n ? {\n or: [\n { [parentFieldName]: { exists: false } },\n { [parentFieldName]: { equals: null } },\n ],\n }\n : { [parentFieldName]: { equals: parentId } }\n\n const queryString = qs.stringify(\n { limit: treeLimit, page: nextPage, sort: useAsTitle ?? 'id', where },\n { addQueryPrefix: true },\n )\n const url = formatAdminURL({\n apiRoute: api,\n path: `/${collectionSlug}${queryString}`,\n serverURL,\n })\n const response = await fetch(url, {\n credentials: 'include',\n })\n\n if (!response.ok) {\n throw new Error('Failed to fetch more children')\n }\n\n const data = await response.json()\n const newDocs = data.docs || []\n\n setTreeCache((prev) => {\n const newCache = new Map(prev)\n const existingEntry = newCache.get(collectionSlug)\n\n if (existingEntry) {\n const existingDocIds = new Set(existingEntry.docs.map((doc) => doc.id))\n const uniqueNewDocs = newDocs.filter((doc) => !existingDocIds.has(doc.id))\n\n newCache.set(collectionSlug, {\n docs: [...existingEntry.docs, ...uniqueNewDocs],\n loadedParents: {\n ...existingEntry.loadedParents,\n [parentKey]: {\n hasMore: data.hasNextPage || false,\n totalDocs: data.totalDocs || 0,\n },\n },\n })\n }\n\n return newCache\n })\n } catch {\n // Failed to load more children - silently fail\n } finally {\n setIsLoadingMore(false)\n setLoadingNodeId(null)\n }\n },\n [\n api,\n collectionSlug,\n isLoadingMore,\n parentFieldName,\n serverURL,\n treeCache,\n treeLimit,\n useAsTitle,\n ],\n )\n\n const reset = useCallback(() => {\n setBaseFilter(null)\n setCollectionSlug(null)\n setViewCollectionSlug(null)\n setParent(null)\n setParentFieldName('')\n setTreeLimit(DEFAULT_HIERARCHY_TREE_LIMIT)\n setTypeFieldName(null)\n setUseAsTitle(null)\n setTreeCache(new Map())\n setExpandedNodesByCollection(new Map())\n setSelectedFiltersByCollection(new Map())\n setIsLoadingMore(false)\n setLoadingNodeId(null)\n }, [])\n\n const refreshTree = useCallback((slug: string) => {\n setTreeCache((prev) => {\n const next = new Map(prev)\n next.delete(slug)\n return next\n })\n setTreeRefreshKeys((prev) => {\n const next = new Map(prev)\n next.set(slug, (next.get(slug) ?? 0) + 1)\n return next\n })\n }, [])\n\n const expandedNodes =\n collectionSlug && expandedNodesByCollection.has(collectionSlug)\n ? expandedNodesByCollection.get(collectionSlug)\n : new Set<number | string>()\n\n const selectedFilters =\n collectionSlug && selectedFiltersByCollection.has(collectionSlug)\n ? selectedFiltersByCollection.get(collectionSlug)\n : []\n\n const value: HierarchyContextValue = {\n allowedCollections,\n baseFilter,\n collectionSlug,\n expandedNodes,\n getExpandedNodesForCollection,\n getNodeChildren,\n getTreeDataForCollection,\n hydrate,\n isLoadingMore,\n loadingNodeId,\n loadMoreChildren,\n parent,\n parentFieldName,\n refreshTree,\n reset,\n selectedFilters,\n selectParent,\n setSelectedFilters,\n toggleNode,\n toggleNodeForCollection,\n treeLimit,\n treeRefreshKeys,\n typeFieldName,\n useAsTitle,\n viewCollectionSlug,\n }\n\n return <HierarchyContext value={value}>{children}</HierarchyContext>\n}\n\nexport const useHierarchy = (): HierarchyContextValue => {\n const context = use(HierarchyContext)\n if (!context) {\n throw new Error('useHierarchy must be used within HierarchyProvider')\n }\n return context\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,9 +1,10 @@
1
- import type { PaginatedDocs, TypeWithID } from 'payload';
1
+ import type { PaginatedDocs, TypeWithID, Where } from 'payload';
2
2
  export type HierarchyDocument = {
3
3
  [key: string]: unknown;
4
4
  _hasChildren?: boolean;
5
5
  } & TypeWithID;
6
6
  export type HierarchyInitialData = {
7
+ baseFilter?: null | Where;
7
8
  docs: HierarchyDocument[];
8
9
  loadedParents: Record<string, {
9
10
  hasMore: boolean;
@@ -12,6 +13,7 @@ export type HierarchyInitialData = {
12
13
  }>;
13
14
  };
14
15
  export type HierarchyTreeCacheEntry = {
16
+ baseFilter?: null | Where;
15
17
  docs: HierarchyDocument[];
16
18
  loadedParents: Record<string, {
17
19
  hasMore: boolean;
@@ -25,6 +27,7 @@ export type AllowedCollection = {
25
27
  };
26
28
  export type HierarchyHydrateData = {
27
29
  allowedCollections?: AllowedCollection[] | null;
30
+ baseFilter?: null | Where;
28
31
  collectionSlug: string;
29
32
  expandedNodes?: (number | string)[];
30
33
  /** The full data of the current parent (for accessing id, collectionSpecific values, etc.) */
@@ -43,6 +46,7 @@ export type HierarchyHydrateData = {
43
46
  };
44
47
  export type HierarchyContextValue = {
45
48
  allowedCollections: AllowedCollection[] | null;
49
+ baseFilter: null | Where;
46
50
  collectionSlug: null | string;
47
51
  expandedNodes: Set<number | string>;
48
52
  /** Get expanded nodes for a specific collection (use this in tabs to avoid cross-tab state conflicts) */
@@ -57,8 +61,8 @@ export type HierarchyContextValue = {
57
61
  /** The full data of the current parent (for accessing id, collectionSpecific values, etc.) */
58
62
  parent: null | (Record<string, unknown> & TypeWithID);
59
63
  parentFieldName: string;
60
- /** Refresh the tree by clearing cache and incrementing refreshKey to force remount */
61
- refreshTree: () => void;
64
+ /** Refresh the tree for a specific collection by clearing its cache and incrementing its key */
65
+ refreshTree: (collectionSlug: string) => void;
62
66
  reset: () => void;
63
67
  /** Selected collection type filters for the sidebar tree */
64
68
  selectedFilters: string[];
@@ -69,8 +73,8 @@ export type HierarchyContextValue = {
69
73
  /** Toggle node expansion for a specific collection (use this in tabs to avoid cross-tab state conflicts) */
70
74
  toggleNodeForCollection: (collectionSlug: string, id: number | string) => void;
71
75
  treeLimit: number;
72
- /** Key that changes when tree should remount (incremented by refreshTree) */
73
- treeRefreshKey: number;
76
+ /** Per-collection keys that change when refreshTree(slug) is called */
77
+ treeRefreshKeys: Map<string, number>;
74
78
  /** Field name for collection-specific restrictions (e.g., 'hierarchyType') */
75
79
  typeFieldName: null | string;
76
80
  useAsTitle: null | string;
@@ -82,6 +86,7 @@ export type HierarchyProviderProps = {
82
86
  };
83
87
  export type HydrateHierarchyProviderProps = {
84
88
  allowedCollections?: AllowedCollection[] | null;
89
+ baseFilter?: null | Where;
85
90
  collectionSlug: string;
86
91
  expandedNodes?: (number | string)[];
87
92
  /** The full data of the current parent (for accessing id, collectionSpecific values, etc.) */