@multiplatform.one/frappe-ui 7.11.0 → 7.15.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 (341) hide show
  1. package/README.md +2 -2
  2. package/dist/cjs/FrappeDashboard.cjs +8 -10
  3. package/dist/cjs/FrappeDashboard.native.js +8 -14
  4. package/dist/cjs/FrappeDashboard.native.js.map +1 -1
  5. package/dist/cjs/FrappeForm.cjs +465 -175
  6. package/dist/cjs/FrappeForm.native.js +611 -207
  7. package/dist/cjs/FrappeForm.native.js.map +1 -1
  8. package/dist/cjs/FrappeFormConnections.cjs +125 -0
  9. package/dist/cjs/FrappeFormConnections.native.js +149 -0
  10. package/dist/cjs/FrappeFormConnections.native.js.map +1 -0
  11. package/dist/cjs/FrappeImageView.cjs +7 -9
  12. package/dist/cjs/FrappeImageView.native.js +7 -13
  13. package/dist/cjs/FrappeImageView.native.js.map +1 -1
  14. package/dist/cjs/FrappeList.cjs +29 -4
  15. package/dist/cjs/FrappeList.native.js +37 -5
  16. package/dist/cjs/FrappeList.native.js.map +1 -1
  17. package/dist/cjs/FrappeListView.cjs +102 -29
  18. package/dist/cjs/FrappeListView.native.js +109 -29
  19. package/dist/cjs/FrappeListView.native.js.map +1 -1
  20. package/dist/cjs/FrappeProvider.cjs +7 -2
  21. package/dist/cjs/FrappeProvider.native.js +7 -2
  22. package/dist/cjs/FrappeProvider.native.js.map +1 -1
  23. package/dist/cjs/FrappeReportBuilder.cjs +10 -11
  24. package/dist/cjs/FrappeReportBuilder.native.js +10 -16
  25. package/dist/cjs/FrappeReportBuilder.native.js.map +1 -1
  26. package/dist/cjs/FrappeRowsReader.cjs +49 -0
  27. package/dist/cjs/FrappeRowsReader.native.js +53 -0
  28. package/dist/cjs/FrappeRowsReader.native.js.map +1 -0
  29. package/dist/cjs/FrappeTable.cjs +18 -6
  30. package/dist/cjs/FrappeTable.native.js +24 -6
  31. package/dist/cjs/FrappeTable.native.js.map +1 -1
  32. package/dist/cjs/fieldRegistry.cjs +36 -11
  33. package/dist/cjs/fieldRegistry.native.js +59 -11
  34. package/dist/cjs/fieldRegistry.native.js.map +1 -1
  35. package/dist/cjs/fields/Date/index.native.js +5 -2
  36. package/dist/cjs/fields/Date/index.native.js.map +1 -1
  37. package/dist/cjs/fields/Date/sheetKeyboard.cjs +2 -2
  38. package/dist/cjs/fields/Date/sheetKeyboard.native.js +2 -2
  39. package/dist/cjs/fields/Date/sheetKeyboard.native.js.map +1 -1
  40. package/dist/cjs/fields/DateRange/index.cjs +2 -1
  41. package/dist/cjs/fields/DateRange/index.native.js +4 -1
  42. package/dist/cjs/fields/DateRange/index.native.js.map +1 -1
  43. package/dist/cjs/formEngine/index.cjs +4 -2
  44. package/dist/cjs/formEngine/index.native.js +3 -1
  45. package/dist/cjs/formEngine/index.native.js.map +1 -1
  46. package/dist/cjs/formEngine/useSessionRoles.cjs +77 -0
  47. package/dist/cjs/formEngine/useSessionRoles.native.js +84 -0
  48. package/dist/cjs/formEngine/useSessionRoles.native.js.map +1 -0
  49. package/dist/cjs/frappeConnections.cjs +41 -0
  50. package/dist/cjs/frappeConnections.native.js +50 -0
  51. package/dist/cjs/frappeConnections.native.js.map +1 -0
  52. package/dist/cjs/frappeNavigation.cjs +107 -0
  53. package/dist/cjs/frappeNavigation.native.js +112 -0
  54. package/dist/cjs/frappeNavigation.native.js.map +1 -0
  55. package/dist/cjs/index.cjs +18 -1
  56. package/dist/cjs/index.native.js +18 -1
  57. package/dist/cjs/index.native.js.map +1 -1
  58. package/dist/cjs/schemaForm/index.cjs +4 -1
  59. package/dist/cjs/schemaForm/index.native.js +4 -1
  60. package/dist/cjs/schemaForm/index.native.js.map +1 -1
  61. package/dist/cjs/useConnectionFilters.cjs +146 -0
  62. package/dist/cjs/useConnectionFilters.native.js +213 -0
  63. package/dist/cjs/useConnectionFilters.native.js.map +1 -0
  64. package/dist/cjs/useFrappePagination.cjs +37 -18
  65. package/dist/cjs/useFrappePagination.native.js +59 -23
  66. package/dist/cjs/useFrappePagination.native.js.map +1 -1
  67. package/dist/cjs/useFrappeRows.native.js.map +1 -1
  68. package/dist/esm/FrappeDashboard.mjs +9 -11
  69. package/dist/esm/FrappeDashboard.mjs.map +1 -1
  70. package/dist/esm/FrappeDashboard.native.js +9 -15
  71. package/dist/esm/FrappeDashboard.native.js.map +1 -1
  72. package/dist/esm/FrappeForm.mjs +471 -181
  73. package/dist/esm/FrappeForm.mjs.map +1 -1
  74. package/dist/esm/FrappeForm.native.js +599 -195
  75. package/dist/esm/FrappeForm.native.js.map +1 -1
  76. package/dist/esm/FrappeFormConnections.mjs +99 -0
  77. package/dist/esm/FrappeFormConnections.mjs.map +1 -0
  78. package/dist/esm/FrappeFormConnections.native.js +120 -0
  79. package/dist/esm/FrappeFormConnections.native.js.map +1 -0
  80. package/dist/esm/FrappeImageView.mjs +8 -10
  81. package/dist/esm/FrappeImageView.mjs.map +1 -1
  82. package/dist/esm/FrappeImageView.native.js +8 -14
  83. package/dist/esm/FrappeImageView.native.js.map +1 -1
  84. package/dist/esm/FrappeList.mjs +31 -6
  85. package/dist/esm/FrappeList.mjs.map +1 -1
  86. package/dist/esm/FrappeList.native.js +39 -7
  87. package/dist/esm/FrappeList.native.js.map +1 -1
  88. package/dist/esm/FrappeListView.mjs +103 -30
  89. package/dist/esm/FrappeListView.mjs.map +1 -1
  90. package/dist/esm/FrappeListView.native.js +110 -30
  91. package/dist/esm/FrappeListView.native.js.map +1 -1
  92. package/dist/esm/FrappeProvider.mjs +7 -2
  93. package/dist/esm/FrappeProvider.mjs.map +1 -1
  94. package/dist/esm/FrappeProvider.native.js +7 -2
  95. package/dist/esm/FrappeProvider.native.js.map +1 -1
  96. package/dist/esm/FrappeReportBuilder.mjs +11 -12
  97. package/dist/esm/FrappeReportBuilder.mjs.map +1 -1
  98. package/dist/esm/FrappeReportBuilder.native.js +11 -17
  99. package/dist/esm/FrappeReportBuilder.native.js.map +1 -1
  100. package/dist/esm/FrappeRowsReader.mjs +24 -0
  101. package/dist/esm/FrappeRowsReader.mjs.map +1 -0
  102. package/dist/esm/FrappeRowsReader.native.js +25 -0
  103. package/dist/esm/FrappeRowsReader.native.js.map +1 -0
  104. package/dist/esm/FrappeTable.mjs +18 -6
  105. package/dist/esm/FrappeTable.mjs.map +1 -1
  106. package/dist/esm/FrappeTable.native.js +24 -6
  107. package/dist/esm/FrappeTable.native.js.map +1 -1
  108. package/dist/esm/fieldRegistry.mjs +35 -12
  109. package/dist/esm/fieldRegistry.mjs.map +1 -1
  110. package/dist/esm/fieldRegistry.native.js +58 -12
  111. package/dist/esm/fieldRegistry.native.js.map +1 -1
  112. package/dist/esm/fields/Date/index.native.js +6 -3
  113. package/dist/esm/fields/Date/index.native.js.map +1 -1
  114. package/dist/esm/fields/Date/sheetKeyboard.mjs +2 -2
  115. package/dist/esm/fields/Date/sheetKeyboard.mjs.map +1 -1
  116. package/dist/esm/fields/Date/sheetKeyboard.native.js +2 -2
  117. package/dist/esm/fields/Date/sheetKeyboard.native.js.map +1 -1
  118. package/dist/esm/fields/DateRange/index.mjs +2 -1
  119. package/dist/esm/fields/DateRange/index.mjs.map +1 -1
  120. package/dist/esm/fields/DateRange/index.native.js +4 -1
  121. package/dist/esm/fields/DateRange/index.native.js.map +1 -1
  122. package/dist/esm/formEngine/index.mjs +2 -1
  123. package/dist/esm/formEngine/index.mjs.map +1 -1
  124. package/dist/esm/formEngine/index.native.js +2 -1
  125. package/dist/esm/formEngine/index.native.js.map +1 -1
  126. package/dist/esm/formEngine/useSessionRoles.mjs +52 -0
  127. package/dist/esm/formEngine/useSessionRoles.mjs.map +1 -0
  128. package/dist/esm/formEngine/useSessionRoles.native.js +56 -0
  129. package/dist/esm/formEngine/useSessionRoles.native.js.map +1 -0
  130. package/dist/esm/frappeConnections.mjs +15 -0
  131. package/dist/esm/frappeConnections.mjs.map +1 -0
  132. package/dist/esm/frappeConnections.native.js +21 -0
  133. package/dist/esm/frappeConnections.native.js.map +1 -0
  134. package/dist/esm/frappeNavigation.mjs +78 -0
  135. package/dist/esm/frappeNavigation.mjs.map +1 -0
  136. package/dist/esm/frappeNavigation.native.js +80 -0
  137. package/dist/esm/frappeNavigation.native.js.map +1 -0
  138. package/dist/esm/index.mjs +7 -3
  139. package/dist/esm/index.mjs.map +1 -1
  140. package/dist/esm/index.native.js +7 -3
  141. package/dist/esm/index.native.js.map +1 -1
  142. package/dist/esm/schemaForm/index.mjs +4 -1
  143. package/dist/esm/schemaForm/index.mjs.map +1 -1
  144. package/dist/esm/schemaForm/index.native.js +4 -1
  145. package/dist/esm/schemaForm/index.native.js.map +1 -1
  146. package/dist/esm/useConnectionFilters.mjs +121 -0
  147. package/dist/esm/useConnectionFilters.mjs.map +1 -0
  148. package/dist/esm/useConnectionFilters.native.js +185 -0
  149. package/dist/esm/useConnectionFilters.native.js.map +1 -0
  150. package/dist/esm/useFrappePagination.mjs +38 -19
  151. package/dist/esm/useFrappePagination.mjs.map +1 -1
  152. package/dist/esm/useFrappePagination.native.js +60 -24
  153. package/dist/esm/useFrappePagination.native.js.map +1 -1
  154. package/dist/esm/useFrappeRows.mjs.map +1 -1
  155. package/dist/esm/useFrappeRows.native.js.map +1 -1
  156. package/dist/jsx/FrappeDashboard.mjs +9 -11
  157. package/dist/jsx/FrappeDashboard.mjs.map +1 -1
  158. package/dist/jsx/FrappeDashboard.native.js +8 -14
  159. package/dist/jsx/FrappeDashboard.native.js.map +1 -1
  160. package/dist/jsx/FrappeForm.mjs +471 -181
  161. package/dist/jsx/FrappeForm.mjs.map +1 -1
  162. package/dist/jsx/FrappeForm.native.js +611 -207
  163. package/dist/jsx/FrappeForm.native.js.map +1 -1
  164. package/dist/jsx/FrappeFormConnections.mjs +99 -0
  165. package/dist/jsx/FrappeFormConnections.mjs.map +1 -0
  166. package/dist/jsx/FrappeFormConnections.native.js +149 -0
  167. package/dist/jsx/FrappeFormConnections.native.js.map +1 -0
  168. package/dist/jsx/FrappeImageView.mjs +8 -10
  169. package/dist/jsx/FrappeImageView.mjs.map +1 -1
  170. package/dist/jsx/FrappeImageView.native.js +7 -13
  171. package/dist/jsx/FrappeImageView.native.js.map +1 -1
  172. package/dist/jsx/FrappeList.mjs +31 -6
  173. package/dist/jsx/FrappeList.mjs.map +1 -1
  174. package/dist/jsx/FrappeList.native.js +37 -5
  175. package/dist/jsx/FrappeList.native.js.map +1 -1
  176. package/dist/jsx/FrappeListView.mjs +103 -30
  177. package/dist/jsx/FrappeListView.mjs.map +1 -1
  178. package/dist/jsx/FrappeListView.native.js +109 -29
  179. package/dist/jsx/FrappeListView.native.js.map +1 -1
  180. package/dist/jsx/FrappeProvider.mjs +7 -2
  181. package/dist/jsx/FrappeProvider.mjs.map +1 -1
  182. package/dist/jsx/FrappeProvider.native.js +7 -2
  183. package/dist/jsx/FrappeProvider.native.js.map +1 -1
  184. package/dist/jsx/FrappeReportBuilder.mjs +11 -12
  185. package/dist/jsx/FrappeReportBuilder.mjs.map +1 -1
  186. package/dist/jsx/FrappeReportBuilder.native.js +10 -16
  187. package/dist/jsx/FrappeReportBuilder.native.js.map +1 -1
  188. package/dist/jsx/FrappeRowsReader.mjs +24 -0
  189. package/dist/jsx/FrappeRowsReader.mjs.map +1 -0
  190. package/dist/jsx/FrappeRowsReader.native.js +53 -0
  191. package/dist/jsx/FrappeRowsReader.native.js.map +1 -0
  192. package/dist/jsx/FrappeTable.mjs +18 -6
  193. package/dist/jsx/FrappeTable.mjs.map +1 -1
  194. package/dist/jsx/FrappeTable.native.js +24 -6
  195. package/dist/jsx/FrappeTable.native.js.map +1 -1
  196. package/dist/jsx/fieldRegistry.mjs +35 -12
  197. package/dist/jsx/fieldRegistry.mjs.map +1 -1
  198. package/dist/jsx/fieldRegistry.native.js +59 -11
  199. package/dist/jsx/fieldRegistry.native.js.map +1 -1
  200. package/dist/jsx/fields/Date/index.native.js +5 -2
  201. package/dist/jsx/fields/Date/index.native.js.map +1 -1
  202. package/dist/jsx/fields/Date/sheetKeyboard.mjs +2 -2
  203. package/dist/jsx/fields/Date/sheetKeyboard.mjs.map +1 -1
  204. package/dist/jsx/fields/Date/sheetKeyboard.native.js +2 -2
  205. package/dist/jsx/fields/Date/sheetKeyboard.native.js.map +1 -1
  206. package/dist/jsx/fields/DateRange/index.mjs +2 -1
  207. package/dist/jsx/fields/DateRange/index.mjs.map +1 -1
  208. package/dist/jsx/fields/DateRange/index.native.js +4 -1
  209. package/dist/jsx/fields/DateRange/index.native.js.map +1 -1
  210. package/dist/jsx/formEngine/index.mjs +2 -1
  211. package/dist/jsx/formEngine/index.mjs.map +1 -1
  212. package/dist/jsx/formEngine/index.native.js +3 -1
  213. package/dist/jsx/formEngine/index.native.js.map +1 -1
  214. package/dist/jsx/formEngine/useSessionRoles.mjs +52 -0
  215. package/dist/jsx/formEngine/useSessionRoles.mjs.map +1 -0
  216. package/dist/jsx/formEngine/useSessionRoles.native.js +84 -0
  217. package/dist/jsx/formEngine/useSessionRoles.native.js.map +1 -0
  218. package/dist/jsx/frappeConnections.mjs +15 -0
  219. package/dist/jsx/frappeConnections.mjs.map +1 -0
  220. package/dist/jsx/frappeConnections.native.js +50 -0
  221. package/dist/jsx/frappeConnections.native.js.map +1 -0
  222. package/dist/jsx/frappeNavigation.mjs +78 -0
  223. package/dist/jsx/frappeNavigation.mjs.map +1 -0
  224. package/dist/jsx/frappeNavigation.native.js +112 -0
  225. package/dist/jsx/frappeNavigation.native.js.map +1 -0
  226. package/dist/jsx/index.js +7 -3
  227. package/dist/jsx/index.js.map +1 -1
  228. package/dist/jsx/index.mjs +7 -3
  229. package/dist/jsx/index.mjs.map +1 -1
  230. package/dist/jsx/index.native.js +18 -1
  231. package/dist/jsx/index.native.js.map +1 -1
  232. package/dist/jsx/schemaForm/index.mjs +4 -1
  233. package/dist/jsx/schemaForm/index.mjs.map +1 -1
  234. package/dist/jsx/schemaForm/index.native.js +4 -1
  235. package/dist/jsx/schemaForm/index.native.js.map +1 -1
  236. package/dist/jsx/useConnectionFilters.mjs +121 -0
  237. package/dist/jsx/useConnectionFilters.mjs.map +1 -0
  238. package/dist/jsx/useConnectionFilters.native.js +213 -0
  239. package/dist/jsx/useConnectionFilters.native.js.map +1 -0
  240. package/dist/jsx/useFrappePagination.mjs +38 -19
  241. package/dist/jsx/useFrappePagination.mjs.map +1 -1
  242. package/dist/jsx/useFrappePagination.native.js +59 -23
  243. package/dist/jsx/useFrappePagination.native.js.map +1 -1
  244. package/dist/jsx/useFrappeRows.mjs.map +1 -1
  245. package/dist/jsx/useFrappeRows.native.js.map +1 -1
  246. package/package.json +24 -20
  247. package/src/FileBrowser/AttachLibrary.stories.tsx +23 -0
  248. package/src/FrappeDashboard.tsx +11 -16
  249. package/src/FrappeForm.connections.spec.tsx +280 -0
  250. package/src/FrappeForm.connections.stories.tsx +93 -0
  251. package/src/FrappeForm.deskSemantics.spec.tsx +284 -0
  252. package/src/FrappeForm.tsx +560 -145
  253. package/src/FrappeFormConnections.tsx +148 -0
  254. package/src/FrappeGuestMeta.spec.tsx +143 -0
  255. package/src/FrappeImageView.tsx +8 -12
  256. package/src/FrappeList.tsx +71 -15
  257. package/src/FrappeListView.cards.spec.tsx +175 -0
  258. package/src/FrappeListView.cards.stories.tsx +131 -0
  259. package/src/FrappeListView.connections.spec.tsx +192 -0
  260. package/src/FrappeListView.connections.stories.tsx +99 -0
  261. package/src/FrappeListView.seed.spec.tsx +228 -0
  262. package/src/FrappeListView.tsx +177 -31
  263. package/src/FrappeProvider.tsx +13 -1
  264. package/src/FrappeReportBuilder.tsx +11 -19
  265. package/src/FrappeRowsReader.tsx +38 -0
  266. package/src/FrappeTable.optionalProps.spec.tsx +249 -0
  267. package/src/FrappeTable.spec.tsx +32 -42
  268. package/src/FrappeTable.stories.spec.tsx +55 -0
  269. package/src/FrappeTable.stories.tsx +28 -37
  270. package/src/FrappeTable.tsx +108 -45
  271. package/src/childTableDependsOn.spec.tsx +85 -0
  272. package/src/desk/DeskFormSidebar.spec.tsx +20 -0
  273. package/src/desk/DeskFormSidebar.stories.tsx +42 -0
  274. package/src/fieldRegistry.spec.tsx +27 -64
  275. package/src/fieldRegistry.ts +71 -14
  276. package/src/fields/Date/index.native.tsx +4 -2
  277. package/src/fields/Date/sheetKeyboard.spec.ts +14 -5
  278. package/src/fields/Date/sheetKeyboard.ts +12 -4
  279. package/src/fields/DateRange/DateRange.spec.tsx +67 -0
  280. package/src/fields/DateRange/index.tsx +5 -1
  281. package/src/fields/LinkTree.spec.tsx +8 -0
  282. package/src/fields/LinkTree.stories.tsx +28 -5
  283. package/src/fields/Select/Select.hydration.spec.tsx +177 -0
  284. package/src/formEngine/doctypeMeta.ts +15 -114
  285. package/src/formEngine/index.ts +2 -0
  286. package/src/formEngine/seam.spec.ts +23 -4
  287. package/src/formEngine/useSessionRoles.ts +73 -0
  288. package/src/frappeConnections.ts +50 -0
  289. package/src/frappeNavigation.tsx +112 -0
  290. package/src/frappeRoutes.spec.tsx +335 -0
  291. package/src/index.ts +28 -1
  292. package/src/schemaForm/index.tsx +1 -0
  293. package/src/useConnectionFilters.tsx +157 -0
  294. package/src/useFrappePagination.ts +70 -26
  295. package/src/useFrappeRows.sharedPath.spec.tsx +206 -0
  296. package/src/useFrappeRows.ts +5 -4
  297. package/types/FrappeDashboard.d.ts +3 -4
  298. package/types/FrappeDashboard.d.ts.map +1 -1
  299. package/types/FrappeForm.d.ts +57 -5
  300. package/types/FrappeForm.d.ts.map +1 -1
  301. package/types/FrappeFormConnections.d.ts +18 -0
  302. package/types/FrappeFormConnections.d.ts.map +1 -0
  303. package/types/FrappeImageView.d.ts +2 -3
  304. package/types/FrappeImageView.d.ts.map +1 -1
  305. package/types/FrappeList.d.ts +20 -2
  306. package/types/FrappeList.d.ts.map +1 -1
  307. package/types/FrappeListView.d.ts +53 -3
  308. package/types/FrappeListView.d.ts.map +1 -1
  309. package/types/FrappeProvider.d.ts +8 -1
  310. package/types/FrappeProvider.d.ts.map +1 -1
  311. package/types/FrappeReportBuilder.d.ts.map +1 -1
  312. package/types/FrappeRowsReader.d.ts +26 -0
  313. package/types/FrappeRowsReader.d.ts.map +1 -0
  314. package/types/FrappeTable.d.ts +39 -8
  315. package/types/FrappeTable.d.ts.map +1 -1
  316. package/types/fieldRegistry.d.ts +17 -3
  317. package/types/fieldRegistry.d.ts.map +1 -1
  318. package/types/fields/Date/index.native.d.ts.map +1 -1
  319. package/types/fields/Date/sheetKeyboard.d.ts +4 -3
  320. package/types/fields/Date/sheetKeyboard.d.ts.map +1 -1
  321. package/types/fields/DateRange/index.d.ts.map +1 -1
  322. package/types/formEngine/doctypeMeta.d.ts +10 -114
  323. package/types/formEngine/doctypeMeta.d.ts.map +1 -1
  324. package/types/formEngine/index.d.ts +1 -0
  325. package/types/formEngine/index.d.ts.map +1 -1
  326. package/types/formEngine/useSessionRoles.d.ts +19 -0
  327. package/types/formEngine/useSessionRoles.d.ts.map +1 -0
  328. package/types/frappeConnections.d.ts +33 -0
  329. package/types/frappeConnections.d.ts.map +1 -0
  330. package/types/frappeNavigation.d.ts +49 -0
  331. package/types/frappeNavigation.d.ts.map +1 -0
  332. package/types/index.d.ts +7 -3
  333. package/types/index.d.ts.map +1 -1
  334. package/types/schemaForm/index.d.ts.map +1 -1
  335. package/types/useConnectionFilters.d.ts +34 -0
  336. package/types/useConnectionFilters.d.ts.map +1 -0
  337. package/types/useFrappePagination.d.ts +18 -5
  338. package/types/useFrappePagination.d.ts.map +1 -1
  339. package/types/useFrappeRows.d.ts +5 -4
  340. package/types/useFrappeRows.d.ts.map +1 -1
  341. package/src/FileBrowser/AttachLibrary.spec.tsx +0 -74
