@multiplatform.one/frappe-ui 7.28.0 → 7.29.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 (618) 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.cjs +20 -3
  5. package/dist/cjs/FileBrowser/index.native.js +20 -3
  6. package/dist/cjs/FileBrowser/index.native.js.map +1 -1
  7. package/dist/cjs/FileBrowser/types.native.js.map +1 -1
  8. package/dist/cjs/FileBrowser/viewPersistence.native.js.map +1 -1
  9. package/dist/cjs/FormSidebar.native.js.map +1 -1
  10. package/dist/cjs/FrappeAssignment.native.js.map +1 -1
  11. package/dist/cjs/FrappeCalendar.cjs +3 -2
  12. package/dist/cjs/FrappeCalendar.native.js +3 -2
  13. package/dist/cjs/FrappeCalendar.native.js.map +1 -1
  14. package/dist/cjs/FrappeChartCard.native.js.map +1 -1
  15. package/dist/cjs/FrappeConnectionIndicator.native.js.map +1 -1
  16. package/dist/cjs/FrappeDashboard.native.js.map +1 -1
  17. package/dist/cjs/FrappeForm.cjs +148 -464
  18. package/dist/cjs/FrappeForm.native.js +153 -634
  19. package/dist/cjs/FrappeForm.native.js.map +1 -1
  20. package/dist/cjs/FrappeFormActions.native.js.map +1 -1
  21. package/dist/cjs/FrappeFormConnections.native.js.map +1 -1
  22. package/dist/cjs/FrappeGantt.native.js.map +1 -1
  23. package/dist/cjs/FrappeImageView.native.js.map +1 -1
  24. package/dist/cjs/FrappeInsights.native.js.map +1 -1
  25. package/dist/cjs/FrappeKPICard.native.js.map +1 -1
  26. package/dist/cjs/FrappeKanban.native.js.map +1 -1
  27. package/dist/cjs/FrappeLikedBy.native.js.map +1 -1
  28. package/dist/cjs/FrappeList.native.js.map +1 -1
  29. package/dist/cjs/FrappeListView.cjs +5 -27
  30. package/dist/cjs/FrappeListView.native.js +11 -32
  31. package/dist/cjs/FrappeListView.native.js.map +1 -1
  32. package/dist/cjs/FrappeNotConfigured.native.js.map +1 -1
  33. package/dist/cjs/FrappeProvider.native.js.map +1 -1
  34. package/dist/cjs/FrappeReconnectIndicator.native.js.map +1 -1
  35. package/dist/cjs/FrappeRecordView.native.js.map +1 -1
  36. package/dist/cjs/FrappeReportBuilder.cjs +523 -309
  37. package/dist/cjs/FrappeReportBuilder.native.js +658 -353
  38. package/dist/cjs/FrappeReportBuilder.native.js.map +1 -1
  39. package/dist/cjs/FrappeReportView.cjs +35 -234
  40. package/dist/cjs/FrappeReportView.native.js +42 -286
  41. package/dist/cjs/FrappeReportView.native.js.map +1 -1
  42. package/dist/cjs/FrappeRowsReader.native.js.map +1 -1
  43. package/dist/cjs/FrappeTable.native.js.map +1 -1
  44. package/dist/cjs/FrappeTreeView.native.js.map +1 -1
  45. package/dist/cjs/SyncErrorNotice.native.js.map +1 -1
  46. package/dist/cjs/commentActions.native.js.map +1 -1
  47. package/dist/cjs/components/attachments.native.js.map +1 -1
  48. package/dist/cjs/components/tags.native.js.map +1 -1
  49. package/dist/cjs/components/timeline.native.js.map +1 -1
  50. package/dist/cjs/dependsOn.cjs +2 -2
  51. package/dist/cjs/dependsOn.native.js +1 -2
  52. package/dist/cjs/dependsOn.native.js.map +1 -1
  53. package/dist/cjs/desk/DeskFormPage.native.js.map +1 -1
  54. package/dist/cjs/desk/DeskFormSidebar.native.js.map +1 -1
  55. package/dist/cjs/desk/DeskListPage.native.js.map +1 -1
  56. package/dist/cjs/desk/DeskShell.native.js.map +1 -1
  57. package/dist/cjs/desk/DeskSidebar.native.js.map +1 -1
  58. package/dist/cjs/desk/awesomebar.native.js.map +1 -1
  59. package/dist/cjs/fieldOverrides.native.js.map +1 -1
  60. package/dist/cjs/fieldRegistry.native.js +31 -31
  61. package/dist/cjs/fieldRegistry.native.js.map +1 -1
  62. package/dist/cjs/fields/Barcode/index.native.js.map +1 -1
  63. package/dist/cjs/fields/Check/index.native.js.map +1 -1
  64. package/dist/cjs/fields/CodeEditor/index.native.js.map +1 -1
  65. package/dist/cjs/fields/Color/index.native.js.map +1 -1
  66. package/dist/cjs/fields/Data/index.native.js.map +1 -1
  67. package/dist/cjs/fields/Date/sheetKeyboard.native.js.map +1 -1
  68. package/dist/cjs/fields/Date/types.native.js.map +1 -1
  69. package/dist/cjs/fields/Date/wire.native.js.map +1 -1
  70. package/dist/cjs/fields/DateRange/index.native.js.map +1 -1
  71. package/dist/cjs/fields/Duration/index.native.js.map +1 -1
  72. package/dist/cjs/fields/DynamicLink.native.js.map +1 -1
  73. package/dist/cjs/fields/FileUpload.native.js.map +1 -1
  74. package/dist/cjs/fields/FileUploadField/index.native.js.map +1 -1
  75. package/dist/cjs/fields/Geolocation/index.native.js.map +1 -1
  76. package/dist/cjs/fields/HTML/index.native.js.map +1 -1
  77. package/dist/cjs/fields/Heading/index.native.js.map +1 -1
  78. package/dist/cjs/fields/Icon/index.native.js.map +1 -1
  79. package/dist/cjs/fields/Link.native.js.map +1 -1
  80. package/dist/cjs/fields/LinkTree.native.js.map +1 -1
  81. package/dist/cjs/fields/LongText/index.native.js.map +1 -1
  82. package/dist/cjs/fields/MentionInput/index.native.js.map +1 -1
  83. package/dist/cjs/fields/Numeric/index.native.js.map +1 -1
  84. package/dist/cjs/fields/OTPInput/index.native.js.map +1 -1
  85. package/dist/cjs/fields/Password/index.native.js.map +1 -1
  86. package/dist/cjs/fields/Phone/index.native.js.map +1 -1
  87. package/dist/cjs/fields/Progress/index.native.js.map +1 -1
  88. package/dist/cjs/fields/RadioGroup/index.native.js.map +1 -1
  89. package/dist/cjs/fields/Rating/index.native.js.map +1 -1
  90. package/dist/cjs/fields/ReadOnly/index.native.js.map +1 -1
  91. package/dist/cjs/fields/Select/index.native.js.map +1 -1
  92. package/dist/cjs/fields/Signature/index.native.js.map +1 -1
  93. package/dist/cjs/fields/Slider/index.native.js.map +1 -1
  94. package/dist/cjs/fields/SmallText/index.native.js.map +1 -1
  95. package/dist/cjs/fields/Switch/index.native.js.map +1 -1
  96. package/dist/cjs/fields/TableMultiSelect.native.js.map +1 -1
  97. package/dist/cjs/fields/TextEditor/types.native.js.map +1 -1
  98. package/dist/cjs/fields/TimePicker/index.native.js.map +1 -1
  99. package/dist/cjs/fields/ToggleGroup/index.native.js.map +1 -1
  100. package/dist/cjs/fields/shared/EditorPreviewPanes.cjs +2 -2
  101. package/dist/cjs/fields/shared/EditorPreviewPanes.native.js +2 -2
  102. package/dist/cjs/fields/shared/EditorPreviewPanes.native.js.map +1 -1
  103. package/dist/cjs/filterFields.native.js.map +1 -1
  104. package/dist/cjs/formEngine/createPrefill.native.js.map +1 -1
  105. package/dist/cjs/formEngine/dirtyTracking.native.js.map +1 -1
  106. package/dist/cjs/formEngine/docLifecycle.native.js.map +1 -1
  107. package/dist/cjs/formEngine/docPermissions.cjs +20 -0
  108. package/dist/cjs/formEngine/docPermissions.native.js +69 -0
  109. package/dist/cjs/formEngine/docPermissions.native.js.map +1 -1
  110. package/dist/cjs/formEngine/doctypeMeta.native.js.map +1 -1
  111. package/dist/cjs/formEngine/fetchFrom.native.js.map +1 -1
  112. package/dist/cjs/formEngine/fieldPermissions.native.js.map +1 -1
  113. package/dist/cjs/formEngine/formActions.native.js.map +1 -1
  114. package/dist/cjs/formEngine/formLayout.native.js.map +1 -1
  115. package/dist/cjs/formEngine/index.cjs +2 -0
  116. package/dist/cjs/formEngine/index.native.js +2 -0
  117. package/dist/cjs/formEngine/index.native.js.map +1 -1
  118. package/dist/cjs/formEngine/useAmendedAs.native.js.map +1 -1
  119. package/dist/cjs/formEngine/useDocRights.native.js.map +1 -1
  120. package/dist/cjs/formEngine/useFormEngine.native.js.map +1 -1
  121. package/dist/cjs/formEngine/useSessionRoles.native.js.map +1 -1
  122. package/dist/cjs/frappeConnections.native.js.map +1 -1
  123. package/dist/cjs/frappeEventColor.native.js.map +1 -1
  124. package/dist/cjs/frappeNavigation.native.js.map +1 -1
  125. package/dist/cjs/frappeStoryTarget.native.js.map +1 -1
  126. package/dist/cjs/frappeUsers.native.js.map +1 -1
  127. package/dist/cjs/index.cjs +67 -7
  128. package/dist/cjs/index.native.js +101 -41
  129. package/dist/cjs/index.native.js.map +1 -1
  130. package/dist/cjs/insights/InsightsFacetTags.native.js.map +1 -1
  131. package/dist/cjs/insights/InsightsKpiBand.native.js.map +1 -1
  132. package/dist/cjs/insights/InsightsLeaders.native.js.map +1 -1
  133. package/dist/cjs/insights/InsightsRecords.native.js.map +1 -1
  134. package/dist/cjs/insights/InsightsTable.native.js.map +1 -1
  135. package/dist/cjs/insights/insightsData.native.js.map +1 -1
  136. package/dist/cjs/insights/insightsRecord.native.js.map +1 -1
  137. package/dist/cjs/list/FacetBadge.native.js.map +1 -1
  138. package/dist/cjs/list/FacetRail.native.js.map +1 -1
  139. package/dist/cjs/list/ImageWell.native.js.map +1 -1
  140. package/dist/cjs/list/ListControls.native.js.map +1 -1
  141. package/dist/cjs/list/ListToastHost.native.js.map +1 -1
  142. package/dist/cjs/list/RangeFilter.native.js.map +1 -1
  143. package/dist/cjs/list/ShufflePanel.native.js.map +1 -1
  144. package/dist/cjs/list/facetReading.native.js.map +1 -1
  145. package/dist/cjs/list/favorites.native.js.map +1 -1
  146. package/dist/cjs/list/listColumns.native.js.map +1 -1
  147. package/dist/cjs/list/listFields.native.js.map +1 -1
  148. package/dist/cjs/list/listFormat.native.js.map +1 -1
  149. package/dist/cjs/list/listState.native.js.map +1 -1
  150. package/dist/cjs/list/recordLook.native.js.map +1 -1
  151. package/dist/cjs/list/statusColors.native.js.map +1 -1
  152. package/dist/cjs/list/useListControls.native.js.map +1 -1
  153. package/dist/cjs/liveErrors.cjs +8 -2
  154. package/dist/cjs/liveErrors.native.js +8 -2
  155. package/dist/cjs/liveErrors.native.js.map +1 -1
  156. package/dist/cjs/measures.cjs +31 -0
  157. package/dist/cjs/measures.native.js +34 -0
  158. package/dist/cjs/measures.native.js.map +1 -0
  159. package/dist/cjs/record/RecordBars.native.js.map +1 -1
  160. package/dist/cjs/record/RecordGallery.native.js.map +1 -1
  161. package/dist/cjs/record/RecordHero.native.js.map +1 -1
  162. package/dist/cjs/record/RecordPage.native.js.map +1 -1
  163. package/dist/cjs/record/RecordPager.native.js.map +1 -1
  164. package/dist/cjs/record/RecordRows.native.js.map +1 -1
  165. package/dist/cjs/record/recordData.native.js.map +1 -1
  166. package/dist/cjs/record/recordSections.native.js.map +1 -1
  167. package/dist/cjs/recordShape.cjs +103 -0
  168. package/dist/cjs/recordShape.native.js +115 -0
  169. package/dist/cjs/recordShape.native.js.map +1 -0
  170. package/dist/cjs/report/ReportGrid.cjs +453 -0
  171. package/dist/cjs/report/ReportGrid.native.js +510 -0
  172. package/dist/cjs/report/ReportGrid.native.js.map +1 -0
  173. package/dist/cjs/report/ReportViewToolbar.cjs +253 -0
  174. package/dist/cjs/report/ReportViewToolbar.native.js +303 -0
  175. package/dist/cjs/report/ReportViewToolbar.native.js.map +1 -0
  176. package/dist/cjs/report/queryReport.cjs +444 -0
  177. package/dist/cjs/report/queryReport.native.js +588 -0
  178. package/dist/cjs/report/queryReport.native.js.map +1 -0
  179. package/dist/cjs/report/queryReportColumns.cjs +131 -0
  180. package/dist/cjs/report/queryReportColumns.native.js +159 -0
  181. package/dist/cjs/report/queryReportColumns.native.js.map +1 -0
  182. package/dist/cjs/report/reportViewModel.cjs +386 -0
  183. package/dist/cjs/report/reportViewModel.native.js +657 -0
  184. package/dist/cjs/report/reportViewModel.native.js.map +1 -0
  185. package/dist/cjs/report/savedReports.cjs +137 -0
  186. package/dist/cjs/report/savedReports.native.js +169 -0
  187. package/dist/cjs/report/savedReports.native.js.map +1 -0
  188. package/dist/cjs/report/useFrappeReport.cjs +184 -0
  189. package/dist/cjs/report/useFrappeReport.native.js +214 -0
  190. package/dist/cjs/report/useFrappeReport.native.js.map +1 -0
  191. package/dist/cjs/report/useQueryReport.cjs +201 -0
  192. package/dist/cjs/report/useQueryReport.native.js +233 -0
  193. package/dist/cjs/report/useQueryReport.native.js.map +1 -0
  194. package/dist/cjs/resolveControl.native.js.map +1 -1
  195. package/dist/cjs/schemaForm/SchemaWizard.native.js.map +1 -1
  196. package/dist/cjs/schemaForm/applyFieldOrder.native.js.map +1 -1
  197. package/dist/cjs/schemaForm/index.native.js +1 -1
  198. package/dist/cjs/schemaForm/index.native.js.map +1 -1
  199. package/dist/cjs/shared/devWarn.native.js.map +1 -1
  200. package/dist/cjs/shared/useKeyboardInset.native.js.map +1 -1
  201. package/dist/cjs/syncError.native.js.map +1 -1
  202. package/dist/cjs/useConnectionFilters.native.js.map +1 -1
  203. package/dist/cjs/useFrappeAggregate.native.js.map +1 -1
  204. package/dist/cjs/useFrappeFacets.native.js.map +1 -1
  205. package/dist/cjs/useFrappeForm.cjs +558 -0
  206. package/dist/cjs/useFrappeForm.native.js +714 -0
  207. package/dist/cjs/useFrappeForm.native.js.map +1 -0
  208. package/dist/cjs/useFrappePagination.native.js.map +1 -1
  209. package/dist/cjs/useFrappeRows.native.js.map +1 -1
  210. package/dist/esm/ChartCard.native.js.map +1 -1
  211. package/dist/esm/FileBrowser/AttachLibrary.native.js.map +1 -1
  212. package/dist/esm/FileBrowser/folderTree.native.js.map +1 -1
  213. package/dist/esm/FileBrowser/index.mjs +20 -3
  214. package/dist/esm/FileBrowser/index.mjs.map +1 -1
  215. package/dist/esm/FileBrowser/index.native.js +20 -3
  216. package/dist/esm/FileBrowser/index.native.js.map +1 -1
  217. package/dist/esm/FileBrowser/types.native.js.map +1 -1
  218. package/dist/esm/FileBrowser/viewPersistence.native.js.map +1 -1
  219. package/dist/esm/FormSidebar.native.js.map +1 -1
  220. package/dist/esm/FrappeAssignment.native.js.map +1 -1
  221. package/dist/esm/FrappeCalendar.mjs +4 -3
  222. package/dist/esm/FrappeCalendar.mjs.map +1 -1
  223. package/dist/esm/FrappeCalendar.native.js +4 -3
  224. package/dist/esm/FrappeCalendar.native.js.map +1 -1
  225. package/dist/esm/FrappeChartCard.native.js.map +1 -1
  226. package/dist/esm/FrappeConnectionIndicator.native.js.map +1 -1
  227. package/dist/esm/FrappeDashboard.native.js.map +1 -1
  228. package/dist/esm/FrappeForm.mjs +151 -467
  229. package/dist/esm/FrappeForm.mjs.map +1 -1
  230. package/dist/esm/FrappeForm.native.js +155 -636
  231. package/dist/esm/FrappeForm.native.js.map +1 -1
  232. package/dist/esm/FrappeFormActions.native.js.map +1 -1
  233. package/dist/esm/FrappeFormConnections.native.js.map +1 -1
  234. package/dist/esm/FrappeGantt.native.js.map +1 -1
  235. package/dist/esm/FrappeImageView.native.js.map +1 -1
  236. package/dist/esm/FrappeInsights.native.js.map +1 -1
  237. package/dist/esm/FrappeKPICard.native.js.map +1 -1
  238. package/dist/esm/FrappeKanban.native.js.map +1 -1
  239. package/dist/esm/FrappeLikedBy.native.js.map +1 -1
  240. package/dist/esm/FrappeList.native.js.map +1 -1
  241. package/dist/esm/FrappeListView.mjs +6 -28
  242. package/dist/esm/FrappeListView.mjs.map +1 -1
  243. package/dist/esm/FrappeListView.native.js +12 -33
  244. package/dist/esm/FrappeListView.native.js.map +1 -1
  245. package/dist/esm/FrappeNotConfigured.native.js.map +1 -1
  246. package/dist/esm/FrappeProvider.native.js.map +1 -1
  247. package/dist/esm/FrappeReconnectIndicator.native.js.map +1 -1
  248. package/dist/esm/FrappeRecordView.native.js.map +1 -1
  249. package/dist/esm/FrappeReportBuilder.mjs +526 -312
  250. package/dist/esm/FrappeReportBuilder.mjs.map +1 -1
  251. package/dist/esm/FrappeReportBuilder.native.js +661 -356
  252. package/dist/esm/FrappeReportBuilder.native.js.map +1 -1
  253. package/dist/esm/FrappeReportView.mjs +30 -229
  254. package/dist/esm/FrappeReportView.mjs.map +1 -1
  255. package/dist/esm/FrappeReportView.native.js +34 -278
  256. package/dist/esm/FrappeReportView.native.js.map +1 -1
  257. package/dist/esm/FrappeRowsReader.native.js.map +1 -1
  258. package/dist/esm/FrappeTable.native.js.map +1 -1
  259. package/dist/esm/FrappeTreeView.native.js.map +1 -1
  260. package/dist/esm/SyncErrorNotice.native.js.map +1 -1
  261. package/dist/esm/commentActions.native.js.map +1 -1
  262. package/dist/esm/components/attachments.native.js.map +1 -1
  263. package/dist/esm/components/tags.native.js.map +1 -1
  264. package/dist/esm/components/timeline.native.js.map +1 -1
  265. package/dist/esm/dependsOn.mjs +2 -2
  266. package/dist/esm/dependsOn.mjs.map +1 -1
  267. package/dist/esm/dependsOn.native.js +1 -2
  268. package/dist/esm/dependsOn.native.js.map +1 -1
  269. package/dist/esm/desk/DeskFormPage.native.js.map +1 -1
  270. package/dist/esm/desk/DeskFormSidebar.native.js.map +1 -1
  271. package/dist/esm/desk/DeskListPage.native.js.map +1 -1
  272. package/dist/esm/desk/DeskShell.native.js.map +1 -1
  273. package/dist/esm/desk/DeskSidebar.native.js.map +1 -1
  274. package/dist/esm/desk/awesomebar.native.js.map +1 -1
  275. package/dist/esm/fieldOverrides.native.js.map +1 -1
  276. package/dist/esm/fieldRegistry.native.js.map +1 -1
  277. package/dist/esm/fields/Barcode/index.native.js.map +1 -1
  278. package/dist/esm/fields/Check/index.native.js.map +1 -1
  279. package/dist/esm/fields/CodeEditor/index.native.js.map +1 -1
  280. package/dist/esm/fields/Color/index.native.js.map +1 -1
  281. package/dist/esm/fields/Data/index.native.js.map +1 -1
  282. package/dist/esm/fields/Date/sheetKeyboard.native.js.map +1 -1
  283. package/dist/esm/fields/Date/types.native.js.map +1 -1
  284. package/dist/esm/fields/Date/wire.native.js.map +1 -1
  285. package/dist/esm/fields/DateRange/index.native.js.map +1 -1
  286. package/dist/esm/fields/Duration/index.native.js.map +1 -1
  287. package/dist/esm/fields/DynamicLink.native.js.map +1 -1
  288. package/dist/esm/fields/FileUpload.native.js.map +1 -1
  289. package/dist/esm/fields/FileUploadField/index.native.js.map +1 -1
  290. package/dist/esm/fields/Geolocation/index.native.js.map +1 -1
  291. package/dist/esm/fields/HTML/index.native.js.map +1 -1
  292. package/dist/esm/fields/Heading/index.native.js.map +1 -1
  293. package/dist/esm/fields/Icon/index.native.js.map +1 -1
  294. package/dist/esm/fields/Link.native.js.map +1 -1
  295. package/dist/esm/fields/LinkTree.native.js.map +1 -1
  296. package/dist/esm/fields/LongText/index.native.js.map +1 -1
  297. package/dist/esm/fields/MentionInput/index.native.js.map +1 -1
  298. package/dist/esm/fields/Numeric/index.native.js.map +1 -1
  299. package/dist/esm/fields/OTPInput/index.native.js.map +1 -1
  300. package/dist/esm/fields/Password/index.native.js.map +1 -1
  301. package/dist/esm/fields/Phone/index.native.js.map +1 -1
  302. package/dist/esm/fields/Progress/index.native.js.map +1 -1
  303. package/dist/esm/fields/RadioGroup/index.native.js.map +1 -1
  304. package/dist/esm/fields/Rating/index.native.js.map +1 -1
  305. package/dist/esm/fields/ReadOnly/index.native.js.map +1 -1
  306. package/dist/esm/fields/Select/index.native.js.map +1 -1
  307. package/dist/esm/fields/Signature/index.native.js.map +1 -1
  308. package/dist/esm/fields/Slider/index.native.js.map +1 -1
  309. package/dist/esm/fields/SmallText/index.native.js.map +1 -1
  310. package/dist/esm/fields/Switch/index.native.js.map +1 -1
  311. package/dist/esm/fields/TableMultiSelect.native.js.map +1 -1
  312. package/dist/esm/fields/TextEditor/types.native.js.map +1 -1
  313. package/dist/esm/fields/TimePicker/index.native.js.map +1 -1
  314. package/dist/esm/fields/ToggleGroup/index.native.js.map +1 -1
  315. package/dist/esm/fields/shared/EditorPreviewPanes.mjs +2 -2
  316. package/dist/esm/fields/shared/EditorPreviewPanes.mjs.map +1 -1
  317. package/dist/esm/fields/shared/EditorPreviewPanes.native.js +2 -2
  318. package/dist/esm/fields/shared/EditorPreviewPanes.native.js.map +1 -1
  319. package/dist/esm/filterFields.native.js.map +1 -1
  320. package/dist/esm/formEngine/createPrefill.native.js.map +1 -1
  321. package/dist/esm/formEngine/dirtyTracking.native.js.map +1 -1
  322. package/dist/esm/formEngine/docLifecycle.native.js.map +1 -1
  323. package/dist/esm/formEngine/docPermissions.mjs +19 -1
  324. package/dist/esm/formEngine/docPermissions.mjs.map +1 -1
  325. package/dist/esm/formEngine/docPermissions.native.js +68 -1
  326. package/dist/esm/formEngine/docPermissions.native.js.map +1 -1
  327. package/dist/esm/formEngine/doctypeMeta.native.js.map +1 -1
  328. package/dist/esm/formEngine/fetchFrom.native.js.map +1 -1
  329. package/dist/esm/formEngine/fieldPermissions.native.js.map +1 -1
  330. package/dist/esm/formEngine/formActions.native.js.map +1 -1
  331. package/dist/esm/formEngine/formLayout.native.js.map +1 -1
  332. package/dist/esm/formEngine/index.mjs +2 -2
  333. package/dist/esm/formEngine/index.mjs.map +1 -1
  334. package/dist/esm/formEngine/index.native.js +2 -2
  335. package/dist/esm/formEngine/index.native.js.map +1 -1
  336. package/dist/esm/formEngine/useAmendedAs.native.js.map +1 -1
  337. package/dist/esm/formEngine/useDocRights.native.js.map +1 -1
  338. package/dist/esm/formEngine/useFormEngine.native.js.map +1 -1
  339. package/dist/esm/formEngine/useSessionRoles.native.js.map +1 -1
  340. package/dist/esm/frappeConnections.native.js.map +1 -1
  341. package/dist/esm/frappeEventColor.native.js.map +1 -1
  342. package/dist/esm/frappeNavigation.native.js.map +1 -1
  343. package/dist/esm/frappeStoryTarget.native.js.map +1 -1
  344. package/dist/esm/frappeUsers.native.js.map +1 -1
  345. package/dist/esm/index.mjs +16 -4
  346. package/dist/esm/index.mjs.map +1 -1
  347. package/dist/esm/index.native.js +16 -4
  348. package/dist/esm/index.native.js.map +1 -1
  349. package/dist/esm/insights/InsightsFacetTags.native.js.map +1 -1
  350. package/dist/esm/insights/InsightsKpiBand.native.js.map +1 -1
  351. package/dist/esm/insights/InsightsLeaders.native.js.map +1 -1
  352. package/dist/esm/insights/InsightsRecords.native.js.map +1 -1
  353. package/dist/esm/insights/InsightsTable.native.js.map +1 -1
  354. package/dist/esm/insights/insightsData.native.js.map +1 -1
  355. package/dist/esm/insights/insightsRecord.native.js.map +1 -1
  356. package/dist/esm/list/FacetBadge.native.js.map +1 -1
  357. package/dist/esm/list/FacetRail.native.js.map +1 -1
  358. package/dist/esm/list/ImageWell.native.js.map +1 -1
  359. package/dist/esm/list/ListControls.native.js.map +1 -1
  360. package/dist/esm/list/ListToastHost.native.js.map +1 -1
  361. package/dist/esm/list/RangeFilter.native.js.map +1 -1
  362. package/dist/esm/list/ShufflePanel.native.js.map +1 -1
  363. package/dist/esm/list/facetReading.native.js.map +1 -1
  364. package/dist/esm/list/favorites.native.js.map +1 -1
  365. package/dist/esm/list/listColumns.native.js.map +1 -1
  366. package/dist/esm/list/listFields.native.js.map +1 -1
  367. package/dist/esm/list/listFormat.native.js.map +1 -1
  368. package/dist/esm/list/listState.native.js.map +1 -1
  369. package/dist/esm/list/recordLook.native.js.map +1 -1
  370. package/dist/esm/list/statusColors.native.js.map +1 -1
  371. package/dist/esm/list/useListControls.native.js.map +1 -1
  372. package/dist/esm/liveErrors.mjs +8 -3
  373. package/dist/esm/liveErrors.mjs.map +1 -1
  374. package/dist/esm/liveErrors.native.js +8 -3
  375. package/dist/esm/liveErrors.native.js.map +1 -1
  376. package/dist/esm/measures.mjs +5 -0
  377. package/dist/esm/measures.mjs.map +1 -0
  378. package/dist/esm/measures.native.js +5 -0
  379. package/dist/esm/measures.native.js.map +1 -0
  380. package/dist/esm/record/RecordBars.native.js.map +1 -1
  381. package/dist/esm/record/RecordGallery.native.js.map +1 -1
  382. package/dist/esm/record/RecordHero.native.js.map +1 -1
  383. package/dist/esm/record/RecordPage.native.js.map +1 -1
  384. package/dist/esm/record/RecordPager.native.js.map +1 -1
  385. package/dist/esm/record/RecordRows.native.js.map +1 -1
  386. package/dist/esm/record/recordData.native.js.map +1 -1
  387. package/dist/esm/record/recordSections.native.js.map +1 -1
  388. package/dist/esm/recordShape.mjs +74 -0
  389. package/dist/esm/recordShape.mjs.map +1 -0
  390. package/dist/esm/recordShape.native.js +83 -0
  391. package/dist/esm/recordShape.native.js.map +1 -0
  392. package/dist/esm/report/ReportGrid.mjs +428 -0
  393. package/dist/esm/report/ReportGrid.mjs.map +1 -0
  394. package/dist/esm/report/ReportGrid.native.js +471 -0
  395. package/dist/esm/report/ReportGrid.native.js.map +1 -0
  396. package/dist/esm/report/ReportViewToolbar.mjs +228 -0
  397. package/dist/esm/report/ReportViewToolbar.mjs.map +1 -0
  398. package/dist/esm/report/ReportViewToolbar.native.js +264 -0
  399. package/dist/esm/report/ReportViewToolbar.native.js.map +1 -0
  400. package/dist/esm/report/queryReport.mjs +404 -0
  401. package/dist/esm/report/queryReport.mjs.map +1 -0
  402. package/dist/esm/report/queryReport.native.js +545 -0
  403. package/dist/esm/report/queryReport.native.js.map +1 -0
  404. package/dist/esm/report/queryReportColumns.mjs +105 -0
  405. package/dist/esm/report/queryReportColumns.mjs.map +1 -0
  406. package/dist/esm/report/queryReportColumns.native.js +119 -0
  407. package/dist/esm/report/queryReportColumns.native.js.map +1 -0
  408. package/dist/esm/report/reportViewModel.mjs +343 -0
  409. package/dist/esm/report/reportViewModel.mjs.map +1 -0
  410. package/dist/esm/report/reportViewModel.native.js +611 -0
  411. package/dist/esm/report/reportViewModel.native.js.map +1 -0
  412. package/dist/esm/report/savedReports.mjs +112 -0
  413. package/dist/esm/report/savedReports.mjs.map +1 -0
  414. package/dist/esm/report/savedReports.native.js +141 -0
  415. package/dist/esm/report/savedReports.native.js.map +1 -0
  416. package/dist/esm/report/useFrappeReport.mjs +158 -0
  417. package/dist/esm/report/useFrappeReport.mjs.map +1 -0
  418. package/dist/esm/report/useFrappeReport.native.js +185 -0
  419. package/dist/esm/report/useFrappeReport.native.js.map +1 -0
  420. package/dist/esm/report/useQueryReport.mjs +176 -0
  421. package/dist/esm/report/useQueryReport.mjs.map +1 -0
  422. package/dist/esm/report/useQueryReport.native.js +205 -0
  423. package/dist/esm/report/useQueryReport.native.js.map +1 -0
  424. package/dist/esm/resolveControl.native.js.map +1 -1
  425. package/dist/esm/schemaForm/SchemaWizard.native.js.map +1 -1
  426. package/dist/esm/schemaForm/applyFieldOrder.native.js.map +1 -1
  427. package/dist/esm/schemaForm/index.native.js.map +1 -1
  428. package/dist/esm/shared/devWarn.native.js.map +1 -1
  429. package/dist/esm/shared/useKeyboardInset.native.js.map +1 -1
  430. package/dist/esm/syncError.native.js.map +1 -1
  431. package/dist/esm/useConnectionFilters.native.js.map +1 -1
  432. package/dist/esm/useFrappeAggregate.native.js.map +1 -1
  433. package/dist/esm/useFrappeFacets.native.js.map +1 -1
  434. package/dist/esm/useFrappeForm.mjs +533 -0
  435. package/dist/esm/useFrappeForm.mjs.map +1 -0
  436. package/dist/esm/useFrappeForm.native.js +686 -0
  437. package/dist/esm/useFrappeForm.native.js.map +1 -0
  438. package/dist/esm/useFrappePagination.native.js.map +1 -1
  439. package/dist/esm/useFrappeRows.native.js.map +1 -1
  440. package/dist/jsx/FileBrowser/index.mjs +20 -3
  441. package/dist/jsx/FileBrowser/index.mjs.map +1 -1
  442. package/dist/jsx/FileBrowser/index.native.js +20 -3
  443. package/dist/jsx/FileBrowser/index.native.js.map +1 -1
  444. package/dist/jsx/FrappeCalendar.mjs +4 -3
  445. package/dist/jsx/FrappeCalendar.mjs.map +1 -1
  446. package/dist/jsx/FrappeCalendar.native.js +3 -2
  447. package/dist/jsx/FrappeCalendar.native.js.map +1 -1
  448. package/dist/jsx/FrappeForm.mjs +151 -467
  449. package/dist/jsx/FrappeForm.mjs.map +1 -1
  450. package/dist/jsx/FrappeForm.native.js +152 -633
  451. package/dist/jsx/FrappeForm.native.js.map +1 -1
  452. package/dist/jsx/FrappeListView.mjs +6 -28
  453. package/dist/jsx/FrappeListView.mjs.map +1 -1
  454. package/dist/jsx/FrappeListView.native.js +11 -32
  455. package/dist/jsx/FrappeListView.native.js.map +1 -1
  456. package/dist/jsx/FrappeReportBuilder.mjs +526 -312
  457. package/dist/jsx/FrappeReportBuilder.mjs.map +1 -1
  458. package/dist/jsx/FrappeReportBuilder.native.js +658 -353
  459. package/dist/jsx/FrappeReportBuilder.native.js.map +1 -1
  460. package/dist/jsx/FrappeReportView.mjs +30 -229
  461. package/dist/jsx/FrappeReportView.mjs.map +1 -1
  462. package/dist/jsx/FrappeReportView.native.js +39 -283
  463. package/dist/jsx/FrappeReportView.native.js.map +1 -1
  464. package/dist/jsx/dependsOn.mjs +2 -2
  465. package/dist/jsx/dependsOn.mjs.map +1 -1
  466. package/dist/jsx/dependsOn.native.js +1 -2
  467. package/dist/jsx/dependsOn.native.js.map +1 -1
  468. package/dist/jsx/fields/shared/EditorPreviewPanes.mjs +2 -2
  469. package/dist/jsx/fields/shared/EditorPreviewPanes.mjs.map +1 -1
  470. package/dist/jsx/fields/shared/EditorPreviewPanes.native.js +2 -2
  471. package/dist/jsx/fields/shared/EditorPreviewPanes.native.js.map +1 -1
  472. package/dist/jsx/formEngine/docPermissions.mjs +19 -1
  473. package/dist/jsx/formEngine/docPermissions.mjs.map +1 -1
  474. package/dist/jsx/formEngine/docPermissions.native.js +69 -0
  475. package/dist/jsx/formEngine/docPermissions.native.js.map +1 -1
  476. package/dist/jsx/formEngine/index.mjs +2 -2
  477. package/dist/jsx/formEngine/index.mjs.map +1 -1
  478. package/dist/jsx/formEngine/index.native.js +2 -0
  479. package/dist/jsx/formEngine/index.native.js.map +1 -1
  480. package/dist/jsx/index.js +16 -4
  481. package/dist/jsx/index.js.map +1 -1
  482. package/dist/jsx/index.mjs +16 -4
  483. package/dist/jsx/index.mjs.map +1 -1
  484. package/dist/jsx/index.native.js +67 -7
  485. package/dist/jsx/index.native.js.map +1 -1
  486. package/dist/jsx/liveErrors.mjs +8 -3
  487. package/dist/jsx/liveErrors.mjs.map +1 -1
  488. package/dist/jsx/liveErrors.native.js +8 -2
  489. package/dist/jsx/liveErrors.native.js.map +1 -1
  490. package/dist/jsx/measures.mjs +5 -0
  491. package/dist/jsx/measures.mjs.map +1 -0
  492. package/dist/jsx/measures.native.js +34 -0
  493. package/dist/jsx/measures.native.js.map +1 -0
  494. package/dist/jsx/recordShape.mjs +74 -0
  495. package/dist/jsx/recordShape.mjs.map +1 -0
  496. package/dist/jsx/recordShape.native.js +115 -0
  497. package/dist/jsx/recordShape.native.js.map +1 -0
  498. package/dist/jsx/report/ReportGrid.mjs +428 -0
  499. package/dist/jsx/report/ReportGrid.mjs.map +1 -0
  500. package/dist/jsx/report/ReportGrid.native.js +510 -0
  501. package/dist/jsx/report/ReportGrid.native.js.map +1 -0
  502. package/dist/jsx/report/ReportViewToolbar.mjs +228 -0
  503. package/dist/jsx/report/ReportViewToolbar.mjs.map +1 -0
  504. package/dist/jsx/report/ReportViewToolbar.native.js +303 -0
  505. package/dist/jsx/report/ReportViewToolbar.native.js.map +1 -0
  506. package/dist/jsx/report/queryReport.mjs +404 -0
  507. package/dist/jsx/report/queryReport.mjs.map +1 -0
  508. package/dist/jsx/report/queryReport.native.js +588 -0
  509. package/dist/jsx/report/queryReport.native.js.map +1 -0
  510. package/dist/jsx/report/queryReportColumns.mjs +105 -0
  511. package/dist/jsx/report/queryReportColumns.mjs.map +1 -0
  512. package/dist/jsx/report/queryReportColumns.native.js +159 -0
  513. package/dist/jsx/report/queryReportColumns.native.js.map +1 -0
  514. package/dist/jsx/report/reportViewModel.mjs +343 -0
  515. package/dist/jsx/report/reportViewModel.mjs.map +1 -0
  516. package/dist/jsx/report/reportViewModel.native.js +657 -0
  517. package/dist/jsx/report/reportViewModel.native.js.map +1 -0
  518. package/dist/jsx/report/savedReports.mjs +112 -0
  519. package/dist/jsx/report/savedReports.mjs.map +1 -0
  520. package/dist/jsx/report/savedReports.native.js +169 -0
  521. package/dist/jsx/report/savedReports.native.js.map +1 -0
  522. package/dist/jsx/report/useFrappeReport.mjs +158 -0
  523. package/dist/jsx/report/useFrappeReport.mjs.map +1 -0
  524. package/dist/jsx/report/useFrappeReport.native.js +214 -0
  525. package/dist/jsx/report/useFrappeReport.native.js.map +1 -0
  526. package/dist/jsx/report/useQueryReport.mjs +176 -0
  527. package/dist/jsx/report/useQueryReport.mjs.map +1 -0
  528. package/dist/jsx/report/useQueryReport.native.js +233 -0
  529. package/dist/jsx/report/useQueryReport.native.js.map +1 -0
  530. package/dist/jsx/useFrappeForm.mjs +533 -0
  531. package/dist/jsx/useFrappeForm.mjs.map +1 -0
  532. package/dist/jsx/useFrappeForm.native.js +714 -0
  533. package/dist/jsx/useFrappeForm.native.js.map +1 -0
  534. package/package.json +16 -16
  535. package/src/FileBrowser/FileBrowser.spec.tsx +21 -0
  536. package/src/FileBrowser/FileBrowser.stories.tsx +27 -0
  537. package/src/FileBrowser/index.tsx +25 -2
  538. package/src/FrappeCalendar.tsx +8 -2
  539. package/src/FrappeForm.stories.tsx +52 -0
  540. package/src/FrappeForm.tsx +176 -565
  541. package/src/FrappeListView.cards.stories.tsx +3 -6
  542. package/src/FrappeListView.tsx +15 -55
  543. package/src/FrappeReportBuilder.stories.tsx +34 -7
  544. package/src/FrappeReportBuilder.tsx +790 -380
  545. package/src/FrappeReportView.spec.tsx +10 -6
  546. package/src/FrappeReportView.stories.tsx +20 -1
  547. package/src/FrappeReportView.tsx +89 -415
  548. package/src/dependsOn.ts +4 -1
  549. package/src/fields/shared/EditorPreviewPanes.tsx +2 -2
  550. package/src/formEngine/docPermissions.spec.ts +36 -1
  551. package/src/formEngine/docPermissions.ts +34 -0
  552. package/src/formEngine/index.ts +8 -1
  553. package/src/frappeRemainder.designLaw.spec.ts +9 -1
  554. package/src/frappeRoutes.spec.tsx +9 -0
  555. package/src/frappeViews.designLaw.spec.ts +15 -2
  556. package/src/guestFallback.spec.tsx +236 -0
  557. package/src/index.ts +117 -16
  558. package/src/liveErrors.spec.ts +10 -0
  559. package/src/liveErrors.ts +16 -3
  560. package/src/measures.ts +11 -0
  561. package/src/recordShape.spec.ts +100 -0
  562. package/src/recordShape.ts +133 -0
  563. package/src/report/ReportGrid.spec.tsx +175 -0
  564. package/src/report/ReportGrid.tsx +530 -0
  565. package/src/report/ReportViewToolbar.spec.tsx +90 -0
  566. package/src/report/ReportViewToolbar.tsx +314 -0
  567. package/src/report/queryReport.spec.ts +483 -0
  568. package/src/report/queryReport.ts +722 -0
  569. package/src/report/queryReportColumns.tsx +123 -0
  570. package/src/report/reportViewModel.spec.ts +393 -0
  571. package/src/report/reportViewModel.ts +617 -0
  572. package/src/report/savedReports.ts +172 -0
  573. package/src/report/seam.spec.ts +216 -0
  574. package/src/report/useFrappeReport.ts +241 -0
  575. package/src/report/useQueryReport.spec.tsx +131 -0
  576. package/src/report/useQueryReport.ts +309 -0
  577. package/src/useFrappeForm.spec.tsx +209 -0
  578. package/src/useFrappeForm.ts +778 -0
  579. package/types/FileBrowser/index.d.ts.map +1 -1
  580. package/types/FrappeCalendar.d.ts.map +1 -1
  581. package/types/FrappeForm.d.ts +21 -1
  582. package/types/FrappeForm.d.ts.map +1 -1
  583. package/types/FrappeListView.d.ts.map +1 -1
  584. package/types/FrappeReportBuilder.d.ts +66 -16
  585. package/types/FrappeReportBuilder.d.ts.map +1 -1
  586. package/types/FrappeReportView.d.ts +9 -127
  587. package/types/FrappeReportView.d.ts.map +1 -1
  588. package/types/dependsOn.d.ts.map +1 -1
  589. package/types/formEngine/docPermissions.d.ts +14 -0
  590. package/types/formEngine/docPermissions.d.ts.map +1 -1
  591. package/types/formEngine/index.d.ts +1 -1
  592. package/types/formEngine/index.d.ts.map +1 -1
  593. package/types/index.d.ts +15 -3
  594. package/types/index.d.ts.map +1 -1
  595. package/types/liveErrors.d.ts +9 -1
  596. package/types/liveErrors.d.ts.map +1 -1
  597. package/types/measures.d.ts +3 -0
  598. package/types/measures.d.ts.map +1 -0
  599. package/types/recordShape.d.ts +45 -0
  600. package/types/recordShape.d.ts.map +1 -0
  601. package/types/report/ReportGrid.d.ts +20 -0
  602. package/types/report/ReportGrid.d.ts.map +1 -0
  603. package/types/report/ReportViewToolbar.d.ts +31 -0
  604. package/types/report/ReportViewToolbar.d.ts.map +1 -0
  605. package/types/report/queryReport.d.ts +181 -0
  606. package/types/report/queryReport.d.ts.map +1 -0
  607. package/types/report/queryReportColumns.d.ts +12 -0
  608. package/types/report/queryReportColumns.d.ts.map +1 -0
  609. package/types/report/reportViewModel.d.ts +146 -0
  610. package/types/report/reportViewModel.d.ts.map +1 -0
  611. package/types/report/savedReports.d.ts +27 -0
  612. package/types/report/savedReports.d.ts.map +1 -0
  613. package/types/report/useFrappeReport.d.ts +60 -0
  614. package/types/report/useFrappeReport.d.ts.map +1 -0
  615. package/types/report/useQueryReport.d.ts +37 -0
  616. package/types/report/useQueryReport.d.ts.map +1 -0
  617. package/types/useFrappeForm.d.ts +142 -0
  618. package/types/useFrappeForm.d.ts.map +1 -0
