@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,123 @@
1
+ // Query-report column meta → DataTable columns with fieldtype-aware cells:
2
+ // numerics right-aligned, Date/Datetime trimmed like desk lists, Link cells
3
+ // navigable to the target doc form, HTML values (desk anchor markup)
4
+ // flattened to text.
5
+ import React from "react";
6
+ import { Text } from "@multiplatform.one/components";
7
+ import type { DataTableColumn } from "@multiplatform.one/table";
8
+ import { formatDateCell } from "../list/listFormat";
9
+ import { type QueryReportColumn, type QueryReportRow, stripHtml } from "./queryReport";
10
+
11
+ const NUMERIC_FIELDTYPES = new Set(["Currency", "Float", "Int", "Percent", "Duration"]);
12
+
13
+ export interface BuildQueryReportColumnsArgs {
14
+ columns: readonly QueryReportColumn[];
15
+ /** Open a Link cell's target document (doctype comes from column options). */
16
+ onOpenLink?: (doctype: string, name: string) => void;
17
+ }
18
+
19
+ function queryReportCell(
20
+ column: QueryReportColumn,
21
+ onOpenLink?: (doctype: string, name: string) => void,
22
+ ) {
23
+ return ({ getValue }: { getValue: () => unknown }) => {
24
+ const raw = getValue();
25
+ if (raw === null || raw === undefined || raw === "") {
26
+ return (
27
+ <Text fontSize="$3" color="$color8">
28
+ —
29
+ </Text>
30
+ );
31
+ }
32
+ if (column.fieldtype === "Check") {
33
+ return (
34
+ <Text fontSize="$3" color={raw ? "$green11" : "$color8"}>
35
+ {raw ? "✓" : "—"}
36
+ </Text>
37
+ );
38
+ }
39
+ const value = String(raw);
40
+ if (NUMERIC_FIELDTYPES.has(column.fieldtype)) {
41
+ return (
42
+ <Text fontSize="$3" color="$color12" textAlign="right">
43
+ {value}
44
+ </Text>
45
+ );
46
+ }
47
+ switch (column.fieldtype) {
48
+ case "Date":
49
+ case "Datetime":
50
+ return (
51
+ <Text fontSize="$3" color="$color11">
52
+ {formatDateCell(value)}
53
+ </Text>
54
+ );
55
+ case "Link": {
56
+ const doctype = column.options;
57
+ if (doctype && onOpenLink) {
58
+ return (
59
+ <Text
60
+ fontSize="$3"
61
+ color="$color11"
62
+ textDecorationLine="underline"
63
+ cursor="pointer"
64
+ numberOfLines={1}
65
+ role="link"
66
+ onPress={(event) => {
67
+ event?.stopPropagation?.();
68
+ onOpenLink(doctype, value);
69
+ }}
70
+ >
71
+ {value}
72
+ </Text>
73
+ );
74
+ }
75
+ return (
76
+ <Text fontSize="$3" color="$color11" numberOfLines={1}>
77
+ {value}
78
+ </Text>
79
+ );
80
+ }
81
+ default:
82
+ return (
83
+ <Text fontSize="$3" color="$color11" numberOfLines={1}>
84
+ {stripHtml(value)}
85
+ </Text>
86
+ );
87
+ }
88
+ };
89
+ }
90
+
91
+ /** Build DataTable columns for a query-report run result. */
92
+ export function buildQueryReportColumns({
93
+ columns,
94
+ onOpenLink,
95
+ }: BuildQueryReportColumnsArgs): DataTableColumn<QueryReportRow>[] {
96
+ return columns.map((column) => ({
97
+ id: column.fieldname,
98
+ header: column.label,
99
+ // accessorFn (not accessorKey): report fieldnames may contain path-y
100
+ // characters like "assigned_to/owner" that key-based access mangles.
101
+ accessorFn: (row: QueryReportRow) => row[column.fieldname],
102
+ ...(NUMERIC_FIELDTYPES.has(column.fieldtype) ? { align: "right" as const } : {}),
103
+ ...(column.width ? { width: column.width } : {}),
104
+ cell: queryReportCell(column, onOpenLink),
105
+ }));
106
+ }
107
+
108
+ function escapeCsvCell(value: unknown): string {
109
+ if (value === null || value === undefined) return "";
110
+ const text = stripHtml(String(value));
111
+ return /[",\n]/.test(text) ? `"${text.replace(/"/g, '""')}"` : text;
112
+ }
113
+
114
+ /** CSV over the full run result (Desk Export, not just the current page). */
115
+ export function buildQueryReportCsv(
116
+ columns: readonly QueryReportColumn[],
117
+ rows: readonly QueryReportRow[],
118
+ ): string {
119
+ return [
120
+ columns.map((column) => escapeCsvCell(column.label)).join(","),
121
+ ...rows.map((row) => columns.map((column) => escapeCsvCell(row[column.fieldname])).join(",")),
122
+ ].join("\n");
123
+ }
@@ -0,0 +1,393 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import type { DoctypeMeta } from "../formEngine/doctypeMeta";
3
+ import {
4
+ buildGridRows,
5
+ buildReportCsv,
6
+ columnFilterTuple,
7
+ columnFilterTuples,
8
+ computeTotals,
9
+ defaultReportFieldnames,
10
+ fromDeskReportSettings,
11
+ orderReportRows,
12
+ parseDeskOrderBy,
13
+ parseReportFiltersParam,
14
+ reportColumnsFromMeta,
15
+ resolveSelectedColumns,
16
+ toDeskReportSettings,
17
+ type ReportColumnDef,
18
+ type ReportRow,
19
+ } from "./reportViewModel";
20
+
21
+ const userMeta: DoctypeMeta = {
22
+ name: "User",
23
+ title_field: "full_name",
24
+ sort_field: "modified",
25
+ sort_order: "DESC",
26
+ fields: [
27
+ { fieldname: "basic_section", fieldtype: "Section Break" },
28
+ { fieldname: "email", label: "Email", fieldtype: "Data", in_list_view: 1 },
29
+ { fieldname: "first_name", label: "First Name", fieldtype: "Data", in_standard_filter: 1 },
30
+ { fieldname: "full_name", label: "Full Name", fieldtype: "Data", in_list_view: 1 },
31
+ { fieldname: "enabled", label: "Enabled", fieldtype: "Check", in_standard_filter: 1 },
32
+ {
33
+ fieldname: "user_type",
34
+ label: "User Type",
35
+ fieldtype: "Select",
36
+ options: "System User\nWebsite User",
37
+ in_list_view: 1,
38
+ in_standard_filter: 1,
39
+ },
40
+ {
41
+ fieldname: "api_secret",
42
+ label: "API Secret",
43
+ fieldtype: "Data",
44
+ in_list_view: 1,
45
+ report_hide: 1,
46
+ },
47
+ {
48
+ fieldname: "roles",
49
+ label: "Roles",
50
+ fieldtype: "Table",
51
+ options: "Has Role",
52
+ in_list_view: 1,
53
+ },
54
+ { fieldname: "bio", label: "Bio", fieldtype: "Small Text" },
55
+ { fieldname: "points", label: "Points", fieldtype: "Int" },
56
+ {
57
+ fieldname: "role_profile",
58
+ label: "Role Profile",
59
+ fieldtype: "Link",
60
+ options: "Role Profile",
61
+ },
62
+ ],
63
+ };
64
+
65
+ function column(fieldname: string, overrides: Partial<ReportColumnDef> = {}): ReportColumnDef {
66
+ return {
67
+ fieldname,
68
+ label: fieldname,
69
+ fieldtype: "Data",
70
+ kind: "text",
71
+ width: 160,
72
+ align: "left",
73
+ ...overrides,
74
+ };
75
+ }
76
+
77
+ describe("defaultReportFieldnames", () => {
78
+ it("seeds desk defaults: name, title field, in_list_view/in_standard_filter, modified", () => {
79
+ expect(defaultReportFieldnames(userMeta)).toEqual([
80
+ "name",
81
+ "full_name",
82
+ "email",
83
+ "first_name",
84
+ "enabled",
85
+ "user_type",
86
+ "modified",
87
+ ]);
88
+ });
89
+
90
+ it("excludes report_hide, layout and table fields, dedupes the title field", () => {
91
+ const fields = defaultReportFieldnames(userMeta);
92
+ expect(fields).not.toContain("api_secret");
93
+ expect(fields).not.toContain("roles");
94
+ expect(fields).not.toContain("basic_section");
95
+ expect(fields.filter((field) => field === "full_name")).toHaveLength(1);
96
+ });
97
+
98
+ it("degrades to name + modified without meta", () => {
99
+ expect(defaultReportFieldnames(undefined)).toEqual(["name", "modified"]);
100
+ });
101
+
102
+ it("includes the image_field after the title field (desk set_default_fields)", () => {
103
+ const meta: DoctypeMeta = {
104
+ ...userMeta,
105
+ image_field: "user_image",
106
+ fields: [
107
+ ...userMeta.fields,
108
+ { fieldname: "user_image", label: "User Image", fieldtype: "Attach Image" },
109
+ ],
110
+ };
111
+ const fields = defaultReportFieldnames(meta);
112
+ expect(fields.indexOf("user_image")).toBe(fields.indexOf("full_name") + 1);
113
+ });
114
+
115
+ it("seeds an unflagged status docfield right after name", () => {
116
+ const meta: DoctypeMeta = {
117
+ name: "ToDo",
118
+ fields: [
119
+ { fieldname: "status", label: "Status", fieldtype: "Select", options: "Open\nClosed" },
120
+ { fieldname: "description", label: "Description", fieldtype: "Text", in_list_view: 1 },
121
+ ],
122
+ };
123
+ expect(defaultReportFieldnames(meta)).toEqual(["name", "status", "description", "modified"]);
124
+ });
125
+
126
+ it("pulls the currency-source field referenced by a flagged Currency column", () => {
127
+ const meta: DoctypeMeta = {
128
+ name: "Quote",
129
+ fields: [
130
+ {
131
+ fieldname: "amount",
132
+ label: "Amount",
133
+ fieldtype: "Currency",
134
+ options: "currency",
135
+ in_list_view: 1,
136
+ },
137
+ { fieldname: "currency", label: "Currency", fieldtype: "Link", options: "Currency" },
138
+ {
139
+ fieldname: "converted",
140
+ label: "Converted",
141
+ fieldtype: "Currency",
142
+ options: "Company:company:default_currency",
143
+ in_list_view: 1,
144
+ },
145
+ ],
146
+ };
147
+ expect(defaultReportFieldnames(meta)).toEqual([
148
+ "name",
149
+ "amount",
150
+ "converted",
151
+ "currency",
152
+ "company",
153
+ "modified",
154
+ ]);
155
+ });
156
+ });
157
+
158
+ describe("reportColumnsFromMeta", () => {
159
+ it("offers ID first, all value-type meta fields, then standard doc fields", () => {
160
+ const columns = reportColumnsFromMeta(userMeta);
161
+ expect(columns[0].fieldname).toBe("name");
162
+ const names = columns.map((entry) => entry.fieldname);
163
+ expect(names).toContain("bio");
164
+ expect(names).toContain("points");
165
+ expect(names).toContain("owner");
166
+ expect(names).toContain("modified");
167
+ expect(names).not.toContain("roles");
168
+ expect(names).not.toContain("basic_section");
169
+ });
170
+
171
+ it("derives kind, width and alignment from the fieldtype", () => {
172
+ const columns = reportColumnsFromMeta(userMeta);
173
+ const points = columns.find((entry) => entry.fieldname === "points");
174
+ expect(points).toMatchObject({ kind: "number", align: "right" });
175
+ const enabled = columns.find((entry) => entry.fieldname === "enabled");
176
+ expect(enabled).toMatchObject({ kind: "check", align: "center" });
177
+ const userType = columns.find((entry) => entry.fieldname === "user_type");
178
+ expect(userType).toMatchObject({ kind: "select", options: "System User\nWebsite User" });
179
+ });
180
+ });
181
+
182
+ describe("resolveSelectedColumns", () => {
183
+ it("keeps selection order and drops unknown fieldnames", () => {
184
+ const all = reportColumnsFromMeta(userMeta);
185
+ const resolved = resolveSelectedColumns(all, ["user_type", "nope", "name"]);
186
+ expect(resolved.map((entry) => entry.fieldname)).toEqual(["user_type", "name"]);
187
+ });
188
+ });
189
+
190
+ describe("columnFilterTuple", () => {
191
+ it("wraps text in contains-like (user wildcards win)", () => {
192
+ expect(columnFilterTuple(column("email"), "test")).toEqual(["email", "like", "%test%"]);
193
+ expect(columnFilterTuple(column("email"), "test%")).toEqual(["email", "like", "test%"]);
194
+ expect(columnFilterTuple(column("email"), " ")).toBeNull();
195
+ });
196
+
197
+ it("equals exact select options (case-insensitive), likes partials", () => {
198
+ const select = column("user_type", {
199
+ fieldtype: "Select",
200
+ kind: "select",
201
+ options: "System User\nWebsite User",
202
+ });
203
+ expect(columnFilterTuple(select, "system user")).toEqual(["user_type", "=", "System User"]);
204
+ expect(columnFilterTuple(select, "Sys")).toEqual(["user_type", "like", "%Sys%"]);
205
+ });
206
+
207
+ it("parses check values, rejects unparseable input", () => {
208
+ const check = column("enabled", { fieldtype: "Check", kind: "check" });
209
+ expect(columnFilterTuple(check, "yes")).toEqual(["enabled", "=", 1]);
210
+ expect(columnFilterTuple(check, "0")).toEqual(["enabled", "=", 0]);
211
+ expect(columnFilterTuple(check, "maybe")).toBeNull();
212
+ });
213
+
214
+ it("supports comparison prefixes on numbers and dates", () => {
215
+ const points = column("points", { fieldtype: "Int", kind: "number" });
216
+ expect(columnFilterTuple(points, ">= 10")).toEqual(["points", ">=", "10"]);
217
+ expect(columnFilterTuple(points, "5")).toEqual(["points", "=", "5"]);
218
+ expect(columnFilterTuple(points, ">")).toBeNull();
219
+ const modified = column("modified", { fieldtype: "Datetime", kind: "date" });
220
+ expect(columnFilterTuple(modified, ">2026-01-01")).toEqual(["modified", ">", "2026-01-01"]);
221
+ });
222
+ });
223
+
224
+ describe("columnFilterTuples", () => {
225
+ it("collects only parseable inputs, keyed by fieldname", () => {
226
+ const columns = [column("email"), column("enabled", { fieldtype: "Check", kind: "check" })];
227
+ expect(columnFilterTuples(columns, { email: "a", enabled: "??", other: "x" })).toEqual([
228
+ ["email", "like", "%a%"],
229
+ ]);
230
+ });
231
+ });
232
+
233
+ describe("desk report settings round trip", () => {
234
+ it("serializes fields/filters/order_by/group_by in desk shape", () => {
235
+ const settings = toDeskReportSettings("User", {
236
+ fieldnames: ["name", "email"],
237
+ filters: [["enabled", "=", 1]],
238
+ sort: { field: "creation", order: "asc" },
239
+ pageSize: 100,
240
+ groupBy: "user_type",
241
+ addTotals: true,
242
+ });
243
+ expect(settings.fields).toEqual([
244
+ ["name", "User"],
245
+ ["email", "User"],
246
+ ]);
247
+ expect(settings.filters).toEqual([["User", "enabled", "=", 1]]);
248
+ expect(settings.order_by).toBe("`tabUser`.`creation` asc");
249
+ expect(settings.add_totals_row).toBe(1);
250
+ expect(settings.page_length).toBe(100);
251
+ expect(settings.group_by).toEqual({
252
+ group_by: "`tabUser`.`user_type`",
253
+ aggregate_function: "count",
254
+ aggregate_on: null,
255
+ });
256
+ });
257
+
258
+ it("parses desk json back (dropping child-doctype fields and filters)", () => {
259
+ const parsed = fromDeskReportSettings("User", {
260
+ fields: [["name", "User"], ["role", "Has Role"], "email"],
261
+ filters: [
262
+ ["User", "enabled", "=", 1],
263
+ ["Has Role", "role", "=", "System Manager"],
264
+ ["user_type", "=", "System User"],
265
+ ],
266
+ order_by: "`tabUser`.`modified` desc",
267
+ add_totals_row: 1,
268
+ page_length: 500,
269
+ group_by: { group_by: "`tabUser`.`user_type`", aggregate_function: "count" },
270
+ });
271
+ expect(parsed).toEqual({
272
+ fieldnames: ["name", "email"],
273
+ filters: [
274
+ ["enabled", "=", 1],
275
+ ["user_type", "=", "System User"],
276
+ ],
277
+ sort: { field: "modified", order: "desc" },
278
+ pageSize: 500,
279
+ groupBy: "user_type",
280
+ addTotals: true,
281
+ });
282
+ });
283
+
284
+ it("round-trips through its own serialization", () => {
285
+ const config = {
286
+ fieldnames: ["name", "points"],
287
+ filters: [["points", ">", "5"]] as Array<[string, string, unknown]>,
288
+ sort: { field: "points", order: "asc" as const },
289
+ pageSize: 20,
290
+ groupBy: null,
291
+ addTotals: false,
292
+ };
293
+ const parsed = fromDeskReportSettings("User", toDeskReportSettings("User", config));
294
+ expect(parsed).toEqual(config);
295
+ });
296
+
297
+ it("tolerates garbage", () => {
298
+ expect(fromDeskReportSettings("User", null)).toBeUndefined();
299
+ expect(fromDeskReportSettings("User", "{}")).toBeUndefined();
300
+ expect(fromDeskReportSettings("User", {})).toMatchObject({ fieldnames: [], filters: [] });
301
+ });
302
+ });
303
+
304
+ describe("parseDeskOrderBy", () => {
305
+ it("parses backticked and bare expressions", () => {
306
+ expect(parseDeskOrderBy("`tabUser`.`modified` desc")).toEqual({
307
+ field: "modified",
308
+ order: "desc",
309
+ });
310
+ expect(parseDeskOrderBy("creation asc")).toEqual({ field: "creation", order: "asc" });
311
+ expect(parseDeskOrderBy("")).toBeUndefined();
312
+ expect(parseDeskOrderBy(42)).toBeUndefined();
313
+ });
314
+ });
315
+
316
+ describe("orderReportRows / buildGridRows", () => {
317
+ const rows: ReportRow[] = [
318
+ { name: "c", status: "Open", points: 3 },
319
+ { name: "a", status: "Closed", points: 1 },
320
+ { name: "b", status: "Open", points: 2 },
321
+ { name: "d", status: "Open", points: null },
322
+ ];
323
+
324
+ it("orders by sort field with name tiebreak, nulls last", () => {
325
+ const ordered = orderReportRows(rows, { field: "points", order: "desc" });
326
+ expect(ordered.map((row) => row.name)).toEqual(["c", "b", "a", "d"]);
327
+ });
328
+
329
+ it("groups first when grouping, then sorts inside groups", () => {
330
+ const ordered = orderReportRows(rows, { field: "points", order: "asc" }, "status");
331
+ expect(ordered.map((row) => row.name)).toEqual(["a", "b", "c", "d"]);
332
+ });
333
+
334
+ it("injects group headers with full-result counts inside the page", () => {
335
+ const ordered = orderReportRows(rows, { field: "points", order: "asc" }, "status");
336
+ const page = buildGridRows(ordered, 0, 2, "status");
337
+ expect(page).toHaveLength(4);
338
+ expect(page[0]).toMatchObject({ kind: "group", value: "Closed", count: 1 });
339
+ expect(page[1]).toMatchObject({ kind: "row", key: "a", index: 1 });
340
+ expect(page[2]).toMatchObject({ kind: "group", value: "Open", count: 3 });
341
+ expect(page[3]).toMatchObject({ kind: "row", key: "b", index: 2 });
342
+ });
343
+
344
+ it("numbers rows across pages without grouping", () => {
345
+ const ordered = orderReportRows(rows, { field: "name", order: "asc" });
346
+ const page = buildGridRows(ordered, 2, 2);
347
+ expect(page).toEqual([
348
+ { kind: "row", key: "c", row: ordered[2], index: 3 },
349
+ { kind: "row", key: "d", row: ordered[3], index: 4 },
350
+ ]);
351
+ });
352
+ });
353
+
354
+ describe("computeTotals", () => {
355
+ it("sums numeric visible columns over all rows", () => {
356
+ const columns = [column("name"), column("points", { fieldtype: "Int", kind: "number" })];
357
+ const totals = computeTotals(columns, [
358
+ { name: "a", points: 1 },
359
+ { name: "b", points: 2 },
360
+ { name: "c", points: "x" },
361
+ ]);
362
+ expect(totals).toEqual([{ fieldname: "points", fieldtype: "Int", value: 3 }]);
363
+ });
364
+
365
+ it("is empty without rows", () => {
366
+ expect(computeTotals([column("points", { fieldtype: "Int", kind: "number" })], [])).toEqual([]);
367
+ });
368
+ });
369
+
370
+ describe("buildReportCsv", () => {
371
+ it("escapes quotes, commas and newlines", () => {
372
+ const csv = buildReportCsv(
373
+ [column("name", { label: "ID" }), column("bio", { label: "Bio, or so" })],
374
+ [{ name: "a", bio: 'say "hi"\nplease' }],
375
+ );
376
+ expect(csv).toBe('ID,"Bio, or so"\na,"say ""hi""\nplease"');
377
+ });
378
+ });
379
+
380
+ describe("parseReportFiltersParam", () => {
381
+ it("parses raw and urlencoded JSON tuples", () => {
382
+ expect(parseReportFiltersParam('[["enabled","=",1]]')).toEqual([["enabled", "=", 1]]);
383
+ expect(
384
+ parseReportFiltersParam(encodeURIComponent('[["user_type","=","System User"]]')),
385
+ ).toEqual([["user_type", "=", "System User"]]);
386
+ });
387
+
388
+ it("degrades to undefined on malformed input", () => {
389
+ expect(parseReportFiltersParam("not json")).toBeUndefined();
390
+ expect(parseReportFiltersParam("")).toBeUndefined();
391
+ expect(parseReportFiltersParam(42)).toBeUndefined();
392
+ });
393
+ });