@multiplatform.one/frappe-ui 7.7.4 → 7.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (670) hide show
  1. package/dist/cjs/ChartCard.native.js.map +1 -1
  2. package/dist/cjs/FileBrowser/AttachLibrary.native.js.map +1 -1
  3. package/dist/cjs/FileBrowser/folderTree.native.js.map +1 -1
  4. package/dist/cjs/FileBrowser/index.native.js.map +1 -1
  5. package/dist/cjs/FileBrowser/types.native.js.map +1 -1
  6. package/dist/cjs/FileBrowser/viewPersistence.native.js.map +1 -1
  7. package/dist/cjs/FormSidebar.native.js.map +1 -1
  8. package/dist/cjs/FrappeAssignment.cjs +1 -0
  9. package/dist/cjs/FrappeAssignment.native.js +1 -0
  10. package/dist/cjs/FrappeAssignment.native.js.map +1 -1
  11. package/dist/cjs/FrappeCalendar.cjs +22 -18
  12. package/dist/cjs/FrappeCalendar.native.js +24 -22
  13. package/dist/cjs/FrappeCalendar.native.js.map +1 -1
  14. package/dist/cjs/FrappeChartCard.cjs +1 -0
  15. package/dist/cjs/FrappeChartCard.native.js +1 -0
  16. package/dist/cjs/FrappeChartCard.native.js.map +1 -1
  17. package/dist/cjs/FrappeConnectionIndicator.native.js.map +1 -1
  18. package/dist/cjs/FrappeDashboard.cjs +1 -0
  19. package/dist/cjs/FrappeDashboard.native.js +1 -0
  20. package/dist/cjs/FrappeDashboard.native.js.map +1 -1
  21. package/dist/cjs/FrappeForm.cjs +3 -2
  22. package/dist/cjs/FrappeForm.native.js +4 -3
  23. package/dist/cjs/FrappeForm.native.js.map +1 -1
  24. package/dist/cjs/FrappeGantt.cjs +27 -35
  25. package/dist/cjs/FrappeGantt.native.js +29 -39
  26. package/dist/cjs/FrappeGantt.native.js.map +1 -1
  27. package/dist/cjs/FrappeImageView.cjs +6 -3
  28. package/dist/cjs/FrappeImageView.native.js +10 -5
  29. package/dist/cjs/FrappeImageView.native.js.map +1 -1
  30. package/dist/cjs/FrappeKPICard.cjs +27 -1
  31. package/dist/cjs/FrappeKPICard.native.js +27 -1
  32. package/dist/cjs/FrappeKPICard.native.js.map +1 -1
  33. package/dist/cjs/FrappeKanban.cjs +18 -18
  34. package/dist/cjs/FrappeKanban.native.js +20 -22
  35. package/dist/cjs/FrappeKanban.native.js.map +1 -1
  36. package/dist/cjs/FrappeLikedBy.cjs +2 -1
  37. package/dist/cjs/FrappeLikedBy.native.js +2 -1
  38. package/dist/cjs/FrappeLikedBy.native.js.map +1 -1
  39. package/dist/cjs/FrappeList.cjs +4 -3
  40. package/dist/cjs/FrappeList.native.js +4 -3
  41. package/dist/cjs/FrappeList.native.js.map +1 -1
  42. package/dist/cjs/FrappeListView.cjs +1 -0
  43. package/dist/cjs/FrappeListView.native.js +1 -0
  44. package/dist/cjs/FrappeListView.native.js.map +1 -1
  45. package/dist/cjs/FrappeProvider.cjs +3 -1
  46. package/dist/cjs/FrappeProvider.native.js +3 -1
  47. package/dist/cjs/FrappeProvider.native.js.map +1 -1
  48. package/dist/cjs/FrappeReconnectIndicator.native.js.map +1 -1
  49. package/dist/cjs/FrappeReportBuilder.cjs +3 -2
  50. package/dist/cjs/FrappeReportBuilder.native.js +3 -2
  51. package/dist/cjs/FrappeReportBuilder.native.js.map +1 -1
  52. package/dist/cjs/FrappeReportView.cjs +2 -1
  53. package/dist/cjs/FrappeReportView.native.js +5 -4
  54. package/dist/cjs/FrappeReportView.native.js.map +1 -1
  55. package/dist/cjs/FrappeTable.cjs +37 -39
  56. package/dist/cjs/FrappeTable.native.js +40 -40
  57. package/dist/cjs/FrappeTable.native.js.map +1 -1
  58. package/dist/cjs/FrappeTreeView.cjs +87 -51
  59. package/dist/cjs/FrappeTreeView.native.js +131 -51
  60. package/dist/cjs/FrappeTreeView.native.js.map +1 -1
  61. package/dist/cjs/SyncErrorNotice.native.js.map +1 -1
  62. package/dist/cjs/commentActions.cjs +1 -1
  63. package/dist/cjs/commentActions.native.js +1 -1
  64. package/dist/cjs/commentActions.native.js.map +1 -1
  65. package/dist/cjs/components/attachments.cjs +1 -0
  66. package/dist/cjs/components/attachments.native.js +1 -0
  67. package/dist/cjs/components/attachments.native.js.map +1 -1
  68. package/dist/cjs/components/tags.cjs +1 -0
  69. package/dist/cjs/components/tags.native.js +1 -0
  70. package/dist/cjs/components/tags.native.js.map +1 -1
  71. package/dist/cjs/components/timeline.cjs +2 -1
  72. package/dist/cjs/components/timeline.native.js +2 -1
  73. package/dist/cjs/components/timeline.native.js.map +1 -1
  74. package/dist/cjs/dependsOn.native.js.map +1 -1
  75. package/dist/cjs/desk/DeskFormPage.native.js.map +1 -1
  76. package/dist/cjs/desk/DeskFormSidebar.cjs +1 -0
  77. package/dist/cjs/desk/DeskFormSidebar.native.js +1 -0
  78. package/dist/cjs/desk/DeskFormSidebar.native.js.map +1 -1
  79. package/dist/cjs/desk/DeskListPage.native.js.map +1 -1
  80. package/dist/cjs/desk/DeskShell.cjs +2 -0
  81. package/dist/cjs/desk/DeskShell.native.js +2 -0
  82. package/dist/cjs/desk/DeskShell.native.js.map +1 -1
  83. package/dist/cjs/desk/DeskSidebar.cjs +1 -0
  84. package/dist/cjs/desk/DeskSidebar.native.js +1 -0
  85. package/dist/cjs/desk/DeskSidebar.native.js.map +1 -1
  86. package/dist/cjs/desk/awesomebar.cjs +2 -1
  87. package/dist/cjs/desk/awesomebar.native.js +2 -1
  88. package/dist/cjs/desk/awesomebar.native.js.map +1 -1
  89. package/dist/cjs/fieldOverrides.native.js.map +1 -1
  90. package/dist/cjs/fieldRegistry.cjs +1 -0
  91. package/dist/cjs/fieldRegistry.native.js +32 -31
  92. package/dist/cjs/fieldRegistry.native.js.map +1 -1
  93. package/dist/cjs/fields/Barcode/index.native.js.map +1 -1
  94. package/dist/cjs/fields/Check/index.native.js.map +1 -1
  95. package/dist/cjs/fields/CodeEditor/index.native.js.map +1 -1
  96. package/dist/cjs/fields/Color/index.native.js.map +1 -1
  97. package/dist/cjs/fields/Data/index.native.js.map +1 -1
  98. package/dist/cjs/fields/Date/sheetKeyboard.native.js.map +1 -1
  99. package/dist/cjs/fields/Date/types.native.js.map +1 -1
  100. package/dist/cjs/fields/Date/wire.native.js.map +1 -1
  101. package/dist/cjs/fields/DateRange/index.native.js.map +1 -1
  102. package/dist/cjs/fields/Duration/index.native.js.map +1 -1
  103. package/dist/cjs/fields/DynamicLink.native.js.map +1 -1
  104. package/dist/cjs/fields/FileUpload.cjs +1 -0
  105. package/dist/cjs/fields/FileUpload.native.js +1 -0
  106. package/dist/cjs/fields/FileUpload.native.js.map +1 -1
  107. package/dist/cjs/fields/FileUploadField/index.native.js.map +1 -1
  108. package/dist/cjs/fields/Geolocation/index.native.js.map +1 -1
  109. package/dist/cjs/fields/HTML/index.native.js.map +1 -1
  110. package/dist/cjs/fields/Heading/index.native.js.map +1 -1
  111. package/dist/cjs/fields/Icon/index.native.js.map +1 -1
  112. package/dist/cjs/fields/Link.cjs +1 -0
  113. package/dist/cjs/fields/Link.native.js +1 -0
  114. package/dist/cjs/fields/Link.native.js.map +1 -1
  115. package/dist/cjs/fields/LinkTree.cjs +2 -1
  116. package/dist/cjs/fields/LinkTree.native.js +2 -1
  117. package/dist/cjs/fields/LinkTree.native.js.map +1 -1
  118. package/dist/cjs/fields/LongText/index.native.js.map +1 -1
  119. package/dist/cjs/fields/MentionInput/index.cjs +4 -1
  120. package/dist/cjs/fields/MentionInput/index.native.js +4 -1
  121. package/dist/cjs/fields/MentionInput/index.native.js.map +1 -1
  122. package/dist/cjs/fields/Numeric/index.native.js.map +1 -1
  123. package/dist/cjs/fields/OTPInput/index.native.js.map +1 -1
  124. package/dist/cjs/fields/Password/index.native.js.map +1 -1
  125. package/dist/cjs/fields/Phone/index.native.js.map +1 -1
  126. package/dist/cjs/fields/Progress/index.native.js.map +1 -1
  127. package/dist/cjs/fields/RadioGroup/index.native.js.map +1 -1
  128. package/dist/cjs/fields/Rating/index.native.js.map +1 -1
  129. package/dist/cjs/fields/ReadOnly/index.native.js.map +1 -1
  130. package/dist/cjs/fields/Select/index.native.js.map +1 -1
  131. package/dist/cjs/fields/Signature/index.native.js.map +1 -1
  132. package/dist/cjs/fields/Slider/index.native.js.map +1 -1
  133. package/dist/cjs/fields/SmallText/index.native.js.map +1 -1
  134. package/dist/cjs/fields/Switch/index.native.js.map +1 -1
  135. package/dist/cjs/fields/TableMultiSelect.cjs +1 -0
  136. package/dist/cjs/fields/TableMultiSelect.native.js +1 -0
  137. package/dist/cjs/fields/TableMultiSelect.native.js.map +1 -1
  138. package/dist/cjs/fields/TextEditor/types.native.js.map +1 -1
  139. package/dist/cjs/fields/TimePicker/index.native.js.map +1 -1
  140. package/dist/cjs/fields/ToggleGroup/index.native.js.map +1 -1
  141. package/dist/cjs/fields/shared/EditorPreviewPanes.native.js.map +1 -1
  142. package/dist/cjs/filterFields.native.js.map +1 -1
  143. package/dist/cjs/formEngine/createPrefill.native.js.map +1 -1
  144. package/dist/cjs/formEngine/dirtyTracking.native.js.map +1 -1
  145. package/dist/cjs/formEngine/doctypeMeta.native.js.map +1 -1
  146. package/dist/cjs/formEngine/fetchFrom.native.js.map +1 -1
  147. package/dist/cjs/formEngine/fieldPermissions.native.js.map +1 -1
  148. package/dist/cjs/formEngine/formActions.native.js.map +1 -1
  149. package/dist/cjs/formEngine/formLayout.native.js.map +1 -1
  150. package/dist/cjs/formEngine/index.native.js.map +1 -1
  151. package/dist/cjs/formEngine/useFormEngine.native.js.map +1 -1
  152. package/dist/cjs/frappeEventColor.native.js.map +1 -1
  153. package/dist/cjs/frappeStoryTarget.native.js.map +1 -1
  154. package/dist/cjs/frappeUsers.cjs +1 -0
  155. package/dist/cjs/frappeUsers.native.js +1 -0
  156. package/dist/cjs/frappeUsers.native.js.map +1 -1
  157. package/dist/cjs/index.cjs +4 -0
  158. package/dist/cjs/index.native.js +38 -34
  159. package/dist/cjs/index.native.js.map +1 -1
  160. package/dist/cjs/liveErrors.native.js.map +1 -1
  161. package/dist/cjs/resolveControl.native.js.map +1 -1
  162. package/dist/cjs/schemaForm/SchemaWizard.native.js.map +1 -1
  163. package/dist/cjs/schemaForm/applyFieldOrder.native.js.map +1 -1
  164. package/dist/cjs/schemaForm/index.cjs +10 -9
  165. package/dist/cjs/schemaForm/index.native.js +11 -10
  166. package/dist/cjs/schemaForm/index.native.js.map +1 -1
  167. package/dist/cjs/shared/devWarn.cjs +40 -0
  168. package/dist/cjs/shared/devWarn.native.js +45 -0
  169. package/dist/cjs/shared/devWarn.native.js.map +1 -0
  170. package/dist/cjs/shared/useKeyboardInset.native.js.map +1 -1
  171. package/dist/cjs/syncError.native.js.map +1 -1
  172. package/dist/cjs/useFrappeAggregate.cjs +15 -8
  173. package/dist/cjs/useFrappeAggregate.native.js +15 -9
  174. package/dist/cjs/useFrappeAggregate.native.js.map +1 -1
  175. package/dist/cjs/useFrappeFacets.cjs +10 -9
  176. package/dist/cjs/useFrappeFacets.native.js +10 -10
  177. package/dist/cjs/useFrappeFacets.native.js.map +1 -1
  178. package/dist/cjs/useFrappePagination.native.js.map +1 -1
  179. package/dist/cjs/useFrappeRows.cjs +113 -0
  180. package/dist/cjs/useFrappeRows.native.js +129 -0
  181. package/dist/cjs/useFrappeRows.native.js.map +1 -0
  182. package/dist/esm/ChartCard.native.js.map +1 -1
  183. package/dist/esm/FileBrowser/AttachLibrary.native.js.map +1 -1
  184. package/dist/esm/FileBrowser/folderTree.native.js.map +1 -1
  185. package/dist/esm/FileBrowser/index.native.js.map +1 -1
  186. package/dist/esm/FileBrowser/types.native.js.map +1 -1
  187. package/dist/esm/FileBrowser/viewPersistence.native.js.map +1 -1
  188. package/dist/esm/FormSidebar.native.js.map +1 -1
  189. package/dist/esm/FrappeAssignment.mjs +1 -0
  190. package/dist/esm/FrappeAssignment.mjs.map +1 -1
  191. package/dist/esm/FrappeAssignment.native.js +1 -0
  192. package/dist/esm/FrappeAssignment.native.js.map +1 -1
  193. package/dist/esm/FrappeCalendar.mjs +22 -18
  194. package/dist/esm/FrappeCalendar.mjs.map +1 -1
  195. package/dist/esm/FrappeCalendar.native.js +24 -22
  196. package/dist/esm/FrappeCalendar.native.js.map +1 -1
  197. package/dist/esm/FrappeChartCard.mjs +1 -0
  198. package/dist/esm/FrappeChartCard.mjs.map +1 -1
  199. package/dist/esm/FrappeChartCard.native.js +1 -0
  200. package/dist/esm/FrappeChartCard.native.js.map +1 -1
  201. package/dist/esm/FrappeConnectionIndicator.native.js.map +1 -1
  202. package/dist/esm/FrappeDashboard.mjs +1 -0
  203. package/dist/esm/FrappeDashboard.mjs.map +1 -1
  204. package/dist/esm/FrappeDashboard.native.js +1 -0
  205. package/dist/esm/FrappeDashboard.native.js.map +1 -1
  206. package/dist/esm/FrappeForm.mjs +3 -2
  207. package/dist/esm/FrappeForm.mjs.map +1 -1
  208. package/dist/esm/FrappeForm.native.js +3 -2
  209. package/dist/esm/FrappeForm.native.js.map +1 -1
  210. package/dist/esm/FrappeGantt.mjs +29 -37
  211. package/dist/esm/FrappeGantt.mjs.map +1 -1
  212. package/dist/esm/FrappeGantt.native.js +31 -41
  213. package/dist/esm/FrappeGantt.native.js.map +1 -1
  214. package/dist/esm/FrappeImageView.mjs +7 -4
  215. package/dist/esm/FrappeImageView.mjs.map +1 -1
  216. package/dist/esm/FrappeImageView.native.js +11 -6
  217. package/dist/esm/FrappeImageView.native.js.map +1 -1
  218. package/dist/esm/FrappeKPICard.mjs +28 -2
  219. package/dist/esm/FrappeKPICard.mjs.map +1 -1
  220. package/dist/esm/FrappeKPICard.native.js +28 -2
  221. package/dist/esm/FrappeKPICard.native.js.map +1 -1
  222. package/dist/esm/FrappeKanban.mjs +18 -18
  223. package/dist/esm/FrappeKanban.mjs.map +1 -1
  224. package/dist/esm/FrappeKanban.native.js +20 -22
  225. package/dist/esm/FrappeKanban.native.js.map +1 -1
  226. package/dist/esm/FrappeLikedBy.mjs +2 -1
  227. package/dist/esm/FrappeLikedBy.mjs.map +1 -1
  228. package/dist/esm/FrappeLikedBy.native.js +2 -1
  229. package/dist/esm/FrappeLikedBy.native.js.map +1 -1
  230. package/dist/esm/FrappeList.mjs +4 -3
  231. package/dist/esm/FrappeList.mjs.map +1 -1
  232. package/dist/esm/FrappeList.native.js +4 -3
  233. package/dist/esm/FrappeList.native.js.map +1 -1
  234. package/dist/esm/FrappeListView.mjs +1 -0
  235. package/dist/esm/FrappeListView.mjs.map +1 -1
  236. package/dist/esm/FrappeListView.native.js +1 -0
  237. package/dist/esm/FrappeListView.native.js.map +1 -1
  238. package/dist/esm/FrappeProvider.mjs +3 -1
  239. package/dist/esm/FrappeProvider.mjs.map +1 -1
  240. package/dist/esm/FrappeProvider.native.js +3 -1
  241. package/dist/esm/FrappeProvider.native.js.map +1 -1
  242. package/dist/esm/FrappeReconnectIndicator.native.js.map +1 -1
  243. package/dist/esm/FrappeReportBuilder.mjs +3 -2
  244. package/dist/esm/FrappeReportBuilder.mjs.map +1 -1
  245. package/dist/esm/FrappeReportBuilder.native.js +3 -2
  246. package/dist/esm/FrappeReportBuilder.native.js.map +1 -1
  247. package/dist/esm/FrappeReportView.mjs +2 -1
  248. package/dist/esm/FrappeReportView.mjs.map +1 -1
  249. package/dist/esm/FrappeReportView.native.js +2 -1
  250. package/dist/esm/FrappeReportView.native.js.map +1 -1
  251. package/dist/esm/FrappeTable.mjs +38 -40
  252. package/dist/esm/FrappeTable.mjs.map +1 -1
  253. package/dist/esm/FrappeTable.native.js +41 -41
  254. package/dist/esm/FrappeTable.native.js.map +1 -1
  255. package/dist/esm/FrappeTreeView.mjs +91 -56
  256. package/dist/esm/FrappeTreeView.mjs.map +1 -1
  257. package/dist/esm/FrappeTreeView.native.js +135 -56
  258. package/dist/esm/FrappeTreeView.native.js.map +1 -1
  259. package/dist/esm/SyncErrorNotice.native.js.map +1 -1
  260. package/dist/esm/commentActions.mjs +1 -1
  261. package/dist/esm/commentActions.mjs.map +1 -1
  262. package/dist/esm/commentActions.native.js +1 -1
  263. package/dist/esm/commentActions.native.js.map +1 -1
  264. package/dist/esm/components/attachments.mjs +1 -0
  265. package/dist/esm/components/attachments.mjs.map +1 -1
  266. package/dist/esm/components/attachments.native.js +1 -0
  267. package/dist/esm/components/attachments.native.js.map +1 -1
  268. package/dist/esm/components/tags.mjs +1 -0
  269. package/dist/esm/components/tags.mjs.map +1 -1
  270. package/dist/esm/components/tags.native.js +1 -0
  271. package/dist/esm/components/tags.native.js.map +1 -1
  272. package/dist/esm/components/timeline.mjs +2 -1
  273. package/dist/esm/components/timeline.mjs.map +1 -1
  274. package/dist/esm/components/timeline.native.js +2 -1
  275. package/dist/esm/components/timeline.native.js.map +1 -1
  276. package/dist/esm/dependsOn.native.js.map +1 -1
  277. package/dist/esm/desk/DeskFormPage.native.js.map +1 -1
  278. package/dist/esm/desk/DeskFormSidebar.mjs +1 -0
  279. package/dist/esm/desk/DeskFormSidebar.mjs.map +1 -1
  280. package/dist/esm/desk/DeskFormSidebar.native.js +1 -0
  281. package/dist/esm/desk/DeskFormSidebar.native.js.map +1 -1
  282. package/dist/esm/desk/DeskListPage.native.js.map +1 -1
  283. package/dist/esm/desk/DeskShell.mjs +2 -0
  284. package/dist/esm/desk/DeskShell.mjs.map +1 -1
  285. package/dist/esm/desk/DeskShell.native.js +2 -0
  286. package/dist/esm/desk/DeskShell.native.js.map +1 -1
  287. package/dist/esm/desk/DeskSidebar.mjs +1 -0
  288. package/dist/esm/desk/DeskSidebar.mjs.map +1 -1
  289. package/dist/esm/desk/DeskSidebar.native.js +1 -0
  290. package/dist/esm/desk/DeskSidebar.native.js.map +1 -1
  291. package/dist/esm/desk/awesomebar.mjs +2 -1
  292. package/dist/esm/desk/awesomebar.mjs.map +1 -1
  293. package/dist/esm/desk/awesomebar.native.js +2 -1
  294. package/dist/esm/desk/awesomebar.native.js.map +1 -1
  295. package/dist/esm/fieldOverrides.native.js.map +1 -1
  296. package/dist/esm/fieldRegistry.mjs +1 -0
  297. package/dist/esm/fieldRegistry.mjs.map +1 -1
  298. package/dist/esm/fieldRegistry.native.js +1 -0
  299. package/dist/esm/fieldRegistry.native.js.map +1 -1
  300. package/dist/esm/fields/Barcode/index.native.js.map +1 -1
  301. package/dist/esm/fields/Check/index.native.js.map +1 -1
  302. package/dist/esm/fields/CodeEditor/index.native.js.map +1 -1
  303. package/dist/esm/fields/Color/index.native.js.map +1 -1
  304. package/dist/esm/fields/Data/index.native.js.map +1 -1
  305. package/dist/esm/fields/Date/sheetKeyboard.native.js.map +1 -1
  306. package/dist/esm/fields/Date/types.native.js.map +1 -1
  307. package/dist/esm/fields/Date/wire.native.js.map +1 -1
  308. package/dist/esm/fields/DateRange/index.native.js.map +1 -1
  309. package/dist/esm/fields/Duration/index.native.js.map +1 -1
  310. package/dist/esm/fields/DynamicLink.native.js.map +1 -1
  311. package/dist/esm/fields/FileUpload.mjs +1 -0
  312. package/dist/esm/fields/FileUpload.mjs.map +1 -1
  313. package/dist/esm/fields/FileUpload.native.js +1 -0
  314. package/dist/esm/fields/FileUpload.native.js.map +1 -1
  315. package/dist/esm/fields/FileUploadField/index.native.js.map +1 -1
  316. package/dist/esm/fields/Geolocation/index.native.js.map +1 -1
  317. package/dist/esm/fields/HTML/index.native.js.map +1 -1
  318. package/dist/esm/fields/Heading/index.native.js.map +1 -1
  319. package/dist/esm/fields/Icon/index.native.js.map +1 -1
  320. package/dist/esm/fields/Link.mjs +1 -0
  321. package/dist/esm/fields/Link.mjs.map +1 -1
  322. package/dist/esm/fields/Link.native.js +1 -0
  323. package/dist/esm/fields/Link.native.js.map +1 -1
  324. package/dist/esm/fields/LinkTree.mjs +2 -1
  325. package/dist/esm/fields/LinkTree.mjs.map +1 -1
  326. package/dist/esm/fields/LinkTree.native.js +2 -1
  327. package/dist/esm/fields/LinkTree.native.js.map +1 -1
  328. package/dist/esm/fields/LongText/index.native.js.map +1 -1
  329. package/dist/esm/fields/MentionInput/index.mjs +4 -1
  330. package/dist/esm/fields/MentionInput/index.mjs.map +1 -1
  331. package/dist/esm/fields/MentionInput/index.native.js +4 -1
  332. package/dist/esm/fields/MentionInput/index.native.js.map +1 -1
  333. package/dist/esm/fields/Numeric/index.native.js.map +1 -1
  334. package/dist/esm/fields/OTPInput/index.native.js.map +1 -1
  335. package/dist/esm/fields/Password/index.native.js.map +1 -1
  336. package/dist/esm/fields/Phone/index.native.js.map +1 -1
  337. package/dist/esm/fields/Progress/index.native.js.map +1 -1
  338. package/dist/esm/fields/RadioGroup/index.native.js.map +1 -1
  339. package/dist/esm/fields/Rating/index.native.js.map +1 -1
  340. package/dist/esm/fields/ReadOnly/index.native.js.map +1 -1
  341. package/dist/esm/fields/Select/index.native.js.map +1 -1
  342. package/dist/esm/fields/Signature/index.native.js.map +1 -1
  343. package/dist/esm/fields/Slider/index.native.js.map +1 -1
  344. package/dist/esm/fields/SmallText/index.native.js.map +1 -1
  345. package/dist/esm/fields/Switch/index.native.js.map +1 -1
  346. package/dist/esm/fields/TableMultiSelect.mjs +1 -0
  347. package/dist/esm/fields/TableMultiSelect.mjs.map +1 -1
  348. package/dist/esm/fields/TableMultiSelect.native.js +1 -0
  349. package/dist/esm/fields/TableMultiSelect.native.js.map +1 -1
  350. package/dist/esm/fields/TextEditor/types.native.js.map +1 -1
  351. package/dist/esm/fields/TimePicker/index.native.js.map +1 -1
  352. package/dist/esm/fields/ToggleGroup/index.native.js.map +1 -1
  353. package/dist/esm/fields/shared/EditorPreviewPanes.native.js.map +1 -1
  354. package/dist/esm/filterFields.native.js.map +1 -1
  355. package/dist/esm/formEngine/createPrefill.native.js.map +1 -1
  356. package/dist/esm/formEngine/dirtyTracking.native.js.map +1 -1
  357. package/dist/esm/formEngine/doctypeMeta.native.js.map +1 -1
  358. package/dist/esm/formEngine/fetchFrom.native.js.map +1 -1
  359. package/dist/esm/formEngine/fieldPermissions.native.js.map +1 -1
  360. package/dist/esm/formEngine/formActions.mjs.map +1 -1
  361. package/dist/esm/formEngine/formActions.native.js.map +1 -1
  362. package/dist/esm/formEngine/formLayout.native.js.map +1 -1
  363. package/dist/esm/formEngine/index.native.js.map +1 -1
  364. package/dist/esm/formEngine/useFormEngine.native.js.map +1 -1
  365. package/dist/esm/frappeEventColor.native.js.map +1 -1
  366. package/dist/esm/frappeStoryTarget.native.js.map +1 -1
  367. package/dist/esm/frappeUsers.mjs +1 -0
  368. package/dist/esm/frappeUsers.mjs.map +1 -1
  369. package/dist/esm/frappeUsers.native.js +1 -0
  370. package/dist/esm/frappeUsers.native.js.map +1 -1
  371. package/dist/esm/index.mjs +2 -1
  372. package/dist/esm/index.mjs.map +1 -1
  373. package/dist/esm/index.native.js +2 -1
  374. package/dist/esm/index.native.js.map +1 -1
  375. package/dist/esm/liveErrors.native.js.map +1 -1
  376. package/dist/esm/resolveControl.native.js.map +1 -1
  377. package/dist/esm/schemaForm/SchemaWizard.native.js.map +1 -1
  378. package/dist/esm/schemaForm/applyFieldOrder.native.js.map +1 -1
  379. package/dist/esm/schemaForm/index.mjs +8 -7
  380. package/dist/esm/schemaForm/index.mjs.map +1 -1
  381. package/dist/esm/schemaForm/index.native.js +8 -7
  382. package/dist/esm/schemaForm/index.native.js.map +1 -1
  383. package/dist/esm/shared/devWarn.mjs +14 -0
  384. package/dist/esm/shared/devWarn.mjs.map +1 -0
  385. package/dist/esm/shared/devWarn.native.js +16 -0
  386. package/dist/esm/shared/devWarn.native.js.map +1 -0
  387. package/dist/esm/shared/useKeyboardInset.native.js.map +1 -1
  388. package/dist/esm/syncError.native.js.map +1 -1
  389. package/dist/esm/useFrappeAggregate.mjs +15 -8
  390. package/dist/esm/useFrappeAggregate.mjs.map +1 -1
  391. package/dist/esm/useFrappeAggregate.native.js +15 -9
  392. package/dist/esm/useFrappeAggregate.native.js.map +1 -1
  393. package/dist/esm/useFrappeFacets.mjs +10 -9
  394. package/dist/esm/useFrappeFacets.mjs.map +1 -1
  395. package/dist/esm/useFrappeFacets.native.js +10 -10
  396. package/dist/esm/useFrappeFacets.native.js.map +1 -1
  397. package/dist/esm/useFrappePagination.native.js.map +1 -1
  398. package/dist/esm/useFrappeRows.mjs +86 -0
  399. package/dist/esm/useFrappeRows.mjs.map +1 -0
  400. package/dist/esm/useFrappeRows.native.js +99 -0
  401. package/dist/esm/useFrappeRows.native.js.map +1 -0
  402. package/dist/jsx/FrappeAssignment.mjs +1 -0
  403. package/dist/jsx/FrappeAssignment.mjs.map +1 -1
  404. package/dist/jsx/FrappeAssignment.native.js +1 -0
  405. package/dist/jsx/FrappeAssignment.native.js.map +1 -1
  406. package/dist/jsx/FrappeCalendar.mjs +22 -18
  407. package/dist/jsx/FrappeCalendar.mjs.map +1 -1
  408. package/dist/jsx/FrappeCalendar.native.js +24 -22
  409. package/dist/jsx/FrappeCalendar.native.js.map +1 -1
  410. package/dist/jsx/FrappeChartCard.mjs +1 -0
  411. package/dist/jsx/FrappeChartCard.mjs.map +1 -1
  412. package/dist/jsx/FrappeChartCard.native.js +1 -0
  413. package/dist/jsx/FrappeChartCard.native.js.map +1 -1
  414. package/dist/jsx/FrappeDashboard.mjs +1 -0
  415. package/dist/jsx/FrappeDashboard.mjs.map +1 -1
  416. package/dist/jsx/FrappeDashboard.native.js +1 -0
  417. package/dist/jsx/FrappeDashboard.native.js.map +1 -1
  418. package/dist/jsx/FrappeForm.mjs +3 -2
  419. package/dist/jsx/FrappeForm.mjs.map +1 -1
  420. package/dist/jsx/FrappeForm.native.js +3 -2
  421. package/dist/jsx/FrappeForm.native.js.map +1 -1
  422. package/dist/jsx/FrappeGantt.mjs +29 -37
  423. package/dist/jsx/FrappeGantt.mjs.map +1 -1
  424. package/dist/jsx/FrappeGantt.native.js +29 -39
  425. package/dist/jsx/FrappeGantt.native.js.map +1 -1
  426. package/dist/jsx/FrappeImageView.mjs +7 -4
  427. package/dist/jsx/FrappeImageView.mjs.map +1 -1
  428. package/dist/jsx/FrappeImageView.native.js +10 -5
  429. package/dist/jsx/FrappeImageView.native.js.map +1 -1
  430. package/dist/jsx/FrappeKPICard.mjs +28 -2
  431. package/dist/jsx/FrappeKPICard.mjs.map +1 -1
  432. package/dist/jsx/FrappeKPICard.native.js +27 -1
  433. package/dist/jsx/FrappeKPICard.native.js.map +1 -1
  434. package/dist/jsx/FrappeKanban.mjs +18 -18
  435. package/dist/jsx/FrappeKanban.mjs.map +1 -1
  436. package/dist/jsx/FrappeKanban.native.js +20 -22
  437. package/dist/jsx/FrappeKanban.native.js.map +1 -1
  438. package/dist/jsx/FrappeLikedBy.mjs +2 -1
  439. package/dist/jsx/FrappeLikedBy.mjs.map +1 -1
  440. package/dist/jsx/FrappeLikedBy.native.js +2 -1
  441. package/dist/jsx/FrappeLikedBy.native.js.map +1 -1
  442. package/dist/jsx/FrappeList.mjs +4 -3
  443. package/dist/jsx/FrappeList.mjs.map +1 -1
  444. package/dist/jsx/FrappeList.native.js +4 -3
  445. package/dist/jsx/FrappeList.native.js.map +1 -1
  446. package/dist/jsx/FrappeListView.mjs +1 -0
  447. package/dist/jsx/FrappeListView.mjs.map +1 -1
  448. package/dist/jsx/FrappeListView.native.js +1 -0
  449. package/dist/jsx/FrappeListView.native.js.map +1 -1
  450. package/dist/jsx/FrappeProvider.mjs +3 -1
  451. package/dist/jsx/FrappeProvider.mjs.map +1 -1
  452. package/dist/jsx/FrappeProvider.native.js +3 -1
  453. package/dist/jsx/FrappeProvider.native.js.map +1 -1
  454. package/dist/jsx/FrappeReportBuilder.mjs +3 -2
  455. package/dist/jsx/FrappeReportBuilder.mjs.map +1 -1
  456. package/dist/jsx/FrappeReportBuilder.native.js +3 -2
  457. package/dist/jsx/FrappeReportBuilder.native.js.map +1 -1
  458. package/dist/jsx/FrappeReportView.mjs +2 -1
  459. package/dist/jsx/FrappeReportView.mjs.map +1 -1
  460. package/dist/jsx/FrappeReportView.native.js +2 -1
  461. package/dist/jsx/FrappeReportView.native.js.map +1 -1
  462. package/dist/jsx/FrappeTable.mjs +38 -40
  463. package/dist/jsx/FrappeTable.mjs.map +1 -1
  464. package/dist/jsx/FrappeTable.native.js +40 -40
  465. package/dist/jsx/FrappeTable.native.js.map +1 -1
  466. package/dist/jsx/FrappeTreeView.mjs +91 -56
  467. package/dist/jsx/FrappeTreeView.mjs.map +1 -1
  468. package/dist/jsx/FrappeTreeView.native.js +131 -51
  469. package/dist/jsx/FrappeTreeView.native.js.map +1 -1
  470. package/dist/jsx/commentActions.mjs +1 -1
  471. package/dist/jsx/commentActions.mjs.map +1 -1
  472. package/dist/jsx/commentActions.native.js +1 -1
  473. package/dist/jsx/commentActions.native.js.map +1 -1
  474. package/dist/jsx/components/attachments.mjs +1 -0
  475. package/dist/jsx/components/attachments.mjs.map +1 -1
  476. package/dist/jsx/components/attachments.native.js +1 -0
  477. package/dist/jsx/components/attachments.native.js.map +1 -1
  478. package/dist/jsx/components/tags.mjs +1 -0
  479. package/dist/jsx/components/tags.mjs.map +1 -1
  480. package/dist/jsx/components/tags.native.js +1 -0
  481. package/dist/jsx/components/tags.native.js.map +1 -1
  482. package/dist/jsx/components/timeline.mjs +2 -1
  483. package/dist/jsx/components/timeline.mjs.map +1 -1
  484. package/dist/jsx/components/timeline.native.js +2 -1
  485. package/dist/jsx/components/timeline.native.js.map +1 -1
  486. package/dist/jsx/desk/DeskFormSidebar.mjs +1 -0
  487. package/dist/jsx/desk/DeskFormSidebar.mjs.map +1 -1
  488. package/dist/jsx/desk/DeskFormSidebar.native.js +1 -0
  489. package/dist/jsx/desk/DeskFormSidebar.native.js.map +1 -1
  490. package/dist/jsx/desk/DeskShell.mjs +2 -0
  491. package/dist/jsx/desk/DeskShell.mjs.map +1 -1
  492. package/dist/jsx/desk/DeskShell.native.js +2 -0
  493. package/dist/jsx/desk/DeskShell.native.js.map +1 -1
  494. package/dist/jsx/desk/DeskSidebar.mjs +1 -0
  495. package/dist/jsx/desk/DeskSidebar.mjs.map +1 -1
  496. package/dist/jsx/desk/DeskSidebar.native.js +1 -0
  497. package/dist/jsx/desk/DeskSidebar.native.js.map +1 -1
  498. package/dist/jsx/desk/awesomebar.mjs +2 -1
  499. package/dist/jsx/desk/awesomebar.mjs.map +1 -1
  500. package/dist/jsx/desk/awesomebar.native.js +2 -1
  501. package/dist/jsx/desk/awesomebar.native.js.map +1 -1
  502. package/dist/jsx/fieldRegistry.mjs +1 -0
  503. package/dist/jsx/fieldRegistry.mjs.map +1 -1
  504. package/dist/jsx/fieldRegistry.native.js +1 -0
  505. package/dist/jsx/fieldRegistry.native.js.map +1 -1
  506. package/dist/jsx/fields/FileUpload.mjs +1 -0
  507. package/dist/jsx/fields/FileUpload.mjs.map +1 -1
  508. package/dist/jsx/fields/FileUpload.native.js +1 -0
  509. package/dist/jsx/fields/FileUpload.native.js.map +1 -1
  510. package/dist/jsx/fields/Link.mjs +1 -0
  511. package/dist/jsx/fields/Link.mjs.map +1 -1
  512. package/dist/jsx/fields/Link.native.js +1 -0
  513. package/dist/jsx/fields/Link.native.js.map +1 -1
  514. package/dist/jsx/fields/LinkTree.mjs +2 -1
  515. package/dist/jsx/fields/LinkTree.mjs.map +1 -1
  516. package/dist/jsx/fields/LinkTree.native.js +2 -1
  517. package/dist/jsx/fields/LinkTree.native.js.map +1 -1
  518. package/dist/jsx/fields/MentionInput/index.mjs +4 -1
  519. package/dist/jsx/fields/MentionInput/index.mjs.map +1 -1
  520. package/dist/jsx/fields/MentionInput/index.native.js +4 -1
  521. package/dist/jsx/fields/MentionInput/index.native.js.map +1 -1
  522. package/dist/jsx/fields/TableMultiSelect.mjs +1 -0
  523. package/dist/jsx/fields/TableMultiSelect.mjs.map +1 -1
  524. package/dist/jsx/fields/TableMultiSelect.native.js +1 -0
  525. package/dist/jsx/fields/TableMultiSelect.native.js.map +1 -1
  526. package/dist/jsx/formEngine/formActions.mjs.map +1 -1
  527. package/dist/jsx/formEngine/formActions.native.js.map +1 -1
  528. package/dist/jsx/frappeUsers.mjs +1 -0
  529. package/dist/jsx/frappeUsers.mjs.map +1 -1
  530. package/dist/jsx/frappeUsers.native.js +1 -0
  531. package/dist/jsx/frappeUsers.native.js.map +1 -1
  532. package/dist/jsx/index.js +2 -1
  533. package/dist/jsx/index.js.map +1 -1
  534. package/dist/jsx/index.mjs +2 -1
  535. package/dist/jsx/index.mjs.map +1 -1
  536. package/dist/jsx/index.native.js +4 -0
  537. package/dist/jsx/index.native.js.map +1 -1
  538. package/dist/jsx/schemaForm/index.mjs +8 -7
  539. package/dist/jsx/schemaForm/index.mjs.map +1 -1
  540. package/dist/jsx/schemaForm/index.native.js +10 -9
  541. package/dist/jsx/schemaForm/index.native.js.map +1 -1
  542. package/dist/jsx/shared/devWarn.mjs +14 -0
  543. package/dist/jsx/shared/devWarn.mjs.map +1 -0
  544. package/dist/jsx/shared/devWarn.native.js +45 -0
  545. package/dist/jsx/shared/devWarn.native.js.map +1 -0
  546. package/dist/jsx/useFrappeAggregate.mjs +15 -8
  547. package/dist/jsx/useFrappeAggregate.mjs.map +1 -1
  548. package/dist/jsx/useFrappeAggregate.native.js +15 -9
  549. package/dist/jsx/useFrappeAggregate.native.js.map +1 -1
  550. package/dist/jsx/useFrappeFacets.mjs +10 -9
  551. package/dist/jsx/useFrappeFacets.mjs.map +1 -1
  552. package/dist/jsx/useFrappeFacets.native.js +10 -10
  553. package/dist/jsx/useFrappeFacets.native.js.map +1 -1
  554. package/dist/jsx/useFrappeRows.mjs +86 -0
  555. package/dist/jsx/useFrappeRows.mjs.map +1 -0
  556. package/dist/jsx/useFrappeRows.native.js +129 -0
  557. package/dist/jsx/useFrappeRows.native.js.map +1 -0
  558. package/package.json +17 -16
  559. package/src/FileBrowser/FileBrowser.spec.tsx +11 -1
  560. package/src/FrappeAssignment.tsx +1 -0
  561. package/src/FrappeCalendar.tsx +27 -22
  562. package/src/FrappeChartCard.tsx +1 -0
  563. package/src/FrappeDashboard.tsx +3 -0
  564. package/src/FrappeForm.tsx +9 -3
  565. package/src/FrappeGantt.tsx +31 -39
  566. package/src/FrappeImageView.tsx +7 -3
  567. package/src/FrappeKPICard.spec.tsx +128 -0
  568. package/src/FrappeKPICard.tsx +45 -4
  569. package/src/FrappeKanban.tsx +26 -17
  570. package/src/FrappeLikedBy.tsx +2 -1
  571. package/src/FrappeList.tsx +5 -2
  572. package/src/FrappeListView.tsx +1 -0
  573. package/src/FrappeProvider.fixturesOnly.spec.tsx +129 -0
  574. package/src/FrappeProvider.realtime.spec.tsx +59 -0
  575. package/src/FrappeProvider.tsx +33 -7
  576. package/src/FrappeReportBuilder.tsx +5 -2
  577. package/src/FrappeReportView.tsx +5 -2
  578. package/src/FrappeTable.autoHeight.spec.tsx +142 -0
  579. package/src/FrappeTable.rowAccumulator.spec.tsx +110 -0
  580. package/src/FrappeTable.tsx +77 -48
  581. package/src/FrappeTreeView.stories.tsx +59 -0
  582. package/src/FrappeTreeView.tsx +168 -56
  583. package/src/commentActions.ts +1 -1
  584. package/src/components/attachments.tsx +1 -0
  585. package/src/components/tags.tsx +1 -0
  586. package/src/components/timeline.tsx +2 -1
  587. package/src/desk/DeskFormSidebar.tsx +1 -0
  588. package/src/desk/DeskShell.tsx +2 -0
  589. package/src/desk/DeskSidebar.tsx +6 -1
  590. package/src/desk/awesomebar.tsx +11 -3
  591. package/src/fieldRegistry.ts +1 -0
  592. package/src/fields/CodeEditor/CodeEditor.spec.tsx +10 -9
  593. package/src/fields/Date/typeParity.spec.tsx +19 -9
  594. package/src/fields/Duration/Duration.spec.tsx +73 -0
  595. package/src/fields/FileUpload.tsx +1 -0
  596. package/src/fields/Link.tsx +6 -1
  597. package/src/fields/LinkTree.tsx +2 -1
  598. package/src/fields/MentionInput/MentionInput.spec.tsx +110 -0
  599. package/src/fields/MentionInput/index.tsx +4 -1
  600. package/src/fields/Password/index.tsx +1 -1
  601. package/src/fields/Progress/Progress.spec.tsx +9 -0
  602. package/src/fields/RadioGroup/RadioGroup.spec.tsx +93 -0
  603. package/src/fields/Signature/Signature.spec.tsx +105 -0
  604. package/src/fields/Slider/Slider.spec.tsx +73 -0
  605. package/src/fields/Switch/Switch.spec.tsx +65 -0
  606. package/src/fields/TableMultiSelect.tsx +1 -0
  607. package/src/fields/TextEditor/TextEditor.spec.tsx +2 -3
  608. package/src/fields/TextEditor/TextEditor.stories.tsx +31 -1
  609. package/src/fields/ToggleGroup/ToggleGroup.spec.tsx +110 -0
  610. package/src/formEngine/formActions.ts +2 -0
  611. package/src/frappeUsers.ts +1 -0
  612. package/src/frappeViews.designLaw.spec.ts +11 -7
  613. package/src/index.ts +13 -0
  614. package/src/schemaForm/index.tsx +6 -7
  615. package/src/shared/devWarn.ts +42 -0
  616. package/src/useFrappeAggregate.ts +19 -11
  617. package/src/useFrappeFacets.ts +17 -10
  618. package/src/useFrappeRows.spec.tsx +176 -0
  619. package/src/useFrappeRows.ts +293 -0
  620. package/types/FrappeAssignment.d.ts.map +1 -1
  621. package/types/FrappeCalendar.d.ts.map +1 -1
  622. package/types/FrappeChartCard.d.ts.map +1 -1
  623. package/types/FrappeDashboard.d.ts.map +1 -1
  624. package/types/FrappeForm.d.ts +6 -2
  625. package/types/FrappeForm.d.ts.map +1 -1
  626. package/types/FrappeGantt.d.ts.map +1 -1
  627. package/types/FrappeImageView.d.ts.map +1 -1
  628. package/types/FrappeKPICard.d.ts +9 -1
  629. package/types/FrappeKPICard.d.ts.map +1 -1
  630. package/types/FrappeKanban.d.ts.map +1 -1
  631. package/types/FrappeLikedBy.d.ts.map +1 -1
  632. package/types/FrappeList.d.ts.map +1 -1
  633. package/types/FrappeListView.d.ts.map +1 -1
  634. package/types/FrappeProvider.d.ts +21 -7
  635. package/types/FrappeProvider.d.ts.map +1 -1
  636. package/types/FrappeReportBuilder.d.ts.map +1 -1
  637. package/types/FrappeReportView.d.ts.map +1 -1
  638. package/types/FrappeTable.d.ts +20 -1
  639. package/types/FrappeTable.d.ts.map +1 -1
  640. package/types/FrappeTreeView.d.ts +38 -1
  641. package/types/FrappeTreeView.d.ts.map +1 -1
  642. package/types/components/attachments.d.ts.map +1 -1
  643. package/types/components/tags.d.ts.map +1 -1
  644. package/types/components/timeline.d.ts.map +1 -1
  645. package/types/desk/DeskFormSidebar.d.ts.map +1 -1
  646. package/types/desk/DeskShell.d.ts.map +1 -1
  647. package/types/desk/DeskSidebar.d.ts.map +1 -1
  648. package/types/desk/awesomebar.d.ts.map +1 -1
  649. package/types/fieldRegistry.d.ts.map +1 -1
  650. package/types/fields/FileUpload.d.ts.map +1 -1
  651. package/types/fields/Link.d.ts.map +1 -1
  652. package/types/fields/LinkTree.d.ts.map +1 -1
  653. package/types/fields/MentionInput/index.d.ts.map +1 -1
  654. package/types/fields/Password/index.d.ts +1 -1
  655. package/types/fields/Password/index.d.ts.map +1 -1
  656. package/types/fields/TableMultiSelect.d.ts.map +1 -1
  657. package/types/formEngine/formActions.d.ts +2 -0
  658. package/types/formEngine/formActions.d.ts.map +1 -1
  659. package/types/frappeUsers.d.ts.map +1 -1
  660. package/types/index.d.ts +1 -0
  661. package/types/index.d.ts.map +1 -1
  662. package/types/schemaForm/index.d.ts.map +1 -1
  663. package/types/shared/devWarn.d.ts +23 -0
  664. package/types/shared/devWarn.d.ts.map +1 -0
  665. package/types/useFrappeAggregate.d.ts +4 -1
  666. package/types/useFrappeAggregate.d.ts.map +1 -1
  667. package/types/useFrappeFacets.d.ts +2 -1
  668. package/types/useFrappeFacets.d.ts.map +1 -1
  669. package/types/useFrappeRows.d.ts +186 -0
  670. package/types/useFrappeRows.d.ts.map +1 -0