@@ -1,62 +1,87 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useFrappeCollection, useFrappeDoctypeEvents, useLiveQuery, useDocTypeMeta } from "@multiplatform.one/frappe";
3
- import { AsyncSkeleton } from "@multiplatform.one/components";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { createElement as _createElement } from "react";
3
+ import { getFrappeSyncModule, useFrappeCollection, useFrappeDoctypeEvents, useLiveQuery, useDocTypeMeta } from "@multiplatform.one/frappe";
4
+ import { AsyncBoundary, AsyncSkeleton, DetailPageLayout, PageHeader, Tabs } from "@multiplatform.one/components";
4
5
  import { SchemaForm } from "./schemaForm/index.native.js";
5
6
  import { FormSidebar } from "./FormSidebar.native.js";
6
7
  import { eq } from "@tanstack/db";
7
- import { FloppyDiskIcon, TrashIcon, XIcon } from "@phosphor-icons/react";
8
- import { useEffect, useMemo, useRef, useState } from "react";
8
+ import { ArrowLeftIcon, FloppyDiskIcon, PencilSimpleIcon, TrashIcon, XIcon } from "@phosphor-icons/react";
9
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
9
10
  import { useTranslation } from "react-i18next";
10
- import { Button, formCommonColors } from "@multiplatform.one/forms";
11
+ import { Button, Input, formCommonColors } from "@multiplatform.one/forms";
11
12
  import { Text, XStack, YStack } from "tamagui";
