@multiplatform.one/backoffice 7.6.3 → 7.7.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 (485) hide show
  1. package/dist/cjs/chrome/BackofficeAwesomebar.native.js +1 -1
  2. package/dist/cjs/chrome/BackofficeAwesomebar.native.js.map +1 -1
  3. package/dist/cjs/chrome/CommandPalette.native.js +1 -1
  4. package/dist/cjs/chrome/CommandPalette.native.js.map +1 -1
  5. package/dist/cjs/chrome/HelpMenu.native.js +1 -1
  6. package/dist/cjs/chrome/HelpMenu.native.js.map +1 -1
  7. package/dist/cjs/chrome/NotificationsButton.native.js +1 -1
  8. package/dist/cjs/chrome/NotificationsButton.native.js.map +1 -1
  9. package/dist/cjs/chrome/UserMenu.native.js +1 -1
  10. package/dist/cjs/chrome/UserMenu.native.js.map +1 -1
  11. package/dist/cjs/chrome/awesomebar-data.native.js.map +1 -1
  12. package/dist/cjs/chrome/command-palette-model.native.js +1 -1
  13. package/dist/cjs/chrome/command-palette-model.native.js.map +1 -1
  14. package/dist/cjs/chrome/help-about-dialog.native.js +1 -1
  15. package/dist/cjs/chrome/help-about-dialog.native.js.map +1 -1
  16. package/dist/cjs/chrome/help-shortcuts-dialog.native.js +1 -1
  17. package/dist/cjs/chrome/help-shortcuts-dialog.native.js.map +1 -1
  18. package/dist/cjs/chrome/notifications-data.native.js.map +1 -1
  19. package/dist/cjs/chrome/notifications-panel.native.js +1 -1
  20. package/dist/cjs/chrome/notifications-panel.native.js.map +1 -1
  21. package/dist/cjs/chrome/notifications-utils.native.js.map +1 -1
  22. package/dist/cjs/chrome/shortcuts.native.js.map +1 -1
  23. package/dist/cjs/chrome/user-session.native.js.map +1 -1
  24. package/dist/cjs/config/BackofficeProvider.native.js +1 -1
  25. package/dist/cjs/config/BackofficeProvider.native.js.map +1 -1
  26. package/dist/cjs/config/capabilities.native.js.map +1 -1
  27. package/dist/cjs/config/events.native.js.map +1 -1
  28. package/dist/cjs/config/slots.native.js.map +1 -1
  29. package/dist/cjs/desk/Desk.native.js.map +1 -1
  30. package/dist/cjs/desk/DeskSurface.native.js.map +1 -1
  31. package/dist/cjs/desk/resolveDeskPath.native.js.map +1 -1
  32. package/dist/cjs/desk/scope.native.js.map +1 -1
  33. package/dist/cjs/desk/target.native.js.map +1 -1
  34. package/dist/cjs/form/DocFormScreen.native.js +1 -1
  35. package/dist/cjs/form/DocFormScreen.native.js.map +1 -1
  36. package/dist/cjs/form/FormConnections.native.js +1 -1
  37. package/dist/cjs/form/FormConnections.native.js.map +1 -1
  38. package/dist/cjs/form/FormDialogs.native.js +1 -1
  39. package/dist/cjs/form/FormDialogs.native.js.map +1 -1
  40. package/dist/cjs/form/FormErrorBoundary.native.js +1 -1
  41. package/dist/cjs/form/FormErrorBoundary.native.js.map +1 -1
  42. package/dist/cjs/form/FormHeaderCluster.native.js +1 -1
  43. package/dist/cjs/form/FormHeaderCluster.native.js.map +1 -1
  44. package/dist/cjs/form/FormSidebarPanel.native.js +1 -1
  45. package/dist/cjs/form/FormSidebarPanel.native.js.map +1 -1
  46. package/dist/cjs/form/FormTimeline.native.js +1 -1
  47. package/dist/cjs/form/FormTimeline.native.js.map +1 -1
  48. package/dist/cjs/form/FormToolbar.native.js +1 -1
  49. package/dist/cjs/form/FormToolbar.native.js.map +1 -1
  50. package/dist/cjs/form/connections-data.native.js.map +1 -1
  51. package/dist/cjs/form/createPrefill.cjs +3 -11
  52. package/dist/cjs/form/createPrefill.native.js +3 -11
  53. package/dist/cjs/form/createPrefill.native.js.map +1 -1
  54. package/dist/cjs/form/dependsOn.native.js.map +1 -1
  55. package/dist/cjs/form/dirtyTracking.cjs +4 -29
  56. package/dist/cjs/form/dirtyTracking.native.js +4 -48
  57. package/dist/cjs/form/dirtyTracking.native.js.map +1 -1
  58. package/dist/cjs/form/docinfo.native.js.map +1 -1
  59. package/dist/cjs/form/fetchFrom.cjs +4 -41
  60. package/dist/cjs/form/fetchFrom.native.js +4 -81
  61. package/dist/cjs/form/fetchFrom.native.js.map +1 -1
  62. package/dist/cjs/form/fieldPermissions.cjs +4 -29
  63. package/dist/cjs/form/fieldPermissions.native.js +4 -51
  64. package/dist/cjs/form/fieldPermissions.native.js.map +1 -1
  65. package/dist/cjs/form/formActions.cjs +2 -171
  66. package/dist/cjs/form/formActions.native.js +2 -178
  67. package/dist/cjs/form/formActions.native.js.map +1 -1
  68. package/dist/cjs/form/formLayout.cjs +5 -219
  69. package/dist/cjs/form/formLayout.native.js +5 -359
  70. package/dist/cjs/form/formLayout.native.js.map +1 -1
  71. package/dist/cjs/form/platformHooks.native.js.map +1 -1
  72. package/dist/cjs/form/sidebar-attachments.native.js +1 -1
  73. package/dist/cjs/form/sidebar-attachments.native.js.map +1 -1
  74. package/dist/cjs/form/sidebar-dialogs.native.js +1 -1
  75. package/dist/cjs/form/sidebar-dialogs.native.js.map +1 -1
  76. package/dist/cjs/form/sidebar-people.native.js +1 -1
  77. package/dist/cjs/form/sidebar-people.native.js.map +1 -1
  78. package/dist/cjs/form/sidebar-rpc.native.js.map +1 -1
  79. package/dist/cjs/form/sidebar-utils.native.js.map +1 -1
  80. package/dist/cjs/form/timeline-entries.native.js.map +1 -1
  81. package/dist/cjs/form/timeline-utils.native.js.map +1 -1
  82. package/dist/cjs/form/useFormEngine.cjs +2 -361
  83. package/dist/cjs/form/useFormEngine.native.js +2 -447
  84. package/dist/cjs/form/useFormEngine.native.js.map +1 -1
  85. package/dist/cjs/i18n/en.native.js.map +1 -1
  86. package/dist/cjs/i18n/index.native.js.map +1 -1
  87. package/dist/cjs/index.native.js +1 -1
  88. package/dist/cjs/index.native.js.map +1 -1
  89. package/dist/cjs/list/AddTagsDialog.native.js +1 -1
  90. package/dist/cjs/list/AddTagsDialog.native.js.map +1 -1
  91. package/dist/cjs/list/AssignToDialog.native.js +1 -1
  92. package/dist/cjs/list/AssignToDialog.native.js.map +1 -1
  93. package/dist/cjs/list/DoctypeListScreen.native.js +1 -1
  94. package/dist/cjs/list/DoctypeListScreen.native.js.map +1 -1
  95. package/dist/cjs/list/ListBulkActionsBar.native.js +1 -1
  96. package/dist/cjs/list/ListBulkActionsBar.native.js.map +1 -1
  97. package/dist/cjs/list/ListFilterBar.native.js +1 -1
  98. package/dist/cjs/list/ListFilterBar.native.js.map +1 -1
  99. package/dist/cjs/list/ListSidebar.native.js +1 -1
  100. package/dist/cjs/list/ListSidebar.native.js.map +1 -1
  101. package/dist/cjs/list/bulk-edit-dialog.native.js +1 -1
  102. package/dist/cjs/list/bulk-edit-dialog.native.js.map +1 -1
  103. package/dist/cjs/list/bulk-export.native.js.map +1 -1
  104. package/dist/cjs/list/bulk-submit-cancel.native.js.map +1 -1
  105. package/dist/cjs/list/bulkActions.native.js.map +1 -1
  106. package/dist/cjs/list/filter-chips.native.js +1 -1
  107. package/dist/cjs/list/filter-chips.native.js.map +1 -1
  108. package/dist/cjs/list/filter-editor.native.js +1 -1
  109. package/dist/cjs/list/filter-editor.native.js.map +1 -1
  110. package/dist/cjs/list/filter-fields.native.js.map +1 -1
  111. package/dist/cjs/list/filter-saved.native.js +1 -1
  112. package/dist/cjs/list/filter-saved.native.js.map +1 -1
  113. package/dist/cjs/list/filter-sort.native.js +1 -1
  114. package/dist/cjs/list/filter-sort.native.js.map +1 -1
  115. package/dist/cjs/list/filter-standard.native.js.map +1 -1
  116. package/dist/cjs/list/filterConversion.native.js.map +1 -1
  117. package/dist/cjs/list/list-tools-sheet.native.js +1 -1
  118. package/dist/cjs/list/list-tools-sheet.native.js.map +1 -1
  119. package/dist/cjs/list/listColumns.native.js.map +1 -1
  120. package/dist/cjs/list/listFields.native.js.map +1 -1
  121. package/dist/cjs/list/listFormat.native.js.map +1 -1
  122. package/dist/cjs/list/listUrlState.native.js.map +1 -1
  123. package/dist/cjs/list/sidebar-section.native.js +1 -1
  124. package/dist/cjs/list/sidebar-section.native.js.map +1 -1
  125. package/dist/cjs/list/sidebar-stats.native.js.map +1 -1
  126. package/dist/cjs/list/statusColors.native.js.map +1 -1
  127. package/dist/cjs/navigation/navigator.native.js.map +1 -1
  128. package/dist/cjs/navigation/paths.native.js.map +1 -1
  129. package/dist/cjs/oneAdapter/index.native.js.map +1 -1
  130. package/dist/cjs/quickEntry/QuickEntryDialog.native.js +1 -1
  131. package/dist/cjs/quickEntry/QuickEntryDialog.native.js.map +1 -1
  132. package/dist/cjs/quickEntry/quickEntryPlan.native.js.map +1 -1
  133. package/dist/cjs/report/DoctypeReportView.native.js +1 -1
  134. package/dist/cjs/report/DoctypeReportView.native.js.map +1 -1
  135. package/dist/cjs/report/QueryReportScreen.native.js +1 -1
  136. package/dist/cjs/report/QueryReportScreen.native.js.map +1 -1
  137. package/dist/cjs/report/queryReportColumns.native.js.map +1 -1
  138. package/dist/cjs/report/queryReportFilterBar.native.js +1 -1
  139. package/dist/cjs/report/queryReportFilterBar.native.js.map +1 -1
  140. package/dist/cjs/report/queryReportUrlState.native.js.map +1 -1
  141. package/dist/cjs/report/report-grid.native.js +1 -1
  142. package/dist/cjs/report/report-grid.native.js.map +1 -1
  143. package/dist/cjs/report/report-toolbar.native.js +1 -1
  144. package/dist/cjs/report/report-toolbar.native.js.map +1 -1
  145. package/dist/cjs/report/reportShapes.native.js.map +1 -1
  146. package/dist/cjs/report/reportViewModel.native.js.map +1 -1
  147. package/dist/cjs/report/savedReports.native.js.map +1 -1
  148. package/dist/cjs/report/useQueryReport.native.js.map +1 -1
  149. package/dist/cjs/shared/deskLinks.native.js.map +1 -1
  150. package/dist/cjs/shared/listNavContext.native.js.map +1 -1
  151. package/dist/cjs/shared/types.native.js.map +1 -1
  152. package/dist/cjs/shared/useDocinfo.native.js.map +1 -1
  153. package/dist/cjs/shared/useDoctypeMeta.native.js.map +1 -1
  154. package/dist/cjs/shared/useFrappeApp.native.js.map +1 -1
  155. package/dist/cjs/shared/useRecentVisit.native.js.map +1 -1
  156. package/dist/cjs/shared/useSessionUserId.native.js.map +1 -1
  157. package/dist/cjs/shared/useSlugTarget.native.js.map +1 -1
  158. package/dist/cjs/shared/useUserRoles.native.js.map +1 -1
  159. package/dist/cjs/shell/BackofficeShell.native.js +1 -1
  160. package/dist/cjs/shell/BackofficeShell.native.js.map +1 -1
  161. package/dist/cjs/shell/HomeRedirect.native.js +1 -1
  162. package/dist/cjs/shell/HomeRedirect.native.js.map +1 -1
  163. package/dist/cjs/shell/NotFoundScreen.native.js +1 -1
  164. package/dist/cjs/shell/NotFoundScreen.native.js.map +1 -1
  165. package/dist/cjs/shell/SlugScreen.native.js +1 -1
  166. package/dist/cjs/shell/SlugScreen.native.js.map +1 -1
  167. package/dist/cjs/shell/WorkspaceSidebar.native.js +1 -1
  168. package/dist/cjs/shell/WorkspaceSidebar.native.js.map +1 -1
  169. package/dist/cjs/shell/useWorkspaces.native.js.map +1 -1
  170. package/dist/cjs/shell/workspaceIcons.native.js.map +1 -1
  171. package/dist/cjs/views/CalendarView.native.js +1 -1
  172. package/dist/cjs/views/CalendarView.native.js.map +1 -1
  173. package/dist/cjs/views/DashboardView.native.js +1 -1
  174. package/dist/cjs/views/DashboardView.native.js.map +1 -1
  175. package/dist/cjs/views/DoctypeViewScreen.native.js.map +1 -1
  176. package/dist/cjs/views/ImageView.native.js +1 -1
  177. package/dist/cjs/views/ImageView.native.js.map +1 -1
  178. package/dist/cjs/views/KanbanView.native.js +1 -1
  179. package/dist/cjs/views/KanbanView.native.js.map +1 -1
  180. package/dist/cjs/views/ReportView.native.js +1 -1
  181. package/dist/cjs/views/ReportView.native.js.map +1 -1
  182. package/dist/cjs/views/TreeView.native.js +1 -1
  183. package/dist/cjs/views/TreeView.native.js.map +1 -1
  184. package/dist/cjs/views/ViewHeader.native.js +1 -1
  185. package/dist/cjs/views/ViewHeader.native.js.map +1 -1
  186. package/dist/cjs/views/ViewStates.native.js +1 -1
  187. package/dist/cjs/views/ViewStates.native.js.map +1 -1
  188. package/dist/cjs/views/ViewSwitcherMenu.native.js +1 -1
  189. package/dist/cjs/views/ViewSwitcherMenu.native.js.map +1 -1
  190. package/dist/cjs/views/calendar-field-selector.native.js +1 -1
  191. package/dist/cjs/views/calendar-field-selector.native.js.map +1 -1
  192. package/dist/cjs/views/connection.native.js.map +1 -1
  193. package/dist/cjs/views/dashboard-data.native.js.map +1 -1
  194. package/dist/cjs/views/deskViewConfigs.native.js.map +1 -1
  195. package/dist/cjs/views/kanban-board-controls.native.js +1 -1
  196. package/dist/cjs/views/kanban-board-controls.native.js.map +1 -1
  197. package/dist/cjs/views/kanban-field-picker.native.js +1 -1
  198. package/dist/cjs/views/kanban-field-picker.native.js.map +1 -1
  199. package/dist/cjs/views/kanbanBoardOps.native.js.map +1 -1
  200. package/dist/cjs/views/report-controls.native.js +1 -1
  201. package/dist/cjs/views/report-controls.native.js.map +1 -1
  202. package/dist/cjs/views/viewAvailability.native.js.map +1 -1
  203. package/dist/cjs/views/viewMeta.native.js.map +1 -1
  204. package/dist/cjs/workspace/WorkspaceChartBlock.native.js +1 -1
  205. package/dist/cjs/workspace/WorkspaceChartBlock.native.js.map +1 -1
  206. package/dist/cjs/workspace/WorkspaceGrid.native.js.map +1 -1
  207. package/dist/cjs/workspace/WorkspaceLinkCard.native.js +1 -1
  208. package/dist/cjs/workspace/WorkspaceLinkCard.native.js.map +1 -1
  209. package/dist/cjs/workspace/WorkspaceLinkDirectory.native.js +1 -1
  210. package/dist/cjs/workspace/WorkspaceLinkDirectory.native.js.map +1 -1
  211. package/dist/cjs/workspace/WorkspaceNumberCard.native.js +1 -1
  212. package/dist/cjs/workspace/WorkspaceNumberCard.native.js.map +1 -1
  213. package/dist/cjs/workspace/WorkspaceQuickList.cjs +1 -1
  214. package/dist/cjs/workspace/WorkspaceQuickList.native.js +4 -2
  215. package/dist/cjs/workspace/WorkspaceQuickList.native.js.map +1 -1
  216. package/dist/cjs/workspace/WorkspaceRecents.cjs +1 -3
  217. package/dist/cjs/workspace/WorkspaceRecents.native.js +4 -4
  218. package/dist/cjs/workspace/WorkspaceRecents.native.js.map +1 -1
  219. package/dist/cjs/workspace/WorkspaceScreen.native.js +1 -1
  220. package/dist/cjs/workspace/WorkspaceScreen.native.js.map +1 -1
  221. package/dist/cjs/workspace/WorkspaceShortcut.cjs +1 -3
  222. package/dist/cjs/workspace/WorkspaceShortcut.native.js +5 -4
  223. package/dist/cjs/workspace/WorkspaceShortcut.native.js.map +1 -1
  224. package/dist/cjs/workspace/parseContent.native.js.map +1 -1
  225. package/dist/cjs/workspace/types.native.js.map +1 -1
  226. package/dist/cjs/workspace/useDashboardChart.native.js.map +1 -1
  227. package/dist/cjs/workspace/useWorkspaceDoc.native.js.map +1 -1
  228. package/dist/esm/chrome/BackofficeAwesomebar.native.js.map +1 -1
  229. package/dist/esm/chrome/CommandPalette.native.js.map +1 -1
  230. package/dist/esm/chrome/HelpMenu.native.js.map +1 -1
  231. package/dist/esm/chrome/NotificationsButton.native.js.map +1 -1
  232. package/dist/esm/chrome/UserMenu.native.js.map +1 -1
  233. package/dist/esm/chrome/awesomebar-data.native.js.map +1 -1
  234. package/dist/esm/chrome/command-palette-model.native.js.map +1 -1
  235. package/dist/esm/chrome/help-about-dialog.native.js.map +1 -1
  236. package/dist/esm/chrome/help-shortcuts-dialog.native.js.map +1 -1
  237. package/dist/esm/chrome/notifications-data.native.js.map +1 -1
  238. package/dist/esm/chrome/notifications-panel.native.js.map +1 -1
  239. package/dist/esm/chrome/notifications-utils.native.js.map +1 -1
  240. package/dist/esm/chrome/shortcuts.native.js.map +1 -1
  241. package/dist/esm/chrome/user-session.native.js.map +1 -1
  242. package/dist/esm/config/BackofficeProvider.native.js.map +1 -1
  243. package/dist/esm/config/capabilities.native.js.map +1 -1
  244. package/dist/esm/config/events.native.js.map +1 -1
  245. package/dist/esm/config/slots.native.js.map +1 -1
  246. package/dist/esm/desk/Desk.native.js.map +1 -1
  247. package/dist/esm/desk/DeskSurface.mjs.map +1 -1
  248. package/dist/esm/desk/DeskSurface.native.js.map +1 -1
  249. package/dist/esm/desk/resolveDeskPath.native.js.map +1 -1
  250. package/dist/esm/desk/scope.native.js.map +1 -1
  251. package/dist/esm/desk/target.native.js.map +1 -1
  252. package/dist/esm/form/DocFormScreen.native.js.map +1 -1
  253. package/dist/esm/form/FormConnections.native.js.map +1 -1
  254. package/dist/esm/form/FormDialogs.native.js.map +1 -1
  255. package/dist/esm/form/FormErrorBoundary.native.js.map +1 -1
  256. package/dist/esm/form/FormHeaderCluster.native.js.map +1 -1
  257. package/dist/esm/form/FormSidebarPanel.native.js.map +1 -1
  258. package/dist/esm/form/FormTimeline.native.js.map +1 -1
  259. package/dist/esm/form/FormToolbar.native.js.map +1 -1
  260. package/dist/esm/form/connections-data.native.js.map +1 -1
  261. package/dist/esm/form/createPrefill.mjs +1 -9
  262. package/dist/esm/form/createPrefill.mjs.map +1 -1
  263. package/dist/esm/form/createPrefill.native.js +1 -9
  264. package/dist/esm/form/createPrefill.native.js.map +1 -1
  265. package/dist/esm/form/dependsOn.native.js.map +1 -1
  266. package/dist/esm/form/dirtyTracking.mjs +1 -26
  267. package/dist/esm/form/dirtyTracking.mjs.map +1 -1
  268. package/dist/esm/form/dirtyTracking.native.js +1 -45
  269. package/dist/esm/form/dirtyTracking.native.js.map +1 -1
  270. package/dist/esm/form/docinfo.native.js.map +1 -1
  271. package/dist/esm/form/fetchFrom.mjs +1 -38
  272. package/dist/esm/form/fetchFrom.mjs.map +1 -1
  273. package/dist/esm/form/fetchFrom.native.js +1 -78
  274. package/dist/esm/form/fetchFrom.native.js.map +1 -1
  275. package/dist/esm/form/fieldPermissions.mjs +1 -26
  276. package/dist/esm/form/fieldPermissions.mjs.map +1 -1
  277. package/dist/esm/form/fieldPermissions.native.js +1 -48
  278. package/dist/esm/form/fieldPermissions.native.js.map +1 -1
  279. package/dist/esm/form/formActions.mjs +1 -145
  280. package/dist/esm/form/formActions.mjs.map +1 -1
  281. package/dist/esm/form/formActions.native.js +1 -152
  282. package/dist/esm/form/formActions.native.js.map +1 -1
  283. package/dist/esm/form/formLayout.mjs +1 -215
  284. package/dist/esm/form/formLayout.mjs.map +1 -1
  285. package/dist/esm/form/formLayout.native.js +1 -355
  286. package/dist/esm/form/formLayout.native.js.map +1 -1
  287. package/dist/esm/form/platformHooks.native.js.map +1 -1
  288. package/dist/esm/form/sidebar-attachments.native.js.map +1 -1
  289. package/dist/esm/form/sidebar-dialogs.native.js.map +1 -1
  290. package/dist/esm/form/sidebar-people.native.js.map +1 -1
  291. package/dist/esm/form/sidebar-rpc.native.js.map +1 -1
  292. package/dist/esm/form/sidebar-utils.native.js.map +1 -1
  293. package/dist/esm/form/timeline-entries.native.js.map +1 -1
  294. package/dist/esm/form/timeline-utils.native.js.map +1 -1
  295. package/dist/esm/form/useFormEngine.mjs +1 -360
  296. package/dist/esm/form/useFormEngine.mjs.map +1 -1
  297. package/dist/esm/form/useFormEngine.native.js +1 -446
  298. package/dist/esm/form/useFormEngine.native.js.map +1 -1
  299. package/dist/esm/i18n/en.native.js.map +1 -1
  300. package/dist/esm/i18n/index.native.js.map +1 -1
  301. package/dist/esm/index.native.js.map +1 -1
  302. package/dist/esm/list/AddTagsDialog.native.js.map +1 -1
  303. package/dist/esm/list/AssignToDialog.native.js.map +1 -1
  304. package/dist/esm/list/DoctypeListScreen.native.js.map +1 -1
  305. package/dist/esm/list/ListBulkActionsBar.native.js.map +1 -1
  306. package/dist/esm/list/ListFilterBar.native.js.map +1 -1
  307. package/dist/esm/list/ListSidebar.native.js.map +1 -1
  308. package/dist/esm/list/bulk-edit-dialog.native.js.map +1 -1
  309. package/dist/esm/list/bulk-export.native.js.map +1 -1
  310. package/dist/esm/list/bulk-submit-cancel.native.js.map +1 -1
  311. package/dist/esm/list/bulkActions.native.js.map +1 -1
  312. package/dist/esm/list/filter-chips.native.js.map +1 -1
  313. package/dist/esm/list/filter-editor.native.js.map +1 -1
  314. package/dist/esm/list/filter-fields.native.js.map +1 -1
  315. package/dist/esm/list/filter-saved.native.js.map +1 -1
  316. package/dist/esm/list/filter-sort.native.js.map +1 -1
  317. package/dist/esm/list/filter-standard.native.js.map +1 -1
  318. package/dist/esm/list/filterConversion.native.js.map +1 -1
  319. package/dist/esm/list/list-tools-sheet.native.js.map +1 -1
  320. package/dist/esm/list/listColumns.native.js.map +1 -1
  321. package/dist/esm/list/listFields.native.js.map +1 -1
  322. package/dist/esm/list/listFormat.native.js.map +1 -1
  323. package/dist/esm/list/listUrlState.native.js.map +1 -1
  324. package/dist/esm/list/sidebar-section.native.js.map +1 -1
  325. package/dist/esm/list/sidebar-stats.native.js.map +1 -1
  326. package/dist/esm/list/statusColors.native.js.map +1 -1
  327. package/dist/esm/navigation/navigator.native.js.map +1 -1
  328. package/dist/esm/navigation/paths.native.js.map +1 -1
  329. package/dist/esm/oneAdapter/index.native.js.map +1 -1
  330. package/dist/esm/quickEntry/QuickEntryDialog.native.js.map +1 -1
  331. package/dist/esm/quickEntry/quickEntryPlan.native.js.map +1 -1
  332. package/dist/esm/report/DoctypeReportView.native.js.map +1 -1
  333. package/dist/esm/report/QueryReportScreen.native.js.map +1 -1
  334. package/dist/esm/report/queryReportColumns.native.js.map +1 -1
  335. package/dist/esm/report/queryReportFilterBar.native.js.map +1 -1
  336. package/dist/esm/report/queryReportUrlState.native.js.map +1 -1
  337. package/dist/esm/report/report-grid.native.js.map +1 -1
  338. package/dist/esm/report/report-toolbar.native.js.map +1 -1
  339. package/dist/esm/report/reportShapes.native.js.map +1 -1
  340. package/dist/esm/report/reportViewModel.native.js.map +1 -1
  341. package/dist/esm/report/savedReports.native.js.map +1 -1
  342. package/dist/esm/report/useQueryReport.native.js.map +1 -1
  343. package/dist/esm/shared/deskLinks.native.js.map +1 -1
  344. package/dist/esm/shared/listNavContext.native.js.map +1 -1
  345. package/dist/esm/shared/types.native.js.map +1 -1
  346. package/dist/esm/shared/useDocinfo.native.js.map +1 -1
  347. package/dist/esm/shared/useDoctypeMeta.mjs.map +1 -1
  348. package/dist/esm/shared/useDoctypeMeta.native.js.map +1 -1
  349. package/dist/esm/shared/useFrappeApp.native.js.map +1 -1
  350. package/dist/esm/shared/useRecentVisit.native.js.map +1 -1
  351. package/dist/esm/shared/useSessionUserId.native.js.map +1 -1
  352. package/dist/esm/shared/useSlugTarget.native.js.map +1 -1
  353. package/dist/esm/shared/useUserRoles.native.js.map +1 -1
  354. package/dist/esm/shell/BackofficeShell.native.js.map +1 -1
  355. package/dist/esm/shell/HomeRedirect.native.js.map +1 -1
  356. package/dist/esm/shell/NotFoundScreen.native.js.map +1 -1
  357. package/dist/esm/shell/SlugScreen.native.js.map +1 -1
  358. package/dist/esm/shell/WorkspaceSidebar.native.js.map +1 -1
  359. package/dist/esm/shell/useWorkspaces.native.js.map +1 -1
  360. package/dist/esm/shell/workspaceIcons.native.js.map +1 -1
  361. package/dist/esm/views/CalendarView.native.js.map +1 -1
  362. package/dist/esm/views/DashboardView.native.js.map +1 -1
  363. package/dist/esm/views/DoctypeViewScreen.native.js.map +1 -1
  364. package/dist/esm/views/ImageView.native.js.map +1 -1
  365. package/dist/esm/views/KanbanView.native.js.map +1 -1
  366. package/dist/esm/views/ReportView.native.js.map +1 -1
  367. package/dist/esm/views/TreeView.native.js.map +1 -1
  368. package/dist/esm/views/ViewHeader.native.js.map +1 -1
  369. package/dist/esm/views/ViewStates.native.js.map +1 -1
  370. package/dist/esm/views/ViewSwitcherMenu.native.js.map +1 -1
  371. package/dist/esm/views/calendar-field-selector.native.js.map +1 -1
  372. package/dist/esm/views/connection.native.js.map +1 -1
  373. package/dist/esm/views/dashboard-data.native.js.map +1 -1
  374. package/dist/esm/views/deskViewConfigs.native.js.map +1 -1
  375. package/dist/esm/views/kanban-board-controls.native.js.map +1 -1
  376. package/dist/esm/views/kanban-field-picker.native.js.map +1 -1
  377. package/dist/esm/views/kanbanBoardOps.native.js.map +1 -1
  378. package/dist/esm/views/report-controls.native.js.map +1 -1
  379. package/dist/esm/views/viewAvailability.native.js.map +1 -1
  380. package/dist/esm/views/viewMeta.native.js.map +1 -1
  381. package/dist/esm/workspace/WorkspaceChartBlock.native.js.map +1 -1
  382. package/dist/esm/workspace/WorkspaceGrid.native.js.map +1 -1
  383. package/dist/esm/workspace/WorkspaceLinkCard.native.js.map +1 -1
  384. package/dist/esm/workspace/WorkspaceLinkDirectory.native.js.map +1 -1
  385. package/dist/esm/workspace/WorkspaceNumberCard.native.js.map +1 -1
  386. package/dist/esm/workspace/WorkspaceQuickList.mjs +2 -2
  387. package/dist/esm/workspace/WorkspaceQuickList.mjs.map +1 -1
  388. package/dist/esm/workspace/WorkspaceQuickList.native.js +4 -2
  389. package/dist/esm/workspace/WorkspaceQuickList.native.js.map +1 -1
  390. package/dist/esm/workspace/WorkspaceRecents.mjs +1 -3
  391. package/dist/esm/workspace/WorkspaceRecents.mjs.map +1 -1
  392. package/dist/esm/workspace/WorkspaceRecents.native.js +3 -3
  393. package/dist/esm/workspace/WorkspaceRecents.native.js.map +1 -1
  394. package/dist/esm/workspace/WorkspaceScreen.native.js.map +1 -1
  395. package/dist/esm/workspace/WorkspaceShortcut.mjs +1 -3
  396. package/dist/esm/workspace/WorkspaceShortcut.mjs.map +1 -1
  397. package/dist/esm/workspace/WorkspaceShortcut.native.js +4 -3
  398. package/dist/esm/workspace/WorkspaceShortcut.native.js.map +1 -1
  399. package/dist/esm/workspace/parseContent.native.js.map +1 -1
  400. package/dist/esm/workspace/types.native.js.map +1 -1
  401. package/dist/esm/workspace/useDashboardChart.native.js.map +1 -1
  402. package/dist/esm/workspace/useWorkspaceDoc.native.js.map +1 -1
  403. package/dist/jsx/desk/DeskSurface.mjs.map +1 -1
  404. package/dist/jsx/desk/DeskSurface.native.js.map +1 -1
  405. package/dist/jsx/form/createPrefill.mjs +1 -9
  406. package/dist/jsx/form/createPrefill.mjs.map +1 -1
  407. package/dist/jsx/form/createPrefill.native.js +3 -11
  408. package/dist/jsx/form/createPrefill.native.js.map +1 -1
  409. package/dist/jsx/form/dirtyTracking.mjs +1 -26
  410. package/dist/jsx/form/dirtyTracking.mjs.map +1 -1
  411. package/dist/jsx/form/dirtyTracking.native.js +4 -48
  412. package/dist/jsx/form/dirtyTracking.native.js.map +1 -1
  413. package/dist/jsx/form/fetchFrom.mjs +1 -38
  414. package/dist/jsx/form/fetchFrom.mjs.map +1 -1
  415. package/dist/jsx/form/fetchFrom.native.js +4 -81
  416. package/dist/jsx/form/fetchFrom.native.js.map +1 -1
  417. package/dist/jsx/form/fieldPermissions.mjs +1 -26
  418. package/dist/jsx/form/fieldPermissions.mjs.map +1 -1
  419. package/dist/jsx/form/fieldPermissions.native.js +4 -51
  420. package/dist/jsx/form/fieldPermissions.native.js.map +1 -1
  421. package/dist/jsx/form/formActions.mjs +1 -145
  422. package/dist/jsx/form/formActions.mjs.map +1 -1
  423. package/dist/jsx/form/formActions.native.js +2 -178
  424. package/dist/jsx/form/formActions.native.js.map +1 -1
  425. package/dist/jsx/form/formLayout.mjs +1 -215
  426. package/dist/jsx/form/formLayout.mjs.map +1 -1
  427. package/dist/jsx/form/formLayout.native.js +5 -359
  428. package/dist/jsx/form/formLayout.native.js.map +1 -1
  429. package/dist/jsx/form/useFormEngine.mjs +1 -360
  430. package/dist/jsx/form/useFormEngine.mjs.map +1 -1
  431. package/dist/jsx/form/useFormEngine.native.js +2 -447
  432. package/dist/jsx/form/useFormEngine.native.js.map +1 -1
  433. package/dist/jsx/index.native.js.map +1 -1
  434. package/dist/jsx/shared/useDoctypeMeta.mjs.map +1 -1
  435. package/dist/jsx/shared/useDoctypeMeta.native.js.map +1 -1
  436. package/dist/jsx/workspace/WorkspaceQuickList.mjs +2 -2
  437. package/dist/jsx/workspace/WorkspaceQuickList.mjs.map +1 -1
  438. package/dist/jsx/workspace/WorkspaceQuickList.native.js +3 -1
  439. package/dist/jsx/workspace/WorkspaceQuickList.native.js.map +1 -1
  440. package/dist/jsx/workspace/WorkspaceRecents.mjs +1 -3
  441. package/dist/jsx/workspace/WorkspaceRecents.mjs.map +1 -1
  442. package/dist/jsx/workspace/WorkspaceRecents.native.js +3 -3
  443. package/dist/jsx/workspace/WorkspaceRecents.native.js.map +1 -1
  444. package/dist/jsx/workspace/WorkspaceShortcut.mjs +1 -3
  445. package/dist/jsx/workspace/WorkspaceShortcut.mjs.map +1 -1
  446. package/dist/jsx/workspace/WorkspaceShortcut.native.js +4 -3
  447. package/dist/jsx/workspace/WorkspaceShortcut.native.js.map +1 -1
  448. package/package.json +12 -13
  449. package/src/desk/DeskSurface.tsx +8 -4
  450. package/src/form/createPrefill.ts +5 -25
  451. package/src/form/dirtyTracking.ts +4 -61
  452. package/src/form/fetchFrom.ts +5 -108
  453. package/src/form/fieldPermissions.ts +7 -65
  454. package/src/form/formActions.ts +10 -281
  455. package/src/form/formEngineShim.spec.ts +122 -0
  456. package/src/form/formLayout.ts +15 -387
  457. package/src/form/useFormEngine.ts +5 -493
  458. package/src/shared/useDoctypeMeta.ts +12 -100
  459. package/src/workspace/WorkspaceQuickList.tsx +10 -2
  460. package/src/workspace/WorkspaceRecents.tsx +3 -1
  461. package/src/workspace/WorkspaceShortcut.tsx +4 -1
  462. package/types/desk/DeskSurface.d.ts.map +1 -1
  463. package/types/form/createPrefill.d.ts +5 -16
  464. package/types/form/createPrefill.d.ts.map +1 -1
  465. package/types/form/dirtyTracking.d.ts +4 -33
  466. package/types/form/dirtyTracking.d.ts.map +1 -1
  467. package/types/form/fetchFrom.d.ts +5 -40
  468. package/types/form/fetchFrom.d.ts.map +1 -1
  469. package/types/form/fieldPermissions.d.ts +7 -35
  470. package/types/form/fieldPermissions.d.ts.map +1 -1
  471. package/types/form/formActions.d.ts +6 -91
  472. package/types/form/formActions.d.ts.map +1 -1
  473. package/types/form/formLayout.d.ts +12 -89
  474. package/types/form/formLayout.d.ts.map +1 -1
  475. package/types/form/useFormEngine.d.ts +5 -58
  476. package/types/form/useFormEngine.d.ts.map +1 -1
  477. package/types/shared/useDoctypeMeta.d.ts +2 -100
  478. package/types/shared/useDoctypeMeta.d.ts.map +1 -1
  479. package/types/workspace/WorkspaceQuickList.d.ts.map +1 -1
  480. package/types/workspace/WorkspaceRecents.d.ts.map +1 -1
  481. package/types/workspace/WorkspaceShortcut.d.ts.map +1 -1
  482. package/src/form/dirtyTracking.spec.ts +0 -91
  483. package/src/form/fetchFrom.spec.ts +0 -92
  484. package/src/form/fieldPermissions.spec.ts +0 -61
  485. package/src/form/formLayout.spec.ts +0 -373