@@ -3,9 +3,7 @@ import {
3
3
  Order,
4
4
  matchesFilters,
5
5
  useDocTypeMeta,
6
- useFrappeCollection,
7
6
  useFrappeDoctypeEvents,
8
- useLiveQuery,
9
7
  } from "@multiplatform.one/frappe";
10
8
  import {
11
9
  DataTable,
@@ -25,12 +23,31 @@ import { FilterManager, SavedFilterDropdown, useSavedFilters } from "@multiplatf
25
23
  import { useFrappeConfig } from "./FrappeProvider";
26
24
  import { FrappeReconnectIndicator } from "./FrappeReconnectIndicator";
27
25
  import { docFieldsToFilterFields } from "./filterFields";
28
- import { toLiveLoadError } from "./liveErrors";
26
+ import { useFrappeRows } from "./useFrappeRows";
29
27
 
30
28
  /**
31
29
  * Props for the FrappeTable component.
32
30
  *
33
- * @typeParam TDoc - The document type with at least name and doctype fields
31
+ * `data` is omitted because FrappeTable fetches its own rows. Everything else
32
+ * on `DataTableProps` passes straight through — including `rowAccumulator`
33
+ * (MPO-250), so a Frappe-bound table CAN carry a folded column (a running
34
+ * balance, a per-row cumulative count) without the caller re-fetching the
35
+ * doctype and hand-assembling a DataTable. Declare the derived field on
36
+ * `TDoc` so a column can name it in `accessorKey`:
37
+ *
38
+ * ```tsx
39
+ * const balance: RowAccumulator<Partial<Posting>, string> = {
40
+ * initial: "0",
41
+ * reduce: (carried, row) => addMoney(carried, row.amount ?? "0"),
42
+ * derive: (carried) => ({ running: carried }),
43
+ * order: (a, b) => compareByDateThenName(a, b),
44
+ * };
45
+ * <FrappeTable<Posting & { running?: string }> doctype="Posting" rowAccumulator={balance} … />
46
+ * ```
47
+ *
48
+ * The fold runs over the rows the table HOLDS, before pagination. In
49
+ * `serverSide` mode that is one page, so a running balance there needs the
50
+ * server to send the figure — the fold cannot invent rows it never got.
34
51
  */
35
52
  export interface FrappeTableProps<TDoc extends { name: string; doctype: string }> extends Omit<
36
53
  DataTableProps<Partial<TDoc>>,
@@ -310,8 +327,10 @@ export function FrappeTable<TDoc extends { name: string; doctype: string }>({
310
327
  const finalAuth = auth ?? config?.auth;
311
328
  const finalSyncOptions = syncOptions ?? config?.syncOptions;
312
329
 
313
- if (!finalBaseURL) {
314
- throw new Error("FrappeTable requires baseURL prop or FrappeProvider with baseURL");
330
+ // A fixture corpus is a complete data source, so it satisfies the same
331
+ // requirement a baseURL does: fixture mode never dials a server.
332
+ if (!finalBaseURL && !config?.fixtures) {
333
+ throw new Error("FrappeTable requires baseURL prop or FrappeProvider with baseURL or fixtures");
315
334
  }
316
335
 
317
336
  // One connection config for the live subscription (client mode), the
@@ -324,6 +343,7 @@ export function FrappeTable<TDoc extends { name: string; doctype: string }>({
324
343
  socketBaseURL: config?.socketBaseURL,
325
344
  auth: finalAuth,
326
345
  syncOptions: finalSyncOptions,
346
+ realtime: config?.realtime,
327
347
  fixtures: config?.fixtures,
328
348
  }),
329
349
  [
@@ -331,6 +351,7 @@ export function FrappeTable<TDoc extends { name: string; doctype: string }>({
331
351
  config?.socketPort,
332
352
  config?.siteName,
333
353
  config?.socketBaseURL,
354
+ config?.realtime,
334
355
  finalAuth,
335
356
  finalSyncOptions,
336
357
  config?.fixtures,
@@ -592,32 +613,31 @@ export function FrappeTable<TDoc extends { name: string; doctype: string }>({
592
613
  // Always call the hook — toggling `savedFilters` must not change hook order (SB-M-012).
593
614
  const savedFiltersHook = useSavedFilters({ userId });
594
615
 
595
- // Honest error surface: the collection swallows initial-sync failures
596
- // (renders as empty otherwise); onSyncError turns 403/PermissionError and
597
- // network failures into a visible error state.
598
- const handleSyncError = useCallback(
599
- (err: unknown) => {
600
- setErrorState(
601
- toLiveLoadError(err, {
602
- permissionMessage: t("You do not have permission to view {{doctype}}", { doctype }),
603
- genericMessage: t("Error loading {{doctype}}", { doctype }),
604
- }),
605
- );
606
- },
616
+ // The client/live-collection read is the SHARED one (MPO-251): collection
617
+ // + live query + the honest error surface a bare collection swallows
618
+ // (without onSyncError a 403 or a dead server renders as an empty table).
619
+ // `limit: null` keeps the bench's own page length rather than the hook's
620
+ // default — FrappeTable paginates on the rows it is handed, and moving its
621
+ // row ceiling here would move it for every existing consumer.
622
+ const rowsMessages = useMemo(
623
+ () => ({
624
+ permission: t("You do not have permission to view {{doctype}}", { doctype }),
625
+ generic: t("Error loading {{doctype}}", { doctype }),
626
+ queryFailed: t("Failed to load {{doctype}}", { doctype }),
627
+ }),
607
628
  [doctype, t],
608
629
  );
609
-
610
- const collection = useFrappeCollection<TDoc>(
611
- serverSide ? undefined : connectionConfig,
612
- serverSide ? "" : doctype,
613
- serverSide ? undefined : { fields, filters: activeFilters, onSyncError: handleSyncError },
614
- );
615
630
  const {
616
- data: rawData,
617
- isLoading: isRowsLoading,
618
- isError: isLiveError,
619
- } = useLiveQuery((q) => (collection ? q.from({ _list: collection }) : null), [collection]);
620
- const clientRows = useMemo(() => (rawData as TDoc[] | undefined) ?? [], [rawData]);
631
+ rows: clientRows,
632
+ isQueryLoading: isRowsLoading,
633
+ error: liveError,
634
+ } = useFrappeRows<TDoc>(serverSide ? undefined : connectionConfig, doctype, {
635
+ fields,
636
+ filters: activeFilters,
637
+ limit: null,
638
+ enabled: !serverSide,
639
+ messages: rowsMessages,
640
+ });
621
641
 
622
642
  // Keep-rows-and-reconcile for client/live-collection mode: a filter change
623
643
  // swaps the collection (new subscription), which reports loading from
@@ -659,19 +679,6 @@ export function FrappeTable<TDoc extends { name: string; doctype: string }>({
659
679
  ? !infiniteServerMode && serverLoading && hasLoadedOnce
660
680
  : isRowsLoading && lastGoodClientRows.current !== null;
661
681
 
662
- // Reset stale errors when the underlying collection changes (new doctype
663
- // or filters) so a recovered query doesn't keep showing the old failure.
664
- useEffect(() => {
665
- if (!serverSide) setErrorState(null);
666
- }, [collection, serverSide]);
667
-
668
- // Fallback surface for live-query failures the collection itself reports
669
- // (onSyncError above carries the specific message when available).
670
- useEffect(() => {
671
- if (serverSide || !isLiveError) return;
672
- setErrorState((prev) => prev ?? new Error(t("Failed to load {{doctype}}", { doctype })));
673
- }, [serverSide, isLiveError, doctype, t]);
674
-
675
682
  const handleSelectFilter = (filter: any) => {
676
683
  if (filter) {
677
684
  setActiveFilters(filter.filters);
@@ -695,8 +702,12 @@ export function FrappeTable<TDoc extends { name: string; doctype: string }>({
695
702
  await savedFiltersHook.deleteFilter(name);
696
703
  };
697
704
 
698
- if (errorState && error) {
699
- return <>{error(errorState)}</>;
705
+ // serverSide failures come from the fetch above; client/live failures come
706
+ // from useFrappeRows. Only one path is ever live at a time.
707
+ const resolvedError = serverSide ? errorState : liveError;
708
+
709
+ if (resolvedError && error) {
710
+ return <>{error(resolvedError)}</>;
700
711
  }
701
712
 
702
713
  const rowData = rows ?? [];
@@ -704,8 +715,8 @@ export function FrappeTable<TDoc extends { name: string; doctype: string }>({
704
715
  // Infinite serverSide delegates loading/empty chrome to DataTable.
705
716
  // After the first load, NEVER replace DataTable with empty/loading chrome
706
717
  // while a refetch is in flight — that was the named blank-the-list defect.
707
- const boundaryState = errorState
708
- ? { error: errorState }
718
+ const boundaryState = resolvedError
719
+ ? { error: resolvedError }
709
720
  : isRowsLoadingResolved
710
721
  ? { loading: loading ?? true }
711
722
  : rowData.length === 0 && !infiniteServerMode && !isFetching
@@ -713,7 +724,16 @@ export function FrappeTable<TDoc extends { name: string; doctype: string }>({
713
724
  : null;
714
725
  if (boundaryState) {
715
726
  return (
716
- <YStack {...knobProps.gap} flex={1}>
727
+ <YStack
728
+ {...knobProps.gap}
729
+ // flexBasis auto, not flex={1}: a basis-0 chain resolves to 0 in an
730
+ // auto-height parent and collapses the table to a sliver. Same
731
+ // geometry as DataTableRoot's own root.
732
+ flexGrow={1}
733
+ flexShrink={1}
734
+ flexBasis="auto"
735
+ minHeight={0}
736
+ >
717
737
  <FrappeReconnectIndicator config={connectionConfig} />
718
738
  <AsyncBoundary
719
739
  layout={layout === "list" || layout === "cards" ? "list" : "table"}
@@ -726,7 +746,16 @@ export function FrappeTable<TDoc extends { name: string; doctype: string }>({
726
746
  }
727
747
 
728
748
  return (
729
- <YStack {...knobProps.gap} flex={1}>
749
+ <YStack
750
+ {...knobProps.gap}
751
+ // flexBasis auto, not flex={1}: a basis-0 chain resolves to 0 in an
752
+ // auto-height parent and collapses the table to a sliver. Same
753
+ // geometry as DataTableRoot's own root.
754
+ flexGrow={1}
755
+ flexShrink={1}
756
+ flexBasis="auto"
757
+ minHeight={0}
758
+ >
730
759
  <FrappeReconnectIndicator config={connectionConfig} />
731
760
  {savedFilters && savedFiltersHook && (
732
761
  <XStack {...knobProps.gap} padding="$2">
@@ -75,10 +75,23 @@ function regionMeta(name: string, isTree: boolean) {
75
75
  };
76
76
  }
77
77
 
78
+ /** A chart of accounts: no parent field, no is_tree, the name is the path. */
79
+ function accountMeta(name: string) {
80
+ return {
81
+ name,
82
+ module: "QA",
83
+ title_field: "name",
84
+ is_tree: 0,
85
+ fields: [{ fieldname: "balance", fieldtype: "Currency", label: "Balance", in_list_view: 1 }],
86
+ permissions: [{ role: "All", read: 1 }],
87
+ };
88
+ }
89
+
78
90
  function handleMetaRequest(url: URL): Response | null {
79
91
  const metaMatch = url.pathname.match(/^\/api\/resource\/DocType\/(.+)$/);
80
92
  if (!metaMatch) return null;
81
93
  const name = decodeURIComponent(metaMatch[1]);
94
+ if (name === "QaAccount") return jsonResponse({ data: accountMeta(name) });
82
95
  return jsonResponse({ data: regionMeta(name, name !== "QaFlatDoc") });
83
96
  }
84
97
 
@@ -143,6 +156,52 @@ export const NotATree = () => (
143
156
  </FrappeProvider>
144
157
  );
145
158
 
159
+ interface Account {
160
+ name: string;
161
+ doctype: string;
162
+ balance: string;
163
+ }
164
+
165
+ /**
166
+ * Seven rows, and every one of them is a leaf. "Assets", "Assets:Personal"
167
+ * and "Assets:Personal:Bank" are not documents at all.
168
+ */
169
+ const accountDocs: Account[] = [
170
+ { name: "Assets:Personal:Bank:Checking", doctype: "QaAccount", balance: "4,120.55" },
171
+ { name: "Assets:Personal:Bank:Savings", doctype: "QaAccount", balance: "18,300.00" },
172
+ { name: "Assets:Personal:Cash", doctype: "QaAccount", balance: "260.00" },
173
+ { name: "Expenses:Groceries", doctype: "QaAccount", balance: "612.40" },
174
+ { name: "Expenses:Utilities:Power", doctype: "QaAccount", balance: "148.90" },
175
+ { name: "Income:Salary", doctype: "QaAccount", balance: "9,000.00" },
176
+ { name: "Liabilities:Credit Card", doctype: "QaAccount", balance: "-732.10" },
177
+ ];
178
+
179
+ /** Colon-path doctype: is_tree is 0, there is no parent field, tree renders. */
180
+ export const ColonPath = () => (
181
+ <FrappeProvider
182
+ baseURL={MOCK_HOST}
183
+ fixtures={new InMemoryFixtureProvider({ QaAccount: accountDocs })}
184
+ >
185
+ <FrappeTreeView
186
+ doctype="QaAccount"
187
+ pathSeparator=":"
188
+ pathField="name"
189
+ valueField="balance"
190
+ expandByDefault
191
+ onNodeClick={action("onNodeClick")}
192
+ onPathSelect={action("onPathSelect")}
193
+ />
194
+ </FrappeProvider>
195
+ );
196
+ ColonPath.parameters = {
197
+ docs: {
198
+ description: {
199
+ story:
200
+ "The account IS its path (Assets:Personal:Bank:Checking). Meta reports is_tree 0 and the doctype has no parent field, so the parent-field path would paint the unsupported state instead. pathSeparator synthesises the branches client-side from each row's own key. A synthesised branch carries no document: clicking it fires onPathSelect with the path and no doc, and onNodeClick stays silent. The balances hang off the leaves, which are the only real rows.",
201
+ },
202
+ },
203
+ };
204
+
146
205
  /** Tree doctype with zero root nodes: empty message. */
147
206
  export const EmptyTree = () => (
148
207
  <FrappeProvider baseURL={MOCK_HOST} fixtures={new InMemoryFixtureProvider({ QaRegionEmpty: [] })}>
@@ -1,14 +1,14 @@
1
- import { useDocTypeMeta, useFrappeCollection, useLiveQuery } from "@multiplatform.one/frappe";
2
- import { AsyncBoundary, TreeView, type TreeNode } from "@multiplatform.one/components";
1
+ import { useDocTypeMeta } from "@multiplatform.one/frappe";
2
+ import { AsyncBoundary, EmptyState, TreeView, type TreeNode } from "@multiplatform.one/components";
3
3
  import { TreeStructureIcon } from "@phosphor-icons/react";
4
- import React, { useCallback, useEffect, useMemo, useState } from "react";
4
+ import React, { useCallback, useMemo, useState } from "react";
5
5
  import { useTranslation } from "react-i18next";
6
6
  import { Text, YStack, type YStackProps } from "tamagui";
7
- import { useResolvedKnobs } from "@multiplatform.one/theme";
7
+ import { useGlyphColor, useResolvedKnobs } from "@multiplatform.one/theme";
8
8
  import { formCommonColors } from "@multiplatform.one/forms";
9
9
  import { useFrappeConfig } from "./FrappeProvider";
10
10
  import { FrappeReconnectIndicator } from "./FrappeReconnectIndicator";
11
- import { toLiveLoadError } from "./liveErrors";
11
+ import { useFrappeRows } from "./useFrappeRows";
12
12
 
13
13
  export interface FrappeTreeViewProps<TDoc extends { name: string; doctype: string }> extends Omit<
14
14
  YStackProps,
@@ -16,11 +16,32 @@ export interface FrappeTreeViewProps<TDoc extends { name: string; doctype: strin
16
16
  > {
17
17
  doctype: string;
18
18
  parentField?: string;
19
+ /**
20
+ * Separator that splits {@link FrappeTreeViewProps.pathField} into levels,
21
+ * e.g. ":" for an account named `Assets:Personal:Bank:Checking`. Setting it
22
+ * switches the tree to path mode: the branches between root and leaf are
23
+ * synthesised from the segments, `parentField` is neither read nor fetched,
24
+ * and the `is_tree` gate is skipped. A doctype whose hierarchy lives in the
25
+ * row's own key has no parent field and the server will never report
26
+ * `is_tree`.
27
+ */
28
+ pathSeparator?: string;
29
+ /**
30
+ * Row field holding the path. Path mode only; defaults to `name`. Path mode
31
+ * fetches `name`, this field, `valueField` and whatever `fields` adds, so a
32
+ * caller who needs more on the `onNodeClick` document asks for it there.
33
+ */
34
+ pathField?: string;
19
35
  titleField?: string;
20
36
  valueField?: string;
21
37
  fields?: readonly (keyof TDoc & string)[];
22
38
  filters?: Partial<TDoc> | Array<[keyof TDoc & string, string, any]>;
23
39
  onNodeClick?: (doc: Partial<TDoc>) => void;
40
+ /**
41
+ * Path-mode selection, fired for synthesised branches as well as documents.
42
+ * `doc` is present only when a document actually sits at that path.
43
+ */
44
+ onPathSelect?: (path: string, doc?: Partial<TDoc>) => void;
24
45
  /** Reserved for future DnD reparenting; not wired yet. */
25
46
  enableDragDrop?: boolean;
26
47
  /** Expand every branch on first paint (passed through to TreeView). */
@@ -88,20 +109,94 @@ export function buildTreeNodes<TDoc extends { name: string }>(
88
109
  return sortDocs(roots).map(buildNode);
89
110
  }
90
111
 
112
+ /** One level of the path forest, before it becomes TreeNodes. */
113
+ interface PathBucket<TDoc> {
114
+ path: string;
115
+ segment: string;
116
+ doc?: TDoc;
117
+ children: Map<string, PathBucket<TDoc>>;
118
+ }
119
+
120
+ /**
121
+ * Build a TreeNode forest from paths held on the rows themselves, e.g.
122
+ * `Assets:Personal:Bank:Checking` split on ":".
123
+ *
124
+ * The branches between root and leaf are not rows, so they are synthesised:
125
+ * a synthesised node carries no `data` and its `id` is the path prefix it
126
+ * stands for. A row whose path value is empty falls back to a single segment
127
+ * of its own name, so nothing is silently dropped.
128
+ */
129
+ export function buildPathTreeNodes<TDoc extends { name: string }>(
130
+ docs: TDoc[],
131
+ pathField: string,
132
+ separator: string,
133
+ ): TreeNode<Record<string, unknown>>[] {
134
+ const roots = new Map<string, PathBucket<TDoc>>();
135
+
136
+ const splitPath = (doc: TDoc): string[] => {
137
+ const raw = (doc as Record<string, unknown>)[pathField];
138
+ const value = raw == null ? "" : String(raw);
139
+ // An empty separator would split the value into single characters.
140
+ const segments = separator ? value.split(separator) : [value];
141
+ const cleaned = segments.map((segment) => segment.trim()).filter((segment) => segment !== "");
142
+ return cleaned.length > 0 ? cleaned : [doc.name];
143
+ };
144
+
145
+ for (const doc of docs) {
146
+ let level = roots;
147
+ let prefix = "";
148
+ let bucket: PathBucket<TDoc> | undefined;
149
+ for (const segment of splitPath(doc)) {
150
+ prefix = prefix ? `${prefix}${separator}${segment}` : segment;
151
+ bucket = level.get(segment);
152
+ if (!bucket) {
153
+ bucket = { path: prefix, segment, children: new Map() };
154
+ level.set(segment, bucket);
155
+ }
156
+ level = bucket.children;
157
+ }
158
+ // Two rows on one path: the first keeps the node rather than the last
159
+ // row the live query happened to deliver.
160
+ if (bucket && !bucket.doc) bucket.doc = doc;
161
+ }
162
+
163
+ const toNodes = (level: Map<string, PathBucket<TDoc>>): TreeNode<Record<string, unknown>>[] =>
164
+ Array.from(level.values())
165
+ .sort((a, b) => a.segment.localeCompare(b.segment))
166
+ .map((bucket) => {
167
+ const children = toNodes(bucket.children);
168
+ return {
169
+ id: bucket.path,
170
+ label: bucket.segment,
171
+ data: bucket.doc as unknown as Record<string, unknown> | undefined,
172
+ children: children.length > 0 ? children : undefined,
173
+ };
174
+ });
175
+
176
+ return toNodes(roots);
177
+ }
178
+
91
179
  /**
92
180
  * Thin Frappe wrapper around the generic TreeView component.
93
181
  *
94
182
  * Fetches the full DocType list via `useFrappeCollection` / `useLiveQuery`
95
183
  * (realtime-backed), then builds a `TreeNode` forest from the parent field.
184
+ *
185
+ * Pass `pathSeparator` instead when the hierarchy lives in the row's own key
186
+ * (`Assets:Personal:Bank:Checking`). The branches are synthesised client-side,
187
+ * so no parent field and no `is_tree` are needed.
96
188
  */
97
189
  export function FrappeTreeView<TDoc extends { name: string; doctype: string }>({
98
190
  doctype,
99
191
  parentField: parentFieldProp,
192
+ pathSeparator,
193
+ pathField,
100
194
  titleField: titleFieldProp,
101
195
  valueField,
102
196
  fields,
103
197
  filters,
104
198
  onNodeClick,
199
+ onPathSelect,
105
200
  enableDragDrop: _enableDragDrop = false,
106
201
  expandByDefault = false,
107
202
  display = "default",
@@ -116,6 +211,7 @@ export function FrappeTreeView<TDoc extends { name: string; doctype: string }>({
116
211
 
117
212
  const config = useFrappeConfig();
118
213
  const { knobProps } = useResolvedKnobs();
214
+ const emptyIconColor = useGlyphColor(formCommonColors.muted);
119
215
  const { t } = useTranslation();
120
216
  const [selectedId, setSelectedId] = useState<string | undefined>();
121
217
 
@@ -123,8 +219,10 @@ export function FrappeTreeView<TDoc extends { name: string; doctype: string }>({
123
219
  const finalAuth = auth ?? config?.auth;
124
220
  const finalSyncOptions = syncOptions ?? config?.syncOptions;
125
221
 
126
- if (!finalBaseURL) {
127
- throw new Error("FrappeTreeView requires baseURL prop or FrappeProvider with baseURL");
222
+ if (!finalBaseURL && !config?.fixtures) {
223
+ throw new Error(
224
+ "FrappeTreeView requires baseURL prop or FrappeProvider with baseURL or fixtures",
225
+ );
128
226
  }
129
227
 
130
228
  const appConfig = useMemo(
@@ -135,6 +233,7 @@ export function FrappeTreeView<TDoc extends { name: string; doctype: string }>({
135
233
  socketBaseURL: config?.socketBaseURL,
136
234
  auth: finalAuth,
137
235
  syncOptions: finalSyncOptions,
236
+ realtime: config?.realtime,
138
237
  fixtures: config?.fixtures,
139
238
  }),
140
239
  [
@@ -142,6 +241,7 @@ export function FrappeTreeView<TDoc extends { name: string; doctype: string }>({
142
241
  config?.socketPort,
143
242
  config?.siteName,
144
243
  config?.socketBaseURL,
244
+ config?.realtime,
145
245
  finalAuth,
146
246
  finalSyncOptions,
147
247
  config?.fixtures,
@@ -150,6 +250,8 @@ export function FrappeTreeView<TDoc extends { name: string; doctype: string }>({
150
250
 
151
251
  const { meta, isLoading: isMetaLoading, error: metaError } = useDocTypeMeta(appConfig, doctype);
152
252
 
253
+ const isPathMode = !!pathSeparator;
254
+ const effectivePathField = pathField ?? "name";
153
255
  const effectiveTitleField = titleFieldProp ?? meta?.title_field ?? "name";
154
256
  const effectiveParentField =
155
257
  parentFieldProp ?? `parent_${doctype.toLowerCase().replace(/ /g, "_")}`;
@@ -158,67 +260,75 @@ export function FrappeTreeView<TDoc extends { name: string; doctype: string }>({
158
260
  // lets callers continue (Guest peek / offline). Successful meta always
159
261
  // wins for the is_tree gate — including rejecting flat DocTypes that
160
262
  // happened to pass parentField.
161
- const isKnownNotTree = !!meta && !meta.is_tree;
162
- const canProceed = !!meta?.is_tree || (!!metaError && !meta && !!parentFieldProp);
263
+ //
264
+ // Path mode is the exception: the hierarchy comes from the row's own key,
265
+ // so there is nothing for is_tree to be right about.
266
+ const isKnownNotTree = !isPathMode && !!meta && !meta.is_tree;
267
+ const canProceed = isPathMode || !!meta?.is_tree || (!!metaError && !meta && !!parentFieldProp);
163
268
 
164
269
  const effectiveFields = useMemo(() => {
165
270
  const fieldSet = new Set<string>(fields as string[] | undefined);
166
271
  fieldSet.add("name");
167
- fieldSet.add(effectiveTitleField);
168
- fieldSet.add(effectiveParentField);
272
+ if (isPathMode) {
273
+ // The parent field does not exist on a path-shaped doctype; asking for
274
+ // it would fail the read on a live bench.
275
+ fieldSet.add(effectivePathField);
276
+ } else {
277
+ fieldSet.add(effectiveTitleField);
278
+ fieldSet.add(effectiveParentField);
279
+ }
169
280
  if (valueField) fieldSet.add(valueField);
170
281
  return Array.from(fieldSet) as (keyof TDoc & string)[];
171
- }, [fields, effectiveTitleField, effectiveParentField, valueField]);
172
-
173
- // Honest error surface: without onSyncError a 403/network failure renders
174
- // as an empty tree.
175
- const [syncError, setSyncError] = useState<Error | null>(null);
176
- const handleSyncError = useCallback(
177
- (err: unknown) => {
178
- setSyncError(
179
- toLiveLoadError(err, {
180
- permissionMessage: t("You do not have permission to view {{doctype}}", { doctype }),
181
- genericMessage: t("Failed to load {{doctype}} tree", { doctype }),
182
- }),
183
- );
184
- },
185
- [doctype, t],
186
- );
282
+ }, [
283
+ fields,
284
+ isPathMode,
285
+ effectivePathField,
286
+ effectiveTitleField,
287
+ effectiveParentField,
288
+ valueField,
289
+ ]);
187
290
 
188
- const collection = useFrappeCollection<TDoc>(
189
- canProceed && !isKnownNotTree ? appConfig : undefined,
190
- doctype,
191
- { fields: effectiveFields, filters, onSyncError: handleSyncError },
291
+ // The shared doctype read (MPO-251): collection + live query + the honest
292
+ // error surface a bare collection swallows — without it a 403 or a network
293
+ // failure renders as an empty tree. `limit: null` keeps the tree on the
294
+ // bench's own page length, as it was before the hook existed.
295
+ const rowsMessages = useMemo(
296
+ () => ({
297
+ permission: t("You do not have permission to view {{doctype}}", { doctype }),
298
+ generic: t("Failed to load {{doctype}} tree", { doctype }),
299
+ }),
300
+ [doctype, t],
192
301
  );
193
-
194
- // A new collection (doctype/filter change) starts with a clean slate.
195
- useEffect(() => {
196
- setSyncError(null);
197
- }, [collection]);
198
-
199
302
  const {
200
- data: rawData,
201
- isLoading: isDataLoading,
202
- isError,
203
- } = useLiveQuery((q) => (collection ? q.from({ _list: collection }) : null), [collection]);
204
-
205
- const docs = useMemo(() => (rawData as TDoc[] | undefined) ?? [], [rawData]);
303
+ rows: docs,
304
+ isQueryLoading: isDataLoading,
305
+ error: queryError,
306
+ } = useFrappeRows<TDoc>(appConfig, doctype, {
307
+ fields: effectiveFields,
308
+ filters,
309
+ limit: null,
310
+ enabled: canProceed && !isKnownNotTree,
311
+ messages: rowsMessages,
312
+ });
206
313
 
207
314
  const treeNodes = useMemo(
208
- () => buildTreeNodes(docs, effectiveParentField, effectiveTitleField),
209
- [docs, effectiveParentField, effectiveTitleField],
315
+ () =>
316
+ pathSeparator
317
+ ? buildPathTreeNodes(docs, effectivePathField, pathSeparator)
318
+ : buildTreeNodes(docs, effectiveParentField, effectiveTitleField),
319
+ [docs, pathSeparator, effectivePathField, effectiveParentField, effectiveTitleField],
210
320
  );
211
321
 
212
- const queryError =
213
- syncError ?? (isError ? new Error(t("Failed to load {{doctype}} tree", { doctype })) : null);
214
-
215
322
  const handleNodeSelect = useCallback(
216
323
  (node: TreeNode<Record<string, unknown>>) => {
217
324
  setSelectedId(node.id);
325
+ if (isPathMode) onPathSelect?.(node.id, node.data as Partial<TDoc> | undefined);
326
+ // A synthesised branch is not a document, so onNodeClick stays silent
327
+ // rather than handing a caller a name that would 404 on open.
218
328
  if (!node.data) return;
219
329
  onNodeClick?.(node.data as Partial<TDoc>);
220
330
  },
221
- [onNodeClick],
331
+ [isPathMode, onNodeClick, onPathSelect],
222
332
  );
223
333
 
224
334
  if (isMetaLoading) {
@@ -226,7 +336,7 @@ export function FrappeTreeView<TDoc extends { name: string; doctype: string }>({
226
336
  return <AsyncBoundary layout="list" loading {...stackProps} />;
227
337
  }
228
338
 
229
- if (metaError && !meta && !parentFieldProp) {
339
+ if (metaError && !meta && !parentFieldProp && !isPathMode) {
230
340
  if (error) return <>{error(metaError)}</>;
231
341
  return (
232
342
  <AsyncBoundary
@@ -241,12 +351,14 @@ export function FrappeTreeView<TDoc extends { name: string; doctype: string }>({
241
351
  if (isKnownNotTree) {
242
352
  const iconSize = Number(knobProps.controlIcon?.width) || 16;
243
353
  return (
244
- <YStack {...knobProps.panelPadding} alignItems="center" {...knobProps.gap} {...stackProps}>
245
- <TreeStructureIcon size={iconSize * 2} color={formCommonColors.muted} />
246
- <Text color={formCommonColors.muted} {...knobProps.body}>
247
- {t("This DocType does not support tree view")}
248
- </Text>
249
- </YStack>
354
+ <EmptyState
355
+ title={t("This DocType does not support tree view")}
356
+ description={t(
357
+ "Pass pathSeparator and pathField to build the hierarchy from a path-shaped value on each row. parentField alone does not, because a flat DocType has no parent field.",
358
+ )}
359
+ icon={<TreeStructureIcon size={iconSize * 2} color={emptyIconColor} />}
360
+ {...stackProps}
361
+ />
250
362
  );
251
363
  }
252
364
 
@@ -67,7 +67,7 @@ export function useFrappeCommentActions(
67
67
  ): FrappeCommentActions {
68
68
  return useMemo(() => {
69
69
  const app =
70
- config && !config.fixtures
70
+ config?.baseURL && !config.fixtures
71
71
  ? new FrappeApp(config.baseURL, (config.auth ?? {}) as Record<string, unknown>)
72
72
  : undefined;
73
73
 
@@ -81,6 +81,7 @@ function AttachmentsBody({
81
81
  socketBaseURL: config.socketBaseURL,
82
82
  auth: config.auth,
83
83
  syncOptions: config.syncOptions,
84
+ realtime: config.realtime,
84
85
  fixtures: config.fixtures,
85
86
  }
86
87
  : undefined,
@@ -41,6 +41,7 @@ export function Tags({ doctype, docname, onAdd, onRemove, enableAdd, ...props }:
41
41
  auth: config.auth,
42
42
  syncOptions: config.syncOptions,
43
43
  socketOptions: config.socketOptions,
44
+ realtime: config.realtime,
44
45
  fixtures: config.fixtures,
45
46
  }
46
47
  : undefined;
@@ -130,6 +130,7 @@ export function Timeline({
130
130
  auth: config.auth,
131
131
  syncOptions: config.syncOptions,
132
132
  socketOptions: config.socketOptions,
133
+ realtime: config.realtime,
133
134
  fixtures: config.fixtures,
134
135
  }
135
136
  : undefined;
@@ -207,7 +208,7 @@ export function Timeline({
207
208
 
208
209
  const resolveSessionUser = useCallback(async (): Promise<string> => {
209
210
  if (sessionUserRef.current) return sessionUserRef.current;
210
- if (config && !config.fixtures) {
211
+ if (config?.baseURL && !config.fixtures) {
211
212
  const app = new FrappeApp(config.baseURL, (config.auth ?? {}) as Record<string, unknown>);
212
213
  sessionUserRef.current = await app.auth().getLoggedInUser();
213
214
  } else {