12
13
  import { useResolvedKnobs } from "@multiplatform.one/theme";
13
14
  import { useFrappeConfig } from "./FrappeProvider.native.js";
14
15
  import { FrappeReconnectIndicator } from "./FrappeReconnectIndicator.native.js";
15
16
  import { Timeline } from "./components/timeline.native.js";
16
17
  import { dialog } from "@multiplatform.one/desktop";
17
- var LAYOUT_FIELDTYPES = /* @__PURE__ */new Set(["Section Break", "Column Break", "Tab Break"]);
18
+ import { applyFetchedValues, buildFetchMap } from "./formEngine/fetchFrom.native.js";
19
+ import { buildPermLevelMatrix } from "./formEngine/fieldPermissions.native.js";
20
+ import { createHttpClient, validateLink } from "./formEngine/formActions.native.js";
21
+ import { buildFormTabs, isPromptNamed } from "./formEngine/formLayout.native.js";
22
+ import { useSessionRoles } from "./formEngine/useSessionRoles.native.js";
23
+ import { connectionFields, connectionsFromMeta } from "./frappeConnections.native.js";
24
+ import { FrappeFormConnections } from "./FrappeFormConnections.native.js";
25
+ import { FrappeRowsReader } from "./FrappeRowsReader.native.js";
26
+ import { frappeRouteHref, frappeRouteTarget, useFrappeRouter } from "./frappeNavigation.native.js";
27
+ function _instanceof(left, right) {
28
+ "@swc/helpers - instanceof";
29
+
30
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
31
+ return !!right[Symbol.hasInstance](left);
32
+ } else {
33
+ return left instanceof right;
34
+ }
35
+ }
18
36
  function isEmptyFieldValue(value) {
19
37
  if (value === void 0 || value === null) return true;
20
38
  if (typeof value === "string" && value.trim() === "") return true;
21
39
  if (Array.isArray(value) && value.length === 0) return true;
22
40
  return false;
23
41
  }