@@ -0,0 +1,172 @@
1
+ // Saved reports — desk parity via the `Report` doctype (report_type
2
+ // "Report Builder"): the same records desk's "Select Report" dropdown
3
+ // lists. Save/Save As ride the whitelisted frappe.desk.reportview
4
+ // save_report / delete_report methods (identical payload shape, so desk
5
+ // opens reports saved here and vice versa). Fixture mode (stories / no
6
+ // bench) keeps an in-memory list so the control stays demonstrable.
7
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
8
+ import { useFrappeConfig } from "../FrappeProvider";
9
+ import {
10
+ toDeskReportSettings,
11
+ fromDeskReportSettings,
12
+ type ReportViewConfig,
13
+ } from "./reportViewModel";
14
+ import { reportCall, type FrappeReportConnection } from "./useFrappeReport";
15
+
16
+ export interface SavedReportSummary {
17
+ /** Report document name (usually equals the report title). */
18
+ name: string;
19
+ reportName: string;
20
+ json?: string;
21
+ }
22
+
23
+ export interface UseSavedReportsResult {
24
+ reports: SavedReportSummary[];
25
+ loading: boolean;
26
+ /** Load a saved report's view config (fields/filters/sort/…). */
27
+ load: (name: string) => Promise<ReportViewConfig | undefined>;
28
+ /** Create or update a Report doc; returns the server-side name. */
29
+ save: (name: string, config: ReportViewConfig) => Promise<string>;
30
+ remove: (name: string) => Promise<void>;
31
+ refresh: () => void;
32
+ }
33
+
34
+ type ReportListRow = { name: string; report_name?: string; json?: string };
35
+
36
+ /**
37
+ * Where saved reports are read and written. Omitted, the ambient
38
+ * FrappeProvider's connection; `fixtures` keeps them in memory.
39
+ */
40
+ export interface SavedReportsConnection extends FrappeReportConnection {
41
+ fixtures?: unknown;
42
+ }
43
+
44
+ export function useSavedReports(
45
+ doctype: string,
46
+ connection?: SavedReportsConnection,
47
+ ): UseSavedReportsResult {
48
+ const config = useFrappeConfig();
49
+ const baseURL = connection ? connection.baseURL : config?.baseURL;
50
+ const auth = connection ? connection.auth : config?.auth;
51
+ const fixtureMode = Boolean(connection ? connection.fixtures : config?.fixtures);
52
+ const call = useMemo(
53
+ () => (baseURL ? reportCall({ baseURL, auth }) : undefined),
54
+ [baseURL, auth],
55
+ );
56
+ const [reports, setReports] = useState<SavedReportSummary[]>([]);
57
+ const [loading, setLoading] = useState(false);
58
+ const [generation, setGeneration] = useState(0);
59
+ // Fixture-mode saves live here (stories/tests) — never reaches a bench.
60
+ const memoryConfigs = useRef(new Map<string, ReportViewConfig>());
61
+
62
+ useEffect(() => {
63
+ memoryConfigs.current = new Map();
64
+ setReports([]);
65
+ }, [doctype]);
66
+
67
+ useEffect(() => {
68
+ if (!call || fixtureMode) return;
69
+ let cancelled = false;
70
+ setLoading(true);
71
+ call
72
+ .get<{ message?: ReportListRow[] }>("frappe.client.get_list", {
73
+ doctype: "Report",
74
+ filters: JSON.stringify([
75
+ ["ref_doctype", "=", doctype],
76
+ ["report_type", "=", "Report Builder"],
77
+ ["disabled", "=", 0],
78
+ ]),
79
+ fields: JSON.stringify(["name", "report_name", "json"]),
80
+ limit_page_length: 0,
81
+ order_by: "report_name asc",
82
+ })
83
+ .then((res) => {
84
+ if (cancelled) return;
85
+ const rows = res.payload?.message ?? [];
86
+ setReports(
87
+ rows.map((row) => ({
88
+ name: row.name,
89
+ reportName: row.report_name || row.name,
90
+ json: row.json,
91
+ })),
92
+ );
93
+ setLoading(false);
94
+ })
95
+ .catch(() => {
96
+ // Report doctype may be unreadable for restricted roles — the
97
+ // selector then simply offers no saved reports.
98
+ if (cancelled) return;
99
+ setReports([]);
100
+ setLoading(false);
101
+ });
102
+ return () => {
103
+ cancelled = true;
104
+ };
105
+ }, [call, fixtureMode, doctype, generation]);
106
+
107
+ const load = useCallback(
108
+ async (name: string): Promise<ReportViewConfig | undefined> => {
109
+ if (fixtureMode) return memoryConfigs.current.get(name);
110
+ const summary = reports.find((report) => report.name === name);
111
+ let json = summary?.json;
112
+ if (json === undefined && call) {
113
+ const res = await call.get<{ message?: { json?: string } }>("frappe.client.get_value", {
114
+ doctype: "Report",
115
+ filters: JSON.stringify({ name }),
116
+ fieldname: JSON.stringify(["json"]),
117
+ });
118
+ json = res.payload?.message?.json;
119
+ }
120
+ if (!json) return undefined;
121
+ try {
122
+ return fromDeskReportSettings(doctype, JSON.parse(json));
123
+ } catch {
124
+ return undefined;
125
+ }
126
+ },
127
+ [call, fixtureMode, reports, doctype],
128
+ );
129
+
130
+ const save = useCallback(
131
+ async (name: string, viewConfig: ReportViewConfig): Promise<string> => {
132
+ const trimmed = name.trim();
133
+ if (!trimmed) throw new Error("Report name is required");
134
+ if (fixtureMode || !call) {
135
+ memoryConfigs.current.set(trimmed, viewConfig);
136
+ setReports((previous) => [
137
+ ...previous.filter((report) => report.name !== trimmed),
138
+ { name: trimmed, reportName: trimmed },
139
+ ]);
140
+ return trimmed;
141
+ }
142
+ const res = await call.post<{ message?: string }>("frappe.desk.reportview.save_report", {
143
+ name: trimmed,
144
+ doctype,
145
+ report_settings: JSON.stringify(toDeskReportSettings(doctype, viewConfig)),
146
+ });
147
+ setGeneration((value) => value + 1);
148
+ return res.payload?.message ?? trimmed;
149
+ },
150
+ [call, fixtureMode, doctype],
151
+ );
152
+
153
+ const remove = useCallback(
154
+ async (name: string): Promise<void> => {
155
+ if (fixtureMode || !call) {
156
+ memoryConfigs.current.delete(name);
157
+ setReports((previous) => previous.filter((report) => report.name !== name));
158
+ return;
159
+ }
160
+ await call.post("frappe.desk.reportview.delete_report", { name });
161
+ setGeneration((value) => value + 1);
162
+ },
163
+ [call, fixtureMode],
164
+ );
165
+
166
+ const refresh = useCallback(() => setGeneration((value) => value + 1), []);
167
+
168
+ return useMemo(
169
+ () => ({ reports, loading, load, save, remove, refresh }),
170
+ [reports, loading, load, save, remove, refresh],
171
+ );
172
+ }
@@ -0,0 +1,216 @@
1
+ /**
2
+ * MPO-15 (GL-28) — the report seam, from this side.
3
+ *
4
+ * Two report concepts, a named query/script report and a doctype's report
5
+ * view, used to carry four models: FrappeReportView and FrappeReportBuilder
6
+ * here, reportShapes and reportViewModel plus DoctypeReportView one tier up
7
+ * in `@multiplatform.one/backoffice`. One model per concept lives here now,
8
+ * and four things have to stay true for that to mean anything:
9
+ *
10
+ * 1. The package barrel hands every name out.
11
+ * 2. The report modules reach nothing above them: no backoffice import and
12
+ * no bounce back through this package's own barrel.
13
+ * 3. Each model is declared once across both packages, and scrub is the
14
+ * server's `frappe.scrub`.
15
+ * 4. The exported components render through the models: FrappeReportView
16
+ * through the query-report model, FrappeReportBuilder through the
17
+ * report-view model.
18
+ */
19
+ import fs from "node:fs";
20
+ import path from "node:path";
21
+ import { describe, expect, it } from "vitest";
22
+
23
+ const reportDir = path.resolve(__dirname);
24
+ const srcDir = path.resolve(__dirname, "..");
25
+ const publicDir = path.resolve(srcDir, "../..");
26
+
27
+ function sourceFiles(dir: string): string[] {
28
+ const out: string[] = [];
29
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
30
+ const full = path.join(dir, entry.name);
31
+ if (entry.isDirectory()) {
32
+ out.push(...sourceFiles(full));
33
+ continue;
34
+ }
35
+ if (!/\.(ts|tsx)$/.test(entry.name)) continue;
36
+ if (/\.(spec|stories)\./.test(entry.name)) continue;
37
+ out.push(full);
38
+ }
39
+ return out;
40
+ }
41
+
42
+ function read(rel: string): string {
43
+ return fs.readFileSync(path.resolve(srcDir, rel), "utf-8");
44
+ }
45
+
46
+ function declaredIn(pattern: RegExp): string[] {
47
+ return [...sourceFiles(srcDir), ...sourceFiles(path.resolve(publicDir, "backoffice/src"))]
48
+ .filter((file) => pattern.test(fs.readFileSync(file, "utf-8")))
49
+ .map((file) => path.relative(publicDir, file))
50
+ .sort();
51
+ }
52
+
53
+ const QUERY_REPORT_NAMES = [
54
+ "QueryReportColumn",
55
+ "QueryReportRow",
56
+ "QueryReportFilters",
57
+ "QueryReportFilterMeta",
58
+ "QueryReportMeta",
59
+ "QueryReportFixture",
60
+ "QueryReportRunMessage",
61
+ "ScriptFilterExtraction",
62
+ "buildRunFilters",
63
+ "compactFilterValues",
64
+ "compactQueryReportFilters",
65
+ "defaultFilterValues",
66
+ "extractScriptFilters",
67
+ "humanizeFrappeError",
68
+ "isEmptyFilterValue",
69
+ "normalizeFilterMeta",
70
+ "normalizeQueryReportColumns",
71
+ "normalizeQueryReportPayload",
72
+ "normalizeQueryReportRows",
73
+ "scrubFieldname",
74
+ "stripReportHtml",
75
+ "useFrappeReport",
76
+ "useQueryReport",
77
+ "UseQueryReportOptions",
78
+ "UseQueryReportResult",
79
+ "buildQueryReportColumns",
80
+ "buildQueryReportCsv",
81
+ "BuildQueryReportColumnsArgs",
82
+ ];
83
+
84
+ const REPORT_VIEW_NAMES = [
85
+ "ReportColumnDef",
86
+ "ReportRow",
87
+ "ReportSortState",
88
+ "ReportViewConfig",
89
+ "DeskReportSettings",
90
+ "ReportGridRow",
91
+ "ReportTotalsCell",
92
+ "REPORT_NUMERIC_FIELDTYPES",
93
+ "REPORT_PAGE_SIZES",
94
+ "DEFAULT_REPORT_PAGE_SIZE",
95
+ "reportColumnsFromMeta",
96
+ "defaultReportFieldnames",
97
+ "resolveReportColumns",
98
+ "reportColumnFilterTuple",
99
+ "reportColumnFilterTuples",
100
+ "parseReportFiltersParam",
101
+ "parseDeskOrderBy",
102
+ "toDeskReportSettings",
103
+ "fromDeskReportSettings",
104
+ "orderReportRows",
105
+ "buildReportGridRows",
106
+ "computeReportTotals",
107
+ "buildReportCsv",
108
+ "ReportGrid",
109
+ "ReportGridProps",
110
+ "ReportViewToolbar",
111
+ "ReportViewToolbarProps",
112
+ "useSavedReports",
113
+ "SavedReportSummary",
114
+ "UseSavedReportsResult",
115
+ "dialogBodyMinWidth",
116
+ "overlayListMaxHeight",
117
+ ];
118
+
119
+ describe("report seam (MPO-15, GL-28)", () => {
120
+ it("hands both report models out of the package barrel", () => {
121
+ const barrel = read("index.ts");
122
+ const start = barrel.indexOf("Report models (MPO-15");
123
+ expect(start, "the barrel must carry a report models block").toBeGreaterThan(-1);
124
+ const block = barrel.slice(start);
125
+ expect(block).toContain('from "./report/queryReport"');
126
+ expect(block).toContain('from "./report/reportViewModel"');
127
+ for (const name of [...QUERY_REPORT_NAMES, ...REPORT_VIEW_NAMES]) {
128
+ expect(block, `the barrel must re-export "${name}"`).toMatch(new RegExp(`\\b${name}\\b`));
129
+ }
130
+ });
131
+
132
+ it("keeps the report modules off backoffice and off their own barrel", () => {
133
+ const files = [
134
+ ...sourceFiles(reportDir),
135
+ path.resolve(srcDir, "FrappeReportView.tsx"),
136
+ path.resolve(srcDir, "FrappeReportBuilder.tsx"),
137
+ ];
138
+ for (const file of files) {
139
+ const source = fs.readFileSync(file, "utf-8");
140
+ expect(source, file).not.toMatch(/from ["']@multiplatform\.one\/backoffice/);
141
+ expect(source, file).not.toMatch(/from ["']@multiplatform\.one\/frappe-ui/);
142
+ expect(source, file).not.toMatch(/from ["']\.\.?\/index["']/);
143
+ }
144
+ });
145
+
146
+ it("scrubs a label the way the server's frappe.scrub does", async () => {
147
+ const modelPath = "./queryReport";
148
+ const { scrubFieldname } = (await import(/* @vite-ignore */ modelPath)) as {
149
+ scrubFieldname: (label: string) => string;
150
+ };
151
+ expect(scrubFieldname("Modified On")).toBe("modified_on");
152
+ expect(scrubFieldname("Multi-Word Label")).toBe("multi_word_label");
153
+ expect(scrubFieldname("Size (MB)")).toBe("size_(mb)");
154
+ expect(scrubFieldname("Assigned To/Owner")).toBe("assigned_to/owner");
155
+ expect(scrubFieldname(" Total (USD) ")).toBe("__total_(usd)_");
156
+ });
157
+
158
+ it("declares the query-report model once, across both packages", () => {
159
+ expect(declaredIn(/function scrubFieldname\b/)).toEqual([
160
+ "frappe-ui/src/report/queryReport.ts",
161
+ ]);
162
+ expect(declaredIn(/function normalizeQueryReportColumns\b/)).toEqual([
163
+ "frappe-ui/src/report/queryReport.ts",
164
+ ]);
165
+ expect(declaredIn(/function normalizeQueryReportRows\b/)).toEqual([
166
+ "frappe-ui/src/report/queryReport.ts",
167
+ ]);
168
+ expect(declaredIn(/function (?:compactFilterValues|compactQueryReportFilters)\b/)).toEqual([
169
+ "frappe-ui/src/report/queryReport.ts",
170
+ ]);
171
+ expect(declaredIn(/interface (?:QueryReportColumn|FrappeReportColumn)\b/)).toEqual([
172
+ "frappe-ui/src/report/queryReport.ts",
173
+ ]);
174
+ });
175
+
176
+ it("declares the report-view model once, across both packages", () => {
177
+ for (const name of [
178
+ "reportColumnsFromMeta",
179
+ "defaultReportFieldnames",
180
+ "columnFilterTuple",
181
+ "orderReportRows",
182
+ "buildReportCsv",
183
+ "parseReportFiltersParam",
184
+ ]) {
185
+ expect(declaredIn(new RegExp(`function ${name}\\b`)), name).toEqual([
186
+ "frappe-ui/src/report/reportViewModel.ts",
187
+ ]);
188
+ }
189
+ expect(declaredIn(/REPORT_NUMERIC_FIELDTYPES\s*=/)).toEqual([
190
+ "frappe-ui/src/report/reportViewModel.ts",
191
+ ]);
192
+ });
193
+
194
+ it("renders FrappeReportView through the query-report model", () => {
195
+ const view = read("FrappeReportView.tsx");
196
+ expect(view).toContain('from "./report/queryReport"');
197
+ expect(view).toContain('from "./report/useFrappeReport"');
198
+ expect(view).not.toMatch(
199
+ /export function (?:normalizeReport|compactFilterValues|scrubFieldname)/,
200
+ );
201
+ const useQueryReport = read("report/useQueryReport.ts");
202
+ expect(useQueryReport, "the desk hook runs through the same transport").toContain(
203
+ 'from "./useFrappeReport"',
204
+ );
205
+ });
206
+
207
+ it("renders FrappeReportBuilder through the report-view model", () => {
208
+ const builder = read("FrappeReportBuilder.tsx");
209
+ expect(builder).toContain('from "./report/reportViewModel"');
210
+ for (const call of ["reportColumnsFromMeta(", "defaultReportFieldnames(", "orderReportRows("]) {
211
+ expect(builder, call).toContain(call);
212
+ }
213
+ expect(builder).toContain("<ReportGrid");
214
+ expect(builder).not.toMatch(/<ReportBuilder\b/);
215
+ });
216
+ });
@@ -0,0 +1,241 @@
1
+ /**
2
+ * The query-report transport: one `frappe.desk.query_report.run` caller per
3
+ * connection, debounced filter changes, the Report's DB-defined filters via
4
+ * `get_script`. FrappeReportView runs on it directly and the desk's
5
+ * `useQueryReport` runs its reports through it, so both surfaces send the
6
+ * same request and read the same normalized payload (MPO-15, GL-28).
7
+ */
8
+ import { AsyncDebouncer, CallModule, HttpClient, type AuthConfig } from "@multiplatform.one/frappe";
9
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
10
+ import {
11
+ compactFilterValues,
12
+ normalizeQueryReportPayload,
13
+ type QueryReportFilterInput,
14
+ type QueryReportFilters,
15
+ type QueryReportPayload,
16
+ type QueryReportRunMessage,
17
+ } from "./queryReport";
18
+
19
+ /** Fixture payload or loader — renders the report without any network. */
20
+ export type FrappeReportFixture =
21
+ | QueryReportRunMessage
22
+ | ((args: {
23
+ reportName: string;
24
+ filters: QueryReportFilters;
25
+ }) => QueryReportRunMessage | Promise<QueryReportRunMessage>);
26
+
27
+ export interface FrappeReportConnection {
28
+ baseURL: string;
29
+ auth?: {
30
+ useToken?: boolean;
31
+ token?: string | (() => string | Promise<string>);
32
+ type?: string;
33
+ };
34
+ }
35
+
36
+ // One whitelisted-method caller per connection — report views sharing a
37
+ // bench share it (same pattern as useFrappeAggregate's DbModule cache).
38
+ const callCache = new Map<string, CallModule>();
39
+
40
+ /** The shared caller for a connection (report runs, Report doc reads, get_script). */
41
+ export function reportCall(connection: FrappeReportConnection): CallModule {
42
+ const key = `${connection.baseURL}:${connection.auth?.useToken ? "t" : ""}:${connection.auth?.token ?? ""}:${connection.auth?.type ?? ""}`;
43
+ let call = callCache.get(key);
44
+ if (!call) {
45
+ const authConfig: AuthConfig | undefined = connection.auth
46
+ ? {
47
+ useToken: connection.auth.useToken,
48
+ token: connection.auth.token,
49
+ type: connection.auth.type as AuthConfig["type"],
50
+ }
51
+ : undefined;
52
+ call = new CallModule(new HttpClient(connection.baseURL, authConfig));
53
+ callCache.set(key, call);
54
+ }
55
+ return call;
56
+ }
57
+
58
+ const DEFAULT_DEBOUNCE_MS = 400;
59
+
60
+ export interface UseFrappeReportOptions {
61
+ reportName: string;
62
+ /** Current filter values (already compacted values are fine too). */
63
+ filters?: QueryReportFilters;
64
+ /** Fixture payload / loader — no network is touched when set. */
65
+ fixture?: FrappeReportFixture;
66
+ /**
67
+ * Fetch the report's DB-defined filter definitions (`get_script`).
68
+ * Off when the consumer supplies `filterFields` explicitly.
69
+ */
70
+ fetchFilterDefs?: boolean;
71
+ /** Bypass the prepared-report cache and execute the report now. */
72
+ ignorePreparedReport?: boolean;
73
+ /** Debounce for filter-change refetches in ms (default 400). */
74
+ debounceMs?: number;
75
+ enabled?: boolean;
76
+ }
77
+
78
+ export interface UseFrappeReportResult {
79
+ payload: QueryReportPayload | undefined;
80
+ /** DB-defined filter defs (`get_script`); undefined while unknown. */
81
+ scriptFilters: QueryReportFilterInput[] | undefined;
82
+ /** First run in flight — nothing to show yet. */
83
+ isLoading: boolean;
84
+ /** Any run in flight (filter-change / refresh refetches included). */
85
+ isFetching: boolean;
86
+ error: Error | undefined;
87
+ /** Immediate re-run (skips the debounce window). */
88
+ refresh: () => void;
89
+ }
90
+
91
+ /**
92
+ * Run a named server-side report (`frappe.desk.query_report.run`) with the
93
+ * given filters. Filter-value changes are debounced; report changes and
94
+ * explicit `refresh()` run immediately.
95
+ */
96
+ export function useFrappeReport(
97
+ connection: FrappeReportConnection | undefined,
98
+ {
99
+ reportName,
100
+ filters,
101
+ fixture,
102
+ fetchFilterDefs = false,
103
+ ignorePreparedReport = false,
104
+ debounceMs = DEFAULT_DEBOUNCE_MS,
105
+ enabled = true,
106
+ }: UseFrappeReportOptions,
107
+ ): UseFrappeReportResult {
108
+ const isEnabled = enabled && !!reportName && (!!connection || !!fixture);
109
+
110
+ const [payload, setPayload] = useState<QueryReportPayload | undefined>(undefined);
111
+ const [scriptFilters, setScriptFilters] = useState<QueryReportFilterInput[] | undefined>(
112
+ undefined,
113
+ );
114
+ const [isLoading, setIsLoading] = useState(isEnabled);
115
+ const [isFetching, setIsFetching] = useState(false);
116
+ const [error, setError] = useState<Error | undefined>(undefined);
117
+
118
+ const compactedFilters = useMemo(() => compactFilterValues(filters), [filters]);
119
+ const filtersKey = JSON.stringify(compactedFilters);
120
+ const runKey = JSON.stringify([
121
+ connection?.baseURL,
122
+ !!fixture,
123
+ reportName,
124
+ filtersKey,
125
+ ignorePreparedReport,
126
+ ]);
127
+
128
+ const fetchSeq = useRef(0);
129
+ const argsRef = useRef({ reportName, filters: compactedFilters, fixture, ignorePreparedReport });
130
+ argsRef.current = { reportName, filters: compactedFilters, fixture, ignorePreparedReport };
131
+ const connectionRef = useRef(connection);
132
+ connectionRef.current = connection;
133
+
134
+ const runFetch = useCallback(async () => {
135
+ const {
136
+ reportName: name,
137
+ filters: values,
138
+ fixture: fx,
139
+ ignorePreparedReport: skipPrepared,
140
+ } = argsRef.current;
141
+ const conn = connectionRef.current;
142
+ if (!name || (!conn && !fx)) return;
143
+ const seq = ++fetchSeq.current;
144
+ setIsFetching(true);
145
+ try {
146
+ let raw: QueryReportRunMessage | undefined;
147
+ if (fx) {
148
+ raw = typeof fx === "function" ? await fx({ reportName: name, filters: values }) : fx;
149
+ } else if (conn) {
150
+ const res = await reportCall(conn).post<{ message: QueryReportRunMessage }>(
151
+ "frappe.desk.query_report.run",
152
+ {
153
+ report_name: name,
154
+ filters: values,
155
+ ignore_prepared_report: skipPrepared ? 1 : 0,
156
+ // Desk parity: only let the server substitute saved custom
157
+ // filters when the caller sent no filter values at all.
158
+ are_default_filters: Object.keys(values).length ? 0 : 1,
159
+ },
160
+ );
161
+ raw = res.payload.message;
162
+ }
163
+ if (seq !== fetchSeq.current) return; // stale response — a newer run won
164
+ setPayload(normalizeQueryReportPayload(raw ?? {}));
165
+ setError(undefined);
166
+ } catch (err) {
167
+ if (seq !== fetchSeq.current) return;
168
+ setError(err instanceof Error ? err : new Error(String(err)));
169
+ } finally {
170
+ if (seq === fetchSeq.current) {
171
+ setIsLoading(false);
172
+ setIsFetching(false);
173
+ }
174
+ }
175
+ }, []);
176
+
177
+ // Debouncer coalescing filter keystrokes into one refetch.
178
+ const debouncerRef = useRef<AsyncDebouncer<() => Promise<void>> | undefined>(undefined);
179
+ if (!debouncerRef.current) {
180
+ debouncerRef.current = new AsyncDebouncer(() => runFetch(), {
181
+ wait: debounceMs,
182
+ });
183
+ }
184
+ useEffect(() => {
185
+ debouncerRef.current?.setOptions({ wait: debounceMs });
186
+ }, [debounceMs]);
187
+ useEffect(() => () => debouncerRef.current?.cancel(), []);
188
+
189
+ // Report identity changes (and first mount) run immediately; filter-value
190
+ // changes ride the debouncer so per-keystroke Data filters cost one run.
191
+ // The run key guards actual query changes; captured args ride argsRef.
192
+ const lastRunKeyRef = useRef<string | undefined>(undefined);
193
+ const lastReportRef = useRef<string | undefined>(undefined);
194
+ useEffect(() => {
195
+ if (!isEnabled || lastRunKeyRef.current === runKey) return;
196
+ lastRunKeyRef.current = runKey;
197
+ const reportChanged = lastReportRef.current !== argsRef.current.reportName;
198
+ lastReportRef.current = argsRef.current.reportName;
199
+ setError(undefined);
200
+ if (reportChanged) {
201
+ setIsLoading(true);
202
+ debouncerRef.current?.cancel();
203
+ void runFetch();
204
+ } else if (debounceMs <= 0) {
205
+ void runFetch();
206
+ } else {
207
+ void debouncerRef.current?.maybeExecute();
208
+ }
209
+ }, [isEnabled, runKey, debounceMs, runFetch]);
210
+
211
+ // DB-defined filter definitions (Report doc `filters` child table) via
212
+ // get_script — live mode only; fixtures carry defs on the payload itself.
213
+ useEffect(() => {
214
+ if (!isEnabled || !fetchFilterDefs || fixture || !connection) {
215
+ return;
216
+ }
217
+ let cancelled = false;
218
+ void (async () => {
219
+ try {
220
+ const res = await reportCall(connection).get<{
221
+ message: { filters?: QueryReportFilterInput[] };
222
+ }>("frappe.desk.query_report.get_script", { report_name: reportName });
223
+ if (!cancelled) setScriptFilters(res.payload.message?.filters ?? []);
224
+ } catch {
225
+ // Filter defs are progressive enhancement — a failing get_script
226
+ // must not take the report down (run() surfaces real errors).
227
+ if (!cancelled) setScriptFilters([]);
228
+ }
229
+ })();
230
+ return () => {
231
+ cancelled = true;
232
+ };
233
+ }, [isEnabled, fetchFilterDefs, fixture, connection, reportName]);
234
+
235
+ const refresh = useCallback(() => {
236
+ debouncerRef.current?.cancel();
237
+ void runFetch();
238
+ }, [runFetch]);
239
+
240
+ return { payload, scriptFilters, isLoading, isFetching, error, refresh };
241
+ }