@@ -1,91 +0,0 @@
1
- // R-1 false "Not Saved": engine-level dirty-tracking contract.
2
- // An untouched existing doc must read pristine, a real edit must read dirty,
3
- // create mode must read dirty from applied defaults (desk parity).
4
- import { describe, expect, it } from "vitest";
5
- import { computeDirtyFields, isSameValue } from "./dirtyTracking";
6
-
7
- describe("isSameValue (normalization-insensitive equality)", () => {
8
- it("treats null / undefined / empty string / empty array as one empty state", () => {
9
- expect(isSameValue(null, "")).toBe(true);
10
- expect(isSameValue(undefined, "")).toBe(true);
11
- expect(isSameValue(null, undefined)).toBe(true);
12
- expect(isSameValue([], null)).toBe(true);
13
- expect(isSameValue(" ", "")).toBe(true);
14
- });
15
-
16
- it("folds boolean and wire 0/1 representations", () => {
17
- expect(isSameValue(false, 0)).toBe(true);
18
- expect(isSameValue(true, 1)).toBe(true);
19
- expect(isSameValue(0, false)).toBe(true);
20
- expect(isSameValue(true, 0)).toBe(false);
21
- expect(isSameValue(false, 1)).toBe(false);
22
- });
23
-
24
- it("does not conflate empty with falsy non-empty values", () => {
25
- expect(isSameValue(0, "")).toBe(false);
26
- expect(isSameValue(false, "")).toBe(false);
27
- expect(isSameValue(0, null)).toBe(false);
28
- });
29
-
30
- it("stays strict for real values — no deep equality", () => {
31
- expect(isSameValue("a", "a")).toBe(true);
32
- expect(isSameValue("a", "b")).toBe(false);
33
- // Distinct array/object identities read as different even when
34
- // structurally equal (deliberate: no deep-equality time bombs).
35
- expect(isSameValue([{ a: 1 }], [{ a: 1 }])).toBe(false);
36
- // Representation changes of real content are edits (the field layer is
37
- // responsible for not emitting them during initialization).
38
- expect(isSameValue("plain", "<p>plain</p>")).toBe(false);
39
- });
40
- });
41
-
42
- describe("computeDirtyFields", () => {
43
- const baseline = {
44
- doctype: "ToDo",
45
- name: "abc",
46
- description: "hello",
47
- status: "Open",
48
- color: null,
49
- priority: "Medium",
50
- date: "2026-08-12",
51
- checked: 0,
52
- };
53
-
54
- it("existing doc mount: local === baseline snapshot reads pristine", () => {
55
- expect(computeDirtyFields({ ...baseline }, baseline)).toEqual([]);
56
- });
57
-
58
- it("field re-representation during init does not dirty (null→'' and 0→false)", () => {
59
- const local = { ...baseline, color: "", checked: false };
60
- expect(computeDirtyFields(local, baseline)).toEqual([]);
61
- });
62
-
63
- it("a real edit reads dirty", () => {
64
- const local = { ...baseline, description: "hello edited" };
65
- expect(computeDirtyFields(local, baseline)).toEqual(["description"]);
66
- });
67
-
68
- it("revert to the exact baseline value reads clean again", () => {
69
- // Documented behavior: value equality, not edit history — typing and
70
- // deleting back to the original string is pristine. An equivalent-but-
71
- // differently-represented value (e.g. tiptap-normalized HTML) would
72
- // still read dirty, which matches desk.
73
- const local = { ...baseline, description: "hello" };
74
- expect(computeDirtyFields(local, baseline)).toEqual([]);
75
- });
76
-
77
- it("bookkeeping keys never dirty", () => {
78
- const local = { ...baseline, name: "renamed", doctype: "Other" };
79
- expect(computeDirtyFields(local, baseline)).toEqual([]);
80
- });
81
-
82
- it("new doc (no baseline) with applied create-defaults reads dirty — desk parity", () => {
83
- const local = { doctype: "ToDo", status: "Open", priority: "Medium", description: "" };
84
- expect(computeDirtyFields(local, undefined)).toEqual(["status", "priority"]);
85
- });
86
-
87
- it("new doc with only empty values reads pristine", () => {
88
- const local = { doctype: "ToDo", description: "", color: null };
89
- expect(computeDirtyFields(local, undefined)).toEqual([]);
90
- });
91
- });
@@ -1,92 +0,0 @@
1
- /**
2
- * fetchFrom — fetch_from preview parity with desk script_manager.js
3
- * setup_add_fetch + link.js validate_link_and_fetch.
4
- */
5
- import { describe, expect, it } from "vitest";
6
- import type { DocFieldMeta } from "../shared/useDoctypeMeta";
7
- import { applyFetchedValues, buildFetchMap, isFetchLocked } from "./fetchFrom";
8
-
9
- function field(overrides: Partial<DocFieldMeta> & { fieldname: string }): DocFieldMeta {
10
- return { fieldtype: "Data", ...overrides };
11
- }
12
-
13
- describe("buildFetchMap", () => {
14
- it("registers scalar fieldtypes keyed by their link field", () => {
15
- const map = buildFetchMap([
16
- field({ fieldname: "customer", fieldtype: "Link", options: "Customer" }),
17
- field({ fieldname: "customer_name", fetch_from: "customer.customer_name" }),
18
- field({ fieldname: "territory", fieldtype: "Select", fetch_from: "customer.territory" }),
19
- ]);
20
- expect(map.get("customer")).toEqual([
21
- { target: "customer_name", source: "customer_name", fetchIfEmpty: false },
22
- { target: "territory", source: "territory", fetchIfEmpty: false },
23
- ]);
24
- });
25
-
26
- it("skips fetch_from without a dot and non-registered fieldtypes", () => {
27
- const map = buildFetchMap([
28
- field({ fieldname: "bad", fetch_from: "customer" }),
29
- field({ fieldname: "html", fieldtype: "HTML", fetch_from: "customer.blurb" }),
30
- ]);
31
- expect(map.size).toBe(0);
32
- });
33
-
34
- it("includes non-scalar fieldtypes when read_only (script_manager gate)", () => {
35
- const map = buildFetchMap([
36
- field({
37
- fieldname: "blurb",
38
- fieldtype: "HTML Editor",
39
- fetch_from: "customer.blurb",
40
- read_only: 1,
41
- }),
42
- ]);
43
- expect(map.get("customer")).toHaveLength(1);
44
- });
45
-
46
- it("records fetch_if_empty", () => {
47
- const map = buildFetchMap([
48
- field({ fieldname: "note", fetch_from: "customer.note", fetch_if_empty: 1 }),
49
- ]);
50
- expect(map.get("customer")?.[0].fetchIfEmpty).toBe(true);
51
- });
52
- });
53
-
54
- describe("applyFetchedValues", () => {
55
- const rules = [
56
- { target: "customer_name", source: "customer_name", fetchIfEmpty: false },
57
- { target: "note", source: "note", fetchIfEmpty: true },
58
- ];
59
-
60
- it("writes fetched values onto targets", () => {
61
- const patch = applyFetchedValues(rules, { customer_name: "Acme", note: "VIP" }, {});
62
- expect(patch).toEqual({ customer_name: "Acme", note: "VIP" });
63
- });
64
-
65
- it("fetch_if_empty targets keep an existing value", () => {
66
- const patch = applyFetchedValues(
67
- rules,
68
- { customer_name: "Acme", note: "VIP" },
69
- { note: "user wrote this" },
70
- );
71
- expect(patch).toEqual({ customer_name: "Acme" });
72
- });
73
-
74
- it("clearing the link blanks plain targets but spares fetch_if_empty values", () => {
75
- const patch = applyFetchedValues(rules, {}, { customer_name: "Acme", note: "mine" });
76
- expect(patch).toEqual({ customer_name: "" });
77
- });
78
- });
79
-
80
- describe("isFetchLocked", () => {
81
- it("locks while the source link holds a value, unless fetch_if_empty", () => {
82
- const target = field({ fieldname: "customer_name", fetch_from: "customer.customer_name" });
83
- expect(isFetchLocked(target, { customer: "CUST-1" })).toBe(true);
84
- expect(isFetchLocked(target, {})).toBe(false);
85
- const softTarget = field({
86
- fieldname: "note",
87
- fetch_from: "customer.note",
88
- fetch_if_empty: 1,
89
- });
90
- expect(isFetchLocked(softTarget, { customer: "CUST-1" })).toBe(false);
91
- });
92
- });
@@ -1,61 +0,0 @@
1
- /**
2
- * fieldPermissions — permlevel matrix parity with desk perm.js
3
- * get_role_permissions / get_field_display_status.
4
- */
5
- import { describe, expect, it } from "vitest";
6
- import { buildPermLevelMatrix, canReadLevel, canWriteLevel } from "./fieldPermissions";
7
-
8
- const userDoctypePerms = [
9
- { role: "System Manager", permlevel: 0, read: 1 as const, write: 1 as const },
10
- { role: "System Manager", permlevel: 1, read: 1 as const, write: 1 as const },
11
- { role: "Desk User", permlevel: 0, read: 0 as const, write: 0 as const },
12
- ];
13
-
14
- describe("buildPermLevelMatrix", () => {
15
- it("unions rights across the user's matching roles", () => {
16
- const matrix = buildPermLevelMatrix(
17
- [
18
- { role: "Blogger", permlevel: 1, read: 1 as const, write: 0 as const },
19
- { role: "Website Manager", permlevel: 1, read: 1 as const, write: 1 as const },
20
- ],
21
- ["Blogger", "Website Manager"],
22
- );
23
- expect(matrix?.[1]).toEqual({ read: true, write: true });
24
- });
25
-
26
- it("ignores rows for roles the user does not hold (User doctype shape)", () => {
27
- const matrix = buildPermLevelMatrix(userDoctypePerms, ["Desk User"]);
28
- expect(matrix?.[1]).toBeUndefined();
29
- expect(canReadLevel(matrix, 1)).toBe(false);
30
- expect(canWriteLevel(matrix, 1)).toBe(false);
31
- });
32
-
33
- it("returns undefined without roles or permission rows (fallback signal)", () => {
34
- expect(buildPermLevelMatrix(userDoctypePerms, undefined)).toBeUndefined();
35
- expect(buildPermLevelMatrix([], ["System Manager"])).toBeUndefined();
36
- expect(buildPermLevelMatrix(undefined, ["System Manager"])).toBeUndefined();
37
- });
38
- });
39
-
40
- describe("canReadLevel / canWriteLevel", () => {
41
- const matrix = buildPermLevelMatrix(userDoctypePerms, ["System Manager"]);
42
-
43
- it("level 0 defers to doc-level perms (always true here)", () => {
44
- expect(canReadLevel(matrix, 0)).toBe(true);
45
- expect(canWriteLevel(matrix, 0)).toBe(true);
46
- expect(canReadLevel(undefined, 0)).toBe(true);
47
- expect(canWriteLevel(undefined, 0)).toBe(true);
48
- });
49
-
50
- it("higher levels resolve from the matrix", () => {
51
- expect(canReadLevel(matrix, 1)).toBe(true);
52
- expect(canWriteLevel(matrix, 1)).toBe(true);
53
- // Level with no rows at all → hidden (desk fills gaps with {}).
54
- expect(canReadLevel(matrix, 2)).toBe(false);
55
- });
56
-
57
- it("without a matrix: visible but read-only above level 0 (coarse fallback)", () => {
58
- expect(canReadLevel(undefined, 1)).toBe(true);
59
- expect(canWriteLevel(undefined, 1)).toBe(false);
60
- });
61
- });
@@ -1,373 +0,0 @@
1
- /**
2
- * formLayout — desk layout-engine parity specs. Ground truth:
3
- * frappe/public/js/frappe/form/layout.js (+ section.js, tab.js) and
4
- * frappe/public/js/frappe/model/perm.js get_field_display_status.
5
- */
6
- import { describe, expect, it } from "vitest";
7
- import type { DocFieldMeta } from "../shared/useDoctypeMeta";
8
- import { buildPermLevelMatrix } from "./fieldPermissions";
9
- import { buildCreateDefaults, buildFormTabs, type BuildTabsOptions } from "./formLayout";
10
-
11
- function field(overrides: Partial<DocFieldMeta> & { fieldname: string }): DocFieldMeta {
12
- return { fieldtype: "Data", label: overrides.fieldname, ...overrides };
13
- }
14
-
15
- function build(
16
- fields: DocFieldMeta[],
17
- overrides: Partial<BuildTabsOptions> = {},
18
- ): ReturnType<typeof buildFormTabs> {
19
- return buildFormTabs({
20
- fields,
21
- doc: {},
22
- docstatus: 0,
23
- formReadOnly: false,
24
- isCreate: false,
25
- detailsLabel: "Details",
26
- ...overrides,
27
- });
28
- }
29
-
30
- function flatFieldNames(tabs: ReturnType<typeof buildFormTabs>): string[] {
31
- return tabs.flatMap((tab) => tab.schema.fields.map((f) => f.name));
32
- }
33
-
34
- function findField(tabs: ReturnType<typeof buildFormTabs>, name: string) {
35
- for (const tab of tabs) {
36
- const hit = tab.schema.fields.find((f) => f.name === name);
37
- if (hit) return hit;
38
- }
39
- return undefined;
40
- }
41
-
42
- describe("tab / section / column grouping", () => {
43
- it("groups fields under Tab Breaks with an implicit Details tab", () => {
44
- const tabs = build([
45
- field({ fieldname: "a" }),
46
- field({ fieldname: "tab1", fieldtype: "Tab Break", label: "More" }),
47
- field({ fieldname: "b" }),
48
- ]);
49
- expect(tabs.map((t) => t.key)).toEqual(["__details", "tab1"]);
50
- expect(tabs[0].label).toBe("Details");
51
- expect(tabs[0].schema.fields.map((f) => f.name)).toEqual(["a"]);
52
- expect(tabs[1].schema.fields.map((f) => f.name)).toEqual(["b"]);
53
- });
54
-
55
- it("drops the implicit Details tab when the doctype starts with a Tab Break (User)", () => {
56
- const tabs = build([
57
- field({ fieldname: "details_tab", fieldtype: "Tab Break", label: "User Details" }),
58
- field({ fieldname: "email" }),
59
- ]);
60
- expect(tabs.map((t) => t.key)).toEqual(["details_tab"]);
61
- });
62
-
63
- it("splits Section Breaks into sections and Column Breaks into columns", () => {
64
- const tabs = build([
65
- field({ fieldname: "a" }),
66
- field({ fieldname: "sec1", fieldtype: "Section Break", label: "Second" }),
67
- field({ fieldname: "b" }),
68
- field({ fieldname: "col1", fieldtype: "Column Break" }),
69
- field({ fieldname: "c" }),
70
- ]);
71
- const sections = tabs[0].schema.sections;
72
- expect(sections).toHaveLength(2);
73
- expect(sections[1].label).toBe("Second");
74
- expect(sections[1].columns).toHaveLength(2);
75
- expect(sections[1].columns[0].fields[0].name).toBe("b");
76
- expect(sections[1].columns[1].fields[0].name).toBe("c");
77
- });
78
- });
79
-
80
- describe("hidden + depends_on visibility", () => {
81
- it("drops hidden fields", () => {
82
- const tabs = build([field({ fieldname: "a" }), field({ fieldname: "b", hidden: 1 })]);
83
- expect(flatFieldNames(tabs)).toEqual(["a"]);
84
- });
85
-
86
- it("auto-hides a section when all its fields hide (desk empty-section)", () => {
87
- const tabs = build([
88
- field({ fieldname: "a" }),
89
- field({ fieldname: "sec1", fieldtype: "Section Break", label: "Hidden Section" }),
90
- field({ fieldname: "b", hidden: 1 }),
91
- field({ fieldname: "c", depends_on: "eval:doc.missing" }),
92
- ]);
93
- expect(tabs[0].schema.sections).toHaveLength(1);
94
- });
95
-
96
- it("auto-hides a tab when all its sections hide", () => {
97
- const tabs = build([
98
- field({ fieldname: "a" }),
99
- field({ fieldname: "tab1", fieldtype: "Tab Break", label: "Empty" }),
100
- field({ fieldname: "b", hidden: 1 }),
101
- ]);
102
- expect(tabs.map((t) => t.key)).toEqual(["__details"]);
103
- });
104
-
105
- it("hides a whole section when its Section Break depends_on is false", () => {
106
- const tabs = build(
107
- [
108
- field({ fieldname: "a" }),
109
- field({
110
- fieldname: "sec1",
111
- fieldtype: "Section Break",
112
- depends_on: "eval:doc.show_more",
113
- }),
114
- field({ fieldname: "b" }),
115
- ],
116
- { doc: { show_more: 0 } },
117
- );
118
- expect(flatFieldNames(tabs)).toEqual(["a"]);
119
- });
120
-
121
- it("re-resolves depends_on against the live doc", () => {
122
- const fields = [
123
- field({ fieldname: "channel", fieldtype: "Select", options: "Email\nSlack" }),
124
- field({
125
- fieldname: "slack_webhook_url",
126
- depends_on: "eval:doc.channel=='Slack'",
127
- mandatory_depends_on: "eval:doc.channel=='Slack'",
128
- }),
129
- ];
130
- expect(flatFieldNames(build(fields, { doc: { channel: "Email" } }))).toEqual(["channel"]);
131
- const slackTabs = build(fields, { doc: { channel: "Slack" } });
132
- expect(flatFieldNames(slackTabs)).toEqual(["channel", "slack_webhook_url"]);
133
- expect(findField(slackTabs, "slack_webhook_url")?.required).toBe(true);
134
- });
135
- });
136
-
137
- describe("read_only / read_only_depends_on / set_only_once", () => {
138
- it("marks read_only fields readOnly", () => {
139
- const tabs = build([field({ fieldname: "a", read_only: 1 })]);
140
- expect(findField(tabs, "a")?.readOnly).toBe(true);
141
- });
142
-
143
- it("resolves read_only_depends_on per doc state", () => {
144
- const fields = [field({ fieldname: "a", read_only_depends_on: "eval:doc.locked" })];
145
- expect(findField(build(fields, { doc: { locked: 1 } }), "a")?.readOnly).toBe(true);
146
- expect(findField(build(fields, { doc: { locked: 0 } }), "a")?.readOnly).toBe(false);
147
- });
148
-
149
- it("set_only_once: editable on new docs, read-only on saved docs (perm.js:261)", () => {
150
- const fields = [field({ fieldname: "a", set_only_once: 1 })];
151
- expect(findField(build(fields, { isCreate: true }), "a")?.readOnly).toBe(false);
152
- expect(findField(build(fields, { isCreate: false }), "a")?.readOnly).toBe(true);
153
- });
154
- });
155
-
156
- describe("docstatus lifecycle locking", () => {
157
- const fields = [
158
- field({ fieldname: "locked_field" }),
159
- field({ fieldname: "open_field", allow_on_submit: 1 }),
160
- ];
161
-
162
- it("docstatus 1 locks everything except allow_on_submit", () => {
163
- const tabs = build(fields, { docstatus: 1 });
164
- expect(findField(tabs, "locked_field")?.readOnly).toBe(true);
165
- expect(findField(tabs, "open_field")?.readOnly).toBe(false);
166
- });
167
-
168
- it("docstatus 2 locks allow_on_submit fields too", () => {
169
- const tabs = build(fields, { docstatus: 2 });
170
- expect(findField(tabs, "open_field")?.readOnly).toBe(true);
171
- });
172
- });
173
-
174
- describe("permlevel gating (perm.js get_field_display_status)", () => {
175
- const permissions = [
176
- { role: "System Manager", permlevel: 0, read: 1 as const, write: 1 as const },
177
- { role: "System Manager", permlevel: 1, read: 1 as const, write: 1 as const },
178
- { role: "Auditor", permlevel: 1, read: 1 as const, write: 0 as const },
179
- { role: "Desk User", permlevel: 0, read: 1 as const, write: 1 as const },
180
- ];
181
- const fields = [field({ fieldname: "plain" }), field({ fieldname: "restricted", permlevel: 1 })];
182
-
183
- it("write at the level → editable (fixes the coarse always-read-only rule)", () => {
184
- const matrix = buildPermLevelMatrix(permissions, ["System Manager"]);
185
- const tabs = build(fields, { permLevels: matrix });
186
- expect(findField(tabs, "restricted")?.readOnly).toBe(false);
187
- });
188
-
189
- it("read without write at the level → read-only", () => {
190
- const matrix = buildPermLevelMatrix(permissions, ["Auditor"]);
191
- const tabs = build(fields, { permLevels: matrix });
192
- expect(findField(tabs, "restricted")?.readOnly).toBe(true);
193
- });
194
-
195
- it("no read at the level → field hidden (desk status None)", () => {
196
- const matrix = buildPermLevelMatrix(permissions, ["Desk User"]);
197
- const tabs = build(fields, { permLevels: matrix });
198
- expect(findField(tabs, "restricted")).toBeUndefined();
199
- expect(findField(tabs, "plain")).toBeDefined();
200
- });
201
-
202
- it("without a matrix falls back to coarse permlevel>0 read-only, never hidden", () => {
203
- const tabs = build(fields);
204
- expect(findField(tabs, "restricted")?.readOnly).toBe(true);
205
- });
206
-
207
- it("hides a Tab Break the user cannot read (tab.js:41)", () => {
208
- const matrix = buildPermLevelMatrix(permissions, ["Desk User"]);
209
- const tabs = build(
210
- [
211
- field({ fieldname: "a" }),
212
- field({ fieldname: "sec_tab", fieldtype: "Tab Break", label: "Secret", permlevel: 1 }),
213
- field({ fieldname: "b" }),
214
- ],
215
- { permLevels: matrix },
216
- );
217
- expect(tabs.map((t) => t.key)).toEqual(["__details"]);
218
- });
219
- });
220
-
221
- describe("section collapse state (layout.js refresh_section_collapse)", () => {
222
- it("collapsible sections start collapsed", () => {
223
- const tabs = build([
224
- field({ fieldname: "sec1", fieldtype: "Section Break", label: "S", collapsible: 1 }),
225
- field({ fieldname: "a" }),
226
- ]);
227
- expect(tabs[0].schema.sections[0].collapsed).toBe(true);
228
- });
229
-
230
- it("collapsible_depends_on truthy → expanded (Notification print settings)", () => {
231
- const fields = [
232
- field({
233
- fieldname: "sec1",
234
- fieldtype: "Section Break",
235
- label: "S",
236
- collapsible: 1,
237
- collapsible_depends_on: "attach_print",
238
- }),
239
- field({ fieldname: "a" }),
240
- ];
241
- expect(build(fields, { doc: { attach_print: 1 } })[0].schema.sections[0].collapsed).toBe(false);
242
- expect(build(fields, { doc: { attach_print: 0 } })[0].schema.sections[0].collapsed).toBe(true);
243
- });
244
-
245
- it("a missing mandatory value forces the section open (section.js has_missing_mandatory)", () => {
246
- const fields = [
247
- field({ fieldname: "sec1", fieldtype: "Section Break", label: "S", collapsible: 1 }),
248
- field({ fieldname: "a", reqd: 1 }),
249
- ];
250
- expect(build(fields, { doc: {} })[0].schema.sections[0].collapsed).toBe(false);
251
- // Desk checks `value == null` — an empty string counts as present.
252
- expect(build(fields, { doc: { a: "" } })[0].schema.sections[0].collapsed).toBe(true);
253
- });
254
-
255
- it("non-collapsible sections have no collapse state", () => {
256
- const tabs = build([
257
- field({ fieldname: "sec1", fieldtype: "Section Break", label: "S" }),
258
- field({ fieldname: "a" }),
259
- ]);
260
- expect(tabs[0].schema.sections[0].collapsed).toBeUndefined();
261
- expect(tabs[0].schema.sections[0].collapsible).toBe(false);
262
- });
263
-
264
- it("forwards hide_border and description", () => {
265
- const tabs = build([
266
- field({
267
- fieldname: "sec1",
268
- fieldtype: "Section Break",
269
- label: "S",
270
- hide_border: 1,
271
- description: "About this group",
272
- }),
273
- field({ fieldname: "a" }),
274
- ]);
275
- expect(tabs[0].schema.sections[0].hideBorder).toBe(true);
276
- expect(tabs[0].schema.sections[0].description).toBe("About this group");
277
- });
278
- });
279
-
280
- describe("fetch_from read-only lock", () => {
281
- const fields = [
282
- field({ fieldname: "customer", fieldtype: "Link", options: "Customer" }),
283
- field({ fieldname: "customer_name", fetch_from: "customer.customer_name" }),
284
- field({
285
- fieldname: "note",
286
- fetch_from: "customer.note",
287
- fetch_if_empty: 1,
288
- }),
289
- ];
290
-
291
- it("locks a fetch target while its source link is set (base_input.js:56)", () => {
292
- const tabs = build(fields, { doc: { customer: "CUST-1" } });
293
- expect(findField(tabs, "customer_name")?.readOnly).toBe(true);
294
- });
295
-
296
- it("keeps the target editable when the source is empty or fetch_if_empty is set", () => {
297
- const emptyTabs = build(fields, { doc: {} });
298
- expect(findField(emptyTabs, "customer_name")?.readOnly).toBe(false);
299
- const setTabs = build(fields, { doc: { customer: "CUST-1" } });
300
- expect(findField(setTabs, "note")?.readOnly).toBe(false);
301
- });
302
- });
303
-
304
- describe("field property pass-through", () => {
305
- it("forwards description, precision, and length", () => {
306
- const tabs = build([
307
- field({ fieldname: "a", description: "help", precision: "3", length: 20 }),
308
- ]);
309
- const schema = findField(tabs, "a");
310
- expect(schema?.description).toBe("help");
311
- expect(schema?.precision).toBe(3);
312
- expect(schema?.maxLength).toBe(20);
313
- });
314
- });
315
-
316
- describe("buildCreateDefaults (create_new.js get_default_value)", () => {
317
- it("seeds static, Today, and __user defaults", () => {
318
- const doc = buildCreateDefaults(
319
- [
320
- field({
321
- fieldname: "status",
322
- fieldtype: "Select",
323
- options: "Open\nClosed",
324
- default: "Open",
325
- }),
326
- field({ fieldname: "date", fieldtype: "Date", default: "Today" }),
327
- field({ fieldname: "owner_field", fieldtype: "Link", options: "User", default: "__user" }),
328
- field({ fieldname: "count", fieldtype: "Int", default: "5" }),
329
- ],
330
- "admin@example.com",
331
- );
332
- expect(doc.status).toBe("Open");
333
- expect(doc.date).toMatch(/^\d{4}-\d{2}-\d{2}$/);
334
- expect(doc.owner_field).toBe("admin@example.com");
335
- expect(doc.count).toBe(5);
336
- });
337
-
338
- it("seeds `user` alias on Link/Data only and `now` per fieldtype", () => {
339
- const doc = buildCreateDefaults(
340
- [
341
- field({ fieldname: "who", fieldtype: "Link", options: "User", default: "user" }),
342
- field({ fieldname: "sel", fieldtype: "Select", options: "user\nrole", default: "user" }),
343
- field({ fieldname: "at_time", fieldtype: "Time", default: "now" }),
344
- field({ fieldname: "at_dt", fieldtype: "Datetime", default: "now" }),
345
- ],
346
- "admin@example.com",
347
- );
348
- expect(doc.who).toBe("admin@example.com");
349
- expect(doc.sel).toBe("user"); // Select keeps its literal option
350
- expect(doc.at_time).toMatch(/^\d{2}:\d{2}:\d{2}$/);
351
- expect(doc.at_dt).toMatch(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/);
352
- });
353
-
354
- it("seeds the first Select option when no default exists (create_new.js:107)", () => {
355
- const doc = buildCreateDefaults([
356
- field({ fieldname: "kind", fieldtype: "Select", options: "Small\nLarge" }),
357
- field({ fieldname: "empty_first", fieldtype: "Select", options: "\nA\nB" }),
358
- field({ fieldname: "placeholder", fieldtype: "Select", options: "[Select]" }),
359
- ]);
360
- expect(doc.kind).toBe("Small");
361
- expect(doc.empty_first).toBe("");
362
- expect(doc.placeholder).toBeUndefined();
363
- });
364
-
365
- it("leaves server-resolved tokens unset", () => {
366
- const doc = buildCreateDefaults([
367
- field({ fieldname: "company", fieldtype: "Link", options: "Company", default: ":Company" }),
368
- field({ fieldname: "fullname", fieldtype: "Data", default: "user_fullname" }),
369
- ]);
370
- expect(doc.company).toBeUndefined();
371
- expect(doc.fullname).toBeUndefined();
372
- });
373
- });