24
- function mapFieldToGenericSchema(field) {
25
- return {
26
- type: field.fieldtype,
27
- name: field.fieldname,
28
- label: field.label,
29
- options: field.options,
30
- required: !!field.reqd,
31
- hidden: !!field.hidden,
32
- readOnly: !!field.read_only,
33
- precision: field.precision,
34
- depends_on: field.depends_on,
35
- // Pass through additional Frappe-specific metadata
36
- fieldtype: field.fieldtype,
37
- fieldname: field.fieldname,
38
- in_list_view: field.in_list_view,
39
- in_standard_filter: field.in_standard_filter
40
- };
42
+ function sectionsToLayoutFields(sections) {
43
+ var fields = [];
44
+ sections.forEach(function (section, sectionIndex) {
45
+ fields.push({
46
+ fieldname: `__section_${sectionIndex}`,
47
+ fieldtype: section.tab ? "Tab Break" : "Section Break",
48
+ label: section.label,
49
+ collapsible: section.collapsible ? 1 : 0
50
+ });
51
+ section.columns.forEach(function (column, columnIndex) {
52
+ if (columnIndex > 0) {
53
+ fields.push({
54
+ fieldname: `__column_${sectionIndex}_${columnIndex}`,
55
+ fieldtype: "Column Break"
56
+ });
57
+ }
58
+ fields.push(...column.fields);
59
+ });
60
+ });
61
+ return fields;
41
62
  }
42
- function mapMetaToFormSchema(meta, sectionOverrides) {
43
- var sections = sectionOverrides !== null && sectionOverrides !== void 0 ? sectionOverrides : meta.sections;
44
- var genericSections = sections.map(function (section) {
63
+ var documentBookkeeping = /* @__PURE__ */new Set(["name", "owner", "creation", "modified", "modified_by", "docstatus", "idx", "doctype", "_user_tags", "_comments", "_assign", "_liked_by", "_seen"]);
64
+ function fieldsFromDocument(doc) {
65
+ return Object.entries(doc).filter(function (param) {
66
+ var [key, value] = param;
67
+ return !key.startsWith("$") && !documentBookkeeping.has(key) && (value === null || typeof value === "string" || typeof value === "number");
68
+ }).map(function (param) {
69
+ var [key, value] = param;
45
70
  return {
46
- label: section.label,
47
- collapsible: section.collapsible,
48
- columns: section.columns.map(function (col) {
49
- return {
50
- fields: col.fields.map(mapFieldToGenericSchema)
51
- };
52
- })
71
+ name: key,
72
+ label: key.replace(/_/g, " ").replace(/(^|\s)\S/g, function (c) {
73
+ return c.toUpperCase();
74
+ }),
75
+ type: typeof value === "number" ? Number.isInteger(value) ? "Int" : "Float" : "Data",
76
+ readOnly: true
53
77
  };
54
78
  });
55
- var allFields = meta.fields.map(mapFieldToGenericSchema);
56
- return {
57
- sections: genericSections,
58
- fields: allFields
59
- };
79
+ }
80
+ function hasRestrictedPermLevel(meta) {
81
+ return !!(meta === null || meta === void 0 ? void 0 : meta.fields.some(function (field) {
82
+ var _field_permlevel;
83
+ return Number((_field_permlevel = field.permlevel) !== null && _field_permlevel !== void 0 ? _field_permlevel : 0) > 0;
84
+ }));
60
85
  }
61
86
  function resolveFileUrl(value, baseURL) {
62
87
  if (!value || typeof value !== "string") return void 0;
@@ -131,7 +156,85 @@ function mapDocToSidebarMetadata(doc, t) {
131
156
  }
132
157
  return metadata;
133
158
  }
134
- function FrappeForm(param) {
159
+ function FrappeForm(props) {
160
+ var {
161
+ route,
162
+ ...formProps
163
+ } = props;
164
+ if (route === void 0) return /* @__PURE__ */_jsx(FrappeFormBody, {
165
+ ...formProps
166
+ });
167
+ return /* @__PURE__ */_jsx(FrappeFormRoute, {
168
+ ...formProps,
169
+ route
170
+ });
171
+ }
172
+ function FrappeFormRoute(param) {
173
+ var {
174
+ route,
175
+ name: nameProp,
176
+ onSave,
177
+ onCancel,
178
+ onDelete,
179
+ onEdit,
180
+ ...props
181
+ } = param;
182
+ var router = useFrappeRouter();
183
+ var fromPath = router ? frappeRouteTarget(route, router.pathname) : void 0;
184
+ var target = nameProp ? {
185
+ mode: (fromPath === null || fromPath === void 0 ? void 0 : fromPath.mode) === "view" ? "view" : "edit",
186
+ name: nameProp
187
+ } : (fromPath === null || fromPath === void 0 ? void 0 : fromPath.mode) === "view" || (fromPath === null || fromPath === void 0 ? void 0 : fromPath.mode) === "edit" ? fromPath : {
188
+ mode: "create"
189
+ };
190
+ var go = function go2(next) {
191
+ return router === null || router === void 0 ? void 0 : router.navigate(frappeRouteHref(route, next));
192
+ };
193
+ var name = target.mode === "view" || target.mode === "edit" ? target.name : void 0;
194
+ return /* @__PURE__ */_createElement(FrappeFormBody, {
195
+ ...props,
196
+ // A new target is a new page: no state carries over from the last one.
197
+ key: `${target.mode}:${name !== null && name !== void 0 ? name : ""}`,
198
+ name,
199
+ routePage: {
200
+ onBack: function onBack() {
201
+ return go({
202
+ mode: "list"
203
+ });
204
+ }
205
+ },
206
+ onEdit: target.mode === "view" ? onEdit !== null && onEdit !== void 0 ? onEdit : function () {
207
+ return go({
208
+ mode: "edit",
209
+ name: target.name
210
+ });
211
+ } : void 0,
212
+ onSave: onSave !== null && onSave !== void 0 ? onSave : function (doc) {
213
+ var _doc_name;
214
+ var saved = (_doc_name = doc.name) !== null && _doc_name !== void 0 ? _doc_name : name;
215
+ go(saved ? {
216
+ mode: "view",
217
+ name: saved
218
+ } : {
219
+ mode: "list"
220
+ });
221
+ },
222
+ onCancel: onCancel !== null && onCancel !== void 0 ? onCancel : function () {
223
+ return go(name ? {
224
+ mode: "view",
225
+ name
226
+ } : {
227
+ mode: "list"
228
+ });
229
+ },
230
+ onDelete: onDelete !== null && onDelete !== void 0 ? onDelete : function () {
231
+ return go({
232
+ mode: "list"
233
+ });
234
+ }
235
+ });
236
+ }
237
+ function FrappeFormBody(param) {
135
238
  var {
136
239
  baseURL,
137
240
  auth,
@@ -145,15 +248,26 @@ function FrappeForm(param) {
145
248
  readOnlyFields,
146
249
  sections,
147
250
  order,
251
+ roles,
148
252
  onSave,
149
253
  onCancel,
150
254
  onDelete,
255
+ onEdit,
151
256
  showToolbar = true,
152
257
  showSidebar = true,
153
258
  showTimeline = true,
154
259
  disabled = false,
155
- sectionHeadingLevel
260
+ sectionHeadingLevel,
261
+ connections,
262
+ showConnections = true,
263
+ initialDoc,
264
+ loadingFallback,
265
+ notFoundFallback,
266
+ errorFallback,
267
+ routePage
156
268
  } = param;
269
+ var _ref, _ref1;
270
+ var _tabItems_, _tabItems_1;
157
271
  var config = useFrappeConfig();
158
272
  var {
159
273
  knobProps
@@ -161,12 +275,21 @@ function FrappeForm(param) {
161
275
  var {
162
276
  t
163
277
  } = useTranslation();
164
- var [localDoc, setLocalDoc] = useState({});
165
- var [baselineDoc, setBaselineDoc] = useState(void 0);
278
+ var seedDoc = name && initialDoc && initialDoc.name === name ? initialDoc : void 0;
279
+ var seedRef = useRef(seedDoc);
280
+ seedRef.current = seedDoc;
281
+ var [localDoc, setLocalDoc] = useState(function () {
282
+ return seedDoc !== null && seedDoc !== void 0 ? seedDoc : {};
283
+ });
284
+ var [baselineDoc, setBaselineDoc] = useState(function () {
285
+ return seedDoc;
286
+ });
287
+ var [docError, setDocError] = useState(null);
166
288
  var [conflictFields, setConflictFields] = useState([]);
167
289
  var [wasDeleted, setWasDeleted] = useState(false);
168
290
  var [isSubmitting, setIsSubmitting] = useState(false);
169
291
  var [errors, setErrors] = useState({});
292
+ var [activeTab, setActiveTab] = useState(void 0);
170
293
  var everLoadedRef = useRef(false);
171
294
  var localDocRef = useRef(localDoc);
172
295
  localDocRef.current = localDoc;
@@ -195,18 +318,63 @@ function FrappeForm(param) {
195
318
  isLoading: isMetaLoading,
196
319
  error: metaError
197
320
  } = useDocTypeMeta(frappeConfig, doctype);
198
- var formSchema = useMemo(function () {
321
+ var sessionRoles = useSessionRoles(!roles && hasRestrictedPermLevel(meta) ? frappeConfig : void 0);
322
+ var effectiveRoles = roles !== null && roles !== void 0 ? roles : sessionRoles;
323
+ var permLevels = useMemo(function () {
324
+ return buildPermLevelMatrix(meta === null || meta === void 0 ? void 0 : meta.permissions, effectiveRoles);
325
+ }, [meta === null || meta === void 0 ? void 0 : meta.permissions, effectiveRoles]);
326
+ var isCreate = !name;
327
+ var docstatus = Number((_ref = baselineDoc === null || baselineDoc === void 0 ? void 0 : baselineDoc.docstatus) !== null && _ref !== void 0 ? _ref : 0);
328
+ var layoutFields = useMemo(function () {
199
329
  if (!meta) return void 0;
200
- return mapMetaToFormSchema(meta, sections);
330
+ return sections ? sectionsToLayoutFields(sections) : meta.fields;
201
331
  }, [meta, sections]);
202
- var hideFieldSet = useMemo(function () {
203
- return new Set(hideFields !== null && hideFields !== void 0 ? hideFields : []);
204
- }, [hideFields]);
332
+ var formTabs = useMemo(function () {
333
+ if (!layoutFields) return void 0;
334
+ return buildFormTabs({
335
+ fields: layoutFields,
336
+ doc: {
337
+ ...localDoc,
338
+ __islocal: isCreate ? 1 : 0
339
+ },
340
+ docstatus,
341
+ formReadOnly: !!(meta === null || meta === void 0 ? void 0 : meta.read_only),
342
+ isCreate,
343
+ detailsLabel: t("Details"),
344
+ permLevels,
345
+ hiddenFields: hideFields
346
+ });
347
+ }, [layoutFields, localDoc, docstatus, meta === null || meta === void 0 ? void 0 : meta.read_only, isCreate, permLevels, hideFields, t]);
348
+ var readsWithoutMeta = !children && !meta && Boolean(metaError) && Boolean(name);
349
+ var recordTabs = useMemo(function () {
350
+ if (!readsWithoutMeta || !baselineDoc) return void 0;
351
+ var recordFields = fieldsFromDocument(baselineDoc);
352
+ return [{
353
+ key: "__details",
354
+ label: t("Details"),
355
+ schema: {
356
+ sections: [{
357
+ columns: [{
358
+ fields: recordFields
359
+ }]
360
+ }],
361
+ fields: recordFields
362
+ }
363
+ }];
364
+ }, [readsWithoutMeta, baselineDoc, t]);
365
+ var promptNamed = isCreate && !!meta && isPromptNamed(meta.autoname, meta.naming_rule);
366
+ var fetchMap = useMemo(function () {
367
+ return meta ? buildFetchMap(meta.fields) : void 0;
368
+ }, [meta]);
369
+ var handleDocSyncError = useCallback(function (err) {
370
+ setDocError(_instanceof(err, Error) ? err : new Error(String(err)));
371
+ }, []);
205
372
  var docCollection = useFrappeCollection(name ? frappeConfig : void 0, doctype, {
206
373
  fields,
207
374
  filters: name ? {
208
375
  name
209
- } : void 0
376
+ } : void 0,
377
+ onSyncError: handleDocSyncError
210
378
  });
211
379
  var {
212
380
  data: rawDocData,
@@ -277,8 +445,78 @@ function FrappeForm(param) {
277
445
  everLoadedRef.current = false;
278
446
  setWasDeleted(false);
279
447
  setConflictFields([]);
280
- setBaselineDoc(void 0);
448
+ setDocError(null);
449
+ var seed = seedRef.current;
450
+ setBaselineDoc(seed);
451
+ if (seed) setLocalDoc(seed);
281
452
  }, [doctype, name]);
453
+ var effectiveConnections = useMemo(function () {
454
+ return connections !== null && connections !== void 0 ? connections : connectionsFromMeta(meta);
455
+ }, [connections, meta]);
456
+ var readsConnections = Boolean(children) && Boolean(name) && effectiveConnections.length > 0;
457
+ var [connectionSnapshots, setConnectionSnapshots] = useState({});
458
+ useEffect(function () {
459
+ setConnectionSnapshots({});
460
+ }, [doctype, name]);
461
+ var connectionReads = useMemo(function () {
462
+ return readsConnections && name ? effectiveConnections.map(function (link) {
463
+ var _link_limit;
464
+ return {
465
+ link,
466
+ options: {
467
+ fields: connectionFields(link),
468
+ filters: [[link.fieldname, "=", name]],
469
+ limit: (_link_limit = link.limit) !== null && _link_limit !== void 0 ? _link_limit : 0
470
+ },
471
+ onChange: function onChange(snapshot) {
472
+ return setConnectionSnapshots(function (prev) {
473
+ return {
474
+ ...prev,
475
+ [link.doctype]: snapshot
476
+ };
477
+ });
478
+ }
479
+ };
480
+ }) : [];
481
+ }, [readsConnections, effectiveConnections, name]);
482
+ var connectionRows = useMemo(function () {
483
+ var rows = {};
484
+ var _iteratorNormalCompletion = true,
485
+ _didIteratorError = false,
486
+ _iteratorError = void 0;
487
+ try {
488
+ for (var _iterator = connectionReads[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
489
+ var {
490
+ link
491
+ } = _step.value;
492
+ var _ref2;
493
+ var _connectionSnapshots_link_doctype;
494
+ rows[link.doctype] = (_ref2 = (_connectionSnapshots_link_doctype = connectionSnapshots[link.doctype]) === null || _connectionSnapshots_link_doctype === void 0 ? void 0 : _connectionSnapshots_link_doctype.rows) !== null && _ref2 !== void 0 ? _ref2 : [];
495
+ }
496
+ } catch (err) {
497
+ _didIteratorError = true;
498
+ _iteratorError = err;
499
+ } finally {
500
+ try {
501
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
502
+ _iterator.return();
503
+ }
504
+ } finally {
505
+ if (_didIteratorError) {
506
+ throw _iteratorError;
507
+ }
508
+ }
509
+ }
510
+ return rows;
511
+ }, [connectionReads, connectionSnapshots]);
512
+ var connectionsLoading = connectionReads.some(function (param2) {
513
+ var {
514
+ link
515
+ } = param2;
516
+ var _ref2;
517
+ var _connectionSnapshots_link_doctype;
518
+ return (_ref2 = (_connectionSnapshots_link_doctype = connectionSnapshots[link.doctype]) === null || _connectionSnapshots_link_doctype === void 0 ? void 0 : _connectionSnapshots_link_doctype.isLoading) !== null && _ref2 !== void 0 ? _ref2 : true;
519
+ });
282
520
  useFrappeDoctypeEvents(name ? frappeConfig : void 0, doctype, function (event) {
283
521
  if (event.type !== "doc_deleted") return;
284
522
  var payload = event.payload;
@@ -371,6 +609,40 @@ function FrappeForm(param) {
371
609
  return dirty;
372
610
  }, [localDoc, baselineDoc]);
373
611
  var hasUnsavedChanges = dirtyFieldNames.length > 0;
612
+ var runFetchFrom = function runFetchFrom2(field, value) {
613
+ var rules = fetchMap === null || fetchMap === void 0 ? void 0 : fetchMap.get(field);
614
+ if (!rules || rules.length === 0) return;
615
+ var applyPatch = function applyPatch2(fetched2) {
616
+ setLocalDoc(function (prev) {
617
+ var current = prev;
618
+ if (current[field] !== value) return prev;
619
+ var patch = applyFetchedValues(rules, fetched2, current);
620
+ return Object.keys(patch).length > 0 ? {
621
+ ...current,
622
+ ...patch
623
+ } : prev;
624
+ });
625
+ };
626
+ if (isEmptyFieldValue(value)) {
627
+ applyPatch({});
628
+ return;
629
+ }
630
+ var linkField = meta === null || meta === void 0 ? void 0 : meta.fields.find(function (metaField) {
631
+ return metaField.fieldname === field;
632
+ });
633
+ var targetDoctype = typeof (linkField === null || linkField === void 0 ? void 0 : linkField.options) === "string" ? linkField.options : "";
634
+ if (!targetDoctype) return;
635
+ var sources = Array.from(new Set(rules.map(function (rule) {
636
+ return rule.source;
637
+ })));
638
+ var fixtures = frappeConfig.fixtures;
639
+ var fetched = fixtures ? fixtures.getDoc(targetDoctype, String(value), sources).then(function (doc) {
640
+ return doc !== null && doc !== void 0 ? doc : {};
641
+ }) : validateLink(createHttpClient(frappeConfig), targetDoctype, String(value), sources);
642
+ fetched.then(applyPatch).catch(function () {
643
+ return void 0;
644
+ });
645
+ };
374
646
  var setValue = function setValue2(field, value) {
375
647
  setLocalDoc(function (prev) {
376
648
  return {
@@ -385,24 +657,47 @@ function FrappeForm(param) {
385
657
  delete newErrors[String(field)];
386
658
  return newErrors;
387
659
  });
660
+ runFetchFrom(String(field), value);
388
661
  };
389
662
  var validateRequiredFields = function validateRequiredFields2() {
390
- if (!meta) return {};
663
+ if (!formTabs) return {};
391
664
  var validationErrors = {};
392
665
  var doc = localDoc;
666
+ if (promptNamed && isEmptyFieldValue(doc.name)) {
667
+ validationErrors.name = t("Name is required");
668
+ }
393
669
  var _iteratorNormalCompletion = true,
394
670
  _didIteratorError = false,
395
671
  _iteratorError = void 0;
396
672
  try {
397
- for (var _iterator = meta.fields[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
398
- var field = _step.value;
399
- if (!field.reqd) continue;
400
- if (field.hidden || LAYOUT_FIELDTYPES.has(field.fieldtype)) continue;
401
- if (hideFieldSet.has(field.fieldname)) continue;
402
- if (isEmptyFieldValue(doc[field.fieldname])) {
403
- validationErrors[field.fieldname] = t("{{label}} is required", {
404
- label: field.label || field.fieldname
405
- });
673
+ for (var _iterator = formTabs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
674
+ var tab = _step.value;
675
+ var _iteratorNormalCompletion1 = true,
676
+ _didIteratorError1 = false,
677
+ _iteratorError1 = void 0;
678
+ try {
679
+ for (var _iterator1 = tab.schema.fields[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true) {
680
+ var field = _step1.value;
681
+ if (!field.required) continue;
682
+ if (isEmptyFieldValue(doc[field.name])) {
683
+ validationErrors[field.name] = t("{{label}} is required", {
684
+ label: field.label || field.name
685
+ });
686
+ }
687
+ }
688
+ } catch (err) {
689
+ _didIteratorError1 = true;
690
+ _iteratorError1 = err;
691
+ } finally {
692
+ try {
693
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
694
+ _iterator1.return();
695
+ }
696
+ } finally {
697
+ if (_didIteratorError1) {
698
+ throw _iteratorError1;
699
+ }
700
+ }
406
701
  }
407
702
  }
408
703
  } catch (err) {
@@ -464,15 +759,23 @@ function FrappeForm(param) {
464
759
  }
465
760
  setConflictFields([]);
466
761
  } else {
467
- var _localDoc_name;
762
+ var _localDoc_name, _ref2;
763
+ var _getFrappeSyncModule;
468
764
  if (!collection) return;
765
+ var temporaryName = (_localDoc_name = localDoc.name) !== null && _localDoc_name !== void 0 ? _localDoc_name : `new-${Date.now()}`;
469
766
  var docToInsert = {
470
767
  ...localDoc,
471
768
  doctype,
472
- name: (_localDoc_name = localDoc.name) !== null && _localDoc_name !== void 0 ? _localDoc_name : `new-${Date.now()}`
769
+ name: temporaryName
473
770
  };
474
771
  var tx1 = collection.insert(docToInsert);
475
772
  await tx1.isPersisted.promise;
773
+ var createdName = (_ref2 = (_getFrappeSyncModule = getFrappeSyncModule(frappeConfig)) === null || _getFrappeSyncModule === void 0 ? void 0 : _getFrappeSyncModule.createdName(temporaryName)) !== null && _ref2 !== void 0 ? _ref2 : temporaryName;
774
+ onSave === null || onSave === void 0 ? void 0 : onSave({
775
+ ...localDoc,
776
+ name: createdName
777
+ });
778
+ return;
476
779
  }
477
780
  onSave === null || onSave === void 0 ? void 0 : onSave(localDoc);
478
781
  } catch (err1) {
@@ -554,17 +857,47 @@ function FrappeForm(param) {
554
857
  setIsSubmitting(false);
555
858
  }
556
859
  };
860
+ var titleField = meta === null || meta === void 0 ? void 0 : meta.title_field;
861
+ var titleValue = titleField ? localDoc[titleField] : void 0;
862
+ var pageTitle = isCreate ? t("New {{doctype}}", {
863
+ doctype
864
+ }) : String(titleValue || name);
865
+ var frame = function frame2(content, aside) {
866
+ return routePage ?
867
+ // flexBasis auto: see DeskFormPage (react-native-web's min-height:0
868
+ // reset would cap the scroll page at viewport height).
869
+ /* @__PURE__ */
870
+ _jsx(DetailPageLayout, {
871
+ flexBasis: "auto",
872
+ toolbarLeading: /* @__PURE__ */_jsx(Button, {
873
+ size: "$3",
874
+ chromeless: true,
875
+ icon: ArrowLeftIcon,
876
+ onPress: routePage.onBack,
877
+ "aria-label": t("Back to {{doctype}} list", {
878
+ doctype
879
+ }),
880
+ children: doctype
881
+ }),
882
+ header: /* @__PURE__ */_jsx(PageHeader, {
883
+ title: pageTitle,
884
+ divider: false
885
+ }),
886
+ aside,
887
+ children: content
888
+ }) : content;
889
+ };
557
890
  if (!children && isMetaLoading && !meta) {
558
- return /* @__PURE__ */_jsx(YStack, {
891
+ return frame(/* @__PURE__ */_jsx(YStack, {
559
892
  ...knobProps.panelPadding,
560
893
  testID: "frappe-form-skeleton",
561
894
  children: /* @__PURE__ */_jsx(AsyncSkeleton, {
562
895
  layout: "generic"
563
896
  })
564
- });
897
+ }));
565
898
  }
566
- if (!children && metaError && !meta) {
567
- return /* @__PURE__ */_jsxs(YStack, {
899
+ if (!children && metaError && !meta && !name) {
900
+ return frame(/* @__PURE__ */_jsxs(YStack, {
568
901
  ...knobProps.panelPadding,
569
902
  alignItems: "center",
570
903
  ...knobProps.gap,
@@ -579,19 +912,33 @@ function FrappeForm(param) {
579
912
  ...knobProps.body,
580
913
  children: metaError.message
581
914
  })]
582
- });
915
+ }));
583
916
  }
584
- if (name && (liveDoc === null || liveDoc === void 0 ? void 0 : liveDoc.isLoading) && !wasDeleted) {
585
- return /* @__PURE__ */_jsx(YStack, {
917
+ var isDocReading = Boolean(name) && (!docCollection || Boolean(liveDoc === null || liveDoc === void 0 ? void 0 : liveDoc.isLoading));
918
+ var showsSeed = Boolean(seedDoc) && isDocReading;
919
+ if (name && docError && !(liveDoc === null || liveDoc === void 0 ? void 0 : liveDoc.data) && !wasDeleted) {
920
+ if (errorFallback !== void 0) return frame(errorFallback);
921
+ return frame(/* @__PURE__ */_jsx(AsyncBoundary, {
922
+ ...knobProps.panelPadding,
923
+ error: docError,
924
+ errorTitle: t("Failed to load {{doctype}}", {
925
+ doctype
926
+ })
927
+ }));
928
+ }
929
+ if (name && isDocReading && !showsSeed && !wasDeleted) {
930
+ if (loadingFallback !== void 0) return frame(loadingFallback);
931
+ return frame(/* @__PURE__ */_jsx(YStack, {
586
932
  ...knobProps.panelPadding,
587
933
  testID: "frappe-form-skeleton",
588
934
  children: /* @__PURE__ */_jsx(AsyncSkeleton, {
589
935
  layout: "generic"
590
936
  })
591
- });
937
+ }));
592
938
  }
593
- if (name && !(liveDoc === null || liveDoc === void 0 ? void 0 : liveDoc.isLoading) && !(liveDoc === null || liveDoc === void 0 ? void 0 : liveDoc.data) && !wasDeleted) {
594
- return /* @__PURE__ */_jsxs(YStack, {
939
+ if (name && !isDocReading && !(liveDoc === null || liveDoc === void 0 ? void 0 : liveDoc.data) && !wasDeleted) {
940
+ if (notFoundFallback !== void 0) return frame(notFoundFallback);
941
+ return frame(/* @__PURE__ */_jsxs(YStack, {
595
942
  ...knobProps.panelPadding,
596
943
  alignItems: "center",
597
944
  ...knobProps.gap,
@@ -608,9 +955,12 @@ function FrappeForm(param) {
608
955
  name
609
956
  })
610
957
  })]
611
- });
958
+ }));
612
959
  }
613
960
  var effectiveDisabled = disabled || wasDeleted;
961
+ var readOnlyView = Boolean(onEdit) || readsWithoutMeta;
962
+ var fieldsDisabled = effectiveDisabled || readOnlyView;
963
+ var shownTabs = formTabs !== null && formTabs !== void 0 ? formTabs : recordTabs;
614
964
  var imageFieldName = meta === null || meta === void 0 ? void 0 : meta.image_field;
615
965
  var sidebarImageUrl = imageFieldName ? resolveFileUrl(localDoc[imageFieldName], finalBaseURL) : void 0;
616
966
  var conflictLabels = conflictFields.map(function (fieldname) {
@@ -619,131 +969,185 @@ function FrappeForm(param) {
619
969
  });
620
970
  return (field === null || field === void 0 ? void 0 : field.label) || fieldname;
621
971
  }).join(", ");
622
- return (
623
- // flexBasis auto (not the flex:1 shorthand's 0%): inside scroll-flow page
624
- // scaffolds (LC-29 templates) the parent is auto-height, and a 0% basis
625
- // collapses this stack to zero height on web — content then paints over
626
- // whatever follows. Bounded parents still fill (grow 1) exactly as before.
972
+ var formTabItems = (shownTabs !== null && shownTabs !== void 0 ? shownTabs : []).map(function (tab) {
973
+ return {
974
+ value: tab.key,
975
+ label: tab.label,
976
+ content: /* @__PURE__ */_jsx(SchemaForm, {
977
+ schema: tab.schema,
978
+ doc: localDoc,
979
+ setValue: function setValue1(field, value) {
980
+ return setValue(field, value);
981
+ },
982
+ errors,
983
+ disabled: fieldsDisabled,
984
+ overrides,
985
+ readOnlyFields,
986
+ sectionHeadingLevel,
987
+ order
988
+ })
989
+ };
990
+ });
991
+ var tabItems = showConnections && name && effectiveConnections.length > 0 ? [...formTabItems, {
992
+ value: "__connections",
993
+ label: t("Connections"),
994
+ content: /* @__PURE__ */_jsx(FrappeFormConnections, {
995
+ connection: frappeConfig,
996
+ connections: effectiveConnections,
997
+ name
998
+ })
999
+ }] : formTabItems;
1000
+ var effectiveTab = activeTab && tabItems.some(function (tab) {
1001
+ return tab.value === activeTab;
1002
+ }) ? activeTab : (_tabItems_ = tabItems[0]) === null || _tabItems_ === void 0 ? void 0 : _tabItems_.value;
1003
+ var localName = localDoc.name;
1004
+ var sidebar = showSidebar && name && meta ? /* @__PURE__ */_jsx(FormSidebar, {
1005
+ imageUrl: sidebarImageUrl,
1006
+ sections: buildSidebarSections(localDoc, shareRows, t, assignmentRows),
1007
+ metadata: mapDocToSidebarMetadata(localDoc, t)
1008
+ }) : void 0;
1009
+ return frame(
1010
+ // flexBasis auto (not the flex:1 shorthand's 0%): inside scroll-flow page
1011
+ // scaffolds (LC-29 templates) the parent is auto-height, and a 0% basis
1012
+ // collapses this stack to zero height on web — content then paints over
1013
+ // whatever follows. Bounded parents still fill (grow 1) exactly as before.
1014
+ /* @__PURE__ */
1015
+ _jsxs(YStack, {
1016
+ ...knobProps.gapLg,
1017
+ flexGrow: 1,
1018
+ flexShrink: 1,
1019
+ flexBasis: "auto",
1020
+ children: [/* @__PURE__ */_jsx(FrappeReconnectIndicator, {
1021
+ config: frappeConfig
1022
+ }), connectionReads.map(function (read) {
1023
+ return /* @__PURE__ */_jsx(FrappeRowsReader, {
1024
+ connection: frappeConfig,
1025
+ doctype: read.link.doctype,
1026
+ options: read.options,
1027
+ onChange: read.onChange
1028
+ }, read.link.doctype);
1029
+ }), wasDeleted && /* @__PURE__ */_jsx(XStack, {
1030
+ role: "alert",
1031
+ alignItems: "center",
1032
+ ...knobProps.containerRadius,
1033
+ ...knobProps.panelPadding,
1034
+ backgroundColor: "$red3",
1035
+ testID: "frappe-form-deleted-banner",
1036
+ children: /* @__PURE__ */_jsx(Text, {
1037
+ color: formCommonColors.error,
1038
+ ...knobProps.body,
1039
+ children: hasUnsavedChanges ? t("This {{doctype}} was deleted on the server. Fields are read-only and your unsaved edits can no longer be saved.", {
1040
+ doctype
1041
+ }) : t("This {{doctype}} was deleted on the server. Fields are read-only.", {
1042
+ doctype
1043
+ })
1044
+ })
1045
+ }), !wasDeleted && conflictFields.length > 0 && /* @__PURE__ */_jsx(XStack, {
1046
+ role: "status",
1047
+ alignItems: "center",
1048
+ ...knobProps.containerRadius,
1049
+ ...knobProps.panelPadding,
1050
+ backgroundColor: "$orange3",
1051
+ testID: "frappe-form-conflict-banner",
1052
+ children: /* @__PURE__ */_jsx(Text, {
1053
+ color: "$orange11",
1054
+ ...knobProps.body,
1055
+ children: t("Changed elsewhere while you were editing: {{fields}}. Your edits are kept \u2014 saving will overwrite the newer server values.", {
1056
+ fields: conflictLabels
1057
+ })
1058
+ })
1059
+ }),
1060
+ /* flexBasis auto — see the root stack note (zero-height collapse in
1061
+ auto-height scroll flows would paint the Timeline over the form). */
627
1062
  /* @__PURE__ */
628
- _jsxs(YStack, {
629
- ...knobProps.gapLg,
1063
+ _jsxs(XStack, {
630
1064
  flexGrow: 1,
631
1065
  flexShrink: 1,
632
1066
  flexBasis: "auto",
633
- children: [/* @__PURE__ */_jsx(FrappeReconnectIndicator, {
634
- config: frappeConfig
635
- }), wasDeleted && /* @__PURE__ */_jsx(XStack, {
636
- role: "alert",
637
- alignItems: "center",
638
- ...knobProps.containerRadius,
639
- ...knobProps.panelPadding,
640
- backgroundColor: "$red3",
641
- testID: "frappe-form-deleted-banner",
642
- children: /* @__PURE__ */_jsx(Text, {
643
- color: formCommonColors.error,
644
- ...knobProps.body,
645
- children: hasUnsavedChanges ? t("This {{doctype}} was deleted on the server. Fields are read-only and your unsaved edits can no longer be saved.", {
646
- doctype
647
- }) : t("This {{doctype}} was deleted on the server. Fields are read-only.", {
648
- doctype
649
- })
650
- })
651
- }), !wasDeleted && conflictFields.length > 0 && /* @__PURE__ */_jsx(XStack, {
652
- role: "status",
653
- alignItems: "center",
654
- ...knobProps.containerRadius,
655
- ...knobProps.panelPadding,
656
- backgroundColor: "$orange3",
657
- testID: "frappe-form-conflict-banner",
658
- children: /* @__PURE__ */_jsx(Text, {
659
- color: "$orange11",
660
- ...knobProps.body,
661
- children: t("Changed elsewhere while you were editing: {{fields}}. Your edits are kept \u2014 saving will overwrite the newer server values.", {
662
- fields: conflictLabels
663
- })
664
- })
665
- }),
666
- /* flexBasis auto — see the root stack note (zero-height collapse in
667
- auto-height scroll flows would paint the Timeline over the form). */
668
- /* @__PURE__ */
669
- _jsxs(XStack, {
670
- flexGrow: 1,
671
- flexShrink: 1,
672
- flexBasis: "auto",
1067
+ ...knobProps.gapLg,
1068
+ children: [
1069
+ /* Sidebar (edit mode only) — assignments/shares/image are live.
1070
+ A routed page carries it in the template's aside instead. */
1071
+ routePage ? null : sidebar, /* Form body */
1072
+ /* @__PURE__ */_jsxs(YStack, {
1073
+ flex: 1,
673
1074
  ...knobProps.gapLg,
674
- children: [/* Sidebar (edit mode only) — assignments/shares/image are live */
675
- showSidebar && name && meta && /* @__PURE__ */_jsx(FormSidebar, {
676
- imageUrl: sidebarImageUrl,
677
- sections: buildSidebarSections(localDoc, shareRows, t, assignmentRows),
678
- metadata: mapDocToSidebarMetadata(localDoc, t)
679
- }), /* Form body */
680
- /* @__PURE__ */_jsxs(YStack, {
681
- flex: 1,
1075
+ children: [children ?
1076
+ // Render-prop mode
1077
+ children({
1078
+ doc: localDoc,
1079
+ setValue,
1080
+ isSubmitting,
1081
+ errors,
1082
+ meta,
1083
+ disabled: fieldsDisabled,
1084
+ connections: connectionRows,
1085
+ connectionsLoading
1086
+ }) : shownTabs ? /* @__PURE__ */_jsxs(YStack, {
682
1087
  ...knobProps.gapLg,
683
- children: [children ?
684
- // Render-prop mode
685
- children({
686
- doc: localDoc,
687
- setValue,
688
- isSubmitting,
689
- errors,
690
- meta,
691
- disabled: effectiveDisabled
692
- }) : formSchema ?
693
- // Schema-driven mode using generic SchemaForm from @multiplatform.one/forms
694
- /* @__PURE__ */
695
- _jsx(SchemaForm, {
696
- schema: formSchema,
697
- doc: localDoc,
698
- setValue: function setValue1(field, value) {
699
- return setValue(field, value);
1088
+ children: [promptNamed && /* @__PURE__ */_jsx(Input, {
1089
+ label: t("Name"),
1090
+ value: typeof localName === "string" ? localName : "",
1091
+ onChangeText: function onChangeText(value) {
1092
+ return setValue("name", value);
700
1093
  },
701
- errors,
702
- disabled: effectiveDisabled,
703
- overrides,
704
- hideFields,
705
- readOnlyFields,
706
- sectionHeadingLevel,
707
- order
708
- }) :
709
- // Metadata unavailable (should be covered by metaError branch above)
710
- /* @__PURE__ */
711
- _jsx(YStack, {
712
- ...knobProps.panelPadding,
713
- alignItems: "center",
714
- children: /* @__PURE__ */_jsx(Text, {
715
- color: formCommonColors.muted,
716
- ...knobProps.body,
717
- children: t("Form schema unavailable")
718
- })
719
- }), errors.general && /* @__PURE__ */_jsx(Text, {
720
- color: formCommonColors.error,
1094
+ placeholder: t("New document name"),
1095
+ error: errors.name,
1096
+ disabled: effectiveDisabled
1097
+ }), tabItems.length > 1 ? /* @__PURE__ */_jsx(Tabs, {
1098
+ items: tabItems,
1099
+ value: effectiveTab,
1100
+ onChange: setActiveTab,
1101
+ lazyMount: true
1102
+ }) : (_ref1 = (_tabItems_1 = tabItems[0]) === null || _tabItems_1 === void 0 ? void 0 : _tabItems_1.content) !== null && _ref1 !== void 0 ? _ref1 : null]
1103
+ }) :
1104
+ // Metadata unavailable (should be covered by metaError branch above)
1105
+ /* @__PURE__ */
1106
+ _jsx(YStack, {
1107
+ ...knobProps.panelPadding,
1108
+ alignItems: "center",
1109
+ children: /* @__PURE__ */_jsx(Text, {
1110
+ color: formCommonColors.muted,
721
1111
  ...knobProps.body,
722
- children: errors.general
723
- }), showToolbar && /* @__PURE__ */_jsxs(XStack, {
724
- ...knobProps.gap,
725
- justifyContent: "flex-end",
726
- alignItems: "center",
727
- paddingTop: "$3",
728
- children: [hasUnsavedChanges && /* @__PURE__ */_jsx(Text, {
729
- color: "$orange11",
730
- marginInlineEnd: "auto",
731
- ...knobProps.body,
732
- children: t("Not Saved")
733
- }), name && onDelete && !wasDeleted && /* @__PURE__ */_jsx(Button, {
734
- outlined: true,
735
- error: true,
736
- icon: TrashIcon,
737
- loading: isSubmitting,
738
- disabled: effectiveDisabled,
739
- disabledReason: t("Form is read-only"),
740
- disabledReasonPlacement: "inline",
741
- onPress: handleDelete,
742
- children: t("Delete")
743
- }), onCancel && /* @__PURE__ */_jsx(Button, {
1112
+ children: t("Form schema unavailable")
1113
+ })
1114
+ }), errors.general && /* @__PURE__ */_jsx(Text, {
1115
+ color: formCommonColors.error,
1116
+ ...knobProps.body,
1117
+ children: errors.general
1118
+ }), showToolbar && !readsWithoutMeta && /* @__PURE__ */_jsxs(XStack, {
1119
+ ...knobProps.gap,
1120
+ justifyContent: "flex-end",
1121
+ alignItems: "center",
1122
+ paddingTop: "$3",
1123
+ children: [hasUnsavedChanges && !onEdit && /* @__PURE__ */_jsx(Text, {
1124
+ color: "$orange11",
1125
+ marginInlineEnd: "auto",
1126
+ ...knobProps.body,
1127
+ children: t("Not Saved")
1128
+ }), name && onDelete && !wasDeleted && /* @__PURE__ */_jsx(Button, {
1129
+ outlined: true,
1130
+ error: true,
1131
+ icon: TrashIcon,
1132
+ loading: isSubmitting,
1133
+ disabled: effectiveDisabled,
1134
+ disabledReason: t("Form is read-only"),
1135
+ disabledReasonPlacement: "inline",
1136
+ onPress: handleDelete,
1137
+ children: t("Delete")
1138
+ }), onEdit ? /* @__PURE__ */_jsx(Button, {
1139
+ accent: true,
1140
+ icon: PencilSimpleIcon,
1141
+ disabled: effectiveDisabled,
1142
+ disabledReason: t("Form is read-only"),
1143
+ disabledReasonPlacement: "inline",
1144
+ onPress: onEdit,
1145
+ children: t("Edit")
1146
+ }) : /* @__PURE__ */_jsxs(_Fragment, {
1147
+ children: [onCancel && /* @__PURE__ */_jsx(Button, {
744
1148
  outlined: true,
745
1149
  icon: XIcon,
746
- disabled: isSubmitting || disabled,
1150
+ disabled,
747
1151
  disabledReason: t("Form is read-only"),
748
1152
  disabledReasonPlacement: "inline",
749
1153
  onPress: handleCancel,
@@ -760,14 +1164,14 @@ function FrappeForm(param) {
760
1164
  })]
761
1165
  })]
762
1166
  })]
763
- }), /* Timeline (edit mode only) — live Comment/Version via useFrappeCollection */
764
- showTimeline && name && /* @__PURE__ */_jsx(Timeline, {
765
- doctype,
766
- docname: name,
767
- label: t("Activity")
768
1167
  })]
769
- })
770
- );
1168
+ }), /* Timeline (edit mode only) — live Comment/Version via useFrappeCollection */
1169
+ showTimeline && name && !readsWithoutMeta && /* @__PURE__ */_jsx(Timeline, {
1170
+ doctype,
1171
+ docname: name,
1172
+ label: t("Activity")
1173
+ })]
1174
+ }), routePage ? sidebar : void 0);
771
1175
  }
772
1176
  export { FrappeForm, buildSidebarSections, mapDocToSidebarMetadata, resolveFileUrl };
773
1177
  //# sourceMappingURL=FrappeForm.native.js.map